@cello-protocol/daemon 0.0.3 → 0.0.5
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/agent-loader.d.ts +41 -0
- package/dist/agent-loader.d.ts.map +1 -0
- package/dist/agent-loader.js +94 -0
- package/dist/agent-loader.js.map +1 -0
- package/dist/bin/cello-daemon.d.ts +13 -0
- package/dist/bin/cello-daemon.d.ts.map +1 -0
- package/dist/bin/cello-daemon.js +170 -0
- package/dist/bin/cello-daemon.js.map +1 -0
- package/dist/cello-node-transport-dialer.d.ts +59 -0
- package/dist/cello-node-transport-dialer.d.ts.map +1 -0
- package/dist/cello-node-transport-dialer.js +108 -0
- package/dist/cello-node-transport-dialer.js.map +1 -0
- package/dist/challenge-verifier.d.ts +12 -0
- package/dist/challenge-verifier.d.ts.map +1 -0
- package/dist/challenge-verifier.js +11 -0
- package/dist/challenge-verifier.js.map +1 -0
- package/dist/connect-or-start.d.ts +25 -0
- package/dist/connect-or-start.d.ts.map +1 -0
- package/dist/connect-or-start.js +117 -0
- package/dist/connect-or-start.js.map +1 -0
- package/dist/content-park-client.d.ts +49 -0
- package/dist/content-park-client.d.ts.map +1 -0
- package/dist/content-park-client.js +196 -0
- package/dist/content-park-client.js.map +1 -0
- package/dist/daemon.d.ts +65 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +3202 -0
- package/dist/daemon.js.map +1 -0
- package/dist/directory-bootstrap.d.ts +55 -0
- package/dist/directory-bootstrap.d.ts.map +1 -0
- package/dist/directory-bootstrap.js +102 -0
- package/dist/directory-bootstrap.js.map +1 -0
- package/dist/file-manifest-provider.d.ts +18 -0
- package/dist/file-manifest-provider.d.ts.map +1 -0
- package/dist/file-manifest-provider.js +72 -0
- package/dist/file-manifest-provider.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc-client.d.ts +31 -0
- package/dist/ipc-client.d.ts.map +1 -0
- package/dist/ipc-client.js +112 -0
- package/dist/ipc-client.js.map +1 -0
- package/dist/ipc-server.d.ts +49 -0
- package/dist/ipc-server.d.ts.map +1 -0
- package/dist/ipc-server.js +268 -0
- package/dist/ipc-server.js.map +1 -0
- package/dist/lock-file.d.ts +27 -0
- package/dist/lock-file.d.ts.map +1 -0
- package/dist/lock-file.js +84 -0
- package/dist/lock-file.js.map +1 -0
- package/dist/manifest-loader.d.ts +33 -0
- package/dist/manifest-loader.d.ts.map +1 -0
- package/dist/manifest-loader.js +70 -0
- package/dist/manifest-loader.js.map +1 -0
- package/dist/manifest-poll-scheduler.d.ts +31 -0
- package/dist/manifest-poll-scheduler.d.ts.map +1 -0
- package/dist/manifest-poll-scheduler.js +59 -0
- package/dist/manifest-poll-scheduler.js.map +1 -0
- package/dist/manifest-version-store-file.d.ts +18 -0
- package/dist/manifest-version-store-file.d.ts.map +1 -0
- package/dist/manifest-version-store-file.js +40 -0
- package/dist/manifest-version-store-file.js.map +1 -0
- package/dist/manifest-version-store.d.ts +14 -0
- package/dist/manifest-version-store.d.ts.map +1 -0
- package/dist/manifest-version-store.js +13 -0
- package/dist/manifest-version-store.js.map +1 -0
- package/dist/network-directory-node.d.ts +94 -0
- package/dist/network-directory-node.d.ts.map +1 -0
- package/dist/network-directory-node.js +626 -0
- package/dist/network-directory-node.js.map +1 -0
- package/dist/nonce-dedup.d.ts +68 -0
- package/dist/nonce-dedup.d.ts.map +1 -0
- package/dist/nonce-dedup.js +204 -0
- package/dist/nonce-dedup.js.map +1 -0
- package/dist/notification-dispatcher.d.ts +65 -0
- package/dist/notification-dispatcher.d.ts.map +1 -0
- package/dist/notification-dispatcher.js +138 -0
- package/dist/notification-dispatcher.js.map +1 -0
- package/dist/registration-context.d.ts +69 -0
- package/dist/registration-context.d.ts.map +1 -0
- package/dist/registration-context.js +118 -0
- package/dist/registration-context.js.map +1 -0
- package/dist/registration-manager.d.ts +72 -0
- package/dist/registration-manager.d.ts.map +1 -0
- package/dist/registration-manager.js +267 -0
- package/dist/registration-manager.js.map +1 -0
- package/dist/registration-persistence.d.ts +131 -0
- package/dist/registration-persistence.d.ts.map +1 -0
- package/dist/registration-persistence.js +233 -0
- package/dist/registration-persistence.js.map +1 -0
- package/dist/retry-queue.d.ts +144 -0
- package/dist/retry-queue.d.ts.map +1 -0
- package/dist/retry-queue.js +444 -0
- package/dist/retry-queue.js.map +1 -0
- package/dist/seal-frontier-verify.d.ts +58 -0
- package/dist/seal-frontier-verify.d.ts.map +1 -0
- package/dist/seal-frontier-verify.js +87 -0
- package/dist/seal-frontier-verify.js.map +1 -0
- package/dist/seal-legibility-tbs.d.ts +25 -0
- package/dist/seal-legibility-tbs.d.ts.map +1 -0
- package/dist/seal-legibility-tbs.js +78 -0
- package/dist/seal-legibility-tbs.js.map +1 -0
- package/dist/seal-upgrade.d.ts +90 -0
- package/dist/seal-upgrade.d.ts.map +1 -0
- package/dist/seal-upgrade.js +178 -0
- package/dist/seal-upgrade.js.map +1 -0
- package/dist/session-assignment-parser.d.ts +22 -0
- package/dist/session-assignment-parser.d.ts.map +1 -0
- package/dist/session-assignment-parser.js +139 -0
- package/dist/session-assignment-parser.js.map +1 -0
- package/dist/session-ceremony.d.ts +156 -0
- package/dist/session-ceremony.d.ts.map +1 -0
- package/dist/session-ceremony.js +447 -0
- package/dist/session-ceremony.js.map +1 -0
- package/dist/session-connection-gater.d.ts +91 -0
- package/dist/session-connection-gater.d.ts.map +1 -0
- package/dist/session-connection-gater.js +146 -0
- package/dist/session-connection-gater.js.map +1 -0
- package/dist/session-node-manager.d.ts +585 -0
- package/dist/session-node-manager.d.ts.map +1 -0
- package/dist/session-node-manager.js +2609 -0
- package/dist/session-node-manager.js.map +1 -0
- package/dist/session-relay-client.d.ts +101 -0
- package/dist/session-relay-client.d.ts.map +1 -0
- package/dist/session-relay-client.js +520 -0
- package/dist/session-relay-client.js.map +1 -0
- package/dist/session-tree.d.ts +80 -0
- package/dist/session-tree.d.ts.map +1 -0
- package/dist/session-tree.js +123 -0
- package/dist/session-tree.js.map +1 -0
- package/dist/signaling-connect.d.ts +83 -0
- package/dist/signaling-connect.d.ts.map +1 -0
- package/dist/signaling-connect.js +266 -0
- package/dist/signaling-connect.js.map +1 -0
- package/dist/transcript-cipher.d.ts +31 -0
- package/dist/transcript-cipher.d.ts.map +1 -0
- package/dist/transcript-cipher.js +74 -0
- package/dist/transcript-cipher.js.map +1 -0
- package/dist/transport-composition.d.ts +31 -0
- package/dist/transport-composition.d.ts.map +1 -0
- package/dist/transport-composition.js +55 -0
- package/dist/transport-composition.js.map +1 -0
- package/dist/transport-selector.d.ts +189 -0
- package/dist/transport-selector.d.ts.map +1 -0
- package/dist/transport-selector.js +195 -0
- package/dist/transport-selector.js.map +1 -0
- package/dist/types.d.ts +265 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +33 -0
- package/dist/types.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M7-MANIFEST-002 — FileManifestProvider: production IManifestProvider implementation.
|
|
3
|
+
*
|
|
4
|
+
* Reads the bundled consortium-manifest.json from the package root, parses it,
|
|
5
|
+
* verifies the threshold signatures, and caches the result for subsequent calls
|
|
6
|
+
* to getCurrentManifest().
|
|
7
|
+
*
|
|
8
|
+
* Tests use TestManifestProvider (from @cello-protocol/transport) which
|
|
9
|
+
* takes a pre-built ConsortiumManifest and skips file read and signature verification.
|
|
10
|
+
*
|
|
11
|
+
* Crypto reference: RFC 8032 (Ed25519 threshold signature verification via verifyManifest).
|
|
12
|
+
*/
|
|
13
|
+
import { readFile } from "node:fs/promises";
|
|
14
|
+
import { join, dirname } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { verifyManifest } from "@cello-protocol/crypto";
|
|
17
|
+
/**
|
|
18
|
+
* FileManifestProvider — reads consortium-manifest.json from the package root.
|
|
19
|
+
*
|
|
20
|
+
* Pseudocode:
|
|
21
|
+
* loadAndVerify(rootKeys, threshold):
|
|
22
|
+
* 1. Read consortium-manifest.json from the package root (same directory as this file).
|
|
23
|
+
* 2. Parse as JSON — throw on parse failure.
|
|
24
|
+
* 3. Call verifyManifest(parsed, rootKeys, threshold) — RFC 8032 Ed25519 threshold check.
|
|
25
|
+
* 4. If ok: cache the manifest, return it.
|
|
26
|
+
* 5. If not ok: throw Error with reason from verifyManifest diagnostics.
|
|
27
|
+
*/
|
|
28
|
+
export class FileManifestProvider {
|
|
29
|
+
#manifestPath;
|
|
30
|
+
#cachedManifest = null;
|
|
31
|
+
constructor(manifestPath) {
|
|
32
|
+
// Default: consortium-manifest.json in the same directory as this file
|
|
33
|
+
this.#manifestPath = manifestPath ?? join(dirname(fileURLToPath(import.meta.url)), "consortium-manifest.json");
|
|
34
|
+
}
|
|
35
|
+
async loadAndVerify(rootKeys, threshold) {
|
|
36
|
+
// Step 1: read the manifest file
|
|
37
|
+
let raw;
|
|
38
|
+
try {
|
|
39
|
+
raw = await readFile(this.#manifestPath, "utf-8");
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
throw new Error(`manifest_file_unreadable: cannot read ${this.#manifestPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
43
|
+
}
|
|
44
|
+
// Step 2: parse JSON
|
|
45
|
+
let parsed;
|
|
46
|
+
try {
|
|
47
|
+
parsed = JSON.parse(raw);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
throw new Error(`manifest_parse_failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
51
|
+
}
|
|
52
|
+
// Cast to ConsortiumManifestInput for verifyManifest (uses indexed record type)
|
|
53
|
+
const manifest = parsed;
|
|
54
|
+
// Step 3: verify threshold signatures (RFC 8032)
|
|
55
|
+
const result = verifyManifest(manifest, rootKeys, threshold);
|
|
56
|
+
if (!result.ok) {
|
|
57
|
+
throw new Error(`${result.reason}: ${result.detail} (threshold=${result.diagnostics.threshold}, valid=${result.diagnostics.validOfficers.length})`);
|
|
58
|
+
}
|
|
59
|
+
// Step 4: cache and return (cast back to ConsortiumManifest for consumers)
|
|
60
|
+
this.#cachedManifest = manifest;
|
|
61
|
+
return this.#cachedManifest;
|
|
62
|
+
}
|
|
63
|
+
getCurrentManifest() {
|
|
64
|
+
return this.#cachedManifest;
|
|
65
|
+
}
|
|
66
|
+
updateManifest(manifest) {
|
|
67
|
+
this.#cachedManifest = manifest;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=manifest-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-loader.js","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAKxD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,oBAAoB;IACtB,aAAa,CAAS;IAC/B,eAAe,GAA8B,IAAI,CAAC;IAElD,YAAY,YAAqB;QAC/B,uEAAuE;QACvE,IAAI,CAAC,aAAa,GAAG,YAAY,IAAI,IAAI,CACvC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,0BAA0B,CAC3B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAA2B,EAAE,SAAiB;QAChE,iCAAiC;QACjC,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,yCAAyC,IAAI,CAAC,aAAa,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACnH,CAAC;QACJ,CAAC;QAED,qBAAqB;QACrB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;QAED,gFAAgF;QAChF,MAAM,QAAQ,GAAG,MAAiC,CAAC;QAEnD,iDAAiD;QACjD,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,eAAe,MAAM,CAAC,WAAW,CAAC,SAAS,WAAW,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,GAAG,CACnI,CAAC;QACJ,CAAC;QAED,2EAA2E;QAC3E,IAAI,CAAC,eAAe,GAAG,QAAyC,CAAC;QACjE,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,cAAc,CAAC,QAA4B;QACzC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M7-MANIFEST-002 — Manifest poll scheduler implementations.
|
|
3
|
+
*
|
|
4
|
+
* IManifestPollScheduler schedules the background manifest poll that keeps the
|
|
5
|
+
* in-memory manifest current over long-lived daemon sessions.
|
|
6
|
+
*
|
|
7
|
+
* RandomizedPollScheduler: production implementation — fires after a random delay
|
|
8
|
+
* in the 6-12 hour window (prevents thundering-herd against the directory).
|
|
9
|
+
*
|
|
10
|
+
* ImmediatePollScheduler: test stub — fires once with a configurable delay (0ms default).
|
|
11
|
+
* Exported from @cello-protocol/transport.
|
|
12
|
+
*/
|
|
13
|
+
import type { IManifestPollScheduler } from "@cello-protocol/transport";
|
|
14
|
+
export { ImmediatePollScheduler } from "@cello-protocol/transport";
|
|
15
|
+
export type { IManifestPollScheduler };
|
|
16
|
+
/**
|
|
17
|
+
* RandomizedPollScheduler — fires after a random interval between 6 and 12 hours.
|
|
18
|
+
*
|
|
19
|
+
* The randomization window prevents thundering-herd scenarios where many agents
|
|
20
|
+
* all poll simultaneously. Each agent picks an independent random delay.
|
|
21
|
+
*/
|
|
22
|
+
export declare class RandomizedPollScheduler implements IManifestPollScheduler {
|
|
23
|
+
#private;
|
|
24
|
+
constructor(opts?: {
|
|
25
|
+
minMs?: number;
|
|
26
|
+
maxMs?: number;
|
|
27
|
+
});
|
|
28
|
+
scheduleNext(callbackFn: () => Promise<void>): void;
|
|
29
|
+
cancel(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=manifest-poll-scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-poll-scheduler.d.ts","sourceRoot":"","sources":["../src/manifest-poll-scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,CAAC;AAOvC;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,sBAAsB;;gBAMxD,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAKrD,YAAY,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAkBnD,MAAM,IAAI,IAAI;CAOf"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M7-MANIFEST-002 — Manifest poll scheduler implementations.
|
|
3
|
+
*
|
|
4
|
+
* IManifestPollScheduler schedules the background manifest poll that keeps the
|
|
5
|
+
* in-memory manifest current over long-lived daemon sessions.
|
|
6
|
+
*
|
|
7
|
+
* RandomizedPollScheduler: production implementation — fires after a random delay
|
|
8
|
+
* in the 6-12 hour window (prevents thundering-herd against the directory).
|
|
9
|
+
*
|
|
10
|
+
* ImmediatePollScheduler: test stub — fires once with a configurable delay (0ms default).
|
|
11
|
+
* Exported from @cello-protocol/transport.
|
|
12
|
+
*/
|
|
13
|
+
// Re-export the test stub for convenience
|
|
14
|
+
export { ImmediatePollScheduler } from "@cello-protocol/transport";
|
|
15
|
+
// ─── RandomizedPollScheduler (production) ─────────────────────────────────────
|
|
16
|
+
const POLL_MIN_MS = 6 * 60 * 60 * 1000; // 6 hours
|
|
17
|
+
const POLL_MAX_MS = 12 * 60 * 60 * 1000; // 12 hours
|
|
18
|
+
/**
|
|
19
|
+
* RandomizedPollScheduler — fires after a random interval between 6 and 12 hours.
|
|
20
|
+
*
|
|
21
|
+
* The randomization window prevents thundering-herd scenarios where many agents
|
|
22
|
+
* all poll simultaneously. Each agent picks an independent random delay.
|
|
23
|
+
*/
|
|
24
|
+
export class RandomizedPollScheduler {
|
|
25
|
+
#timer = null;
|
|
26
|
+
#cancelled = false;
|
|
27
|
+
#minMs;
|
|
28
|
+
#maxMs;
|
|
29
|
+
constructor(opts) {
|
|
30
|
+
this.#minMs = opts?.minMs ?? POLL_MIN_MS;
|
|
31
|
+
this.#maxMs = opts?.maxMs ?? POLL_MAX_MS;
|
|
32
|
+
}
|
|
33
|
+
scheduleNext(callbackFn) {
|
|
34
|
+
this.cancel();
|
|
35
|
+
// ADV-003: Reset cancelled flag when scheduling a new callback (cancel() sets it).
|
|
36
|
+
// If cancel() was called to clear a previous timer before scheduling the next one,
|
|
37
|
+
// the flag must be reset so the new callback can fire.
|
|
38
|
+
this.#cancelled = false;
|
|
39
|
+
const delay = this.#minMs + Math.random() * (this.#maxMs - this.#minMs);
|
|
40
|
+
this.#timer = setTimeout(() => {
|
|
41
|
+
this.#timer = null;
|
|
42
|
+
// ADV-003: Check cancelled flag at callback entry point. If cancel() was called
|
|
43
|
+
// between timer fire and callback execution, do not run the callback.
|
|
44
|
+
if (this.#cancelled)
|
|
45
|
+
return;
|
|
46
|
+
callbackFn().catch(() => {
|
|
47
|
+
// Poll errors are logged by the caller; scheduling errors don't crash the daemon
|
|
48
|
+
});
|
|
49
|
+
}, delay);
|
|
50
|
+
}
|
|
51
|
+
cancel() {
|
|
52
|
+
this.#cancelled = true;
|
|
53
|
+
if (this.#timer !== null) {
|
|
54
|
+
clearTimeout(this.#timer);
|
|
55
|
+
this.#timer = null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=manifest-poll-scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-poll-scheduler.js","sourceRoot":"","sources":["../src/manifest-poll-scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,0CAA0C;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,iFAAiF;AAEjF,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAE,UAAU;AACnD,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;AAEpD;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IAClC,MAAM,GAAyC,IAAI,CAAC;IACpD,UAAU,GAAG,KAAK,CAAC;IACV,MAAM,CAAS;IACf,MAAM,CAAS;IAExB,YAAY,IAAyC;QACnD,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,KAAK,IAAI,WAAW,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,KAAK,IAAI,WAAW,CAAC;IAC3C,CAAC;IAED,YAAY,CAAC,UAA+B;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,mFAAmF;QACnF,mFAAmF;QACnF,uDAAuD;QACvD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACxE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,gFAAgF;YAChF,sEAAsE;YACtE,IAAI,IAAI,CAAC,UAAU;gBAAE,OAAO;YAC5B,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;gBACtB,iFAAiF;YACnF,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileManifestVersionStore — file-backed IManifestVersionStore.
|
|
3
|
+
*
|
|
4
|
+
* Persists the last-seen manifest version to a JSON file on disk, enabling
|
|
5
|
+
* version monotonicity enforcement across daemon restarts.
|
|
6
|
+
*
|
|
7
|
+
* Crypto reference: RFC 8032 (this module stores the manifest version number
|
|
8
|
+
* that backs the monotonicity invariant; the version itself is not cryptographic,
|
|
9
|
+
* but its correct persistence is load-bearing for anti-rollback security).
|
|
10
|
+
*/
|
|
11
|
+
import type { IManifestVersionStore } from "@cello-protocol/transport";
|
|
12
|
+
export declare class FileManifestVersionStore implements IManifestVersionStore {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(filePath: string);
|
|
15
|
+
getLastSeenVersion(): Promise<number | null>;
|
|
16
|
+
persistVersion(version: number): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=manifest-version-store-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-version-store-file.d.ts","sourceRoot":"","sources":["../src/manifest-version-store-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAMvE,qBAAa,wBAAyB,YAAW,qBAAqB;;gBAGxD,QAAQ,EAAE,MAAM;IAItB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAU5C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWrD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileManifestVersionStore — file-backed IManifestVersionStore.
|
|
3
|
+
*
|
|
4
|
+
* Persists the last-seen manifest version to a JSON file on disk, enabling
|
|
5
|
+
* version monotonicity enforcement across daemon restarts.
|
|
6
|
+
*
|
|
7
|
+
* Crypto reference: RFC 8032 (this module stores the manifest version number
|
|
8
|
+
* that backs the monotonicity invariant; the version itself is not cryptographic,
|
|
9
|
+
* but its correct persistence is load-bearing for anti-rollback security).
|
|
10
|
+
*/
|
|
11
|
+
import { readFile, writeFile, rename, mkdir } from "node:fs/promises";
|
|
12
|
+
import { dirname } from "node:path";
|
|
13
|
+
export class FileManifestVersionStore {
|
|
14
|
+
#filePath;
|
|
15
|
+
constructor(filePath) {
|
|
16
|
+
this.#filePath = filePath;
|
|
17
|
+
}
|
|
18
|
+
async getLastSeenVersion() {
|
|
19
|
+
try {
|
|
20
|
+
const raw = await readFile(this.#filePath, "utf-8");
|
|
21
|
+
const parsed = JSON.parse(raw);
|
|
22
|
+
return typeof parsed.lastSeenVersion === "number" ? parsed.lastSeenVersion : null;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async persistVersion(version) {
|
|
29
|
+
await mkdir(dirname(this.#filePath), { recursive: true });
|
|
30
|
+
const content = { lastSeenVersion: version };
|
|
31
|
+
// ADV-005: Atomic write using write-to-temp-then-rename pattern.
|
|
32
|
+
// rename() is atomic on POSIX (same filesystem). This prevents a crash
|
|
33
|
+
// during write from corrupting the version file and resetting the
|
|
34
|
+
// monotonicity check (which would enable a rollback attack on next start).
|
|
35
|
+
const tmpPath = this.#filePath + ".tmp";
|
|
36
|
+
await writeFile(tmpPath, JSON.stringify(content), "utf-8");
|
|
37
|
+
await rename(tmpPath, this.#filePath);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=manifest-version-store-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-version-store-file.js","sourceRoot":"","sources":["../src/manifest-version-store-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,MAAM,OAAO,wBAAwB;IAC1B,SAAS,CAAS;IAE3B,YAAY,QAAgB;QAC1B,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;YACnD,OAAO,OAAO,MAAM,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAe;QAClC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAqB,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC;QAC/D,iEAAiE;QACjE,uEAAuE;QACvE,kEAAkE;QAClE,2EAA2E;QAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACxC,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M7-MANIFEST-002 — Manifest version store re-exports.
|
|
3
|
+
*
|
|
4
|
+
* IManifestVersionStore persists the last-seen manifest version number to enforce
|
|
5
|
+
* version monotonicity across daemon restarts. A manifest with a lower version
|
|
6
|
+
* number than the last-seen version is rejected as a potential rollback attack.
|
|
7
|
+
*
|
|
8
|
+
* InMemoryManifestVersionStore: stub for tests and initial deployments.
|
|
9
|
+
* FileManifestVersionStore: file-backed bridge for cross-process persistence (AC-005).
|
|
10
|
+
*/
|
|
11
|
+
import type { IManifestVersionStore } from "@cello-protocol/transport";
|
|
12
|
+
export { InMemoryManifestVersionStore } from "@cello-protocol/transport";
|
|
13
|
+
export type { IManifestVersionStore };
|
|
14
|
+
//# sourceMappingURL=manifest-version-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-version-store.d.ts","sourceRoot":"","sources":["../src/manifest-version-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAEzE,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M7-MANIFEST-002 — Manifest version store re-exports.
|
|
3
|
+
*
|
|
4
|
+
* IManifestVersionStore persists the last-seen manifest version number to enforce
|
|
5
|
+
* version monotonicity across daemon restarts. A manifest with a lower version
|
|
6
|
+
* number than the last-seen version is rejected as a potential rollback attack.
|
|
7
|
+
*
|
|
8
|
+
* InMemoryManifestVersionStore: stub for tests and initial deployments.
|
|
9
|
+
* FileManifestVersionStore: file-backed bridge for cross-process persistence (AC-005).
|
|
10
|
+
*/
|
|
11
|
+
// Re-export from transport stubs for convenience
|
|
12
|
+
export { InMemoryManifestVersionStore } from "@cello-protocol/transport";
|
|
13
|
+
//# sourceMappingURL=manifest-version-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-version-store.js","sourceRoot":"","sources":["../src/manifest-version-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,iDAAiD;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetworkDirectoryNode — DirectoryNodeStub backed by a real libp2p connection.
|
|
3
|
+
*
|
|
4
|
+
* Implements the DirectoryNodeStub interface by dialing the directory node's
|
|
5
|
+
* /cello/frost/1.0.0 endpoint. Used in live e2e mode instead of InProcessDirectoryNodeStub.
|
|
6
|
+
*
|
|
7
|
+
* Wire protocol (one stream per operation, CBOR + it-length-prefixed):
|
|
8
|
+
* frost_bootstrap: push share material to directory (called from bootstrapKeyShares)
|
|
9
|
+
* frost_commit_request: ask directory to generate a nonce commitment
|
|
10
|
+
* frost_sign_request: ask directory to compute a partial signature
|
|
11
|
+
*/
|
|
12
|
+
import { FrostThresholdSigner } from "@cello-protocol/crypto";
|
|
13
|
+
import type { CelloNode } from "@cello-protocol/transport";
|
|
14
|
+
import type { Logger } from "./types.js";
|
|
15
|
+
import type { DirectoryNodeStub, StubCommitment, StubSignParams } from "@cello-protocol/crypto/frost/types.js";
|
|
16
|
+
export declare class NetworkDirectoryNode implements DirectoryNodeStub {
|
|
17
|
+
#private;
|
|
18
|
+
readonly id: string;
|
|
19
|
+
constructor(opts: {
|
|
20
|
+
id: string;
|
|
21
|
+
node: CelloNode;
|
|
22
|
+
directoryPeerId: string;
|
|
23
|
+
directoryMultiaddrs: string[];
|
|
24
|
+
logger?: Logger;
|
|
25
|
+
});
|
|
26
|
+
isReachable(): boolean;
|
|
27
|
+
/** Return the FrostPublic from the last receiveShare call. Used by tests to construct signRound params. */
|
|
28
|
+
getLastPub(): Parameters<DirectoryNodeStub["receiveShare"]>[1] | null;
|
|
29
|
+
receiveShare(...[secret, pub]: Parameters<DirectoryNodeStub["receiveShare"]>): Promise<void>;
|
|
30
|
+
generateCommitment(): Promise<StubCommitment>;
|
|
31
|
+
signRound(params: StubSignParams): Promise<Uint8Array | null>;
|
|
32
|
+
setBootstrapContext(agentPubkeyHex: string, epochId: string): void;
|
|
33
|
+
/** Open a /cello/frost/1.0.0 stream to this directory node. Used by DKG coordinator. */
|
|
34
|
+
openStream(): Promise<import("@libp2p/interface").Stream>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Network-aware FROST bootstrap for live e2e mode.
|
|
38
|
+
*
|
|
39
|
+
* Runs trustedDealer locally, then pushes each directory node's share over the
|
|
40
|
+
* /cello/frost/1.0.0 network protocol. Returns a FrostThresholdSigner configured
|
|
41
|
+
* to use NetworkDirectoryNodes, plus the primaryPubkey.
|
|
42
|
+
*
|
|
43
|
+
* NODE_ENV=test guard is kept because this still uses the trustedDealer shortcut.
|
|
44
|
+
* Real DKG (M3) will replace this entirely.
|
|
45
|
+
*/
|
|
46
|
+
export declare function bootstrapNetworkKeyShares(agentPubkey: Uint8Array, opts: {
|
|
47
|
+
threshold: number;
|
|
48
|
+
participants: number;
|
|
49
|
+
directoryNodes: NetworkDirectoryNode[];
|
|
50
|
+
}): Promise<{
|
|
51
|
+
signer: FrostThresholdSigner;
|
|
52
|
+
primaryPubkey: Uint8Array;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Run a real 3-round FROST DKG ceremony with directory nodes over /cello/frost/1.0.0.
|
|
56
|
+
*
|
|
57
|
+
* Production path for key establishment. The client acts as DKG coordinator:
|
|
58
|
+
* Round 1: All nodes generate their secret polynomials. Client does the same.
|
|
59
|
+
* Round 2: Client collects all round1 broadcasts and distributes them to all nodes.
|
|
60
|
+
* All nodes compute shares for every other participant.
|
|
61
|
+
* Round 3: Client routes round2 shares to recipients and all nodes finalize.
|
|
62
|
+
* All nodes return shareCommitment = group public key.
|
|
63
|
+
*
|
|
64
|
+
* Validates that all nodes derive the same primary_pubkey before returning.
|
|
65
|
+
*
|
|
66
|
+
* After a successful DKG:
|
|
67
|
+
* - Each directory node has its FrostSecret stored (via dkgRound3)
|
|
68
|
+
* - The client's local share is stored via storeDkgResult
|
|
69
|
+
* - Returns a FrostThresholdSigner for future signing ceremonies
|
|
70
|
+
*
|
|
71
|
+
* Crypto reference: RFC 9591 (FROST DKG)
|
|
72
|
+
*
|
|
73
|
+
* @param agentPubkey - client's Ed25519 K_local public key (32 bytes)
|
|
74
|
+
* @param opts.threshold - minimum signers required (t in t-of-n)
|
|
75
|
+
* @param opts.directoryNodes - the n directory nodes (each will hold a share)
|
|
76
|
+
*/
|
|
77
|
+
export declare function runNetworkDkg(agentPubkey: Uint8Array, opts: {
|
|
78
|
+
threshold: number;
|
|
79
|
+
participants: number;
|
|
80
|
+
directoryNodes: NetworkDirectoryNode[];
|
|
81
|
+
/** OPS-AGENT-001: Pre-authorization token to present in Round 1 frame. */
|
|
82
|
+
preAuthToken?: string;
|
|
83
|
+
}): Promise<{
|
|
84
|
+
signer: FrostThresholdSigner;
|
|
85
|
+
primaryPubkey: Uint8Array;
|
|
86
|
+
/** PERSIST-024: serializable FROST share data for DB persistence. SI-001: never log signingShare. */
|
|
87
|
+
signingShare: Uint8Array;
|
|
88
|
+
identifier: string;
|
|
89
|
+
commitments: Uint8Array[];
|
|
90
|
+
verifyingShares: Record<string, Uint8Array>;
|
|
91
|
+
threshold: number;
|
|
92
|
+
participants: number;
|
|
93
|
+
}>;
|
|
94
|
+
//# sourceMappingURL=network-directory-node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-directory-node.d.ts","sourceRoot":"","sources":["../src/network-directory-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAiB,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,EAEf,MAAM,uCAAuC,CAAC;AAqB/C,qBAAa,oBAAqB,YAAW,iBAAiB;;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAcR,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,SAAS,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAQD,WAAW,IAAI,OAAO;IAMtB,2GAA2G;IAC3G,UAAU,IAAI,UAAU,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAI/D,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA+C5F,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC;IAiD7C,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAkDnE,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAKlE,wFAAwF;IAClF,UAAU,IAAI,OAAO,CAAC,OAAO,mBAAmB,EAAE,MAAM,CAAC;CA0BhE;AAoOD;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,UAAU,EACvB,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,oBAAoB,EAAE,CAAC;CACxC,GACA,OAAO,CAAC;IAAE,MAAM,EAAE,oBAAoB,CAAC;IAAC,aAAa,EAAE,UAAU,CAAA;CAAE,CAAC,CAgCtE;AAID;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,UAAU,EACvB,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACA,OAAO,CAAC;IACT,MAAM,EAAE,oBAAoB,CAAC;IAC7B,aAAa,EAAE,UAAU,CAAC;IAC1B,qGAAqG;IACrG,YAAY,EAAE,UAAU,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAqKD"}
|