Generating utility modules
- squid-evm-typegen
- squid-substrate-typegen
- squid-ink-typegen
The squid-evm-typegen(1) tool generates TypeScript facades for EVM transactions, logs and eth_call queries.
The generated facades are assumed to be used by squids indexing EVM data.
The tool takes a JSON ABIs as an input. Those can be specified in three ways:
-
as a plain JSON file(s):
npx squid-evm-typegen src/abi abi/erc20.jsonTo include all files in
./abiand add an interface for the Multicall contract, runnpx squid-evm-typegen ./src/abi ./abi/*.json --multicall -
as a contract address (to fetch the ABI from Etherscan API). Once can pass multiple addresses at once.
npx squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413
Please check if your contract is a proxy when using this method. If it is, consult this page for guidance.
-
as an arbitrary URL:
npx squid-evm-typegen src/abi https://example.com/erc721.json
In all cases typegen will use basename of the ABI as the root name for the generated files. You can change the basename of generated files using the fragment (#) suffix.
squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#my-contract-name
Arguments:
output-dir | output directory for generated definitions |
abi | A contract address, an URL or a local path to the ABI file. Accepts multiple contracts. |
Options:
--multicall | generate a facade for the MakerDAO multicall contract. May significantly improve the performance of contract state calls by batching RPC requests |
--etherscan-api <url> | etherscan API to fetch contract ABI by a known address. By default, https://api.etherscan.io/ |
--clean | delete output directory before the run |
-h, --help | display help for command |
The generated modules depend on @subsquid/evm-abi. Please add it to your package.json as a peer dependency if it's not there already:
npm i @subsquid/evm-abi
Usage
The generated utility modules have three intended uses:
-
Constants: EVM log topic0 values and sighashes for transactions. Example:
// generated by evm-typegen
import * as weth from './abi/weth'
const CONTRACT_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'.toLowerCase()
const processor = new EvmBatchProcessor()
.setGateway('https://v2.archive.subsquid.io/network/ethereum-mainnet')
.addLog({
address: [CONTRACT_ADDRESS],
topic0: [
weth.events.Deposit.topic,
weth.events.Withdrawal.topic
]
}) -
Direct chain state queries, including queries to multicall.
The substrate typegen tool is a part of Subsquid SDK. It generates TypeScript wrappers for interfacing Substrate events and calls.
Usage:
npx squid-substrate-typegen typegen.json
If necessary, multiple config files can be supplied:
npx squid-substrate-typegen typegen0.json typegen1.json ...
The structure of the typegen.json config file is best illustrated with an example:
{
"outDir": "src/types",
"specVersions": "https://v2.archive.subsquid.io/metadata/kusama",
"pallets": {
// add one such section for each pallet
"Balances": {
"events": [
// list of events to generate wrappers for
"Transfer"
],
"calls": [
// list of calls to generate wrappers for
"transfer_allow_death"
],
"storage": [
"Account"
],
"constants": [
"ExistentialDeposit"
]
}
}
}
The specVersions field is either
- a metadata service endpoint URL, like
or
https://v2.archive.subsquid.io/metadata/{network} - a path to a
jsonlfile generated bysubstrate-metadata-explorer(1).
To generate all items defined by a given pallet, set any of the events, calls, storage or constants fields to true, e.g.
{
"outDir": "src/types",
"specVersions": "kusamaVersions.jsonl",
"pallets": {
"Balances": {
// generate wrappers for all Balances pallet constants
"constants": true
}
}
}
In the rare cases when the typegen needs a types bundle, supply it alongside metadata:
{
"outDir": "src/types",
"specVersions": "westendVersions.jsonl",
"typesBundle": "westendTypes.json",
...
}
TypeScript wrappers
Wrappers generated by the typegen command can be found in the specified outDir (src/types by convention). Assuming that this folder is imported as types (e.g. with import * as types from './types'), you'll be able to find the wrappers at:
- for events:
types.events.${palletName}.${eventName} - for calls:
types.calls.${palletName}.${callName} - for storage items:
types.storage.${palletName}.${storageItemName} - for constants:
types.constants.${palletName}.${constantName}
All identifiers (pallet name, call name etc) are lowerCamelCased. E.g. the constant Balances.ExistentialDeposit becomes types.events.balances.existentialDeposit and the call Balances.set_balance becomes types.calls.setBalance.
Usage
-
Item name constants (e.g.
events.balances.transfer.name). -
Runtime versioning-aware decoding.
-
Runtime constants:
import {constants} from './types'
// ...
processor.run(new TypeormDatabase(), async ctx => {
for (let block of ctx.blocks) {
if (constants.balances.existentialDeposit.v1020.is(block.header)) {
let c = new constants.balances.existentialDeposit.v1020.get(block.header)
ctx.log.info(`Balances.ExistentialDeposit (runtime version V1020): ${c}`)
}
}
})
Use squid-ink-typegen to generate facade classes for decoding ink! smart contract data from JSON ABI metadata.
Usage:
npx squid-ink-typegen --abi abi/erc20.json --output src/abi/erc20.ts
The generated source code exposes the decoding methods, some useful types and a class for performing wrapped RPC queries, using @subsquid/ink-abi under the hood