Getting Started
Installation
npm i @3loop/transaction-decoder viem effectQuick Start
Loop Decoder requires three components:
- RPC Provider
- ABI Data Store
- Contract Metadata Store
This guide demonstrates setup using the default in-memory implementations for Data Stores. For custom storage solutions, see our How To Decode Transaction guide.
1. Set up your RPC Provider
Create a getPublicClient function that accepts a chain ID and returns an object with Viem PublicClient.
import { createPublicClient, http } from 'viem'
// Create a public client for the Ethereum Mainnet networkconst getPublicClient = (chainId: number) => { return { client: createPublicClient({ transport: http('https://rpc.ankr.com/eth'), }), }}For detailed configuration options and trace API settings, see the RPC Provider documentation.
2. Initialize ABI Data Store
The InMemoryAbiStoreLive provides default ABI loading and caching functionality:
- Fetches ABIs from multiple sources (Etherscan, 4bytes, Openchain, Sourcify)
- Caches results in memory
import { InMemoryAbiStoreLive } from '@3loop/transaction-decoder/in-memory'import { ConfigProvider, Layer } from 'effect'
// We use Effect library to provide custom configurationconst Config = ConfigProvider.fromMap(new Map([['ETHERSCAN_API_KEY', 'YourApiKey']]))const ABILoaderLayer = Layer.setConfigProvider(Config)const abiStore = InMemoryAbiStoreLive.pipe(Layer.provide(ABILoaderLayer))For a custom implementation, see our How To Decode Transaction (ABI Data Store) guide.
3. Initialize Contract Metadata Store
The InMemoryContractMetaStoreLive handles contract metadata resolution:
- Resolves
ERC20,ERC721andERC1155metadata using RPC calls - Caches results in memory
import { InMemoryContractMetaStoreLive } from '@3loop/transaction-decoder/in-memory'
const contractMetaStore = InMemoryContractMetaStoreLiveFor a custom implementation, see our How To Decode Transaction (Contract Metadata Store) guide.
4. Decode a Transaction
Finally, you can create a new instance of the LoopDecoder class and invoke decodeTransaction method with the transaction hash and chain ID:
import { TransactionDecoder } from '@3loop/transaction-decoder'
const decoder = new TransactionDecoder({ getPublicClient: getPublicClient, abiStore, contractMetaStore,})
const decoded = await decoder.decodeTransaction({ chainID: 1, hash: '0x...',})