Skip to main content
Version: v2

Dynamic Contracts / Factories

If you have a system that does not know all the contracts that need indexing at the beginning (e.g., a factory contract that dynamically creates new contracts over time), you can use dynamic contracts.

Contract Registration

Contract factories are currently supported in the event's contractRegister function for when you want to register the contract.

You can register a dynamic contract by including the following line inside the contractRegister function:

<contract-name>.<event-name>.contractRegister(({ event, context }) => {
context.add<your-contract-name>(<address-of-the-contract>);
});

You can also configure the "preRegisterDynamicContracts" flag in your event config. For all the events that have this config, there will be an end to end indexer run just for these events to run each relevant contractRegister functions and collect all the dynamic contract addresses. The indexer then restarts with all these addresses from the start block configured for the network (rather than from the block that the contract gets registered). For a standard factory contract setup this drastically reduces indexing time since it doesn't result in many small block range queries but rather larger grouped queries.

<contract-name>.<event-name>.contractRegister(({ event, context }) => {
context.add<your-contract-name>(<address-of-the-contract>);
},
{
preRegisterDynamicContracts: true
}
);

The syntax is exactly the same for JavaScript, TypeScript, and ReScript.

Example using an NFT factory

In the NFT factory example, we want to dynamically register all the SimpleNft contracts that get created by the NftFactory contract, via SimpleNftCreated events.

Both types of contracts will be defined in the configuration file; however, the address field will be omitted for the SimpleNft contract - address values will instead be retrieved from the SimpleNftCreated event.

Config file

name: nftindexer
description: NFT Factory
networks:
- id: 1337
start_block: 0
contracts:
- name: NftFactory
abi_file_path: abis/NftFactory.json
address: 0x4675a6B115329294e0518A2B7cC12B70987895C4
handler: src/EventHandlers.ts
events:
- event: SimpleNftCreated (string name, string symbol, uint256 maxSupply, address contractAddress)
- name: SimpleNft
abi_file_path: abis/SimpleNft.json
handler: src/EventHandlers.ts
events:
- event: Transfer (address from, address to, uint256 tokenId)

Registering SimpleNft contracts in contractRegister function for SimpleNftCreated event

NftFactory.SimpleNftCreated.contractRegister(({ event, context }) => {
context.addSimpleNft(event.params.contractAddress);
});

The syntax is exactly the same for JavaScript, TypeScript, and ReScript.

For more information on how to write the event handlers file, go here.

Important Note

When a dynamic contract is loaded, we load all the events in the block in which the contract was registered (even if they were from a previous transaction). Please let us know if this is an issue for you, as the team also has a solution where it only loads events after the event that loaded the contract. We decided this was better since many contracts emit an event upon creation, and this occurs before the contract is loaded (for example, in Uniswap v2).