Skip to content

Getting Started

Installation

Terminal window
npm i @3loop/transaction-decoder viem effect

Quick Start

Loop Decoder requires three components:

  1. RPC Provider
  2. ABI Data Store
  3. 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.

index.ts
import { createPublicClient, http } from 'viem'
// Create a public client for the Ethereum Mainnet network
const 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 configuration
const 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, ERC721 and ERC1155 metadata using RPC calls
  • Caches results in memory
import { InMemoryContractMetaStoreLive } from '@3loop/transaction-decoder/in-memory'
const contractMetaStore = InMemoryContractMetaStoreLive

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...',
})

Live Demo