Getting Started
Installation
npm i @3loop/transaction-decoder viem effectOverview
To begin using the Loop Decoder, you must provide three components:
- RPC Provider
- ABI Loader
- Contract Metadata Loader
This guide demonstrates setup using the default in-memory implementations for data loaders. 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 Loader
The InMemoryAbiStoreLive provides default ABI loading 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 Loader guide.
3. Initialize Contract Metadata Loader
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 Loader guide.
4. Final Step
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...',})