@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.
Files changed (153) hide show
  1. package/dist/agent-loader.d.ts +41 -0
  2. package/dist/agent-loader.d.ts.map +1 -0
  3. package/dist/agent-loader.js +94 -0
  4. package/dist/agent-loader.js.map +1 -0
  5. package/dist/bin/cello-daemon.d.ts +13 -0
  6. package/dist/bin/cello-daemon.d.ts.map +1 -0
  7. package/dist/bin/cello-daemon.js +170 -0
  8. package/dist/bin/cello-daemon.js.map +1 -0
  9. package/dist/cello-node-transport-dialer.d.ts +59 -0
  10. package/dist/cello-node-transport-dialer.d.ts.map +1 -0
  11. package/dist/cello-node-transport-dialer.js +108 -0
  12. package/dist/cello-node-transport-dialer.js.map +1 -0
  13. package/dist/challenge-verifier.d.ts +12 -0
  14. package/dist/challenge-verifier.d.ts.map +1 -0
  15. package/dist/challenge-verifier.js +11 -0
  16. package/dist/challenge-verifier.js.map +1 -0
  17. package/dist/connect-or-start.d.ts +25 -0
  18. package/dist/connect-or-start.d.ts.map +1 -0
  19. package/dist/connect-or-start.js +117 -0
  20. package/dist/connect-or-start.js.map +1 -0
  21. package/dist/content-park-client.d.ts +49 -0
  22. package/dist/content-park-client.d.ts.map +1 -0
  23. package/dist/content-park-client.js +196 -0
  24. package/dist/content-park-client.js.map +1 -0
  25. package/dist/daemon.d.ts +65 -0
  26. package/dist/daemon.d.ts.map +1 -0
  27. package/dist/daemon.js +3202 -0
  28. package/dist/daemon.js.map +1 -0
  29. package/dist/directory-bootstrap.d.ts +55 -0
  30. package/dist/directory-bootstrap.d.ts.map +1 -0
  31. package/dist/directory-bootstrap.js +102 -0
  32. package/dist/directory-bootstrap.js.map +1 -0
  33. package/dist/file-manifest-provider.d.ts +18 -0
  34. package/dist/file-manifest-provider.d.ts.map +1 -0
  35. package/dist/file-manifest-provider.js +72 -0
  36. package/dist/file-manifest-provider.js.map +1 -0
  37. package/dist/index.d.ts +18 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +18 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/ipc-client.d.ts +31 -0
  42. package/dist/ipc-client.d.ts.map +1 -0
  43. package/dist/ipc-client.js +112 -0
  44. package/dist/ipc-client.js.map +1 -0
  45. package/dist/ipc-server.d.ts +49 -0
  46. package/dist/ipc-server.d.ts.map +1 -0
  47. package/dist/ipc-server.js +268 -0
  48. package/dist/ipc-server.js.map +1 -0
  49. package/dist/lock-file.d.ts +27 -0
  50. package/dist/lock-file.d.ts.map +1 -0
  51. package/dist/lock-file.js +84 -0
  52. package/dist/lock-file.js.map +1 -0
  53. package/dist/manifest-loader.d.ts +33 -0
  54. package/dist/manifest-loader.d.ts.map +1 -0
  55. package/dist/manifest-loader.js +70 -0
  56. package/dist/manifest-loader.js.map +1 -0
  57. package/dist/manifest-poll-scheduler.d.ts +31 -0
  58. package/dist/manifest-poll-scheduler.d.ts.map +1 -0
  59. package/dist/manifest-poll-scheduler.js +59 -0
  60. package/dist/manifest-poll-scheduler.js.map +1 -0
  61. package/dist/manifest-version-store-file.d.ts +18 -0
  62. package/dist/manifest-version-store-file.d.ts.map +1 -0
  63. package/dist/manifest-version-store-file.js +40 -0
  64. package/dist/manifest-version-store-file.js.map +1 -0
  65. package/dist/manifest-version-store.d.ts +14 -0
  66. package/dist/manifest-version-store.d.ts.map +1 -0
  67. package/dist/manifest-version-store.js +13 -0
  68. package/dist/manifest-version-store.js.map +1 -0
  69. package/dist/network-directory-node.d.ts +94 -0
  70. package/dist/network-directory-node.d.ts.map +1 -0
  71. package/dist/network-directory-node.js +626 -0
  72. package/dist/network-directory-node.js.map +1 -0
  73. package/dist/nonce-dedup.d.ts +68 -0
  74. package/dist/nonce-dedup.d.ts.map +1 -0
  75. package/dist/nonce-dedup.js +204 -0
  76. package/dist/nonce-dedup.js.map +1 -0
  77. package/dist/notification-dispatcher.d.ts +65 -0
  78. package/dist/notification-dispatcher.d.ts.map +1 -0
  79. package/dist/notification-dispatcher.js +138 -0
  80. package/dist/notification-dispatcher.js.map +1 -0
  81. package/dist/registration-context.d.ts +69 -0
  82. package/dist/registration-context.d.ts.map +1 -0
  83. package/dist/registration-context.js +118 -0
  84. package/dist/registration-context.js.map +1 -0
  85. package/dist/registration-manager.d.ts +72 -0
  86. package/dist/registration-manager.d.ts.map +1 -0
  87. package/dist/registration-manager.js +267 -0
  88. package/dist/registration-manager.js.map +1 -0
  89. package/dist/registration-persistence.d.ts +131 -0
  90. package/dist/registration-persistence.d.ts.map +1 -0
  91. package/dist/registration-persistence.js +233 -0
  92. package/dist/registration-persistence.js.map +1 -0
  93. package/dist/retry-queue.d.ts +144 -0
  94. package/dist/retry-queue.d.ts.map +1 -0
  95. package/dist/retry-queue.js +444 -0
  96. package/dist/retry-queue.js.map +1 -0
  97. package/dist/seal-frontier-verify.d.ts +58 -0
  98. package/dist/seal-frontier-verify.d.ts.map +1 -0
  99. package/dist/seal-frontier-verify.js +87 -0
  100. package/dist/seal-frontier-verify.js.map +1 -0
  101. package/dist/seal-legibility-tbs.d.ts +25 -0
  102. package/dist/seal-legibility-tbs.d.ts.map +1 -0
  103. package/dist/seal-legibility-tbs.js +78 -0
  104. package/dist/seal-legibility-tbs.js.map +1 -0
  105. package/dist/seal-upgrade.d.ts +90 -0
  106. package/dist/seal-upgrade.d.ts.map +1 -0
  107. package/dist/seal-upgrade.js +178 -0
  108. package/dist/seal-upgrade.js.map +1 -0
  109. package/dist/session-assignment-parser.d.ts +22 -0
  110. package/dist/session-assignment-parser.d.ts.map +1 -0
  111. package/dist/session-assignment-parser.js +139 -0
  112. package/dist/session-assignment-parser.js.map +1 -0
  113. package/dist/session-ceremony.d.ts +156 -0
  114. package/dist/session-ceremony.d.ts.map +1 -0
  115. package/dist/session-ceremony.js +447 -0
  116. package/dist/session-ceremony.js.map +1 -0
  117. package/dist/session-connection-gater.d.ts +91 -0
  118. package/dist/session-connection-gater.d.ts.map +1 -0
  119. package/dist/session-connection-gater.js +146 -0
  120. package/dist/session-connection-gater.js.map +1 -0
  121. package/dist/session-node-manager.d.ts +585 -0
  122. package/dist/session-node-manager.d.ts.map +1 -0
  123. package/dist/session-node-manager.js +2609 -0
  124. package/dist/session-node-manager.js.map +1 -0
  125. package/dist/session-relay-client.d.ts +101 -0
  126. package/dist/session-relay-client.d.ts.map +1 -0
  127. package/dist/session-relay-client.js +520 -0
  128. package/dist/session-relay-client.js.map +1 -0
  129. package/dist/session-tree.d.ts +80 -0
  130. package/dist/session-tree.d.ts.map +1 -0
  131. package/dist/session-tree.js +123 -0
  132. package/dist/session-tree.js.map +1 -0
  133. package/dist/signaling-connect.d.ts +83 -0
  134. package/dist/signaling-connect.d.ts.map +1 -0
  135. package/dist/signaling-connect.js +266 -0
  136. package/dist/signaling-connect.js.map +1 -0
  137. package/dist/transcript-cipher.d.ts +31 -0
  138. package/dist/transcript-cipher.d.ts.map +1 -0
  139. package/dist/transcript-cipher.js +74 -0
  140. package/dist/transcript-cipher.js.map +1 -0
  141. package/dist/transport-composition.d.ts +31 -0
  142. package/dist/transport-composition.d.ts.map +1 -0
  143. package/dist/transport-composition.js +55 -0
  144. package/dist/transport-composition.js.map +1 -0
  145. package/dist/transport-selector.d.ts +189 -0
  146. package/dist/transport-selector.d.ts.map +1 -0
  147. package/dist/transport-selector.js +195 -0
  148. package/dist/transport-selector.js.map +1 -0
  149. package/dist/types.d.ts +265 -0
  150. package/dist/types.d.ts.map +1 -0
  151. package/dist/types.js +33 -0
  152. package/dist/types.js.map +1 -0
  153. package/package.json +4 -4
@@ -0,0 +1,118 @@
1
+ /**
2
+ * DaemonRegistrationContext — CELLO-M7-REGISTRATION (Action 2, step c part 2).
3
+ *
4
+ * Implements the RegistrationManager's RegistrationContext seam against daemon
5
+ * internals. The one non-trivial piece is the signaling bridge: the client wrote
6
+ * directly to a raw persistent libp2p Stream and ran its own read loop; the
7
+ * daemon's directory signaling lives behind SignalingManager. So this context:
8
+ * - sends frames via SignalingManager.sendRaw (which CBOR/length-prefix-encodes),
9
+ * - registers ONE inbound handler that routes the registration reply frames
10
+ * (dkg_ready / register_success / register_error) to whichever pending
11
+ * resolver RegistrationManager.register() has currently armed.
12
+ *
13
+ * register() drives the two stages strictly sequentially (await dkg_ready, then
14
+ * await register_success), so at most one resolver is armed at any moment — which
15
+ * is why a bare register_error can be routed to "whichever stage is waiting".
16
+ */
17
+ const REGISTRATION_REPLY_TYPES = new Set(["dkg_ready", "register_success", "register_error"]);
18
+ export class DaemonRegistrationContext {
19
+ keyProvider;
20
+ logger;
21
+ persistence;
22
+ mlDsaKeyFile;
23
+ #signaling;
24
+ #getDirectoryNode;
25
+ #getDirectoryEndpoint;
26
+ #unregisterInbound;
27
+ #myPubkeyHex = null;
28
+ #thresholdSigner = undefined;
29
+ #myPrimaryPubkey = null;
30
+ #pendingDkgReady = null;
31
+ #pendingRegister = null;
32
+ constructor(opts) {
33
+ this.#signaling = opts.signaling;
34
+ this.#getDirectoryNode = opts.getDirectoryNode;
35
+ this.#getDirectoryEndpoint = opts.getDirectoryEndpoint;
36
+ this.keyProvider = opts.keyProvider;
37
+ this.persistence = opts.persistence;
38
+ this.logger = opts.logger;
39
+ this.mlDsaKeyFile = opts.mlDsaKeyFile;
40
+ this.#unregisterInbound = this.#signaling.registerInboundHandler((frame) => this.#onInbound(frame));
41
+ }
42
+ // ─── Node + identity ────────────────────────────────────────────────────────
43
+ getNode() {
44
+ return this.#getDirectoryNode();
45
+ }
46
+ getMyPubkeyHex() {
47
+ return this.#myPubkeyHex;
48
+ }
49
+ setMyPubkeyHex(hex) {
50
+ this.#myPubkeyHex = hex;
51
+ }
52
+ getDirectoryEndpoint() {
53
+ return this.#getDirectoryEndpoint();
54
+ }
55
+ getThresholdSigner() {
56
+ return this.#thresholdSigner;
57
+ }
58
+ setThresholdSigner(signer) {
59
+ this.#thresholdSigner = signer;
60
+ }
61
+ getMyPrimaryPubkey() {
62
+ return this.#myPrimaryPubkey;
63
+ }
64
+ setMyPrimaryPubkey(pubkey) {
65
+ this.#myPrimaryPubkey = pubkey;
66
+ }
67
+ // ─── Signaling seam ──────────────────────────────────────────────────────────
68
+ isSignalingConnected() {
69
+ return this.#signaling.status === "connected";
70
+ }
71
+ async sendSignalingFrame(frame) {
72
+ return this.#signaling.sendRaw(frame);
73
+ }
74
+ setPendingDkgReadyResolve(resolve) {
75
+ this.#pendingDkgReady = resolve;
76
+ }
77
+ setPendingRegisterResolve(resolve) {
78
+ this.#pendingRegister = resolve;
79
+ }
80
+ /** Stop routing inbound frames (call when the owning agent is torn down). */
81
+ dispose() {
82
+ this.#unregisterInbound();
83
+ this.#pendingDkgReady = null;
84
+ this.#pendingRegister = null;
85
+ }
86
+ // ─── Inbound routing ──────────────────────────────────────────────────────────
87
+ #onInbound(frame) {
88
+ const type = frame["type"];
89
+ if (typeof type !== "string" || !REGISTRATION_REPLY_TYPES.has(type)) {
90
+ return; // not a registration reply — leave it for other inbound handlers
91
+ }
92
+ if (type === "dkg_ready") {
93
+ const resolve = this.#pendingDkgReady;
94
+ this.#pendingDkgReady = null;
95
+ resolve?.(frame);
96
+ return;
97
+ }
98
+ if (type === "register_success") {
99
+ const resolve = this.#pendingRegister;
100
+ this.#pendingRegister = null;
101
+ resolve?.(frame);
102
+ return;
103
+ }
104
+ // register_error → deliver to whichever stage is currently waiting.
105
+ // Stages are sequential, so at most one resolver is armed.
106
+ if (this.#pendingDkgReady) {
107
+ const resolve = this.#pendingDkgReady;
108
+ this.#pendingDkgReady = null;
109
+ resolve(frame);
110
+ }
111
+ else if (this.#pendingRegister) {
112
+ const resolve = this.#pendingRegister;
113
+ this.#pendingRegister = null;
114
+ resolve(frame);
115
+ }
116
+ }
117
+ }
118
+ //# sourceMappingURL=registration-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration-context.js","sourceRoot":"","sources":["../src/registration-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * RegistrationManager — REG-001, ML-DSA keygen, DKG (daemon port).
3
+ *
4
+ * Ported from cello-client's RegistrationManager. Owns registration domain
5
+ * state (#registrationState, #mlDsaProvider). The only adaptation vs the client
6
+ * is the signaling seam: the client wrote directly to a raw persistent libp2p
7
+ * Stream, whereas the daemon's directory signaling lives behind SignalingManager.
8
+ * So RegistrationContext exposes `sendSignalingFrame` (→ SignalingManager.sendRaw,
9
+ * which CBOR/length-prefix-encodes internally) and `isSignalingConnected`, and a
10
+ * single daemon-owned inbound handler drives the pending dkg_ready/register
11
+ * resolvers (see DaemonRegistrationContext). The register() control flow is
12
+ * otherwise unchanged.
13
+ */
14
+ import type { IThresholdSigner, MlDsaKeyProvider } from "@cello-protocol/crypto";
15
+ import type { RegistrationState } from "@cello-protocol/protocol-types";
16
+ import type { DaemonRegistrationPersistence } from "./registration-persistence.js";
17
+ import type { Logger } from "./types.js";
18
+ import type { CelloNode } from "@cello-protocol/transport";
19
+ import type { KeyProvider } from "@cello-protocol/crypto";
20
+ /** Result of attempting to send a frame over the daemon's directory signaling stream. */
21
+ export interface SignalingSendResult {
22
+ ok: boolean;
23
+ reason?: string;
24
+ }
25
+ /**
26
+ * Narrow interface exposing only what RegistrationManager needs from the daemon.
27
+ * This avoids importing daemon internals and prevents circular dependencies.
28
+ */
29
+ export interface RegistrationContext {
30
+ readonly keyProvider: KeyProvider;
31
+ readonly logger: Logger;
32
+ readonly persistence: DaemonRegistrationPersistence | null;
33
+ readonly mlDsaKeyFile: string | undefined;
34
+ /**
35
+ * The live directory-facing libp2p node FROST DKG opens streams on. May be
36
+ * null even when signaling reads connected (brief stream-death window) — the
37
+ * caller MUST null-check before constructing a NetworkDirectoryNode.
38
+ */
39
+ getNode(): CelloNode | null;
40
+ getMyPubkeyHex(): string | null;
41
+ setMyPubkeyHex(hex: string): void;
42
+ getDirectoryEndpoint(): {
43
+ peer_id: string;
44
+ multiaddrs: string[];
45
+ } | null;
46
+ getThresholdSigner(): IThresholdSigner | undefined;
47
+ setThresholdSigner(signer: IThresholdSigner): void;
48
+ getMyPrimaryPubkey(): Uint8Array | null;
49
+ setMyPrimaryPubkey(pubkey: Uint8Array): void;
50
+ /** True when the directory signaling stream is connected and a send can be attempted. */
51
+ isSignalingConnected(): boolean;
52
+ /** Send a frame object over directory signaling (SignalingManager encodes it). */
53
+ sendSignalingFrame(frame: Record<string, unknown>): Promise<SignalingSendResult>;
54
+ setPendingDkgReadyResolve(resolve: ((frame: Record<string, unknown>) => void) | null): void;
55
+ setPendingRegisterResolve(resolve: ((frame: Record<string, unknown>) => void) | null): void;
56
+ }
57
+ export declare class RegistrationManager {
58
+ #private;
59
+ constructor(ctx: RegistrationContext);
60
+ getRegistrationState(): RegistrationState | null;
61
+ setRegistrationState(state: RegistrationState | null): void;
62
+ getMlDsaProvider(): MlDsaKeyProvider | null;
63
+ setMlDsaProvider(provider: MlDsaKeyProvider | null): void;
64
+ /**
65
+ * Register this agent with the directory.
66
+ * REG-001: ML-DSA keygen → signaling stream → register_request → DKG → register_success.
67
+ */
68
+ register(phoneStub?: string, preAuthToken?: string): Promise<RegistrationState | {
69
+ error: string;
70
+ }>;
71
+ }
72
+ //# sourceMappingURL=registration-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration-manager.d.ts","sourceRoot":"","sources":["../src/registration-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAMxE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,OAAO,IAAI,SAAS,GAAG,IAAI,CAAC;IAC5B,cAAc,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,oBAAoB,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,kBAAkB,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACnD,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnD,kBAAkB,IAAI,UAAU,GAAG,IAAI,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7C,yFAAyF;IACzF,oBAAoB,IAAI,OAAO,CAAC;IAChC,kFAAkF;IAClF,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjF,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC5F,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;CAC7F;AAED,qBAAa,mBAAmB;;gBAOlB,GAAG,EAAE,mBAAmB;IAMpC,oBAAoB,IAAI,iBAAiB,GAAG,IAAI;IAIhD,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAI3D,gBAAgB,IAAI,gBAAgB,GAAG,IAAI;IAI3C,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAIzD;;;OAGG;IACG,QAAQ,CAAC,SAAS,GAAE,MAAW,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CA0O9G"}
@@ -0,0 +1,267 @@
1
+ /**
2
+ * RegistrationManager — REG-001, ML-DSA keygen, DKG (daemon port).
3
+ *
4
+ * Ported from cello-client's RegistrationManager. Owns registration domain
5
+ * state (#registrationState, #mlDsaProvider). The only adaptation vs the client
6
+ * is the signaling seam: the client wrote directly to a raw persistent libp2p
7
+ * Stream, whereas the daemon's directory signaling lives behind SignalingManager.
8
+ * So RegistrationContext exposes `sendSignalingFrame` (→ SignalingManager.sendRaw,
9
+ * which CBOR/length-prefix-encodes internally) and `isSignalingConnected`, and a
10
+ * single daemon-owned inbound handler drives the pending dkg_ready/register
11
+ * resolvers (see DaemonRegistrationContext). The register() control flow is
12
+ * otherwise unchanged.
13
+ */
14
+ import { Encoder } from "cbor-x";
15
+ import { mlDsaKeygen, mlDsaKeygenWithBytes, FileMlDsaKeyProvider } from "@cello-protocol/crypto";
16
+ import { NetworkDirectoryNode, runNetworkDkg } from "./network-directory-node.js";
17
+ // CBOR encoder for serializing FROST commitments/verifyingShares before
18
+ // persistence (not signaling frames — those go through SignalingManager).
19
+ const CBOR_ENC = new Encoder({ tagUint8Array: false });
20
+ export class RegistrationManager {
21
+ #ctx;
22
+ // Registration state owned by this manager
23
+ #registrationState = null;
24
+ #mlDsaProvider = null;
25
+ constructor(ctx) {
26
+ this.#ctx = ctx;
27
+ }
28
+ // ─── Public state accessors ──────────────────────────────────────────────────
29
+ getRegistrationState() {
30
+ return this.#registrationState;
31
+ }
32
+ setRegistrationState(state) {
33
+ this.#registrationState = state;
34
+ }
35
+ getMlDsaProvider() {
36
+ return this.#mlDsaProvider;
37
+ }
38
+ setMlDsaProvider(provider) {
39
+ this.#mlDsaProvider = provider;
40
+ }
41
+ /**
42
+ * Register this agent with the directory.
43
+ * REG-001: ML-DSA keygen → signaling stream → register_request → DKG → register_success.
44
+ */
45
+ async register(phoneStub = "", preAuthToken) {
46
+ // Step 1: already registered
47
+ if (this.#registrationState) {
48
+ return { error: "already_registered" };
49
+ }
50
+ // Step 2: generate or load ML-DSA-44 keypair
51
+ let mlDsaProvider;
52
+ let mlDsaSecretKeyBlob = null;
53
+ if (this.#ctx.mlDsaKeyFile) {
54
+ mlDsaProvider = await FileMlDsaKeyProvider.load(this.#ctx.mlDsaKeyFile);
55
+ }
56
+ else if (this.#ctx.persistence) {
57
+ const { provider, secretKeyBlob } = await mlDsaKeygenWithBytes();
58
+ mlDsaProvider = provider;
59
+ mlDsaSecretKeyBlob = secretKeyBlob;
60
+ }
61
+ else {
62
+ mlDsaProvider = await mlDsaKeygen();
63
+ }
64
+ const mlDsaPubkey = await mlDsaProvider.getPublicKey();
65
+ const mlDsaPubkeyHex = Buffer.from(mlDsaPubkey).toString("hex");
66
+ // Step 3: require the directory signaling stream to be connected.
67
+ // (The daemon keeps it connected via SignalingManager; we don't open it here.)
68
+ if (!this.#ctx.isSignalingConnected()) {
69
+ return { error: "directory_unreachable" };
70
+ }
71
+ // Step 4: get K_local pubkey hex
72
+ if (!this.#ctx.getMyPubkeyHex()) {
73
+ const pubkey = await this.#ctx.keyProvider.getPublicKey();
74
+ this.#ctx.setMyPubkeyHex(Buffer.from(pubkey).toString("hex"));
75
+ }
76
+ const kLocalPubkeyHex = this.#ctx.getMyPubkeyHex();
77
+ // Step 5: send register_request (SignalingManager CBOR/lp-encodes the frame)
78
+ const regSent = await this.#ctx.sendSignalingFrame({
79
+ type: "register_request",
80
+ phone_stub: phoneStub,
81
+ k_local_pubkey: kLocalPubkeyHex,
82
+ ml_dsa_pubkey: mlDsaPubkeyHex,
83
+ });
84
+ if (!regSent.ok) {
85
+ return { error: regSent.reason ?? "directory_unreachable" };
86
+ }
87
+ // Step 5a: await dkg_ready
88
+ const DKG_READY_TIMEOUT_MS = 15_000;
89
+ let dkgReadyTimeoutHandle;
90
+ const dkgReadyFrame = await Promise.race([
91
+ new Promise((resolve) => {
92
+ this.#ctx.setPendingDkgReadyResolve(resolve);
93
+ }),
94
+ new Promise((resolve) => {
95
+ dkgReadyTimeoutHandle = setTimeout(() => {
96
+ this.#ctx.setPendingDkgReadyResolve(null);
97
+ resolve({ type: "register_error", reason: "timeout" });
98
+ }, DKG_READY_TIMEOUT_MS);
99
+ }),
100
+ ]);
101
+ clearTimeout(dkgReadyTimeoutHandle);
102
+ if (dkgReadyFrame["type"] !== "dkg_ready") {
103
+ const reason = dkgReadyFrame["reason"] ?? "unknown";
104
+ if (reason === "already_registered" &&
105
+ dkgReadyFrame["agent_id"] &&
106
+ dkgReadyFrame["primary_pubkey"]) {
107
+ const state = {
108
+ agent_id: dkgReadyFrame["agent_id"],
109
+ primary_pubkey: dkgReadyFrame["primary_pubkey"],
110
+ ml_dsa_pubkey: dkgReadyFrame["ml_dsa_pubkey"] ?? mlDsaPubkeyHex,
111
+ registered_at: Date.now(),
112
+ status: "active",
113
+ };
114
+ this.#registrationState = state;
115
+ this.#mlDsaProvider = mlDsaProvider;
116
+ if (this.#ctx.persistence && mlDsaSecretKeyBlob) {
117
+ void this.#ctx.persistence.persistMlDsaKeypair({
118
+ mlDsaPubkey: mlDsaPubkeyHex,
119
+ secretKeyBlob: mlDsaSecretKeyBlob,
120
+ });
121
+ void this.#ctx.persistence.persistRegistrationState({
122
+ agentId: state.agent_id,
123
+ primaryPubkey: state.primary_pubkey,
124
+ mlDsaPubkey: state.ml_dsa_pubkey,
125
+ registeredAt: state.registered_at,
126
+ });
127
+ }
128
+ return state;
129
+ }
130
+ return { error: reason };
131
+ }
132
+ // Step 5b: run real FROST DKG
133
+ const epochId = dkgReadyFrame["epochId"];
134
+ const participants = dkgReadyFrame["participants"];
135
+ const threshold = dkgReadyFrame["threshold"];
136
+ const directoryEndpoint = this.#ctx.getDirectoryEndpoint();
137
+ if (!directoryEndpoint) {
138
+ return { error: "directory_unreachable" };
139
+ }
140
+ // getNode() may be null even when signaling reads connected (brief
141
+ // stream-death window) — null-check before FROST DKG opens streams on it.
142
+ const dkgNode = this.#ctx.getNode();
143
+ if (!dkgNode) {
144
+ return { error: "directory_unreachable" };
145
+ }
146
+ const dirNode = new NetworkDirectoryNode({
147
+ id: directoryEndpoint.peer_id,
148
+ node: dkgNode,
149
+ directoryPeerId: directoryEndpoint.peer_id,
150
+ directoryMultiaddrs: directoryEndpoint.multiaddrs,
151
+ logger: this.#ctx.logger,
152
+ });
153
+ void epochId;
154
+ const kLocalPubkeyBytes = Buffer.from(kLocalPubkeyHex, "hex");
155
+ let dkgPrimaryPubkeyHex;
156
+ try {
157
+ const dkgResult = await runNetworkDkg(kLocalPubkeyBytes, {
158
+ threshold,
159
+ participants,
160
+ directoryNodes: [dirNode],
161
+ preAuthToken,
162
+ });
163
+ dkgPrimaryPubkeyHex = Buffer.from(dkgResult.primaryPubkey).toString("hex");
164
+ this.#ctx.setThresholdSigner(dkgResult.signer);
165
+ this.#ctx.setMyPrimaryPubkey(new Uint8Array(dkgResult.primaryPubkey));
166
+ if (this.#ctx.persistence) {
167
+ const commitmentsCbor = CBOR_ENC.encode(dkgResult.commitments);
168
+ const verifyingSharesCbor = CBOR_ENC.encode(dkgResult.verifyingShares);
169
+ void this.#ctx.persistence.persistFrostKeyShare({
170
+ epochId,
171
+ primaryPubkey: dkgPrimaryPubkeyHex,
172
+ identifier: dkgResult.identifier,
173
+ signingShare: dkgResult.signingShare,
174
+ threshold: dkgResult.threshold,
175
+ participants: dkgResult.participants,
176
+ commitmentsCbor,
177
+ verifyingSharesCbor,
178
+ dkgMethod: "network_dkg",
179
+ });
180
+ }
181
+ }
182
+ catch {
183
+ return { error: "dkg_failed" };
184
+ }
185
+ // Step 5c: send dkg_complete (SignalingManager CBOR/lp-encodes the frame)
186
+ const dkgSent = await this.#ctx.sendSignalingFrame({
187
+ type: "dkg_complete",
188
+ primary_pubkey: dkgPrimaryPubkeyHex,
189
+ });
190
+ if (!dkgSent.ok) {
191
+ return { error: dkgSent.reason ?? "directory_unreachable" };
192
+ }
193
+ // Step 6: await register_success or register_error
194
+ const REGISTER_TIMEOUT_MS = 15_000;
195
+ let timeoutHandle;
196
+ const responseWithTimeout = await Promise.race([
197
+ new Promise((resolve) => {
198
+ this.#ctx.setPendingRegisterResolve(resolve);
199
+ }),
200
+ new Promise((resolve) => {
201
+ timeoutHandle = setTimeout(() => {
202
+ this.#ctx.setPendingRegisterResolve(null);
203
+ resolve({ type: "register_error", reason: "timeout" });
204
+ }, REGISTER_TIMEOUT_MS);
205
+ }),
206
+ ]);
207
+ clearTimeout(timeoutHandle);
208
+ if (responseWithTimeout["type"] !== "register_success") {
209
+ const reason = responseWithTimeout["reason"] ?? "unknown";
210
+ if (reason === "already_registered" &&
211
+ responseWithTimeout["agent_id"] &&
212
+ responseWithTimeout["primary_pubkey"]) {
213
+ const state = {
214
+ agent_id: responseWithTimeout["agent_id"],
215
+ primary_pubkey: responseWithTimeout["primary_pubkey"],
216
+ ml_dsa_pubkey: responseWithTimeout["ml_dsa_pubkey"] ?? mlDsaPubkeyHex,
217
+ registered_at: Date.now(),
218
+ status: "active",
219
+ };
220
+ this.#registrationState = state;
221
+ this.#mlDsaProvider = mlDsaProvider;
222
+ if (this.#ctx.persistence && mlDsaSecretKeyBlob) {
223
+ void this.#ctx.persistence.persistMlDsaKeypair({
224
+ mlDsaPubkey: mlDsaPubkeyHex,
225
+ secretKeyBlob: mlDsaSecretKeyBlob,
226
+ });
227
+ void this.#ctx.persistence.persistRegistrationState({
228
+ agentId: state.agent_id,
229
+ primaryPubkey: state.primary_pubkey,
230
+ mlDsaPubkey: state.ml_dsa_pubkey,
231
+ registeredAt: state.registered_at,
232
+ });
233
+ }
234
+ return state;
235
+ }
236
+ return { error: reason };
237
+ }
238
+ // Step 7: build RegistrationState and cache
239
+ const agentId = responseWithTimeout["agent_id"];
240
+ const primaryPubkey = responseWithTimeout["primary_pubkey"];
241
+ const state = {
242
+ agent_id: agentId,
243
+ primary_pubkey: primaryPubkey,
244
+ ml_dsa_pubkey: mlDsaPubkeyHex,
245
+ registered_at: Date.now(),
246
+ status: "active",
247
+ };
248
+ this.#registrationState = state;
249
+ this.#mlDsaProvider = mlDsaProvider;
250
+ if (this.#ctx.persistence && mlDsaSecretKeyBlob) {
251
+ void this.#ctx.persistence.persistMlDsaKeypair({
252
+ mlDsaPubkey: mlDsaPubkeyHex,
253
+ secretKeyBlob: mlDsaSecretKeyBlob,
254
+ });
255
+ }
256
+ if (this.#ctx.persistence) {
257
+ void this.#ctx.persistence.persistRegistrationState({
258
+ agentId: state.agent_id,
259
+ primaryPubkey: state.primary_pubkey,
260
+ mlDsaPubkey: state.ml_dsa_pubkey,
261
+ registeredAt: state.registered_at,
262
+ });
263
+ }
264
+ return state;
265
+ }
266
+ }
267
+ //# sourceMappingURL=registration-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration-manager.js","sourceRoot":"","sources":["../src/registration-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Daemon registration persistence — CELLO-M7-REGISTRATION.
3
+ *
4
+ * The daemon owns each agent's registration material (ML-DSA keypair, FROST key
5
+ * share, registration state) as per-agent files under ~/.cello/agents/<name>/.
6
+ * This mirrors the daemon's existing `key`-file model (see agent-loader.ts) and
7
+ * deliberately does NOT drag the client's SQLCipher ClientStatePersistence into
8
+ * the daemon — that layer is keyed by agent_pubkey in one shared DB, whereas the
9
+ * daemon isolates each agent in its own directory (cleaner for multi-agent).
10
+ *
11
+ * Security posture: the FROST signing share and ML-DSA secret key are written
12
+ * with 0o600 permissions, atomically (write-to-tmp + rename), consistent with the
13
+ * daemon's existing plaintext K_local `key` file. Encryption-at-rest for the
14
+ * daemon is a separate future concern and is intentionally NOT introduced
15
+ * piecemeal here. The signing share (SI-001) and secret key blob (SI-002) must
16
+ * never appear in a log event — only the files hold them.
17
+ */
18
+ import type { Logger } from "./types.js";
19
+ export interface RegistrationStateRecord {
20
+ agentId: string;
21
+ primaryPubkey: string;
22
+ mlDsaPubkey: string;
23
+ registeredAt: number;
24
+ status: string;
25
+ }
26
+ export interface MlDsaKeypairRecord {
27
+ mlDsaPubkey: string;
28
+ secretKeyBlob: Uint8Array;
29
+ algorithm: string;
30
+ }
31
+ export interface FrostKeyShareRecord {
32
+ epochId: string;
33
+ primaryPubkey: string;
34
+ identifier: string;
35
+ signingShare: Uint8Array;
36
+ threshold: number;
37
+ participants: number;
38
+ commitmentsCbor: Uint8Array;
39
+ verifyingSharesCbor: Uint8Array;
40
+ dkgMethod: string;
41
+ }
42
+ /**
43
+ * The agent→user linkage captured at registration. The pre-authorization ticket
44
+ * (issued by the CELLO Operations Agent) binds this agent to a user; recording it
45
+ * here is the M7 "capture-now-or-lose-it" requirement — *using* the link (trust
46
+ * signals that attach to the user) is future trust-layer work.
47
+ */
48
+ export interface AgentUserLinkRecord {
49
+ agentId: string;
50
+ preAuthToken: string;
51
+ linkedAt: number;
52
+ }
53
+ /**
54
+ * Narrow persistence seam consumed by the daemon's RegistrationManager. Exactly
55
+ * the three persist operations the registration flow performs, plus the matching
56
+ * load operations needed to rehydrate an already-registered agent on restart.
57
+ */
58
+ export interface DaemonRegistrationPersistence {
59
+ persistMlDsaKeypair(opts: {
60
+ mlDsaPubkey: string;
61
+ secretKeyBlob: Uint8Array;
62
+ }): Promise<void>;
63
+ persistRegistrationState(opts: {
64
+ agentId: string;
65
+ primaryPubkey: string;
66
+ mlDsaPubkey: string;
67
+ registeredAt: number;
68
+ }): Promise<void>;
69
+ persistFrostKeyShare(opts: {
70
+ epochId: string;
71
+ primaryPubkey: string;
72
+ identifier: string;
73
+ signingShare: Uint8Array;
74
+ threshold: number;
75
+ participants: number;
76
+ commitmentsCbor: Uint8Array;
77
+ verifyingSharesCbor: Uint8Array;
78
+ dkgMethod: "trusted_dealer" | "network_dkg";
79
+ }): Promise<void>;
80
+ loadRegistrationState(): Promise<RegistrationStateRecord | null>;
81
+ loadMlDsaKeypair(): Promise<MlDsaKeypairRecord | null>;
82
+ loadActiveFrostKeyShare(): Promise<FrostKeyShareRecord | null>;
83
+ }
84
+ /**
85
+ * File-backed implementation. One instance is scoped to a single agent's
86
+ * directory (e.g. ~/.cello/agents/alice/). The directory is created on first
87
+ * write; load methods on a fresh agent return null (ENOENT is not an error).
88
+ */
89
+ export declare class FileRegistrationPersistence implements DaemonRegistrationPersistence {
90
+ #private;
91
+ constructor(opts: {
92
+ agentDir: string;
93
+ logger: Logger;
94
+ });
95
+ persistMlDsaKeypair(opts: {
96
+ mlDsaPubkey: string;
97
+ secretKeyBlob: Uint8Array;
98
+ }): Promise<void>;
99
+ persistRegistrationState(opts: {
100
+ agentId: string;
101
+ primaryPubkey: string;
102
+ mlDsaPubkey: string;
103
+ registeredAt: number;
104
+ }): Promise<void>;
105
+ persistFrostKeyShare(opts: {
106
+ epochId: string;
107
+ primaryPubkey: string;
108
+ identifier: string;
109
+ signingShare: Uint8Array;
110
+ threshold: number;
111
+ participants: number;
112
+ commitmentsCbor: Uint8Array;
113
+ verifyingSharesCbor: Uint8Array;
114
+ dkgMethod: "trusted_dealer" | "network_dkg";
115
+ }): Promise<void>;
116
+ /**
117
+ * Capture the agent→user link at registration (M7 capture-now-or-lose-it). Not
118
+ * part of the RegistrationManager seam — called by the cello_register handler
119
+ * after a successful register(), since only the handler holds the pre-auth ticket.
120
+ */
121
+ persistAgentUserLink(opts: {
122
+ agentId: string;
123
+ preAuthToken: string;
124
+ linkedAt: number;
125
+ }): Promise<void>;
126
+ loadRegistrationState(): Promise<RegistrationStateRecord | null>;
127
+ loadMlDsaKeypair(): Promise<MlDsaKeypairRecord | null>;
128
+ loadActiveFrostKeyShare(): Promise<FrostKeyShareRecord | null>;
129
+ loadAgentUserLink(): Promise<AgentUserLinkRecord | null>;
130
+ }
131
+ //# sourceMappingURL=registration-persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration-persistence.d.ts","sourceRoot":"","sources":["../src/registration-persistence.ts"],"names":[],"mappings":"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"}