Skip to main content
In EVM Squid SDK, the data is processed by repeatedly calling the user-defined batch handler function on batches of on-chain data. The sole argument of the batch handler is its context ctx with the structure {store, blocks, isHead}:
  • ctx.store is the store exposed by the database passed to run() or Processor;
  • ctx.blocks is an array of Block objects containing the data to be processed, aligned at the block level;
  • ctx.isHead is true when the batch ends at the current chain head.
Portal-native handlers do not receive ctx.log — create a logger explicitly with createLogger() from @subsquid/logger if the handler needs one. The Block interface is defined as follows:
F here is the type of the argument of the setFields() method of DataSourceBuilder. Block.header contains the block header data; use header.number for the block height (header.height remains available only as a deprecated alias). The rest of the fields are flat iterables containing the four kinds of blockchain data. The items are not nested under their transactions — related items land in their own iterables (see Augmented blocks for convenient navigation between them). The canonical ordering within each iterable depends on the data kind:
  • transactions and logs are ordered in the same way as they are within blocks;
  • stateDiffs follow the order of transactions that gave rise to them;
  • traces are ordered by transactionIndex and then lexicographically by traceAddress.

Field guarantees

Each data item is guaranteed to have a small set of always-present fields (e.g. logIndex and transactionIndex for logs) plus exactly the fields requested with setFields() — there are no default optional fields. The exact fields available in each data item type are inferred from the setFields() call argument and documented on the field selection page: Use GetDataSourceBlock to derive the exact block type from a configured data source:

Augmented blocks

The raw items of ctx.blocks are plain data objects without item IDs or references between related items. augmentBlock() from @subsquid/evm-objects adds them:
Augmented items gain:
  • id: a unique string identifier, handy as an entity primary key (also available on header);
  • block: a reference to the block header of the item’s block;
  • log.transaction / log.getTransaction(): the parent transaction of a log;
  • trace.transaction / trace.getTransaction(), trace.parent / trace.getParent(), trace.children: navigation across the trace tree and to the parent transaction;
  • stateDiff.transaction / stateDiff.getTransaction(): the parent transaction of a state diff;
  • transaction.logs, transaction.traces, transaction.stateDiffs: the related items of a transaction.
The optional properties (e.g. log.transaction) are populated only when the related items are present in the block data — request them with the include flags of the data requests. The get*() variants return the same values but throw instead of returning undefined when the related item is missing. The package also exports the formatId() and shortHash() utilities used to build the IDs, and the AugmentedBlock<B> type that maps a raw block type to its augmented counterpart:

Example

The handler below simply outputs all the log items emitted by the contract 0x2E645469f354BB4F5c8a05B3b30A929361cf77eC in real time:
Note that the address field must be requested with setFields() to be read in the handler — there are no default fields. For more elaborate examples, check EVM Examples.