mit einem Klick
indexing-filters
// 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.
// 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.
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.
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.
| name | indexing-filters |
| description | 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. |
where)The where handler option filters events by indexed parameters and restricts the per-event block range. Works with or without wildcard: true.
The filter value is a { params?, block? } record. params can be a single object (AND-conjunction across indexed parameters) or an array of objects (OR across multiple AND-conjunctions). block.number._gte (or block.height._gte on Fuel) promotes to the event's startBlock and overrides the contract-level start_block from config.yaml.
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 }) => {
/* ... */
},
);
startBlock via block.number._gteUse where.block as a sibling of params to restrict an event to blocks at or after a given number. Overrides the contract's start_block from config.yaml — useful for narrowing a single event without touching the whole contract.
Use a switch on chain.id to pick the startBlock only, so the shared params filter isn't duplicated per chain. The default: never branch makes TypeScript flag any chain added to config.yaml but not handled here:
indexer.onEvent(
{
contract: "ERC20",
event: "Transfer",
wildcard: true,
where: ({ chain }) => {
let startBlock: number;
switch (chain.id) {
case 1:
startBlock = 18000000;
break;
case 8453:
startBlock = 2000000;
break;
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;
}
}
return {
block: { number: { _gte: startBlock } },
params: [{ from: chain.ERC20.addresses }, { to: chain.ERC20.addresses }],
};
},
},
async ({ event, context }) => {
/* ... */
},
);
On Fuel, key the block range on block.height instead of block.number. SVM has no event handlers. Only _gte is accepted on event filters. The block filter is only valid at the top level of where, not nested inside params array entries.
params entry correspond to the event's indexed parameters onlyparams array → OR (match any)block.number._gte (EVM) / block.height._gte (Fuel) → per-event startBlock, overrides contract start_blockreturn 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