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.
1. Initialize the App from the Template
First, create a new directory for your project and initialize a Sim IDX app using the--template=contract-decoder
flag.
To make development even faster, you can add our official Cursor Rules to your project.
These rules teach Cursor about Sim IDX’s architecture, helping it generate correct and consistent code.Learn more in our Build with AI guide.
2. Remove the Sample ABI
The template includes a default ABI atabis/UniswapV3Factory.json
. Since we’re replacing it, the first step is to delete this file.
sim abi codegen
. This command re-scans the abis/
directory and regenerates the bindings, effectively removing the ones for the now-deleted Uniswap ABI.
3. Add the Moonbirds Contract 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.- Navigate to the Moonbirds contract on Etherscan.
- Scroll down to the “Contract ABI” section and copy the entire JSON blob.
- Create a new file in your project at
abis/Moonbirds.json
and paste the ABI into it.
sim abi add
to register it with your project and generate the necessary Solidity bindings.
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.
4. Configure the Listener to Decode All Events
Openlisteners/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:
- React to every event defined in the Moonbirds ABI.
- Define and emit corresponding events that Sim IDX will use to create database tables.
- Expose a helper function,
allTriggers()
, to register all event listeners at once.
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:
Main.sol
Listener
contract inherits the decoding logic, and the Triggers
contract points to the on-chain Moonbirds address, registering all its events for indexing.
5. Evaluate the Listener Against Live Data
Before deploying, you can test your listener against historical blockchain data usingsim 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.
events
array and an empty errors
array.
6. Update the API to Query New Data
When you ransim 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.
7. Build the Project
With the listener and API updated, runsim build
to compile your contracts and API code.
contract-decoder
template does not include listener tests that need to be updated, simplifying the development workflow.