@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 +1 -0
- package/dist/index.d.ts +121 -121
- package/dist/index.js +262 -27
- package/dist/index.js.map +9 -8
- package/dist/runtime/emitter.js +1 -1
- package/dist/runtime/emitter.js.map +2 -2
- package/dist/runtime/replay.d.ts +32 -13
- package/dist/runtime/replay.js +724 -22
- package/dist/runtime/replay.js.map +9 -6
- package/dist/schema/index.d.ts +39 -39
- package/dist/schema/index.js +27 -14
- package/dist/schema/index.js.map +5 -5
- package/dist/testing/index.d.ts +105 -105
- package/dist/testing/index.js +406 -95
- package/dist/testing/index.js.map +7 -6
- package/dist/types.d.ts +31 -31
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validate.d.ts +27 -27
- package/dist/validate.js +1 -1
- package/dist/validate.js.map +2 -2
- package/dist/verification.d.ts +41 -26
- package/dist/verification.js +23 -13
- package/dist/verification.js.map +4 -4
- package/dist/verify/index.d.ts +475 -0
- package/dist/verify/index.js +3341 -0
- package/dist/verify/index.js.map +27 -0
- package/package.json +9 -3
package/dist/schema/index.d.ts
CHANGED
|
@@ -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 };
|
package/dist/schema/index.js
CHANGED
|
@@ -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.
|
|
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.
|
|
525
|
-
"@secondlayer/stacks": "^6.
|
|
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
|
|
713
|
-
const
|
|
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
|
|
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
|
|
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
|
-
}
|
|
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=
|
|
1094
|
+
//# debugId=6A7DA7E9E6C054A564756E2164756E21
|
|
1082
1095
|
//# sourceMappingURL=index.js.map
|