@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.
@@ -16,7 +16,7 @@ import { AssetIdentifier } from "@secondlayer/stacks/filters";
16
16
  */
17
17
  type ChainReadCacheMode = "per-block" | "contract-constant";
18
18
  type ChainReadOptions = {
19
- cache?: ChainReadCacheMode
19
+ cache?: ChainReadCacheMode;
20
20
  };
21
21
  /**
22
22
  * `ChainReadClient` with the ABI generic erased. Structurally cheap, so the
@@ -25,7 +25,7 @@ type ChainReadOptions = {
25
25
  */
26
26
  interface ErasedChainReadClient {
27
27
  contract(contractId: string, abi: unknown, options?: ChainReadOptions): {
28
- read: Record<string, (args?: Record<string, unknown>) => Promise<unknown>>
28
+ read: Record<string, (args?: Record<string, unknown>) => Promise<unknown>>;
29
29
  };
30
30
  }
31
31
  /** Supported column types for subgraph schemas */
@@ -86,7 +86,7 @@ interface StxLockFilter {
86
86
  * as-of each processed block. Lets a source index "all SIP-010 tokens" etc.
87
87
  */
88
88
  type TraitScope = {
89
- trait?: string
89
+ trait?: string;
90
90
  };
91
91
  /**
92
92
  * Scope a source to a DYNAMIC address set discovered from another source's
@@ -126,10 +126,10 @@ type TraitScope = {
126
126
  interface FactoryScope {
127
127
  factory?: {
128
128
  /** Source name whose events reveal the addresses. */
129
- from: string
129
+ from: string;
130
130
  /** Dotted path to the address on that source's payload
131
131
  * (e.g. `"data.pool"`, `"contractId"`, `"data.token.id"`). */
132
- field: string
132
+ field: string;
133
133
  };
134
134
  }
135
135
  /** FT event filters */
@@ -235,12 +235,12 @@ interface MapWriteFilter extends TraitScope, FactoryScope {
235
235
  * - `{ list: F }` — a list of `F`.
236
236
  */
237
237
  type PrintField = ColumnType | {
238
- type: PrintField
239
- optional: true
238
+ type: PrintField;
239
+ optional: true;
240
240
  } | {
241
- tuple: Record<string, PrintField>
241
+ tuple: Record<string, PrintField>;
242
242
  } | {
243
- list: PrintField
243
+ list: PrintField;
244
244
  };
245
245
  /**
246
246
  * Per-topic field schema for a print_event source. When declared, the handler's
@@ -252,34 +252,34 @@ type PrintField = ColumnType | {
252
252
  */
253
253
  type PrintEventPrints = Record<string, Record<string, PrintField>>;
254
254
  type PrintEventFields = FactoryScope & {
255
- type: "print_event"
256
- topic?: string
255
+ type: "print_event";
256
+ topic?: string;
257
257
  };
258
258
  /**
259
259
  * Pinned to one or more contract ids with no trait — `prints` is required so
260
260
  * `event.data` is typed and empty-table handlers cannot typecheck.
261
261
  */
262
262
  type PinnedPrintEventFilter = PrintEventFields & {
263
- contractId: string | readonly string[]
264
- trait?: undefined
265
- prints: PrintEventPrints
263
+ contractId: string | readonly string[];
264
+ trait?: undefined;
265
+ prints: PrintEventPrints;
266
266
  };
267
267
  /**
268
268
  * Trait-scoped print source (optionally narrowed by contractId). No single
269
269
  * schema — `prints` stays optional.
270
270
  */
271
271
  type TraitPrintEventFilter = PrintEventFields & {
272
- contractId?: string | readonly string[]
273
- trait: string
274
- prints?: PrintEventPrints
272
+ contractId?: string | readonly string[];
273
+ trait: string;
274
+ prints?: PrintEventPrints;
275
275
  };
276
276
  /**
277
277
  * Unpinned / factory-only print source (no contractId). `prints` optional.
278
278
  */
279
279
  type UnpinnedPrintEventFilter = PrintEventFields & {
280
- contractId?: undefined
281
- trait?: string
282
- prints?: PrintEventPrints
280
+ contractId?: undefined;
281
+ trait?: string;
282
+ prints?: PrintEventPrints;
283
283
  };
284
284
  /**
285
285
  * Print-event filter. Pinned sources (contractId set, no trait) require
@@ -300,12 +300,12 @@ interface TxMeta {
300
300
  /** Context passed to subgraph handlers during event processing */
301
301
  interface SubgraphContext {
302
302
  block: {
303
- height: number
304
- hash: string
305
- timestamp: number
306
- burnBlockHeight: number
303
+ height: number;
304
+ hash: string;
305
+ timestamp: number;
306
+ burnBlockHeight: number;
307
307
  /** Nakamoto StacksBlockId, when the block row carries one. */
308
- indexBlockHash?: string | null
308
+ indexBlockHash?: string | null;
309
309
  };
310
310
  tx: TxMeta;
311
311
  /**
@@ -423,24 +423,24 @@ interface DeployDiff {
423
423
  * - Breaking change → auto-reindex (drop + recreate)
424
424
  */
425
425
  declare function deploySchema(db: AnyDb, def: SubgraphDefinition, handlerPath: string, opts?: {
426
- forceReindex?: boolean
427
- apiKeyId?: string
428
- accountId?: string
429
- schemaName?: string
430
- handlerCode?: string
431
- sourceCode?: string
426
+ forceReindex?: boolean;
427
+ apiKeyId?: string;
428
+ accountId?: string;
429
+ schemaName?: string;
430
+ handlerCode?: string;
431
+ sourceCode?: string;
432
432
  /** Derived level to store (see `deriveVerification`). */
433
- verification?: SubgraphVerification
433
+ verification?: SubgraphVerification;
434
434
  /** Network baked into the pin. Defaults to `NETWORK`, then mainnet. */
435
- network?: string
435
+ network?: string;
436
436
  }): Promise<{
437
- action: "created" | "unchanged" | "handler_updated" | "updated" | "reindexed"
438
- subgraphId: string
439
- version: string
437
+ action: "created" | "unchanged" | "handler_updated" | "updated" | "reindexed";
438
+ subgraphId: string;
439
+ version: string;
440
440
  /** Present when the deploy carried a bundled handler. */
441
- pin?: string
442
- diff?: DeployDiff
441
+ pin?: string;
442
+ diff?: DeployDiff;
443
443
  /** Non-fatal caveats the caller should surface (e.g. handler grafts at tip). */
444
- warnings?: string[]
444
+ warnings?: string[];
445
445
  }>;
446
446
  export { ColumnDiff, GeneratedSQL, TYPE_MAP, TableDiff, deploySchema, diffSchema, generateSubgraphSQL };
@@ -466,7 +466,7 @@ import { createHash as createHash2 } from "node:crypto";
466
466
  // package.json
467
467
  var package_default = {
468
468
  name: "@secondlayer/subgraphs",
469
- version: "6.4.0",
469
+ version: "6.6.0",
470
470
  description: "Describe the Stacks data you want as one TypeScript file; it fills itself and survives reorgs.",
471
471
  license: "MIT",
472
472
  repository: {
@@ -510,6 +510,10 @@ var package_default = {
510
510
  "./testing": {
511
511
  types: "./dist/testing/index.d.ts",
512
512
  import: "./dist/testing/index.js"
513
+ },
514
+ "./verify": {
515
+ types: "./dist/verify/index.d.ts",
516
+ import: "./dist/verify/index.js"
513
517
  }
514
518
  },
515
519
  files: ["dist"],
@@ -521,14 +525,16 @@ var package_default = {
521
525
  prepublishOnly: "bun run build"
522
526
  },
523
527
  dependencies: {
524
- "@secondlayer/shared": "^11.22.0",
525
- "@secondlayer/stacks": "^6.1.0",
528
+ "@secondlayer/shared": "^11.24.0",
529
+ "@secondlayer/stacks": "^6.2.0",
530
+ "@secondlayer/verify": "^0.3.0",
526
531
  esbuild: "^0.28.2",
527
532
  kysely: "0.28.17",
528
533
  zod: "^4.3.6"
529
534
  },
530
535
  devDependencies: {
531
536
  "@types/bun": "latest",
537
+ bunup: "0.16.32",
532
538
  typescript: "^5"
533
539
  },
534
540
  publishConfig: {
@@ -658,7 +664,6 @@ function formatFinding(f) {
658
664
  var STATE_SOURCE_TYPES = new Set([
659
665
  "var_set",
660
666
  "map_set",
661
- "map_insert",
662
667
  "map_delete"
663
668
  ]);
664
669
  var LEVEL_RANK = { state: 0, events: 1, none: 2 };
@@ -675,6 +680,9 @@ function deriveVerification(def, findings = []) {
675
680
  if (filter.trait) {
676
681
  raise("none");
677
682
  reasons.push(`source "${name}": trait scope needs a proven contract registry`);
683
+ } else if (filter.type === "map_insert") {
684
+ raise("events");
685
+ reasons.push(`map_insert source "${name}": map_insert vs map_set needs event proofs`);
678
686
  } else if (!STATE_SOURCE_TYPES.has(filter.type)) {
679
687
  raise("events");
680
688
  reasons.push(`${filter.type} source "${name}" needs event proofs`);
@@ -692,14 +700,12 @@ function deriveVerification(def, findings = []) {
692
700
  if (findings.length > MAX_LISTED_FINDINGS) {
693
701
  reasons.push(`…and ${findings.length - MAX_LISTED_FINDINGS} more handler findings`);
694
702
  }
695
- const writesMapInsert = Object.values(def.sources ?? {}).some((s) => s.type === "map_insert");
696
703
  return {
697
704
  level,
698
705
  reasons,
699
706
  unproven: reasons.length === 0 ? [
700
707
  "tx attribution of writes: event.tx, _tx_id (needs event proofs)",
701
- "intermediate writes within a block (needs event proofs)",
702
- ...writesMapInsert ? ["map_insert vs map_set (needs event proofs)"] : []
708
+ "intermediate writes within a block (needs event proofs)"
703
709
  ] : []
704
710
  };
705
711
  }
@@ -709,15 +715,18 @@ function isDeterminismViolation(v) {
709
715
  function sha256(input) {
710
716
  return createHash2("sha256").update(input).digest("hex");
711
717
  }
712
- function computePin(input) {
713
- const canonical = JSON.stringify({
718
+ function pinPreimage(input) {
719
+ const fields = {
714
720
  handlerHash: sha256(input.handlerCode),
715
721
  network: input.network,
716
722
  runtime: input.runtime ?? SUBGRAPHS_RUNTIME,
717
723
  schemaHash: input.schemaHash,
718
724
  startBlock: input.startBlock ?? null
719
- });
720
- return sha256(canonical);
725
+ };
726
+ return JSON.stringify(fields);
727
+ }
728
+ function computePin(input) {
729
+ return sha256(pinPreimage(input));
721
730
  }
722
731
 
723
732
  // src/schema/deployer.ts
@@ -817,12 +826,14 @@ function renderDeployPlan(def, schemaName) {
817
826
  async function deploySchema(db, def, handlerPath, opts) {
818
827
  validateSubgraphDefinition(def);
819
828
  const { statements, hash } = generateSubgraphSQL(def, opts?.schemaName);
820
- const pin = opts?.handlerCode != null ? computePin({
829
+ const pinInput = opts?.handlerCode != null ? {
821
830
  schemaHash: hash,
822
831
  handlerCode: opts.handlerCode,
823
832
  startBlock: def.startBlock,
824
833
  network: opts.network ?? process.env.NETWORK ?? "mainnet"
825
- }) : null;
834
+ } : null;
835
+ const pin = pinInput ? computePin(pinInput) : null;
836
+ const preimage = pinInput ? pinPreimage(pinInput) : null;
826
837
  const identity = pin ? { pin } : {};
827
838
  const { getSubgraph, registerSubgraph } = await import("@secondlayer/shared/db/queries/subgraphs");
828
839
  const ddlDb = db;
@@ -848,6 +859,7 @@ async function deploySchema(db, def, handlerPath, opts) {
848
859
  schemaName,
849
860
  startBlock: def.startBlock,
850
861
  pin,
862
+ pinPreimage: preimage,
851
863
  verification: opts?.verification ?? null
852
864
  };
853
865
  if (existing) {
@@ -876,6 +888,7 @@ async function deploySchema(db, def, handlerPath, opts) {
876
888
  handlerCode: opts?.handlerCode,
877
889
  sourceCode: opts?.sourceCode,
878
890
  pin,
891
+ pinPreimage: preimage,
879
892
  verification: opts?.verification ?? null
880
893
  });
881
894
  return {
@@ -1078,5 +1091,5 @@ export {
1078
1091
  generateSubgraphSQL
1079
1092
  };
1080
1093
 
1081
- //# debugId=437B69A70A1DC76C64756E2164756E21
1094
+ //# debugId=6A7DA7E9E6C054A564756E2164756E21
1082
1095
  //# sourceMappingURL=index.js.map