@secondlayer/shared 7.11.2 → 9.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.
Files changed (60) hide show
  1. package/dist/src/archive/range-digest.d.ts +16 -169
  2. package/dist/src/archive/semantic-digest-builder.d.ts +16 -169
  3. package/dist/src/archive/status.js +11 -3
  4. package/dist/src/archive/status.js.map +3 -3
  5. package/dist/src/coverage/index.d.ts +15 -169
  6. package/dist/src/crypto/secrets.js +22 -3
  7. package/dist/src/crypto/secrets.js.map +3 -3
  8. package/dist/src/db/index.d.ts +18 -211
  9. package/dist/src/db/index.js +23 -16
  10. package/dist/src/db/index.js.map +4 -4
  11. package/dist/src/db/queries/chain-reorgs.d.ts +16 -169
  12. package/dist/src/db/queries/chain-reorgs.js +23 -16
  13. package/dist/src/db/queries/chain-reorgs.js.map +4 -4
  14. package/dist/src/db/queries/contracts.d.ts +16 -169
  15. package/dist/src/db/queries/instance.d.ts +16 -169
  16. package/dist/src/db/queries/integrity.d.ts +16 -169
  17. package/dist/src/db/queries/subgraph-gaps.d.ts +16 -169
  18. package/dist/src/db/queries/subgraph-operations.d.ts +17 -170
  19. package/dist/src/db/queries/subgraph-operations.js +1 -15
  20. package/dist/src/db/queries/subgraph-operations.js.map +3 -3
  21. package/dist/src/db/queries/subgraphs.d.ts +17 -191
  22. package/dist/src/db/queries/subgraphs.js +30 -1068
  23. package/dist/src/db/queries/subgraphs.js.map +5 -12
  24. package/dist/src/db/queries/subscriptions.d.ts +16 -169
  25. package/dist/src/db/queries/subscriptions.js +22 -3
  26. package/dist/src/db/queries/subscriptions.js.map +3 -3
  27. package/dist/src/db/queries/sync-scope.d.ts +1006 -0
  28. package/dist/src/db/queries/sync-scope.js +116 -0
  29. package/dist/src/db/queries/sync-scope.js.map +10 -0
  30. package/dist/src/db/schema.d.ts +17 -198
  31. package/dist/src/errors.d.ts +1 -22
  32. package/dist/src/errors.js +2 -4
  33. package/dist/src/errors.js.map +3 -3
  34. package/dist/src/index.d.ts +22 -256
  35. package/dist/src/index.js +24 -20
  36. package/dist/src/index.js.map +6 -6
  37. package/dist/src/mode.d.ts +16 -2
  38. package/dist/src/mode.js +25 -4
  39. package/dist/src/mode.js.map +3 -3
  40. package/dist/src/node/local-client.d.ts +16 -169
  41. package/dist/src/runtime/index.d.ts +137 -18
  42. package/dist/src/runtime/index.js +261 -41
  43. package/dist/src/runtime/index.js.map +9 -7
  44. package/dist/src/schemas/index.d.ts +5 -25
  45. package/dist/src/schemas/index.js +1 -2
  46. package/dist/src/schemas/index.js.map +3 -3
  47. package/dist/src/schemas/subgraphs.d.ts +5 -25
  48. package/dist/src/schemas/subgraphs.js +1 -2
  49. package/dist/src/schemas/subgraphs.js.map +3 -3
  50. package/dist/src/streams-rows/index.d.ts +399 -0
  51. package/dist/src/streams-rows/index.js +336 -0
  52. package/dist/src/streams-rows/index.js.map +17 -0
  53. package/dist/src/subgraphs/spec.d.ts +0 -9
  54. package/migrations/0118_drop_retired_control_tables.ts +53 -0
  55. package/migrations/0119_drop_accounts_plan.ts +29 -0
  56. package/migrations/0120_sync_scopes.ts +42 -0
  57. package/package.json +10 -6
  58. package/dist/src/x402.d.ts +0 -47
  59. package/dist/src/x402.js +0 -79
  60. package/dist/src/x402.js.map +0 -10
@@ -0,0 +1,336 @@
1
+ import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+
17
+ // src/streams-rows/clarity.ts
18
+ import { cvToValue, deserializeCV } from "@secondlayer/stacks/clarity";
19
+ function toJsonSafe(value) {
20
+ if (typeof value === "bigint")
21
+ return value.toString();
22
+ if (Array.isArray(value))
23
+ return value.map(toJsonSafe);
24
+ if (value && typeof value === "object") {
25
+ const out = {};
26
+ for (const [key, val] of Object.entries(value)) {
27
+ out[key] = toJsonSafe(val);
28
+ }
29
+ return out;
30
+ }
31
+ return value;
32
+ }
33
+ function decodeClarityValue(hex) {
34
+ try {
35
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
36
+ return toJsonSafe(cvToValue(deserializeCV(clean)));
37
+ } catch {
38
+ return hex;
39
+ }
40
+ }
41
+ // src/event-types.ts
42
+ import { DECODED_EVENT_TYPES } from "@secondlayer/stacks/filters";
43
+ import {
44
+ DECODED_EVENT_TYPES as DECODED_EVENT_TYPES2
45
+ } from "@secondlayer/stacks/filters";
46
+ var STREAMS_EVENT_TYPES = DECODED_EVENT_TYPES;
47
+ // src/streams-rows/_payload.ts
48
+ function requireString(payload, field, eventType) {
49
+ const value = payload[field];
50
+ if (typeof value !== "string" || value.length === 0) {
51
+ throw new Error(`${eventType} payload missing ${field}`);
52
+ }
53
+ return value;
54
+ }
55
+ function optionalString(value) {
56
+ return typeof value === "string" && value.length > 0 ? value : null;
57
+ }
58
+ function requireAmountField(payload, field, eventType) {
59
+ const amount = requireString(payload, field, eventType);
60
+ if (!/^(0|[1-9]\d*)$/.test(amount)) {
61
+ throw new Error(`${eventType} payload has malformed ${field}`);
62
+ }
63
+ return amount;
64
+ }
65
+ function requireAmount(payload, eventType) {
66
+ return requireAmountField(payload, "amount", eventType);
67
+ }
68
+ function parseAssetIdentifier(assetIdentifier, eventType) {
69
+ const [contractId, tokenName] = assetIdentifier.split("::");
70
+ if (!contractId) {
71
+ throw new Error(`${eventType} payload has malformed asset_identifier`);
72
+ }
73
+ return {
74
+ contract_id: contractId,
75
+ token_name: tokenName && tokenName.length > 0 ? tokenName : null
76
+ };
77
+ }
78
+ function requireHexValue(payload, eventType) {
79
+ const rawValue = payload.raw_value;
80
+ if (typeof rawValue === "string") {
81
+ if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
82
+ throw new Error(`${eventType} payload has malformed value`);
83
+ }
84
+ return rawValue;
85
+ }
86
+ const value = payload.value;
87
+ const hex = typeof value === "string" ? value : value && typeof value === "object" && typeof value.hex === "string" ? value.hex : null;
88
+ if (!hex) {
89
+ throw new Error(`${eventType} payload missing value`);
90
+ }
91
+ if (!/^0x[0-9a-fA-F]*$/.test(hex)) {
92
+ throw new Error(`${eventType} payload has malformed value`);
93
+ }
94
+ return hex;
95
+ }
96
+ function decodedRow(event, eventType, decoded_payload) {
97
+ return {
98
+ cursor: event.cursor,
99
+ block_height: event.block_height,
100
+ tx_id: event.tx_id,
101
+ tx_index: event.tx_index,
102
+ event_index: event.event_index,
103
+ event_type: eventType,
104
+ decoded_payload,
105
+ source_cursor: event.cursor
106
+ };
107
+ }
108
+ // src/streams-rows/ft-transfer.ts
109
+ function isFtTransfer(event) {
110
+ return event.event_type === "ft_transfer";
111
+ }
112
+ function decodeFtTransfer(event) {
113
+ if (!isFtTransfer(event)) {
114
+ throw new Error(`Expected ft_transfer event, got ${event.event_type}`);
115
+ }
116
+ const payload = event.payload;
117
+ const assetIdentifier = requireString(payload, "asset_identifier", "ft_transfer");
118
+ const sender = requireString(payload, "sender", "ft_transfer");
119
+ const recipient = requireString(payload, "recipient", "ft_transfer");
120
+ const amount = requireAmount(payload, "ft_transfer");
121
+ const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, "ft_transfer");
122
+ return decodedRow(event, "ft_transfer", {
123
+ asset_identifier: assetIdentifier,
124
+ contract_id: event.contract_id ?? contract_id,
125
+ token_name,
126
+ sender,
127
+ recipient,
128
+ amount
129
+ });
130
+ }
131
+ // src/streams-rows/nft-transfer.ts
132
+ function isNftTransfer(event) {
133
+ return event.event_type === "nft_transfer";
134
+ }
135
+ function decodeNftTransfer(event) {
136
+ if (!isNftTransfer(event)) {
137
+ throw new Error(`Expected nft_transfer event, got ${event.event_type}`);
138
+ }
139
+ const payload = event.payload;
140
+ const assetIdentifier = requireString(payload, "asset_identifier", "nft_transfer");
141
+ const sender = requireString(payload, "sender", "nft_transfer");
142
+ const recipient = requireString(payload, "recipient", "nft_transfer");
143
+ const value = requireHexValue(payload, "nft_transfer");
144
+ const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, "nft_transfer");
145
+ return decodedRow(event, "nft_transfer", {
146
+ asset_identifier: assetIdentifier,
147
+ contract_id: event.contract_id ?? contract_id,
148
+ token_name,
149
+ sender,
150
+ recipient,
151
+ value
152
+ });
153
+ }
154
+ // src/streams-rows/print.ts
155
+ function printValueHex(payload) {
156
+ if (typeof payload.raw_value === "string")
157
+ return payload.raw_value;
158
+ const value = payload.value;
159
+ if (typeof value === "string" && value.startsWith("0x"))
160
+ return value;
161
+ if (value && typeof value === "object" && typeof value.hex === "string") {
162
+ return value.hex;
163
+ }
164
+ return null;
165
+ }
166
+ function isPrint(event) {
167
+ return event.event_type === "print";
168
+ }
169
+ function decodePrint(event) {
170
+ if (!isPrint(event)) {
171
+ throw new Error(`Expected print event, got ${event.event_type}`);
172
+ }
173
+ const payload = event.payload;
174
+ const topic = optionalString(payload.topic);
175
+ const rawValue = printValueHex(payload);
176
+ const value = rawValue ? decodeClarityValue(rawValue) : toJsonSafe(payload.value ?? null);
177
+ return decodedRow(event, "print", {
178
+ contract_id: event.contract_id ?? optionalString(payload.contract_id),
179
+ payload: { topic, value, raw_value: rawValue }
180
+ });
181
+ }
182
+ // src/streams-rows/stx-events.ts
183
+ function isStxTransfer(event) {
184
+ return event.event_type === "stx_transfer";
185
+ }
186
+ function decodeStxTransfer(event) {
187
+ if (!isStxTransfer(event)) {
188
+ throw new Error(`Expected stx_transfer event, got ${event.event_type}`);
189
+ }
190
+ const payload = event.payload;
191
+ return decodedRow(event, "stx_transfer", {
192
+ sender: requireString(payload, "sender", "stx_transfer"),
193
+ recipient: requireString(payload, "recipient", "stx_transfer"),
194
+ amount: requireAmount(payload, "stx_transfer"),
195
+ memo: optionalString(payload.memo)
196
+ });
197
+ }
198
+ function isStxMint(event) {
199
+ return event.event_type === "stx_mint";
200
+ }
201
+ function decodeStxMint(event) {
202
+ if (!isStxMint(event)) {
203
+ throw new Error(`Expected stx_mint event, got ${event.event_type}`);
204
+ }
205
+ const payload = event.payload;
206
+ return decodedRow(event, "stx_mint", {
207
+ recipient: requireString(payload, "recipient", "stx_mint"),
208
+ amount: requireAmount(payload, "stx_mint")
209
+ });
210
+ }
211
+ function isStxBurn(event) {
212
+ return event.event_type === "stx_burn";
213
+ }
214
+ function decodeStxBurn(event) {
215
+ if (!isStxBurn(event)) {
216
+ throw new Error(`Expected stx_burn event, got ${event.event_type}`);
217
+ }
218
+ const payload = event.payload;
219
+ return decodedRow(event, "stx_burn", {
220
+ sender: requireString(payload, "sender", "stx_burn"),
221
+ amount: requireAmount(payload, "stx_burn")
222
+ });
223
+ }
224
+ function isStxLock(event) {
225
+ return event.event_type === "stx_lock";
226
+ }
227
+ function decodeStxLock(event) {
228
+ if (!isStxLock(event)) {
229
+ throw new Error(`Expected stx_lock event, got ${event.event_type}`);
230
+ }
231
+ const payload = event.payload;
232
+ return decodedRow(event, "stx_lock", {
233
+ sender: requireString(payload, "locked_address", "stx_lock"),
234
+ amount: requireAmountField(payload, "locked_amount", "stx_lock"),
235
+ payload: { unlock_height: optionalString(payload.unlock_height) }
236
+ });
237
+ }
238
+ // src/streams-rows/token-mint-burn.ts
239
+ function assetFields(event, eventType) {
240
+ const assetIdentifier = requireString(event.payload, "asset_identifier", eventType);
241
+ const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, eventType);
242
+ return {
243
+ asset_identifier: assetIdentifier,
244
+ contract_id: event.contract_id ?? contract_id,
245
+ token_name
246
+ };
247
+ }
248
+ function isFtMint(event) {
249
+ return event.event_type === "ft_mint";
250
+ }
251
+ function decodeFtMint(event) {
252
+ if (!isFtMint(event)) {
253
+ throw new Error(`Expected ft_mint event, got ${event.event_type}`);
254
+ }
255
+ return decodedRow(event, "ft_mint", {
256
+ ...assetFields(event, "ft_mint"),
257
+ recipient: requireString(event.payload, "recipient", "ft_mint"),
258
+ amount: requireAmount(event.payload, "ft_mint")
259
+ });
260
+ }
261
+ function isFtBurn(event) {
262
+ return event.event_type === "ft_burn";
263
+ }
264
+ function decodeFtBurn(event) {
265
+ if (!isFtBurn(event)) {
266
+ throw new Error(`Expected ft_burn event, got ${event.event_type}`);
267
+ }
268
+ return decodedRow(event, "ft_burn", {
269
+ ...assetFields(event, "ft_burn"),
270
+ sender: requireString(event.payload, "sender", "ft_burn"),
271
+ amount: requireAmount(event.payload, "ft_burn")
272
+ });
273
+ }
274
+ function isNftMint(event) {
275
+ return event.event_type === "nft_mint";
276
+ }
277
+ function decodeNftMint(event) {
278
+ if (!isNftMint(event)) {
279
+ throw new Error(`Expected nft_mint event, got ${event.event_type}`);
280
+ }
281
+ return decodedRow(event, "nft_mint", {
282
+ ...assetFields(event, "nft_mint"),
283
+ recipient: requireString(event.payload, "recipient", "nft_mint"),
284
+ value: requireHexValue(event.payload, "nft_mint")
285
+ });
286
+ }
287
+ function isNftBurn(event) {
288
+ return event.event_type === "nft_burn";
289
+ }
290
+ function decodeNftBurn(event) {
291
+ if (!isNftBurn(event)) {
292
+ throw new Error(`Expected nft_burn event, got ${event.event_type}`);
293
+ }
294
+ return decodedRow(event, "nft_burn", {
295
+ ...assetFields(event, "nft_burn"),
296
+ sender: requireString(event.payload, "sender", "nft_burn"),
297
+ value: requireHexValue(event.payload, "nft_burn")
298
+ });
299
+ }
300
+ export {
301
+ toJsonSafe,
302
+ requireString,
303
+ requireHexValue,
304
+ requireAmountField,
305
+ requireAmount,
306
+ parseAssetIdentifier,
307
+ optionalString,
308
+ isStxTransfer,
309
+ isStxMint,
310
+ isStxLock,
311
+ isStxBurn,
312
+ isPrint,
313
+ isNftTransfer,
314
+ isNftMint,
315
+ isNftBurn,
316
+ isFtTransfer,
317
+ isFtMint,
318
+ isFtBurn,
319
+ decodedRow,
320
+ decodeStxTransfer,
321
+ decodeStxMint,
322
+ decodeStxLock,
323
+ decodeStxBurn,
324
+ decodePrint,
325
+ decodeNftTransfer,
326
+ decodeNftMint,
327
+ decodeNftBurn,
328
+ decodeFtTransfer,
329
+ decodeFtMint,
330
+ decodeFtBurn,
331
+ decodeClarityValue,
332
+ STREAMS_EVENT_TYPES
333
+ };
334
+
335
+ //# debugId=931E315D241CB50664756E2164756E21
336
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,17 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/streams-rows/clarity.ts", "../src/event-types.ts", "../src/streams-rows/_payload.ts", "../src/streams-rows/ft-transfer.ts", "../src/streams-rows/nft-transfer.ts", "../src/streams-rows/print.ts", "../src/streams-rows/stx-events.ts", "../src/streams-rows/token-mint-burn.ts"],
4
+ "sourcesContent": [
5
+ "import { cvToValue, deserializeCV } from \"@secondlayer/stacks/clarity\";\n\n/** Make a cvToValue result JSON-serializable: Clarity (u)ints decode to bigint,\n * which JSON.stringify can't handle — convert recursively to strings. */\nexport function toJsonSafe(value: unknown): unknown {\n\tif (typeof value === \"bigint\") return value.toString();\n\tif (Array.isArray(value)) return value.map(toJsonSafe);\n\tif (value && typeof value === \"object\") {\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [key, val] of Object.entries(value)) {\n\t\t\tout[key] = toJsonSafe(val);\n\t\t}\n\t\treturn out;\n\t}\n\treturn value;\n}\n\n/** Decode a hex-encoded Clarity value to JSON-safe JS (uints as strings,\n * buffers as `0x…` hex, tuples as objects). Returns the input hex on failure. */\nexport function decodeClarityValue(hex: string): unknown {\n\ttry {\n\t\tconst clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n\t\treturn toJsonSafe(cvToValue(deserializeCV(clean)));\n\t} catch {\n\t\treturn hex;\n\t}\n}\n",
6
+ "// The decoded event-type vocabulary — canonical home is now\n// `@secondlayer/stacks/filters` (the LEAF of the dependency graph: shared\n// depends on stacks, never the reverse, so no package can drift a private\n// copy upward). Re-exported here so every existing `@secondlayer/shared`\n// import keeps working unchanged.\nimport { DECODED_EVENT_TYPES } from \"@secondlayer/stacks/filters\";\nimport type { DecodedEventType } from \"@secondlayer/stacks/filters\";\n\nexport {\n\tDECODED_EVENT_TYPES,\n\ttype DecodedEventType,\n} from \"@secondlayer/stacks/filters\";\n\n/** Alias kept for the Streams surface (identical to {@link DECODED_EVENT_TYPES}).\n * Explicit type annotation required — isolatedDeclarations emits `unknown` for\n * a bare const-to-const alias. */\nexport const STREAMS_EVENT_TYPES: typeof DECODED_EVENT_TYPES =\n\tDECODED_EVENT_TYPES;\nexport type StreamsEventType = DecodedEventType;\n",
7
+ "import type { StreamsEvent } from \"./events.ts\";\n\n/** Superset of the columns the decoded_events table holds. Every decoded\n * event's `decoded_payload` is assignable to this, so the indexer's writer\n * can map columns generically instead of per-event-type. */\nexport type DecodedEventColumns = {\n\tcontract_id?: string | null;\n\tasset_identifier?: string | null;\n\tsender?: string | null;\n\trecipient?: string | null;\n\tamount?: string | null;\n\tvalue?: string | null;\n\tmemo?: string | null;\n\t/** JSONB overflow for non-flat types (e.g. print's decoded value). */\n\tpayload?: unknown;\n};\n\nexport function requireString(\n\tpayload: Record<string, unknown>,\n\tfield: string,\n\teventType: string,\n): string {\n\tconst value = payload[field];\n\tif (typeof value !== \"string\" || value.length === 0) {\n\t\tthrow new Error(`${eventType} payload missing ${field}`);\n\t}\n\treturn value;\n}\n\nexport function optionalString(value: unknown): string | null {\n\treturn typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nexport function requireAmountField(\n\tpayload: Record<string, unknown>,\n\tfield: string,\n\teventType: string,\n): string {\n\tconst amount = requireString(payload, field, eventType);\n\tif (!/^(0|[1-9]\\d*)$/.test(amount)) {\n\t\tthrow new Error(`${eventType} payload has malformed ${field}`);\n\t}\n\treturn amount;\n}\n\nexport function requireAmount(\n\tpayload: Record<string, unknown>,\n\teventType: string,\n): string {\n\treturn requireAmountField(payload, \"amount\", eventType);\n}\n\nexport function parseAssetIdentifier(\n\tassetIdentifier: string,\n\teventType: string,\n): { contract_id: string; token_name: string | null } {\n\tconst [contractId, tokenName] = assetIdentifier.split(\"::\");\n\tif (!contractId) {\n\t\tthrow new Error(`${eventType} payload has malformed asset_identifier`);\n\t}\n\treturn {\n\t\tcontract_id: contractId,\n\t\ttoken_name: tokenName && tokenName.length > 0 ? tokenName : null,\n\t};\n}\n\n/** NFT token id: live streams emits a typed Clarity value at `value` and the\n * canonical hex at `raw_value`; prefer raw_value when present. */\nexport function requireHexValue(\n\tpayload: Record<string, unknown>,\n\teventType: string,\n): string {\n\tconst rawValue = payload.raw_value;\n\tif (typeof rawValue === \"string\") {\n\t\tif (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {\n\t\t\tthrow new Error(`${eventType} payload has malformed value`);\n\t\t}\n\t\treturn rawValue;\n\t}\n\n\tconst value = payload.value;\n\tconst hex =\n\t\ttypeof value === \"string\"\n\t\t\t? value\n\t\t\t: value &&\n\t\t\t\t\ttypeof value === \"object\" &&\n\t\t\t\t\ttypeof (value as { hex?: unknown }).hex === \"string\"\n\t\t\t\t? (value as { hex: string }).hex\n\t\t\t\t: null;\n\n\tif (!hex) {\n\t\tthrow new Error(`${eventType} payload missing value`);\n\t}\n\tif (!/^0x[0-9a-fA-F]*$/.test(hex)) {\n\t\tthrow new Error(`${eventType} payload has malformed value`);\n\t}\n\treturn hex;\n}\n\n/** Common envelope fields shared by every decoded event, lifted off the\n * source StreamsEvent. The decoder supplies event_type + decoded_payload. */\nexport function decodedRow<T extends string, P>(\n\tevent: StreamsEvent,\n\teventType: T,\n\tdecoded_payload: P,\n): {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: T;\n\tdecoded_payload: P;\n\tsource_cursor: string;\n} {\n\treturn {\n\t\tcursor: event.cursor,\n\t\tblock_height: event.block_height,\n\t\ttx_id: event.tx_id,\n\t\ttx_index: event.tx_index,\n\t\tevent_index: event.event_index,\n\t\tevent_type: eventType,\n\t\tdecoded_payload,\n\t\tsource_cursor: event.cursor,\n\t};\n}\n",
8
+ "import {\n\tdecodedRow,\n\tparseAssetIdentifier,\n\trequireAmount,\n\trequireString,\n} from \"./_payload.ts\";\nimport type { StreamsEvent } from \"./events.ts\";\n\nexport type { FtTransferPayload } from \"./events.ts\";\n\nexport type FtTransferEvent = Extract<\n\tStreamsEvent,\n\t{ event_type: \"ft_transfer\" }\n>;\n\nexport type DecodedFtTransferPayload = {\n\tasset_identifier: string;\n\tcontract_id: string;\n\ttoken_name: string | null;\n\tsender: string;\n\trecipient: string;\n\tamount: string;\n};\n\nexport type DecodedFtTransfer = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"ft_transfer\";\n\tdecoded_payload: DecodedFtTransferPayload;\n\tsource_cursor: string;\n};\n\nexport function isFtTransfer(event: StreamsEvent): event is FtTransferEvent {\n\treturn event.event_type === \"ft_transfer\";\n}\n\nexport function decodeFtTransfer(event: StreamsEvent): DecodedFtTransfer {\n\tif (!isFtTransfer(event)) {\n\t\tthrow new Error(`Expected ft_transfer event, got ${event.event_type}`);\n\t}\n\n\tconst payload = event.payload;\n\tconst assetIdentifier = requireString(\n\t\tpayload,\n\t\t\"asset_identifier\",\n\t\t\"ft_transfer\",\n\t);\n\tconst sender = requireString(payload, \"sender\", \"ft_transfer\");\n\tconst recipient = requireString(payload, \"recipient\", \"ft_transfer\");\n\tconst amount = requireAmount(payload, \"ft_transfer\");\n\tconst { contract_id, token_name } = parseAssetIdentifier(\n\t\tassetIdentifier,\n\t\t\"ft_transfer\",\n\t);\n\n\treturn decodedRow(event, \"ft_transfer\", {\n\t\tasset_identifier: assetIdentifier,\n\t\tcontract_id: event.contract_id ?? contract_id,\n\t\ttoken_name,\n\t\tsender,\n\t\trecipient,\n\t\tamount,\n\t});\n}\n",
9
+ "import {\n\tdecodedRow,\n\tparseAssetIdentifier,\n\trequireHexValue,\n\trequireString,\n} from \"./_payload.ts\";\nimport type { StreamsEvent } from \"./events.ts\";\n\nexport type { NftTransferPayload } from \"./events.ts\";\n\nexport type NftTransferEvent = Extract<\n\tStreamsEvent,\n\t{ event_type: \"nft_transfer\" }\n>;\n\nexport type DecodedNftTransferPayload = {\n\tasset_identifier: string;\n\tcontract_id: string;\n\ttoken_name: string | null;\n\tsender: string;\n\trecipient: string;\n\tvalue: string;\n};\n\nexport type DecodedNftTransfer = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"nft_transfer\";\n\tdecoded_payload: DecodedNftTransferPayload;\n\tsource_cursor: string;\n};\n\nexport function isNftTransfer(event: StreamsEvent): event is NftTransferEvent {\n\treturn event.event_type === \"nft_transfer\";\n}\n\nexport function decodeNftTransfer(event: StreamsEvent): DecodedNftTransfer {\n\tif (!isNftTransfer(event)) {\n\t\tthrow new Error(`Expected nft_transfer event, got ${event.event_type}`);\n\t}\n\n\tconst payload = event.payload;\n\tconst assetIdentifier = requireString(\n\t\tpayload,\n\t\t\"asset_identifier\",\n\t\t\"nft_transfer\",\n\t);\n\tconst sender = requireString(payload, \"sender\", \"nft_transfer\");\n\tconst recipient = requireString(payload, \"recipient\", \"nft_transfer\");\n\tconst value = requireHexValue(payload, \"nft_transfer\");\n\tconst { contract_id, token_name } = parseAssetIdentifier(\n\t\tassetIdentifier,\n\t\t\"nft_transfer\",\n\t);\n\n\treturn decodedRow(event, \"nft_transfer\", {\n\t\tasset_identifier: assetIdentifier,\n\t\tcontract_id: event.contract_id ?? contract_id,\n\t\ttoken_name,\n\t\tsender,\n\t\trecipient,\n\t\tvalue,\n\t});\n}\n",
10
+ "import { decodedRow, optionalString } from \"./_payload.ts\";\nimport { decodeClarityValue, toJsonSafe } from \"./clarity.ts\";\nimport type { StreamsEvent } from \"./events.ts\";\n\n/** Decoded form of a Clarity `print` event:\n * - `topic`: the print topic, when the contract emits a `{ topic, ... }` tuple\n * - `value`: the Clarity value decoded to JSON (uints as strings, buffers as\n * `0x…` hex, tuples as objects)\n * - `raw_value`: the canonical serialized hex, for byte-exact consumers */\nexport type DecodedPrintValue = {\n\ttopic: string | null;\n\tvalue: unknown;\n\traw_value: string | null;\n};\n\nexport type DecodedPrintPayload = {\n\tcontract_id: string | null;\n\tpayload: DecodedPrintValue;\n};\n\nexport type DecodedPrint = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"print\";\n\tdecoded_payload: DecodedPrintPayload;\n\tsource_cursor: string;\n};\n\nfunction printValueHex(payload: Record<string, unknown>): string | null {\n\tif (typeof payload.raw_value === \"string\") return payload.raw_value;\n\tconst value = payload.value;\n\tif (typeof value === \"string\" && value.startsWith(\"0x\")) return value;\n\tif (\n\t\tvalue &&\n\t\ttypeof value === \"object\" &&\n\t\ttypeof (value as { hex?: unknown }).hex === \"string\"\n\t) {\n\t\treturn (value as { hex: string }).hex;\n\t}\n\treturn null;\n}\n\nexport function isPrint(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"print\" } {\n\treturn event.event_type === \"print\";\n}\n\nexport function decodePrint(event: StreamsEvent): DecodedPrint {\n\tif (!isPrint(event)) {\n\t\tthrow new Error(`Expected print event, got ${event.event_type}`);\n\t}\n\tconst payload = event.payload;\n\tconst topic = optionalString(payload.topic);\n\tconst rawValue = printValueHex(payload);\n\n\tconst value = rawValue\n\t\t? decodeClarityValue(rawValue)\n\t\t: toJsonSafe(payload.value ?? null);\n\n\treturn decodedRow(event, \"print\", {\n\t\tcontract_id: event.contract_id ?? optionalString(payload.contract_id),\n\t\tpayload: { topic, value, raw_value: rawValue },\n\t});\n}\n",
11
+ "import {\n\tdecodedRow,\n\toptionalString,\n\trequireAmount,\n\trequireAmountField,\n\trequireString,\n} from \"./_payload.ts\";\nimport type { StreamsEvent } from \"./events.ts\";\n\nexport type DecodedStxTransferPayload = {\n\tsender: string;\n\trecipient: string;\n\tamount: string;\n\tmemo: string | null;\n};\n\nexport type DecodedStxTransfer = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"stx_transfer\";\n\tdecoded_payload: DecodedStxTransferPayload;\n\tsource_cursor: string;\n};\n\nexport type DecodedStxMintPayload = {\n\trecipient: string;\n\tamount: string;\n};\n\nexport type DecodedStxMint = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"stx_mint\";\n\tdecoded_payload: DecodedStxMintPayload;\n\tsource_cursor: string;\n};\n\nexport type DecodedStxBurnPayload = {\n\tsender: string;\n\tamount: string;\n};\n\nexport type DecodedStxBurn = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"stx_burn\";\n\tdecoded_payload: DecodedStxBurnPayload;\n\tsource_cursor: string;\n};\n\nexport function isStxTransfer(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"stx_transfer\" } {\n\treturn event.event_type === \"stx_transfer\";\n}\n\nexport function decodeStxTransfer(event: StreamsEvent): DecodedStxTransfer {\n\tif (!isStxTransfer(event)) {\n\t\tthrow new Error(`Expected stx_transfer event, got ${event.event_type}`);\n\t}\n\tconst payload = event.payload;\n\treturn decodedRow(event, \"stx_transfer\", {\n\t\tsender: requireString(payload, \"sender\", \"stx_transfer\"),\n\t\trecipient: requireString(payload, \"recipient\", \"stx_transfer\"),\n\t\tamount: requireAmount(payload, \"stx_transfer\"),\n\t\tmemo: optionalString(payload.memo),\n\t});\n}\n\nexport function isStxMint(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"stx_mint\" } {\n\treturn event.event_type === \"stx_mint\";\n}\n\nexport function decodeStxMint(event: StreamsEvent): DecodedStxMint {\n\tif (!isStxMint(event)) {\n\t\tthrow new Error(`Expected stx_mint event, got ${event.event_type}`);\n\t}\n\tconst payload = event.payload;\n\treturn decodedRow(event, \"stx_mint\", {\n\t\trecipient: requireString(payload, \"recipient\", \"stx_mint\"),\n\t\tamount: requireAmount(payload, \"stx_mint\"),\n\t});\n}\n\nexport function isStxBurn(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"stx_burn\" } {\n\treturn event.event_type === \"stx_burn\";\n}\n\nexport function decodeStxBurn(event: StreamsEvent): DecodedStxBurn {\n\tif (!isStxBurn(event)) {\n\t\tthrow new Error(`Expected stx_burn event, got ${event.event_type}`);\n\t}\n\tconst payload = event.payload;\n\treturn decodedRow(event, \"stx_burn\", {\n\t\tsender: requireString(payload, \"sender\", \"stx_burn\"),\n\t\tamount: requireAmount(payload, \"stx_burn\"),\n\t});\n}\n\nexport type DecodedStxLockPayload = {\n\t// The locked principal maps to `sender` and the locked uSTX to `amount` so\n\t// stx_lock is filterable like the other STX types; the lock-specific\n\t// unlock_height rides in the jsonb `payload` overflow.\n\tsender: string;\n\tamount: string;\n\tpayload: { unlock_height: string | null };\n};\n\nexport type DecodedStxLock = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"stx_lock\";\n\tdecoded_payload: DecodedStxLockPayload;\n\tsource_cursor: string;\n};\n\nexport function isStxLock(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"stx_lock\" } {\n\treturn event.event_type === \"stx_lock\";\n}\n\nexport function decodeStxLock(event: StreamsEvent): DecodedStxLock {\n\tif (!isStxLock(event)) {\n\t\tthrow new Error(`Expected stx_lock event, got ${event.event_type}`);\n\t}\n\tconst payload = event.payload;\n\treturn decodedRow(event, \"stx_lock\", {\n\t\tsender: requireString(payload, \"locked_address\", \"stx_lock\"),\n\t\tamount: requireAmountField(payload, \"locked_amount\", \"stx_lock\"),\n\t\tpayload: { unlock_height: optionalString(payload.unlock_height) },\n\t});\n}\n",
12
+ "import {\n\tdecodedRow,\n\tparseAssetIdentifier,\n\trequireAmount,\n\trequireHexValue,\n\trequireString,\n} from \"./_payload.ts\";\nimport type { StreamsEvent } from \"./events.ts\";\n\nexport type DecodedFtMintPayload = {\n\tasset_identifier: string;\n\tcontract_id: string;\n\ttoken_name: string | null;\n\trecipient: string;\n\tamount: string;\n};\n\nexport type DecodedFtMint = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"ft_mint\";\n\tdecoded_payload: DecodedFtMintPayload;\n\tsource_cursor: string;\n};\n\nexport type DecodedFtBurnPayload = {\n\tasset_identifier: string;\n\tcontract_id: string;\n\ttoken_name: string | null;\n\tsender: string;\n\tamount: string;\n};\n\nexport type DecodedFtBurn = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"ft_burn\";\n\tdecoded_payload: DecodedFtBurnPayload;\n\tsource_cursor: string;\n};\n\nexport type DecodedNftMintPayload = {\n\tasset_identifier: string;\n\tcontract_id: string;\n\ttoken_name: string | null;\n\trecipient: string;\n\tvalue: string;\n};\n\nexport type DecodedNftMint = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"nft_mint\";\n\tdecoded_payload: DecodedNftMintPayload;\n\tsource_cursor: string;\n};\n\nexport type DecodedNftBurnPayload = {\n\tasset_identifier: string;\n\tcontract_id: string;\n\ttoken_name: string | null;\n\tsender: string;\n\tvalue: string;\n};\n\nexport type DecodedNftBurn = {\n\tcursor: string;\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index: number;\n\tevent_index: number;\n\tevent_type: \"nft_burn\";\n\tdecoded_payload: DecodedNftBurnPayload;\n\tsource_cursor: string;\n};\n\nfunction assetFields(event: StreamsEvent, eventType: string) {\n\tconst assetIdentifier = requireString(\n\t\tevent.payload,\n\t\t\"asset_identifier\",\n\t\teventType,\n\t);\n\tconst { contract_id, token_name } = parseAssetIdentifier(\n\t\tassetIdentifier,\n\t\teventType,\n\t);\n\treturn {\n\t\tasset_identifier: assetIdentifier,\n\t\tcontract_id: event.contract_id ?? contract_id,\n\t\ttoken_name,\n\t};\n}\n\nexport function isFtMint(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"ft_mint\" } {\n\treturn event.event_type === \"ft_mint\";\n}\n\nexport function decodeFtMint(event: StreamsEvent): DecodedFtMint {\n\tif (!isFtMint(event)) {\n\t\tthrow new Error(`Expected ft_mint event, got ${event.event_type}`);\n\t}\n\treturn decodedRow(event, \"ft_mint\", {\n\t\t...assetFields(event, \"ft_mint\"),\n\t\trecipient: requireString(event.payload, \"recipient\", \"ft_mint\"),\n\t\tamount: requireAmount(event.payload, \"ft_mint\"),\n\t});\n}\n\nexport function isFtBurn(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"ft_burn\" } {\n\treturn event.event_type === \"ft_burn\";\n}\n\nexport function decodeFtBurn(event: StreamsEvent): DecodedFtBurn {\n\tif (!isFtBurn(event)) {\n\t\tthrow new Error(`Expected ft_burn event, got ${event.event_type}`);\n\t}\n\treturn decodedRow(event, \"ft_burn\", {\n\t\t...assetFields(event, \"ft_burn\"),\n\t\tsender: requireString(event.payload, \"sender\", \"ft_burn\"),\n\t\tamount: requireAmount(event.payload, \"ft_burn\"),\n\t});\n}\n\nexport function isNftMint(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"nft_mint\" } {\n\treturn event.event_type === \"nft_mint\";\n}\n\nexport function decodeNftMint(event: StreamsEvent): DecodedNftMint {\n\tif (!isNftMint(event)) {\n\t\tthrow new Error(`Expected nft_mint event, got ${event.event_type}`);\n\t}\n\treturn decodedRow(event, \"nft_mint\", {\n\t\t...assetFields(event, \"nft_mint\"),\n\t\trecipient: requireString(event.payload, \"recipient\", \"nft_mint\"),\n\t\tvalue: requireHexValue(event.payload, \"nft_mint\"),\n\t});\n}\n\nexport function isNftBurn(\n\tevent: StreamsEvent,\n): event is StreamsEvent & { event_type: \"nft_burn\" } {\n\treturn event.event_type === \"nft_burn\";\n}\n\nexport function decodeNftBurn(event: StreamsEvent): DecodedNftBurn {\n\tif (!isNftBurn(event)) {\n\t\tthrow new Error(`Expected nft_burn event, got ${event.event_type}`);\n\t}\n\treturn decodedRow(event, \"nft_burn\", {\n\t\t...assetFields(event, \"nft_burn\"),\n\t\tsender: requireString(event.payload, \"sender\", \"nft_burn\"),\n\t\tvalue: requireHexValue(event.payload, \"nft_burn\"),\n\t});\n}\n"
13
+ ],
14
+ "mappings": "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",
15
+ "debugId": "931E315D241CB50664756E2164756E21",
16
+ "names": []
17
+ }
@@ -32,7 +32,6 @@ interface SubgraphSyncInfo {
32
32
  estimatedEvents?: number;
33
33
  processedEvents?: number;
34
34
  etaSeconds?: number | null;
35
- resourceWarning?: SubgraphResourceWarning;
36
35
  gaps: {
37
36
  count: number
38
37
  totalMissingBlocks: number
@@ -41,14 +40,6 @@ interface SubgraphSyncInfo {
41
40
  /** history_filling = expected gaps while a tip-first backfill op runs. */
42
41
  integrity: "complete" | "gaps_detected" | "history_filling";
43
42
  }
44
- interface SubgraphResourceWarning {
45
- code: string;
46
- message: string;
47
- plan?: string;
48
- blockRange: number;
49
- processorMemoryMb: number;
50
- recommendedPlan: "launch";
51
- }
52
43
  interface SubgraphDetail {
53
44
  name: string;
54
45
  version: string;
@@ -0,0 +1,53 @@
1
+ import { type Kysely, sql } from "kysely";
2
+ import { onControlPlane } from "../src/db/migration-role.ts";
3
+
4
+ /**
5
+ * Gate-g Slice D: drop the retired hosted-control-plane tables. The metered
6
+ * archive keeps accounts/sessions/magic_links/api_keys plus the credit +
7
+ * Stripe + x402 tables; everything below belonged to plans, tenancy, hosted
8
+ * console, usage metering, or the ghost-claim mint path — all deleted from the
9
+ * codebase in the same change.
10
+ *
11
+ * `IF EXISTS` + `CASCADE` throughout so the migration is safe on databases
12
+ * where some tables were never created (fresh self-host) or already removed.
13
+ * CASCADE also detaches surviving FKs that point at a dropped table
14
+ * (`subgraphs.project_id -> projects`) without touching the surviving column.
15
+ *
16
+ * `accounts.slug` (hosted-console public-directory handle) is the one
17
+ * plan/slug-era account column with zero remaining code refs; `accounts.plan`
18
+ * is still read by the subgraph deploy gates and stays.
19
+ */
20
+ export async function up(db: Kysely<unknown>): Promise<void> {
21
+ await onControlPlane(async () => {
22
+ await sql`SET lock_timeout = '30s'`.execute(db);
23
+ // Leaves first (FK-dependent), then roots — though CASCADE makes the
24
+ // order non-load-bearing.
25
+ await sql`DROP TABLE IF EXISTS tenant_usage_monthly CASCADE`.execute(db);
26
+ await sql`DROP TABLE IF EXISTS tenant_compute_addons CASCADE`.execute(db);
27
+ await sql`DROP TABLE IF EXISTS provisioning_audit_log CASCADE`.execute(db);
28
+ await sql`DROP TABLE IF EXISTS tenants CASCADE`.execute(db);
29
+ await sql`DROP TABLE IF EXISTS team_invitations CASCADE`.execute(db);
30
+ await sql`DROP TABLE IF EXISTS team_members CASCADE`.execute(db);
31
+ await sql`DROP TABLE IF EXISTS projects CASCADE`.execute(db);
32
+ await sql`DROP TABLE IF EXISTS usage_daily CASCADE`.execute(db);
33
+ await sql`DROP TABLE IF EXISTS usage_snapshots CASCADE`.execute(db);
34
+ await sql`DROP TABLE IF EXISTS account_insights CASCADE`.execute(db);
35
+ await sql`DROP TABLE IF EXISTS account_agent_runs CASCADE`.execute(db);
36
+ await sql`DROP TABLE IF EXISTS subgraph_usage_daily CASCADE`.execute(db);
37
+ await sql`DROP TABLE IF EXISTS claim_tokens CASCADE`.execute(db);
38
+
39
+ await sql`ALTER TABLE accounts DROP COLUMN IF EXISTS slug`.execute(db);
40
+ });
41
+ }
42
+
43
+ export async function down(db: Kysely<unknown>): Promise<void> {
44
+ await onControlPlane(async () => {
45
+ // Irreversible by design: the dropped tables' data is gone and their
46
+ // creating migrations (0001…0117) remain the historical schema record.
47
+ // Restore the accounts column only, so a rollback of THIS migration
48
+ // leaves a consistent accounts shape.
49
+ await sql`ALTER TABLE accounts ADD COLUMN IF NOT EXISTS slug TEXT`.execute(
50
+ db,
51
+ );
52
+ });
53
+ }
@@ -0,0 +1,29 @@
1
+ import { type Kysely, sql } from "kysely";
2
+ import { onControlPlane } from "../src/db/migration-role.ts";
3
+
4
+ /**
5
+ * Plans are fully retired: deploys are open on every instance and the only
6
+ * metered surface is archive-data access (read credits). `accounts.plan` —
7
+ * the last plan-machinery column, previously read by the subgraph deploy /
8
+ * genesis / visibility / subscription gates — has zero remaining code refs,
9
+ * so drop it.
10
+ *
11
+ * `IF EXISTS` so the migration is safe on databases where the column was
12
+ * never created (fresh self-host) or already removed.
13
+ */
14
+ export async function up(db: Kysely<unknown>): Promise<void> {
15
+ await onControlPlane(async () => {
16
+ await sql`SET lock_timeout = '30s'`.execute(db);
17
+ await sql`ALTER TABLE accounts DROP COLUMN IF EXISTS plan`.execute(db);
18
+ });
19
+ }
20
+
21
+ export async function down(db: Kysely<unknown>): Promise<void> {
22
+ await onControlPlane(async () => {
23
+ // Restore the column with its pre-drop default ('none' since 0064).
24
+ // Values are gone; every account comes back as plan 'none'.
25
+ await sql`ALTER TABLE accounts ADD COLUMN IF NOT EXISTS plan TEXT NOT NULL DEFAULT 'none'`.execute(
26
+ db,
27
+ );
28
+ });
29
+ }
@@ -0,0 +1,42 @@
1
+ import { type Kysely, sql } from "kysely";
2
+ import { onChainPlane } from "../src/db/migration-role.ts";
3
+
4
+ /**
5
+ * `sync_scopes` — the instance's declared scope: network, where its history
6
+ * starts, and how that history got here.
7
+ *
8
+ * Without a recorded start, "everything below the lowest stored block" is
9
+ * indistinguishable from data loss: a forward-only instance reads as a chain
10
+ * with an 8M-block hole. The row makes the absence deliberate, so the coverage
11
+ * evaluator can call the prefix `out_of_scope` instead of a gap.
12
+ *
13
+ * One row per network (the network is the primary key) and it lives on the
14
+ * source plane, next to the chain whose scope it declares.
15
+ */
16
+ export async function up(db: Kysely<unknown>): Promise<void> {
17
+ await onChainPlane(async () => {
18
+ await sql`SET lock_timeout = '30s'`.execute(db);
19
+
20
+ await sql`
21
+ CREATE TABLE sync_scopes (
22
+ network TEXT PRIMARY KEY,
23
+ start_height BIGINT NOT NULL CHECK (start_height >= 0),
24
+ target_height BIGINT,
25
+ bootstrap_source TEXT NOT NULL
26
+ CHECK (bootstrap_source IN ('archive', 'genesis', 'import')),
27
+ bootstrap_manifest_digest TEXT,
28
+ genesis_hash TEXT,
29
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
30
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
31
+ CONSTRAINT sync_scopes_target_above_start
32
+ CHECK (target_height IS NULL OR target_height >= start_height)
33
+ )
34
+ `.execute(db);
35
+ });
36
+ }
37
+
38
+ export async function down(db: Kysely<unknown>): Promise<void> {
39
+ await onChainPlane(async () => {
40
+ await sql`DROP TABLE IF EXISTS sync_scopes`.execute(db);
41
+ });
42
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/shared",
3
- "version": "7.11.2",
3
+ "version": "9.0.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,6 +24,10 @@
24
24
  "types": "./dist/src/db/queries/instance.d.ts",
25
25
  "import": "./dist/src/db/queries/instance.js"
26
26
  },
27
+ "./db/queries/sync-scope": {
28
+ "types": "./dist/src/db/queries/sync-scope.d.ts",
29
+ "import": "./dist/src/db/queries/sync-scope.js"
30
+ },
27
31
  "./db/queries/integrity": {
28
32
  "types": "./dist/src/db/queries/integrity.d.ts",
29
33
  "import": "./dist/src/db/queries/integrity.js"
@@ -112,6 +116,10 @@
112
116
  "types": "./dist/src/streams-bulk-manifest.d.ts",
113
117
  "import": "./dist/src/streams-bulk-manifest.js"
114
118
  },
119
+ "./streams-rows": {
120
+ "types": "./dist/src/streams-rows/index.d.ts",
121
+ "import": "./dist/src/streams-rows/index.js"
122
+ },
115
123
  "./archive/disk-guard": {
116
124
  "types": "./dist/src/archive/disk-guard.d.ts",
117
125
  "import": "./dist/src/archive/disk-guard.js"
@@ -164,10 +172,6 @@
164
172
  "types": "./dist/src/errors.d.ts",
165
173
  "import": "./dist/src/errors.js"
166
174
  },
167
- "./x402": {
168
- "types": "./dist/src/x402.d.ts",
169
- "import": "./dist/src/x402.js"
170
- },
171
175
  "./crypto/secrets": {
172
176
  "types": "./dist/src/crypto/secrets.d.ts",
173
177
  "import": "./dist/src/crypto/secrets.js"
@@ -216,7 +220,7 @@
216
220
  "prepublishOnly": "bun run build"
217
221
  },
218
222
  "dependencies": {
219
- "@secondlayer/stacks": "^3.3.1",
223
+ "@secondlayer/stacks": "^4.0.0",
220
224
  "kysely": "0.28.17",
221
225
  "kysely-postgres-js": "3.0.0",
222
226
  "postgres": "^3.4.6",
@@ -1,47 +0,0 @@
1
- /**
2
- * x402 payment-rail shared constants: the v1 token set + CAIP-2 network ids.
3
- *
4
- * Single-sourced here (not in the API package) so the SDK/MCP client and the
5
- * API facilitator agree on asset ids, decimals, and the `accepts[]` asset-string
6
- * format. All ids are mainnet and confirmed on-chain (2026-06). Per-call prices
7
- * are NOT here — they are API-local (see `packages/api/src/x402/catalog.ts`) and
8
- * exposed to clients at runtime via `GET /x402/supported`.
9
- */
10
- /** CAIP-2 network ids used in x402 v2 `accepts[]` entries. */
11
- declare const X402_NETWORK: {
12
- readonly mainnet: "stacks:1"
13
- readonly testnet: "stacks:2147483648"
14
- };
15
- type X402Network = (typeof X402_NETWORK)[keyof typeof X402_NETWORK];
16
- type X402TokenSymbol = "STX" | "sBTC" | "USDCx";
17
- type X402Token = {
18
- symbol: X402TokenSymbol
19
- /** x402 `asset` string: `"STX"` for native, else the `<addr>.<contract>` id. */
20
- asset: string
21
- /** SIP-010 contract id (`<addr>.<contract>`); `null` for native STX. */
22
- contractId: string | null
23
- /** SIP-010 fungible-token asset name (the `::<name>` suffix); `null` for STX. */
24
- assetName: string | null
25
- /** Fully-qualified SIP-010 asset identifier (`<id>::<name>`); `null` for STX. */
26
- assetIdentifier: string | null
27
- decimals: number
28
- };
29
- /** v1 token set. sBTC + USDCx ids verified against the deployed mainnet contracts. */
30
- declare const X402_TOKENS: Record<X402TokenSymbol, X402Token>;
31
- declare const X402_TOKEN_SYMBOLS: X402TokenSymbol[];
32
- declare function getX402Token(symbol: X402TokenSymbol): X402Token;
33
- /**\\n* Optimistic-serve reputation: the Redis key + TTL for a payer principal's\\n* "strike" counter (reverted/dropped payments). Single-sourced so the API gate\\n* (reader) and the worker reconciler (writer, on revert) agree without a\\n* cross-package import.\\n*/
34
- declare const X402_STRIKE_TTL_SECONDS: number;
35
- declare function x402StrikeKey(principal: string): string;
36
- /**
37
- * Normalize an x402 payment txid to the form stored in `decoded_events`.
38
- * Broadcast/ledger txids are bare lowercase hex; the index stores them
39
- * `0x`-prefixed. Querying `decoded_events` with the bare form silently never
40
- * matches — which wedged the rail's confirmation layer (optimistic payments
41
- * reverted + struck the payer; confirmed-tier never confirmed). Idempotent and
42
- * case-normalizing, so it's safe to apply at every index query site.
43
- */
44
- declare function toIndexTxId(txid: string): string;
45
- /** Resolve a token by its x402 `asset` string (the value carried in `accepts[].asset`). */
46
- declare function findX402TokenByAsset(asset: string): X402Token | undefined;
47
- export { x402StrikeKey, toIndexTxId, getX402Token, findX402TokenByAsset, X402_TOKEN_SYMBOLS, X402_TOKENS, X402_STRIKE_TTL_SECONDS, X402_NETWORK, X402TokenSymbol, X402Token, X402Network };