@secondlayer/subgraphs 6.3.6 → 6.5.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 +200 -119
- package/dist/index.js +761 -21
- package/dist/index.js.map +9 -6
- 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 +723 -22
- package/dist/runtime/replay.js.map +8 -5
- package/dist/schema/index.d.ts +43 -36
- package/dist/schema/index.js +307 -6
- package/dist/schema/index.js.map +6 -5
- package/dist/testing/index.d.ts +105 -105
- package/dist/testing/index.js +867 -84
- package/dist/testing/index.js.map +9 -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 +441 -0
- package/dist/verification.js +282 -0
- package/dist/verification.js.map +10 -0
- 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 +13 -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
|
/**
|
|
@@ -366,6 +366,7 @@ interface GeneratedSQL {
|
|
|
366
366
|
declare function generateSubgraphSQL(def: SubgraphDefinition, schemaNameOverride?: string): GeneratedSQL;
|
|
367
367
|
import { Database as Database2 } from "@secondlayer/shared/db";
|
|
368
368
|
import { Kysely as Kysely2 } from "kysely";
|
|
369
|
+
import { SubgraphVerification } from "@secondlayer/shared/schemas/subgraphs";
|
|
369
370
|
type AnyDb = Kysely2<Database2>;
|
|
370
371
|
interface TableDiff {
|
|
371
372
|
/** Tables added to the schema */
|
|
@@ -422,18 +423,24 @@ interface DeployDiff {
|
|
|
422
423
|
* - Breaking change → auto-reindex (drop + recreate)
|
|
423
424
|
*/
|
|
424
425
|
declare function deploySchema(db: AnyDb, def: SubgraphDefinition, handlerPath: string, opts?: {
|
|
425
|
-
forceReindex?: boolean
|
|
426
|
-
apiKeyId?: string
|
|
427
|
-
accountId?: string
|
|
428
|
-
schemaName?: string
|
|
429
|
-
handlerCode?: string
|
|
430
|
-
sourceCode?: string
|
|
426
|
+
forceReindex?: boolean;
|
|
427
|
+
apiKeyId?: string;
|
|
428
|
+
accountId?: string;
|
|
429
|
+
schemaName?: string;
|
|
430
|
+
handlerCode?: string;
|
|
431
|
+
sourceCode?: string;
|
|
432
|
+
/** Derived level to store (see `deriveVerification`). */
|
|
433
|
+
verification?: SubgraphVerification;
|
|
434
|
+
/** Network baked into the pin. Defaults to `NETWORK`, then mainnet. */
|
|
435
|
+
network?: string;
|
|
431
436
|
}): Promise<{
|
|
432
|
-
action: "created" | "unchanged" | "handler_updated" | "updated" | "reindexed"
|
|
433
|
-
subgraphId: string
|
|
434
|
-
version: string
|
|
435
|
-
|
|
437
|
+
action: "created" | "unchanged" | "handler_updated" | "updated" | "reindexed";
|
|
438
|
+
subgraphId: string;
|
|
439
|
+
version: string;
|
|
440
|
+
/** Present when the deploy carried a bundled handler. */
|
|
441
|
+
pin?: string;
|
|
442
|
+
diff?: DeployDiff;
|
|
436
443
|
/** Non-fatal caveats the caller should surface (e.g. handler grafts at tip). */
|
|
437
|
-
warnings?: string[]
|
|
444
|
+
warnings?: string[];
|
|
438
445
|
}>;
|
|
439
446
|
export { ColumnDiff, GeneratedSQL, TYPE_MAP, TableDiff, deploySchema, diffSchema, generateSubgraphSQL };
|
package/dist/schema/index.js
CHANGED
|
@@ -461,6 +461,274 @@ function filterFieldsByType() {
|
|
|
461
461
|
return out;
|
|
462
462
|
}
|
|
463
463
|
|
|
464
|
+
// src/verification.ts
|
|
465
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
466
|
+
// package.json
|
|
467
|
+
var package_default = {
|
|
468
|
+
name: "@secondlayer/subgraphs",
|
|
469
|
+
version: "6.5.0",
|
|
470
|
+
description: "Describe the Stacks data you want as one TypeScript file; it fills itself and survives reorgs.",
|
|
471
|
+
license: "MIT",
|
|
472
|
+
repository: {
|
|
473
|
+
type: "git",
|
|
474
|
+
url: "git+https://github.com/ryanwaits/secondlayer.git",
|
|
475
|
+
directory: "packages/subgraphs"
|
|
476
|
+
},
|
|
477
|
+
homepage: "https://github.com/ryanwaits/secondlayer/tree/main/packages/subgraphs#readme",
|
|
478
|
+
type: "module",
|
|
479
|
+
main: "./dist/index.js",
|
|
480
|
+
types: "./dist/index.d.ts",
|
|
481
|
+
exports: {
|
|
482
|
+
".": {
|
|
483
|
+
types: "./dist/index.d.ts",
|
|
484
|
+
import: "./dist/index.js"
|
|
485
|
+
},
|
|
486
|
+
"./types": {
|
|
487
|
+
types: "./dist/types.d.ts",
|
|
488
|
+
import: "./dist/types.js"
|
|
489
|
+
},
|
|
490
|
+
"./schema": {
|
|
491
|
+
types: "./dist/schema/index.d.ts",
|
|
492
|
+
import: "./dist/schema/index.js"
|
|
493
|
+
},
|
|
494
|
+
"./validate": {
|
|
495
|
+
types: "./dist/validate.d.ts",
|
|
496
|
+
import: "./dist/validate.js"
|
|
497
|
+
},
|
|
498
|
+
"./verification": {
|
|
499
|
+
types: "./dist/verification.d.ts",
|
|
500
|
+
import: "./dist/verification.js"
|
|
501
|
+
},
|
|
502
|
+
"./runtime/replay": {
|
|
503
|
+
types: "./dist/runtime/replay.d.ts",
|
|
504
|
+
import: "./dist/runtime/replay.js"
|
|
505
|
+
},
|
|
506
|
+
"./runtime/emitter": {
|
|
507
|
+
types: "./dist/runtime/emitter.d.ts",
|
|
508
|
+
import: "./dist/runtime/emitter.js"
|
|
509
|
+
},
|
|
510
|
+
"./testing": {
|
|
511
|
+
types: "./dist/testing/index.d.ts",
|
|
512
|
+
import: "./dist/testing/index.js"
|
|
513
|
+
},
|
|
514
|
+
"./verify": {
|
|
515
|
+
types: "./dist/verify/index.d.ts",
|
|
516
|
+
import: "./dist/verify/index.js"
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
files: ["dist"],
|
|
520
|
+
scripts: {
|
|
521
|
+
build: "bunup",
|
|
522
|
+
dev: "bunup --watch",
|
|
523
|
+
test: "bun test",
|
|
524
|
+
typecheck: "tsc --noEmit",
|
|
525
|
+
prepublishOnly: "bun run build"
|
|
526
|
+
},
|
|
527
|
+
dependencies: {
|
|
528
|
+
"@secondlayer/shared": "^11.23.0",
|
|
529
|
+
"@secondlayer/stacks": "^6.2.0",
|
|
530
|
+
"@secondlayer/verify": "^0.3.0",
|
|
531
|
+
esbuild: "^0.28.2",
|
|
532
|
+
kysely: "0.28.17",
|
|
533
|
+
zod: "^4.3.6"
|
|
534
|
+
},
|
|
535
|
+
devDependencies: {
|
|
536
|
+
"@types/bun": "latest",
|
|
537
|
+
bunup: "0.16.32",
|
|
538
|
+
typescript: "^5"
|
|
539
|
+
},
|
|
540
|
+
publishConfig: {
|
|
541
|
+
access: "public"
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
// src/verification.ts
|
|
546
|
+
var SUBGRAPHS_RUNTIME = `@secondlayer/subgraphs@${package_default.version}`;
|
|
547
|
+
var FORBIDDEN_GLOBALS = {
|
|
548
|
+
Date: "wall-clock time differs per run",
|
|
549
|
+
performance: "timers differ per run",
|
|
550
|
+
process: "host environment differs per run",
|
|
551
|
+
fetch: "network reads are not chain inputs",
|
|
552
|
+
crypto: "randomness differs per run",
|
|
553
|
+
setTimeout: "scheduling order differs per run",
|
|
554
|
+
setInterval: "scheduling order differs per run",
|
|
555
|
+
setImmediate: "scheduling order differs per run",
|
|
556
|
+
clearTimeout: "scheduling order differs per run",
|
|
557
|
+
clearInterval: "scheduling order differs per run",
|
|
558
|
+
queueMicrotask: "scheduling order differs per run",
|
|
559
|
+
WeakRef: "garbage collection timing differs per run",
|
|
560
|
+
FinalizationRegistry: "garbage collection timing differs per run",
|
|
561
|
+
Atomics: "shared memory is not single-threaded",
|
|
562
|
+
SharedArrayBuffer: "shared memory is not single-threaded",
|
|
563
|
+
Intl: "locale and time zone data differ per host",
|
|
564
|
+
Temporal: "locale and time zone data differ per host",
|
|
565
|
+
eval: "generated code hides inputs from the scan",
|
|
566
|
+
WebAssembly: "compiled code hides inputs from the scan",
|
|
567
|
+
ShadowRealm: "a nested realm escapes the allow-list",
|
|
568
|
+
require: "imports must be bundled into the handler"
|
|
569
|
+
};
|
|
570
|
+
var ALLOWED_GLOBALS = [
|
|
571
|
+
"undefined",
|
|
572
|
+
"NaN",
|
|
573
|
+
"Infinity",
|
|
574
|
+
"globalThis",
|
|
575
|
+
"isNaN",
|
|
576
|
+
"isFinite",
|
|
577
|
+
"parseInt",
|
|
578
|
+
"parseFloat",
|
|
579
|
+
"decodeURI",
|
|
580
|
+
"decodeURIComponent",
|
|
581
|
+
"encodeURI",
|
|
582
|
+
"encodeURIComponent",
|
|
583
|
+
"escape",
|
|
584
|
+
"unescape",
|
|
585
|
+
"Object",
|
|
586
|
+
"Function",
|
|
587
|
+
"Array",
|
|
588
|
+
"Number",
|
|
589
|
+
"Boolean",
|
|
590
|
+
"String",
|
|
591
|
+
"Symbol",
|
|
592
|
+
"BigInt",
|
|
593
|
+
"Math",
|
|
594
|
+
"JSON",
|
|
595
|
+
"Reflect",
|
|
596
|
+
"Proxy",
|
|
597
|
+
"Promise",
|
|
598
|
+
"Map",
|
|
599
|
+
"Set",
|
|
600
|
+
"WeakMap",
|
|
601
|
+
"WeakSet",
|
|
602
|
+
"RegExp",
|
|
603
|
+
"Iterator",
|
|
604
|
+
"DisposableStack",
|
|
605
|
+
"AsyncDisposableStack",
|
|
606
|
+
"Error",
|
|
607
|
+
"AggregateError",
|
|
608
|
+
"SuppressedError",
|
|
609
|
+
"EvalError",
|
|
610
|
+
"RangeError",
|
|
611
|
+
"ReferenceError",
|
|
612
|
+
"SyntaxError",
|
|
613
|
+
"TypeError",
|
|
614
|
+
"URIError",
|
|
615
|
+
"ArrayBuffer",
|
|
616
|
+
"DataView",
|
|
617
|
+
"Int8Array",
|
|
618
|
+
"Uint8Array",
|
|
619
|
+
"Uint8ClampedArray",
|
|
620
|
+
"Int16Array",
|
|
621
|
+
"Uint16Array",
|
|
622
|
+
"Int32Array",
|
|
623
|
+
"Uint32Array",
|
|
624
|
+
"Float16Array",
|
|
625
|
+
"Float32Array",
|
|
626
|
+
"Float64Array",
|
|
627
|
+
"BigInt64Array",
|
|
628
|
+
"BigUint64Array",
|
|
629
|
+
"TextEncoder",
|
|
630
|
+
"TextDecoder",
|
|
631
|
+
"atob",
|
|
632
|
+
"btoa",
|
|
633
|
+
"console"
|
|
634
|
+
];
|
|
635
|
+
var ALLOWED_MATH = [
|
|
636
|
+
"abs",
|
|
637
|
+
"min",
|
|
638
|
+
"max",
|
|
639
|
+
"floor",
|
|
640
|
+
"ceil",
|
|
641
|
+
"trunc",
|
|
642
|
+
"sign",
|
|
643
|
+
"round",
|
|
644
|
+
"E",
|
|
645
|
+
"LN10",
|
|
646
|
+
"LN2",
|
|
647
|
+
"LOG10E",
|
|
648
|
+
"LOG2E",
|
|
649
|
+
"PI",
|
|
650
|
+
"SQRT1_2",
|
|
651
|
+
"SQRT2"
|
|
652
|
+
];
|
|
653
|
+
var LOCALE_METHODS = [
|
|
654
|
+
"toLocaleString",
|
|
655
|
+
"toLocaleDateString",
|
|
656
|
+
"toLocaleTimeString",
|
|
657
|
+
"toLocaleUpperCase",
|
|
658
|
+
"toLocaleLowerCase",
|
|
659
|
+
"localeCompare"
|
|
660
|
+
];
|
|
661
|
+
function formatFinding(f) {
|
|
662
|
+
return `${f.file}:${f.line}:${f.column} ${f.name}: ${f.reason}`;
|
|
663
|
+
}
|
|
664
|
+
var STATE_SOURCE_TYPES = new Set([
|
|
665
|
+
"var_set",
|
|
666
|
+
"map_set",
|
|
667
|
+
"map_delete"
|
|
668
|
+
]);
|
|
669
|
+
var LEVEL_RANK = { state: 0, events: 1, none: 2 };
|
|
670
|
+
var MAX_LISTED_FINDINGS = 10;
|
|
671
|
+
function deriveVerification(def, findings = []) {
|
|
672
|
+
let level = "state";
|
|
673
|
+
const raise = (to) => {
|
|
674
|
+
if (LEVEL_RANK[to] > LEVEL_RANK[level])
|
|
675
|
+
level = to;
|
|
676
|
+
};
|
|
677
|
+
const reasons = [];
|
|
678
|
+
for (const [name, source] of Object.entries(def.sources ?? {})) {
|
|
679
|
+
const filter = source;
|
|
680
|
+
if (filter.trait) {
|
|
681
|
+
raise("none");
|
|
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`);
|
|
686
|
+
} else if (!STATE_SOURCE_TYPES.has(filter.type)) {
|
|
687
|
+
raise("events");
|
|
688
|
+
reasons.push(`${filter.type} source "${name}" needs event proofs`);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if (def.backfillMode === "concurrent") {
|
|
692
|
+
raise("none");
|
|
693
|
+
reasons.push("backfillMode concurrent: tip-first order is not chain order");
|
|
694
|
+
}
|
|
695
|
+
if (findings.some((f) => f.kind === "needs-events"))
|
|
696
|
+
raise("events");
|
|
697
|
+
for (const f of findings.slice(0, MAX_LISTED_FINDINGS)) {
|
|
698
|
+
reasons.push(f.kind === "needs-events" ? `${formatFinding(f)} (needs event proofs)` : formatFinding(f));
|
|
699
|
+
}
|
|
700
|
+
if (findings.length > MAX_LISTED_FINDINGS) {
|
|
701
|
+
reasons.push(`…and ${findings.length - MAX_LISTED_FINDINGS} more handler findings`);
|
|
702
|
+
}
|
|
703
|
+
return {
|
|
704
|
+
level,
|
|
705
|
+
reasons,
|
|
706
|
+
unproven: reasons.length === 0 ? [
|
|
707
|
+
"tx attribution of writes: event.tx, _tx_id (needs event proofs)",
|
|
708
|
+
"intermediate writes within a block (needs event proofs)"
|
|
709
|
+
] : []
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
function isDeterminismViolation(v) {
|
|
713
|
+
return v.level === "state" && v.reasons.length > 0;
|
|
714
|
+
}
|
|
715
|
+
function sha256(input) {
|
|
716
|
+
return createHash2("sha256").update(input).digest("hex");
|
|
717
|
+
}
|
|
718
|
+
function pinPreimage(input) {
|
|
719
|
+
const fields = {
|
|
720
|
+
handlerHash: sha256(input.handlerCode),
|
|
721
|
+
network: input.network,
|
|
722
|
+
runtime: input.runtime ?? SUBGRAPHS_RUNTIME,
|
|
723
|
+
schemaHash: input.schemaHash,
|
|
724
|
+
startBlock: input.startBlock ?? null
|
|
725
|
+
};
|
|
726
|
+
return JSON.stringify(fields);
|
|
727
|
+
}
|
|
728
|
+
function computePin(input) {
|
|
729
|
+
return sha256(pinPreimage(input));
|
|
730
|
+
}
|
|
731
|
+
|
|
464
732
|
// src/schema/deployer.ts
|
|
465
733
|
function toJsonSafe(obj) {
|
|
466
734
|
return JSON.parse(JSON.stringify(obj, (_key, value) => typeof value === "bigint" ? value.toString() : value));
|
|
@@ -558,6 +826,15 @@ function renderDeployPlan(def, schemaName) {
|
|
|
558
826
|
async function deploySchema(db, def, handlerPath, opts) {
|
|
559
827
|
validateSubgraphDefinition(def);
|
|
560
828
|
const { statements, hash } = generateSubgraphSQL(def, opts?.schemaName);
|
|
829
|
+
const pinInput = opts?.handlerCode != null ? {
|
|
830
|
+
schemaHash: hash,
|
|
831
|
+
handlerCode: opts.handlerCode,
|
|
832
|
+
startBlock: def.startBlock,
|
|
833
|
+
network: opts.network ?? process.env.NETWORK ?? "mainnet"
|
|
834
|
+
} : null;
|
|
835
|
+
const pin = pinInput ? computePin(pinInput) : null;
|
|
836
|
+
const preimage = pinInput ? pinPreimage(pinInput) : null;
|
|
837
|
+
const identity = pin ? { pin } : {};
|
|
561
838
|
const { getSubgraph, registerSubgraph } = await import("@secondlayer/shared/db/queries/subgraphs");
|
|
562
839
|
const ddlDb = db;
|
|
563
840
|
const existing = await getSubgraph(db, def.name, opts?.accountId);
|
|
@@ -580,7 +857,10 @@ async function deploySchema(db, def, handlerPath, opts) {
|
|
|
580
857
|
handlerCode: opts?.handlerCode,
|
|
581
858
|
sourceCode: opts?.sourceCode,
|
|
582
859
|
schemaName,
|
|
583
|
-
startBlock: def.startBlock
|
|
860
|
+
startBlock: def.startBlock,
|
|
861
|
+
pin,
|
|
862
|
+
pinPreimage: preimage,
|
|
863
|
+
verification: opts?.verification ?? null
|
|
584
864
|
};
|
|
585
865
|
if (existing) {
|
|
586
866
|
const schemaExists = await sql`
|
|
@@ -594,19 +874,28 @@ async function deploySchema(db, def, handlerPath, opts) {
|
|
|
594
874
|
await sql.raw(stmt).execute(ddlDb);
|
|
595
875
|
}
|
|
596
876
|
const sg = await registerSubgraph(db, regData);
|
|
597
|
-
return {
|
|
877
|
+
return {
|
|
878
|
+
action: "reindexed",
|
|
879
|
+
subgraphId: sg.id,
|
|
880
|
+
version: newVersion,
|
|
881
|
+
...identity
|
|
882
|
+
};
|
|
598
883
|
}
|
|
599
884
|
if (existing.schema_hash === hash && !opts?.forceReindex) {
|
|
600
885
|
const handlerChanged = opts?.handlerCode != null && opts.handlerCode !== existing.handler_code;
|
|
601
886
|
const { updateSubgraphHandlerPath } = await import("@secondlayer/shared/db/queries/subgraphs");
|
|
602
887
|
await updateSubgraphHandlerPath(db, def.name, handlerPath, {
|
|
603
888
|
handlerCode: opts?.handlerCode,
|
|
604
|
-
sourceCode: opts?.sourceCode
|
|
889
|
+
sourceCode: opts?.sourceCode,
|
|
890
|
+
pin,
|
|
891
|
+
pinPreimage: preimage,
|
|
892
|
+
verification: opts?.verification ?? null
|
|
605
893
|
});
|
|
606
894
|
return {
|
|
607
895
|
action: handlerChanged ? "handler_updated" : "unchanged",
|
|
608
896
|
subgraphId: existing.id,
|
|
609
897
|
version: existing.version,
|
|
898
|
+
...identity,
|
|
610
899
|
...handlerChanged ? {
|
|
611
900
|
warnings: [
|
|
612
901
|
"handler changed but schema did not: new logic applies from the current tip only. Rows already indexed were computed by the previous handler. To recompute history, redeploy with --reindex (or backfill a range)."
|
|
@@ -620,7 +909,12 @@ async function deploySchema(db, def, handlerPath, opts) {
|
|
|
620
909
|
await sql.raw(stmt).execute(ddlDb);
|
|
621
910
|
}
|
|
622
911
|
const sg = await registerSubgraph(db, regData);
|
|
623
|
-
return {
|
|
912
|
+
return {
|
|
913
|
+
action: "reindexed",
|
|
914
|
+
subgraphId: sg.id,
|
|
915
|
+
version: newVersion,
|
|
916
|
+
...identity
|
|
917
|
+
};
|
|
624
918
|
}
|
|
625
919
|
if (existing.definition.schema) {
|
|
626
920
|
const diff = diffSchema(existing.definition.schema, def.schema);
|
|
@@ -636,6 +930,7 @@ async function deploySchema(db, def, handlerPath, opts) {
|
|
|
636
930
|
action: "reindexed",
|
|
637
931
|
subgraphId: sg.id,
|
|
638
932
|
version: newVersion,
|
|
933
|
+
...identity,
|
|
639
934
|
diff: deployDiff
|
|
640
935
|
};
|
|
641
936
|
}
|
|
@@ -755,6 +1050,7 @@ async function deploySchema(db, def, handlerPath, opts) {
|
|
|
755
1050
|
action: "updated",
|
|
756
1051
|
subgraphId: sg.id,
|
|
757
1052
|
version: newVersion,
|
|
1053
|
+
...identity,
|
|
758
1054
|
diff: deployDiff
|
|
759
1055
|
};
|
|
760
1056
|
}
|
|
@@ -763,7 +1059,12 @@ async function deploySchema(db, def, handlerPath, opts) {
|
|
|
763
1059
|
await sql.raw(stmt).execute(ddlDb);
|
|
764
1060
|
}
|
|
765
1061
|
const sg = await registerSubgraph(db, regData);
|
|
766
|
-
return {
|
|
1062
|
+
return {
|
|
1063
|
+
action: "created",
|
|
1064
|
+
subgraphId: sg.id,
|
|
1065
|
+
version: newVersion,
|
|
1066
|
+
...identity
|
|
1067
|
+
};
|
|
767
1068
|
}
|
|
768
1069
|
function getDefault(type) {
|
|
769
1070
|
switch (type) {
|
|
@@ -790,5 +1091,5 @@ export {
|
|
|
790
1091
|
generateSubgraphSQL
|
|
791
1092
|
};
|
|
792
1093
|
|
|
793
|
-
//# debugId=
|
|
1094
|
+
//# debugId=858E528FDE59D30764756E2164756E21
|
|
794
1095
|
//# sourceMappingURL=index.js.map
|