Parameterized Modules
Substreams allows you to pass parameters to your modules by specifying them in the manifest.
Parameterization of a Factory contract
It's quite common for a smart contract to be deployed on different networks or even by different dApps within the same network. Uniswap Factory smart contract is a good example of that.
When running Substreams for a dApp, you need to know the smart contract deployment address and for obvious reasons, this address will be different for each deployment.
Instead of hard-coding the address in the Substreams binary, you can customize it without having to rebuild or even repackage the Substreams package. The consumer can then just provide the address as a parameter.
First, you need to add the params
field as an input. Note that it's always a string and it's always the first input for the module:
You can specify the default value directly in the manifest. In this case, we use 0x1f98431c8ad98523631ae4a59f267346ea31f984
- the deployment address for UniswapV3 contract on Ethereum Mainnet.
Handling the parameter in the module is easy. The module handler receives it as a first input parameter and you can use it to filter transactions instead of the hard-coded value:
To pass the parameter to the module using substreams
CLI you can use -p
key:
Documenting parameters
It's always a good idea to document what the params represent and how they are structured, so the consumers of your modules know how to properly parameterize them. You can use doc
field for the module definition in the manifest.
Advanced parameters
Sometimes you may need to use multiple parameters for a module. To pass multiple parameters, you can encode them as a URL-encoded query string, i.e. param1=value1¶m2=value2
.
Suppose you want to track transfers to/from a certain address exceeding a certain amount of ETH. Your module manifest could look like this:
Our module gets a params string with two parameters: address
and amount
.
In your module handler, you can decode your parameters using one of the URL decoding crates such as serde_qs
, serde_urlencoded
or your own helper functions. Here's an example using serde_qs
:
Sometimes parameters can be optional, i.e. you want to track all transfers rather than a specific address. Decoding will look like this in that case:
You can even pass a vector of addresses to track multiple specific whales in our example:
Depending on the crate you use to decode params string, you can pass them to Substreams CLI like this for example:
Parameters Per Network
It also possible to specify parameters per network. For example, consider that you want to specify a specific parameter for Ethereum and a different one for Solana.
The syntax to specify the parameters per network in your manifest uses the top-level networks
block.
For example, if you want to specify a parameter for the my-module
module on Ethereum Mainnet:
Last updated