envio 3.0.0-alpha.21 → 3.0.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/bin.mjs +2 -48
- package/evm.schema.json +67 -0
- package/fuel.schema.json +67 -0
- package/index.d.ts +822 -38
- package/index.js +5 -3
- package/package.json +10 -8
- package/rescript.json +5 -9
- package/src/Address.res +4 -5
- package/src/Address.res.mjs +9 -12
- package/src/Api.res +15 -0
- package/src/Api.res.mjs +20 -0
- package/src/Batch.res +32 -34
- package/src/Batch.res.mjs +172 -187
- package/src/Bin.res +89 -0
- package/src/Bin.res.mjs +97 -0
- package/src/ChainFetcher.res +33 -57
- package/src/ChainFetcher.res.mjs +197 -227
- package/src/ChainManager.res +6 -14
- package/src/ChainManager.res.mjs +74 -85
- package/src/ChainMap.res +14 -16
- package/src/ChainMap.res.mjs +38 -38
- package/src/Config.res +193 -135
- package/src/Config.res.mjs +566 -592
- package/src/Core.res +182 -0
- package/src/Core.res.mjs +207 -0
- package/src/Ecosystem.res +25 -4
- package/src/Ecosystem.res.mjs +12 -13
- package/src/Env.res +20 -13
- package/src/Env.res.mjs +124 -113
- package/src/EnvSafe.res +269 -0
- package/src/EnvSafe.res.mjs +296 -0
- package/src/EnvSafe.resi +18 -0
- package/src/Envio.res +37 -26
- package/src/Envio.res.mjs +59 -60
- package/src/ErrorHandling.res +2 -2
- package/src/ErrorHandling.res.mjs +15 -15
- package/src/EventConfigBuilder.res +219 -81
- package/src/EventConfigBuilder.res.mjs +259 -202
- package/src/EventProcessing.res +27 -38
- package/src/EventProcessing.res.mjs +165 -183
- package/src/EventUtils.res +11 -11
- package/src/EventUtils.res.mjs +21 -22
- package/src/EvmTypes.res +0 -1
- package/src/EvmTypes.res.mjs +5 -5
- package/src/FetchState.res +360 -256
- package/src/FetchState.res.mjs +958 -914
- package/src/GlobalState.res +365 -351
- package/src/GlobalState.res.mjs +958 -992
- package/src/GlobalStateManager.res +1 -2
- package/src/GlobalStateManager.res.mjs +36 -44
- package/src/HandlerLoader.res +107 -23
- package/src/HandlerLoader.res.mjs +128 -38
- package/src/HandlerRegister.res +127 -103
- package/src/HandlerRegister.res.mjs +164 -164
- package/src/HandlerRegister.resi +12 -4
- package/src/Hasura.res +35 -22
- package/src/Hasura.res.mjs +158 -167
- package/src/InMemoryStore.res +20 -27
- package/src/InMemoryStore.res.mjs +64 -80
- package/src/InMemoryTable.res +34 -39
- package/src/InMemoryTable.res.mjs +165 -170
- package/src/Internal.res +52 -33
- package/src/Internal.res.mjs +84 -81
- package/src/LazyLoader.res.mjs +55 -61
- package/src/LoadLayer.res +77 -78
- package/src/LoadLayer.res.mjs +160 -189
- package/src/LoadManager.res +16 -21
- package/src/LoadManager.res.mjs +79 -84
- package/src/LogSelection.res +236 -68
- package/src/LogSelection.res.mjs +211 -141
- package/src/Logging.res +13 -9
- package/src/Logging.res.mjs +130 -143
- package/src/Main.res +430 -51
- package/src/Main.res.mjs +530 -271
- package/src/Persistence.res +80 -84
- package/src/Persistence.res.mjs +131 -132
- package/src/PgStorage.res +294 -167
- package/src/PgStorage.res.mjs +799 -817
- package/src/Prometheus.res +50 -58
- package/src/Prometheus.res.mjs +345 -373
- package/src/ReorgDetection.res +22 -24
- package/src/ReorgDetection.res.mjs +100 -106
- package/src/SafeCheckpointTracking.res +7 -7
- package/src/SafeCheckpointTracking.res.mjs +40 -43
- package/src/SimulateItems.res +41 -49
- package/src/SimulateItems.res.mjs +257 -272
- package/src/Sink.res +2 -2
- package/src/Sink.res.mjs +22 -26
- package/src/TableIndices.res +1 -2
- package/src/TableIndices.res.mjs +42 -48
- package/src/TestIndexer.res +196 -189
- package/src/TestIndexer.res.mjs +536 -536
- package/src/TestIndexerProxyStorage.res +16 -16
- package/src/TestIndexerProxyStorage.res.mjs +99 -122
- package/src/TestIndexerWorker.res +4 -0
- package/src/TestIndexerWorker.res.mjs +7 -0
- package/src/Throttler.res +3 -3
- package/src/Throttler.res.mjs +23 -24
- package/src/Time.res +1 -1
- package/src/Time.res.mjs +18 -21
- package/src/TopicFilter.res +3 -3
- package/src/TopicFilter.res.mjs +29 -30
- package/src/UserContext.res +93 -54
- package/src/UserContext.res.mjs +197 -182
- package/src/Utils.res +141 -86
- package/src/Utils.res.mjs +334 -295
- package/src/bindings/BigDecimal.res +0 -2
- package/src/bindings/BigDecimal.res.mjs +19 -23
- package/src/bindings/ClickHouse.res +28 -27
- package/src/bindings/ClickHouse.res.mjs +243 -240
- package/src/bindings/DateFns.res +11 -11
- package/src/bindings/DateFns.res.mjs +7 -7
- package/src/bindings/EventSource.res.mjs +2 -2
- package/src/bindings/Express.res +2 -5
- package/src/bindings/Hrtime.res +2 -2
- package/src/bindings/Hrtime.res.mjs +30 -32
- package/src/bindings/Lodash.res.mjs +1 -1
- package/src/bindings/NodeJs.res +14 -9
- package/src/bindings/NodeJs.res.mjs +20 -20
- package/src/bindings/Pino.res +8 -10
- package/src/bindings/Pino.res.mjs +40 -43
- package/src/bindings/Postgres.res +7 -5
- package/src/bindings/Postgres.res.mjs +9 -9
- package/src/bindings/PromClient.res +17 -2
- package/src/bindings/PromClient.res.mjs +30 -7
- package/src/bindings/SDSL.res.mjs +2 -2
- package/src/bindings/Viem.res +4 -4
- package/src/bindings/Viem.res.mjs +20 -22
- package/src/bindings/Vitest.res +1 -1
- package/src/bindings/Vitest.res.mjs +2 -2
- package/src/bindings/WebSocket.res +1 -1
- package/src/db/EntityHistory.res +9 -3
- package/src/db/EntityHistory.res.mjs +84 -59
- package/src/db/InternalTable.res +62 -60
- package/src/db/InternalTable.res.mjs +271 -203
- package/src/db/Schema.res +1 -2
- package/src/db/Schema.res.mjs +28 -32
- package/src/db/Table.res +28 -27
- package/src/db/Table.res.mjs +276 -292
- package/src/sources/EventRouter.res +21 -16
- package/src/sources/EventRouter.res.mjs +55 -57
- package/src/sources/Evm.res +17 -1
- package/src/sources/Evm.res.mjs +16 -8
- package/src/sources/EvmChain.res +15 -17
- package/src/sources/EvmChain.res.mjs +40 -42
- package/src/sources/Fuel.res +14 -1
- package/src/sources/Fuel.res.mjs +16 -8
- package/src/sources/FuelSDK.res +1 -1
- package/src/sources/FuelSDK.res.mjs +6 -8
- package/src/sources/HyperFuel.res +8 -10
- package/src/sources/HyperFuel.res.mjs +113 -123
- package/src/sources/HyperFuelClient.res.mjs +6 -7
- package/src/sources/HyperFuelSource.res +19 -20
- package/src/sources/HyperFuelSource.res.mjs +339 -356
- package/src/sources/HyperSync.res +11 -13
- package/src/sources/HyperSync.res.mjs +206 -220
- package/src/sources/HyperSyncClient.res +5 -7
- package/src/sources/HyperSyncClient.res.mjs +70 -75
- package/src/sources/HyperSyncHeightStream.res +8 -9
- package/src/sources/HyperSyncHeightStream.res.mjs +78 -86
- package/src/sources/HyperSyncJsonApi.res +18 -15
- package/src/sources/HyperSyncJsonApi.res.mjs +201 -231
- package/src/sources/HyperSyncSource.res +17 -21
- package/src/sources/HyperSyncSource.res.mjs +268 -290
- package/src/sources/Rpc.res +5 -5
- package/src/sources/Rpc.res.mjs +168 -192
- package/src/sources/RpcSource.res +166 -167
- package/src/sources/RpcSource.res.mjs +972 -1046
- package/src/sources/RpcWebSocketHeightStream.res +10 -11
- package/src/sources/RpcWebSocketHeightStream.res.mjs +131 -145
- package/src/sources/SimulateSource.res +1 -1
- package/src/sources/SimulateSource.res.mjs +35 -38
- package/src/sources/Source.res +1 -1
- package/src/sources/Source.res.mjs +3 -3
- package/src/sources/SourceManager.res +39 -20
- package/src/sources/SourceManager.res.mjs +340 -371
- package/src/sources/SourceManager.resi +2 -1
- package/src/sources/Svm.res +12 -5
- package/src/sources/Svm.res.mjs +44 -41
- package/src/tui/Tui.res +23 -12
- package/src/tui/Tui.res.mjs +292 -290
- package/src/tui/bindings/Ink.res +2 -4
- package/src/tui/bindings/Ink.res.mjs +35 -41
- package/src/tui/components/BufferedProgressBar.res +7 -7
- package/src/tui/components/BufferedProgressBar.res.mjs +46 -46
- package/src/tui/components/CustomHooks.res +1 -2
- package/src/tui/components/CustomHooks.res.mjs +102 -122
- package/src/tui/components/Messages.res +1 -2
- package/src/tui/components/Messages.res.mjs +38 -42
- package/src/tui/components/SyncETA.res +10 -11
- package/src/tui/components/SyncETA.res.mjs +178 -196
- package/src/tui/components/TuiData.res +1 -1
- package/src/tui/components/TuiData.res.mjs +7 -6
- package/src/vendored/Rest.res +52 -66
- package/src/vendored/Rest.res.mjs +324 -364
- package/svm.schema.json +67 -0
- package/src/Address.gen.ts +0 -8
- package/src/Config.gen.ts +0 -19
- package/src/Envio.gen.ts +0 -55
- package/src/EvmTypes.gen.ts +0 -6
- package/src/InMemoryStore.gen.ts +0 -6
- package/src/Internal.gen.ts +0 -64
- package/src/PgStorage.gen.ts +0 -10
- package/src/PgStorage.res.d.mts +0 -5
- package/src/Types.ts +0 -56
- package/src/bindings/BigDecimal.gen.ts +0 -14
- package/src/bindings/BigDecimal.res.d.mts +0 -5
- package/src/bindings/BigInt.gen.ts +0 -10
- package/src/bindings/BigInt.res +0 -70
- package/src/bindings/BigInt.res.d.mts +0 -5
- package/src/bindings/BigInt.res.mjs +0 -154
- package/src/bindings/Ethers.res.d.mts +0 -5
- package/src/bindings/Pino.gen.ts +0 -17
- package/src/bindings/Postgres.gen.ts +0 -8
- package/src/bindings/Postgres.res.d.mts +0 -5
- package/src/bindings/Promise.res +0 -67
- package/src/bindings/Promise.res.mjs +0 -26
- package/src/db/InternalTable.gen.ts +0 -36
- package/src/sources/HyperSyncClient.gen.ts +0 -19
package/index.d.ts
CHANGED
|
@@ -1,19 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import * as Sury from "rescript-schema";
|
|
2
|
+
import type { default as BigDecimalT } from "bignumber.js";
|
|
3
|
+
export { default as BigDecimal } from "bignumber.js";
|
|
4
|
+
|
|
5
|
+
// Runtime value stubs used by the `S.*` namespace declarations further down
|
|
6
|
+
// so the exported `S.bigDecimal` / `S.bigint` consts pick up typed schemas.
|
|
7
|
+
// The implementations live in `index.js`, sourced from `.res.mjs` compiled
|
|
8
|
+
// output.
|
|
9
|
+
declare const bigDecimalSchema: Sury.Schema<BigDecimalT>;
|
|
10
|
+
declare const bigintSchema: Sury.Schema<bigint>;
|
|
11
|
+
|
|
12
|
+
/** Ethereum address — a 20-byte hex string prefixed with `0x`. */
|
|
13
|
+
export type Address = `0x${string}`;
|
|
14
|
+
|
|
15
|
+
/** Structured logger bound to an event or handler context. Messages are
|
|
16
|
+
* displayed in the console and the Envio Hosted Service. */
|
|
17
|
+
export type Logger = {
|
|
18
|
+
readonly debug: (
|
|
19
|
+
message: string,
|
|
20
|
+
params?: Record<string, unknown> | Error
|
|
21
|
+
) => void;
|
|
22
|
+
readonly info: (
|
|
23
|
+
message: string,
|
|
24
|
+
params?: Record<string, unknown> | Error
|
|
25
|
+
) => void;
|
|
26
|
+
readonly warn: (
|
|
27
|
+
message: string,
|
|
28
|
+
params?: Record<string, unknown> | Error
|
|
29
|
+
) => void;
|
|
30
|
+
readonly error: (
|
|
31
|
+
message: string,
|
|
32
|
+
params?: Record<string, unknown> | Error
|
|
33
|
+
) => void;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Handle for an external-call effect created via {@link createEffect}.
|
|
37
|
+
* Effects provide automatic deduplication, error handling, and caching. */
|
|
38
|
+
export declare abstract class Effect<I, O> {
|
|
39
|
+
protected opaque: I | O;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Calls an {@link Effect} with the given input and returns its output. */
|
|
43
|
+
export type EffectCaller = <I, O>(
|
|
44
|
+
effect: Effect<I, O>,
|
|
45
|
+
// This is a hack to make the call complain on undefined
|
|
46
|
+
// when it's not needed, instead of extending the input type.
|
|
47
|
+
// Might be not needed if I misunderstand something in TS.
|
|
48
|
+
input: I extends undefined ? undefined : I
|
|
49
|
+
) => Promise<O>;
|
|
50
|
+
|
|
51
|
+
/** Context passed to an Effect's handler function. */
|
|
52
|
+
export type EffectContext = {
|
|
53
|
+
/** Access the logger instance with the event as context. */
|
|
54
|
+
readonly log: Logger;
|
|
55
|
+
/** Call another Effect from inside this one. */
|
|
56
|
+
readonly effect: EffectCaller;
|
|
57
|
+
/** Whether to cache this call's result. Defaults to the effect's `cache`
|
|
58
|
+
* option; set to `false` to skip caching for this specific invocation. */
|
|
59
|
+
cache: boolean;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/** Rate-limit window for an {@link Effect}. Strings resolve to common
|
|
63
|
+
* durations; a plain `number` is treated as milliseconds. */
|
|
64
|
+
export type RateLimitDuration = "second" | "minute" | number;
|
|
65
|
+
|
|
66
|
+
/** Rate-limit configuration for an {@link Effect}. `false` disables rate
|
|
67
|
+
* limiting; otherwise a `{calls, per}` pair caps invocations per duration. */
|
|
68
|
+
export type RateLimit =
|
|
69
|
+
| false
|
|
70
|
+
| { readonly calls: number; readonly per: RateLimitDuration };
|
|
71
|
+
|
|
72
|
+
/** Options accepted by {@link createEffect}. */
|
|
73
|
+
export type EffectOptions<Input, Output> = {
|
|
74
|
+
/** The name of the effect. Used for logging and debugging. */
|
|
75
|
+
readonly name: string;
|
|
76
|
+
/** The input schema of the effect. */
|
|
77
|
+
readonly input: Sury.Schema<Input>;
|
|
78
|
+
/** The output schema of the effect. */
|
|
79
|
+
readonly output: Sury.Schema<Output>;
|
|
80
|
+
/** Rate limit for the effect. Set to `false` to disable or provide
|
|
81
|
+
* `{calls, per: "second" | "minute"}` to enable. */
|
|
82
|
+
readonly rateLimit: RateLimit;
|
|
83
|
+
/** Whether the effect should be cached. */
|
|
84
|
+
readonly cache?: boolean;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/** Arguments passed to the handler function of an {@link Effect}. */
|
|
88
|
+
export type EffectArgs<Input> = {
|
|
89
|
+
readonly input: Input;
|
|
90
|
+
readonly context: EffectContext;
|
|
91
|
+
};
|
|
17
92
|
|
|
18
93
|
export const TestHelpers: {
|
|
19
94
|
Addresses: {
|
|
@@ -60,16 +135,6 @@ export type GetWhereFilter<E> = {
|
|
|
60
135
|
[K in keyof E]?: WhereOperator<E[K]>;
|
|
61
136
|
};
|
|
62
137
|
|
|
63
|
-
import type {
|
|
64
|
-
effect as Effect,
|
|
65
|
-
effectArgs as EffectArgs,
|
|
66
|
-
rateLimit as RateLimit,
|
|
67
|
-
} from "./src/Envio.gen.ts";
|
|
68
|
-
|
|
69
|
-
import { schema as bigDecimalSchema } from "./src/bindings/BigDecimal.gen.ts";
|
|
70
|
-
import { schema as bigintSchema } from "./src/bindings/BigInt.gen.ts";
|
|
71
|
-
import * as Sury from "rescript-schema";
|
|
72
|
-
|
|
73
138
|
type UnknownToOutput<T> = T extends Sury.Schema<unknown>
|
|
74
139
|
? Sury.Output<T>
|
|
75
140
|
: T extends (...args: any[]) => any
|
|
@@ -180,7 +245,9 @@ export declare namespace S {
|
|
|
180
245
|
export const tuple: typeof Sury.tuple;
|
|
181
246
|
export const merge: typeof Sury.merge;
|
|
182
247
|
export const optional: typeof Sury.optional;
|
|
183
|
-
export
|
|
248
|
+
export function nullable<Output, Input>(
|
|
249
|
+
schema: Sury.Schema<Output, Input>
|
|
250
|
+
): Sury.Schema<Output | null, Input | null>;
|
|
184
251
|
export const bigDecimal: typeof bigDecimalSchema;
|
|
185
252
|
export const unknown: typeof Sury.unknown;
|
|
186
253
|
// Nullish type will change in "sury@10"
|
|
@@ -206,9 +273,11 @@ export declare namespace S {
|
|
|
206
273
|
export interface Global {}
|
|
207
274
|
|
|
208
275
|
/**
|
|
209
|
-
* Shape of the indexer configuration.
|
|
210
|
-
*
|
|
211
|
-
*
|
|
276
|
+
* Shape of the indexer configuration used internally for defineConfig.
|
|
277
|
+
* This models only the subset of fields defineConfig consumes; the JSON
|
|
278
|
+
* emitted by `envio config view` is a superset (enums, entities, per-chain
|
|
279
|
+
* sources, event metadata, EVM global field selections, and other
|
|
280
|
+
* serializer-only fields are intentionally omitted here).
|
|
212
281
|
*/
|
|
213
282
|
type IndexerConfig = {
|
|
214
283
|
/** The indexer name. */
|
|
@@ -391,15 +460,467 @@ type IndexerConfigTypes = {
|
|
|
391
460
|
evm?: {
|
|
392
461
|
chains: Record<string, { id: number }>;
|
|
393
462
|
contracts?: Record<string, Record<string, { eventName: string }>>;
|
|
463
|
+
eventFilters?: Record<string, Record<string, { readonly params: object }>>;
|
|
394
464
|
};
|
|
395
465
|
fuel?: {
|
|
396
466
|
chains: Record<string, { id: number }>;
|
|
397
467
|
contracts?: Record<string, Record<string, { eventName: string }>>;
|
|
468
|
+
eventFilters?: Record<string, Record<string, { readonly params: object }>>;
|
|
398
469
|
};
|
|
399
470
|
svm?: { chains: Record<string, { id: number }> };
|
|
400
471
|
entities?: Record<string, object>;
|
|
401
472
|
};
|
|
402
473
|
|
|
474
|
+
// ============== onEvent / contractRegister Types ==============
|
|
475
|
+
|
|
476
|
+
// Extract contracts type from config
|
|
477
|
+
type EvmContracts<Config extends IndexerConfigTypes> =
|
|
478
|
+
Config["evm"] extends { contracts: infer C extends Record<string, Record<string, any>> }
|
|
479
|
+
? C : {};
|
|
480
|
+
|
|
481
|
+
type FuelContracts<Config extends IndexerConfigTypes> =
|
|
482
|
+
Config["fuel"] extends { contracts: infer C extends Record<string, Record<string, any>> }
|
|
483
|
+
? C : {};
|
|
484
|
+
|
|
485
|
+
// Extract eventFilters type from config — a sibling lookup table that maps
|
|
486
|
+
// contract+event to the `where` filter shape `{ params: { ... } }`. Split
|
|
487
|
+
// out from `EvmContracts` so per-event entries stay focused on the event
|
|
488
|
+
// payload and keep the two lookup tables independently composable.
|
|
489
|
+
type EvmEventFilters<Config extends IndexerConfigTypes> =
|
|
490
|
+
Config["evm"] extends { eventFilters: infer F extends Record<string, Record<string, any>> }
|
|
491
|
+
? F : {};
|
|
492
|
+
|
|
493
|
+
type FuelEventFilters<Config extends IndexerConfigTypes> =
|
|
494
|
+
Config["fuel"] extends { eventFilters: infer F extends Record<string, Record<string, any>> }
|
|
495
|
+
? F : {};
|
|
496
|
+
|
|
497
|
+
// Extract contract names for contract registration
|
|
498
|
+
type EvmContractNames<Config extends IndexerConfigTypes> =
|
|
499
|
+
Config["evm"] extends { contracts: Record<infer N, any> } ? N & string : never;
|
|
500
|
+
|
|
501
|
+
type FuelContractNames<Config extends IndexerConfigTypes> =
|
|
502
|
+
Config["fuel"] extends { contracts: Record<infer N, any> } ? N & string : never;
|
|
503
|
+
|
|
504
|
+
/** Event identity for onEvent/contractRegister calls. */
|
|
505
|
+
type EventIdentity<
|
|
506
|
+
Contracts extends Record<string, Record<string, any>>,
|
|
507
|
+
C extends keyof Contracts = keyof Contracts,
|
|
508
|
+
E extends keyof Contracts[C] & string = keyof Contracts[C] & string
|
|
509
|
+
> = {
|
|
510
|
+
/** The contract name as defined in config.yaml. */
|
|
511
|
+
readonly contract: C;
|
|
512
|
+
/** The event name as defined in the contract ABI. */
|
|
513
|
+
readonly event: E;
|
|
514
|
+
/** Whether to process all events (wildcard mode). */
|
|
515
|
+
readonly wildcard?: boolean;
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Shared shape for handler contexts across ecosystems — logger, effect
|
|
520
|
+
* caller, preload flag, chain state, and the entity operations map derived
|
|
521
|
+
* from the project schema.
|
|
522
|
+
*/
|
|
523
|
+
type BaseHandlerContext<Config extends IndexerConfigTypes, ChainId> = {
|
|
524
|
+
/** Access the logger instance. */
|
|
525
|
+
readonly log: Logger;
|
|
526
|
+
/** Call an Effect with the given input. */
|
|
527
|
+
readonly effect: EffectCaller;
|
|
528
|
+
/** True when running in preload mode (parallel pre-run for cache population). */
|
|
529
|
+
readonly isPreload: boolean;
|
|
530
|
+
/** Chain state for the current event's chain. */
|
|
531
|
+
readonly chain: {
|
|
532
|
+
readonly id: ChainId;
|
|
533
|
+
readonly isLive: boolean;
|
|
534
|
+
};
|
|
535
|
+
} & {
|
|
536
|
+
readonly [K in keyof ConfigEntities<Config>]: EntityOperations<ConfigEntities<Config>[K]>;
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
/** Context for onEvent handlers. Includes entity operations, logging, and chain info. */
|
|
540
|
+
export type EvmOnEventContext<Config extends IndexerConfigTypes> = Prettify<
|
|
541
|
+
BaseHandlerContext<Config, EvmChainIds<Config>>
|
|
542
|
+
>;
|
|
543
|
+
|
|
544
|
+
/** Context for onEvent handlers in Fuel ecosystem. */
|
|
545
|
+
export type FuelOnEventContext<Config extends IndexerConfigTypes> = Prettify<
|
|
546
|
+
BaseHandlerContext<Config, FuelChainIds<Config>>
|
|
547
|
+
>;
|
|
548
|
+
|
|
549
|
+
/** Context for `indexer.onSlot` handlers in SVM ecosystem. */
|
|
550
|
+
export type SvmOnSlotContext<Config extends IndexerConfigTypes> = Prettify<
|
|
551
|
+
BaseHandlerContext<Config, SvmChainIds<Config>>
|
|
552
|
+
>;
|
|
553
|
+
|
|
554
|
+
/** Entity operations available in handler contexts. */
|
|
555
|
+
type EntityOperations<Entity> = {
|
|
556
|
+
readonly get: (id: string) => Promise<Entity | undefined>;
|
|
557
|
+
readonly getOrThrow: (id: string, message?: string) => Promise<Entity>;
|
|
558
|
+
readonly getWhere: (filter: GetWhereFilter<Entity>) => Promise<Entity[]>;
|
|
559
|
+
readonly getOrCreate: (entity: Entity) => Promise<Entity>;
|
|
560
|
+
readonly set: (entity: Entity) => void;
|
|
561
|
+
readonly deleteUnsafe: (id: string) => void;
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
/** Contract registration handle. */
|
|
565
|
+
type ContractRegistration = {
|
|
566
|
+
/** Register a new contract address for dynamic indexing. */
|
|
567
|
+
readonly add: (address: Address) => void;
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
/** Context for contractRegister handlers. Chain object includes contract registration methods.
|
|
571
|
+
* `isLive` is intentionally absent: contract registration runs during historical sync,
|
|
572
|
+
* so the "live" distinction isn't meaningful and the runtime does not expose it. */
|
|
573
|
+
export type EvmContractRegisterContext<Config extends IndexerConfigTypes> = Prettify<{
|
|
574
|
+
readonly log: Logger;
|
|
575
|
+
readonly chain: {
|
|
576
|
+
readonly id: EvmChainIds<Config>;
|
|
577
|
+
} & {
|
|
578
|
+
readonly [K in EvmContractNames<Config>]: ContractRegistration;
|
|
579
|
+
};
|
|
580
|
+
}>;
|
|
581
|
+
|
|
582
|
+
/** Context for contractRegister handlers in Fuel ecosystem. `isLive` is intentionally
|
|
583
|
+
* absent — see EvmContractRegisterContext. */
|
|
584
|
+
export type FuelContractRegisterContext<Config extends IndexerConfigTypes> = Prettify<{
|
|
585
|
+
readonly log: Logger;
|
|
586
|
+
readonly chain: {
|
|
587
|
+
readonly id: FuelChainIds<Config>;
|
|
588
|
+
} & {
|
|
589
|
+
readonly [K in FuelContractNames<Config>]: ContractRegistration;
|
|
590
|
+
};
|
|
591
|
+
}>;
|
|
592
|
+
|
|
593
|
+
// ============== onEvent / contractRegister Named Types ==============
|
|
594
|
+
|
|
595
|
+
/** Constraint: any event must have literal contractName and eventName fields. */
|
|
596
|
+
type EventLike = { readonly contractName: string; readonly eventName: string };
|
|
597
|
+
|
|
598
|
+
/** Scalar value or array of values — used by event filter fields to accept either a
|
|
599
|
+
* single topic or multiple alternatives (OR semantics). */
|
|
600
|
+
export type SingleOrMultiple<T> = T | readonly T[];
|
|
601
|
+
|
|
602
|
+
/** EVM event type resolved by contract and event name. Union of all events when no generics provided.
|
|
603
|
+
* The mapped form distributes `K in C` so disjoint event sets across contracts survive — using
|
|
604
|
+
* `EvmContracts<Config>[C][E]` directly would collapse to keys common to *all* contracts (often `never`). */
|
|
605
|
+
export type EvmOnEvent<
|
|
606
|
+
Config extends IndexerConfigTypes,
|
|
607
|
+
C extends keyof EvmContracts<Config> = keyof EvmContracts<Config>,
|
|
608
|
+
E extends string = string
|
|
609
|
+
> = {
|
|
610
|
+
[K in C]: EvmContracts<Config>[K][E & keyof EvmContracts<Config>[K]];
|
|
611
|
+
}[C];
|
|
612
|
+
|
|
613
|
+
/** The chain object passed into the EVM dynamic `where` callback form. Exposes
|
|
614
|
+
* the chain `id` and the event's own contract under its capitalized name,
|
|
615
|
+
* with `addresses` listing the indexed contract addresses on this chain.
|
|
616
|
+
*
|
|
617
|
+
* Only the event's own contract is exposed — multi-contract address
|
|
618
|
+
* filtering is not supported in this iteration. */
|
|
619
|
+
export type EvmOnEventWhereChain<ContractName extends string> = {
|
|
620
|
+
readonly id: number;
|
|
621
|
+
} & {
|
|
622
|
+
readonly [K in ContractName]: { readonly addresses: readonly Address[] };
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
/** Arguments passed to the EVM dynamic `where` callback form. Return an
|
|
626
|
+
* `EvmOnEventWhereFilter` to apply a filter, or `true` / `false` to keep / skip
|
|
627
|
+
* all events for that invocation. */
|
|
628
|
+
export type EvmOnEventWhereArgs<ContractName extends string> = {
|
|
629
|
+
readonly chain: EvmOnEventWhereChain<ContractName>;
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
/** A single EVM `where` filter condition. `params` accepts either a single
|
|
633
|
+
* AND-conjunction of indexed-parameter narrowings, or an array of them (OR
|
|
634
|
+
* semantics). `block.number._gte` promotes to the event's startBlock and
|
|
635
|
+
* overrides the contract-level `start_block` — use it to restrict per-event
|
|
636
|
+
* processing without touching `config.yaml`. Only `_gte` is supported on
|
|
637
|
+
* event filters; use `indexer.onBlock` for `_lte` / `_every`. */
|
|
638
|
+
export type EvmOnEventWhereFilter<Params> = {
|
|
639
|
+
readonly params?: Params | readonly Params[];
|
|
640
|
+
readonly block?: {
|
|
641
|
+
readonly number?: {
|
|
642
|
+
readonly _gte?: number;
|
|
643
|
+
};
|
|
644
|
+
};
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
/** The `where` option value of `indexer.onEvent` / `indexer.contractRegister`
|
|
648
|
+
* in the EVM ecosystem.
|
|
649
|
+
*
|
|
650
|
+
* TypeScript accepts either a static filter object or a dynamic callback.
|
|
651
|
+
* The dynamic callback may return a boolean to keep (`true`) or skip (`false`)
|
|
652
|
+
* all events on that invocation, or an `EvmOnEventWhereFilter` for narrowing.
|
|
653
|
+
*
|
|
654
|
+
* The ReScript surface only exposes the callback form — multi-condition OR
|
|
655
|
+
* semantics are always expressed via an array on `params`, not at the top
|
|
656
|
+
* level of `where`. */
|
|
657
|
+
export type EvmOnEventWhere<Params, ContractName extends string> =
|
|
658
|
+
| EvmOnEventWhereFilter<Params>
|
|
659
|
+
| ((args: EvmOnEventWhereArgs<ContractName>) => EvmOnEventWhereFilter<Params> | boolean);
|
|
660
|
+
|
|
661
|
+
/** The chain object passed into the Fuel dynamic `where` callback form. */
|
|
662
|
+
export type FuelOnEventWhereChain<ContractName extends string> = EvmOnEventWhereChain<ContractName>;
|
|
663
|
+
/** Arguments passed to the Fuel dynamic `where` callback form. */
|
|
664
|
+
export type FuelOnEventWhereArgs<ContractName extends string> = EvmOnEventWhereArgs<ContractName>;
|
|
665
|
+
/** A single Fuel `where` filter condition. Keyed on `block.height` instead
|
|
666
|
+
* of `block.number`. */
|
|
667
|
+
export type FuelOnEventWhereFilter<Params> = {
|
|
668
|
+
readonly params?: Params | readonly Params[];
|
|
669
|
+
readonly block?: {
|
|
670
|
+
readonly height?: {
|
|
671
|
+
readonly _gte?: number;
|
|
672
|
+
};
|
|
673
|
+
};
|
|
674
|
+
};
|
|
675
|
+
/** The `where` option value of `indexer.onEvent` / `indexer.contractRegister` in the Fuel ecosystem. */
|
|
676
|
+
export type FuelOnEventWhere<Params, ContractName extends string> =
|
|
677
|
+
| FuelOnEventWhereFilter<Params>
|
|
678
|
+
| ((args: FuelOnEventWhereArgs<ContractName>) => FuelOnEventWhereFilter<Params> | boolean);
|
|
679
|
+
|
|
680
|
+
/** Options for registering an EVM onEvent handler. Contract and event literal names are derived from the Event type.
|
|
681
|
+
* The conditional `Event extends EventLike` distributes over union members so that each member's
|
|
682
|
+
* contractName/eventName pair is constrained together — preventing invalid cross-member pairings.
|
|
683
|
+
* The `Params` generic carries the indexed-parameter shape (looked up via `EvmEventFilters[C][E]["params"]`
|
|
684
|
+
* by callers) so the `where` option enforces the same per-event narrowing as the inline handler signature. */
|
|
685
|
+
export type EvmOnEventOptions<Event extends EventLike, Params = {}> = Event extends EventLike
|
|
686
|
+
? {
|
|
687
|
+
readonly contract: Event["contractName"];
|
|
688
|
+
readonly event: Event["eventName"];
|
|
689
|
+
readonly wildcard?: boolean;
|
|
690
|
+
readonly where?: EvmOnEventWhere<Params, Event["contractName"] & string>;
|
|
691
|
+
}
|
|
692
|
+
: never;
|
|
693
|
+
|
|
694
|
+
/** Handler function for an EVM onEvent registration. Context is provided as a separate generic so the project alias can bind it. */
|
|
695
|
+
export type EvmOnEventHandler<Event extends EventLike, Context> = (args: {
|
|
696
|
+
event: Event;
|
|
697
|
+
context: Context;
|
|
698
|
+
}) => Promise<void>;
|
|
699
|
+
|
|
700
|
+
/** Options for registering an EVM contractRegister handler. Same shape as EvmOnEventOptions. */
|
|
701
|
+
export type EvmContractRegisterOptions<Event extends EventLike, Params = {}> = EvmOnEventOptions<
|
|
702
|
+
Event,
|
|
703
|
+
Params
|
|
704
|
+
>;
|
|
705
|
+
|
|
706
|
+
/** Handler function for an EVM contractRegister registration. */
|
|
707
|
+
export type EvmContractRegisterHandler<Event extends EventLike, Context> = EvmOnEventHandler<Event, Context>;
|
|
708
|
+
|
|
709
|
+
/** Fuel event type resolved by contract and event name. Same distributive-mapped pattern as `EvmOnEvent`. */
|
|
710
|
+
export type FuelOnEvent<
|
|
711
|
+
Config extends IndexerConfigTypes,
|
|
712
|
+
C extends keyof FuelContracts<Config> = keyof FuelContracts<Config>,
|
|
713
|
+
E extends string = string
|
|
714
|
+
> = {
|
|
715
|
+
[K in C]: FuelContracts<Config>[K][E & keyof FuelContracts<Config>[K]];
|
|
716
|
+
}[C];
|
|
717
|
+
|
|
718
|
+
/** Options for registering a Fuel onEvent handler. */
|
|
719
|
+
export type FuelOnEventOptions<Event extends EventLike, Params = {}> = EvmOnEventOptions<
|
|
720
|
+
Event,
|
|
721
|
+
Params
|
|
722
|
+
>;
|
|
723
|
+
|
|
724
|
+
/** Handler function for a Fuel onEvent registration. */
|
|
725
|
+
export type FuelOnEventHandler<Event extends EventLike, Context> = EvmOnEventHandler<Event, Context>;
|
|
726
|
+
|
|
727
|
+
/** Options for registering a Fuel contractRegister handler. */
|
|
728
|
+
export type FuelContractRegisterOptions<Event extends EventLike, Params = {}> = EvmOnEventOptions<
|
|
729
|
+
Event,
|
|
730
|
+
Params
|
|
731
|
+
>;
|
|
732
|
+
|
|
733
|
+
/** Handler function for a Fuel contractRegister registration. */
|
|
734
|
+
export type FuelContractRegisterHandler<Event extends EventLike, Context> = EvmOnEventHandler<Event, Context>;
|
|
735
|
+
|
|
736
|
+
// ============== EVM onBlock types ==============
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Structured filter object returned by an EVM `indexer.onBlock` `where`
|
|
740
|
+
* predicate. `_every` alignment is relative to `_gte` (or the chain's
|
|
741
|
+
* configured `startBlock` when `_gte` is omitted), preserving
|
|
742
|
+
* `(blockNumber - startBlock) % _every === 0`.
|
|
743
|
+
*/
|
|
744
|
+
export type EvmOnBlockFilter = {
|
|
745
|
+
readonly block?: {
|
|
746
|
+
readonly number?: {
|
|
747
|
+
/** Matches blocks whose number is greater than or equal to the given value. */
|
|
748
|
+
readonly _gte?: number;
|
|
749
|
+
/** Matches blocks whose number is less than or equal to the given value. */
|
|
750
|
+
readonly _lte?: number;
|
|
751
|
+
/** Match every Nth block. Alignment is relative to `_gte`. */
|
|
752
|
+
readonly _every?: number;
|
|
753
|
+
};
|
|
754
|
+
};
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Return type of an EVM `indexer.onBlock` `where` predicate. The predicate
|
|
759
|
+
* must explicitly return — an implicit `undefined` is not accepted.
|
|
760
|
+
* - `false` → skip this chain entirely.
|
|
761
|
+
* - `true` → register on the chain with no extra filter.
|
|
762
|
+
* - {@link EvmOnBlockFilter} → register with the given range/stride.
|
|
763
|
+
*/
|
|
764
|
+
export type EvmOnBlockWhereResult = boolean | EvmOnBlockFilter;
|
|
765
|
+
|
|
766
|
+
/** Argument passed to an EVM `indexer.onBlock` `where` predicate. */
|
|
767
|
+
export type EvmOnBlockWhereArgs<Config extends IndexerConfigTypes> = {
|
|
768
|
+
/** Configured chain being evaluated. Use `chain.id` to branch per chain. */
|
|
769
|
+
readonly chain: EvmChain<EvmChainIds<Config>, EvmContractNames<Config>>;
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
/** Context for EVM `indexer.onBlock` handlers. Alias of {@link EvmOnEventContext}. */
|
|
773
|
+
export type EvmOnBlockContext<Config extends IndexerConfigTypes> = EvmOnEventContext<Config>;
|
|
774
|
+
|
|
775
|
+
/** Arguments passed to an EVM block handler. */
|
|
776
|
+
export type EvmOnBlockHandlerArgs<Config extends IndexerConfigTypes> = {
|
|
777
|
+
/** Block being processed. Contains the block number; extended fields are
|
|
778
|
+
opt-in via `field_selection` in config.yaml. */
|
|
779
|
+
readonly block: { readonly number: number };
|
|
780
|
+
/** Handler context: entity operations, logger, effect caller, chain state. */
|
|
781
|
+
readonly context: EvmOnBlockContext<Config>;
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
/** Handler function for an EVM `indexer.onBlock` registration. */
|
|
785
|
+
export type EvmOnBlockHandler<Config extends IndexerConfigTypes> = (
|
|
786
|
+
args: EvmOnBlockHandlerArgs<Config>,
|
|
787
|
+
) => Promise<void>;
|
|
788
|
+
|
|
789
|
+
/** Options for an EVM `indexer.onBlock` registration. */
|
|
790
|
+
export type EvmOnBlockOptions<Config extends IndexerConfigTypes> = {
|
|
791
|
+
/** Unique name for this block handler. Used as the key in error messages
|
|
792
|
+
and in persisted progress tracking. */
|
|
793
|
+
readonly name: string;
|
|
794
|
+
/** Optional predicate evaluated once per configured chain at registration
|
|
795
|
+
time. Return `false` to skip a chain, `true` to match every block, or
|
|
796
|
+
a filter object to restrict by block number range and stride. */
|
|
797
|
+
readonly where?: (args: EvmOnBlockWhereArgs<Config>) => EvmOnBlockWhereResult;
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
// ============== Fuel onBlock types ==============
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* Structured filter object returned by a Fuel `indexer.onBlock` `where`
|
|
804
|
+
* predicate. `_every` alignment is relative to `_gte` (or the chain's
|
|
805
|
+
* configured `startBlock` when `_gte` is omitted), preserving
|
|
806
|
+
* `(blockNumber - startBlock) % _every === 0`.
|
|
807
|
+
*/
|
|
808
|
+
export type FuelOnBlockFilter = {
|
|
809
|
+
readonly block?: {
|
|
810
|
+
readonly height?: {
|
|
811
|
+
/** Matches blocks whose height is greater than or equal to the given value. */
|
|
812
|
+
readonly _gte?: number;
|
|
813
|
+
/** Matches blocks whose height is less than or equal to the given value. */
|
|
814
|
+
readonly _lte?: number;
|
|
815
|
+
/** Match every Nth block. Alignment is relative to `_gte`. */
|
|
816
|
+
readonly _every?: number;
|
|
817
|
+
};
|
|
818
|
+
};
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Return type of a Fuel `indexer.onBlock` `where` predicate. The predicate
|
|
823
|
+
* must explicitly return — an implicit `undefined` is not accepted.
|
|
824
|
+
* - `false` → skip this chain.
|
|
825
|
+
* - `true` → register on the chain with no extra filter.
|
|
826
|
+
* - {@link FuelOnBlockFilter} → register with the given range/stride.
|
|
827
|
+
*/
|
|
828
|
+
export type FuelOnBlockWhereResult = boolean | FuelOnBlockFilter;
|
|
829
|
+
|
|
830
|
+
/** Argument passed to a Fuel `indexer.onBlock` `where` predicate. */
|
|
831
|
+
export type FuelOnBlockWhereArgs<Config extends IndexerConfigTypes> = {
|
|
832
|
+
/** Configured chain being evaluated. Use `chain.id` to branch per chain. */
|
|
833
|
+
readonly chain: FuelChain<FuelChainIds<Config>, FuelContractNames<Config>>;
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
/** Context for Fuel `indexer.onBlock` handlers. Alias of {@link FuelOnEventContext}. */
|
|
837
|
+
export type FuelOnBlockContext<Config extends IndexerConfigTypes> = FuelOnEventContext<Config>;
|
|
838
|
+
|
|
839
|
+
/** Arguments passed to a Fuel block handler. */
|
|
840
|
+
export type FuelOnBlockHandlerArgs<Config extends IndexerConfigTypes> = {
|
|
841
|
+
/** Block being processed. Contains the block height; extended fields are
|
|
842
|
+
opt-in via `field_selection` in config.yaml. */
|
|
843
|
+
readonly block: { readonly height: number };
|
|
844
|
+
/** Handler context: entity operations, logger, effect caller, chain state. */
|
|
845
|
+
readonly context: FuelOnBlockContext<Config>;
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
/** Handler function for a Fuel `indexer.onBlock` registration. */
|
|
849
|
+
export type FuelOnBlockHandler<Config extends IndexerConfigTypes> = (
|
|
850
|
+
args: FuelOnBlockHandlerArgs<Config>,
|
|
851
|
+
) => Promise<void>;
|
|
852
|
+
|
|
853
|
+
/** Options for a Fuel `indexer.onBlock` registration. */
|
|
854
|
+
export type FuelOnBlockOptions<Config extends IndexerConfigTypes> = {
|
|
855
|
+
/** Unique name for this block handler. Used as the key in error messages
|
|
856
|
+
and in persisted progress tracking. */
|
|
857
|
+
readonly name: string;
|
|
858
|
+
/** Optional predicate evaluated once per configured chain at registration
|
|
859
|
+
time. Return `false` to skip a chain, `true` to match every block, or
|
|
860
|
+
a filter object to restrict by block height range and stride. */
|
|
861
|
+
readonly where?: (args: FuelOnBlockWhereArgs<Config>) => FuelOnBlockWhereResult;
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
// ============== SVM onSlot types ==============
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Structured filter object returned by an SVM `indexer.onSlot` `where`
|
|
868
|
+
* predicate. `_every` alignment is relative to `_gte` (or the chain's
|
|
869
|
+
* configured `startBlock` when `_gte` is omitted), preserving
|
|
870
|
+
* `(slot - startBlock) % _every === 0`.
|
|
871
|
+
*/
|
|
872
|
+
export type SvmOnSlotFilter = {
|
|
873
|
+
readonly slot?: {
|
|
874
|
+
/** Matches slots whose number is greater than or equal to the given value. */
|
|
875
|
+
readonly _gte?: number;
|
|
876
|
+
/** Matches slots whose number is less than or equal to the given value. */
|
|
877
|
+
readonly _lte?: number;
|
|
878
|
+
/** Match every Nth slot. Alignment is relative to `_gte`. */
|
|
879
|
+
readonly _every?: number;
|
|
880
|
+
};
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* Return type of an SVM `indexer.onSlot` `where` predicate. The predicate
|
|
885
|
+
* must explicitly return — an implicit `undefined` is not accepted.
|
|
886
|
+
* - `false` → skip this chain.
|
|
887
|
+
* - `true` → register on the chain with no extra filter.
|
|
888
|
+
* - {@link SvmOnSlotFilter} → register with the given range/stride.
|
|
889
|
+
*/
|
|
890
|
+
export type SvmOnSlotWhereResult = boolean | SvmOnSlotFilter;
|
|
891
|
+
|
|
892
|
+
/** Argument passed to an SVM `indexer.onSlot` `where` predicate. */
|
|
893
|
+
export type SvmOnSlotWhereArgs<Config extends IndexerConfigTypes> = {
|
|
894
|
+
/** Configured chain being evaluated. Use `chain.id` to branch per chain. */
|
|
895
|
+
readonly chain: SvmChain<SvmChainIds<Config>>;
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
/** Arguments passed to an SVM slot handler. */
|
|
899
|
+
export type SvmOnSlotHandlerArgs<Config extends IndexerConfigTypes> = {
|
|
900
|
+
/** Slot number being processed. */
|
|
901
|
+
readonly slot: number;
|
|
902
|
+
/** Handler context: entity operations, logger, effect caller, chain state. */
|
|
903
|
+
readonly context: SvmOnSlotContext<Config>;
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
/** Handler function for an SVM `indexer.onSlot` registration. */
|
|
907
|
+
export type SvmOnSlotHandler<Config extends IndexerConfigTypes> = (
|
|
908
|
+
args: SvmOnSlotHandlerArgs<Config>,
|
|
909
|
+
) => Promise<void>;
|
|
910
|
+
|
|
911
|
+
/** Options for an SVM `indexer.onSlot` registration. */
|
|
912
|
+
export type SvmOnSlotOptions<Config extends IndexerConfigTypes> = {
|
|
913
|
+
/** Unique name for this slot handler. Used as the key in error messages
|
|
914
|
+
and in persisted progress tracking. */
|
|
915
|
+
readonly name: string;
|
|
916
|
+
/** Optional predicate evaluated once per configured chain at registration
|
|
917
|
+
time. Return `false` to skip a chain, `true` to match every slot, or
|
|
918
|
+
a filter object to restrict by slot range and stride. */
|
|
919
|
+
readonly where?: (args: SvmOnSlotWhereArgs<Config>) => SvmOnSlotWhereResult;
|
|
920
|
+
};
|
|
921
|
+
|
|
922
|
+
// ============== Indexer Types ==============
|
|
923
|
+
|
|
403
924
|
// Helper: Check if ecosystem is configured in a given config
|
|
404
925
|
type HasEvm<Config> = "evm" extends keyof Config ? true : false;
|
|
405
926
|
type HasFuel<Config> = "fuel" extends keyof Config ? true : false;
|
|
@@ -414,7 +935,11 @@ type EcosystemTuple<Config> = [
|
|
|
414
935
|
];
|
|
415
936
|
type EcosystemCount<Config> = EcosystemTuple<Config>["length"];
|
|
416
937
|
|
|
417
|
-
// EVM ecosystem type
|
|
938
|
+
// EVM ecosystem type — includes chains plus handler registration methods.
|
|
939
|
+
// NOTE: options use inline { contract: C; event: E } shape for TypeScript inference.
|
|
940
|
+
// Using EvmOnEventOptions<Contracts[C][E]> would break inference since C/E can't be
|
|
941
|
+
// derived from indexed access types. The named EvmOnEventOptions type is for end-user
|
|
942
|
+
// reference; the inline shape here is structurally identical.
|
|
418
943
|
type EvmEcosystem<Config extends IndexerConfigTypes> =
|
|
419
944
|
"evm" extends keyof Config
|
|
420
945
|
? Config["evm"] extends {
|
|
@@ -437,12 +962,69 @@ type EvmEcosystem<Config extends IndexerConfigTypes> =
|
|
|
437
962
|
ContractName extends string ? ContractName : never
|
|
438
963
|
>;
|
|
439
964
|
};
|
|
965
|
+
/**
|
|
966
|
+
* Register a block handler. `where` is evaluated once per configured
|
|
967
|
+
* chain at registration time; return `false` to skip a chain, `true`
|
|
968
|
+
* to match every block, or an {@link EvmOnBlockFilter} describing a
|
|
969
|
+
* block-number range and stride. Always available regardless of
|
|
970
|
+
* whether `contracts` are configured — block handlers don't need
|
|
971
|
+
* any contract context.
|
|
972
|
+
*/
|
|
973
|
+
readonly onBlock: (
|
|
974
|
+
options: EvmOnBlockOptions<Config>,
|
|
975
|
+
handler: EvmOnBlockHandler<Config>,
|
|
976
|
+
) => void;
|
|
977
|
+
} & (Config["evm"] extends {
|
|
978
|
+
contracts: infer Contracts extends Record<string, Record<string, any>>;
|
|
440
979
|
}
|
|
980
|
+
? {
|
|
981
|
+
/** Register an event handler. */
|
|
982
|
+
readonly onEvent: <
|
|
983
|
+
C extends keyof Contracts & string,
|
|
984
|
+
E extends keyof Contracts[C] & string
|
|
985
|
+
>(
|
|
986
|
+
options: {
|
|
987
|
+
readonly contract: C;
|
|
988
|
+
readonly event: E;
|
|
989
|
+
readonly wildcard?: boolean;
|
|
990
|
+
readonly where?: EvmOnEventWhere<
|
|
991
|
+
EvmEventFilters<Config>[C] extends Record<string, any>
|
|
992
|
+
? EvmEventFilters<Config>[C][E & keyof EvmEventFilters<Config>[C]] extends { readonly params: infer P }
|
|
993
|
+
? P
|
|
994
|
+
: {}
|
|
995
|
+
: {},
|
|
996
|
+
C
|
|
997
|
+
>;
|
|
998
|
+
},
|
|
999
|
+
handler: EvmOnEventHandler<Contracts[C][E], EvmOnEventContext<Config>>
|
|
1000
|
+
) => void;
|
|
1001
|
+
/** Register a contract register handler for dynamic contract indexing. */
|
|
1002
|
+
readonly contractRegister: <
|
|
1003
|
+
C extends keyof Contracts & string,
|
|
1004
|
+
E extends keyof Contracts[C] & string
|
|
1005
|
+
>(
|
|
1006
|
+
options: {
|
|
1007
|
+
readonly contract: C;
|
|
1008
|
+
readonly event: E;
|
|
1009
|
+
readonly wildcard?: boolean;
|
|
1010
|
+
readonly where?: EvmOnEventWhere<
|
|
1011
|
+
EvmEventFilters<Config>[C] extends Record<string, any>
|
|
1012
|
+
? EvmEventFilters<Config>[C][E & keyof EvmEventFilters<Config>[C]] extends { readonly params: infer P }
|
|
1013
|
+
? P
|
|
1014
|
+
: {}
|
|
1015
|
+
: {},
|
|
1016
|
+
C
|
|
1017
|
+
>;
|
|
1018
|
+
},
|
|
1019
|
+
handler: EvmContractRegisterHandler<Contracts[C][E], EvmContractRegisterContext<Config>>
|
|
1020
|
+
) => void;
|
|
1021
|
+
}
|
|
1022
|
+
: {})
|
|
441
1023
|
: never
|
|
442
1024
|
: never
|
|
443
1025
|
: never;
|
|
444
1026
|
|
|
445
|
-
// Fuel ecosystem type
|
|
1027
|
+
// Fuel ecosystem type — chains plus handler registration methods.
|
|
446
1028
|
type FuelEcosystem<Config extends IndexerConfigTypes> =
|
|
447
1029
|
"fuel" extends keyof Config
|
|
448
1030
|
? Config["fuel"] extends {
|
|
@@ -465,12 +1047,64 @@ type FuelEcosystem<Config extends IndexerConfigTypes> =
|
|
|
465
1047
|
ContractName extends string ? ContractName : never
|
|
466
1048
|
>;
|
|
467
1049
|
};
|
|
1050
|
+
/** Register a Fuel block handler. See `EvmEcosystem.onBlock` for
|
|
1051
|
+
* `where` semantics; Fuel filters on `block.height`. Always
|
|
1052
|
+
* available regardless of whether `contracts` are configured. */
|
|
1053
|
+
readonly onBlock: (
|
|
1054
|
+
options: FuelOnBlockOptions<Config>,
|
|
1055
|
+
handler: FuelOnBlockHandler<Config>,
|
|
1056
|
+
) => void;
|
|
1057
|
+
} & (Config["fuel"] extends {
|
|
1058
|
+
contracts: infer Contracts extends Record<string, Record<string, any>>;
|
|
468
1059
|
}
|
|
1060
|
+
? {
|
|
1061
|
+
/** Register an event handler. */
|
|
1062
|
+
readonly onEvent: <
|
|
1063
|
+
C extends keyof Contracts & string,
|
|
1064
|
+
E extends keyof Contracts[C] & string
|
|
1065
|
+
>(
|
|
1066
|
+
options: {
|
|
1067
|
+
readonly contract: C;
|
|
1068
|
+
readonly event: E;
|
|
1069
|
+
readonly wildcard?: boolean;
|
|
1070
|
+
readonly where?: FuelOnEventWhere<
|
|
1071
|
+
FuelEventFilters<Config>[C] extends Record<string, any>
|
|
1072
|
+
? FuelEventFilters<Config>[C][E & keyof FuelEventFilters<Config>[C]] extends { readonly params: infer P }
|
|
1073
|
+
? P
|
|
1074
|
+
: {}
|
|
1075
|
+
: {},
|
|
1076
|
+
C
|
|
1077
|
+
>;
|
|
1078
|
+
},
|
|
1079
|
+
handler: FuelOnEventHandler<Contracts[C][E], FuelOnEventContext<Config>>
|
|
1080
|
+
) => void;
|
|
1081
|
+
/** Register a contract register handler for dynamic contract indexing. */
|
|
1082
|
+
readonly contractRegister: <
|
|
1083
|
+
C extends keyof Contracts & string,
|
|
1084
|
+
E extends keyof Contracts[C] & string
|
|
1085
|
+
>(
|
|
1086
|
+
options: {
|
|
1087
|
+
readonly contract: C;
|
|
1088
|
+
readonly event: E;
|
|
1089
|
+
readonly wildcard?: boolean;
|
|
1090
|
+
readonly where?: FuelOnEventWhere<
|
|
1091
|
+
FuelEventFilters<Config>[C] extends Record<string, any>
|
|
1092
|
+
? FuelEventFilters<Config>[C][E & keyof FuelEventFilters<Config>[C]] extends { readonly params: infer P }
|
|
1093
|
+
? P
|
|
1094
|
+
: {}
|
|
1095
|
+
: {},
|
|
1096
|
+
C
|
|
1097
|
+
>;
|
|
1098
|
+
},
|
|
1099
|
+
handler: FuelContractRegisterHandler<Contracts[C][E], FuelContractRegisterContext<Config>>
|
|
1100
|
+
) => void;
|
|
1101
|
+
}
|
|
1102
|
+
: {})
|
|
469
1103
|
: never
|
|
470
1104
|
: never
|
|
471
1105
|
: never;
|
|
472
1106
|
|
|
473
|
-
// SVM ecosystem type
|
|
1107
|
+
// SVM ecosystem type — chains plus onSlot handler method. SVM has no onEvent yet.
|
|
474
1108
|
type SvmEcosystem<Config extends IndexerConfigTypes> =
|
|
475
1109
|
"svm" extends keyof Config
|
|
476
1110
|
? Config["svm"] extends { chains: infer Chains }
|
|
@@ -484,12 +1118,23 @@ type SvmEcosystem<Config extends IndexerConfigTypes> =
|
|
|
484
1118
|
} & {
|
|
485
1119
|
readonly [K in keyof Chains]: SvmChain<Chains[K]["id"]>;
|
|
486
1120
|
};
|
|
1121
|
+
/**
|
|
1122
|
+
* Register a slot handler. `where` is evaluated once per configured
|
|
1123
|
+
* chain at registration time; return `false` to skip a chain, `true`
|
|
1124
|
+
* to match every slot, or an {@link SvmOnSlotFilter} describing a
|
|
1125
|
+
* slot range and stride.
|
|
1126
|
+
*/
|
|
1127
|
+
readonly onSlot: (
|
|
1128
|
+
options: SvmOnSlotOptions<Config>,
|
|
1129
|
+
handler: SvmOnSlotHandler<Config>,
|
|
1130
|
+
) => void;
|
|
487
1131
|
}
|
|
488
1132
|
: never
|
|
489
1133
|
: never
|
|
490
1134
|
: never;
|
|
491
1135
|
|
|
492
|
-
// Single ecosystem chains (flattened at root level)
|
|
1136
|
+
// Single ecosystem chains (flattened at root level). Includes handler methods
|
|
1137
|
+
// since, for single-ecosystem indexers, they live at root alongside `chains`.
|
|
493
1138
|
type SingleEcosystemChains<Config extends IndexerConfigTypes> =
|
|
494
1139
|
HasEvm<Config> extends true
|
|
495
1140
|
? EvmEcosystem<Config>
|
|
@@ -499,7 +1144,9 @@ type SingleEcosystemChains<Config extends IndexerConfigTypes> =
|
|
|
499
1144
|
? SvmEcosystem<Config>
|
|
500
1145
|
: {};
|
|
501
1146
|
|
|
502
|
-
// Multi-ecosystem chains (namespaced by ecosystem)
|
|
1147
|
+
// Multi-ecosystem chains (namespaced by ecosystem). Each ecosystem branch
|
|
1148
|
+
// includes its handler registration methods — mirrors the runtime object
|
|
1149
|
+
// built in `Main.res`.
|
|
503
1150
|
type MultiEcosystemChains<Config extends IndexerConfigTypes> =
|
|
504
1151
|
(HasEvm<Config> extends true
|
|
505
1152
|
? {
|
|
@@ -608,6 +1255,16 @@ type FuelTestIndexerChainConfig<Config extends IndexerConfigTypes> = {
|
|
|
608
1255
|
simulate?: FuelSimulateItem<Config>[];
|
|
609
1256
|
};
|
|
610
1257
|
|
|
1258
|
+
/** Configuration for a single SVM chain in the test indexer. SVM has no
|
|
1259
|
+
* `onEvent` handlers yet, so simulate items aren't supported — only slot
|
|
1260
|
+
* range overrides for driving `indexer.onSlot` block handlers under test. */
|
|
1261
|
+
type SvmTestIndexerChainConfig = {
|
|
1262
|
+
/** The slot number to start processing from. Defaults to config startBlock or progressBlock+1. */
|
|
1263
|
+
startBlock?: number;
|
|
1264
|
+
/** The slot number to stop processing at. */
|
|
1265
|
+
endBlock?: number;
|
|
1266
|
+
};
|
|
1267
|
+
|
|
611
1268
|
/** Entity change value containing sets and/or deleted IDs. */
|
|
612
1269
|
type EntityChangeValue<Entity> = {
|
|
613
1270
|
/** Entities that were created or updated. */
|
|
@@ -674,6 +1331,13 @@ type FuelChainIds<Config extends IndexerConfigTypes> =
|
|
|
674
1331
|
: never
|
|
675
1332
|
: never;
|
|
676
1333
|
|
|
1334
|
+
type SvmChainIds<Config extends IndexerConfigTypes> =
|
|
1335
|
+
Config["svm"] extends { chains: infer Chains }
|
|
1336
|
+
? Chains extends Record<string, { id: number }>
|
|
1337
|
+
? Chains[keyof Chains]["id"]
|
|
1338
|
+
: never
|
|
1339
|
+
: never;
|
|
1340
|
+
|
|
677
1341
|
// Per-ecosystem chain config mappings
|
|
678
1342
|
type EvmTestChains<Config extends IndexerConfigTypes> =
|
|
679
1343
|
HasEvm<Config> extends true
|
|
@@ -685,15 +1349,129 @@ type FuelTestChains<Config extends IndexerConfigTypes> =
|
|
|
685
1349
|
? { [K in FuelChainIds<Config>]?: FuelTestIndexerChainConfig<Config> }
|
|
686
1350
|
: {};
|
|
687
1351
|
|
|
1352
|
+
type SvmTestChains<Config extends IndexerConfigTypes> =
|
|
1353
|
+
HasSvm<Config> extends true
|
|
1354
|
+
? { [K in SvmChainIds<Config>]?: SvmTestIndexerChainConfig }
|
|
1355
|
+
: {};
|
|
1356
|
+
|
|
688
1357
|
/** Process configuration for the test indexer, with chains keyed by chain ID. */
|
|
689
1358
|
export type TestIndexerProcessConfig<Config extends IndexerConfigTypes> = {
|
|
690
1359
|
/** Chain configurations keyed by chain ID. Each chain specifies start and end blocks. */
|
|
691
1360
|
chains: Prettify<
|
|
692
1361
|
EvmTestChains<Config> &
|
|
693
|
-
FuelTestChains<Config>
|
|
1362
|
+
FuelTestChains<Config> &
|
|
1363
|
+
SvmTestChains<Config>
|
|
694
1364
|
>;
|
|
695
1365
|
};
|
|
696
1366
|
|
|
1367
|
+
// Per-ecosystem test-indexer ecosystem types — structurally the `chainIds +
|
|
1368
|
+
// chains` slice of the real ecosystem types, but without the handler
|
|
1369
|
+
// registration methods (the test indexer doesn't let you register new
|
|
1370
|
+
// handlers, only run the existing ones over simulated or persisted data).
|
|
1371
|
+
// Kept as a separate type family so the real and test surfaces can evolve
|
|
1372
|
+
// independently without one silently lying about the other.
|
|
1373
|
+
type EvmTestEcosystem<Config extends IndexerConfigTypes> =
|
|
1374
|
+
"evm" extends keyof Config
|
|
1375
|
+
? Config["evm"] extends {
|
|
1376
|
+
chains: infer Chains;
|
|
1377
|
+
contracts?: Record<infer ContractName, any>;
|
|
1378
|
+
}
|
|
1379
|
+
? Chains extends Record<string, { id: number }>
|
|
1380
|
+
? {
|
|
1381
|
+
/** Array of all EVM chain IDs. */
|
|
1382
|
+
readonly chainIds: readonly Chains[keyof Chains]["id"][];
|
|
1383
|
+
/** Per-chain configuration keyed by chain name or ID. */
|
|
1384
|
+
readonly chains: {
|
|
1385
|
+
readonly [K in Chains[keyof Chains]["id"]]: EvmChain<
|
|
1386
|
+
K,
|
|
1387
|
+
ContractName extends string ? ContractName : never
|
|
1388
|
+
>;
|
|
1389
|
+
} & {
|
|
1390
|
+
readonly [K in keyof Chains]: EvmChain<
|
|
1391
|
+
Chains[K]["id"],
|
|
1392
|
+
ContractName extends string ? ContractName : never
|
|
1393
|
+
>;
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
: never
|
|
1397
|
+
: never
|
|
1398
|
+
: never;
|
|
1399
|
+
|
|
1400
|
+
type FuelTestEcosystem<Config extends IndexerConfigTypes> =
|
|
1401
|
+
"fuel" extends keyof Config
|
|
1402
|
+
? Config["fuel"] extends {
|
|
1403
|
+
chains: infer Chains;
|
|
1404
|
+
contracts?: Record<infer ContractName, any>;
|
|
1405
|
+
}
|
|
1406
|
+
? Chains extends Record<string, { id: number }>
|
|
1407
|
+
? {
|
|
1408
|
+
/** Array of all Fuel chain IDs. */
|
|
1409
|
+
readonly chainIds: readonly Chains[keyof Chains]["id"][];
|
|
1410
|
+
/** Per-chain configuration keyed by chain name or ID. */
|
|
1411
|
+
readonly chains: {
|
|
1412
|
+
readonly [K in Chains[keyof Chains]["id"]]: FuelChain<
|
|
1413
|
+
K,
|
|
1414
|
+
ContractName extends string ? ContractName : never
|
|
1415
|
+
>;
|
|
1416
|
+
} & {
|
|
1417
|
+
readonly [K in keyof Chains]: FuelChain<
|
|
1418
|
+
Chains[K]["id"],
|
|
1419
|
+
ContractName extends string ? ContractName : never
|
|
1420
|
+
>;
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1423
|
+
: never
|
|
1424
|
+
: never
|
|
1425
|
+
: never;
|
|
1426
|
+
|
|
1427
|
+
type SvmTestEcosystem<Config extends IndexerConfigTypes> =
|
|
1428
|
+
"svm" extends keyof Config
|
|
1429
|
+
? Config["svm"] extends { chains: infer Chains }
|
|
1430
|
+
? Chains extends Record<string, { id: number }>
|
|
1431
|
+
? {
|
|
1432
|
+
/** Array of all SVM chain IDs. */
|
|
1433
|
+
readonly chainIds: readonly Chains[keyof Chains]["id"][];
|
|
1434
|
+
/** Per-chain configuration keyed by chain name or ID. */
|
|
1435
|
+
readonly chains: {
|
|
1436
|
+
readonly [K in Chains[keyof Chains]["id"]]: SvmChain<K>;
|
|
1437
|
+
} & {
|
|
1438
|
+
readonly [K in keyof Chains]: SvmChain<Chains[K]["id"]>;
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
: never
|
|
1442
|
+
: never
|
|
1443
|
+
: never;
|
|
1444
|
+
|
|
1445
|
+
// Test-side single/multi chain selectors, parallel to the real ones.
|
|
1446
|
+
type SingleEcosystemTestChains<Config extends IndexerConfigTypes> =
|
|
1447
|
+
HasEvm<Config> extends true
|
|
1448
|
+
? EvmTestEcosystem<Config>
|
|
1449
|
+
: HasFuel<Config> extends true
|
|
1450
|
+
? FuelTestEcosystem<Config>
|
|
1451
|
+
: HasSvm<Config> extends true
|
|
1452
|
+
? SvmTestEcosystem<Config>
|
|
1453
|
+
: {};
|
|
1454
|
+
|
|
1455
|
+
type MultiEcosystemTestChains<Config extends IndexerConfigTypes> =
|
|
1456
|
+
(HasEvm<Config> extends true
|
|
1457
|
+
? {
|
|
1458
|
+
/** EVM ecosystem configuration. */
|
|
1459
|
+
readonly evm: EvmTestEcosystem<Config>;
|
|
1460
|
+
}
|
|
1461
|
+
: {}) &
|
|
1462
|
+
(HasFuel<Config> extends true
|
|
1463
|
+
? {
|
|
1464
|
+
/** Fuel ecosystem configuration. */
|
|
1465
|
+
readonly fuel: FuelTestEcosystem<Config>;
|
|
1466
|
+
}
|
|
1467
|
+
: {}) &
|
|
1468
|
+
(HasSvm<Config> extends true
|
|
1469
|
+
? {
|
|
1470
|
+
/** SVM ecosystem configuration. */
|
|
1471
|
+
readonly svm: SvmTestEcosystem<Config>;
|
|
1472
|
+
}
|
|
1473
|
+
: {});
|
|
1474
|
+
|
|
697
1475
|
/**
|
|
698
1476
|
* Test indexer type resolved from config.
|
|
699
1477
|
* Allows running the indexer for specific block ranges and inspecting results.
|
|
@@ -707,10 +1485,16 @@ export type TestIndexerFromConfig<Config extends IndexerConfigTypes> = {
|
|
|
707
1485
|
readonly changes: readonly EntityChange<Config>[];
|
|
708
1486
|
}>;
|
|
709
1487
|
} & (EcosystemCount<Config> extends 1
|
|
710
|
-
?
|
|
711
|
-
:
|
|
1488
|
+
? SingleEcosystemTestChains<Config>
|
|
1489
|
+
: MultiEcosystemTestChains<Config>) & {
|
|
712
1490
|
/** Entity operations for direct manipulation outside of handlers. */
|
|
713
1491
|
readonly [K in keyof ConfigEntities<Config>]: TestIndexerEntityOperations<
|
|
714
1492
|
ConfigEntities<Config>[K]
|
|
715
1493
|
>;
|
|
716
1494
|
};
|
|
1495
|
+
|
|
1496
|
+
// ============== Runtime values ==============
|
|
1497
|
+
|
|
1498
|
+
// `never` steers callers to the project-typed `generated` re-export.
|
|
1499
|
+
export declare const indexer: never;
|
|
1500
|
+
export declare const createTestIndexer: () => never;
|