@derec-alliance/nodejs 0.0.1-alpha.6 → 0.0.1-alpha.9

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/index.d.ts ADDED
@@ -0,0 +1,1214 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (c) 2026 DeRec Alliance. All rights reserved.
3
+
4
+ export interface SecretStore {
5
+ load(
6
+ secretId: string,
7
+ channelId: string,
8
+ kind: 0 | 1 | 2,
9
+ ): Promise<Uint8Array | null | undefined>;
10
+ /**
11
+ * Load secrets of the same `kind` for several channels in one call,
12
+ * scoped to `secretId`. Must return an array with one entry per input
13
+ * id, in the same order, using `null` (or `undefined`) for channels
14
+ * with no stored secret of `kind`.
15
+ */
16
+ loadMany(
17
+ secretId: string,
18
+ channelIds: string[],
19
+ kind: 0 | 1 | 2,
20
+ missingPolicy: "skip" | "fail",
21
+ ): Promise<Array<Uint8Array | null | undefined>>;
22
+ save(
23
+ secretId: string,
24
+ channelId: string,
25
+ kind: 0 | 1 | 2,
26
+ value: Uint8Array,
27
+ ): Promise<void>;
28
+ remove(secretId: string, channelId: string, kind: 0 | 1 | 2): Promise<void>;
29
+ }
30
+
31
+ export interface ChannelStore {
32
+ load(secretId: string, channelId: string): Promise<Uint8Array | null | undefined>;
33
+ save(secretId: string, channelId: string, bytes: Uint8Array): Promise<void>;
34
+ listChannels(secretId: string): Promise<string[]>;
35
+ remove(secretId: string, channelId: string): Promise<boolean>;
36
+ linkChannel(
37
+ secretId: string,
38
+ channelId: string,
39
+ linkedChannelId: string,
40
+ ): Promise<void>;
41
+ linkedChannels(secretId: string, channelId: string): Promise<string[]>;
42
+ }
43
+
44
+ export interface Share {
45
+ secretId: string;
46
+ version: number;
47
+ bytes: Uint8Array;
48
+ }
49
+
50
+ export interface ShareStore {
51
+ load(secretId: string, channelId: string, versions: number[]): Promise<Share[]>;
52
+ loadMany(
53
+ secretId: string,
54
+ channelIds: string[],
55
+ versions: number[],
56
+ ): Promise<Share[]>;
57
+ loadAll(secretId: string, channelIds: string[]): Promise<Share[]>;
58
+ save(secretId: string, channelId: string, share: Share): Promise<void>;
59
+ latestVersion(secretId: string): Promise<number | null>;
60
+ removeChannel(secretId: string, channelId: string): Promise<void>;
61
+ }
62
+
63
+ export interface UserSecretEntry {
64
+ id: Uint8Array;
65
+ name: string;
66
+ data: Uint8Array;
67
+ }
68
+
69
+ export interface UserSecrets {
70
+ version: number;
71
+ secrets: UserSecretEntry[];
72
+ description?: string;
73
+ }
74
+
75
+ /**
76
+ * Persistence for the user-facing secret contents, keyed by `secretId`.
77
+ * One `secretId` maps to at most one stored snapshot — the most recent
78
+ * `start(ProtectSecret)` value. Read back by the pair-completion
79
+ * auto-publish hook so freshly-paired peers receive the current secret.
80
+ */
81
+ export interface UserSecretStore {
82
+ loadLatest(secretId: string): Promise<UserSecrets | null | undefined>;
83
+ saveLatest(secretId: string, value: UserSecrets): Promise<void>;
84
+ remove(secretId: string): Promise<void>;
85
+ }
86
+
87
+ /**
88
+ * In-flight orchestrator state persistence. The library treats item
89
+ * payloads as opaque JSON blobs — `save` writes the blob, `load`
90
+ * returns the exact blob it received, `remove` drops the row, and
91
+ * `loadAll` returns every blob whose `kind` matches the requested
92
+ * category (`0` = PendingVerification, `1` = PendingRecovery,
93
+ * `2` = PendingUnpair, `3` = SharingRound).
94
+ *
95
+ * Rows are keyed by `(secretId, StateKey)` — the `keyJson` buffer is
96
+ * a JSON object `{ kind, channel_id?, version? }` matching the `kind`
97
+ * numbering above. The library will `save`/`load`/`remove` under the
98
+ * same key across a session, so implementations can hash the entire
99
+ * `keyJson` buffer or unpack its fields (`kind` + `channel_id` +
100
+ * `version`) as the composite key.
101
+ *
102
+ * Save is full-replacement upsert — accumulator-style state
103
+ * (PendingRecovery and SharingRound) grows via load-modify-save cycles
104
+ * from the library; no per-row append primitive is required.
105
+ */
106
+ export interface StateStore {
107
+ save(secretId: string, itemJson: Uint8Array): Promise<void>;
108
+ load(
109
+ secretId: string,
110
+ keyJson: Uint8Array,
111
+ ): Promise<Uint8Array | null | undefined>;
112
+ remove(secretId: string, keyJson: Uint8Array): Promise<boolean>;
113
+ loadAll(secretId: string, kind: 0 | 1 | 2 | 3): Promise<Uint8Array[]>;
114
+ }
115
+
116
+ export interface Transport {
117
+ send(endpoint: { protocol: string; uri: string }, message: Uint8Array): Promise<void>;
118
+ }
119
+
120
+ export enum SenderKind {
121
+ Owner = 0,
122
+ Helper = 1,
123
+ ReplicaSource = 3,
124
+ ReplicaDestination = 4,
125
+ }
126
+
127
+ /**
128
+ * Selects how the initiator's public encryption material is delivered in a
129
+ * `ContactMessage`.
130
+ *
131
+ * - `InlineKeys` (default): keys are embedded in the contact itself.
132
+ * - `HashedKeys`: only a SHA-384 commitment to the keys is in the contact;
133
+ * the scanner must fetch the actual keys over the wire via the `PrePair`
134
+ * round-trip and verify them against the commitment before pairing.
135
+ * - `NoKeys`: no key material and no commitment. The contact carries only
136
+ * `channel_id`, `nonce`, and `transport_protocol` — small enough to be
137
+ * hand-typed or dictated. Keys are generated on the fly by the contact
138
+ * creator when the `PrePairRequest` arrives; the scanner accepts them
139
+ * without cryptographic verification. Trust rests entirely on the OOB
140
+ * delivery channel being fully trusted (e.g. a verified email from an
141
+ * already-KYC-authenticated institution). Applications MUST rate-limit
142
+ * inbound `PrePairRequest`s per channel and expire outstanding NoKeys
143
+ * contacts on a short timer.
144
+ */
145
+ export enum ContactMode {
146
+ InlineKeys = 0,
147
+ HashedKeys = 1,
148
+ NoKeys = 2,
149
+ }
150
+
151
+ export enum FlowKind {
152
+ Pairing = 0,
153
+ Discovery = 1,
154
+ ProtectSecret = 2,
155
+ VerifyShares = 3,
156
+ RecoverSecret = 4,
157
+ Unpair = 5,
158
+ UpdateChannelInfo = 6,
159
+ }
160
+
161
+ export type UnpairAck = "required" | "not_required";
162
+
163
+ export interface ContactMessage {
164
+ channel_id: bigint;
165
+ /** `ContactMode` numeric value (0 = INLINE_KEYS, 1 = HASHED_KEYS, 2 = NO_KEYS). */
166
+ contact_mode: number;
167
+ transport_protocol?: TransportProtocol;
168
+ nonce: bigint;
169
+ /** Present only when `contact_mode === ContactMode.InlineKeys`. */
170
+ mlkem_encapsulation_key?: Uint8Array;
171
+ /** Present only when `contact_mode === ContactMode.InlineKeys`. */
172
+ ecies_public_key?: Uint8Array;
173
+ /** Present only when `contact_mode === ContactMode.HashedKeys`. SHA-384 digest (48 bytes). */
174
+ contact_binding_hash?: Uint8Array;
175
+ timestamp?: Timestamp;
176
+ }
177
+
178
+ export interface UserSecret {
179
+
180
+ id: Uint8Array;
181
+ name: string;
182
+ data: Uint8Array;
183
+ }
184
+
185
+ export type Target = bigint | bigint[] | null;
186
+
187
+ export interface PairingParams {
188
+ kind: SenderKind;
189
+ contact: ContactMessage;
190
+
191
+ peerCommunicationInfo?: Record<string, string>;
192
+ }
193
+ export interface DiscoveryParams {
194
+ target?: Target;
195
+ }
196
+ export interface ProtectSecretParams {
197
+ secrets: UserSecret[];
198
+ description?: string;
199
+ }
200
+ export interface VerifySharesParams {
201
+ secretId: bigint | string;
202
+ version: number;
203
+ target?: Target;
204
+ }
205
+ export interface RecoverSecretParams {
206
+
207
+ secretId: bigint | string;
208
+ version: number;
209
+ }
210
+ export interface UnpairParams {
211
+ channel_id: string;
212
+
213
+ memo?: string;
214
+ }
215
+ export interface UpdateChannelInfoParams {
216
+ target?: Target;
217
+
218
+ /** New communication-info map. `null`/absent leaves the peer's stored
219
+ * map untouched; pass an empty object to clear it. */
220
+ communication_info?: Record<string, string>;
221
+
222
+ /** New transport endpoint. Absent leaves it untouched. */
223
+ transport_protocol?: { uri: string; protocol: number };
224
+ }
225
+
226
+ export type DeRecEvent =
227
+ | {
228
+ type: "PairingCompleted";
229
+ /** Long-term `channel_id` both peers atomically rotated to at handshake completion. */
230
+ channel_id: string;
231
+ /** Transient `channel_id` used only during pairing (the one that traveled on the ContactMessage). No longer resolves in library state. */
232
+ pairing_channel_id: string;
233
+ kind: SenderKind;
234
+ peer_communication_info?: Record<string, string>;
235
+ }
236
+ | {
237
+ type: "ActionRequired";
238
+ channel_id: string;
239
+
240
+ action: Uint8Array;
241
+
242
+ action_kind: string;
243
+ peer_communication_info?: Record<string, string>;
244
+
245
+ sender_kind?: SenderKind;
246
+
247
+ version?: number;
248
+ share_description?: string;
249
+
250
+ share_secret_id?: string;
251
+ }
252
+ | { type: "ShareStored"; channel_id: string; version: number }
253
+ | { type: "ShareConfirmed"; channel_id: string; version: number }
254
+ | { type: "ShareRejected"; channel_id: string; version: number; status: number; memo: string }
255
+ | { type: "SharingComplete"; version: number; confirmed_count: number; failed_count: number; threshold_met: boolean }
256
+ | { type: "ShareVerified"; channel_id: string; version: number }
257
+ | {
258
+ type: "SecretsDiscovered";
259
+ channel_id: string;
260
+
261
+ secrets: Array<{ secret_id: string; versions: Array<{ version: number; description: string }> }>;
262
+ }
263
+ | { type: "RecoveryShareReceived"; channel_id: string; shares_received: number }
264
+ | { type: "RecoveryShareError"; channel_id: string; shares_received: number; error: string }
265
+ /** Recovery completed — the typed `Secret` snapshot the owner
266
+ * originally protected. Mirrors `ReplicaSecretReceived.secret`:
267
+ * `secrets` is the user-facing `Vec<UserSecret>` the application
268
+ * fed to `start(FlowKind.ProtectSecret)`; `helpers`, `replicas`
269
+ * and `owner_replica_id` are the roster snapshot captured at
270
+ * distribution time. The library handles the two-stage
271
+ * `DeRecSecret` → `Secret` protobuf decode internally. */
272
+ | {
273
+ type: "SecretRecovered";
274
+ secret: {
275
+ helpers: Array<{
276
+ channel_id: string;
277
+ transport_uri: string;
278
+ shared_key: Uint8Array;
279
+ communication_info: Record<string, string>;
280
+ }>;
281
+ secrets: Array<{
282
+ id: Uint8Array;
283
+ name: string;
284
+ data: Uint8Array;
285
+ }>;
286
+ /** Replica composite. Absent when this `secret_id` has no
287
+ * replica setup. Carries the destination roster, the
288
+ * per-helper share map, and the 32-byte group key. Required
289
+ * by `restore` to rebuild replica channels without re-pairing. */
290
+ replicas?: {
291
+ replicas: Array<{
292
+ channel_id: string;
293
+ transport_uri: string;
294
+ communication_info: Record<string, string>;
295
+ replica_id: string;
296
+ sender_kind: number;
297
+ }>;
298
+ shared_key: Uint8Array;
299
+ };
300
+ owner_replica_id: string;
301
+ };
302
+ }
303
+
304
+ | { type: "Unpaired"; channel_id: string }
305
+
306
+ | { type: "UnpairRejected"; channel_id: string; status: number; memo: string }
307
+
308
+ /** Contact creator answered the scanner's `PrePairRequest` with a
309
+ * non-Ok status (HashedKeys flow). Distinct from a cryptographic
310
+ * hash mismatch, which surfaces as a thrown error from `process()`. */
311
+ | { type: "PrePairRejected"; channel_id: string; status: number; memo: string }
312
+
313
+ /** Fires alongside `PairingCompleted` on replica-mode pair handshakes.
314
+ * `peer_replica_id` is the peer's hex-encoded `u64` (matches the wire
315
+ * `derec.replica_id` representation). The local side's role
316
+ * (`ReplicaSource` vs `ReplicaDestination`) is on the persisted
317
+ * channel record — replica pairings are unidirectional, so there is
318
+ * no separate "role in pair" field. */
319
+ | {
320
+ type: "ReplicaPaired";
321
+ channel_id: string;
322
+ peer_replica_id: string;
323
+ }
324
+ /** A `ReplicaSource` peer pushed a secret sync on a
325
+ * `ReplicaDestination` channel. The library decoded the
326
+ * `ReplicaSecretPayload`; the app installs `secret.secrets` and
327
+ * optionally uses `shares` for recovery. `from_replica_id` and the
328
+ * `replica_id` fields inside `secret` are hex-encoded `u64`. */
329
+ | {
330
+ type: "ReplicaSecretReceived";
331
+ channel_id: string;
332
+ from_replica_id: string;
333
+ secret_id: string;
334
+ version: number;
335
+ secret: {
336
+ helpers: Array<{
337
+ channel_id: string;
338
+ transport_uri: string;
339
+ shared_key: Uint8Array;
340
+ communication_info: Record<string, string>;
341
+ }>;
342
+ secrets: Array<{
343
+ id: Uint8Array;
344
+ name: string;
345
+ data: Uint8Array;
346
+ }>;
347
+ /** Replica composite. Absent when this `secret_id` has no
348
+ * replica setup. The same shape as `SecretRecovered.secret.replicas`. */
349
+ replicas?: {
350
+ replicas: Array<{
351
+ channel_id: string;
352
+ transport_uri: string;
353
+ communication_info: Record<string, string>;
354
+ replica_id: string;
355
+ sender_kind: number;
356
+ }>;
357
+ shared_key: Uint8Array;
358
+ };
359
+ owner_replica_id: string;
360
+ };
361
+ shares: Array<{
362
+ channel_id: string;
363
+ committed_share: Uint8Array;
364
+ }>;
365
+ }
366
+ /** Peer's ack of a secret sync we sent. `status` is the `StatusEnum`
367
+ * integer (0 = Ok), `memo` is the peer's explanation. */
368
+ | {
369
+ type: "ReplicaSecretAcked";
370
+ channel_id: string;
371
+ from_replica_id: string;
372
+ secret_id: string;
373
+ version: number;
374
+ status: number;
375
+ memo: string;
376
+ }
377
+ /** A peer announced an updated `communication_info` map and/or
378
+ * transport endpoint via `start(FlowKind.UpdateChannelInfo)`.
379
+ * Surfaces on both sides — the initiator sees its own update echo
380
+ * back after the responder accepts. */
381
+ | {
382
+ type: "ChannelInfoUpdated";
383
+ channel_id: string;
384
+ }
385
+ /** The peer answered our outbound `UpdateChannelInfo` with a
386
+ * non-`Ok` status. Local state is not rolled back — the app decides
387
+ * whether to retry. */
388
+ | {
389
+ type: "ChannelInfoUpdateRejected";
390
+ channel_id: string;
391
+ status: number;
392
+ memo: string;
393
+ }
394
+ /** Emitted by `process()` in place of `ActionRequired` when the
395
+ * configured {@link AutoAcceptPolicy} opts in to the inbound
396
+ * action's flow. The same event vec carries the flow's completion
397
+ * events (e.g. `ShareStored`, `PairingCompleted`). Use this purely
398
+ * for observability — no further action is required. `action_kind`
399
+ * is the same label vocabulary as `ActionRequired.action_kind`
400
+ * (`"Pairing"`, `"StoreShare"`, …). */
401
+ | { type: "AutoAccepted"; channel_id: string; action_kind: string }
402
+ | { type: "NoOp" }
403
+ /** A pairing handshake was dispatched successfully. `kind` is the
404
+ * local party's role — same value the subsequent `PairingCompleted`
405
+ * will carry. Emitted by `start(Pairing)`. */
406
+ | { type: "PairingStarted"; channel_id: string; kind: SenderKind }
407
+ /** A discovery request was dispatched to `channel_id`. Emitted per
408
+ * targeted helper by `start(Discovery)`. */
409
+ | { type: "DiscoveryStarted"; channel_id: string }
410
+ /** A discovery request could not be dispatched to `channel_id`. Other
411
+ * targeted channels are unaffected. */
412
+ | { type: "DiscoveryFailed"; channel_id: string; error: string }
413
+ /** A share-storage request was dispatched to `channel_id`. Emitted per
414
+ * targeted peer by `start(ProtectSecret)`. */
415
+ | { type: "ProtectSecretStarted"; channel_id: string; version: number }
416
+ /** A share-storage request could not be dispatched to `channel_id`. */
417
+ | {
418
+ type: "ProtectSecretFailed";
419
+ channel_id: string;
420
+ version: number;
421
+ error: string;
422
+ }
423
+ /** A verify-share challenge was dispatched to `channel_id`. */
424
+ | { type: "VerifySharesStarted"; channel_id: string; version: number }
425
+ /** A verify-share challenge could not be dispatched to `channel_id`. */
426
+ | {
427
+ type: "VerifySharesFailed";
428
+ channel_id: string;
429
+ version: number;
430
+ error: string;
431
+ }
432
+ /** A recovery share request was dispatched to `channel_id`. */
433
+ | { type: "RecoverSecretStarted"; channel_id: string; version: number }
434
+ /** A recovery share request could not be dispatched to `channel_id`. */
435
+ | {
436
+ type: "RecoverSecretFailed";
437
+ channel_id: string;
438
+ version: number;
439
+ error: string;
440
+ }
441
+ /** An unpair request was dispatched to `channel_id`. Followed by an
442
+ * `Unpaired` event once the peer acknowledges (or in the same event
443
+ * vec, under `UnpairAck.NotRequired`). */
444
+ | { type: "UnpairStarted"; channel_id: string }
445
+ /** An update-channel-info request was dispatched to `channel_id`. */
446
+ | { type: "UpdateChannelInfoStarted"; channel_id: string }
447
+ /** An update-channel-info request could not be dispatched to
448
+ * `channel_id`. */
449
+ | { type: "UpdateChannelInfoFailed"; channel_id: string; error: string };
450
+
451
+ /**
452
+ * Per-flow auto-accept policy. When a field is `true`, `process()`
453
+ * internally accepts the matching inbound request and emits
454
+ * `AutoAccepted` in place of `ActionRequired`. Every field defaults
455
+ * to `false`.
456
+ *
457
+ * Per-field caveats (read before enabling in production):
458
+ * - `pairing` — covers standard and replica pairing. Replica pairing
459
+ * remains `Pending` until both sides run `verifyFingerprint()`, so
460
+ * auto-accept is safe for replicas. Standard pairing transitions to
461
+ * `Paired` immediately.
462
+ * - `prePair` — turns the initiator into a request-amplification
463
+ * oracle. Anyone who knows a HashedKeys contact's nonce can elicit a
464
+ * key-publish response. Keep off unless you control both ends of
465
+ * the transport.
466
+ * - `unpair` — destructive. Accepting deletes the local channel
467
+ * record before any UI confirmation.
468
+ * - `updateChannelInfo` — silently overwrites the channel record with
469
+ * the peer's announced transport / communication info.
470
+ */
471
+ export interface AutoAcceptPolicy {
472
+ pairing?: boolean;
473
+ prePair?: boolean;
474
+ storeShare?: boolean;
475
+ verifyShare?: boolean;
476
+ discovery?: boolean;
477
+ getShare?: boolean;
478
+ unpair?: boolean;
479
+ updateChannelInfo?: boolean;
480
+ }
481
+
482
+ /**
483
+ * Fluent builder for {@link DeRecProtocol}. Mirrors the Rust
484
+ * `DeRecProtocolBuilder` and the dotnet `DeRecProtocolBuilder`
485
+ * method-for-method so a developer who already knows one SDK can move
486
+ * between them without reaching for reference docs.
487
+ *
488
+ * Required setters: `withChannelStore`, `withShareStore`,
489
+ * `withSecretStore`, `withTransport`, `withOwnTransport`. Calling
490
+ * `build()` without all five throws.
491
+ */
492
+ export declare class DeRecProtocolBuilder {
493
+ /**
494
+ * Construct a builder bound to a specific secret. `secretId`
495
+ * identifies the single secret this protocol instance manages.
496
+ * Apps that juggle multiple secrets instantiate one
497
+ * {@link DeRecProtocol} per id.
498
+ */
499
+ constructor(secretId: bigint | number);
500
+
501
+ withChannelStore(store: ChannelStore): DeRecProtocolBuilder;
502
+ withShareStore(store: ShareStore): DeRecProtocolBuilder;
503
+ withSecretStore(store: SecretStore): DeRecProtocolBuilder;
504
+ withUserSecretStore(store: UserSecretStore): DeRecProtocolBuilder;
505
+ withStateStore(store: StateStore): DeRecProtocolBuilder;
506
+ withTransport(transport: Transport): DeRecProtocolBuilder;
507
+ withOwnTransport(endpoint: { uri: string; protocol: string }): DeRecProtocolBuilder;
508
+
509
+ /** Default: 3. */
510
+ withThreshold(threshold: number): DeRecProtocolBuilder;
511
+ /** Default: 3. */
512
+ withKeepVersionsCount(count: number): DeRecProtocolBuilder;
513
+ /** Seconds. Default: 300 (5 minutes). Clamped to at least 1. */
514
+ withTimeout(timeoutInSecs: number): DeRecProtocolBuilder;
515
+ /** Default: empty. */
516
+ withCommunicationInfo(info: Record<string, string>): DeRecProtocolBuilder;
517
+ /** Default: false. */
518
+ withAutoRespondOnFailure(enabled: boolean): DeRecProtocolBuilder;
519
+ /** Default: "required". */
520
+ withUnpairAck(ack: UnpairAck): DeRecProtocolBuilder;
521
+ /**
522
+ * When `true`, every outbound channel-mode request stamps
523
+ * `request.replyTo = ownTransport` so the responder routes its reply
524
+ * back here even if the channel's stored peer endpoint points
525
+ * elsewhere. Default: false.
526
+ */
527
+ withAutoReplyTo(enabled: boolean): DeRecProtocolBuilder;
528
+ /**
529
+ * Per-flow auto-accept policy. When a field is `true`, `process()`
530
+ * internally accepts the matching inbound request and emits
531
+ * `AutoAccepted` in place of `ActionRequired`. See
532
+ * {@link AutoAcceptPolicy} for per-field caveats.
533
+ *
534
+ * Default: empty policy (every flow off).
535
+ */
536
+ withAutoAccept(policy: AutoAcceptPolicy): DeRecProtocolBuilder;
537
+ /**
538
+ * Stable per-device replica id. Required to participate in any
539
+ * `ReplicaSource` / `ReplicaDestination` pairing. The id must be
540
+ * stable across restarts. Default: unset.
541
+ */
542
+ withReplicaId(id: bigint | number): DeRecProtocolBuilder;
543
+
544
+ /**
545
+ * Finalize the configuration. Throws if any of the required setters
546
+ * was not called.
547
+ */
548
+ build(): DeRecProtocol;
549
+ }
550
+
551
+ export declare class DeRecProtocol {
552
+ /** Use {@link DeRecProtocolBuilder} to construct instances. */
553
+ private constructor();
554
+
555
+ /** The secret identifier this protocol instance is bound to. */
556
+ secretId(): bigint;
557
+
558
+ /**
559
+ * Generate an out-of-band contact message used to bootstrap pairing.
560
+ *
561
+ * @param channelId Optional channel identifier. Pass `null` /
562
+ * `undefined` to have the library generate one.
563
+ * @param contactMode `ContactMode.InlineKeys` embeds the public keys
564
+ * directly in the contact. `ContactMode.HashedKeys`
565
+ * embeds only a SHA-384 binding hash (keys are
566
+ * fetched later via the `PrePair` round-trip).
567
+ * `HashedKeys` requires `ownTransportUri` to be
568
+ * ephemeral.
569
+ */
570
+ /**
571
+ * Single entry point for all three `ContactMode` variants.
572
+ *
573
+ * @param channelId `null`/`undefined` lets the library mint a random id.
574
+ * @param contactMode `InlineKeys` embeds keys directly; `HashedKeys`
575
+ * embeds only a SHA-384 commitment (keys fetched via `PrePair`);
576
+ * `NoKeys` carries no key material — the creator generates keys on the
577
+ * fly when the `PrePairRequest` arrives. Only appropriate for `NoKeys`
578
+ * when the OOB delivery channel is fully trusted.
579
+ * @param nonce `null`/`undefined` lets the library generate a fresh
580
+ * random `bigint`. Required for `NoKeys` where callers typically pick
581
+ * a small human-typable value.
582
+ */
583
+ createContact(
584
+ channelId: bigint | null | undefined,
585
+ contactMode: ContactMode,
586
+ nonce?: bigint | null,
587
+ ): Promise<ContactMessage>;
588
+
589
+ start(flowKind: FlowKind.Pairing, params: PairingParams): Promise<DeRecEvent[]>;
590
+ start(flowKind: FlowKind.Discovery, params: DiscoveryParams): Promise<DeRecEvent[]>;
591
+ start(flowKind: FlowKind.ProtectSecret, params: ProtectSecretParams): Promise<DeRecEvent[]>;
592
+ start(flowKind: FlowKind.VerifyShares, params: VerifySharesParams): Promise<DeRecEvent[]>;
593
+ start(flowKind: FlowKind.RecoverSecret, params: RecoverSecretParams): Promise<DeRecEvent[]>;
594
+ start(flowKind: FlowKind.Unpair, params: UnpairParams): Promise<DeRecEvent[]>;
595
+ start(flowKind: FlowKind.UpdateChannelInfo, params: UpdateChannelInfoParams): Promise<DeRecEvent[]>;
596
+
597
+ /**
598
+ * Replace this node's local <c>communication_info</c> map. Does not
599
+ * contact peers — follow up with
600
+ * <c>start(FlowKind.UpdateChannelInfo, ...)</c> to propagate.
601
+ */
602
+ setCommunicationInfo(info: Record<string, string>): void;
603
+
604
+ /**
605
+ * Replace this node's local transport endpoint. IMPORTANT: keep the
606
+ * old endpoint operational during the changeover (see the Rust docs
607
+ * on the matching setter for the discipline).
608
+ */
609
+ setOwnTransport(uri: string, protocol: string): void;
610
+
611
+ process(message: Uint8Array): Promise<DeRecEvent[]>;
612
+
613
+ accept(actionBytes: Uint8Array): Promise<DeRecEvent[]>;
614
+
615
+ reject(actionBytes: Uint8Array, status: number, memo: string): Promise<void>;
616
+
617
+ /**
618
+ * Derive the human-readable fingerprint for a paired channel. Both sides
619
+ * of a replica pair compute the same fingerprint from the shared key —
620
+ * users compare them out of band before calling `verifyFingerprint`.
621
+ */
622
+ getFingerprint(channelId: bigint | number): Promise<string>;
623
+
624
+ /**
625
+ * Verify `fingerprint` against the channel's locally-derived one. On
626
+ * match, the channel transitions from `Pending` to `Paired`. Returns
627
+ * `true` on confirmation, `false` on mismatch.
628
+ */
629
+ verifyFingerprint(channelId: bigint | number, fingerprint: string): Promise<boolean>;
630
+
631
+ /**
632
+ * Rebuild this protocol's `secret_id` namespace from a recovered
633
+ * `Secret`. Mirrors the Rust `DeRecProtocol::restore` — pass the
634
+ * typed `secret` carried by the `SecretRecovered` event verbatim.
635
+ *
636
+ * Errors surface as structured objects with a `code` field:
637
+ *
638
+ * | code | meaning |
639
+ * |--------------------|------------------------------------------------------------------|
640
+ * | `ALREADY_RESTORED` | A user-secret snapshot already exists for this `secret_id`. |
641
+ * | `CONFLICT` | Channels live at canonical helper / replica ids. The error |
642
+ * | | carries `channel_ids: string[]` listing the collisions. |
643
+ * | `INVARIANT` | The recovered `Secret` is internally inconsistent. |
644
+ * | `STORAGE` | A store I/O call failed mid-restore. |
645
+ */
646
+ restore(
647
+ recoveredSecret: Extract<DeRecEvent, { type: "SecretRecovered" }>["secret"],
648
+ version: number,
649
+ ): Promise<DeRecEvent[]>;
650
+ }
651
+
652
+ /**
653
+ * Envelope-level helpers that operate on raw `DeRecMessage` bytes without
654
+ * touching the encrypted inner payload. Useful for primitive-only consumers
655
+ * that need to set or read the `traceId` correlation token themselves
656
+ * (`DeRecProtocol` handles trace_id end-to-end automatically).
657
+ */
658
+ export declare const envelope: {
659
+ /**
660
+ * Re-stamp `traceId` on an outbound envelope. Returns the re-encoded
661
+ * bytes. The encrypted inner message is untouched.
662
+ */
663
+ apply_trace_id(envelope_bytes: Uint8Array, trace_id: bigint): Uint8Array;
664
+
665
+ /**
666
+ * Read `traceId` off an inbound envelope. Returns `0n` when unset (the
667
+ * protobuf default is indistinguishable from an explicit zero).
668
+ */
669
+ read_trace_id(envelope_bytes: Uint8Array): bigint;
670
+ };
671
+
672
+ export interface Timestamp {
673
+
674
+ seconds: bigint;
675
+ nanos: number;
676
+ }
677
+
678
+ export interface DeRecResult {
679
+ status: number;
680
+ memo: string;
681
+ }
682
+
683
+ export interface GetSecretIdsVersionsRequestMessage {
684
+ timestamp?: Timestamp;
685
+ /** Ephemeral endpoint where the requester wants the response routed.
686
+ * Absent means "use the channel's stored peer endpoint". */
687
+ reply_to?: TransportProtocol;
688
+ }
689
+
690
+ export interface VersionList {
691
+ secret_id: bigint;
692
+ versions: VersionListEntry[];
693
+ }
694
+
695
+ export interface VersionListEntry {
696
+ version: number;
697
+ version_description: string;
698
+ }
699
+
700
+ export interface GetSecretIdsVersionsResponseMessage {
701
+ result?: DeRecResult;
702
+ secret_list: VersionList[];
703
+ timestamp?: Timestamp;
704
+ }
705
+
706
+ export interface VersionEntry {
707
+ version: number;
708
+ description: string;
709
+ }
710
+
711
+ export interface SecretVersionEntry {
712
+ secret_id: bigint;
713
+ versions: VersionEntry[];
714
+ }
715
+
716
+ export interface TransportProtocol {
717
+ uri: string;
718
+
719
+ protocol: number;
720
+ }
721
+
722
+ export interface CommunicationInfoKeyValue {
723
+ key: string;
724
+ string_value: string | null;
725
+ bytes_value: Uint8Array | null;
726
+ }
727
+
728
+ export interface CommunicationInfo {
729
+ communication_info_entries: CommunicationInfoKeyValue[];
730
+ }
731
+
732
+ // `ContactMessage` is defined once above (line ~87) and covers both
733
+ // `INLINE_KEYS` and `HASHED_KEYS` modes.
734
+
735
+
736
+ export interface ParameterRange {
737
+ min_share_size: bigint;
738
+ max_share_size: bigint;
739
+ min_time_between_verifications: bigint;
740
+ max_time_between_verifications: bigint;
741
+ min_time_between_share_updates: bigint;
742
+ max_time_between_share_updates: bigint;
743
+ min_unresponsive_deletion_timeout: bigint;
744
+ max_unresponsive_deletion_timeout: bigint;
745
+ min_unresponsive_deactivation_timeout: bigint;
746
+ max_unresponsive_deactivation_timeout: bigint;
747
+ }
748
+
749
+ export interface PairRequestMessage {
750
+ sender_kind: number;
751
+ mlkem_ciphertext: Uint8Array;
752
+ ecies_public_key: Uint8Array;
753
+ nonce: bigint;
754
+ communication_info?: CommunicationInfo;
755
+ parameter_range?: ParameterRange;
756
+ transport_protocol?: TransportProtocol;
757
+ timestamp?: Timestamp;
758
+ }
759
+
760
+ export interface PairResponseMessage {
761
+ result?: DeRecResult;
762
+ nonce: bigint;
763
+ communication_info?: CommunicationInfo;
764
+ parameter_range?: ParameterRange;
765
+ timestamp?: Timestamp;
766
+ /**
767
+ * Post-handshake rekey channel id. Both sides switch their local channel
768
+ * record to this value once the response is accepted. Derived by the
769
+ * responder as `SHA-384(u64_be(originalChannelId) || sharedKey)[..8]`
770
+ * interpreted as big-endian `u64`, and validated by the requester against
771
+ * its own derivation. Zero on rejection (non-Ok `result.status`).
772
+ */
773
+ channel_id: bigint;
774
+ }
775
+
776
+ export interface PrePairRequestMessage {
777
+ nonce: bigint;
778
+ transport_protocol?: TransportProtocol;
779
+ timestamp?: Timestamp;
780
+ }
781
+
782
+ export interface PrePairResponseMessage {
783
+ result?: DeRecResult;
784
+ /** Present only when `result.status === Ok`. */
785
+ mlkem_encapsulation_key?: Uint8Array;
786
+ /** Present only when `result.status === Ok`. */
787
+ ecies_public_key?: Uint8Array;
788
+ nonce: bigint;
789
+ timestamp?: Timestamp;
790
+ }
791
+
792
+ export interface GetShareRequestMessage {
793
+ secret_id: bigint;
794
+ version: number;
795
+ timestamp?: Timestamp;
796
+ /** Ephemeral response endpoint; see `replyTo` semantics. */
797
+ reply_to?: TransportProtocol;
798
+ }
799
+
800
+ export interface GetShareResponseMessage {
801
+ share_algorithm: number;
802
+
803
+ committed_de_rec_share: Uint8Array;
804
+ result?: DeRecResult;
805
+ timestamp?: Timestamp;
806
+ /** Echoed from the request so the Owner can correlate responses across
807
+ * concurrent recoveries without inspecting the share bytes. */
808
+ secret_id: bigint;
809
+ /** Echoed from the request for the same correlation reasons as `secret_id`. */
810
+ version: number;
811
+ }
812
+
813
+ export interface SiblingHash {
814
+ is_left: boolean;
815
+ hash: Uint8Array;
816
+ }
817
+
818
+ export interface CommittedDeRecShare {
819
+
820
+ de_rec_share: Uint8Array;
821
+ commitment: Uint8Array;
822
+ merkle_path: SiblingHash[];
823
+ }
824
+
825
+ export interface StoreShareRequestMessage {
826
+
827
+ share: Uint8Array;
828
+ share_algorithm: number;
829
+ version: number;
830
+ keep_list: number[];
831
+ version_description: string;
832
+ timestamp?: Timestamp;
833
+ secret_id: bigint;
834
+ /** Ephemeral response endpoint; see `replyTo` semantics. */
835
+ reply_to?: TransportProtocol;
836
+ }
837
+
838
+ export interface StoreShareResponseMessage {
839
+ result?: DeRecResult;
840
+ version: number;
841
+ timestamp?: Timestamp;
842
+ secret_id: bigint;
843
+ }
844
+
845
+ export interface UnpairRequestMessage {
846
+ memo: string;
847
+ timestamp?: Timestamp;
848
+ /** Ephemeral response endpoint; see `replyTo` semantics. */
849
+ reply_to?: TransportProtocol;
850
+ }
851
+
852
+ export interface UnpairResponseMessage {
853
+ result?: DeRecResult;
854
+ timestamp?: Timestamp;
855
+ }
856
+
857
+ export interface VerifyShareRequestMessage {
858
+ secret_id: bigint;
859
+ version: number;
860
+ nonce: bigint;
861
+ timestamp?: Timestamp;
862
+ /** Ephemeral response endpoint; see `replyTo` semantics. */
863
+ reply_to?: TransportProtocol;
864
+ }
865
+
866
+ export interface VerifyShareResponseMessage {
867
+ result?: DeRecResult;
868
+ secret_id: bigint;
869
+ version: number;
870
+ nonce: bigint;
871
+ hash: Uint8Array;
872
+ timestamp?: Timestamp;
873
+ }
874
+
875
+ export interface ProduceResult {
876
+
877
+ envelope: Uint8Array;
878
+ }
879
+
880
+ export interface SharingResponseProduceResult extends ProduceResult {
881
+ committed_share: CommittedDeRecShare;
882
+ secret_id: bigint;
883
+ version: number;
884
+ }
885
+
886
+ export interface CreateContactResult {
887
+ contact_message: ContactMessage;
888
+
889
+ secret_key: Uint8Array;
890
+ }
891
+
892
+ export interface PairingRequestProduceResult extends ProduceResult {
893
+ initiator_contact_message: ContactMessage;
894
+
895
+ secret_key: Uint8Array;
896
+ }
897
+
898
+ export interface PairingResponseProduceResult extends ProduceResult {
899
+ peer_transport_protocol: TransportProtocol;
900
+
901
+ shared_key: Uint8Array;
902
+
903
+ /**
904
+ * Post-handshake rekey channel id the responder is committing to.
905
+ * Callers MUST atomically rename their local channel record from the
906
+ * pre-rekey id (the one passed to `pairing.response.produce`) to this
907
+ * value as part of accepting the response.
908
+ */
909
+ channel_id: bigint;
910
+ }
911
+
912
+ export interface PairingProcessResult {
913
+
914
+ shared_key: Uint8Array;
915
+
916
+ /**
917
+ * Post-handshake rekey channel id — already validated against the
918
+ * caller's own derivation. Callers MUST atomically rename their local
919
+ * channel record from the pre-rekey id (the one in the contact) to this
920
+ * value.
921
+ */
922
+ channel_id: bigint;
923
+ }
924
+
925
+ export interface ProducePrePairResult {
926
+
927
+ envelope: Uint8Array;
928
+ }
929
+
930
+ export interface PrePairRequestExtractResult {
931
+
932
+ request: PrePairRequestMessage;
933
+ }
934
+
935
+ export interface PrePairResponseExtractResult {
936
+
937
+ response: PrePairResponseMessage;
938
+ }
939
+
940
+ export interface ProcessPrePairResult {
941
+
942
+ /** Initiator's ML-KEM-768 encapsulation key, validated against the
943
+ * contact's `contactBindingHash`. */
944
+ mlkem_encapsulation_key: Uint8Array;
945
+
946
+ /** Initiator's ECIES public key, validated against the contact's
947
+ * `contactBindingHash`. */
948
+ ecies_public_key: Uint8Array;
949
+
950
+ /** Nonce echoed from the original `ContactMessage`. */
951
+ nonce: bigint;
952
+ }
953
+
954
+ export interface SplitResult {
955
+ /** Map keyed by channel id (`bigint`). */
956
+ shares: Map<bigint, CommittedDeRecShare>;
957
+ }
958
+
959
+ export interface RecoverResult {
960
+ secret_data: Uint8Array;
961
+ }
962
+
963
+ export interface UnpairingProcessResult {
964
+ acknowledged: boolean;
965
+ }
966
+
967
+ export interface DiscoveryProcessResult {
968
+ secret_list: SecretVersionEntry[];
969
+ }
970
+
971
+ export type DeRecErrorCategory =
972
+ | "pairing"
973
+ | "recovery"
974
+ | "discovery"
975
+ | "sharing"
976
+ | "verification"
977
+ | "unpairing"
978
+ | "derec_message"
979
+ | "secret_store"
980
+ | "channel_store"
981
+ | "share_store"
982
+ | "input"
983
+ | "protobuf"
984
+ | "invariant"
985
+ | "wasm";
986
+
987
+ export interface DeRecError {
988
+ category: DeRecErrorCategory;
989
+ code: string;
990
+ message: string;
991
+ status?: number;
992
+ memo?: string;
993
+ expected?: number;
994
+ got?: number;
995
+ }
996
+
997
+ export declare const primitives: {
998
+ discovery: {
999
+ request: {
1000
+ /**
1001
+ * @param reply_to Optional ephemeral response endpoint. `null` /
1002
+ * `undefined` means "no override" (the responder
1003
+ * routes to the channel's stored peer endpoint).
1004
+ */
1005
+ produce(
1006
+ channel_id: bigint,
1007
+ shared_key: Uint8Array,
1008
+ reply_to?: TransportProtocol | null,
1009
+ ): ProduceResult;
1010
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { request: GetSecretIdsVersionsRequestMessage };
1011
+ };
1012
+ response: {
1013
+ produce(channel_id: bigint, secret_list: SecretVersionEntry[], shared_key: Uint8Array): ProduceResult;
1014
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { response: GetSecretIdsVersionsResponseMessage };
1015
+ process(response: GetSecretIdsVersionsResponseMessage): DiscoveryProcessResult;
1016
+ };
1017
+ };
1018
+ pairing: {
1019
+ request: {
1020
+ /**
1021
+ * Creates an out-of-band `ContactMessage` to bootstrap pairing.
1022
+ *
1023
+ * @param channel_id Identifier for the local pairing session.
1024
+ * @param contact_mode `ContactMode.InlineKeys` embeds the keys directly;
1025
+ * `ContactMode.HashedKeys` embeds only a SHA-384
1026
+ * commitment and the scanner must complete a
1027
+ * `PrePair` round-trip first.
1028
+ * @param transport_protocol Endpoint the scanner uses to talk back. For
1029
+ * `HashedKeys` mode it MUST be ephemeral.
1030
+ */
1031
+ create_contact(
1032
+ channel_id: bigint,
1033
+ contact_mode: ContactMode | number,
1034
+ transport_protocol: TransportProtocol,
1035
+ ): CreateContactResult;
1036
+ encode_contact(contact_message: ContactMessage): Uint8Array;
1037
+ decode_contact(bytes: Uint8Array): ContactMessage;
1038
+ produce(
1039
+ kind: SenderKind,
1040
+ transport_protocol: TransportProtocol,
1041
+ contact_message: ContactMessage,
1042
+ communication_info: CommunicationInfo | null,
1043
+ parameter_range: ParameterRange | null,
1044
+ ): PairingRequestProduceResult;
1045
+
1046
+ extract(envelope_bytes: Uint8Array, secret_key: Uint8Array): { request: PairRequestMessage };
1047
+
1048
+ /**
1049
+ * Scanner-side: build a plaintext `PrePairRequest` envelope when the
1050
+ * contact was sent in `HashedKeys` mode. The keys obtained via the
1051
+ * matching `PrePairResponse` MUST be checked against the contact's
1052
+ * binding hash with `pairing.response.process_pre_pair` before
1053
+ * proceeding to a normal `produce`.
1054
+ */
1055
+ produce_pre_pair(
1056
+ transport_protocol: TransportProtocol,
1057
+ contact_message: ContactMessage,
1058
+ ): ProducePrePairResult;
1059
+
1060
+ /**
1061
+ * Initiator-side: decode an inbound plaintext `PrePairRequest`
1062
+ * envelope.
1063
+ */
1064
+ extract_pre_pair(envelope_bytes: Uint8Array): PrePairRequestExtractResult;
1065
+ };
1066
+ response: {
1067
+ produce(
1068
+ channel_id: bigint,
1069
+ request: PairRequestMessage,
1070
+ secret_key: Uint8Array,
1071
+ communication_info: CommunicationInfo | null,
1072
+ parameter_range: ParameterRange | null,
1073
+ ): PairingResponseProduceResult;
1074
+
1075
+ extract(envelope_bytes: Uint8Array, secret_key: Uint8Array): { response: PairResponseMessage };
1076
+ process(
1077
+ contact_message: ContactMessage,
1078
+ response: PairResponseMessage,
1079
+ secret_key: Uint8Array,
1080
+ ): PairingProcessResult;
1081
+
1082
+ /**
1083
+ * Contact-creator side: publish the actual public keys back to the
1084
+ * scanner in response to a `PrePairRequest`.
1085
+ */
1086
+ produce_pre_pair(
1087
+ channel_id: bigint,
1088
+ request: PrePairRequestMessage,
1089
+ secret_key: Uint8Array,
1090
+ ): ProducePrePairResult;
1091
+
1092
+ /**
1093
+ * Scanner-side: decode an inbound plaintext `PrePairResponse`
1094
+ * envelope.
1095
+ */
1096
+ extract_pre_pair(envelope_bytes: Uint8Array): PrePairResponseExtractResult;
1097
+
1098
+ /**
1099
+ * Scanner-side: validate the `PrePairResponse` against the contact's
1100
+ * SHA-384 binding hash. Returns the validated public keys + echoed
1101
+ * nonce on match; throws on mismatch.
1102
+ */
1103
+ process_pre_pair(
1104
+ contact_message: ContactMessage,
1105
+ response: PrePairResponseMessage,
1106
+ ): ProcessPrePairResult;
1107
+ };
1108
+ };
1109
+ recovery: {
1110
+ request: {
1111
+ produce(
1112
+ channel_id: bigint,
1113
+ secret_id: bigint,
1114
+ version: number,
1115
+ shared_key: Uint8Array,
1116
+ /** See `discovery.request.produce.reply_to`. */
1117
+ reply_to?: TransportProtocol | null,
1118
+ ): ProduceResult;
1119
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { request: GetShareRequestMessage };
1120
+ };
1121
+ response: {
1122
+ produce(
1123
+ channel_id: bigint,
1124
+ request: GetShareRequestMessage,
1125
+ stored_share_request: StoreShareRequestMessage,
1126
+ shared_key: Uint8Array,
1127
+ ): ProduceResult;
1128
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { response: GetShareResponseMessage };
1129
+ recover(secret_id: bigint, version: number, responses: GetShareResponseMessage[]): RecoverResult;
1130
+ };
1131
+ };
1132
+ sharing: {
1133
+ request: {
1134
+ split(
1135
+ channels: bigint[],
1136
+ secret_id: bigint,
1137
+ version: number,
1138
+ secret_data: Uint8Array,
1139
+ threshold: number,
1140
+ ): SplitResult;
1141
+ produce(
1142
+ channel_id: bigint,
1143
+ version: number,
1144
+ secret_id: bigint,
1145
+ committed_share: CommittedDeRecShare,
1146
+ keep_list: number[],
1147
+ description: string,
1148
+ shared_key: Uint8Array,
1149
+ /** See `discovery.request.produce.reply_to`. */
1150
+ reply_to?: TransportProtocol | null,
1151
+ ): ProduceResult;
1152
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { request: StoreShareRequestMessage };
1153
+ };
1154
+ response: {
1155
+ produce(
1156
+ channel_id: bigint,
1157
+ request: StoreShareRequestMessage,
1158
+ shared_key: Uint8Array,
1159
+ ): SharingResponseProduceResult;
1160
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { response: StoreShareResponseMessage };
1161
+ process(version: number, response: StoreShareResponseMessage): void;
1162
+ };
1163
+ };
1164
+ unpairing: {
1165
+ request: {
1166
+ produce(
1167
+ channel_id: bigint,
1168
+ memo: string,
1169
+ shared_key: Uint8Array,
1170
+ /** See `discovery.request.produce.reply_to`. */
1171
+ reply_to?: TransportProtocol | null,
1172
+ ): ProduceResult;
1173
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { request: UnpairRequestMessage };
1174
+ };
1175
+ response: {
1176
+ produce(channel_id: bigint, shared_key: Uint8Array): ProduceResult;
1177
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { response: UnpairResponseMessage };
1178
+ process(response: UnpairResponseMessage): UnpairingProcessResult;
1179
+ };
1180
+ };
1181
+ verification: {
1182
+ request: {
1183
+ produce(
1184
+ channel_id: bigint,
1185
+ secret_id: bigint,
1186
+ version: number,
1187
+ shared_key: Uint8Array,
1188
+ /** See `discovery.request.produce.reply_to`. */
1189
+ reply_to?: TransportProtocol | null,
1190
+ ): ProduceResult;
1191
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { request: VerifyShareRequestMessage };
1192
+ };
1193
+ response: {
1194
+ produce(
1195
+ channel_id: bigint,
1196
+ request: VerifyShareRequestMessage,
1197
+ shared_key: Uint8Array,
1198
+ share_content: Uint8Array,
1199
+ ): ProduceResult;
1200
+ extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): { response: VerifyShareResponseMessage };
1201
+
1202
+ /** `request` must be the request the owner previously produced
1203
+ * for this challenge (kept by the caller in a per-channel
1204
+ * pending-verification map). Responses whose
1205
+ * `(nonce, secret_id, version)` triple doesn't match are
1206
+ * rejected — that's the anti-replay gate. */
1207
+ process(
1208
+ request: VerifyShareRequestMessage,
1209
+ response: VerifyShareResponseMessage,
1210
+ share_content: Uint8Array,
1211
+ ): boolean;
1212
+ };
1213
+ };
1214
+ };