Skip to main content
evmDecoder() bundles an EVM log query with a decoding transform into a single reusable module. Pass the result as an output to evmPortalStream:
evmDecoder() can:
  • Fetch from specific contracts — pass an array of addresses to contracts. Omit it entirely to receive matching events from every contract on-chain.
  • Filter by indexed parameters — instead of a bare event, supply { event, params } to select only logs where specific indexed arguments match.
  • Dynamically discover contracts via factories — pass a contractFactory() to contracts instead of a static list. See the Factory guide.
  • Handle decode errors with a custom onError callback instead of letting them propagate.
See the evmDecoder() reference for all parameters.

Specifying events

The events parameter maps output field names to event specifications. There are three ways to obtain an event specification.

commonAbis

commonAbis is a built-in collection of ABI modules for common token standards. Currently it ships one module, erc20:
See the commonAbis reference for the full list of available events and functions.

Typegen modules

@subsquid/evm-typegen generates TypeScript ABI modules from JSON ABIs. Each generated module exports typed events and functions objects, translating Solidity types to TypeScript — event argument types are statically known at compile time, so you get precise type checking and IDE autocompletion across the entire pipeline. Install the tool:
Generate a module from a local JSON ABI file:
This creates src/abi/your-contract.ts. The tool also accepts a contract address (requires specifying --chain-id) or an arbitrary URL. Use events from a generated module exactly as with commonAbis:

Raw JSON via defineAbi()

defineAbi() converts a JSON ABI array to a subsquid ABI module at runtime, with no code generation step. This is the quickest route — useful for one-off scripts or prototypes — but it comes at a cost: when the ABI is loaded from an external JSON file, event argument fields are typed as any, since TypeScript cannot inspect the runtime JSON value at compile time.
defineAbi() also accepts Hardhat and Foundry artifact objects — it reads the abi field automatically:
If you define the ABI inline with as const, TypeScript can infer the exact decoded types for scalar fields:
For projects where full type safety matters end-to-end, prefer the typegen route instead.