@secondlayer/subgraphs 6.4.0 → 6.6.0

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 CHANGED
@@ -63,6 +63,7 @@ Every source needs a handler of the same name. Handlers write with `ctx.insert`,
63
63
  | `./testing` | `runSubgraphTest`, `createTestContext`, `buildEvent`: run handlers against real or built events before deploying |
64
64
  | `./runtime/replay` | `replayWebhook({ accountId, webhookId, fromBlock, toBlock })`: re-enqueue historical rows as outbox entries |
65
65
  | `./runtime/emitter` | Webhook egress checks used by the API (`checkEgressAllowed`) |
66
+ | `./verify` | `replaySubgraph`, `compareRows`, `checkPin`: recompute a `state` subgraph from blocks proven with `@secondlayer/verify` and compare the served rows (powers `secondlayer verify subgraph --replay`) |
66
67
 
67
68
  ## Runtime
68
69
 
package/dist/index.d.ts CHANGED
@@ -18,7 +18,7 @@ import { AbiContract, ExtractFunctionArgs, ExtractFunctionOutput, ExtractReadOnl
18
18
  */
19
19
  type ChainReadCacheMode = "per-block" | "contract-constant";
20
20
  type ChainReadOptions = {
21
- cache?: ChainReadCacheMode
21
+ cache?: ChainReadCacheMode;
22
22
  };
23
23
  /**
24
24
  * The chain-read surface, fully typed by an ABI.
@@ -49,7 +49,7 @@ interface ChainReadClient {
49
49
  * `cache: "contract-constant"`).
50
50
  */
51
51
  contract<const C extends AbiContract>(contractId: string, abi: C, options?: ChainReadOptions): {
52
- read: ChainReadMethods<C>
52
+ read: ChainReadMethods<C>;
53
53
  };
54
54
  }
55
55
  /**
@@ -78,7 +78,7 @@ type ChainReadMethods<C extends AbiContract> = { [N in ExtractReadOnlyFunctions<
78
78
  */
79
79
  interface ErasedChainReadClient {
80
80
  contract(contractId: string, abi: unknown, options?: ChainReadOptions): {
81
- read: Record<string, (args?: Record<string, unknown>) => Promise<unknown>>
81
+ read: Record<string, (args?: Record<string, unknown>) => Promise<unknown>>;
82
82
  };
83
83
  }
84
84
  /**
@@ -92,9 +92,9 @@ interface ErasedChainReadClient {
92
92
  * ```
93
93
  */
94
94
  declare function readContractAt<const C extends AbiContract>(ctx: {
95
- client: ErasedChainReadClient
95
+ client: ErasedChainReadClient;
96
96
  }, contractId: string, abi: C, options?: ChainReadOptions): {
97
- read: ChainReadMethods<C>
97
+ read: ChainReadMethods<C>;
98
98
  };
99
99
  declare class ChainReadError extends Error {
100
100
  name: string;
@@ -157,7 +157,7 @@ interface StxLockFilter {
157
157
  * as-of each processed block. Lets a source index "all SIP-010 tokens" etc.
158
158
  */
159
159
  type TraitScope = {
160
- trait?: string
160
+ trait?: string;
161
161
  };
162
162
  /**
163
163
  * Scope a source to a DYNAMIC address set discovered from another source's
@@ -197,10 +197,10 @@ type TraitScope = {
197
197
  interface FactoryScope {
198
198
  factory?: {
199
199
  /** Source name whose events reveal the addresses. */
200
- from: string
200
+ from: string;
201
201
  /** Dotted path to the address on that source's payload
202
202
  * (e.g. `"data.pool"`, `"contractId"`, `"data.token.id"`). */
203
- field: string
203
+ field: string;
204
204
  };
205
205
  }
206
206
  /** FT event filters */
@@ -273,12 +273,12 @@ interface ContractCallEvent {
273
273
  resultHex: string | null;
274
274
  /** Transaction metadata. */
275
275
  tx: {
276
- txId: string
277
- sender: string
278
- type: string
279
- status: string
280
- contractId: string | null
281
- functionName: string | null
276
+ txId: string;
277
+ sender: string;
278
+ type: string;
279
+ status: string;
280
+ contractId: string | null;
281
+ functionName: string | null;
282
282
  };
283
283
  }
284
284
  /** Contract event filters */
@@ -347,12 +347,12 @@ interface MapWriteFilter extends TraitScope, FactoryScope {
347
347
  * - `{ list: F }` — a list of `F`.
348
348
  */
349
349
  type PrintField = ColumnType | {
350
- type: PrintField
351
- optional: true
350
+ type: PrintField;
351
+ optional: true;
352
352
  } | {
353
- tuple: Record<string, PrintField>
353
+ tuple: Record<string, PrintField>;
354
354
  } | {
355
- list: PrintField
355
+ list: PrintField;
356
356
  };
357
357
  /**
358
358
  * Per-topic field schema for a print_event source. When declared, the handler's
@@ -364,34 +364,34 @@ type PrintField = ColumnType | {
364
364
  */
365
365
  type PrintEventPrints = Record<string, Record<string, PrintField>>;
366
366
  type PrintEventFields = FactoryScope & {
367
- type: "print_event"
368
- topic?: string
367
+ type: "print_event";
368
+ topic?: string;
369
369
  };
370
370
  /**
371
371
  * Pinned to one or more contract ids with no trait — `prints` is required so
372
372
  * `event.data` is typed and empty-table handlers cannot typecheck.
373
373
  */
374
374
  type PinnedPrintEventFilter = PrintEventFields & {
375
- contractId: string | readonly string[]
376
- trait?: undefined
377
- prints: PrintEventPrints
375
+ contractId: string | readonly string[];
376
+ trait?: undefined;
377
+ prints: PrintEventPrints;
378
378
  };
379
379
  /**
380
380
  * Trait-scoped print source (optionally narrowed by contractId). No single
381
381
  * schema — `prints` stays optional.
382
382
  */
383
383
  type TraitPrintEventFilter = PrintEventFields & {
384
- contractId?: string | readonly string[]
385
- trait: string
386
- prints?: PrintEventPrints
384
+ contractId?: string | readonly string[];
385
+ trait: string;
386
+ prints?: PrintEventPrints;
387
387
  };
388
388
  /**
389
389
  * Unpinned / factory-only print source (no contractId). `prints` optional.
390
390
  */
391
391
  type UnpinnedPrintEventFilter = PrintEventFields & {
392
- contractId?: undefined
393
- trait?: string
394
- prints?: PrintEventPrints
392
+ contractId?: undefined;
393
+ trait?: string;
394
+ prints?: PrintEventPrints;
395
395
  };
396
396
  /**
397
397
  * Print-event filter. Pinned sources (contractId set, no trait) require
@@ -414,12 +414,12 @@ type RowValue = string | number | bigint | boolean | null | undefined | Record<s
414
414
  /** Context passed to subgraph handlers during event processing */
415
415
  interface SubgraphContext {
416
416
  block: {
417
- height: number
418
- hash: string
419
- timestamp: number
420
- burnBlockHeight: number
417
+ height: number;
418
+ hash: string;
419
+ timestamp: number;
420
+ burnBlockHeight: number;
421
421
  /** Nakamoto StacksBlockId, when the block row carries one. */
422
- indexBlockHash?: string | null
422
+ indexBlockHash?: string | null;
423
423
  };
424
424
  tx: TxMeta;
425
425
  /**
@@ -483,18 +483,18 @@ interface SystemRow {
483
483
  type InferTableRow<T extends SubgraphTable> = SystemRow & { [K in keyof T["columns"]] : InferColumnType<T["columns"][K]> };
484
484
  /** Comparison operators for a scalar value */
485
485
  type ComparisonFilter<T> = {
486
- eq?: T
487
- neq?: T
488
- gt?: T
489
- gte?: T
490
- lt?: T
491
- lte?: T
486
+ eq?: T;
487
+ neq?: T;
488
+ gt?: T;
489
+ gte?: T;
490
+ lt?: T;
491
+ lte?: T;
492
492
  /** Match any value in the set. */
493
- in?: T[]
493
+ in?: T[];
494
494
  /** Match none of the values in the set. */
495
- notIn?: T[]
495
+ notIn?: T[];
496
496
  /** SQL ILIKE pattern (case-insensitive); `%`/`_` wildcards. Strings only. */
497
- like?: string
497
+ like?: string;
498
498
  };
499
499
  /** Where clause — each column accepts a scalar (eq) or comparison object */
500
500
  type WhereInput<TRow> = { [K in keyof TRow]? : TRow[K] | ComparisonFilter<TRow[K]> };
@@ -503,16 +503,16 @@ type WhereInput<TRow> = { [K in keyof TRow]? : TRow[K] | ComparisonFilter<TRow[K
503
503
  * Both `_blockHeight` and `blockHeight` are valid — serializer handles mapping.
504
504
  */
505
505
  type SystemWhereAliases = {
506
- blockHeight?: bigint | ComparisonFilter<bigint>
507
- txId?: string | ComparisonFilter<string>
508
- createdAt?: string | ComparisonFilter<string>
509
- id?: string | ComparisonFilter<string>
506
+ blockHeight?: bigint | ComparisonFilter<bigint>;
507
+ txId?: string | ComparisonFilter<string>;
508
+ createdAt?: string | ComparisonFilter<string>;
509
+ id?: string | ComparisonFilter<string>;
510
510
  };
511
511
  type SystemOrderByAliases = {
512
- blockHeight?: "asc" | "desc"
513
- txId?: "asc" | "desc"
514
- createdAt?: "asc" | "desc"
515
- id?: "asc" | "desc"
512
+ blockHeight?: "asc" | "desc";
513
+ txId?: "asc" | "desc";
514
+ createdAt?: "asc" | "desc";
515
+ id?: "asc" | "desc";
516
516
  };
517
517
  interface FindManyOptions<TRow> {
518
518
  where?: WhereInput<TRow> & SystemWhereAliases;
@@ -582,15 +582,15 @@ type AggregateResult<
582
582
  TRow,
583
583
  A extends AggregateSpec<TRow>
584
584
  > = (A["count"] extends true ? {
585
- count: number
585
+ count: number;
586
586
  } : unknown) & (A["countDistinct"] extends readonly string[] ? {
587
- countDistinct: Record<ColsOf<A, "countDistinct">, number>
587
+ countDistinct: Record<ColsOf<A, "countDistinct">, number>;
588
588
  } : unknown) & (A["sum"] extends readonly string[] ? {
589
- sum: Record<ColsOf<A, "sum">, string>
589
+ sum: Record<ColsOf<A, "sum">, string>;
590
590
  } : unknown) & (A["min"] extends readonly string[] ? {
591
- min: Record<ColsOf<A, "min">, string | null>
591
+ min: Record<ColsOf<A, "min">, string | null>;
592
592
  } : unknown) & (A["max"] extends readonly string[] ? {
593
- max: Record<ColsOf<A, "max">, string | null>
593
+ max: Record<ColsOf<A, "max">, string | null>;
594
594
  } : unknown);
595
595
  interface SubgraphTableClient<TRow> {
596
596
  /**
@@ -601,7 +601,7 @@ interface SubgraphTableClient<TRow> {
601
601
  * names without `as const` at the call site (same pattern as `aggregate`).
602
602
  */
603
603
  findMany<const F extends readonly (keyof TRow & string)[] = readonly (keyof TRow & string)[]>(options?: Omit<FindManyOptions<TRow>, "fields"> & {
604
- fields?: F
604
+ fields?: F;
605
605
  }): Promise<FindManyPage<Pick<TRow, F[number]>>>;
606
606
  count(where?: WhereInput<TRow> & SystemWhereAliases): Promise<number>;
607
607
  /**
@@ -620,9 +620,9 @@ interface SubgraphTableClient<TRow> {
620
620
  }
621
621
  /** A column is optional on insert when it's nullable or has a SQL default. */
622
622
  type IsOptionalColumn<C> = C extends {
623
- nullable: true
623
+ nullable: true;
624
624
  } ? true : C extends {
625
- default: string | number | boolean
625
+ default: string | number | boolean;
626
626
  } ? true : false;
627
627
  /**
628
628
  * Like `InferColumnType` but for WRITE inputs: numeric (`uint`/`int`) columns
@@ -653,12 +653,12 @@ type RowWhere<
653
653
  */
654
654
  interface TypedSubgraphContext<S extends SubgraphSchema> {
655
655
  block: {
656
- height: number
657
- hash: string
658
- timestamp: number
659
- burnBlockHeight: number
656
+ height: number;
657
+ hash: string;
658
+ timestamp: number;
659
+ burnBlockHeight: number;
660
660
  /** Nakamoto StacksBlockId, when the block row carries one. */
661
- indexBlockHash?: string | null
661
+ indexBlockHash?: string | null;
662
662
  };
663
663
  tx: TxMeta;
664
664
  /**
@@ -687,7 +687,7 @@ interface TypedSubgraphContext<S extends SubgraphSchema> {
687
687
  }
688
688
  /** Infer a typed client object from a subgraph definition shape */
689
689
  type InferSubgraphClient<T> = T extends {
690
- schema: infer S
690
+ schema: infer S;
691
691
  } ? { [K in keyof S] : S[K] extends SubgraphTable ? SubgraphTableClient<InferTableRow<S[K]>> : never } : never;
692
692
  interface FtTransferPayload {
693
693
  sender: string;
@@ -774,10 +774,10 @@ interface ContractDeployPayload {
774
774
  * present for back-compat. Without an `abi`, the payload is {@link ContractCallEvent}.
775
775
  */
776
776
  type ContractCallPayload<F> = F extends {
777
- abi: infer A extends AbiContract3
778
- functionName: infer N extends string
777
+ abi: infer A extends AbiContract3;
778
+ functionName: infer N extends string;
779
779
  } ? N extends ExtractFunctionNames<A> ? ContractCallEvent & {
780
- input: ExtractFunctionArgs2<A, N>
780
+ input: ExtractFunctionArgs2<A, N>;
781
781
  } : ContractCallEvent : ContractCallEvent;
782
782
  interface NestedContractCallPayload {
783
783
  contractId: string;
@@ -821,24 +821,24 @@ interface MapDeletePayload {
821
821
  * per topic; otherwise it falls back to the untyped {@link PrintEventPayload}.
822
822
  */
823
823
  type PrintEventFor<F> = F extends {
824
- prints: infer P extends Record<string, Record<string, PrintField>>
824
+ prints: infer P extends Record<string, Record<string, PrintField>>;
825
825
  } ? { [K in keyof P] : {
826
- contractId: string
827
- topic: K
828
- data: PrintDataOf<P[K]>
829
- tx: TxMeta
826
+ contractId: string;
827
+ topic: K;
828
+ data: PrintDataOf<P[K]>;
829
+ tx: TxMeta;
830
830
  } }[keyof P] : PrintEventPayload;
831
831
  /** TS type of one declared print field (nested tuples and lists included). */
832
832
  type PrintFieldToTS<F> = F extends ColumnType ? ColumnToTS<F> : F extends {
833
- type: infer Inner
834
- optional: true
833
+ type: infer Inner;
834
+ optional: true;
835
835
  } ? PrintFieldToTS<Inner> : F extends {
836
- tuple: infer T extends Record<string, PrintField>
836
+ tuple: infer T extends Record<string, PrintField>;
837
837
  } ? PrintDataOf<T> : F extends {
838
- list: infer Item
838
+ list: infer Item;
839
839
  } ? PrintFieldToTS<Item>[] : unknown;
840
840
  type OptionalFieldKeys<T> = { [K in keyof T] : T[K] extends {
841
- optional: true
841
+ optional: true;
842
842
  } ? K : never }[keyof T];
843
843
  /** Collapse an intersection into one object literal, so hovering `event.data`
844
844
  * shows the fields rather than `A & B`. */
@@ -851,37 +851,37 @@ type Flatten<T> = { [K in keyof T] : T[K] } & {};
851
851
  type PrintDataOf<T extends Record<string, PrintField>> = Flatten<{ [K in Exclude<keyof T, OptionalFieldKeys<T>>] : PrintFieldToTS<T[K]> } & { [K in OptionalFieldKeys<T>]? : PrintFieldToTS<T[K]> }>;
852
852
  /** The event payload a handler receives for a given source filter. */
853
853
  type EventForFilter<F extends SubgraphFilter> = F extends {
854
- type: "print_event"
854
+ type: "print_event";
855
855
  } ? PrintEventFor<F> : F extends {
856
- type: "ft_transfer"
856
+ type: "ft_transfer";
857
857
  } ? FtTransferPayload : F extends {
858
- type: "ft_mint"
858
+ type: "ft_mint";
859
859
  } ? FtMintPayload : F extends {
860
- type: "ft_burn"
860
+ type: "ft_burn";
861
861
  } ? FtBurnPayload : F extends {
862
- type: "nft_transfer"
862
+ type: "nft_transfer";
863
863
  } ? NftTransferPayload : F extends {
864
- type: "nft_mint"
864
+ type: "nft_mint";
865
865
  } ? NftMintPayload : F extends {
866
- type: "nft_burn"
866
+ type: "nft_burn";
867
867
  } ? NftBurnPayload : F extends {
868
- type: "stx_transfer"
868
+ type: "stx_transfer";
869
869
  } ? StxTransferPayload : F extends {
870
- type: "stx_mint"
870
+ type: "stx_mint";
871
871
  } ? StxMintPayload : F extends {
872
- type: "stx_burn"
872
+ type: "stx_burn";
873
873
  } ? StxBurnPayload : F extends {
874
- type: "stx_lock"
874
+ type: "stx_lock";
875
875
  } ? StxLockPayload : F extends {
876
- type: "contract_call"
876
+ type: "contract_call";
877
877
  } ? ContractCallPayload<F> : F extends {
878
- type: "contract_deploy"
878
+ type: "contract_deploy";
879
879
  } ? ContractDeployPayload : F extends {
880
- type: "nested_contract_call"
880
+ type: "nested_contract_call";
881
881
  } ? NestedContractCallPayload : F extends {
882
- type: "var_set"
882
+ type: "var_set";
883
883
  } ? VarSetPayload : F extends {
884
- type: infer T extends "map_set" | "map_insert" | "map_delete"
884
+ type: infer T extends "map_set" | "map_insert" | "map_delete";
885
885
  } ? T extends "map_delete" ? MapDeletePayload : MapWritePayload : never;
886
886
  /** Union of every event payload. */
887
887
  type AnyEvent = FtTransferPayload | FtMintPayload | FtBurnPayload | NftTransferPayload | NftMintPayload | NftBurnPayload | StxTransferPayload | StxMintPayload | StxBurnPayload | StxLockPayload | PrintEventPayload | ContractCallEvent | ContractDeployPayload | NestedContractCallPayload | VarSetPayload | MapWritePayload | MapDeletePayload;
@@ -905,9 +905,9 @@ type TypedSubgraphDefinition<
905
905
  Sources extends Record<string, SubgraphFilter>,
906
906
  S extends SubgraphSchema
907
907
  > = Omit<SubgraphDefinition, "sources" | "schema" | "handlers"> & {
908
- sources: Sources
909
- schema: S
910
- handlers: TypedHandlers<Sources, S>
908
+ sources: Sources;
909
+ schema: S;
910
+ handlers: TypedHandlers<Sources, S>;
911
911
  };
912
912
  /**
913
913
  * Identity function that preserves `sources` and `schema` literal types so
@@ -972,7 +972,7 @@ declare function defineSchema<const S extends SubgraphSchema>(schema: S): S;
972
972
  * this is the form for when only the definition is in scope.
973
973
  */
974
974
  type InferContext<D> = D extends {
975
- schema: infer S extends SubgraphSchema
975
+ schema: infer S extends SubgraphSchema;
976
976
  } ? TypedSubgraphContext<S> : never;
977
977
  /**
978
978
  * Validates a subgraph definition, returning the parsed result or throwing on failure.
@@ -985,14 +985,14 @@ declare function validateSubgraphDefinition(def: unknown): SubgraphDefinition;
985
985
  * means adding a field to a filter can never leave the documentation behind.
986
986
  */
987
987
  declare function filterFieldsByType(): Array<{
988
- type: string
989
- fields: string[]
988
+ type: string;
989
+ fields: string[];
990
990
  }>;
991
991
  type PrintValidationResult = {
992
- ok: true
992
+ ok: true;
993
993
  } | {
994
- ok: false
995
- reason: string
994
+ ok: false;
995
+ reason: string;
996
996
  };
997
997
  /**
998
998
  * Empirical print-payload schema inference. Callers (the index print-schema
@@ -1214,8 +1214,8 @@ declare function diffSchema(existing: SubgraphSchema, incoming: SubgraphSchema):
1214
1214
  * Index-flag and composite-index changes are never breaking.
1215
1215
  */
1216
1216
  declare function hasBreakingChanges(diff: TableDiff): {
1217
- breaking: boolean
1218
- reasons: string[]
1217
+ breaking: boolean;
1218
+ reasons: string[];
1219
1219
  };
1220
1220
  interface DeployDiff {
1221
1221
  addedTables: string[];
@@ -1247,32 +1247,32 @@ declare function renderDeployPlan(def: SubgraphDefinition, schemaName?: string):
1247
1247
  * - Breaking change → auto-reindex (drop + recreate)
1248
1248
  */
1249
1249
  declare function deploySchema(db: AnyDb, def: SubgraphDefinition, handlerPath: string, opts?: {
1250
- forceReindex?: boolean
1251
- apiKeyId?: string
1252
- accountId?: string
1253
- schemaName?: string
1254
- handlerCode?: string
1255
- sourceCode?: string
1250
+ forceReindex?: boolean;
1251
+ apiKeyId?: string;
1252
+ accountId?: string;
1253
+ schemaName?: string;
1254
+ handlerCode?: string;
1255
+ sourceCode?: string;
1256
1256
  /** Derived level to store (see `deriveVerification`). */
1257
- verification?: SubgraphVerification
1257
+ verification?: SubgraphVerification;
1258
1258
  /** Network baked into the pin. Defaults to `NETWORK`, then mainnet. */
1259
- network?: string
1259
+ network?: string;
1260
1260
  }): Promise<{
1261
- action: "created" | "unchanged" | "handler_updated" | "updated" | "reindexed"
1262
- subgraphId: string
1263
- version: string
1261
+ action: "created" | "unchanged" | "handler_updated" | "updated" | "reindexed";
1262
+ subgraphId: string;
1263
+ version: string;
1264
1264
  /** Present when the deploy carried a bundled handler. */
1265
- pin?: string
1266
- diff?: DeployDiff
1265
+ pin?: string;
1266
+ diff?: DeployDiff;
1267
1267
  /** Non-fatal caveats the caller should surface (e.g. handler grafts at tip). */
1268
- warnings?: string[]
1268
+ warnings?: string[];
1269
1269
  }>;
1270
1270
  /** A (decoded event type, optional contract scope) pair the sparse probe
1271
1271
  * checks. Contract scoping is what makes token-subgraph reindexes leap over
1272
1272
  * everything that isn't their token. */
1273
1273
  type SparseProbeTarget = {
1274
- eventType: string
1275
- contractId?: string
1274
+ eventType: string;
1275
+ contractId?: string;
1276
1276
  };
1277
1277
  /** Sparse scanning is sound only when EVERY source is an event-type filter —
1278
1278
  * a contract_call/contract_deploy source matches transactions, which the