@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.
- package/dist/agent-hash-queue.d.ts +206 -0
- package/dist/agent-hash-queue.d.ts.map +1 -0
- package/dist/agent-hash-queue.js +380 -0
- package/dist/agent-hash-queue.js.map +1 -0
- package/dist/backup-key-derivation.d.ts +37 -0
- package/dist/backup-key-derivation.d.ts.map +1 -0
- package/dist/backup-key-derivation.js +48 -0
- package/dist/backup-key-derivation.js.map +1 -0
- package/dist/client-backup.d.ts +144 -0
- package/dist/client-backup.d.ts.map +1 -0
- package/dist/client-backup.js +273 -0
- package/dist/client-backup.js.map +1 -0
- package/dist/client.d.ts +249 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +4664 -0
- package/dist/client.js.map +1 -0
- package/dist/connection-policy.d.ts +163 -0
- package/dist/connection-policy.d.ts.map +1 -0
- package/dist/connection-policy.js +248 -0
- package/dist/connection-policy.js.map +1 -0
- package/dist/db-key-derivation.d.ts +26 -0
- package/dist/db-key-derivation.d.ts.map +1 -0
- package/dist/db-key-derivation.js +37 -0
- package/dist/db-key-derivation.js.map +1 -0
- package/dist/encrypted-file-signing-key-provider.d.ts +92 -0
- package/dist/encrypted-file-signing-key-provider.d.ts.map +1 -0
- package/dist/encrypted-file-signing-key-provider.js +251 -0
- package/dist/encrypted-file-signing-key-provider.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +270 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +1155 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/network-directory-node.d.ts +85 -0
- package/dist/network-directory-node.d.ts.map +1 -0
- package/dist/network-directory-node.js +584 -0
- package/dist/network-directory-node.js.map +1 -0
- package/dist/s3-cloud-storage-provider.d.ts +54 -0
- package/dist/s3-cloud-storage-provider.d.ts.map +1 -0
- package/dist/s3-cloud-storage-provider.js +78 -0
- package/dist/s3-cloud-storage-provider.js.map +1 -0
- package/dist/sqlcipher-client-store.d.ts +68 -0
- package/dist/sqlcipher-client-store.d.ts.map +1 -0
- package/dist/sqlcipher-client-store.js +382 -0
- package/dist/sqlcipher-client-store.js.map +1 -0
- package/dist/types.d.ts +408 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
package/dist/client.d.ts
ADDED
|
@@ -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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"}
|