ワンクリックで
indexing-handler-syntax
// Use when writing or editing event handlers. Handler registration, context API (entity CRUD, getWhere queries, chain, log), spread updates, indexer runtime API, and common pitfalls.
// Use when writing or editing event handlers. Handler registration, context API (entity CRUD, getWhere queries, chain, log), spread updates, indexer runtime API, and common pitfalls.
| name | indexing-handler-syntax |
| description | Use when writing or editing event handlers. Handler registration, context API (entity CRUD, getWhere queries, chain, log), spread updates, indexer runtime API, and common pitfalls. |
This is an ESM project ("type": "module" in package.json). Top-level await is available. Use import/export syntax, not require.
schema.graphql or config.yaml → run pnpm codegenpnpm tsc --noEmitTUI_OFF=true pnpm dev to catch runtime errorsimport { Contract } from "generated";
Contract.Event.handler(async ({ event, context }) => {
// event.params.<name> — decoded event parameters
// event.chainId — chain ID
// event.srcAddress — emitting contract address (checksummed)
// event.logIndex — log index within block
// event.block — { number, timestamp, hash }
// event.transaction — transaction fields (configure via field_selection)
});
Handlers accept an optional 2nd argument — see indexing-wildcard and indexing-filters skills.
// Read
const entity = await context.Entity.get(id); // Entity | undefined
const entity = await context.Entity.getOrThrow(id); // throws if missing
const entity = await context.Entity.getOrCreate({ id, ...defaults });
// Query by indexed fields (@index in schema)
const list = await context.Entity.getWhere({ fieldName: { _eq: value } });
const list = await context.Entity.getWhere({ fieldName: { _gt: value } });
const list = await context.Entity.getWhere({ fieldName: { _lt: value } });
const list = await context.Entity.getWhere({ fieldName: { _gte: value } });
const list = await context.Entity.getWhere({ fieldName: { _lte: value } });
const list = await context.Entity.getWhere({ fieldName: { _in: [value1, value2] } });
// Write
context.Entity.set(entity); // create or update (sync — no await)
context.Entity.deleteUnsafe(id); // delete (sync — no await)
getWhere operators: _eq, _gt, _lt, _gte, _lte, _in. Only @index fields are queryable. See indexing-schema for @index syntax.
context.chain.id // number — current chain ID
context.chain.isLive // boolean — true when processing live blocks
context.isPreload // boolean — true during preload phase
context.log // { debug, info, warn, error, errorWithExn }
context.effect(fn, input) // external call via Effect API (see indexing-external-calls)
Entities from context.Entity.get() are read-only. Always spread:
const entity = await context.Entity.get(id);
if (entity) {
context.Entity.set({ ...entity, field: newValue });
}
indexer Runtime APIimport { indexer } from "generated";
indexer.name; // "my-indexer"
indexer.chainIds; // [1, 137]
indexer.chains[1].id; // 1
indexer.chains[1].name; // "ethereum"
indexer.chains[1].startBlock; // 0
indexer.chains[1].isLive; // false
indexer.chains[1].MyContract.name; // "MyContract"
indexer.chains[1].MyContract.addresses; // ["0x..."]
indexer.chains[1].MyContract.abi; // [...]
Entity IDs — prefer ${chainId}_${blockNumber}_${logIndex} as a unique ID:
const id = `${event.chainId}_${event.block.number}_${event.logIndex}`;
This is globally unique across chains and blocks. Use it as the default unless the entity is a singleton (e.g., a Token or Pool keyed by address).
Entity relationships — schema uses entity references; handlers use the _id suffix that codegen adds:
// Schema: token0: Token! ← entity reference, field name is "token0"
// Handler: { token0_id: token0.id } ← codegen adds _id; NEVER write "token0" here
// Schema: collection: NftCollection!
// Handler: { collection_id: collectionEntity.id }
// WRONG: { token0: token0.id } ← "token0" is not a valid TypeScript field
// WRONG: { collection_id: String! } in schema ← _id belongs in handlers, not schema
// CORRECT: { token0_id: token0.id } in handler
Optionals — string | undefined, not string | null
Decimal normalization — ALWAYS normalize when adding tokens with different decimals.
Schema & config — see indexing-schema and indexing-config skills for full reference.
Full reference: https://docs.envio.dev/docs/HyperIndex-LLM/hyperindex-complete