packages/cli/templates/static/shared/.claude/skills/indexing-blocks/SKILL.md
Use when processing every block (or every Nth block) for time-series data, periodic snapshots, or block-level aggregations. indexer.onBlock API, where filter with block-number range and stride, and block handler context.
npx skillsauth add enviodev/hyperindex indexing-blocksInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Process every block (or every Nth block) using indexer.onBlock. No contract
address or config.yaml entry needed.
Branch by chain.id with a switch so the type system flags any
unconfigured chain via the default: never exhaustiveness check:
import { indexer } from "generated";
indexer.onBlock(
{
name: "BlockTracker",
where: ({ chain }) => {
switch (chain.id) {
case 1:
return { block: { number: { _gte: 18000000, _every: 100 } } };
case 8453:
return { block: { number: { _every: 50 } } };
default: {
// Exhaustiveness check: TypeScript errors here if a new chain ID
// is added to config.yaml but not handled above.
const _exhaustive: never = chain.id;
return false;
}
}
},
},
async ({ block, context }) => {
context.BlockSnapshot.set({
id: `${block.number}`,
blockNumber: BigInt(block.number),
});
}
);
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| name | string | yes | Handler name for logging |
| where | ({ chain }) => boolean \| filter | no | Predicate evaluated once per configured chain at registration. Return false to skip a chain, true / omit to match every block, or {block: {number: {_gte?, _lte?, _every?}}} to restrict range and stride. _every aligns relative to _gte, preserving (blockNumber - _gte) % _every === 0. |
indexer.onBlock API; filter is keyed by block.height instead of block.number.indexer.onSlot; filter shape is {slot: {_gte?, _lte?, _every?}} and the handler arg is {slot: number, context} (no block wrapper).indexer.onBlock self-registers — no config.yaml entry neededwhere returns false for every configured chain, a warning is logged at registration timeFull reference: https://docs.envio.dev/docs/HyperIndex-LLM/hyperindex-complete
development
Write and run tests for HyperIndex indexers using Vitest and createTestIndexer(). Covers test setup, processing block ranges, asserting entity changes with toMatchInlineSnapshot, and TDD workflow. Use when writing tests, debugging handler output, or verifying indexer behavior.
data-ai
Migrate a TheGraph subgraph to Envio HyperIndex using TDD. Covers schema conversion (remove @entity, Bytes->String, @derivedFrom), handler translation (save->set, store.get->context.get, templates->contractRegister), and verification against subgraph data.
data-ai
Use when indexing all instances of a contract across all addresses (e.g., all ERC-20 transfers on a chain). Config setup (no address), wildcard handler option, and event.srcAddress.
data-ai
Use when needing transaction-level data in handlers. Configure field_selection to include transaction fields on events, and access via event.transaction. No native transaction handler — access through event handlers.