@cello-protocol/client 0.0.2

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 (53) hide show
  1. package/dist/agent-hash-queue.d.ts +206 -0
  2. package/dist/agent-hash-queue.d.ts.map +1 -0
  3. package/dist/agent-hash-queue.js +380 -0
  4. package/dist/agent-hash-queue.js.map +1 -0
  5. package/dist/backup-key-derivation.d.ts +37 -0
  6. package/dist/backup-key-derivation.d.ts.map +1 -0
  7. package/dist/backup-key-derivation.js +48 -0
  8. package/dist/backup-key-derivation.js.map +1 -0
  9. package/dist/client-backup.d.ts +144 -0
  10. package/dist/client-backup.d.ts.map +1 -0
  11. package/dist/client-backup.js +273 -0
  12. package/dist/client-backup.js.map +1 -0
  13. package/dist/client.d.ts +249 -0
  14. package/dist/client.d.ts.map +1 -0
  15. package/dist/client.js +4664 -0
  16. package/dist/client.js.map +1 -0
  17. package/dist/connection-policy.d.ts +163 -0
  18. package/dist/connection-policy.d.ts.map +1 -0
  19. package/dist/connection-policy.js +248 -0
  20. package/dist/connection-policy.js.map +1 -0
  21. package/dist/db-key-derivation.d.ts +26 -0
  22. package/dist/db-key-derivation.d.ts.map +1 -0
  23. package/dist/db-key-derivation.js +37 -0
  24. package/dist/db-key-derivation.js.map +1 -0
  25. package/dist/encrypted-file-signing-key-provider.d.ts +92 -0
  26. package/dist/encrypted-file-signing-key-provider.d.ts.map +1 -0
  27. package/dist/encrypted-file-signing-key-provider.js +251 -0
  28. package/dist/encrypted-file-signing-key-provider.js.map +1 -0
  29. package/dist/index.d.ts +13 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +8 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/mcp-server.d.ts +270 -0
  34. package/dist/mcp-server.d.ts.map +1 -0
  35. package/dist/mcp-server.js +1155 -0
  36. package/dist/mcp-server.js.map +1 -0
  37. package/dist/network-directory-node.d.ts +85 -0
  38. package/dist/network-directory-node.d.ts.map +1 -0
  39. package/dist/network-directory-node.js +584 -0
  40. package/dist/network-directory-node.js.map +1 -0
  41. package/dist/s3-cloud-storage-provider.d.ts +54 -0
  42. package/dist/s3-cloud-storage-provider.d.ts.map +1 -0
  43. package/dist/s3-cloud-storage-provider.js +78 -0
  44. package/dist/s3-cloud-storage-provider.js.map +1 -0
  45. package/dist/sqlcipher-client-store.d.ts +68 -0
  46. package/dist/sqlcipher-client-store.d.ts.map +1 -0
  47. package/dist/sqlcipher-client-store.js +382 -0
  48. package/dist/sqlcipher-client-store.js.map +1 -0
  49. package/dist/types.d.ts +408 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +7 -0
  52. package/dist/types.js.map +1 -0
  53. package/package.json +48 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * CELLO Client — client.ts (MSG-002, SESSION-002)
3
+ *
4
+ * CelloClientImpl: peer registry, send path, inbound stream handler,
5
+ * and receive queue for the M0 one-shot message exchange protocol.
6
+ * SESSION-002 additions: receiveSessionAssignment, listSessions.
7
+ *
8
+ * PSEUDOCODE (Phase P):
9
+ *
10
+ * send(peerPubkeyHex, content):
11
+ * 1. Look up peerPubkeyHex → peer_not_connected if absent
12
+ * 2. buildEnvelope(content, keyProvider, Date.now()) → content_too_large if rejected
13
+ * 3. serializeEnvelope → bytes
14
+ * 4. node.newStream(peerId, CELLO_PROTOCOL_ID):
15
+ * - structured error → peer_unreachable or connection_lost
16
+ * 5. stream.send(lp.encode.single(bytes))
17
+ * 6. stream.close() — half-close write side
18
+ * 7. Drain read side (for await lp.decode(stream)):
19
+ * - clean EOF → delivered:true
20
+ * - stream.status === 'reset' → remote_rejected
21
+ * - transport error → connection_lost
22
+ *
23
+ * inbound handler (stream):
24
+ * 1. AbortController with 5s timeout
25
+ * 2. Read one LP frame via lp.decode(stream) — abort if timeout fires
26
+ * 3. deserializeEnvelope(payload) → malformed_envelope + stream.abort on error
27
+ * 4. validateEnvelope(envelope) → stream.abort on error
28
+ * 5. enqueue to receiveQueue keyed by sender_pubkey hex
29
+ * 6. stream.close() — clean close signals delivered:true to sender
30
+ *
31
+ * sendRaw(peerPubkeyHex, bytes) [internal, exposed for tests]:
32
+ * Open stream, write raw bytes as single LP frame, await close type.
33
+ * Used by tests to inject tampered envelopes.
34
+ *
35
+ * receiveSessionAssignment(assignment, myPubkey):
36
+ * SESSION-002 AC-002, AC-003, AC-004, AC-005, SI-003
37
+ * SESSION-004 changes: replace M1 Ed25519 verify with FROST verify path.
38
+ *
39
+ * SESSION-004 pseudocode (Phase P rev2):
40
+ * RFC 9591 (FROST), RFC 8032 (Ed25519), FIPS 180-4 (SHA-256)
41
+ *
42
+ * 1. Check signature_type (SESSION-004 SI-003, AC-003):
43
+ * if assignment.signature_type === 'single':
44
+ * return { ok:false, reason:"unsupported_signature_type" }
45
+ * // Hard cut — even if the single-key sig itself verifies (SI-003 is absolute)
46
+ * // No session record is created (SI-003). No I/O is attempted.
47
+ *
48
+ * 2. Determine role and verification key (SESSION-004 AC-007):
49
+ * isInitiator = (Buffer.from(myPubkey).equals(Buffer.from(pubA)))
50
+ * if isInitiator:
51
+ * // CRITICAL-1 FIX: initiator MUST have a thresholdSigner injected.
52
+ * // There is NO fallback to assignment.signer_pubkey — that is frame-provided
53
+ * // and attacker-controlled. Absence of a signer is a hard error.
54
+ * if this.#thresholdSigner is null:
55
+ * return { ok:false, reason:"frost_signer_not_configured" }
56
+ * verifyKey = this.#thresholdSigner.getPrimaryPubkey() // HIGH-4: on IThresholdSigner
57
+ * else:
58
+ * // Counterparty: use signer_pubkey embedded in the frame (A's primary_pubkey)
59
+ * // TypeScript discriminated union guarantees signer_pubkey is present for 'frost' frames
60
+ * verifyKey = assignment.signer_pubkey // guaranteed non-undefined by type system
61
+ *
62
+ * 3. Compute genesis_prev_root (same as M1):
63
+ * genesis_prev_root = computeGenesisPrevRoot(pubA, pubB, session_id, session_timestamp)
64
+ *
65
+ * 4. Build session establishment TBS (HIGH-5: uses buildSessionEstablishmentTbs from protocol-types):
66
+ * tbs = buildSessionEstablishmentTbs(session_id, pubA, pubB, genesis_prev_root, session_timestamp)
67
+ *
68
+ * 5. Verify FROST signature (SESSION-004 AC-002, SI-001):
69
+ * // Use FrostThresholdSigner.verifySignature() which handles framing internally:
70
+ * // framedMsg = <context>\0<tbs> (domain separation per CONTEXT.md)
71
+ * // OR use ed25519_FROST.verify(sig, frameMessage(context, tbs), verifyKey) directly
72
+ * // The client imports ed25519_FROST from @noble/curves/ed25519 (not from @cello-protocol/crypto)
73
+ * // to keep the verify path independent from any signer state.
74
+ * framedMsg = frameMessage(CONTEXT_SESSION_ESTABLISHMENT, tbs) // context\0tbs
75
+ * isValid = ed25519_FROST.verify(assignment.directory_signature, framedMsg, verifyKey)
76
+ * if !isValid:
77
+ * return { ok:false, reason:"frost_signature_invalid" }
78
+ * // Never accept a tampered signature (SI-001 absolute)
79
+ *
80
+ * 6-9. (same as M1: content handler, relay auth, counterparty dial, store session)
81
+ *
82
+ * IMPORTANT NOTE on CelloClientImpl constructor and createClient factory changes:
83
+ * - Add optional #thresholdSigner: IThresholdSigner | null field
84
+ * - createClient accepts optional thresholdSigner in opts
85
+ * - No @cello-protocol/directory import — IThresholdSigner comes from @cello-protocol/crypto
86
+ *
87
+ * IMPORTANT NOTE on ReceiveAssignmentResult (IMPORTANT-9):
88
+ * Add 'frost_signature_invalid' | 'unsupported_signature_type' | 'frost_signer_not_configured'
89
+ * to the reason union in types.ts
90
+ *
91
+ * 1. Build TBS = CBOR([session_id, participant_a.pubkey, participant_b.pubkey, session_timestamp])
92
+ * 2. Verify Ed25519(TBS, assignment.directory_pubkey, assignment.directory_signature) [M1, REMOVED in M2]
93
+ * → { ok:false, reason:"directory_signature_invalid" } if fails
94
+ * 3. Determine counterparty: if myPubkey == participant_a.pubkey then counterparty = B, else A
95
+ * 4. Compute genesis_prev_root = computeGenesisPrevRoot(pubA, pubB, session_id, session_timestamp)
96
+ * per FIPS 180-4 / SESSION-002
97
+ * 5. Register /cello/content/1.0.0 handler on node (if not yet registered)
98
+ * 6. Dial relay on /cello/relay/1.0.0, complete challenge-response auth:
99
+ * a. Read relay_auth_challenge frame
100
+ * b. Compute authMsg = SHA-256("CELLO-RELAY-AUTH-v1" || nonce || myPubkey) [RFC 8032, FIPS 180-4]
101
+ * c. Sign authMsg with keyProvider → signature
102
+ * d. Send relay_auth_response{pubkey, signature}
103
+ * → { ok:false, reason:"relay_auth_failed" } or "relay_auth_error" on failure
104
+ * 7. Dial counterparty on /cello/content/1.0.0
105
+ * → { ok:false, reason:"dial_counterparty_failed" } if unreachable
106
+ * 8. Store SessionRecord with status:"active", last_seen_seq:0
107
+ * 9. Return { ok:true, sessionId }
108
+ */
109
+ import type { IThresholdSigner } from "@cello-protocol/crypto";
110
+ import type { KeyProvider } from "@cello-protocol/crypto";
111
+ import type { CelloNode } from "@cello-protocol/transport";
112
+ import type { Stream } from "@libp2p/interface";
113
+ import type { CelloClient, SendResult, SessionRecord } from "./types.js";
114
+ import type { Logger } from "@cello-protocol/interfaces";
115
+ export declare function createClient(node: CelloNode, keyProvider: KeyProvider, opts?: {
116
+ onMessageQueued?: (senderPubkeyHex: string) => void;
117
+ contentGraceMs?: number;
118
+ /** SESSION-006: ms to attempt relay reconnect before giving up. Default: 60000. */
119
+ reconnectTimeoutMs?: number;
120
+ /** SESSION-004/SESSION-005: optional FROST threshold signer for initiator role and seal ceremony coordination. */
121
+ thresholdSigner?: IThresholdSigner;
122
+ /** SESSION-005: ms to wait for FROST seal after bilateral exchange. Default: 15000. */
123
+ sealFrostTimeoutMs?: number;
124
+ /** ADAPTER-003: directory endpoint for initiateSession. */
125
+ directoryEndpoint?: {
126
+ peer_id: string;
127
+ multiaddrs: string[];
128
+ };
129
+ /** REG-001: path for persisting ML-DSA-44 keypair. If set, FileMlDsaKeyProvider.load() is used. */
130
+ mlDsaKeyFile?: string;
131
+ /** CONNREQ-002: connection policy for evaluating inbound connection_request_inbound frames. */
132
+ connectionPolicy?: import("./connection-policy.js").SignalRequirementPolicy;
133
+ /** CONNREQ-002: overall connection timeout in ms. Default: 300000. */
134
+ connectionTimeoutMs?: number;
135
+ /** CONNREQ-002: Round 2 silence timeout in ms. Default: 120000. */
136
+ round2TimeoutMs?: number;
137
+ /** CONNREQ-002: if true, expose _evaluateCallCount on the instance for test assertions. */
138
+ trackEvaluateCount?: boolean;
139
+ /** CONNREQ-002: sender pubkeys that bypass evaluateConnectionPackage. */
140
+ whitelist?: string[];
141
+ /** CONNREQ-002: callback fired when an inbound connection_request_inbound is queued for agent review. */
142
+ onConnectionPendingReview?: (event: import("@cello-protocol/protocol-types").ConnectionRequestInbound) => void;
143
+ /** DB-003: attempt cross-check of sender's ml_dsa_pubkey on inbound requests. */
144
+ crossCheckDirectoryOnInbound?: boolean;
145
+ /** PERSIST-014: injected logger for observability events. */
146
+ logger?: Logger;
147
+ }): CelloClient & {
148
+ sendRaw(peerPubkeyHex: string, bytes: Uint8Array): Promise<SendResult>;
149
+ openRawStream(peerPubkeyHex: string): Promise<Stream>;
150
+ openContentStreamByPeerId(peerId: string): Promise<Stream>;
151
+ /** SESSION-005: register the client's FROST primary_pubkey for seal verification. */
152
+ setPrimaryPubkey(primaryPubkey: Uint8Array): void;
153
+ injectDirectoryFrame(sessionIdHex: string, frame: Record<string, unknown>): void;
154
+ injectLeafDeliver(sessionIdHex: string, frame: Record<string, unknown>): void;
155
+ injectRelayDisconnect(sessionIdHex: string): void;
156
+ /** TEST-ONLY: register a minimal session record without a real relay connection. */
157
+ injectTestSession(sessionIdHex: string, sessionId: Uint8Array, myPubkeyHex: string, directoryPubkey: Uint8Array, status?: SessionRecord["status"], opts?: {
158
+ isInitiator?: boolean;
159
+ }): void;
160
+ /** CONNREQ-002: list active connection records. */
161
+ listConnections(): import("@cello-protocol/protocol-types").ClientConnectionRecord[];
162
+ /** CONNREQ-002: send connection_request to target B and await final outcome. */
163
+ cello_request_connection(opts: {
164
+ target_pubkey: string;
165
+ package_cbor: Uint8Array;
166
+ }): Promise<{
167
+ result: "established";
168
+ connection_id: string;
169
+ } | {
170
+ result: "rejected";
171
+ reason: string;
172
+ } | {
173
+ result: "insufficient";
174
+ unmet_requirements: unknown[];
175
+ } | {
176
+ result: "disclosure_requested";
177
+ connection_request_id: string;
178
+ requested_items: unknown[];
179
+ } | {
180
+ result: "timeout";
181
+ } | {
182
+ result: "error";
183
+ reason: string;
184
+ }>;
185
+ /** CONNREQ-002: respond to disclosure_request (Round 2 sender side). */
186
+ cello_respond_to_disclosure_request(opts: {
187
+ connection_request_id: string;
188
+ package_cbor: Uint8Array;
189
+ }): Promise<{
190
+ result: "established";
191
+ connection_id: string;
192
+ } | {
193
+ result: "rejected";
194
+ reason: string;
195
+ } | {
196
+ result: "insufficient";
197
+ unmet_requirements: unknown[];
198
+ } | {
199
+ result: "timeout";
200
+ } | {
201
+ result: "error";
202
+ reason: string;
203
+ }>;
204
+ /** CONNREQ-002: request more disclosure from sender (Round 2, target side). */
205
+ cello_request_more_disclosure(opts: {
206
+ connection_request_id: string;
207
+ requested_items: unknown[];
208
+ }): Promise<{
209
+ error: "max_rounds_reached";
210
+ } | {
211
+ ok: true;
212
+ }>;
213
+ /** CONNREQ-002: register connection_established event handler. */
214
+ onConnectionEstablished(handler: (event: import("@cello-protocol/protocol-types").ConnectionEstablished) => void): void;
215
+ /** CONNREQ-002: register disclosure_request_inbound event handler (sender side). */
216
+ onDisclosureRequested(handler: (event: import("@cello-protocol/protocol-types").DisclosureRequestInbound) => void): void;
217
+ /** CONNREQ-002: reconnect the persistent directory signaling stream. */
218
+ reconnectDirectory(): Promise<boolean>;
219
+ /** PERSIST-015: send seal_unilateral to directory after delivery_grace_seconds. */
220
+ initiateUnilateralSeal(sessionIdHex: string): Promise<{
221
+ ok: true;
222
+ sealed_root: Uint8Array;
223
+ sealed_at: number;
224
+ } | {
225
+ ok: false;
226
+ reason: "too_early";
227
+ remaining_seconds: number;
228
+ } | {
229
+ ok: false;
230
+ reason: string;
231
+ }>;
232
+ /** TEST-ONLY: inject a pending inbound connection request into state. */
233
+ _injectPendingConnectionRequest(opts: {
234
+ connection_request_id: string;
235
+ from_pubkey: string;
236
+ package_cbor: Uint8Array;
237
+ round: number;
238
+ }): void;
239
+ /**
240
+ * CONNREQ-003 TEST-ONLY: route a synthetic connection outcome frame through the
241
+ * resolver Map — used by SI-001 adversarial test to verify cross-target isolation.
242
+ */
243
+ _injectConnectionFrame(frame: Record<string, unknown>): void;
244
+ /** CONNREQ-003 TEST-ONLY: current size of the pending resolver Map. */
245
+ _pendingConnectionRequestResolverCount: number;
246
+ /** TEST-ONLY: evaluate call counter (only incremented when trackEvaluateCount=true). */
247
+ _evaluateCallCount: number;
248
+ };
249
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}