Skip to main content
squid-substrate-typegen generates TypeScript wrappers for interfacing Substrate events, calls, storage items, and constants, aware of runtime version changes. A companion tool, squid-ink-typegen, does the same for ink! smart contracts. Install both with --save-dev.

Generating wrappers

If necessary, multiple config files can be supplied:
Paths in typegen.json are resolved relative to the config file. The structure is best illustrated with an example:
The specVersions field is either To generate all items defined by a given pallet, set any of the events, calls, storage or constants fields to true. The events, calls, storage, and constants selectors can also be set at the top level to select items across pallets, and a pallet entry can itself be true to select the whole pallet.
In the rare cases when typegen needs pre-v14 type definitions, typesBundle accepts either a built-in chain name or a path to a JSON bundle (resolved relative to typegen.json):
Built-in bundles include acala/karura, aleph-node, altair, astar, basilisk, bifrost, calamari, clover, crust, darwinia, hydradx, khala, kilt, kintsugi, kusama, manta, moonbeam/moonbase/moonriver, parallel/heiko, pioneer, polkadot, reef, shell, shiden, shibuya, sora-substrate, statemint/statemine, subsocial, unique/quartz, and zeitgeist. See also the types bundle miniguide.

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.constants.balances.existentialDeposit and the call Balances.set_balance becomes types.calls.balances.setBalance. Runtime constants are available directly from the wrappers:

Decoding events and calls

To decode events and calls, first determine the appropriate runtime version with .is(), then decode them with .decode():

Storage queries

It is sometimes impossible to extract the required data with only event and call data without querying the runtime state. The context exposes a lightweight JSON-RPC client at ctx._chain.rpc with low-level methods for accessing the storage. However, the recommended way to query the storage is with the type-safe wrappers exposed at src/types/storage.ts, following the general naming pattern:
Note that the generated getters always query historical blockchain state at the height derived from their block argument.
src/types/balances/storage.ts
The generated access interface provides methods for accessing:
  • the default storage value with getDefault(block)
  • a single storage value with get(block, key)
  • multiple values in a batch call with getMany(block, keys[])
  • all storage keys with getKeys(block)
  • all keys with a given prefix with getKeys(block, keyPrefix) (only if the storage keys are decodable)
  • paginated keys via getKeysPaged(pageSize, block) and getKeysPaged(pageSize, block, keyPrefix)
  • key-value pairs via getPairs(block) and getPairs(block, keyPrefix)
  • paginated key-value pairs via getPairsPaged(pageSize, block) and getPairsPaged(pageSize, block, keyPrefix)
src/main.ts

ink! contracts

Use squid-ink-typegen to generate facade classes for decoding ink! smart contract data from JSON ABI metadata:
The generated source code exposes decoding methods, some useful types, and a class for performing wrapped RPC queries, using @subsquid/ink-abi under the hood:
src/abi/erc20.ts
Usage in a batch handler:
The generated Contract class provides facades for all state calls that don’t mutate the contract state (mutability is taken from the contract metadata):
For a complete worked example, see the ink! contract indexing tutorial.