Skip to content

Getting Started

Try Loop Decoder

Requirements

  • TypeScript 5.x
  • exactOptionalPropertyTypes and strict enabled in your tsconfig.json

Dependencies

To get started, install the package from npm, along with its peer dependencies:

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

Quick Start

To begin using the Loop Decoder, you need to create an instance of the LoopDecoder class. At a minimum, you must provide three data loaders:

  • RPC Provider
  • ABI Loader
  • Contract Meta Information Loader

Loop Decoder has default in-memory implementations for ABI and contract meta-information loaders: InMemoryAbiStoreLive and InMemoryContractMetaStoreLive. If you need more customization for a storage, see our guide on How To Decode Transaction.

  1. getPublicClient: This function returns an object with Viem PublicClient based on the chain ID. For detailed configuration options and trace API settings, see the RPC Provider documentation.
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'),
}),
}
}
  1. abiStore: To avoid making unecessary calls to third-party APIs, Loop Decoder uses an API that allows cache. For this example, we will keep it simple and use an in-memory cache. We will also use some strategies to download contract ABIs from Etherscan and 4byte.directory. You can find more information about the strategies in the Strategies reference.

  2. contractMetaStore: Create an in-memory cache for contract meta-information. We will automatically retrieve ERC20, ERC721, and ERC1155 token meta information from the contract such as token name, decimals, symbol, etc.

Finally, you can create a new instance of the LoopDecoder class:

import { TransactionDecoder } from '@3loop/transaction-decoder'
import { InMemoryAbiStoreLive, InMemoryContractMetaStoreLive } from '@3loop/transaction-decoder/in-memory'
import { ConfigProvider, Layer } from 'effect'
// Create a config for the ABI loader, provide Etherscan V2 API key
const ABILoaderConfig = ConfigProvider.fromMap(new Map([['ETHERSCAN_API_KEY', 'YourApiKeyToken']]))
const ConfigLayer = Layer.setConfigProvider(ABILoaderConfig)
const decoder = new TransactionDecoder({
getPublicClient: getPublicClient,
abiStore: InMemoryAbiStoreLive.pipe(Layer.provide(ConfigLayer)),
contractMetaStore: InMemoryContractMetaStoreLive.pipe,
})

It’s important to note that the Loop Decoder does not enforce any specific data source, allowing users of the library to load contract data as they see fit. Depending on the requirements of your application, you can either include the necessary data directly in your code for a small number of contracts or use a database as a cache.

LoopDecoder instances provide a public method, decodeTransaction, which fetches and decodes a given transaction:

const result = await decoded.decodeTransaction({
chainID: 1,
hash: '0x...',
})