@cello-protocol/client 0.0.21 → 0.0.23
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/client-send-helpers.d.ts +25 -0
- package/dist/client-send-helpers.d.ts.map +1 -0
- package/dist/client-send-helpers.js +118 -0
- package/dist/client-send-helpers.js.map +1 -0
- package/dist/client-startup.d.ts +74 -0
- package/dist/client-startup.d.ts.map +1 -0
- package/dist/client-startup.js +338 -0
- package/dist/client-startup.js.map +1 -0
- package/dist/client-wiring.d.ts +120 -0
- package/dist/client-wiring.d.ts.map +1 -0
- package/dist/client-wiring.js +289 -0
- package/dist/client-wiring.js.map +1 -0
- package/dist/client.d.ts +29 -169
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +222 -5396
- package/dist/client.js.map +1 -1
- package/dist/connection-inbound-handler.d.ts +47 -0
- package/dist/connection-inbound-handler.d.ts.map +1 -0
- package/dist/connection-inbound-handler.js +325 -0
- package/dist/connection-inbound-handler.js.map +1 -0
- package/dist/connection-manager.d.ts +191 -0
- package/dist/connection-manager.d.ts.map +1 -0
- package/dist/connection-manager.js +692 -0
- package/dist/connection-manager.js.map +1 -0
- package/dist/frame-dispatch.d.ts +28 -0
- package/dist/frame-dispatch.d.ts.map +1 -0
- package/dist/frame-dispatch.js +118 -0
- package/dist/frame-dispatch.js.map +1 -0
- package/dist/network-directory-node.d.ts +2 -0
- package/dist/network-directory-node.d.ts.map +1 -1
- package/dist/network-directory-node.js +24 -16
- package/dist/network-directory-node.js.map +1 -1
- package/dist/registration-manager.d.ts +54 -0
- package/dist/registration-manager.d.ts.map +1 -0
- package/dist/registration-manager.js +249 -0
- package/dist/registration-manager.js.map +1 -0
- package/dist/relay-stream-manager.d.ts +136 -0
- package/dist/relay-stream-manager.d.ts.map +1 -0
- package/dist/relay-stream-manager.js +834 -0
- package/dist/relay-stream-manager.js.map +1 -0
- package/dist/seal-manager.d.ts +133 -0
- package/dist/seal-manager.d.ts.map +1 -0
- package/dist/seal-manager.js +803 -0
- package/dist/seal-manager.js.map +1 -0
- package/dist/session-assignment-parser.d.ts +33 -0
- package/dist/session-assignment-parser.d.ts.map +1 -0
- package/dist/session-assignment-parser.js +149 -0
- package/dist/session-assignment-parser.js.map +1 -0
- package/dist/session-manager.d.ts +132 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +611 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/signaling-manager.d.ts +85 -0
- package/dist/signaling-manager.d.ts.map +1 -0
- package/dist/signaling-manager.js +605 -0
- package/dist/signaling-manager.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RegistrationManager — REG-001, ML-DSA keygen, DKG
|
|
3
|
+
*
|
|
4
|
+
* Extracted from CelloClientImpl. Owns registration domain state:
|
|
5
|
+
* #registrationState, #mlDsaProvider.
|
|
6
|
+
*/
|
|
7
|
+
import { Encoder } from "cbor-x";
|
|
8
|
+
import * as lp from "it-length-prefixed";
|
|
9
|
+
import { mlDsaKeygen, mlDsaKeygenWithBytes, FileMlDsaKeyProvider } from "@cello-protocol/crypto";
|
|
10
|
+
import { NetworkDirectoryNode, runNetworkDkg } from "./network-directory-node.js";
|
|
11
|
+
const CBOR_ENC = new Encoder({ tagUint8Array: false });
|
|
12
|
+
export class RegistrationManager {
|
|
13
|
+
#ctx;
|
|
14
|
+
// Registration state owned by this manager
|
|
15
|
+
#registrationState = null;
|
|
16
|
+
#mlDsaProvider = null;
|
|
17
|
+
constructor(ctx) {
|
|
18
|
+
this.#ctx = ctx;
|
|
19
|
+
}
|
|
20
|
+
// ─── Public state accessors ──────────────────────────────────────────────────
|
|
21
|
+
getRegistrationState() {
|
|
22
|
+
return this.#registrationState;
|
|
23
|
+
}
|
|
24
|
+
setRegistrationState(state) {
|
|
25
|
+
this.#registrationState = state;
|
|
26
|
+
}
|
|
27
|
+
getMlDsaProvider() {
|
|
28
|
+
return this.#mlDsaProvider;
|
|
29
|
+
}
|
|
30
|
+
setMlDsaProvider(provider) {
|
|
31
|
+
this.#mlDsaProvider = provider;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Register this agent with the directory.
|
|
35
|
+
* REG-001: ML-DSA keygen → signaling stream → register_request → DKG → register_success.
|
|
36
|
+
*/
|
|
37
|
+
async register(phoneStub = "", preAuthToken) {
|
|
38
|
+
// Step 1: already registered
|
|
39
|
+
if (this.#registrationState) {
|
|
40
|
+
return { error: "already_registered" };
|
|
41
|
+
}
|
|
42
|
+
// Step 2: generate or load ML-DSA-44 keypair
|
|
43
|
+
let mlDsaProvider;
|
|
44
|
+
let mlDsaSecretKeyBlob = null;
|
|
45
|
+
if (this.#ctx.mlDsaKeyFile) {
|
|
46
|
+
mlDsaProvider = await FileMlDsaKeyProvider.load(this.#ctx.mlDsaKeyFile);
|
|
47
|
+
}
|
|
48
|
+
else if (this.#ctx.persistence) {
|
|
49
|
+
const { provider, secretKeyBlob } = await mlDsaKeygenWithBytes();
|
|
50
|
+
mlDsaProvider = provider;
|
|
51
|
+
mlDsaSecretKeyBlob = secretKeyBlob;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
mlDsaProvider = await mlDsaKeygen();
|
|
55
|
+
}
|
|
56
|
+
const mlDsaPubkey = await mlDsaProvider.getPublicKey();
|
|
57
|
+
const mlDsaPubkeyHex = Buffer.from(mlDsaPubkey).toString("hex");
|
|
58
|
+
// Step 3: open persistent signaling stream
|
|
59
|
+
const opened = await this.#ctx.openPersistentSignalingStream();
|
|
60
|
+
if (!opened || !this.#ctx.getPersistentSignalingStream()) {
|
|
61
|
+
return { error: "directory_unreachable" };
|
|
62
|
+
}
|
|
63
|
+
// Step 4: get K_local pubkey hex
|
|
64
|
+
if (!this.#ctx.getMyPubkeyHex()) {
|
|
65
|
+
const pubkey = await this.#ctx.keyProvider.getPublicKey();
|
|
66
|
+
this.#ctx.setMyPubkeyHex(Buffer.from(pubkey).toString("hex"));
|
|
67
|
+
}
|
|
68
|
+
const kLocalPubkeyHex = this.#ctx.getMyPubkeyHex();
|
|
69
|
+
// Step 5: send register_request
|
|
70
|
+
const regRequestFrame = CBOR_ENC.encode({
|
|
71
|
+
type: "register_request",
|
|
72
|
+
phone_stub: phoneStub,
|
|
73
|
+
k_local_pubkey: kLocalPubkeyHex,
|
|
74
|
+
ml_dsa_pubkey: mlDsaPubkeyHex,
|
|
75
|
+
});
|
|
76
|
+
this.#ctx.getPersistentSignalingStream().send(lp.encode.single(regRequestFrame));
|
|
77
|
+
// Step 5a: await dkg_ready
|
|
78
|
+
const DKG_READY_TIMEOUT_MS = 15_000;
|
|
79
|
+
let dkgReadyTimeoutHandle;
|
|
80
|
+
const dkgReadyFrame = await Promise.race([
|
|
81
|
+
new Promise((resolve) => {
|
|
82
|
+
this.#ctx.setPendingDkgReadyResolve(resolve);
|
|
83
|
+
}),
|
|
84
|
+
new Promise((resolve) => {
|
|
85
|
+
dkgReadyTimeoutHandle = setTimeout(() => {
|
|
86
|
+
this.#ctx.setPendingDkgReadyResolve(null);
|
|
87
|
+
resolve({ type: "register_error", reason: "timeout" });
|
|
88
|
+
}, DKG_READY_TIMEOUT_MS);
|
|
89
|
+
}),
|
|
90
|
+
]);
|
|
91
|
+
clearTimeout(dkgReadyTimeoutHandle);
|
|
92
|
+
if (dkgReadyFrame["type"] !== "dkg_ready") {
|
|
93
|
+
const reason = dkgReadyFrame["reason"] ?? "unknown";
|
|
94
|
+
if (reason === "already_registered" &&
|
|
95
|
+
dkgReadyFrame["agent_id"] &&
|
|
96
|
+
dkgReadyFrame["primary_pubkey"]) {
|
|
97
|
+
const state = {
|
|
98
|
+
agent_id: dkgReadyFrame["agent_id"],
|
|
99
|
+
primary_pubkey: dkgReadyFrame["primary_pubkey"],
|
|
100
|
+
ml_dsa_pubkey: dkgReadyFrame["ml_dsa_pubkey"] ?? mlDsaPubkeyHex,
|
|
101
|
+
registered_at: Date.now(),
|
|
102
|
+
status: "active",
|
|
103
|
+
};
|
|
104
|
+
this.#registrationState = state;
|
|
105
|
+
this.#mlDsaProvider = mlDsaProvider;
|
|
106
|
+
if (this.#ctx.persistence && mlDsaSecretKeyBlob) {
|
|
107
|
+
void this.#ctx.persistence.persistMlDsaKeypair({
|
|
108
|
+
mlDsaPubkey: mlDsaPubkeyHex,
|
|
109
|
+
secretKeyBlob: mlDsaSecretKeyBlob,
|
|
110
|
+
});
|
|
111
|
+
void this.#ctx.persistence.persistRegistrationState({
|
|
112
|
+
agentId: state.agent_id,
|
|
113
|
+
primaryPubkey: state.primary_pubkey,
|
|
114
|
+
mlDsaPubkey: state.ml_dsa_pubkey,
|
|
115
|
+
registeredAt: state.registered_at,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return state;
|
|
119
|
+
}
|
|
120
|
+
return { error: reason };
|
|
121
|
+
}
|
|
122
|
+
// Step 5b: run real FROST DKG
|
|
123
|
+
const epochId = dkgReadyFrame["epochId"];
|
|
124
|
+
const participants = dkgReadyFrame["participants"];
|
|
125
|
+
const threshold = dkgReadyFrame["threshold"];
|
|
126
|
+
const directoryEndpoint = this.#ctx.getDirectoryEndpoint();
|
|
127
|
+
if (!directoryEndpoint) {
|
|
128
|
+
return { error: "directory_unreachable" };
|
|
129
|
+
}
|
|
130
|
+
const dirNode = new NetworkDirectoryNode({
|
|
131
|
+
id: directoryEndpoint.peer_id,
|
|
132
|
+
node: this.#ctx.node,
|
|
133
|
+
directoryPeerId: directoryEndpoint.peer_id,
|
|
134
|
+
directoryMultiaddrs: directoryEndpoint.multiaddrs,
|
|
135
|
+
logger: this.#ctx.logger,
|
|
136
|
+
});
|
|
137
|
+
void epochId;
|
|
138
|
+
const kLocalPubkeyBytes = Buffer.from(kLocalPubkeyHex, "hex");
|
|
139
|
+
let dkgPrimaryPubkeyHex;
|
|
140
|
+
try {
|
|
141
|
+
const dkgResult = await runNetworkDkg(kLocalPubkeyBytes, {
|
|
142
|
+
threshold,
|
|
143
|
+
participants,
|
|
144
|
+
directoryNodes: [dirNode],
|
|
145
|
+
preAuthToken,
|
|
146
|
+
});
|
|
147
|
+
dkgPrimaryPubkeyHex = Buffer.from(dkgResult.primaryPubkey).toString("hex");
|
|
148
|
+
this.#ctx.setThresholdSigner(dkgResult.signer);
|
|
149
|
+
this.#ctx.setMyPrimaryPubkey(new Uint8Array(dkgResult.primaryPubkey));
|
|
150
|
+
if (this.#ctx.persistence) {
|
|
151
|
+
const commitmentsCbor = CBOR_ENC.encode(dkgResult.commitments);
|
|
152
|
+
const verifyingSharesCbor = CBOR_ENC.encode(dkgResult.verifyingShares);
|
|
153
|
+
void this.#ctx.persistence.persistFrostKeyShare({
|
|
154
|
+
epochId,
|
|
155
|
+
primaryPubkey: dkgPrimaryPubkeyHex,
|
|
156
|
+
identifier: dkgResult.identifier,
|
|
157
|
+
signingShare: dkgResult.signingShare,
|
|
158
|
+
threshold: dkgResult.threshold,
|
|
159
|
+
participants: dkgResult.participants,
|
|
160
|
+
commitmentsCbor,
|
|
161
|
+
verifyingSharesCbor,
|
|
162
|
+
dkgMethod: "network_dkg",
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return { error: "dkg_failed" };
|
|
168
|
+
}
|
|
169
|
+
// Step 5c: send dkg_complete
|
|
170
|
+
const dkgCompleteFrame = CBOR_ENC.encode({
|
|
171
|
+
type: "dkg_complete",
|
|
172
|
+
primary_pubkey: dkgPrimaryPubkeyHex,
|
|
173
|
+
});
|
|
174
|
+
this.#ctx.getPersistentSignalingStream().send(lp.encode.single(dkgCompleteFrame));
|
|
175
|
+
// Step 6: await register_success or register_error
|
|
176
|
+
const REGISTER_TIMEOUT_MS = 15_000;
|
|
177
|
+
let timeoutHandle;
|
|
178
|
+
const responseWithTimeout = await Promise.race([
|
|
179
|
+
new Promise((resolve) => {
|
|
180
|
+
this.#ctx.setPendingRegisterResolve(resolve);
|
|
181
|
+
}),
|
|
182
|
+
new Promise((resolve) => {
|
|
183
|
+
timeoutHandle = setTimeout(() => {
|
|
184
|
+
this.#ctx.setPendingRegisterResolve(null);
|
|
185
|
+
resolve({ type: "register_error", reason: "timeout" });
|
|
186
|
+
}, REGISTER_TIMEOUT_MS);
|
|
187
|
+
}),
|
|
188
|
+
]);
|
|
189
|
+
clearTimeout(timeoutHandle);
|
|
190
|
+
if (responseWithTimeout["type"] !== "register_success") {
|
|
191
|
+
const reason = responseWithTimeout["reason"] ?? "unknown";
|
|
192
|
+
if (reason === "already_registered" &&
|
|
193
|
+
responseWithTimeout["agent_id"] &&
|
|
194
|
+
responseWithTimeout["primary_pubkey"]) {
|
|
195
|
+
const state = {
|
|
196
|
+
agent_id: responseWithTimeout["agent_id"],
|
|
197
|
+
primary_pubkey: responseWithTimeout["primary_pubkey"],
|
|
198
|
+
ml_dsa_pubkey: responseWithTimeout["ml_dsa_pubkey"] ?? mlDsaPubkeyHex,
|
|
199
|
+
registered_at: Date.now(),
|
|
200
|
+
status: "active",
|
|
201
|
+
};
|
|
202
|
+
this.#registrationState = state;
|
|
203
|
+
this.#mlDsaProvider = mlDsaProvider;
|
|
204
|
+
if (this.#ctx.persistence && mlDsaSecretKeyBlob) {
|
|
205
|
+
void this.#ctx.persistence.persistMlDsaKeypair({
|
|
206
|
+
mlDsaPubkey: mlDsaPubkeyHex,
|
|
207
|
+
secretKeyBlob: mlDsaSecretKeyBlob,
|
|
208
|
+
});
|
|
209
|
+
void this.#ctx.persistence.persistRegistrationState({
|
|
210
|
+
agentId: state.agent_id,
|
|
211
|
+
primaryPubkey: state.primary_pubkey,
|
|
212
|
+
mlDsaPubkey: state.ml_dsa_pubkey,
|
|
213
|
+
registeredAt: state.registered_at,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return state;
|
|
217
|
+
}
|
|
218
|
+
return { error: reason };
|
|
219
|
+
}
|
|
220
|
+
// Step 7: build RegistrationState and cache
|
|
221
|
+
const agentId = responseWithTimeout["agent_id"];
|
|
222
|
+
const primaryPubkey = responseWithTimeout["primary_pubkey"];
|
|
223
|
+
const state = {
|
|
224
|
+
agent_id: agentId,
|
|
225
|
+
primary_pubkey: primaryPubkey,
|
|
226
|
+
ml_dsa_pubkey: mlDsaPubkeyHex,
|
|
227
|
+
registered_at: Date.now(),
|
|
228
|
+
status: "active",
|
|
229
|
+
};
|
|
230
|
+
this.#registrationState = state;
|
|
231
|
+
this.#mlDsaProvider = mlDsaProvider;
|
|
232
|
+
if (this.#ctx.persistence && mlDsaSecretKeyBlob) {
|
|
233
|
+
void this.#ctx.persistence.persistMlDsaKeypair({
|
|
234
|
+
mlDsaPubkey: mlDsaPubkeyHex,
|
|
235
|
+
secretKeyBlob: mlDsaSecretKeyBlob,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (this.#ctx.persistence) {
|
|
239
|
+
void this.#ctx.persistence.persistRegistrationState({
|
|
240
|
+
agentId: state.agent_id,
|
|
241
|
+
primaryPubkey: state.primary_pubkey,
|
|
242
|
+
mlDsaPubkey: state.ml_dsa_pubkey,
|
|
243
|
+
registeredAt: state.registered_at,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return state;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
//# 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,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RelayStreamManager — relay reader loop, reconnect logic, cross-check, content frame handling.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from CelloClientImpl. Handles MSG-004 relay stream lifecycle:
|
|
5
|
+
* - #runRelayStreamReader: reads leaf_deliver, hash_submit_ack/error, gap_fill frames
|
|
6
|
+
* - #reconnectRelayStream: SESSION-006 exponential backoff reconnect
|
|
7
|
+
* - #handleInboundLeafDeliver: S2 decode, sequence/signature checks, cross-check pairing
|
|
8
|
+
* - #handleContentStream: content path receiver, cross-check trigger
|
|
9
|
+
* - #crossCheckDelivery / #drainReadyQueue: in-order delivery with prevRoot check
|
|
10
|
+
* - #desync: session desynchronization
|
|
11
|
+
* - #performRelayAuth: challenge-response auth
|
|
12
|
+
* - #performGapFillReconciliation: PERSIST-014 gap fill
|
|
13
|
+
* - #handleGapFillResponse
|
|
14
|
+
*
|
|
15
|
+
* State owned here (not in facade):
|
|
16
|
+
* - #relayStreams, #relayRecvSeq, #reconnectInProgress
|
|
17
|
+
* - #readyQueue, #pendingS2, #pendingContent
|
|
18
|
+
* - #tamperedContentClaims, #pendingGapFillResolvers
|
|
19
|
+
* - #directoryStreams
|
|
20
|
+
*/
|
|
21
|
+
import type { CelloNode } from "@cello-protocol/transport";
|
|
22
|
+
import type { Stream } from "@libp2p/interface";
|
|
23
|
+
import type { Structure2 } from "@cello-protocol/protocol-types";
|
|
24
|
+
import type { Logger } from "@cello-protocol/interfaces";
|
|
25
|
+
import type { KeyProvider } from "@cello-protocol/crypto";
|
|
26
|
+
import type { ClientStatePersistence } from "./client-state-persistence.js";
|
|
27
|
+
import type { SessionRecord, ReceivedMessage } from "./types.js";
|
|
28
|
+
import type { AgentHashQueue } from "./agent-hash-queue.js";
|
|
29
|
+
declare const DEFAULT_RECONNECT_TIMEOUT_MS = 60000;
|
|
30
|
+
interface Structure1Fields {
|
|
31
|
+
last_seen_seq: number;
|
|
32
|
+
timestamp: number | bigint;
|
|
33
|
+
}
|
|
34
|
+
interface PendingS2Entry {
|
|
35
|
+
s2: Structure2;
|
|
36
|
+
s2_cbor: Uint8Array;
|
|
37
|
+
s1_fields: Structure1Fields;
|
|
38
|
+
leaf_kind: number;
|
|
39
|
+
sequence_number: number;
|
|
40
|
+
content_hash: Uint8Array;
|
|
41
|
+
is_own_send: boolean;
|
|
42
|
+
arrived_at: number;
|
|
43
|
+
timer_handle: ReturnType<typeof setTimeout>;
|
|
44
|
+
echo_resolve?: () => void;
|
|
45
|
+
}
|
|
46
|
+
interface PendingContentEntry {
|
|
47
|
+
content_bytes: Uint8Array;
|
|
48
|
+
arrived_at: number;
|
|
49
|
+
}
|
|
50
|
+
interface ReadyEntry {
|
|
51
|
+
s2: Structure2;
|
|
52
|
+
s2_cbor: Uint8Array;
|
|
53
|
+
s1_fields: Structure1Fields;
|
|
54
|
+
leaf_kind: number;
|
|
55
|
+
content_bytes: Uint8Array;
|
|
56
|
+
is_own_send: boolean;
|
|
57
|
+
echo_resolve?: () => void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Narrow interface exposing only what RelayStreamManager needs from external managers.
|
|
61
|
+
* State owned by RelayStreamManager is no longer in this interface.
|
|
62
|
+
*/
|
|
63
|
+
export interface RelayStreamContext {
|
|
64
|
+
readonly node: CelloNode;
|
|
65
|
+
readonly keyProvider: KeyProvider;
|
|
66
|
+
readonly logger: Logger;
|
|
67
|
+
readonly persistence: ClientStatePersistence | null;
|
|
68
|
+
readonly contentGraceMs: number;
|
|
69
|
+
readonly reconnectTimeoutMs: number;
|
|
70
|
+
readonly hashQueue: AgentHashQueue | null;
|
|
71
|
+
getMyPubkeyHex(): string | null;
|
|
72
|
+
getSession(sessionIdHex: string): SessionRecord | undefined;
|
|
73
|
+
getSessions(): Map<string, SessionRecord>;
|
|
74
|
+
getPendingAckResolver(sessionIdHex: string): ((v: {
|
|
75
|
+
ok: true;
|
|
76
|
+
sequence_number: number;
|
|
77
|
+
} | {
|
|
78
|
+
ok: false;
|
|
79
|
+
reason: string;
|
|
80
|
+
}) => void) | undefined;
|
|
81
|
+
setPendingAckResolver(sessionIdHex: string, resolve: (v: {
|
|
82
|
+
ok: true;
|
|
83
|
+
sequence_number: number;
|
|
84
|
+
} | {
|
|
85
|
+
ok: false;
|
|
86
|
+
reason: string;
|
|
87
|
+
}) => void): void;
|
|
88
|
+
deletePendingAckResolver(sessionIdHex: string): void;
|
|
89
|
+
getOwnPendingContent(sessionIdHex: string): Map<string, {
|
|
90
|
+
content_bytes: Uint8Array;
|
|
91
|
+
arrived_at: number;
|
|
92
|
+
}> | undefined;
|
|
93
|
+
getOwnEchoResolvers(sessionIdHex: string): Map<number, () => void> | undefined;
|
|
94
|
+
getOutboundQueue(sessionIdHex: string): Promise<void> | undefined;
|
|
95
|
+
enqueueReceivedMessage(sessionIdHex: string, message: ReceivedMessage): void;
|
|
96
|
+
wakeReceiveWaiters(sessionIdHex: string): void;
|
|
97
|
+
enqueueSessionSealedEvent(sessionIdHex: string, sealedRoot: Uint8Array, closeTimestamp: number): void;
|
|
98
|
+
handleSealVerified(sessionIdHex: string, frame: Record<string, unknown>): void;
|
|
99
|
+
handleSessionFrostSealed(sessionIdHex: string, frame: Record<string, unknown>): void;
|
|
100
|
+
handleSealRejectedTreeMismatch(sessionIdHex: string, frame: Record<string, unknown>): void;
|
|
101
|
+
handleSealUnilateralConfirmed(sessionIdHex: string, frame: Record<string, unknown>): void;
|
|
102
|
+
handleSealUnilateralNotification(sessionIdHex: string, frame: Record<string, unknown>): void;
|
|
103
|
+
handleDirectorySessionSealed(sessionIdHex: string, frame: Record<string, unknown>, directoryPubkey: Uint8Array): void;
|
|
104
|
+
handleDirectorySessionSealRejected(sessionIdHex: string, frame: Record<string, unknown>): void;
|
|
105
|
+
onRelayDisconnected(sessionIdHex: string, myPubkeyHex: string): void;
|
|
106
|
+
}
|
|
107
|
+
export type { ReadyEntry, PendingS2Entry, PendingContentEntry, Structure1Fields };
|
|
108
|
+
export declare class RelayStreamManager {
|
|
109
|
+
#private;
|
|
110
|
+
constructor(ctx: RelayStreamContext);
|
|
111
|
+
getRelayStream(sessionIdHex: string): Stream | undefined;
|
|
112
|
+
setRelayStream(sessionIdHex: string, stream: Stream): void;
|
|
113
|
+
deleteRelayStream(sessionIdHex: string): void;
|
|
114
|
+
getDirectoryStream(sessionIdHex: string): Stream | undefined;
|
|
115
|
+
setDirectoryStream(sessionIdHex: string, stream: Stream): void;
|
|
116
|
+
deleteDirectoryStream(sessionIdHex: string): void;
|
|
117
|
+
/** Called by SessionManager.receiveSessionAssignment to initialize per-session relay state. */
|
|
118
|
+
initSession(sessionIdHex: string): void;
|
|
119
|
+
/** Called by facade.closeSession to tear down per-session relay state. */
|
|
120
|
+
closeSession(sessionIdHex: string): void;
|
|
121
|
+
injectLeafDeliver(sessionIdHex: string, frame: Record<string, unknown>): void;
|
|
122
|
+
injectRelayDisconnect(sessionIdHex: string): void;
|
|
123
|
+
runRelayStreamReader(sessionIdHex: string, stream: Stream, myPubkeyHex: string, iter?: AsyncIterator<Uint8Array>): void;
|
|
124
|
+
reconnectRelayStream(sessionIdHex: string, myPubkeyHex: string): Promise<void>;
|
|
125
|
+
handleContentStream(stream: Stream): Promise<void>;
|
|
126
|
+
performRelayAuth(stream: Stream, myPubkey: Uint8Array): Promise<{
|
|
127
|
+
ok: true;
|
|
128
|
+
iter: AsyncIterator<Uint8Array>;
|
|
129
|
+
} | {
|
|
130
|
+
ok: false;
|
|
131
|
+
reason: "relay_auth_failed" | "relay_auth_error";
|
|
132
|
+
}>;
|
|
133
|
+
performGapFillReconciliation(sessionIdHex: string, fromSeq: number, toSeq: number, correlationId: string): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
export { DEFAULT_RECONNECT_TIMEOUT_MS };
|
|
136
|
+
//# sourceMappingURL=relay-stream-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-stream-manager.d.ts","sourceRoot":"","sources":["../src/relay-stream-manager.ts"],"names":[],"mappings":"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"}
|