@secondlayer/shared 8.0.0 → 10.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 (36) hide show
  1. package/dist/src/archive/range-digest.d.ts +16 -0
  2. package/dist/src/archive/semantic-digest-builder.d.ts +16 -0
  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 +16 -13
  6. package/dist/src/coverage/index.js +1 -11
  7. package/dist/src/coverage/index.js.map +3 -3
  8. package/dist/src/db/index.d.ts +18 -1
  9. package/dist/src/db/index.js +2 -1
  10. package/dist/src/db/index.js.map +3 -3
  11. package/dist/src/db/queries/chain-reorgs.d.ts +16 -0
  12. package/dist/src/db/queries/chain-reorgs.js +2 -1
  13. package/dist/src/db/queries/chain-reorgs.js.map +3 -3
  14. package/dist/src/db/queries/contracts.d.ts +16 -0
  15. package/dist/src/db/queries/instance.d.ts +16 -0
  16. package/dist/src/db/queries/integrity.d.ts +16 -0
  17. package/dist/src/db/queries/subgraph-gaps.d.ts +16 -0
  18. package/dist/src/db/queries/subgraph-operations.d.ts +16 -0
  19. package/dist/src/db/queries/subgraphs.d.ts +16 -0
  20. package/dist/src/db/queries/subscriptions.d.ts +16 -0
  21. package/dist/src/db/queries/sync-scope.d.ts +1006 -0
  22. package/dist/src/db/queries/sync-scope.js +116 -0
  23. package/dist/src/db/queries/sync-scope.js.map +10 -0
  24. package/dist/src/db/schema.d.ts +17 -1
  25. package/dist/src/index.d.ts +18 -1
  26. package/dist/src/index.js +2 -1
  27. package/dist/src/index.js.map +3 -3
  28. package/dist/src/node/local-client.d.ts +16 -0
  29. package/dist/src/runtime/index.d.ts +188 -18
  30. package/dist/src/runtime/index.js +322 -38
  31. package/dist/src/runtime/index.js.map +10 -7
  32. package/migrations/0120_sync_scopes.ts +42 -0
  33. package/package.json +7 -6
  34. package/dist/src/x402.d.ts +0 -47
  35. package/dist/src/x402.js +0 -79
  36. package/dist/src/x402.js.map +0 -10
@@ -155,13 +155,11 @@ declare function reportRuntimeStatus(input: {
155
155
  coverage?: CoverageState | string
156
156
  }): RuntimeStatusReport;
157
157
  declare function actionFor(plane: StatusPlane, state: string): string;
158
- /**
159
- * Backup bundle — consistent DB, pinned config, encrypted keys, handler
160
- * manifests, and scope. Restore onto a wiped host must deep-verify green.
161
- */
158
+ declare const BACKUP_MANIFEST_VERSION = 1;
162
159
  declare const BACKUP_PARTS: readonly ["db", "config", "keys", "handlers", "scope"];
163
160
  type BackupPart = (typeof BACKUP_PARTS)[number];
164
161
  type BackupManifest = {
162
+ schema_version: number
165
163
  created_at: string
166
164
  network: string
167
165
  parts: BackupPart[]
@@ -170,34 +168,141 @@ type BackupManifest = {
170
168
  from_height: number
171
169
  to_height: number | null
172
170
  }
171
+ db: {
172
+ file: string
173
+ sha256: string
174
+ bytes: number
175
+ format: string
176
+ } | null
177
+ /** Never the secrets themselves — only how to check them. */
178
+ secrets: {
179
+ file: string
180
+ encrypted: boolean
181
+ canary: string
182
+ } | null
183
+ signature?: string
184
+ key_id?: string
173
185
  };
174
186
  type BackupPlan = {
175
- ok: boolean
187
+ ok: true
176
188
  manifest: BackupManifest
189
+ } | {
190
+ ok: false
177
191
  reason: string
178
192
  };
193
+ /**
194
+ * Validate a backup before any bytes are written. Refusing early is the whole
195
+ * point: a bundle that omits the keys looks like a backup and is not one.
196
+ */
179
197
  declare function planBackup(input: {
180
198
  network: string
181
- encryptedKeys: boolean
182
199
  fromHeight: number
183
200
  toHeight?: number | null
201
+ includeSecrets: boolean
202
+ secretsEncrypted: boolean
203
+ canary?: string
184
204
  now?: string
185
205
  }): BackupPlan;
186
- type RestoreResult = {
206
+ /**
207
+ * Seal the canary under an EXPLICIT key.
208
+ *
209
+ * Deliberately not reusing `crypto/secrets.ts`: that module resolves the key
210
+ * from the ambient environment and, in OSS mode, generates and persists one as
211
+ * a side effect when it is missing. Calling it here would mean a backup could
212
+ * mint the very key it is supposed to be preserving.
213
+ */
214
+ declare function sealKeyCanary(secretsKeyHex: string): string;
215
+ /** True only when `secretsKeyHex` is the key the canary was sealed with. */
216
+ declare function keyMatchesCanary(canaryBase64: string, secretsKeyHex: string): boolean;
217
+ /**
218
+ * Encrypt the secrets bundle under an operator passphrase.
219
+ * Layout: `salt(16) || iv(12) || authTag(16) || ciphertext`.
220
+ */
221
+ declare function encryptBundle(plaintext: string, passphrase: string): Buffer;
222
+ declare function decryptBundle(envelope: Buffer, passphrase: string): string;
223
+ type RestorePrecheck = {
187
224
  ok: true
188
- applied: boolean
189
- deep_green: boolean
190
225
  } | {
191
226
  ok: false
192
227
  reason: string
228
+ fatal: boolean
193
229
  };
194
- declare function restoreBackup(plan: BackupPlan, opts?: {
195
- apply?: boolean
196
- deepVerify?: boolean
197
- }): RestoreResult;
230
+ /**
231
+ * Everything that must hold before a restore writes anything.
232
+ *
233
+ * `fatal` distinguishes "this bundle can never restore here" from "this needs
234
+ * an explicit override" — the caller surfaces them differently.
235
+ */
236
+ declare function precheckRestore(input: {
237
+ manifest: BackupManifest
238
+ targetNetwork: string
239
+ targetIsEmpty: boolean
240
+ force: boolean
241
+ secretsKeyHex?: string
242
+ }): RestorePrecheck;
243
+ /**
244
+ * Uninstall with data preservation — tear the stack down without destroying
245
+ * what cannot be rebuilt.
246
+ *
247
+ * The asymmetry that shapes this whole file: the index can be reconstructed
248
+ * from the archive, and the chainstate can be re-synced, but the keys cannot be
249
+ * recovered by any means. `SECONDLAYER_SECRETS_KEY` decrypts columns that are
250
+ * otherwise permanently unreadable, and `STREAMS_SIGNING_PRIVATE_KEY` is the
251
+ * identity anything this instance published was signed under.
252
+ *
253
+ * So the default removes containers and leaves every byte of data in place, and
254
+ * the destructive path refuses unless the operator has said the words AND the
255
+ * keys are demonstrably somewhere else. A teardown that silently takes the keys
256
+ * with it is not an uninstall, it is data loss with a friendly name.
257
+ */
258
+ declare const REMOVABLE: readonly ["containers", "networks", "handler-cache"];
259
+ type Removable = (typeof REMOVABLE)[number];
260
+ declare const PRESERVED: readonly ["index", "chainstate", "secrets", "backups"];
261
+ type Preserved = (typeof PRESERVED)[number];
262
+ type UninstallPlan = {
263
+ /** What the plan will actually delete. */
264
+ removes: Removable[]
265
+ /** What survives, and why it matters. */
266
+ preserves: {
267
+ what: Preserved
268
+ detail: string
269
+ }[]
270
+ /** Volumes destroyed only on the purge path. */
271
+ destroys: string[]
272
+ purge: boolean
273
+ };
274
+ type UninstallDecision = {
275
+ ok: true
276
+ plan: UninstallPlan
277
+ warnings: string[]
278
+ } | {
279
+ ok: false
280
+ reason: string
281
+ };
282
+ declare function planUninstall(input: {
283
+ purge: boolean
284
+ /** The operator typed the confirmation. */
285
+ confirmed: boolean
286
+ /** A backup bundle exists that carries the keys. */
287
+ keysBackedUp: boolean
288
+ /** Secrets are currently present (there is something to lose). */
289
+ secretsPresent: boolean
290
+ dataDir: string
291
+ }): UninstallDecision;
292
+ /** The compose invocation a plan corresponds to. */
293
+ declare function uninstallCommand(plan: UninstallPlan, composeFile: string): string[];
198
294
  /**
199
295
  * Upgrade contract — pin image, preflight schema/disk, backup first,
200
296
  * migrate, health/verify, document rollback limits.
297
+ *
298
+ * PLANNER ONLY — `applyUpgrade` returns `{applied:true}` without pulling an
299
+ * image, running a preflight, or migrating anything. Nothing in the product
300
+ * calls it. The upgrade operators actually perform is `docker compose pull &&
301
+ * up -d`, with migrations applied at boot by the runtime entrypoint.
302
+ *
303
+ * Same caution as the sibling backup planner: this step list was published as
304
+ * an operator procedure in the self-host docs until 2026-08-15. Make it do the
305
+ * work before presenting it as one.
201
306
  */
202
307
  declare const UPGRADE_STEPS: readonly ["pin", "preflight", "backup", "migrate", "health", "verify"];
203
308
  type UpgradeStep = (typeof UPGRADE_STEPS)[number];
@@ -227,6 +332,13 @@ declare function applyUpgrade(plan: UpgradePlan, opts?: {
227
332
  /**
228
333
  * Resource guardrails — preflight RAM/disk/Postgres and estimate growth.
229
334
  * Constrained fixtures fail early.
335
+ *
336
+ * The disk numbers here were wrong by 3-6x until 2026-08-15: they promised a
337
+ * full-history mainnet index would fit in 80 GB, and estimated growth at 1 GB
338
+ * per 100k blocks. The reference index measured 504 GB at height 8,771,873.
339
+ * An operator who sized a box from these figures would have filled the disk
340
+ * partway through their first bootstrap, so every constant below now cites what
341
+ * it was measured against.
230
342
  */
231
343
  type ResourceSnapshot = {
232
344
  ramMb: number
@@ -234,23 +346,81 @@ type ResourceSnapshot = {
234
346
  postgresMaxConnections: number
235
347
  postgresSharedBuffersMb?: number
236
348
  };
349
+ type DiskEstimates = {
350
+ /** blocks + transactions + events, no decoded plane. */
351
+ diskGbPer100kBlocks: number
352
+ /** Same, plus a broad decoder set writing `decoded_events`. */
353
+ diskGbPer100kBlocksDecoded: number
354
+ };
237
355
  type GuardrailResult = {
238
356
  ok: true
239
- estimates: {
240
- diskGbPer100kBlocks: number
241
- }
357
+ estimates: DiskEstimates
242
358
  } | {
243
359
  ok: false
244
360
  errors: string[]
245
361
  };
362
+ type GuardrailNetwork = "mainnet" | "testnet" | "devnet";
246
363
  declare const FLOORS: {
247
364
  readonly appRamMb: 4096
248
365
  readonly fullRamMb: 98304
366
+ /**
367
+ * Mainnet full history: 504 GB measured today, growing ~0.5 GB/day at the
368
+ * observed block rate. 600 leaves roughly six months of headroom, which is
369
+ * the point of a floor — a box that fits exactly today fails within weeks.
370
+ */
371
+ readonly mainnetAppDiskGb: 600
372
+ /**
373
+ * Testnet/devnet carry a fraction of mainnet's history. Unmeasured; retained
374
+ * as the long-standing default rather than replaced with a fresh guess.
375
+ */
249
376
  readonly appDiskGb: 80
377
+ /**
378
+ * Bundled node on mainnet. The Stacks chainstate alone measured 1.3 TB on
379
+ * the reference node (2026-08-15), and the index adds ~500 GB; bitcoind is
380
+ * additional and not measured here. The previous 1.5 TB floor was below the
381
+ * two components we HAVE measured.
382
+ */
383
+ readonly mainnetFullDiskGb: 2500
384
+ /** Bundled node, non-mainnet. Unmeasured; retained default. */
250
385
  readonly fullDiskGb: 1500
251
386
  readonly postgresMaxConnections: 50
252
387
  };
253
- declare function preflightResources(snap: ResourceSnapshot, mode: "external" | "stacks" | "full"): GuardrailResult;
388
+ /** The disk floor that applies to a given mode and network. */
389
+ declare function diskFloorGb(mode: "external" | "stacks" | "full", network: GuardrailNetwork): number;
390
+ /**
391
+ * A dimension the caller could not measure is absent, not zero. Skipping it
392
+ * keeps an unreadable `statfs` from presenting as a 0 GB disk and refusing a
393
+ * perfectly adequate box.
394
+ */
395
+ declare function preflightResources(snap: Partial<ResourceSnapshot>, mode: "external" | "stacks" | "full", network?: GuardrailNetwork): GuardrailResult;
396
+ type MeasuredResources = {
397
+ snapshot: Partial<ResourceSnapshot>
398
+ /** Dimensions we could not read, with why. Never guessed at. */
399
+ unknown: string[]
400
+ };
401
+ declare function measureResources(input: {
402
+ dataDir: string
403
+ query?: (sql: string) => Promise<Array<Record<string, unknown>>>
404
+ }): Promise<MeasuredResources>;
405
+ declare const UNDERSIZED_OVERRIDE = "SECONDLAYER_ALLOW_UNDERSIZED";
406
+ type PreflightDecision = {
407
+ action: "pass" | "warn" | "refuse"
408
+ messages: string[]
409
+ };
410
+ declare function decidePreflight(input: {
411
+ measured: MeasuredResources
412
+ mode: "external" | "stacks" | "full"
413
+ network: GuardrailNetwork
414
+ env?: Record<string, string | undefined>
415
+ }): PreflightDecision;
416
+ /** Measure this box and decide. Returns the decision; the caller exits. */
417
+ declare function runPreflight(input: {
418
+ dataDir: string
419
+ mode: "external" | "stacks" | "full"
420
+ network: GuardrailNetwork
421
+ query?: (sql: string) => Promise<Array<Record<string, unknown>>>
422
+ env?: Record<string, string | undefined>
423
+ }): Promise<PreflightDecision>;
254
424
  declare const MODULE_COMMANDS: Record<ModuleId, readonly string[]>;
255
425
  declare function commandFor(id: ModuleId): readonly string[];
256
- export { restoreBackup, reportRuntimeStatus, preflightResources, planUpgrade, planBackup, parseRuntimeConfig, migrateEmbedded, isolateHandler, isModuleId, emptyHealth, createSupervisor, createMemoryModule, createMemoryMigrationRunner, commandFor, applyUpgrade, actionFor, UpgradeStep, UpgradePlan, UPGRADE_STEPS, SupervisorHealth, Supervisor, StatusPlane, STATUS_PLANES, SECRET_KEYS, RuntimeStatusReport, RuntimeNetwork, RuntimeModule, RuntimeConfig, RestoreResult, ResourceSnapshot, RequiredConfigKey, REQUIRED_KEYS, PlaneStatus, PUBLISHER_PROFILE, OPTIONAL_KEYS, NodeMode, NODE_MODES, NETWORKS, ModuleState, ModuleId, ModuleHealth, MigrationRunner, MODULE_STATES, MODULE_IDS, MODULE_COMMANDS, MIGRATION_LOCK_KEY, IsolationResult, IsolationOomError, IsolationNetworkError, IsolationLimits, IsolationKillError, IsolationFault, ISOLATION_FAULTS, GuardrailResult, FLOORS, EmbeddedMigration, DEFAULT_PROFILE, ConfigResult, BackupPlan, BackupPart, BackupManifest, BACKUP_PARTS };
426
+ export { uninstallCommand, sealKeyCanary, runPreflight, reportRuntimeStatus, preflightResources, precheckRestore, planUpgrade, planUninstall, planBackup, parseRuntimeConfig, migrateEmbedded, measureResources, keyMatchesCanary, isolateHandler, isModuleId, encryptBundle, emptyHealth, diskFloorGb, decryptBundle, decidePreflight, createSupervisor, createMemoryModule, createMemoryMigrationRunner, commandFor, applyUpgrade, actionFor, UpgradeStep, UpgradePlan, UninstallPlan, UninstallDecision, UPGRADE_STEPS, UNDERSIZED_OVERRIDE, SupervisorHealth, Supervisor, StatusPlane, STATUS_PLANES, SECRET_KEYS, RuntimeStatusReport, RuntimeNetwork, RuntimeModule, RuntimeConfig, RestorePrecheck, ResourceSnapshot, RequiredConfigKey, Removable, REQUIRED_KEYS, REMOVABLE, Preserved, PreflightDecision, PlaneStatus, PUBLISHER_PROFILE, PRESERVED, OPTIONAL_KEYS, NodeMode, NODE_MODES, NETWORKS, ModuleState, ModuleId, ModuleHealth, MigrationRunner, MeasuredResources, MODULE_STATES, MODULE_IDS, MODULE_COMMANDS, MIGRATION_LOCK_KEY, IsolationResult, IsolationOomError, IsolationNetworkError, IsolationLimits, IsolationKillError, IsolationFault, ISOLATION_FAULTS, GuardrailResult, GuardrailNetwork, FLOORS, EmbeddedMigration, DiskEstimates, DEFAULT_PROFILE, ConfigResult, BackupPlan, BackupPart, BackupManifest, BACKUP_PARTS, BACKUP_MANIFEST_VERSION };