원클릭으로
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 — use _id suffix:
// WRONG: { token0: token0.id }
// CORRECT: { token0_id: token0.id }
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
Use when defining or editing schema.graphql. Entity types, scalar types, enums, relationships, @derivedFrom, @index, @config directives, array rules, naming conventions, and schema-to-TypeScript type mapping.
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.