@secondlayer/subgraphs 4.4.1 → 5.0.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 +13 -21
- package/dist/{src/index.d.ts → index.d.ts} +59 -189
- package/dist/index.js +2151 -0
- package/dist/index.js.map +24 -0
- package/dist/{src/runtime → runtime}/emitter.d.ts +1 -1
- package/dist/{src/runtime → runtime}/emitter.js +8 -12
- package/dist/{src/runtime → runtime}/emitter.js.map +3 -3
- package/dist/{src/runtime → runtime}/replay.d.ts +1 -1
- package/dist/{src/runtime → runtime}/replay.js +342 -683
- package/dist/{src/runtime → runtime}/replay.js.map +5 -5
- package/dist/{src/schema → schema}/index.d.ts +10 -69
- package/dist/{src/schema → schema}/index.js +188 -281
- package/dist/schema/index.js.map +13 -0
- package/dist/{src/testing → testing}/index.d.ts +65 -115
- package/dist/{src/testing → testing}/index.js +554 -968
- package/dist/testing/index.js.map +21 -0
- package/dist/{src/types.d.ts → types.d.ts} +10 -66
- package/dist/{src/validate.d.ts → validate.d.ts} +11 -69
- package/dist/{src/validate.js → validate.js} +18 -98
- package/dist/validate.js.map +10 -0
- package/package.json +18 -26
- package/dist/src/index.js +0 -6081
- package/dist/src/index.js.map +0 -44
- package/dist/src/runtime/block-processor.d.ts +0 -559
- package/dist/src/runtime/block-processor.js +0 -3810
- package/dist/src/runtime/block-processor.js.map +0 -31
- package/dist/src/runtime/catchup.d.ts +0 -473
- package/dist/src/runtime/catchup.js +0 -4228
- package/dist/src/runtime/catchup.js.map +0 -35
- package/dist/src/runtime/clarity.d.ts +0 -15
- package/dist/src/runtime/clarity.js +0 -41
- package/dist/src/runtime/clarity.js.map +0 -10
- package/dist/src/runtime/context.d.ts +0 -325
- package/dist/src/runtime/context.js +0 -936
- package/dist/src/runtime/context.js.map +0 -13
- package/dist/src/runtime/processor.d.ts +0 -11
- package/dist/src/runtime/processor.js +0 -5372
- package/dist/src/runtime/processor.js.map +0 -40
- package/dist/src/runtime/reindex.d.ts +0 -539
- package/dist/src/runtime/reindex.js +0 -4802
- package/dist/src/runtime/reindex.js.map +0 -37
- package/dist/src/runtime/reorg.d.ts +0 -432
- package/dist/src/runtime/reorg.js +0 -4355
- package/dist/src/runtime/reorg.js.map +0 -36
- package/dist/src/runtime/runner.d.ts +0 -719
- package/dist/src/runtime/runner.js +0 -1332
- package/dist/src/runtime/runner.js.map +0 -16
- package/dist/src/runtime/source-matcher.d.ts +0 -304
- package/dist/src/runtime/source-matcher.js +0 -335
- package/dist/src/runtime/source-matcher.js.map +0 -10
- package/dist/src/runtime/stats.d.ts +0 -23
- package/dist/src/runtime/stats.js +0 -71
- package/dist/src/runtime/stats.js.map +0 -10
- package/dist/src/schema/index.js.map +0 -13
- package/dist/src/service.d.ts +0 -0
- package/dist/src/service.js +0 -5398
- package/dist/src/service.js.map +0 -41
- package/dist/src/testing/index.js.map +0 -22
- package/dist/src/triggers/index.d.ts +0 -381
- package/dist/src/triggers/index.js +0 -31
- package/dist/src/triggers/index.js.map +0 -10
- package/dist/src/validate.js.map +0 -10
- /package/dist/{src/types.js → types.js} +0 -0
- /package/dist/{src/types.js.map → types.js.map} +0 -0
package/README.md
CHANGED
|
@@ -12,16 +12,11 @@ bun add @secondlayer/subgraphs
|
|
|
12
12
|
|
|
13
13
|
## Quick Start
|
|
14
14
|
|
|
15
|
-
For the full hosted beta loop, including project setup, fast deploys with
|
|
16
|
-
`--start-block`, querying, and webhooks, start with
|
|
17
|
-
[QUICKSTART.md](QUICKSTART.md).
|
|
18
|
-
|
|
19
15
|
```typescript
|
|
20
16
|
import { defineSubgraph } from "@secondlayer/subgraphs";
|
|
21
17
|
|
|
22
18
|
export default defineSubgraph({
|
|
23
19
|
name: "token-transfers",
|
|
24
|
-
version: "1.0.0",
|
|
25
20
|
sources: {
|
|
26
21
|
// Named event sources — the key becomes the handler name.
|
|
27
22
|
transfer: {
|
|
@@ -51,28 +46,25 @@ export default defineSubgraph({
|
|
|
51
46
|
});
|
|
52
47
|
```
|
|
53
48
|
|
|
54
|
-
Deploy via CLI (`secondlayer subgraphs deploy path/to/definition.ts`), SDK (`sl.subgraphs.deploy({...})`), or MCP (`subgraphs_deploy`). The CLI can also scaffold from a deployed contract with `secondlayer subgraphs scaffold <contract> -o subgraphs/name.ts`; scaffold writes or amends `package.json` and runs `bun install` unless `--no-install` is passed.
|
|
49
|
+
Deploy via CLI (`secondlayer subgraphs deploy path/to/definition.ts`), SDK (`sl.subgraphs.deploy({...})`), or MCP (`subgraphs_deploy`). The CLI can also scaffold from a deployed contract with `secondlayer subgraphs scaffold <contract> -o subgraphs/name.ts`; scaffold writes or amends `package.json` and runs `bun install` unless `--no-install` is passed. `secondlayer subgraphs create <name> --from-contract <id>` writes a definition with one `ctx.insert` handler per print topic.
|
|
50
|
+
|
|
51
|
+
Every source needs a handler of the same name. Handlers write with `ctx.insert`, `update`, `upsert`, `delete` and `increment`, and read with `ctx.findOne` / `findMany`. A `contract_call` source with `functionName` gets its `abi` fetched at deploy by the CLI; pass it yourself for wildcard, multi-contract or trait sources, or a local deploy.
|
|
55
52
|
|
|
56
53
|
## Exports
|
|
57
54
|
|
|
58
55
|
| Subpath | Description |
|
|
59
56
|
| --- | --- |
|
|
60
|
-
| `.` | `defineSubgraph`, `validateSubgraphDefinition`, `
|
|
57
|
+
| `.` | `defineSubgraph`, `defineSchema`, `InferContext` / `TypedSubgraphContext`, `readContractAt`, `validateSubgraphDefinition`, ORM generators (`generatePrismaSchema`, `generateDrizzleSchema`, `generateKyselySchema`), `deploySchema`, `diffSchema`, `generateSubgraphSQL`, `pgSchemaName` |
|
|
61
58
|
| `./types` | All schema + filter + handler types (`SubgraphDefinition`, `SubgraphFilter`, `StxTransferFilter`, etc.) |
|
|
62
59
|
| `./schema` | Generator + deployer internals |
|
|
63
60
|
| `./validate` | Shape + filter validation for deploys |
|
|
64
|
-
| `./
|
|
65
|
-
| `./runtime/
|
|
66
|
-
| `./runtime/
|
|
67
|
-
|
|
68
|
-
## Runtime components
|
|
61
|
+
| `./testing` | `runSubgraphTest`, `createTestContext`, `buildEvent`: run handlers against real or built events before deploying |
|
|
62
|
+
| `./runtime/replay` | `replayWebhook({ accountId, webhookId, fromBlock, toBlock })`: re-enqueue historical rows as outbox entries |
|
|
63
|
+
| `./runtime/emitter` | Webhook egress checks used by the API (`checkEgressAllowed`) |
|
|
69
64
|
|
|
70
|
-
|
|
65
|
+
## Runtime
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
- `processBlock(subgraph, name, height, opts?)` — single-block entry point used by catch-up, reindex, and tests.
|
|
74
|
-
- `catchUpSubgraph(def, name)` — drains pending blocks up to chain tip.
|
|
75
|
-
- `reindexSubgraph(def, opts)` — drop + rebuild schema tables from a start block. Breaking schema changes trigger this automatically on deploy.
|
|
67
|
+
The processor runs as a service, not a library import: `bun run packages/subgraphs/src/service.ts` (the `subgraph-processor` container in `docker/`). It LISTENs on `indexer:new_block`, matches sources, runs handlers, flushes writes inside a transaction, and emits outbox rows for matching webhooks. Breaking schema changes trigger a reindex on deploy.
|
|
76
68
|
|
|
77
69
|
## Webhook emitter
|
|
78
70
|
|
|
@@ -80,7 +72,7 @@ Every row written through `ctx.insert()` / `ctx.upsert()` is atomically enqueued
|
|
|
80
72
|
|
|
81
73
|
The emitter drains the outbox via `LISTEN webhooks:new_outbox` and `FOR UPDATE SKIP LOCKED` batch claims. Live deliveries win a 90/10 split over replays. Each row dispatches through the format builder matching the webhook's `format` column (`standard-webhooks`, `inngest`, `trigger`, `cloudflare`, `cloudevents`, `raw`). Retries follow `30s → 2m → 10m → 1h → 6h → 24h → 72h`. Twenty consecutive failures trips the per-sub circuit breaker and pauses the webhook.
|
|
82
74
|
|
|
83
|
-
Delivery bodies and response previews land in `webhook_deliveries`. Rows whose retries exhaust mark `status = 'dead'` in the outbox
|
|
75
|
+
Delivery bodies and response previews land in `webhook_deliveries`. Rows whose retries exhaust mark `status = 'dead'` in the outbox; list them with `secondlayer webhooks dead <id>` and send one again with `secondlayer webhooks requeue`.
|
|
84
76
|
|
|
85
77
|
## Environment
|
|
86
78
|
|
|
@@ -100,13 +92,13 @@ Delivery bodies and response previews land in `webhook_deliveries`. Rows whose r
|
|
|
100
92
|
Once rows land in your DB, generate a typed schema for your ORM:
|
|
101
93
|
|
|
102
94
|
```bash
|
|
95
|
+
secondlayer codegen subgraph subgraphs/my.ts # Kysely (default)
|
|
103
96
|
secondlayer codegen subgraph subgraphs/my.ts --target prisma -o prisma/schema.prisma
|
|
104
97
|
secondlayer codegen subgraph subgraphs/my.ts --target drizzle -o db/schema.ts
|
|
105
98
|
```
|
|
106
99
|
|
|
107
|
-
|
|
108
|
-
`generateDrizzleSchema`
|
|
109
|
-
schema's `relations` metadata. For Kysely, run `kysely-codegen` against the DB.
|
|
100
|
+
The generators are exported too (`generateKyselySchema`, `generatePrismaSchema`,
|
|
101
|
+
`generateDrizzleSchema`). No foreign keys or relation fields are generated.
|
|
110
102
|
Output mirrors the deployed DDL — `prisma db pull` should be a no-op; treat the
|
|
111
103
|
tables as read-only (the processor owns them) and never `migrate`/`push`.
|
|
112
104
|
`uint`→`Decimal`/`numeric` and the `BigInt` id need `.toString()` for JSON.
|
|
@@ -110,22 +110,6 @@ interface SubgraphColumn {
|
|
|
110
110
|
default?: string | number | boolean;
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
|
-
* A foreign-key relation to another table in the same subgraph. Drives DDL FK
|
|
114
|
-
* constraints and ORM codegen (`@relation` in Prisma, `relations()` in Drizzle)
|
|
115
|
-
* so generated clients get typed joins. The referenced columns must form a
|
|
116
|
-
* `uniqueKeys` entry on the target table.
|
|
117
|
-
*/
|
|
118
|
-
interface SubgraphRelation {
|
|
119
|
-
/** Relation field name on this table's generated model (e.g. "pool"). */
|
|
120
|
-
name: string;
|
|
121
|
-
/** Target table name in this subgraph. */
|
|
122
|
-
references: string;
|
|
123
|
-
/** Local column(s) holding the foreign key. */
|
|
124
|
-
fields: string[];
|
|
125
|
-
/** Target column(s) the fields point at (a uniqueKeys entry on the target). */
|
|
126
|
-
referencedColumns: string[];
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
113
|
* Table definition within a subgraph schema.
|
|
130
114
|
*
|
|
131
115
|
* The array fields are `readonly` so a schema literal can be hoisted out of
|
|
@@ -141,8 +125,6 @@ interface SubgraphTable {
|
|
|
141
125
|
indexes?: readonly (readonly string[])[];
|
|
142
126
|
/** Unique key constraints (each entry is an array of column names). Required for upsert. */
|
|
143
127
|
uniqueKeys?: readonly (readonly string[])[];
|
|
144
|
-
/** Foreign-key relations to other tables (for typed ORM joins). */
|
|
145
|
-
relations?: readonly SubgraphRelation[];
|
|
146
128
|
}
|
|
147
129
|
/** Subgraph schema — maps table names to table definitions */
|
|
148
130
|
type SubgraphSchema = Record<string, SubgraphTable>;
|
|
@@ -305,9 +287,8 @@ interface ContractCallFilter extends TraitScope, FactoryScope {
|
|
|
305
287
|
/**
|
|
306
288
|
* One contract id, or a SET of them (max 20) — the standard DeFi shape is
|
|
307
289
|
* a router plus N pools, which used to cost N near-identical sources and
|
|
308
|
-
* handlers
|
|
309
|
-
*
|
|
310
|
-
* `event.contractId` disambiguates.
|
|
290
|
+
* handlers. Payload types are identical per `type`, so one handler serves
|
|
291
|
+
* the set and `event.contractId` disambiguates.
|
|
311
292
|
*
|
|
312
293
|
* Supports `*` wildcards (e.g. `"SP1ABC….pool-*"`). Mutually exclusive
|
|
313
294
|
* with `trait`, which resolves its own set per block.
|
|
@@ -321,8 +302,11 @@ interface ContractCallFilter extends TraitScope, FactoryScope {
|
|
|
321
302
|
* definition and used at runtime to decode args by name. Omit to keep
|
|
322
303
|
* `event.args` as a positional `unknown[]`.
|
|
323
304
|
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
305
|
+
* Required whenever `functionName` is set. `secondlayer subgraphs deploy`
|
|
306
|
+
* fills it in from the deployed contract for a single concrete
|
|
307
|
+
* `contractId`; pass it yourself for wildcard, multi-contract or trait
|
|
308
|
+
* sources, or a local deploy (`normalizeAbi()` from
|
|
309
|
+
* `@secondlayer/stacks/clarity`).
|
|
326
310
|
*/
|
|
327
311
|
abi?: AbiContract2;
|
|
328
312
|
}
|
|
@@ -379,29 +363,9 @@ type PrintField = ColumnType | {
|
|
|
379
363
|
* is skipped and logged rather than written as nulls.
|
|
380
364
|
*/
|
|
381
365
|
type PrintEventPrints = Record<string, Record<string, PrintField>>;
|
|
382
|
-
/**
|
|
383
|
-
* One column in a static identity map. Literals only — the bundler never
|
|
384
|
-
* executes user code, so `{ from: "tokenX" }` is valid and `from("tokenX")`
|
|
385
|
-
* is not.
|
|
386
|
-
*/
|
|
387
|
-
type MaterializeColumn = {
|
|
388
|
-
from: string
|
|
389
|
-
} | {
|
|
390
|
-
fromTx: "sender" | "txId"
|
|
391
|
-
} | {
|
|
392
|
-
fromBlock: "height" | "hash" | "timestamp"
|
|
393
|
-
};
|
|
394
|
-
/** Static insert from a source event — replaces a 1:1 handler. */
|
|
395
|
-
interface MaterializeSpec {
|
|
396
|
-
table: string;
|
|
397
|
-
/** Keys = schema column names (snake). */
|
|
398
|
-
columns: Record<string, MaterializeColumn>;
|
|
399
|
-
}
|
|
400
366
|
type PrintEventFields = FactoryScope & {
|
|
401
367
|
type: "print_event"
|
|
402
368
|
topic?: string
|
|
403
|
-
/** Identity map: insert without a handler function. XOR with handlers[name]. */
|
|
404
|
-
materialize?: MaterializeSpec
|
|
405
369
|
};
|
|
406
370
|
/**
|
|
407
371
|
* Pinned to one or more contract ids with no trait — `prints` is required so
|
|
@@ -447,8 +411,6 @@ interface TxMeta {
|
|
|
447
411
|
}
|
|
448
412
|
/** Scalar types that can appear as row values */
|
|
449
413
|
type RowValue = string | number | bigint | boolean | null | undefined | Record<string, unknown> | unknown[];
|
|
450
|
-
/** Value or computed function that receives existing row */
|
|
451
|
-
type ComputedValue = RowValue | ((existing: Record<string, unknown> | null) => unknown);
|
|
452
414
|
/** Context passed to subgraph handlers during event processing */
|
|
453
415
|
interface SubgraphContext {
|
|
454
416
|
block: {
|
|
@@ -479,27 +441,11 @@ interface SubgraphContext {
|
|
|
479
441
|
* Atomic counter update — the blessed accumulator primitive. Applies
|
|
480
442
|
* `col = COALESCE(col, 0) + delta` per column (insert-or-add); deltas may
|
|
481
443
|
* be negative. Requires a uniqueKeys constraint matching `key`. Prefer
|
|
482
|
-
* this over
|
|
444
|
+
* this over read-modify-write handlers for running totals.
|
|
483
445
|
*/
|
|
484
446
|
increment(table: string, key: Record<string, unknown>, deltas: Record<string, bigint | number>): void;
|
|
485
|
-
/** Partial update — sets only specified fields, preserves others */
|
|
486
|
-
patch(table: string, where: Record<string, unknown>, set: Record<string, unknown>): void;
|
|
487
|
-
/** Find-then-merge-or-insert. Values can be functions: (existing) => newValue */
|
|
488
|
-
patchOrInsert(table: string, key: Record<string, unknown>, row: Record<string, ComputedValue>): Promise<void>;
|
|
489
447
|
findOne(table: string, where: Record<string, unknown>): Promise<Record<string, unknown> | null>;
|
|
490
448
|
findMany(table: string, where: Record<string, unknown>): Promise<Record<string, unknown>[]>;
|
|
491
|
-
/** Format a bigint amount with decimal places */
|
|
492
|
-
formatUnits(value: bigint, decimals: number): string;
|
|
493
|
-
/** Count rows matching filter */
|
|
494
|
-
count(table: string, where?: Record<string, unknown>): Promise<number>;
|
|
495
|
-
/** Sum a numeric column */
|
|
496
|
-
sum(table: string, column: string, where?: Record<string, unknown>): Promise<bigint>;
|
|
497
|
-
/** Min of a numeric column */
|
|
498
|
-
min(table: string, column: string, where?: Record<string, unknown>): Promise<bigint | null>;
|
|
499
|
-
/** Max of a numeric column */
|
|
500
|
-
max(table: string, column: string, where?: Record<string, unknown>): Promise<bigint | null>;
|
|
501
|
-
/** Count distinct values in a column */
|
|
502
|
-
countDistinct(table: string, column: string, where?: Record<string, unknown>): Promise<number>;
|
|
503
449
|
}
|
|
504
450
|
/** Handler function that processes events and writes to the subgraph */
|
|
505
451
|
type SubgraphHandler = (event: Record<string, unknown>, ctx: SubgraphContext) => Promise<void> | void;
|
|
@@ -507,8 +453,6 @@ type SubgraphHandler = (event: Record<string, unknown>, ctx: SubgraphContext) =>
|
|
|
507
453
|
interface SubgraphDefinition {
|
|
508
454
|
/** Unique subgraph name (lowercase, alphanumeric + hyphens) */
|
|
509
455
|
name: string;
|
|
510
|
-
/** Semantic version */
|
|
511
|
-
version?: string;
|
|
512
456
|
/** Human description */
|
|
513
457
|
description?: string;
|
|
514
458
|
/** Block height to start indexing from (default: 1) */
|
|
@@ -520,90 +464,9 @@ interface SubgraphDefinition {
|
|
|
520
464
|
sources: Record<string, SubgraphFilter>;
|
|
521
465
|
/** Tables in this subgraph */
|
|
522
466
|
schema: SubgraphSchema;
|
|
523
|
-
/** Handler functions
|
|
467
|
+
/** Handler functions, one per source, keyed by source name */
|
|
524
468
|
handlers: Record<string, SubgraphHandler>;
|
|
525
469
|
}
|
|
526
|
-
/**
|
|
527
|
-
* Validates a subgraph definition, returning the parsed result or throwing on failure.
|
|
528
|
-
*/
|
|
529
|
-
declare function validateSubgraphDefinition(def: unknown): SubgraphDefinition;
|
|
530
|
-
/**
|
|
531
|
-
* Per-source-type field vocabulary, DERIVED from
|
|
532
|
-
* {@link SubgraphFilterSchema}. Agent-facing surfaces (the MCP filters
|
|
533
|
-
* reference) used to hand-maintain a parallel copy of this list; deriving it
|
|
534
|
-
* means adding a field to a filter can never leave the documentation behind.
|
|
535
|
-
*/
|
|
536
|
-
declare function filterFieldsByType(): Array<{
|
|
537
|
-
type: string
|
|
538
|
-
fields: string[]
|
|
539
|
-
}>;
|
|
540
|
-
/** A (decoded event type, optional contract scope) pair the sparse probe
|
|
541
|
-
* checks. Contract scoping is what makes token-subgraph reindexes leap over
|
|
542
|
-
* everything that isn't their token. */
|
|
543
|
-
type SparseProbeTarget = {
|
|
544
|
-
eventType: string
|
|
545
|
-
contractId?: string
|
|
546
|
-
};
|
|
547
|
-
/** Sparse scanning is sound only when EVERY source is an event-type filter —
|
|
548
|
-
* a contract_call/contract_deploy source matches transactions, which the
|
|
549
|
-
* event probe can't see. */
|
|
550
|
-
declare function canSparseScan(subgraph: SubgraphDefinition): boolean;
|
|
551
|
-
/** Probe targets for a subgraph's filters: decoded type + contract scope when\\n* the filter pins one (assetIdentifier "SP….contract::asset" or contractId). */
|
|
552
|
-
declare function sparseProbeTargets(subgraph: SubgraphDefinition): SparseProbeTarget[];
|
|
553
|
-
interface ReindexOptions {
|
|
554
|
-
/**
|
|
555
|
-
* Floor on the walk's first block — NOT a caller-supplied range. When set
|
|
556
|
-
* (e.g. an op row carrying a `from_block`), it raises the walk start and
|
|
557
|
-
* can never lower it. There is deliberately no `toBlock` counterpart:
|
|
558
|
-
* a reindex always runs to chain tip. See {@link resolveBlockRange}.
|
|
559
|
-
*/
|
|
560
|
-
startBlockFloor?: number;
|
|
561
|
-
schemaName?: string;
|
|
562
|
-
/** Op row to receive processed_events on each progress flush. */
|
|
563
|
-
operationId?: string;
|
|
564
|
-
signal?: AbortSignal;
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Reindex a subgraph by dropping its tables, recreating them, and reprocessing
|
|
568
|
-
* all historical blocks through the handler pipeline.
|
|
569
|
-
*
|
|
570
|
-
* Always whole-subgraph: `[start_block, chain tip]`. There is no ranged
|
|
571
|
-
* reindex — the drop cannot be scoped to a range without re-running delta
|
|
572
|
-
* handlers (`ctx.increment` / `ctx.update` / `ctx.patchOrInsert`) over rows
|
|
573
|
-
* that were never removed, which is the exact double-count hazard `backfill`
|
|
574
|
-
* already refuses. Use `backfillSubgraph` for ranged, additive work.
|
|
575
|
-
*
|
|
576
|
-
* Supports cancellation via AbortSignal — on shutdown abort, status stays
|
|
577
|
-
* "reindexing" for auto-resume; on user cancel, status resets to "active".
|
|
578
|
-
*/
|
|
579
|
-
declare function reindexSubgraph(def: SubgraphDefinition, opts?: ReindexOptions): Promise<{
|
|
580
|
-
processed: number
|
|
581
|
-
}>;
|
|
582
|
-
/**
|
|
583
|
-
* Resume a previously interrupted reindex. Skips schema drop (already done)
|
|
584
|
-
* and continues from last_processed_block + 1.
|
|
585
|
-
*/
|
|
586
|
-
declare function resumeReindex(def: SubgraphDefinition, opts: {
|
|
587
|
-
schemaName: string
|
|
588
|
-
operationId?: string
|
|
589
|
-
signal?: AbortSignal
|
|
590
|
-
}): Promise<{
|
|
591
|
-
processed: number
|
|
592
|
-
}>;
|
|
593
|
-
/**
|
|
594
|
-
* Backfill a subgraph by re-processing a block range WITHOUT dropping the schema.
|
|
595
|
-
* Uses upserts so existing data is updated, not duplicated. Safe to run while
|
|
596
|
-
* the subgraph is actively syncing.
|
|
597
|
-
*/
|
|
598
|
-
declare function backfillSubgraph(def: SubgraphDefinition, opts: {
|
|
599
|
-
fromBlock: number
|
|
600
|
-
toBlock: number
|
|
601
|
-
schemaName?: string
|
|
602
|
-
operationId?: string
|
|
603
|
-
signal?: AbortSignal
|
|
604
|
-
}): Promise<{
|
|
605
|
-
processed: number
|
|
606
|
-
}>;
|
|
607
470
|
import { AbiContract as AbiContract3, ExtractFunctionArgs as ExtractFunctionArgs2, ExtractFunctionNames } from "@secondlayer/stacks/clarity";
|
|
608
471
|
/** Maps a ColumnType string literal to its TypeScript equivalent */
|
|
609
472
|
type ColumnToTS<T extends string> = T extends "uint" | "int" ? bigint : T extends "text" | "principal" | "timestamp" ? string : T extends "boolean" ? boolean : T extends "jsonb" ? Record<string, unknown> : unknown;
|
|
@@ -758,8 +621,6 @@ type WriteColumnType<C extends SubgraphColumn> = C["type"] extends "uint" | "int
|
|
|
758
621
|
* defaulted columns are optional; all others required.
|
|
759
622
|
*/
|
|
760
623
|
type WriteRow<T extends SubgraphTable> = { [K in keyof T["columns"] as IsOptionalColumn<T["columns"][K]> extends true ? never : K] : WriteColumnType<T["columns"][K]> } & { [K in keyof T["columns"] as IsOptionalColumn<T["columns"][K]> extends true ? K : never]? : WriteColumnType<T["columns"][K]> };
|
|
761
|
-
/** Computed-or-value row for `patchOrInsert` — each field may be a function of the existing row. */
|
|
762
|
-
type PatchRow<T extends SubgraphTable> = { [K in keyof WriteRow<T>]? : WriteRow<T>[K] | ((existing: InferTableRow<T> | null) => unknown) };
|
|
763
624
|
type TableName<S extends SubgraphSchema> = keyof S & string;
|
|
764
625
|
type ColumnName<
|
|
765
626
|
S extends SubgraphSchema,
|
|
@@ -799,8 +660,6 @@ interface TypedSubgraphContext<S extends SubgraphSchema> {
|
|
|
799
660
|
K extends Partial<WriteRow<S[T]>>
|
|
800
661
|
>(table: T, key: K, row: Omit<WriteRow<S[T]>, keyof K> & Partial<WriteRow<S[T]>>): void;
|
|
801
662
|
delete<T extends TableName<S>>(table: T, where: RowWhere<S, T>): void;
|
|
802
|
-
patch<T extends TableName<S>>(table: T, where: RowWhere<S, T>, set: Partial<WriteRow<S[T]>>): void;
|
|
803
|
-
patchOrInsert<T extends TableName<S>>(table: T, key: Partial<WriteRow<S[T]>>, row: PatchRow<S[T]> & Record<string, ComputedValue>): Promise<void>;
|
|
804
663
|
/**
|
|
805
664
|
* Atomic accumulator — `INSERT … ON CONFLICT (key) DO UPDATE SET col =
|
|
806
665
|
* COALESCE(col,0) + delta`. Deltas commute, so it's the reorg-safe primitive
|
|
@@ -810,12 +669,6 @@ interface TypedSubgraphContext<S extends SubgraphSchema> {
|
|
|
810
669
|
increment<T extends TableName<S>>(table: T, key: Partial<WriteRow<S[T]>>, deltas: Partial<Record<ColumnName<S, T>, bigint | number>>): void;
|
|
811
670
|
findOne<T extends TableName<S>>(table: T, where: RowWhere<S, T>): Promise<InferTableRow<S[T]> | null>;
|
|
812
671
|
findMany<T extends TableName<S>>(table: T, where: RowWhere<S, T>): Promise<InferTableRow<S[T]>[]>;
|
|
813
|
-
formatUnits(value: bigint, decimals: number): string;
|
|
814
|
-
count<T extends TableName<S>>(table: T, where?: RowWhere<S, T>): Promise<number>;
|
|
815
|
-
sum<T extends TableName<S>>(table: T, column: ColumnName<S, T>, where?: RowWhere<S, T>): Promise<bigint>;
|
|
816
|
-
min<T extends TableName<S>>(table: T, column: ColumnName<S, T>, where?: RowWhere<S, T>): Promise<bigint | null>;
|
|
817
|
-
max<T extends TableName<S>>(table: T, column: ColumnName<S, T>, where?: RowWhere<S, T>): Promise<bigint | null>;
|
|
818
|
-
countDistinct<T extends TableName<S>>(table: T, column: ColumnName<S, T>, where?: RowWhere<S, T>): Promise<number>;
|
|
819
672
|
}
|
|
820
673
|
/** Infer a typed client object from a subgraph definition shape */
|
|
821
674
|
type InferSubgraphClient<T> = T extends {
|
|
@@ -1015,29 +868,22 @@ type EventForFilter<F extends SubgraphFilter> = F extends {
|
|
|
1015
868
|
} ? VarSetPayload : F extends {
|
|
1016
869
|
type: infer T extends "map_set" | "map_insert" | "map_delete"
|
|
1017
870
|
} ? T extends "map_delete" ? MapDeletePayload : MapWritePayload : never;
|
|
1018
|
-
/** Union of every event payload
|
|
871
|
+
/** Union of every event payload. */
|
|
1019
872
|
type AnyEvent = FtTransferPayload | FtMintPayload | FtBurnPayload | NftTransferPayload | NftMintPayload | NftBurnPayload | StxTransferPayload | StxMintPayload | StxBurnPayload | StxLockPayload | PrintEventPayload | ContractCallEvent | ContractDeployPayload | NestedContractCallPayload | VarSetPayload | MapWritePayload | MapDeletePayload;
|
|
1020
873
|
type HandlerFn<
|
|
1021
874
|
F extends SubgraphFilter,
|
|
1022
875
|
S extends SubgraphSchema
|
|
1023
876
|
> = (event: EventForFilter<F>, ctx: TypedSubgraphContext<S>) => void | Promise<void>;
|
|
1024
|
-
type SourceHasMaterialize<F> = F extends {
|
|
1025
|
-
materialize: MaterializeSpec
|
|
1026
|
-
} ? true : false;
|
|
1027
877
|
/**
|
|
1028
|
-
* Handlers keyed by source name. Each handler's `event` is
|
|
1029
|
-
* matching source's filter `type` (e.g. a `print_event` source
|
|
1030
|
-
*
|
|
1031
|
-
* names + row columns checked).
|
|
1032
|
-
* handler; every other source key is required. Optional `"*"` catch-all
|
|
1033
|
-
* receives any event (validate also accepts `*` alone).
|
|
878
|
+
* Handlers keyed by source name, one per source. Each handler's `event` is
|
|
879
|
+
* typed from the matching source's filter `type` (e.g. a `print_event` source
|
|
880
|
+
* gives `event.topic: string`), and `ctx` is typed against the subgraph
|
|
881
|
+
* `schema` (table names + row columns checked).
|
|
1034
882
|
*/
|
|
1035
883
|
type TypedHandlers<
|
|
1036
884
|
Sources extends Record<string, SubgraphFilter>,
|
|
1037
885
|
S extends SubgraphSchema
|
|
1038
|
-
> = { [K in keyof Sources
|
|
1039
|
-
"*"?: (event: AnyEvent, ctx: TypedSubgraphContext<S>) => void | Promise<void>
|
|
1040
|
-
};
|
|
886
|
+
> = { [K in keyof Sources]-? : HandlerFn<Sources[K], S> };
|
|
1041
887
|
/** Subgraph definition with `sources`/`schema` literals preserved for typed
|
|
1042
888
|
* handlers and downstream query-client inference (`getSubgraph`). */
|
|
1043
889
|
type TypedSubgraphDefinition<
|
|
@@ -1113,6 +959,20 @@ declare function defineSchema<const S extends SubgraphSchema>(schema: S): S;
|
|
|
1113
959
|
type InferContext<D> = D extends {
|
|
1114
960
|
schema: infer S extends SubgraphSchema
|
|
1115
961
|
} ? TypedSubgraphContext<S> : never;
|
|
962
|
+
/**
|
|
963
|
+
* Validates a subgraph definition, returning the parsed result or throwing on failure.
|
|
964
|
+
*/
|
|
965
|
+
declare function validateSubgraphDefinition(def: unknown): SubgraphDefinition;
|
|
966
|
+
/**
|
|
967
|
+
* Per-source-type field vocabulary, DERIVED from
|
|
968
|
+
* {@link SubgraphFilterSchema}. Agent-facing surfaces (the MCP filters
|
|
969
|
+
* reference) used to hand-maintain a parallel copy of this list; deriving it
|
|
970
|
+
* means adding a field to a filter can never leave the documentation behind.
|
|
971
|
+
*/
|
|
972
|
+
declare function filterFieldsByType(): Array<{
|
|
973
|
+
type: string
|
|
974
|
+
fields: string[]
|
|
975
|
+
}>;
|
|
1116
976
|
type PrintValidationResult = {
|
|
1117
977
|
ok: true
|
|
1118
978
|
} | {
|
|
@@ -1120,12 +980,6 @@ type PrintValidationResult = {
|
|
|
1120
980
|
reason: string
|
|
1121
981
|
};
|
|
1122
982
|
/**
|
|
1123
|
-
* Validate one decoded print event against a source's `prints` declaration.
|
|
1124
|
-
* Returns `{ ok: true }` when no declaration covers this topic (undeclared
|
|
1125
|
-
* topics are not the developer's stated contract, so they pass through).
|
|
1126
|
-
*/
|
|
1127
|
-
declare function validatePrintPayload(prints: Record<string, Record<string, PrintField>> | undefined, topic: string, data: Record<string, unknown>): PrintValidationResult;
|
|
1128
|
-
/**
|
|
1129
983
|
* Empirical print-payload schema inference. Callers (the index print-schema
|
|
1130
984
|
* endpoint) extract topic + raw Clarity hex per row; this module deserializes
|
|
1131
985
|
* a bounded sample per topic, unifies the observed value shapes into a single
|
|
@@ -1159,13 +1013,6 @@ interface InferredTopicSchema {
|
|
|
1159
1013
|
non_tuple: boolean;
|
|
1160
1014
|
fields: InferredPrintField[];
|
|
1161
1015
|
}
|
|
1162
|
-
/**
|
|
1163
|
-
* Kebab-case → camelCase for print tuple keys. Canonical: the runner uses
|
|
1164
|
-
* this on `event.data`, and `camel_name` in inferred print schema is the
|
|
1165
|
-
* same function. Distinct from ABI `toCamelCase` (`transfer-STX` stays
|
|
1166
|
-
* `transfer-STX` here, becomes `transferSTX` there).
|
|
1167
|
-
*/
|
|
1168
|
-
declare function camelizeDataKey(str: string): string;
|
|
1169
1016
|
/** Recursively camelize object keys with the print-payload helper (not ABI
|
|
1170
1017
|
* `toCamelCase` — that one strips `-STX` and prefixes leading digits). */
|
|
1171
1018
|
declare function camelizeKeys(obj: unknown): unknown;
|
|
@@ -1229,12 +1076,10 @@ interface IndexCodegenOptions {
|
|
|
1229
1076
|
datasourceEnv?: string;
|
|
1230
1077
|
}
|
|
1231
1078
|
declare function generateIndexSchema(target: IndexCodegenTarget, opts?: IndexCodegenOptions): string;
|
|
1232
|
-
/** Index tables available to codegen, for help text and validation. */
|
|
1233
|
-
declare const INDEX_CODEGEN_TABLES: readonly string[];
|
|
1234
1079
|
import { pgSchemaName } from "@secondlayer/shared/db/queries/subgraphs";
|
|
1235
|
-
import { Database as
|
|
1236
|
-
import { Kysely as
|
|
1237
|
-
type AnyDb =
|
|
1080
|
+
import { Database as Database2 } from "@secondlayer/shared/db";
|
|
1081
|
+
import { Kysely as Kysely2 } from "kysely";
|
|
1082
|
+
type AnyDb = Kysely2<Database2>;
|
|
1238
1083
|
interface TableDiff {
|
|
1239
1084
|
/** Tables added to the schema */
|
|
1240
1085
|
addedTables: string[];
|
|
@@ -1316,7 +1161,6 @@ declare function deploySchema(db: AnyDb, def: SubgraphDefinition, handlerPath: s
|
|
|
1316
1161
|
apiKeyId?: string
|
|
1317
1162
|
accountId?: string
|
|
1318
1163
|
schemaName?: string
|
|
1319
|
-
version?: string
|
|
1320
1164
|
handlerCode?: string
|
|
1321
1165
|
sourceCode?: string
|
|
1322
1166
|
}): Promise<{
|
|
@@ -1327,4 +1171,30 @@ declare function deploySchema(db: AnyDb, def: SubgraphDefinition, handlerPath: s
|
|
|
1327
1171
|
/** Non-fatal caveats the caller should surface (e.g. handler grafts at tip). */
|
|
1328
1172
|
warnings?: string[]
|
|
1329
1173
|
}>;
|
|
1330
|
-
|
|
1174
|
+
/** A (decoded event type, optional contract scope) pair the sparse probe
|
|
1175
|
+
* checks. Contract scoping is what makes token-subgraph reindexes leap over
|
|
1176
|
+
* everything that isn't their token. */
|
|
1177
|
+
type SparseProbeTarget = {
|
|
1178
|
+
eventType: string
|
|
1179
|
+
contractId?: string
|
|
1180
|
+
};
|
|
1181
|
+
/** Sparse scanning is sound only when EVERY source is an event-type filter —
|
|
1182
|
+
* a contract_call/contract_deploy source matches transactions, which the
|
|
1183
|
+
* event probe can't see. */
|
|
1184
|
+
declare function canSparseScan(subgraph: SubgraphDefinition): boolean;
|
|
1185
|
+
/** Probe targets for a subgraph's filters: decoded type + contract scope when\\n* the filter pins one (assetIdentifier "SP….contract::asset" or contractId). */
|
|
1186
|
+
declare function sparseProbeTargets(subgraph: SubgraphDefinition): SparseProbeTarget[];
|
|
1187
|
+
interface ReindexOptions {
|
|
1188
|
+
/**
|
|
1189
|
+
* Floor on the walk's first block — NOT a caller-supplied range. When set
|
|
1190
|
+
* (e.g. an op row carrying a `from_block`), it raises the walk start and
|
|
1191
|
+
* can never lower it. There is deliberately no `toBlock` counterpart:
|
|
1192
|
+
* a reindex always runs to chain tip. See {@link resolveBlockRange}.
|
|
1193
|
+
*/
|
|
1194
|
+
startBlockFloor?: number;
|
|
1195
|
+
schemaName?: string;
|
|
1196
|
+
/** Op row to receive processed_events on each progress flush. */
|
|
1197
|
+
operationId?: string;
|
|
1198
|
+
signal?: AbortSignal;
|
|
1199
|
+
}
|
|
1200
|
+
export { AggregateResult, AggregateSpec, AnyEvent, ChainReadCacheMode, ChainReadClient, ChainReadError, ChainReadMethods, ChainReadOptions, ColumnDiff, ColumnToTS, ColumnType, ComparisonFilter, ContractCallEvent, ContractCallFilter, ContractCallPayload, ContractDeployFilter, ContractDeployPayload, DeployDiff, DeployPlan, DrizzleGenOptions, ErasedChainReadClient, EventForFilter, FactoryScope, FindManyOptions, FtBurnFilter, FtBurnPayload, FtMintFilter, FtMintPayload, FtTransferFilter, FtTransferPayload, GeneratedSQL, IndexCodegenOptions, IndexCodegenTarget, InferColumnType, InferContext, InferSubgraphClient, InferTableRow, InferredPrintField, InferredTopicSchema, KyselyGenOptions, MapDeletePayload, MapWritePayload, NestedContractCallPayload, NftBurnFilter, NftBurnPayload, NftMintFilter, NftMintPayload, NftTransferFilter, NftTransferPayload, PinnedPrintEventFilter, PrintDataOf, PrintEventFilter, PrintEventFor, PrintEventPayload, PrintEventPrints, PrintField, PrintFieldToTS, PrintSample, PrintValidationResult, PrismaGenOptions, ReindexOptions, RowValue, SparseProbeTarget, StxBurnFilter, StxBurnPayload, StxLockFilter, StxLockPayload, StxMintFilter, StxMintPayload, StxTransferFilter, StxTransferPayload, SubgraphColumn, SubgraphContext, SubgraphDefinition, SubgraphFilter, SubgraphHandler, SubgraphSchema, SubgraphTable, SubgraphTableClient, SubscribeOptions, SystemRow, TableDiff, TraitPrintEventFilter, TxMeta, TypedHandlers, TypedSubgraphContext, TypedSubgraphDefinition, UnpinnedPrintEventFilter, VarSetPayload, WhereInput, WriteRow, camelizeKeys, canSparseScan, defineSchema, defineSubgraph, deploySchema, diffSchema, filterFieldsByType, generateDrizzleSchema, generateIndexSchema, generateKyselySchema, generatePrismaSchema, generateSubgraphSQL, hasBreakingChanges, inferPrintTopics, pgSchemaName, readContractAt, renderDeployPlan, sparseProbeTargets, validateSubgraphDefinition };
|