Getting Started
Installation
npm i @3loop/transaction-decoder viem effect
Quick 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 (see and run Full Example Code from this page). 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 { EtherscanV2StrategyResolver } from '@3loop/transaction-decoder'
const abiStore = InMemoryAbiStoreLive.make({ default: [ EtherscanV2StrategyResolver({ apikey: 'YourApiKey', // provide Etherscan V2 API key }), ],})
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
,ERC721
andERC1155
metadata using RPC calls - Caches results in memory
import { ERC20RPCStrategyResolver, ProxyRPCStrategyResolver, PublicClient } from '@3loop/transaction-decoder'import { InMemoryContractMetaStoreLive } from '@3loop/transaction-decoder/in-memory'import { Effect, Layer } from 'effect'
const contractMetaStore = Layer.unwrapEffect( Effect.gen(function* () { const service = yield* PublicClient
return InMemoryContractMetaStoreLive.make({ default: [ERC20RPCStrategyResolver(service), ProxyRPCStrategyResolver(service)], }) }),)
For 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...',})