Set up a new Sim IDX app using the contract-decoder template to decode all events and functions from any smart contract.
This guide shows you how to use the contract-decoder template to set up a Sim IDX app that decodes an entire smart contract. As an example, we will configure the app to listen to and persist every event emitted by the Moonbirds ERC721 NFT contract on Ethereum, but you can follow the same process for any contract.
The contract-decoder
template provides a shortcut to make this happen. Instead of manually defining each event you want to capture, it generates a special listener that automatically handles all events from a given contract ABI.
First, create a new directory for your project and initialize a Sim IDX app using the --template=contract-decoder
flag.
This command scaffolds a new project with a sample Uniswap V3 Factory ABI. In the next steps, we will replace it with the Moonbirds contract ABI.
The template includes a default ABI at abis/UniswapV3Factory.json
. Since we’re replacing it, the first step is to delete this file.
Removing the JSON file is not enough. The project still contains the Solidity bindings that were generated from it. To remove them, run sim abi codegen
. This command re-scans the abis/
directory and regenerates the bindings, effectively removing the ones for the now-deleted Uniswap ABI.
Now, you need the ABI for the contract you want to decode. You can typically find a contract’s ABI on a blockchain explorer like Etherscan. For this guide, we’ll use the Moonbirds contract on Ethereum.
abis/Moonbirds.json
and paste the ABI into it.With the ABI file in place, run sim abi add
to register it with your project and generate the necessary Solidity bindings.
The CLI will parse the new ABI and generate a Moonbirds.sol
file in listeners/lib/sim-idx-generated/
. This file contains all the interfaces and helper contracts needed to interact with the Moonbirds contract in your listener.
Open listeners/src/Main.sol
. This is the core file where you define your indexing logic. We need to make two small changes to trigger on the generated Moonbirds bindings.
The Moonbirds.sol
file generated in the previous step includes a special abstract contract called Moonbirds$EmitAllEvents
. By inheriting from this contract, your listener automatically gains the ability to:
allTriggers()
, to register all event listeners at once.The event names are automatically converted to snake_case
for your PostgreSQL table names. For example, an on-chain event named RoleGranted
will have its data stored in a table named role_granted
.
Update listeners/src/Main.sol
with the following code:
This is all the Solidity code required. The Listener
contract inherits the decoding logic, and the Triggers
contract points to the on-chain Moonbirds address, registering all its events for indexing.
Before deploying, you can test your listener against historical blockchain data using sim listeners evaluate
. This command runs a local dry-run to confirm your triggers fire correctly and decode events as expected.
Find a block number on Etherscan where a Moonbirds transaction occurred and use it for the --start-block
flag.
If the setup is correct, the output will be a JSON object containing a list of decoded Moonbirds events in the events
array and an empty errors
array.
When you ran sim init
, a sample API was created in apis/src/index.ts
. This API is configured to query data from the original Uniswap contract and will fail now that we’ve replaced the ABI. We need to update it to query one of the new tables created for the Moonbirds events.
When you run sim build
, Drizzle schemas for all your new event tables are automatically generated and placed in apis/src/db/schema/Listener.ts
. You can inspect this file to see which tables are available to query.
Let’s update apis/src/index.ts
to fetch the 10 most recent records from the approval_for_all
table, which corresponds to the ApprovalForAll
event.
With the listener and API updated, run sim build
to compile your contracts and API code.
The command should complete successfully. Unlike other templates, the contract-decoder
template does not include listener tests that need to be updated, simplifying the development workflow.
Your app is now configured to decode the entire Moonbirds contract. The final step is to deploy it to Sim’s managed infrastructure so it can begin indexing data and serving your API.