@secondlayer/shared 7.7.0 → 7.9.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/derived-stage-report.d.ts +99 -0
- package/dist/src/archive/derived-stage-report.js +64 -0
- package/dist/src/archive/derived-stage-report.js.map +10 -0
- package/dist/src/archive/disk-guard.d.ts +46 -0
- package/dist/src/archive/disk-guard.js +69 -0
- package/dist/src/archive/disk-guard.js.map +10 -0
- package/dist/src/archive/key-registry.d.ts +52 -0
- package/dist/src/archive/key-registry.js +168 -0
- package/dist/src/archive/key-registry.js.map +11 -0
- package/dist/src/archive/per-height-digest.d.ts +99 -0
- package/dist/src/archive/per-height-digest.js +194 -0
- package/dist/src/archive/per-height-digest.js.map +11 -0
- package/dist/src/archive/progress.d.ts +36 -0
- package/dist/src/archive/progress.js +75 -0
- package/dist/src/archive/progress.js.map +10 -0
- package/dist/src/archive/range-digest.d.ts +7 -0
- package/dist/src/archive/semantic-digest-builder.d.ts +1094 -0
- package/dist/src/archive/semantic-digest-builder.js +302 -0
- package/dist/src/archive/semantic-digest-builder.js.map +11 -0
- package/dist/src/archive/semantic-digest.d.ts +131 -0
- package/dist/src/archive/semantic-digest.js +143 -0
- package/dist/src/archive/semantic-digest.js.map +10 -0
- package/dist/src/archive/status.d.ts +92 -0
- package/dist/src/archive/status.js +106 -0
- package/dist/src/archive/status.js.map +10 -0
- package/dist/src/db/index.d.ts +11 -1
- package/dist/src/db/index.js +26 -1
- package/dist/src/db/index.js.map +6 -5
- package/dist/src/db/queries/chain-reorgs.d.ts +7 -0
- package/dist/src/db/queries/chain-reorgs.js +25 -1
- package/dist/src/db/queries/chain-reorgs.js.map +6 -5
- package/dist/src/db/queries/contracts.d.ts +7 -0
- package/dist/src/db/queries/instance.d.ts +1038 -0
- package/dist/src/db/queries/instance.js +92 -0
- package/dist/src/db/queries/instance.js.map +10 -0
- package/dist/src/db/queries/integrity.d.ts +7 -0
- package/dist/src/db/queries/subgraph-gaps.d.ts +7 -0
- package/dist/src/db/queries/subgraph-operations.d.ts +7 -0
- package/dist/src/db/queries/subgraphs.d.ts +10 -1
- package/dist/src/db/queries/subgraphs.js +47 -23
- package/dist/src/db/queries/subgraphs.js.map +7 -7
- package/dist/src/db/queries/subscriptions.d.ts +7 -0
- package/dist/src/db/queries/subscriptions.js +47 -31
- package/dist/src/db/queries/subscriptions.js.map +5 -5
- package/dist/src/db/schema.d.ts +8 -1
- package/dist/src/index.d.ts +11 -1
- package/dist/src/index.js +26 -1
- package/dist/src/index.js.map +6 -5
- package/dist/src/node/client.d.ts +11 -1
- package/dist/src/node/client.js +42 -4
- package/dist/src/node/client.js.map +3 -3
- package/dist/src/node/local-client.d.ts +7 -0
- package/dist/src/node/nakamoto.d.ts +22 -7
- package/dist/src/node/nakamoto.js +46 -5
- package/dist/src/node/nakamoto.js.map +3 -3
- package/migrations/0115_instances.ts +33 -0
- package/package.json +38 -2
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `status.json` — the archive's operational truth, published short-cache from
|
|
3
|
+
* verified state only.
|
|
4
|
+
*
|
|
5
|
+
* Everything else in the tree is immutable and signed, which makes it durable
|
|
6
|
+
* but silent: a consumer holding a valid manifest cannot tell whether it is
|
|
7
|
+
* current, three days behind, or the last thing published before an incident.
|
|
8
|
+
* This object answers that, and it is the only object allowed to say something
|
|
9
|
+
* unflattering.
|
|
10
|
+
*
|
|
11
|
+
* The distinction this file exists to protect:
|
|
12
|
+
*
|
|
13
|
+
* lagging → the archive trails the chain tip because it only publishes below
|
|
14
|
+
* the finality boundary. This is CORRECT and permanent. An archive
|
|
15
|
+
* that reported `stale` for its own finality lag would be crying
|
|
16
|
+
* wolf forever, and consumers would learn to ignore it.
|
|
17
|
+
* stale → publishing stopped. The lag exceeds what the finality rule can
|
|
18
|
+
* explain, so something is broken.
|
|
19
|
+
*
|
|
20
|
+
* `state` is derived from measurements, never asserted by the publisher, and
|
|
21
|
+
* every unhealthy state is reachable — an archive that can only report health
|
|
22
|
+
* is decoration.
|
|
23
|
+
*/
|
|
24
|
+
declare const ARCHIVE_STATUS_SCHEMA_VERSION = 1;
|
|
25
|
+
type ArchiveState = "fresh" | "lagging" | "stale" | "gap" | "failed-audit" | "source-unavailable";
|
|
26
|
+
type ArchiveStatus = {
|
|
27
|
+
schema_version: typeof ARCHIVE_STATUS_SCHEMA_VERSION
|
|
28
|
+
network: string
|
|
29
|
+
state: ArchiveState
|
|
30
|
+
/** Human-facing one-liner explaining the state, including WHY. */
|
|
31
|
+
detail: string
|
|
32
|
+
generated_at: string
|
|
33
|
+
archive: {
|
|
34
|
+
snapshot_digest: string | null
|
|
35
|
+
coverage_to_block: number | null
|
|
36
|
+
promoted_at: string | null
|
|
37
|
+
signing_key_id: string | null
|
|
38
|
+
}
|
|
39
|
+
source: {
|
|
40
|
+
/** Chain tip as the publisher last observed it. Null when unreachable. */
|
|
41
|
+
tip_height: number | null
|
|
42
|
+
/** Highest height eligible to publish under the finality rule. */
|
|
43
|
+
finalized_height: number | null
|
|
44
|
+
}
|
|
45
|
+
lag: {
|
|
46
|
+
/** Behind the FINALIZED height — the number that indicates a problem. */
|
|
47
|
+
blocks_behind_finalized: number | null
|
|
48
|
+
/** Behind the raw chain tip — expected to be non-zero forever. */
|
|
49
|
+
blocks_behind_tip: number | null
|
|
50
|
+
seconds_since_promotion: number | null
|
|
51
|
+
}
|
|
52
|
+
audit: {
|
|
53
|
+
complete: boolean
|
|
54
|
+
checked_at: string
|
|
55
|
+
} | null
|
|
56
|
+
signature?: string
|
|
57
|
+
key_id?: string
|
|
58
|
+
};
|
|
59
|
+
type StatusInputs = {
|
|
60
|
+
network: string
|
|
61
|
+
snapshotDigest: string | null
|
|
62
|
+
coverageToBlock: number | null
|
|
63
|
+
promotedAt: string | null
|
|
64
|
+
signingKeyId: string | null
|
|
65
|
+
/** Null when the source could not be reached. */
|
|
66
|
+
sourceTipHeight: number | null
|
|
67
|
+
finalizedHeight: number | null
|
|
68
|
+
audit: {
|
|
69
|
+
complete: boolean
|
|
70
|
+
checkedAt: string
|
|
71
|
+
} | null
|
|
72
|
+
now: Date
|
|
73
|
+
/**
|
|
74
|
+
* How far behind the FINALIZED height the archive may fall before it is
|
|
75
|
+
* stale rather than merely lagging. Publishing one partition covers 50k
|
|
76
|
+
* blocks, so a healthy archive sits well inside this.
|
|
77
|
+
*/
|
|
78
|
+
maxBlocksBehindFinalized?: number
|
|
79
|
+
/** How long since the last promotion before staleness, regardless of height. */
|
|
80
|
+
maxSecondsSincePromotion?: number
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Derive status from measurements. Pure, so every state below is reachable in
|
|
84
|
+
* a test rather than only in production at 3am.
|
|
85
|
+
*
|
|
86
|
+
* Order matters: a failing audit outranks freshness, because an archive that
|
|
87
|
+
* is current and wrong is worse than one that is behind and correct.
|
|
88
|
+
*/
|
|
89
|
+
declare function deriveArchiveStatus(inputs: StatusInputs): ArchiveStatus;
|
|
90
|
+
/** States a consumer should refuse to restore from. */
|
|
91
|
+
declare function isRestorable(state: ArchiveState): boolean;
|
|
92
|
+
export { isRestorable, deriveArchiveStatus, StatusInputs, ArchiveStatus, ArchiveState, ARCHIVE_STATUS_SCHEMA_VERSION };
|
|
@@ -0,0 +1,106 @@
|
|
|
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/archive/status.ts
|
|
18
|
+
var ARCHIVE_STATUS_SCHEMA_VERSION = 1;
|
|
19
|
+
var DEFAULT_MAX_BLOCKS_BEHIND_FINALIZED = 60000;
|
|
20
|
+
var DEFAULT_MAX_SECONDS_SINCE_PROMOTION = 48 * 3600;
|
|
21
|
+
function deriveArchiveStatus(inputs) {
|
|
22
|
+
const maxBehind = inputs.maxBlocksBehindFinalized ?? DEFAULT_MAX_BLOCKS_BEHIND_FINALIZED;
|
|
23
|
+
const maxAge = inputs.maxSecondsSincePromotion ?? DEFAULT_MAX_SECONDS_SINCE_PROMOTION;
|
|
24
|
+
const secondsSincePromotion = inputs.promotedAt ? Math.max(0, Math.round((inputs.now.getTime() - Date.parse(inputs.promotedAt)) / 1000)) : null;
|
|
25
|
+
const behindFinalized = inputs.finalizedHeight !== null && inputs.coverageToBlock !== null ? Math.max(0, inputs.finalizedHeight - inputs.coverageToBlock) : null;
|
|
26
|
+
const behindTip = inputs.sourceTipHeight !== null && inputs.coverageToBlock !== null ? Math.max(0, inputs.sourceTipHeight - inputs.coverageToBlock) : null;
|
|
27
|
+
const base = {
|
|
28
|
+
schema_version: ARCHIVE_STATUS_SCHEMA_VERSION,
|
|
29
|
+
network: inputs.network,
|
|
30
|
+
generated_at: inputs.now.toISOString(),
|
|
31
|
+
archive: {
|
|
32
|
+
snapshot_digest: inputs.snapshotDigest,
|
|
33
|
+
coverage_to_block: inputs.coverageToBlock,
|
|
34
|
+
promoted_at: inputs.promotedAt,
|
|
35
|
+
signing_key_id: inputs.signingKeyId
|
|
36
|
+
},
|
|
37
|
+
source: {
|
|
38
|
+
tip_height: inputs.sourceTipHeight,
|
|
39
|
+
finalized_height: inputs.finalizedHeight
|
|
40
|
+
},
|
|
41
|
+
lag: {
|
|
42
|
+
blocks_behind_finalized: behindFinalized,
|
|
43
|
+
blocks_behind_tip: behindTip,
|
|
44
|
+
seconds_since_promotion: secondsSincePromotion
|
|
45
|
+
},
|
|
46
|
+
audit: inputs.audit ? { complete: inputs.audit.complete, checked_at: inputs.audit.checkedAt } : null
|
|
47
|
+
};
|
|
48
|
+
if (inputs.audit && !inputs.audit.complete) {
|
|
49
|
+
return {
|
|
50
|
+
...base,
|
|
51
|
+
state: "failed-audit",
|
|
52
|
+
detail: `the canonical audit did not pass at ${inputs.audit.checkedAt}; this archive is not safe to restore from`
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (!inputs.snapshotDigest || inputs.coverageToBlock === null) {
|
|
56
|
+
return {
|
|
57
|
+
...base,
|
|
58
|
+
state: "gap",
|
|
59
|
+
detail: "no snapshot is currently promoted"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (inputs.sourceTipHeight === null || inputs.finalizedHeight === null) {
|
|
63
|
+
return {
|
|
64
|
+
...base,
|
|
65
|
+
state: "source-unavailable",
|
|
66
|
+
detail: "the chain source could not be reached, so freshness cannot be determined"
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (secondsSincePromotion !== null && secondsSincePromotion > maxAge) {
|
|
70
|
+
return {
|
|
71
|
+
...base,
|
|
72
|
+
state: "stale",
|
|
73
|
+
detail: `last promotion was ${Math.round(secondsSincePromotion / 3600)}h ago, beyond the ${Math.round(maxAge / 3600)}h freshness objective`
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (behindFinalized !== null && behindFinalized > maxBehind) {
|
|
77
|
+
return {
|
|
78
|
+
...base,
|
|
79
|
+
state: "stale",
|
|
80
|
+
detail: `${behindFinalized} blocks behind the finalized height, beyond the ${maxBehind} threshold`
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (behindTip !== null && behindTip > 0) {
|
|
84
|
+
return {
|
|
85
|
+
...base,
|
|
86
|
+
state: "lagging",
|
|
87
|
+
detail: `${behindTip} blocks behind the chain tip, which is expected: only heights below the finality boundary are published`
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
...base,
|
|
92
|
+
state: "fresh",
|
|
93
|
+
detail: "published through the finalized height"
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function isRestorable(state) {
|
|
97
|
+
return state === "fresh" || state === "lagging";
|
|
98
|
+
}
|
|
99
|
+
export {
|
|
100
|
+
isRestorable,
|
|
101
|
+
deriveArchiveStatus,
|
|
102
|
+
ARCHIVE_STATUS_SCHEMA_VERSION
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//# debugId=D9102A12541A66EA64756E2164756E21
|
|
106
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/archive/status.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * `status.json` — the archive's operational truth, published short-cache from\n * verified state only.\n *\n * Everything else in the tree is immutable and signed, which makes it durable\n * but silent: a consumer holding a valid manifest cannot tell whether it is\n * current, three days behind, or the last thing published before an incident.\n * This object answers that, and it is the only object allowed to say something\n * unflattering.\n *\n * The distinction this file exists to protect:\n *\n * lagging → the archive trails the chain tip because it only publishes below\n * the finality boundary. This is CORRECT and permanent. An archive\n * that reported `stale` for its own finality lag would be crying\n * wolf forever, and consumers would learn to ignore it.\n * stale → publishing stopped. The lag exceeds what the finality rule can\n * explain, so something is broken.\n *\n * `state` is derived from measurements, never asserted by the publisher, and\n * every unhealthy state is reachable — an archive that can only report health\n * is decoration.\n */\n\nexport const ARCHIVE_STATUS_SCHEMA_VERSION = 1;\n\nexport type ArchiveState =\n\t| \"fresh\"\n\t| \"lagging\"\n\t| \"stale\"\n\t| \"gap\"\n\t| \"failed-audit\"\n\t| \"source-unavailable\";\n\nexport type ArchiveStatus = {\n\tschema_version: typeof ARCHIVE_STATUS_SCHEMA_VERSION;\n\tnetwork: string;\n\tstate: ArchiveState;\n\t/** Human-facing one-liner explaining the state, including WHY. */\n\tdetail: string;\n\tgenerated_at: string;\n\tarchive: {\n\t\tsnapshot_digest: string | null;\n\t\tcoverage_to_block: number | null;\n\t\tpromoted_at: string | null;\n\t\tsigning_key_id: string | null;\n\t};\n\tsource: {\n\t\t/** Chain tip as the publisher last observed it. Null when unreachable. */\n\t\ttip_height: number | null;\n\t\t/** Highest height eligible to publish under the finality rule. */\n\t\tfinalized_height: number | null;\n\t};\n\tlag: {\n\t\t/** Behind the FINALIZED height — the number that indicates a problem. */\n\t\tblocks_behind_finalized: number | null;\n\t\t/** Behind the raw chain tip — expected to be non-zero forever. */\n\t\tblocks_behind_tip: number | null;\n\t\tseconds_since_promotion: number | null;\n\t};\n\taudit: {\n\t\tcomplete: boolean;\n\t\tchecked_at: string;\n\t} | null;\n\tsignature?: string;\n\tkey_id?: string;\n};\n\nexport type StatusInputs = {\n\tnetwork: string;\n\tsnapshotDigest: string | null;\n\tcoverageToBlock: number | null;\n\tpromotedAt: string | null;\n\tsigningKeyId: string | null;\n\t/** Null when the source could not be reached. */\n\tsourceTipHeight: number | null;\n\tfinalizedHeight: number | null;\n\taudit: { complete: boolean; checkedAt: string } | null;\n\tnow: Date;\n\t/**\n\t * How far behind the FINALIZED height the archive may fall before it is\n\t * stale rather than merely lagging. Publishing one partition covers 50k\n\t * blocks, so a healthy archive sits well inside this.\n\t */\n\tmaxBlocksBehindFinalized?: number;\n\t/** How long since the last promotion before staleness, regardless of height. */\n\tmaxSecondsSincePromotion?: number;\n};\n\nconst DEFAULT_MAX_BLOCKS_BEHIND_FINALIZED = 60_000;\nconst DEFAULT_MAX_SECONDS_SINCE_PROMOTION = 48 * 3_600;\n\n/**\n * Derive status from measurements. Pure, so every state below is reachable in\n * a test rather than only in production at 3am.\n *\n * Order matters: a failing audit outranks freshness, because an archive that\n * is current and wrong is worse than one that is behind and correct.\n */\nexport function deriveArchiveStatus(inputs: StatusInputs): ArchiveStatus {\n\tconst maxBehind =\n\t\tinputs.maxBlocksBehindFinalized ?? DEFAULT_MAX_BLOCKS_BEHIND_FINALIZED;\n\tconst maxAge =\n\t\tinputs.maxSecondsSincePromotion ?? DEFAULT_MAX_SECONDS_SINCE_PROMOTION;\n\n\tconst secondsSincePromotion = inputs.promotedAt\n\t\t? Math.max(\n\t\t\t\t0,\n\t\t\t\tMath.round(\n\t\t\t\t\t(inputs.now.getTime() - Date.parse(inputs.promotedAt)) / 1000,\n\t\t\t\t),\n\t\t\t)\n\t\t: null;\n\n\tconst behindFinalized =\n\t\tinputs.finalizedHeight !== null && inputs.coverageToBlock !== null\n\t\t\t? Math.max(0, inputs.finalizedHeight - inputs.coverageToBlock)\n\t\t\t: null;\n\tconst behindTip =\n\t\tinputs.sourceTipHeight !== null && inputs.coverageToBlock !== null\n\t\t\t? Math.max(0, inputs.sourceTipHeight - inputs.coverageToBlock)\n\t\t\t: null;\n\n\tconst base = {\n\t\tschema_version:\n\t\t\tARCHIVE_STATUS_SCHEMA_VERSION as typeof ARCHIVE_STATUS_SCHEMA_VERSION,\n\t\tnetwork: inputs.network,\n\t\tgenerated_at: inputs.now.toISOString(),\n\t\tarchive: {\n\t\t\tsnapshot_digest: inputs.snapshotDigest,\n\t\t\tcoverage_to_block: inputs.coverageToBlock,\n\t\t\tpromoted_at: inputs.promotedAt,\n\t\t\tsigning_key_id: inputs.signingKeyId,\n\t\t},\n\t\tsource: {\n\t\t\ttip_height: inputs.sourceTipHeight,\n\t\t\tfinalized_height: inputs.finalizedHeight,\n\t\t},\n\t\tlag: {\n\t\t\tblocks_behind_finalized: behindFinalized,\n\t\t\tblocks_behind_tip: behindTip,\n\t\t\tseconds_since_promotion: secondsSincePromotion,\n\t\t},\n\t\taudit: inputs.audit\n\t\t\t? { complete: inputs.audit.complete, checked_at: inputs.audit.checkedAt }\n\t\t\t: null,\n\t};\n\n\t// A failed audit is the loudest signal: current-and-wrong beats behind-and-right.\n\tif (inputs.audit && !inputs.audit.complete) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"failed-audit\",\n\t\t\tdetail: `the canonical audit did not pass at ${inputs.audit.checkedAt}; this archive is not safe to restore from`,\n\t\t};\n\t}\n\n\tif (!inputs.snapshotDigest || inputs.coverageToBlock === null) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"gap\",\n\t\t\tdetail: \"no snapshot is currently promoted\",\n\t\t};\n\t}\n\n\t// Source unreachable: report the gap in KNOWLEDGE rather than guessing. The\n\t// archive may be perfectly healthy; we cannot currently say so.\n\tif (inputs.sourceTipHeight === null || inputs.finalizedHeight === null) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"source-unavailable\",\n\t\t\tdetail:\n\t\t\t\t\"the chain source could not be reached, so freshness cannot be determined\",\n\t\t};\n\t}\n\n\tif (secondsSincePromotion !== null && secondsSincePromotion > maxAge) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"stale\",\n\t\t\tdetail: `last promotion was ${Math.round(secondsSincePromotion / 3_600)}h ago, beyond the ${Math.round(maxAge / 3_600)}h freshness objective`,\n\t\t};\n\t}\n\n\tif (behindFinalized !== null && behindFinalized > maxBehind) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"stale\",\n\t\t\tdetail: `${behindFinalized} blocks behind the finalized height, beyond the ${maxBehind} threshold`,\n\t\t};\n\t}\n\n\t// Behind the tip but within the finality boundary — correct, permanent, and\n\t// explicitly NOT staleness.\n\tif (behindTip !== null && behindTip > 0) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"lagging\",\n\t\t\tdetail: `${behindTip} blocks behind the chain tip, which is expected: only heights below the finality boundary are published`,\n\t\t};\n\t}\n\n\treturn {\n\t\t...base,\n\t\tstate: \"fresh\",\n\t\tdetail: \"published through the finalized height\",\n\t};\n}\n\n/** States a consumer should refuse to restore from. */\nexport function isRestorable(state: ArchiveState): boolean {\n\treturn state === \"fresh\" || state === \"lagging\";\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;AAwBO,IAAM,gCAAgC;AAiE7C,IAAM,sCAAsC;AAC5C,IAAM,sCAAsC,KAAK;AAS1C,SAAS,mBAAmB,CAAC,QAAqC;AAAA,EACxE,MAAM,YACL,OAAO,4BAA4B;AAAA,EACpC,MAAM,SACL,OAAO,4BAA4B;AAAA,EAEpC,MAAM,wBAAwB,OAAO,aAClC,KAAK,IACL,GACA,KAAK,OACH,OAAO,IAAI,QAAQ,IAAI,KAAK,MAAM,OAAO,UAAU,KAAK,IAC1D,CACD,IACC;AAAA,EAEH,MAAM,kBACL,OAAO,oBAAoB,QAAQ,OAAO,oBAAoB,OAC3D,KAAK,IAAI,GAAG,OAAO,kBAAkB,OAAO,eAAe,IAC3D;AAAA,EACJ,MAAM,YACL,OAAO,oBAAoB,QAAQ,OAAO,oBAAoB,OAC3D,KAAK,IAAI,GAAG,OAAO,kBAAkB,OAAO,eAAe,IAC3D;AAAA,EAEJ,MAAM,OAAO;AAAA,IACZ,gBACC;AAAA,IACD,SAAS,OAAO;AAAA,IAChB,cAAc,OAAO,IAAI,YAAY;AAAA,IACrC,SAAS;AAAA,MACR,iBAAiB,OAAO;AAAA,MACxB,mBAAmB,OAAO;AAAA,MAC1B,aAAa,OAAO;AAAA,MACpB,gBAAgB,OAAO;AAAA,IACxB;AAAA,IACA,QAAQ;AAAA,MACP,YAAY,OAAO;AAAA,MACnB,kBAAkB,OAAO;AAAA,IAC1B;AAAA,IACA,KAAK;AAAA,MACJ,yBAAyB;AAAA,MACzB,mBAAmB;AAAA,MACnB,yBAAyB;AAAA,IAC1B;AAAA,IACA,OAAO,OAAO,QACX,EAAE,UAAU,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,UAAU,IACtE;AAAA,EACJ;AAAA,EAGA,IAAI,OAAO,SAAS,CAAC,OAAO,MAAM,UAAU;AAAA,IAC3C,OAAO;AAAA,SACH;AAAA,MACH,OAAO;AAAA,MACP,QAAQ,uCAAuC,OAAO,MAAM;AAAA,IAC7D;AAAA,EACD;AAAA,EAEA,IAAI,CAAC,OAAO,kBAAkB,OAAO,oBAAoB,MAAM;AAAA,IAC9D,OAAO;AAAA,SACH;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,IACT;AAAA,EACD;AAAA,EAIA,IAAI,OAAO,oBAAoB,QAAQ,OAAO,oBAAoB,MAAM;AAAA,IACvE,OAAO;AAAA,SACH;AAAA,MACH,OAAO;AAAA,MACP,QACC;AAAA,IACF;AAAA,EACD;AAAA,EAEA,IAAI,0BAA0B,QAAQ,wBAAwB,QAAQ;AAAA,IACrE,OAAO;AAAA,SACH;AAAA,MACH,OAAO;AAAA,MACP,QAAQ,sBAAsB,KAAK,MAAM,wBAAwB,IAAK,sBAAsB,KAAK,MAAM,SAAS,IAAK;AAAA,IACtH;AAAA,EACD;AAAA,EAEA,IAAI,oBAAoB,QAAQ,kBAAkB,WAAW;AAAA,IAC5D,OAAO;AAAA,SACH;AAAA,MACH,OAAO;AAAA,MACP,QAAQ,GAAG,kEAAkE;AAAA,IAC9E;AAAA,EACD;AAAA,EAIA,IAAI,cAAc,QAAQ,YAAY,GAAG;AAAA,IACxC,OAAO;AAAA,SACH;AAAA,MACH,OAAO;AAAA,MACP,QAAQ,GAAG;AAAA,IACZ;AAAA,EACD;AAAA,EAEA,OAAO;AAAA,OACH;AAAA,IACH,OAAO;AAAA,IACP,QAAQ;AAAA,EACT;AAAA;AAIM,SAAS,YAAY,CAAC,OAA8B;AAAA,EAC1D,OAAO,UAAU,WAAW,UAAU;AAAA;",
|
|
8
|
+
"debugId": "D9102A12541A66EA64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/src/db/index.d.ts
CHANGED
|
@@ -209,6 +209,12 @@ interface ApiKeysTable {
|
|
|
209
209
|
revoked_at: Date | null;
|
|
210
210
|
created_at: Generated<Date>;
|
|
211
211
|
}
|
|
212
|
+
/** Singleton self-host / publisher identity. Network is immutable. */
|
|
213
|
+
interface InstancesTable {
|
|
214
|
+
id: Generated<string>;
|
|
215
|
+
network: string;
|
|
216
|
+
created_at: Generated<Date>;
|
|
217
|
+
}
|
|
212
218
|
interface AccountsTable {
|
|
213
219
|
id: Generated<string>;
|
|
214
220
|
/** NULL for unclaimed ghost accounts (anonymous self-serve keys). */
|
|
@@ -751,6 +757,7 @@ interface Database {
|
|
|
751
757
|
contracts: ContractsTable;
|
|
752
758
|
subgraphs: SubgraphsTable;
|
|
753
759
|
api_keys: ApiKeysTable;
|
|
760
|
+
instances: InstancesTable;
|
|
754
761
|
accounts: AccountsTable;
|
|
755
762
|
sessions: SessionsTable;
|
|
756
763
|
magic_links: MagicLinksTable;
|
|
@@ -2008,6 +2015,7 @@ declare const TABLE_TO_DB: {
|
|
|
2008
2015
|
bns_marketplace_events: string
|
|
2009
2016
|
bns_names: string
|
|
2010
2017
|
bns_namespaces: string
|
|
2018
|
+
instances: string
|
|
2011
2019
|
accounts: string
|
|
2012
2020
|
api_keys: string
|
|
2013
2021
|
sessions: string
|
|
@@ -2042,6 +2050,8 @@ declare const TABLE_TO_DB: {
|
|
|
2042
2050
|
account_credits: string
|
|
2043
2051
|
service_heartbeats: string
|
|
2044
2052
|
};
|
|
2053
|
+
/** OSS: one application URL. SOURCE_/TARGET_ are hosted split only. */
|
|
2054
|
+
declare function applicationDatabaseUrl(): string;
|
|
2045
2055
|
interface DbSplitStatus {
|
|
2046
2056
|
/** "split" when source/target resolve to different DBs, else "single". */
|
|
2047
2057
|
mode: "split" | "single";
|
|
@@ -2109,4 +2119,4 @@ declare function getRawClient(role?: "source" | "target"): ReturnType<typeof pos
|
|
|
2109
2119
|
declare function getRawClientFor(url: string): ReturnType<typeof postgres>;
|
|
2110
2120
|
/** Close all DB connection pools. Call in CLI commands to allow process exit. */
|
|
2111
2121
|
declare function closeDb(): Promise<void>;
|
|
2112
|
-
export { sql, setMigrationRole, parseJsonb, onControlPlane, onChainPlane, jsonb, getTargetDb, getSourceDb, getRawClientFor, getRawClient, getMigrationRole, getDbSplitStatus, getDb, closeDb, assertDbSplit, X402PaymentsTable, X402BalancesTable, UsageSnapshotsTable, UsageSnapshot, UsageDailyTable, UsageDaily, UpdateTransaction, UpdateTenantUsageMonthly, UpdateTenantComputeAddon, UpdateTenant, UpdateSubscriptionOutbox, UpdateSubscription, UpdateSubgraphOperation, UpdateSubgraph, UpdateProject, UpdateIndexProgress, UpdateEvent, UpdateContract, UpdateBlock, UpdateApiKey, UpdateAccountSpendCap, UpdateAccountCredits, TriggerEvaluatorStateTable, TriggerEvaluatorState, TransactionsTable, TransactionsArchiveTable, Transaction, TenantsTable, TenantUsageMonthlyTable, TenantUsageMonthly, TenantStatus, TenantComputeAddonsTable, TenantComputeAddon, Tenant, TeamMembersTable, TeamMember, TeamInvitationsTable, TeamInvitation, TABLE_TO_DB, SubscriptionsTable, SubscriptionStatus, SubscriptionRuntime, SubscriptionOutboxTable, SubscriptionOutbox, SubscriptionKind, SubscriptionFormat, SubscriptionDelivery, SubscriptionDeliveriesTable, Subscription, SubgraphsTable, SubgraphUsageDailyTable, SubgraphUsageDaily, SubgraphTableSnapshotsTable, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGap, Subgraph, SessionsTable, Session, ServiceHeartbeatsTable, SbtcTokenEventsTable, SbtcTokenEventType, SbtcSupplySnapshotsTable, SbtcSettlementsTable, SbtcEventsTable, SbtcEventTopic, SOURCE_READ_TYPES, SOURCE_READ_PKS, SOURCE_READ_COLUMNS, ProvisioningAuditStatus, ProvisioningAuditLogTable, ProvisioningAuditLog, ProvisioningAuditEvent, ProjectsTable, Project, ProcessedStripeEventsTable, Pox5EventsTable, Pox5EventTopic, Pox4SignersDailyTable, Pox4FunctionName, Pox4CyclesDailyTable, Pox4CallsTable, PendingForkBlocksTable, OutboxStatus, ObserverJournalTable, ObserverJournalStatus, NumericAsText, MigrationRole, MempoolTransactionsTable, MempoolTransaction, MagicLinksTable, MagicLink, InsertTransaction, InsertTenantUsageMonthly, InsertTenantComputeAddon, InsertTenant, InsertTeamMember, InsertTeamInvitation, InsertSubscriptionOutbox, InsertSubscriptionDelivery, InsertSubscription, InsertSubgraphUsageDaily, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertProvisioningAuditLog, InsertProject, InsertMempoolTransaction, InsertMagicLink, InsertIndexProgress, InsertEvent, InsertContract, InsertClaimToken, InsertBlock, InsertApiKey, InsertAccountSpendCap, InsertAccountInsight, InsertAccountCredits, InsertAccountAgentRun, InsertAccount, IndexProgressTable, IndexProgress, IndexPrimaryKey, IndexColumnType, IndexColumn, EventsTable, EventsArchiveTable, Event, DecoderCheckpointsTable, DecodedEventsTable, DeadLetterEventsTable, DbSplitStatus, DbReadRow, DbPlane, Database, ContractsTable, Contract, ClaimTokensTable, ClaimToken, ChainReorgsTable, ChainReadCacheTable, BurnBlockRewardsTable, BurnBlockRewardSlotsTable, BnsNamespacesTable, BnsNamespaceEventsTable, BnsNamespaceEventStatus, BnsNamesTable, BnsNameEventsTable, BnsNameEventTopic, BnsMarketplaceEventsTable, BnsMarketplaceAction, BlocksTable, Block, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountInsightsTable, AccountInsight, AccountCreditsTable, AccountCredits, AccountAgentRunsTable, AccountAgentRun, Account };
|
|
2122
|
+
export { sql, setMigrationRole, parseJsonb, onControlPlane, onChainPlane, jsonb, getTargetDb, getSourceDb, getRawClientFor, getRawClient, getMigrationRole, getDbSplitStatus, getDb, closeDb, assertDbSplit, applicationDatabaseUrl, X402PaymentsTable, X402BalancesTable, UsageSnapshotsTable, UsageSnapshot, UsageDailyTable, UsageDaily, UpdateTransaction, UpdateTenantUsageMonthly, UpdateTenantComputeAddon, UpdateTenant, UpdateSubscriptionOutbox, UpdateSubscription, UpdateSubgraphOperation, UpdateSubgraph, UpdateProject, UpdateIndexProgress, UpdateEvent, UpdateContract, UpdateBlock, UpdateApiKey, UpdateAccountSpendCap, UpdateAccountCredits, TriggerEvaluatorStateTable, TriggerEvaluatorState, TransactionsTable, TransactionsArchiveTable, Transaction, TenantsTable, TenantUsageMonthlyTable, TenantUsageMonthly, TenantStatus, TenantComputeAddonsTable, TenantComputeAddon, Tenant, TeamMembersTable, TeamMember, TeamInvitationsTable, TeamInvitation, TABLE_TO_DB, SubscriptionsTable, SubscriptionStatus, SubscriptionRuntime, SubscriptionOutboxTable, SubscriptionOutbox, SubscriptionKind, SubscriptionFormat, SubscriptionDelivery, SubscriptionDeliveriesTable, Subscription, SubgraphsTable, SubgraphUsageDailyTable, SubgraphUsageDaily, SubgraphTableSnapshotsTable, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGap, Subgraph, SessionsTable, Session, ServiceHeartbeatsTable, SbtcTokenEventsTable, SbtcTokenEventType, SbtcSupplySnapshotsTable, SbtcSettlementsTable, SbtcEventsTable, SbtcEventTopic, SOURCE_READ_TYPES, SOURCE_READ_PKS, SOURCE_READ_COLUMNS, ProvisioningAuditStatus, ProvisioningAuditLogTable, ProvisioningAuditLog, ProvisioningAuditEvent, ProjectsTable, Project, ProcessedStripeEventsTable, Pox5EventsTable, Pox5EventTopic, Pox4SignersDailyTable, Pox4FunctionName, Pox4CyclesDailyTable, Pox4CallsTable, PendingForkBlocksTable, OutboxStatus, ObserverJournalTable, ObserverJournalStatus, NumericAsText, MigrationRole, MempoolTransactionsTable, MempoolTransaction, MagicLinksTable, MagicLink, InstancesTable, InsertTransaction, InsertTenantUsageMonthly, InsertTenantComputeAddon, InsertTenant, InsertTeamMember, InsertTeamInvitation, InsertSubscriptionOutbox, InsertSubscriptionDelivery, InsertSubscription, InsertSubgraphUsageDaily, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertProvisioningAuditLog, InsertProject, InsertMempoolTransaction, InsertMagicLink, InsertIndexProgress, InsertEvent, InsertContract, InsertClaimToken, InsertBlock, InsertApiKey, InsertAccountSpendCap, InsertAccountInsight, InsertAccountCredits, InsertAccountAgentRun, InsertAccount, IndexProgressTable, IndexProgress, IndexPrimaryKey, IndexColumnType, IndexColumn, EventsTable, EventsArchiveTable, Event, DecoderCheckpointsTable, DecodedEventsTable, DeadLetterEventsTable, DbSplitStatus, DbReadRow, DbPlane, Database, ContractsTable, Contract, ClaimTokensTable, ClaimToken, ChainReorgsTable, ChainReadCacheTable, BurnBlockRewardsTable, BurnBlockRewardSlotsTable, BnsNamespacesTable, BnsNamespaceEventsTable, BnsNamespaceEventStatus, BnsNamesTable, BnsNameEventsTable, BnsNameEventTopic, BnsMarketplaceEventsTable, BnsMarketplaceAction, BlocksTable, Block, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountInsightsTable, AccountInsight, AccountCreditsTable, AccountCredits, AccountAgentRunsTable, AccountAgentRun, Account };
|
package/dist/src/db/index.js
CHANGED
|
@@ -138,6 +138,22 @@ class Logger {
|
|
|
138
138
|
}
|
|
139
139
|
var logger = new Logger;
|
|
140
140
|
|
|
141
|
+
// src/mode.ts
|
|
142
|
+
var VALID_MODES = ["oss", "platform"];
|
|
143
|
+
function getInstanceMode() {
|
|
144
|
+
const raw = process.env.INSTANCE_MODE?.trim().toLowerCase();
|
|
145
|
+
if (raw && VALID_MODES.includes(raw)) {
|
|
146
|
+
return raw;
|
|
147
|
+
}
|
|
148
|
+
return "oss";
|
|
149
|
+
}
|
|
150
|
+
function isPlatformMode() {
|
|
151
|
+
return getInstanceMode() === "platform";
|
|
152
|
+
}
|
|
153
|
+
function isOssMode() {
|
|
154
|
+
return getInstanceMode() === "oss";
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
// src/db/jsonb.ts
|
|
142
158
|
import { sql } from "kysely";
|
|
143
159
|
function jsonb(value) {
|
|
@@ -723,6 +739,7 @@ var TABLE_TO_DB = {
|
|
|
723
739
|
bns_marketplace_events: "source",
|
|
724
740
|
bns_names: "source",
|
|
725
741
|
bns_namespaces: "source",
|
|
742
|
+
instances: "target",
|
|
726
743
|
accounts: "target",
|
|
727
744
|
api_keys: "target",
|
|
728
745
|
sessions: "target",
|
|
@@ -785,10 +802,17 @@ function evictIfNeeded() {
|
|
|
785
802
|
const evicted = lruEntry;
|
|
786
803
|
evicted.db.destroy().catch(() => {}).then(() => evicted.rawClient.end({ timeout: 5 })).catch(() => {});
|
|
787
804
|
}
|
|
805
|
+
function applicationDatabaseUrl() {
|
|
806
|
+
return process.env.DATABASE_URL || DEFAULT_URL;
|
|
807
|
+
}
|
|
788
808
|
function resolveSourceUrl() {
|
|
809
|
+
if (!isPlatformMode())
|
|
810
|
+
return applicationDatabaseUrl();
|
|
789
811
|
return process.env.SOURCE_DATABASE_URL || process.env.DATABASE_URL || DEFAULT_URL;
|
|
790
812
|
}
|
|
791
813
|
function resolveTargetUrl() {
|
|
814
|
+
if (!isPlatformMode())
|
|
815
|
+
return applicationDatabaseUrl();
|
|
792
816
|
return process.env.TARGET_DATABASE_URL || process.env.DATABASE_URL || DEFAULT_URL;
|
|
793
817
|
}
|
|
794
818
|
function describeDbUrl(url) {
|
|
@@ -943,11 +967,12 @@ export {
|
|
|
943
967
|
getDb,
|
|
944
968
|
closeDb,
|
|
945
969
|
assertDbSplit,
|
|
970
|
+
applicationDatabaseUrl,
|
|
946
971
|
TABLE_TO_DB,
|
|
947
972
|
SOURCE_READ_TYPES,
|
|
948
973
|
SOURCE_READ_PKS,
|
|
949
974
|
SOURCE_READ_COLUMNS
|
|
950
975
|
};
|
|
951
976
|
|
|
952
|
-
//# debugId=
|
|
977
|
+
//# debugId=BB27A04E8664D30164756E2164756E21
|
|
953
978
|
//# sourceMappingURL=index.js.map
|