Skip to main content

Dynamic Contracts / Factories

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

Loader Function

Contract factories are currently supported in the loader function of the event that you want to register the contract in.

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

context.contractRegistration.add<your-contract-name>(<address-of-the-contract>)

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

Example using a 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 address field will be omitted for the SimpleNft contract - address values will instead be retrieved from 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 loader function for SimpleNftCreated event

context.contractRegistration.addSimpleNft(event.params.contractAddress);

The syntax is exactly 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).