Skip to content

Commit 1f8b2af

Browse files
moose-codeclaude
andcommitted
chore: upgrade Envio HyperIndex to 3.3.0-alpha.4
Migrate from envio 3.0.0-alpha.20, which removed the `generated` package and the namespaced Contract.Event.handler() API. - Imports now resolve from `envio` (types wired via envio-env.d.ts + .envio/) - Handlers use indexer.onEvent({ contract, event }, fn) - Dynamic registration uses context.chain.CryptoPool.add() - Effect context typed as EvmOnEventContext - Tests migrated to createTestIndexer() + indexer.process({ simulate }) - Make startup RPC probe in effects.ts resilient to a missing dRPC key (CI and tests only provide ENVIO_API_TOKEN) - Drop obsolete optionalDependencies.generated; ignore .envio/cache - Refresh .claude/skills via `envio skills update` codegen + tsc --noEmit + vitest all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c72810c commit 1f8b2af

35 files changed

Lines changed: 994 additions & 2165 deletions

File tree

.claude/skills/envio-docs/SKILL.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
name: envio-docs
3+
description: >-
4+
Use when something is unclear, confusing, or not covered by other skills.
5+
Search and read the latest Envio documentation without leaving the terminal.
6+
metadata:
7+
managed-by: envio
8+
---
9+
10+
- `envio tools search-docs "<query>"` — find docs pages by keyword
11+
- `envio tools fetch-docs <url>` — read a page in full (use a URL from search results)
12+
- `envio --help` — list available CLI commands and flags
13+
14+
Example: `envio tools search-docs "schema derivedFrom"` → pick a URL → `envio tools fetch-docs <url>`
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
name: indexer-blocks
3+
description: >-
4+
Use when processing every block (or every Nth block) for time-series data,
5+
periodic snapshots, or block-level aggregations. indexer.onBlock API, where
6+
filter with block-number range and stride, and block handler context.
7+
metadata:
8+
managed-by: envio
9+
---
10+
11+
# Block Handlers
12+
13+
Process every block (or every Nth block) using `indexer.onBlock`. No contract
14+
address or `config.yaml` entry needed.
15+
16+
## Handler
17+
18+
Branch by `chain.id` with a `switch` so the type system flags any
19+
unconfigured chain via the `default: never` exhaustiveness check:
20+
21+
```ts
22+
import { indexer } from "envio";
23+
24+
indexer.onBlock(
25+
{
26+
name: "BlockTracker",
27+
where: ({ chain }) => {
28+
switch (chain.id) {
29+
case 1:
30+
return { block: { number: { _gte: 18000000, _every: 100 } } };
31+
case 8453:
32+
return { block: { number: { _every: 50 } } };
33+
default: {
34+
// Exhaustiveness check: TypeScript errors here if a new chain ID
35+
// is added to config.yaml but not handled above.
36+
const _exhaustive: never = chain.id;
37+
return false;
38+
}
39+
}
40+
},
41+
},
42+
async ({ block, context }) => {
43+
context.BlockSnapshot.set({
44+
id: `${block.number}`,
45+
blockNumber: BigInt(block.number),
46+
});
47+
}
48+
);
49+
```
50+
51+
## Options
52+
53+
| Option | Type | Required | Description |
54+
|--------|------|----------|-------------|
55+
| `name` | `string` | yes | Handler name for logging |
56+
| `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`. |
57+
58+
## Other ecosystems
59+
60+
- **Fuel**: same `indexer.onBlock` API; filter is keyed by `block.height` instead of `block.number`.
61+
- **SVM**: use `indexer.onSlot`; filter shape is `{slot: {_gte?, _lte?, _every?}}` and the handler arg is `{slot: number, context}` (no `block` wrapper).
62+
63+
## Notes
64+
65+
- `indexer.onBlock` self-registers — no `config.yaml` entry needed
66+
- No events or contract address required
67+
- The handler context has the same entity API as event handlers
68+
- If `where` returns `false` for every configured chain, a warning is logged at registration time
69+
- For per-event startBlock (not stride), use `indexer.onEvent` with `where.block.number._gte` (see `indexer-filters`). Event filters accept `_gte` only; `_lte`/`_every` are reserved for `onBlock`.
70+
71+
> If something is unclear, use the `envio-docs` skill to search and read the latest documentation.

.claude/skills/indexing-config/SKILL.md renamed to .claude/skills/indexer-configuration/SKILL.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
---
2-
name: indexing-config
2+
name: indexer-configuration
33
description: >-
44
Use when writing or editing config.yaml. Chain/contract structure, addresses,
55
start_block, event selection, field_selection, custom event names, env vars,
66
address_format, schema/output paths, YAML validation, and deprecated options.
7+
metadata:
8+
managed-by: envio
79
---
810

911
# Config Reference (config.yaml)
@@ -14,7 +16,6 @@ description: >-
1416
name: my-indexer
1517
description: Optional description
1618
schema: schema.graphql # custom path (default: schema.graphql)
17-
output: generated/ # custom output path (default: generated/)
1819
address_format: checksum # checksum (default) | lowercase
1920

2021
contracts:
@@ -51,7 +52,7 @@ Uses `chains` (not `networks`) and `max_reorg_depth` (not `confirmed_block_thres
5152
- name: Token
5253
# address omitted — indexes all matching events chain-wide
5354
54-
# Factory-registered — see indexing-factory skill
55+
# Factory-registered — see indexer-factory skill
5556
```
5657

5758
For proxied contracts, use the **proxy address** (where events emit), not the implementation.
@@ -110,18 +111,26 @@ contracts:
110111
- gasPrice
111112
```
112113

113-
Global `field_selection` is at the root level (sibling to `contracts` and `chains`). Per-event `field_selection` is directly under the event entry. See `indexing-transactions` skill for full field lists.
114+
Global `field_selection` is at the root level (sibling to `contracts` and `chains`). Per-event `field_selection` is directly under the event entry. See `indexer-transactions` skill for full field lists.
114115

115116
## Environment Variables
116117

117118
```yaml
118119
rpc:
119-
- url: ${RPC_URL} # required — errors if missing
120-
- url: ${RPC_URL:-http://localhost:8545} # with default value
120+
- url: ${ENVIO_RPC_URL} # required — errors if missing
121+
- url: ${ENVIO_RPC_URL:-http://localhost:8545} # with default value
121122
```
122123

123124
Works in any string value in config. Set via `.env` file or shell environment.
124125

126+
**IMPORTANT:** All environment variables MUST use the `ENVIO_` prefix (e.g., `ENVIO_RPC_URL`, not `RPC_URL`). The hosted service requires the `ENVIO_` prefix — variables without it will not be available at runtime.
127+
128+
## Runtime Environment Variables
129+
130+
Set on the indexer process (not interpolated into config.yaml):
131+
132+
- `ENVIO_TUI` — `true` forces the terminal UI on, `false` forces it off. Unset (default) auto-disables under agents, CI, and non-TTY stdout, so plain `pnpm dev` produces line-buffered output suitable for log capture without manual intervention.
133+
125134
## YAML Validation
126135

127136
Add at top of file for IDE schema validation:
@@ -140,8 +149,6 @@ Add at top of file for IDE schema validation:
140149

141150
## RPC Configuration
142151

143-
RPC tuning parameters are documented in the `indexing-performance` skill.
144-
145-
## Deep Documentation
152+
RPC tuning parameters are documented in the `indexer-performance` skill.
146153

147-
Full reference: https://docs.envio.dev/docs/HyperIndex-LLM/hyperindex-complete
154+
> If something is unclear, use the `envio-docs` skill to search and read the latest documentation.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
name: indexer-external-calls
3+
description: >-
4+
Use when making RPC calls, fetch requests, or any external I/O from handlers.
5+
Effect API with createEffect, S schema validation, context.effect(), preload
6+
optimization (handlers run twice), cache and rateLimit options.
7+
metadata:
8+
managed-by: envio
9+
---
10+
11+
# External Calls (Effect API)
12+
13+
Handlers run twice: parallel **preload pass** (warms caches), then **sequential pass** (state changes). All external I/O (fetch, RPC, APIs) MUST go through `createEffect` + `context.effect()` — otherwise it double-executes and blocks parallelization.
14+
15+
## Define and call
16+
17+
```ts
18+
import { S, createEffect } from "envio";
19+
20+
const getOwner = createEffect(
21+
{
22+
name: "getOwner",
23+
input: { tokenId: S.bigint },
24+
output: S.union([S.string, null]),
25+
cache: true,
26+
rateLimit: false,
27+
},
28+
async ({ input }) => {
29+
const res = await fetch(`https://api.example.com/owner/${input.tokenId}`);
30+
return res.json();
31+
}
32+
);
33+
34+
indexer.onEvent(
35+
{ contract: "Token", event: "Transfer" },
36+
async ({ event, context }) => {
37+
const owner = await context.effect(getOwner, { tokenId: event.params.tokenId });
38+
}
39+
);
40+
```
41+
42+
## Pass minimum input
43+
44+
`input` carries only what varies per call. Bake static config (URLs, tokens, channel IDs, env vars) into the effect body. Build payloads/strings inside the effect.
45+
46+
```ts
47+
// ❌ input: { url, chatId, text } — config and pre-built strings leak into the call site
48+
// ✅ input: { usd, blockNumber } — only the values that vary per call
49+
```
50+
51+
Dedup is keyed by hash of `input`; leaner inputs dedupe better, validate faster, and let one effect serve many call sites.
52+
53+
## Schema (`S`)
54+
55+
`S.string`, `S.number`, `S.bigint`, `S.boolean`, `S.schema({ ... })`, `S.array(...)`, `S.union([..., null])`, `S.optional(...)`.
56+
Full ref: https://raw.githubusercontent.com/DZakh/sury/refs/tags/v9.3.0/docs/js-usage.md
57+
58+
## RPC pattern (viem)
59+
60+
```ts
61+
const client = createPublicClient({ transport: http(process.env.ENVIO_RPC_URL) });
62+
63+
const getTokenMetadata = createEffect(
64+
{
65+
name: "getTokenMetadata",
66+
input: S.string,
67+
output: { name: S.string, symbol: S.string, decimals: S.number },
68+
cache: true,
69+
rateLimit: false,
70+
},
71+
async ({ input: address }) => {
72+
const args = { address: address as `0x${string}`, abi: ERC20_ABI };
73+
const [name, symbol, decimals] = await Promise.all([
74+
client.readContract({ ...args, functionName: "name" }),
75+
client.readContract({ ...args, functionName: "symbol" }),
76+
client.readContract({ ...args, functionName: "decimals" }),
77+
]);
78+
return { name, symbol, decimals: Number(decimals) };
79+
}
80+
);
81+
```
82+
83+
## Options
84+
85+
| Option | Type | Default |
86+
|---|---|---|
87+
| `name` | `string` ||
88+
| `input` | `S.Schema` ||
89+
| `output` | `S.Schema` ||
90+
| `cache` | `boolean` | `false` |
91+
| `rateLimit` | `false \| { calls, per }` | required |
92+
93+
> If something is unclear, use the `envio-docs` skill to search and read the latest documentation.
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
---
2-
name: indexing-factory
2+
name: indexer-factory
33
description: >-
44
Use when indexing contracts deployed by factory contracts at runtime.
55
contractRegister API, dynamic contract config (no address), async
66
registration, and same-block event coverage.
7+
metadata:
8+
managed-by: envio
79
---
810

911
# Factory / Dynamic Contracts
@@ -73,8 +75,6 @@ NftFactory.SimpleNftCreated.contractRegister(async ({ event, context }) => {
7375

7476
## Same-Block Coverage
7577

76-
When a dynamic contract is registered, HyperIndex indexes all events from that contract in the **same block** where it was created — even events from earlier transactions in that block.
78+
When a dynamic contract is registered, the Envio Indexer indexes all events from that contract in the **same block** where it was created — even events from earlier transactions in that block.
7779

78-
## Deep Documentation
79-
80-
Full reference: https://docs.envio.dev/docs/HyperIndex-LLM/hyperindex-complete
80+
> If something is unclear, use the `envio-docs` skill to search and read the latest documentation.

0 commit comments

Comments
 (0)