@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.
- package/dist/src/archive/range-digest.d.ts +16 -0
- package/dist/src/archive/semantic-digest-builder.d.ts +16 -0
- package/dist/src/archive/status.js +11 -3
- package/dist/src/archive/status.js.map +3 -3
- package/dist/src/coverage/index.d.ts +16 -13
- package/dist/src/coverage/index.js +1 -11
- package/dist/src/coverage/index.js.map +3 -3
- package/dist/src/db/index.d.ts +18 -1
- package/dist/src/db/index.js +2 -1
- package/dist/src/db/index.js.map +3 -3
- package/dist/src/db/queries/chain-reorgs.d.ts +16 -0
- package/dist/src/db/queries/chain-reorgs.js +2 -1
- package/dist/src/db/queries/chain-reorgs.js.map +3 -3
- package/dist/src/db/queries/contracts.d.ts +16 -0
- package/dist/src/db/queries/instance.d.ts +16 -0
- package/dist/src/db/queries/integrity.d.ts +16 -0
- package/dist/src/db/queries/subgraph-gaps.d.ts +16 -0
- package/dist/src/db/queries/subgraph-operations.d.ts +16 -0
- package/dist/src/db/queries/subgraphs.d.ts +16 -0
- package/dist/src/db/queries/subscriptions.d.ts +16 -0
- package/dist/src/db/queries/sync-scope.d.ts +1006 -0
- package/dist/src/db/queries/sync-scope.js +116 -0
- package/dist/src/db/queries/sync-scope.js.map +10 -0
- package/dist/src/db/schema.d.ts +17 -1
- package/dist/src/index.d.ts +18 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +3 -3
- package/dist/src/node/local-client.d.ts +16 -0
- package/dist/src/runtime/index.d.ts +188 -18
- package/dist/src/runtime/index.js +322 -38
- package/dist/src/runtime/index.js.map +10 -7
- package/migrations/0120_sync_scopes.ts +42 -0
- package/package.json +7 -6
- package/dist/src/x402.d.ts +0 -47
- package/dist/src/x402.js +0 -79
- 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:
|
|
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
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
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 {
|
|
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 };
|