Skip to content

Instantly share code, notes, and snippets.

@anastasiarods
Created October 20, 2024 19:12
Show Gist options
  • Save anastasiarods/cb3547b1e215a325619269ad1efdfcde to your computer and use it in GitHub Desktop.
Save anastasiarods/cb3547b1e215a325619269ad1efdfcde to your computer and use it in GitHub Desktop.
Example of decoding EVM tx with Loop Decoder
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'),
}),
}
}
import {
EtherscanStrategyResolver,
FourByteStrategyResolver,
VanillaAbiStore,
ContractABI,
} from '@3loop/transaction-decoder'
// Create an in-memory cache for the ABIs
const abiCache = new Map<string, ContractABI>()
const abiStore: VanillaAbiStore = {
// Define the strategies to use for fetching the ABIs
strategies: [
EtherscanStrategyResolver({
apikey: 'YourApiKeyToken',
}),
FourByteStrategyResolver(),
],
// Get the ABI from the cache
// Get it by contract address, event name or signature hash
get: async ({ address, event, signature }) => {
const value = abiCache.get(address)
if (value) {
return {
status: 'success',
result: value,
}
} else if (event) {
const value = abiCache.get(event)
if (value) {
return {
status: 'success',
result: value,
}
}
} else if (signature) {
const value = abiCache.get(signature)
if (value) {
return {
status: 'success',
result: value,
}
}
}
return {
status: 'empty',
result: null,
}
},
// Set the ABI in the cache
// Store it by contract address, event name or signature hash
set: async (_key, value) => {
if (value.status === 'success') {
if (value.result.type === 'address') {
abiCache.set(value.result.address, value.result)
} else if (value.result.type === 'event') {
abiCache.set(value.result.event, value.result)
} else if (value.result.type === 'func') {
abiCache.set(value.result.signature, value.result)
}
}
},
}
import type { ContractData, VanillaContractMetaStore } from '@3loop/transaction-decoder'
import { ERC20RPCStrategyResolver } from '@3loop/transaction-decoder'
// Create an in-memory cache for the contract meta-information
const contractMetaCache = new Map<string, ContractData>()
const contractMetaStore: VanillaContractMetaStore = {
// Define the strategies to use for fetching the contract meta-information
strategies: [ERC20RPCStrategyResolver],
// Get the contract meta-information from the cache
get: async ({ address, chainID }) => {
const key = `${address}-${chainID}`.toLowerCase()
const value = contractMetaCache.get(key)
if (value) {
return {
status: 'success',
result: value,
}
}
return {
status: 'empty',
result: null,
}
},
// Set the contract meta-information in the cache
set: async ({ address, chainID }, result) => {
const key = `${address}-${chainID}`.toLowerCase()
if (result.status === 'success') {
contractMetaCache.set(key, result.result)
}
},
}
import { TransactionDecoder } from '@3loop/transaction-decoder'
const decoder = new TransactionDecoder({
getPublicClient: getPublicClient,
abiStore: abiStore,
contractMetaStore: contractMetaStore,
})
async function main() {
try {
const decoded = await decoder.decodeTransaction({
chainID: 1,
hash: '0xc0bd04d7e94542e58709f51879f64946ff4a744e1c37f5f920cea3d478e115d7',
})
console.log(JSON.stringify(decoded, null, 2))
} catch (e) {
console.error(JSON.stringify(e, null, 2))
}
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment