packages/cli/templates/static/shared/.claude/skills/indexing-filters/SKILL.md
Use when filtering events by indexed parameters to reduce processing volume. The `where` option supports static filters, dynamic per-chain functions, contract address filtering, and conditional enable/disable.
npx skillsauth add enviodev/hyperindex indexing-filtersInstall 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.
where)The where handler option filters events by indexed parameters. Works with or without wildcard: true.
The filter value is a { params: ... } record. params can be a single object (AND-conjunction across indexed parameters) or an array of objects (OR across multiple AND-conjunctions). The {params} wrapper reserves room for future filter dimensions (block, transaction, …) as sibling fields.
indexer.onEvent(
{
contract: "ERC20",
event: "Transfer",
wildcard: true,
where: { params: { from: ZERO_ADDRESS, to: WHITELISTED } },
},
async ({ event, context }) => {
/* ... */
},
);
indexer.onEvent(
{
contract: "ERC20",
event: "Transfer",
wildcard: true,
where: {
params: [{ from: ZERO_ADDRESS }, { to: ZERO_ADDRESS }],
},
},
async ({ event, context }) => {
/* ... */
},
);
Each entry in the params array is OR'd together. Within a single entry, fields are AND'd. Arrays in a field position match any value in the array.
Return a filter based on the current chain. The callback receives { chain } where chain.id is the chain ID and chain.<ContractName>.addresses exposes the indexed addresses of the event's own contract on that chain. Return false to skip the chain entirely (no events processed), or true to allow all events. To filter, return a {params: ...} object where params is a single record or an array of records:
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
const WHITELISTED = {
137: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" as const],
100: ["0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" as const],
};
indexer.onEvent(
{
contract: "ERC20",
event: "Transfer",
wildcard: true,
where: ({ chain }) => {
if (chain.id !== 100 && chain.id !== 137) return false;
return {
params: [
{ from: ZERO_ADDRESS, to: WHITELISTED[chain.id] },
{ from: WHITELISTED[chain.id], to: ZERO_ADDRESS },
],
};
},
},
async ({ event, context }) => {
/* ... */
},
);
chain.<Contract>.addresses — Filter by Registered ContractsFor dynamically registered contracts, use chain.<ContractName>.addresses to filter by their addresses. Only the event's own contract is exposed:
indexer.onEvent(
{
contract: "ERC20",
event: "Transfer",
wildcard: true,
where: ({ chain }) => {
if (chain.id !== 100 && chain.id !== 137) return false;
return {
params: [
{ from: ZERO_ADDRESS, to: chain.ERC20.addresses },
{ from: chain.ERC20.addresses, to: ZERO_ADDRESS },
],
};
},
},
async ({ event, context }) => {
/* ... */
},
);
params entry correspond to the event's indexed parameters onlyparams array → OR (match any)return false → skip the chain entirely (no events processed for that chain)return true → accept all events (no filtering, default topic0-only selection)Full 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.