@derec-alliance/nodejs 0.0.4 → 0.0.6

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 CHANGED
@@ -9,15 +9,15 @@ export interface SecretStore {
9
9
  ): Promise<Uint8Array | null | undefined>;
10
10
  /**
11
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`.
12
+ * scoped to `secretId`. Must return an array with exactly one entry per
13
+ * input id, in the same order, using `null` (or `undefined`) for channels
14
+ * with no stored secret of `kind`. Whether a missing entry is an error is
15
+ * decided by the library.
15
16
  */
16
17
  loadMany(
17
18
  secretId: string,
18
19
  channelIds: string[],
19
20
  kind: 0 | 1 | 2,
20
- missingPolicy: "skip" | "fail",
21
21
  ): Promise<Array<Uint8Array | null | undefined>>;
22
22
  save(
23
23
  secretId: string,
@@ -123,22 +123,15 @@ export declare function channelFilterMatches(
123
123
  /**
124
124
  * The endpoints a peer-supplied message advertises, in the peer's own order.
125
125
  *
126
- * Yields `supported_transports` when it is non-empty, and otherwise the
127
- * singular `transport_protocol` — which is how every implementation predating
128
- * the offer list advertises, and the reason this is a function rather than a
129
- * field read. Reading `transport_protocol` directly is a bug: its meaning
130
- * narrowed to "one entry of a list, and possibly absent", so a peer that has
131
- * moved past it looks unreachable to a reader that was correct before 0.0.3.
132
- *
133
126
  * Reports what was advertised, not what is acceptable — nothing here is
134
127
  * validated, and the protocol still applies its own transport policy to
135
128
  * whatever it records.
136
129
  */
137
130
  export declare function advertisedEndpoints(
138
131
  message:
139
- | Pick<ContactMessage, "transport_protocol" | "supported_transports">
140
- | Pick<PairRequestMessage, "transport_protocol" | "supported_transports">
141
- | Pick<PrePairRequestMessage, "transport_protocol" | "supported_transports">
132
+ | Pick<ContactMessage, "supported_transports">
133
+ | Pick<PairRequestMessage, "supported_transports">
134
+ | Pick<PrePairRequestMessage, "supported_transports">
142
135
  | null
143
136
  | undefined,
144
137
  ): TransportProtocol[];
@@ -228,11 +221,7 @@ export interface ChannelStore {
228
221
  secretId: string,
229
222
  filter: ReplicaFilter,
230
223
  ): Promise<Uint8Array | null | undefined>;
231
- linkChannel(
232
- secretId: string,
233
- channelId: string,
234
- linkedChannelId: string,
235
- ): Promise<void>;
224
+ linkChannel(secretId: string, a: string, b: string): Promise<void>;
236
225
  linkedChannels(secretId: string, channelId: string): Promise<string[]>;
237
226
  }
238
227
 
@@ -242,6 +231,17 @@ export interface Share {
242
231
  bytes: Uint8Array;
243
232
  }
244
233
 
234
+ /**
235
+ * Share-record persistence.
236
+ *
237
+ * Rows are keyed by `(secretId, channelId, version)` where `secretId` is
238
+ * the partition passed to every method. `Share.secretId` is a different
239
+ * value: it names the secret the bytes belong to, which on a helper is
240
+ * the owner's id and routinely differs from the partition this device
241
+ * stores under. Key on the argument and carry `share.secretId` alongside
242
+ * as data — keying on it instead puts rows where no `load` looks, since
243
+ * every read filters on the partition.
244
+ */
245
245
  export interface ShareStore {
246
246
  load(secretId: string, channelId: string, versions: number[]): Promise<Share[]>;
247
247
  loadMany(
@@ -265,6 +265,10 @@ export interface UserSecrets {
265
265
  version: number;
266
266
  secrets: UserSecretEntry[];
267
267
  description?: string;
268
+ /** Decimal `replica_id` of the member that published `version`. Absent
269
+ * when none is recorded. Store and return it unchanged: replica members
270
+ * compare it to detect a conflicting copy of the same version. */
271
+ author_replica_id?: string;
268
272
  }
269
273
 
270
274
  /**
@@ -308,6 +312,18 @@ export interface StateStore {
308
312
  loadAll(secretId: string, kind: 0 | 1 | 2 | 3 | 4): Promise<Uint8Array[]>;
309
313
  }
310
314
 
315
+ /** A transport protocol, by name. */
316
+ export type TransportProtocolName = "https" | "grpc";
317
+
318
+ /**
319
+ * One endpoint a node serves or a peer advertised, as every app-facing call
320
+ * and event carries it.
321
+ */
322
+ export interface Endpoint {
323
+ uri: string;
324
+ protocol: TransportProtocolName;
325
+ }
326
+
311
327
  /**
312
328
  * Outbound message delivery.
313
329
  *
@@ -353,7 +369,7 @@ export interface Transport {
353
369
  * with {@link singleEndpointTransport} rather than by indexing.
354
370
  */
355
371
  send(
356
- endpoints: ReadonlyArray<{ protocol: string; uri: string }>,
372
+ endpoints: ReadonlyArray<Endpoint>,
357
373
  message: Uint8Array,
358
374
  ): Promise<void>;
359
375
  }
@@ -373,10 +389,25 @@ export interface Transport {
373
389
  * a round trip; skipping one that would have worked costs the delivery.
374
390
  */
375
391
  export type SendOne = (
376
- endpoint: { protocol: string; uri: string },
392
+ endpoint: Endpoint,
377
393
  message: Uint8Array,
378
394
  ) => Promise<void>;
379
395
 
396
+ /**
397
+ * The DeRec protocol version this build speaks — the `protocolVersionMajor` /
398
+ * `protocolVersionMinor` it writes into every envelope it produces. Not the
399
+ * package version.
400
+ */
401
+ export declare function protocol_version(): { major: number; minor: number };
402
+
403
+ /**
404
+ * A fresh replica identity, generated by the core — never `0`. Persist it
405
+ * once per device and pass the same value to `withReplicaId` on every
406
+ * protocol init: a device whose id changes cannot be re-identified by its
407
+ * group.
408
+ */
409
+ export declare function generate_replica_id(): bigint;
410
+
380
411
  /**
381
412
  * Builds a {@link Transport} that tries each endpoint in the order the peer
382
413
  * offered it and stops at the first success.
@@ -421,7 +452,7 @@ export enum SenderKind {
421
452
  * the scanner must fetch the actual keys over the wire via the `PrePair`
422
453
  * round-trip and verify them against the commitment before pairing.
423
454
  * - `NoKeys`: no key material and no commitment. The contact carries only
424
- * `channel_id`, `nonce`, and `transport_protocol` — small enough to be
455
+ * `channel_id`, `nonce`, and `supported_transports` — small enough to be
425
456
  * hand-typed or dictated. Keys are generated on the fly by the contact
426
457
  * creator when the `PrePairRequest` arrives; the scanner accepts them
427
458
  * without cryptographic verification. Trust rests entirely on the OOB
@@ -463,20 +494,33 @@ export enum FlowKind {
463
494
  UnpairReplica = 8,
464
495
  }
465
496
 
497
+ /** Result status carried in every protocol response (`result.proto`). Passed
498
+ * to `reject()` to say why an inbound request was refused. */
499
+ export enum StatusEnum {
500
+ Ok = 0,
501
+ Partial = 1,
502
+ Fail = 2,
503
+ SizeLimitExceeded = 3,
504
+ TooFrequent = 4,
505
+ UnknownSecretId = 5,
506
+ UnknownShareVersion = 6,
507
+ DecryptionFailed = 7,
508
+ VerificationFailed = 8,
509
+ FormatError = 9,
510
+ Rejected = 10,
511
+ IncompatibleParameterRange = 11,
512
+ UnsupportedTransportProtocol = 12,
513
+ VersionConflict = 13,
514
+ ReplicaIdConflict = 14,
515
+ RequestToClose = 99,
516
+ }
517
+
466
518
  export type UnpairAck = "required" | "not_required";
467
519
 
468
520
  export interface ContactMessage {
469
521
  channel_id: bigint;
470
522
  /** `ContactMode` numeric value (0 = INLINE_KEYS, 1 = HASHED_KEYS, 2 = NO_KEYS). */
471
523
  contact_mode: number;
472
- /**
473
- * @deprecated Reading this field directly is incorrect: its meaning narrowed
474
- * to "one entry of a list, and possibly absent", so a peer advertising only
475
- * `supported_transports` looks unreachable to a reader that was correct
476
- * before 0.0.3. Call {@link advertisedEndpoints}, which resolves both
477
- * spellings. Removed at 0.0.5.
478
- */
479
- transport_protocol?: TransportProtocol;
480
524
  nonce: bigint;
481
525
  /** Present only when `contact_mode === ContactMode.InlineKeys`. */
482
526
  mlkem_encapsulation_key?: Uint8Array;
@@ -486,8 +530,7 @@ export interface ContactMessage {
486
530
  contact_binding_hash?: Uint8Array;
487
531
  timestamp?: Timestamp;
488
532
  /** Every transport endpoint the creator of this contact can be reached
489
- * on, in its own preference order. Empty means "only
490
- * `transport_protocol` is offered". */
533
+ * on, in its own preference order. */
491
534
  supported_transports: TransportProtocol[];
492
535
  }
493
536
 
@@ -535,20 +578,11 @@ export interface UpdateChannelInfoParams {
535
578
  * map untouched; pass an empty object to clear it. */
536
579
  communication_info?: Record<string, string>;
537
580
 
538
- /**
539
- * New transport endpoint. Absent leaves it untouched.
540
- *
541
- * @deprecated Use `own_transports`, which carries every endpoint this node
542
- * now serves; its first entry also fills this field for peers predating the
543
- * list. Removed at 0.0.5.
544
- */
545
- transport_protocol?: { uri: string; protocol: number };
546
581
  /**
547
582
  * Every endpoint this node now serves, in its own preference order.
548
- * Omitted leaves the target(s)' stored set untouched. Takes precedence
549
- * over `transport_protocol`, whose first entry it also fills.
583
+ * Omitted leaves the target(s)' stored set untouched.
550
584
  */
551
- own_transports?: TransportProtocol[];
585
+ own_transports?: Endpoint[];
552
586
  }
553
587
 
554
588
  /**
@@ -607,18 +641,34 @@ export type DeRecEvent =
607
641
  action: Uint8Array;
608
642
 
609
643
  action_kind: PendingActionKind;
644
+ /** Correlation token of the inbound request, decimal-encoded. */
645
+ trace_id: string;
646
+ /** Pairing only. */
610
647
  peer_communication_info?: Record<string, string>;
611
-
648
+ /** `sender_kind` of the inbound pair request (Pairing only). */
612
649
  sender_kind?: SenderKind;
613
-
650
+ /** Share version (StoreShare / VerifyShare / GetShare). */
614
651
  version?: number;
652
+ /** Description of the secret version (StoreShare only). */
615
653
  share_description?: string;
616
-
654
+ /** Secret identifier, decimal-encoded (StoreShare / VerifyShare /
655
+ * GetShare). On GetShare, with `version`, names the requested share. */
617
656
  share_secret_id?: string;
657
+ /** Length in bytes of the share the helper would store (StoreShare
658
+ * only) — what a size or quota decision is made on. */
659
+ share_size?: number;
660
+ /** The peer's memo (Unpair only). */
661
+ unpair_memo?: string;
662
+ /** Communication info the peer replaces its stored map with
663
+ * (UpdateChannelInfo only). Absent: unchanged. Empty: cleared. */
664
+ updated_communication_info?: Record<string, string>;
665
+ /** Endpoints the peer is moving to (UpdateChannelInfo only). Absent:
666
+ * unchanged. */
667
+ updated_transports?: Endpoint[];
618
668
  }
619
669
  | { type: "ShareStored"; channel_id: string; version: number }
620
670
  | { type: "ShareConfirmed"; channel_id: string; version: number }
621
- | { type: "ShareRejected"; channel_id: string; version: number; status: number; memo: string }
671
+ | { type: "ShareRejected"; channel_id: string; version: number; status: StatusEnum; memo: string }
622
672
  /** A publishing round finished — every targeted helper confirmed,
623
673
  * rejected, or timed out.
624
674
  *
@@ -643,7 +693,7 @@ export type DeRecEvent =
643
693
  replica_id: string;
644
694
  secret_id: string;
645
695
  version: number;
646
- status: number;
696
+ status: StatusEnum;
647
697
  memo: string;
648
698
  }
649
699
  /** A secret sync could not be delivered to a member at all — distinct from
@@ -696,9 +746,9 @@ export type DeRecEvent =
696
746
  helpers: Array<{
697
747
  channel_id: string;
698
748
  /** Every endpoint this peer advertised, in the order it offered them. */
699
- transports: Array<{ uri: string; protocol: number }>;
749
+ transports: Endpoint[];
700
750
  shared_key: Uint8Array;
701
- communication_info: Record<string, string>;
751
+ communication_info?: Record<string, string>;
702
752
  }>;
703
753
  secrets: Array<{
704
754
  id: Uint8Array;
@@ -718,9 +768,9 @@ export type DeRecEvent =
718
768
  members: Array<{
719
769
  replica_id: string;
720
770
  /** Every endpoint this peer advertised, in the order it offered them. */
721
- transports: Array<{ uri: string; protocol: number }>;
771
+ transports: Endpoint[];
722
772
  role: "Source" | "Destination";
723
- communication_info: Record<string, string>;
773
+ communication_info?: Record<string, string>;
724
774
  }>;
725
775
  shared_key: Uint8Array;
726
776
  };
@@ -729,12 +779,12 @@ export type DeRecEvent =
729
779
 
730
780
  | { type: "Unpaired"; channel_id: string }
731
781
 
732
- | { type: "UnpairRejected"; channel_id: string; status: number; memo: string }
782
+ | { type: "UnpairRejected"; channel_id: string; status: StatusEnum; memo: string }
733
783
 
734
784
  /** Contact creator answered the scanner's `PrePairRequest` with a
735
785
  * non-Ok status (HashedKeys flow). Distinct from a cryptographic
736
786
  * hash mismatch, which surfaces as a thrown error from `process()`. */
737
- | { type: "PrePairRejected"; channel_id: string; status: number; memo: string }
787
+ | { type: "PrePairRejected"; channel_id: string; status: StatusEnum; memo: string }
738
788
 
739
789
  /** Fires alongside `PairingCompleted` on replica-mode pair handshakes.
740
790
  * `peer_replica_id` is the peer's `u64` as a **decimal** string,
@@ -752,22 +802,28 @@ export type DeRecEvent =
752
802
  /** A `ReplicaSource` peer pushed a secret sync on a
753
803
  * `ReplicaDestination` channel. The library decoded the
754
804
  * `ReplicaSecretPayload`; the app installs `secret.secrets` and
755
- * optionally uses `shares` for recovery. `from_replica_id` and the
756
- * `replica_id` fields inside `secret` are `u64` as **decimal**
757
- * strings. */
805
+ * optionally uses `shares` for recovery. `from_replica_id`,
806
+ * `author_replica_id` and the `replica_id` fields inside `secret` are
807
+ * `u64` as **decimal** strings.
808
+ *
809
+ * `from_replica_id` is the member this copy came from: the publisher on
810
+ * a push, the serving member on a catch-up. `author_replica_id` is the
811
+ * member that published `version`, or `null` when the serving member's
812
+ * snapshot records none. */
758
813
  | {
759
814
  type: "ReplicaSecretReceived";
760
815
  channel_id: string;
761
816
  from_replica_id: string;
817
+ author_replica_id: string | null;
762
818
  secret_id: string;
763
819
  version: number;
764
820
  secret: {
765
821
  helpers: Array<{
766
822
  channel_id: string;
767
823
  /** Every endpoint this peer advertised, in the order it offered them. */
768
- transports: Array<{ uri: string; protocol: number }>;
824
+ transports: Endpoint[];
769
825
  shared_key: Uint8Array;
770
- communication_info: Record<string, string>;
826
+ communication_info?: Record<string, string>;
771
827
  }>;
772
828
  secrets: Array<{
773
829
  id: Uint8Array;
@@ -785,9 +841,9 @@ export type DeRecEvent =
785
841
  members: Array<{
786
842
  replica_id: string;
787
843
  /** Every endpoint this peer advertised, in the order it offered them. */
788
- transports: Array<{ uri: string; protocol: number }>;
844
+ transports: Endpoint[];
789
845
  role: "Source" | "Destination";
790
- communication_info: Record<string, string>;
846
+ communication_info?: Record<string, string>;
791
847
  }>;
792
848
  shared_key: Uint8Array;
793
849
  };
@@ -810,15 +866,16 @@ export type DeRecEvent =
810
866
  type: "ReplicaSecretInstalled";
811
867
  channel_id: string;
812
868
  from_replica_id: string;
869
+ author_replica_id: string | null;
813
870
  secret_id: string;
814
871
  version: number;
815
872
  secret: {
816
873
  helpers: Array<{
817
874
  channel_id: string;
818
875
  /** Every endpoint this peer advertised, in the order it offered them. */
819
- transports: Array<{ uri: string; protocol: number }>;
876
+ transports: Endpoint[];
820
877
  shared_key: Uint8Array;
821
- communication_info: Record<string, string>;
878
+ communication_info?: Record<string, string>;
822
879
  }>;
823
880
  secrets: Array<{
824
881
  id: Uint8Array;
@@ -836,9 +893,9 @@ export type DeRecEvent =
836
893
  members: Array<{
837
894
  replica_id: string;
838
895
  /** Every endpoint this peer advertised, in the order it offered them. */
839
- transports: Array<{ uri: string; protocol: number }>;
896
+ transports: Endpoint[];
840
897
  role: "Source" | "Destination";
841
- communication_info: Record<string, string>;
898
+ communication_info?: Record<string, string>;
842
899
  }>;
843
900
  shared_key: Uint8Array;
844
901
  };
@@ -848,6 +905,56 @@ export type DeRecEvent =
848
905
  committed_share: Uint8Array;
849
906
  }>;
850
907
  }
908
+ /** A member offered a different copy of the version this device holds.
909
+ * Nothing was written: this device keeps its own copy and refuses the
910
+ * incoming one with `VERSION_CONFLICT`, so the publisher sees
911
+ * `ReplicaSyncRejected`. Both copies are complete states — the held one
912
+ * is in the local stores, the incoming one is `secret`. Resolve by
913
+ * publishing the chosen state with `start(FlowKind.ProtectSecret)`; the
914
+ * next version supersedes both on every member and helper.
915
+ *
916
+ * `held_author_replica_id` / `incoming_author_replica_id` are the
917
+ * decimal `replica_id` of each copy's publisher, or `null` when that
918
+ * copy records none. */
919
+ | {
920
+ type: "ReplicaVersionConflict";
921
+ channel_id: string;
922
+ from_replica_id: string;
923
+ secret_id: string;
924
+ version: number;
925
+ held_author_replica_id: string | null;
926
+ incoming_author_replica_id: string | null;
927
+ secret: {
928
+ helpers: Array<{
929
+ channel_id: string;
930
+ /** Every endpoint this peer advertised, in the order it offered them. */
931
+ transports: Endpoint[];
932
+ shared_key: Uint8Array;
933
+ communication_info?: Record<string, string>;
934
+ }>;
935
+ secrets: Array<{
936
+ id: Uint8Array;
937
+ name: string;
938
+ data: Uint8Array;
939
+ }>;
940
+ /** The same shape as `SecretRecovered.secret.replicas`. */
941
+ replicas?: {
942
+ /** The one channel every member is addressed on. */
943
+ channel_id: string;
944
+ /** Every member of the group, including the writer. Exactly one
945
+ * carries `role: "Source"` — that member is where the secret
946
+ * originated, which is why no separate owner field is needed. */
947
+ members: Array<{
948
+ replica_id: string;
949
+ /** Every endpoint this peer advertised, in the order it offered them. */
950
+ transports: Endpoint[];
951
+ role: "Source" | "Destination";
952
+ communication_info?: Record<string, string>;
953
+ }>;
954
+ shared_key: Uint8Array;
955
+ };
956
+ };
957
+ }
851
958
  /** Peer's ack of a secret sync we sent. `status` is the `StatusEnum`
852
959
  * integer (0 = Ok), `memo` is the peer's explanation. */
853
960
  | {
@@ -856,7 +963,7 @@ export type DeRecEvent =
856
963
  from_replica_id: string;
857
964
  secret_id: string;
858
965
  version: number;
859
- status: number;
966
+ status: StatusEnum;
860
967
  memo: string;
861
968
  }
862
969
  /** A peer announced an updated `communication_info` map and/or
@@ -873,7 +980,7 @@ export type DeRecEvent =
873
980
  | {
874
981
  type: "ChannelInfoUpdateRejected";
875
982
  channel_id: string;
876
- status: number;
983
+ status: StatusEnum;
877
984
  memo: string;
878
985
  }
879
986
  /** Emitted by `process()` in place of `ActionRequired` when the
@@ -885,6 +992,38 @@ export type DeRecEvent =
885
992
  * (`"Pairing"`, `"StoreShare"`, …). */
886
993
  | { type: "AutoAccepted"; channel_id: string; action_kind: PendingActionKind }
887
994
  | { type: "NoOp" }
995
+ /** An inbound message was dropped untouched: no store was written and
996
+ * nothing was sent back. `reason` says why.
997
+ *
998
+ * `"PendingVerification"` means the peer sent something before this
999
+ * device confirmed the channel's fingerprint — typically a replica source
1000
+ * pushing its first copy while this destination still shows the code.
1001
+ * Confirming does not replay it: after `verifyFingerprint` succeeds, a
1002
+ * replica destination calls `start(FlowKind.ReplicaDiscovery)` to pull
1003
+ * the copy itself. `"Expired"` means the message was older than the
1004
+ * inbound timeout. `trace_id` matches the peer's `*Started` event for
1005
+ * the same round (`"0"` when the sender set none). */
1006
+ | {
1007
+ type: "MessageIgnored";
1008
+ channel_id: string;
1009
+ reason: IgnoreReason;
1010
+ trace_id: string;
1011
+ }
1012
+ /** Returned by `restore`: a roster entry got no channel, so this device
1013
+ * cannot reach that peer. Every other entry and the user-secret snapshot
1014
+ * were restored; `reason` says why this one was not. `"NoTransports"`
1015
+ * means the recovered roster names no endpoint for it.
1016
+ *
1017
+ * For a helper, `channel_id` is its channel and `replica_id` is absent.
1018
+ * For a replica group member, `channel_id` is the group's channel and
1019
+ * `replica_id` names the member. The peer itself is untouched — a helper
1020
+ * still holds its share — and pairing with it again makes it reachable. */
1021
+ | {
1022
+ type: "PeerNotRestored";
1023
+ channel_id: string;
1024
+ replica_id?: string;
1025
+ reason: NotRestoredReason;
1026
+ }
888
1027
  /** A pairing handshake was dispatched successfully. `kind` is the
889
1028
  * local party's role — same value the subsequent `PairingCompleted`
890
1029
  * will carry. Emitted by `start(Pairing)`. */
@@ -953,8 +1092,8 @@ export type DeRecEvent =
953
1092
  * inbound shares. The protocol enforces no size, quota or rate limit
954
1093
  * of its own, and `maxShareSize` is checked for range overlap at
955
1094
  * pairing time only, never against an actual share. While this is
956
- * `false`, `ActionRequired` carries the decoded request, so the
957
- * application can inspect the share and call `reject()` with
1095
+ * `false`, `ActionRequired` carries `share_size`, so the application
1096
+ * can compare it to its quota and call `reject()` with
958
1097
  * `StatusEnum.SizeLimitExceeded`. Setting it `true` removes that
959
1098
  * opportunity entirely: every share from every paired Owner is stored
960
1099
  * unconditionally, at whatever size it arrives. Keep off in any
@@ -982,10 +1121,23 @@ export interface AutoAcceptPolicy {
982
1121
  * between them without reaching for reference docs.
983
1122
  *
984
1123
  * Required setters: `withChannelStore`, `withShareStore`,
985
- * `withSecretStore`, `withTransport`, and either `withOwnTransport` or
986
- * `withOwnTransports`. Calling `build()` without all five throws.
1124
+ * `withSecretStore`, `withUserSecretStore`, `withStateStore`,
1125
+ * `withTransport`, and `withOwnTransports`. Calling `build()` without all
1126
+ * seven throws.
1127
+ *
1128
+ * An optional setter that is never called leaves the library's default in
1129
+ * force.
987
1130
  */
988
1131
  export declare class DeRecProtocolBuilder {
1132
+ /**
1133
+ * Release the builder's memory in the library. `build()` already releases
1134
+ * it; call this only for a builder that is discarded unbuilt. Safe to call
1135
+ * more than once.
1136
+ */
1137
+ free(): void;
1138
+ /** Same as {@link DeRecProtocolBuilder.free}, for `using`. */
1139
+ [Symbol.dispose](): void;
1140
+
989
1141
  /**
990
1142
  * Construct a builder bound to a specific secret. `secretId`
991
1143
  * identifies the single secret this protocol instance manages.
@@ -1000,32 +1152,22 @@ export declare class DeRecProtocolBuilder {
1000
1152
  withUserSecretStore(store: UserSecretStore): DeRecProtocolBuilder;
1001
1153
  withStateStore(store: StateStore): DeRecProtocolBuilder;
1002
1154
  withTransport(transport: Transport): DeRecProtocolBuilder;
1003
- /**
1004
- * @deprecated Use {@link withOwnTransports}, which takes the whole
1005
- * preference list — `withOwnTransports([endpoint])` is the direct
1006
- * replacement. Removed at 0.0.5.
1007
- */
1008
- withOwnTransport(endpoint: { uri: string; protocol: string }): DeRecProtocolBuilder;
1009
1155
  /**
1010
1156
  * Set every transport endpoint this application serves, in preference
1011
1157
  * order. `protocol` is `"https"` or `"grpc"` (case-insensitive) per
1012
- * entry, same as {@link withOwnTransport}.
1158
+ * entry.
1013
1159
  *
1014
1160
  * The order is this application's own preference and decides which of
1015
1161
  * a peer's offered endpoints is used; it is not sorted, deduplicated,
1016
1162
  * or reordered. Every listed transport must actually be served,
1017
1163
  * because delivery is push-only — listing an endpoint this application
1018
1164
  * does not serve makes pairing succeed and replies vanish.
1019
- *
1020
- * Supersedes {@link withOwnTransport} for applications serving more
1021
- * than one transport; the single-endpoint setter remains fully
1022
- * supported.
1023
1165
  */
1024
- withOwnTransports(transports: { uri: string; protocol: string }[]): DeRecProtocolBuilder;
1166
+ withOwnTransports(transports: Endpoint[]): DeRecProtocolBuilder;
1025
1167
 
1026
- /** Default: 3. */
1168
+ /** Minimum number of shares required to reconstruct the secret. Default: 3. */
1027
1169
  withThreshold(threshold: number): DeRecProtocolBuilder;
1028
- /** Default: 3. */
1170
+ /** Number of recent versions each helper must retain. Default: 3. */
1029
1171
  withKeepVersionsCount(count: number): DeRecProtocolBuilder;
1030
1172
  /**
1031
1173
  * Configure how long the protocol waits on each thing that can keep it
@@ -1044,8 +1186,8 @@ export declare class DeRecProtocolBuilder {
1044
1186
  withTimeouts(timeouts: Timeouts): DeRecProtocolBuilder;
1045
1187
 
1046
1188
  /**
1047
- * Accept plaintext `http://` transport endpoints. **Development only.**
1048
- * Default: `false`.
1189
+ * Accept plaintext `http://` and `grpc://` transport endpoints.
1190
+ * **Development only.** Default: `false`.
1049
1191
  *
1050
1192
  * With `false`, plaintext is accepted in exactly one situation: an endpoint
1051
1193
  * this device configured for **itself** that names loopback (`localhost`,
@@ -1061,33 +1203,20 @@ export declare class DeRecProtocolBuilder {
1061
1203
  * delivery is your `Transport`. Nothing here stops an application sending
1062
1204
  * plaintext — it governs which endpoints the protocol will record,
1063
1205
  * propagate to peers, and reply to.
1064
- *
1065
- * @deprecated Use {@link withUnsafeConnection}, which names both gated
1066
- * schemes. Removed at 0.0.5.
1067
- */
1068
- withUnsafeHttp(allow: boolean): DeRecProtocolBuilder;
1069
- /**
1070
- * Accept plaintext `http://` and `grpc://` transport endpoints.
1071
- * **Development only.** Default: `false`. Supersedes
1072
- * {@link withUnsafeHttp}, which names only the HTTP scheme.
1073
- *
1074
- * Either flag alone is honored. Setting both to disagreeing values fails
1075
- * construction with the error code `CONFLICTING_PLAINTEXT_OPT_IN` rather
1076
- * than resolving silently, because precedence would hand the decision to
1077
- * the flag being removed.
1078
1206
  */
1079
1207
  withUnsafeConnection(allow: boolean): DeRecProtocolBuilder;
1080
1208
  /** Default: empty. */
1081
1209
  withCommunicationInfo(info: Record<string, string>): DeRecProtocolBuilder;
1082
1210
  /** Default: false. */
1083
1211
  withAutoRespondOnFailure(enabled: boolean): DeRecProtocolBuilder;
1084
- /** Default: "required". */
1212
+ /** Exactly `"required"` or `"not_required"`; any other string throws
1213
+ * `invalid_unpair_ack`. Default: `"required"`. */
1085
1214
  withUnpairAck(ack: UnpairAck): DeRecProtocolBuilder;
1086
1215
  /**
1087
1216
  * When `true`, every outbound channel-mode request stamps
1088
- * `request.replyTo = ownTransport` so the responder routes its reply
1089
- * back here even if the channel's stored peer endpoint points
1090
- * elsewhere. Default: false.
1217
+ * `request.reply_to` with this node's own transports so the responder
1218
+ * routes its reply back here even if the channel's stored peer endpoint
1219
+ * points elsewhere. Default: false.
1091
1220
  */
1092
1221
  withAutoReplyTo(enabled: boolean): DeRecProtocolBuilder;
1093
1222
  /**
@@ -1102,7 +1231,8 @@ export declare class DeRecProtocolBuilder {
1102
1231
  /**
1103
1232
  * Stable per-device replica id. Required to participate in any
1104
1233
  * `ReplicaSource` / `ReplicaDestination` pairing. The id must be
1105
- * stable across restarts. Default: unset.
1234
+ * stable across restarts: mint it once with {@link generate_replica_id}
1235
+ * and persist it. Default: unset.
1106
1236
  */
1107
1237
  withReplicaId(id: bigint | number): DeRecProtocolBuilder;
1108
1238
  /**
@@ -1125,10 +1255,33 @@ export declare class DeRecProtocolBuilder {
1125
1255
  build(): DeRecProtocol;
1126
1256
  }
1127
1257
 
1258
+ /**
1259
+ * Every method that touches protocol state returns a `Promise` and runs under
1260
+ * one lock per instance, so overlapping calls on the same instance — a `tick`
1261
+ * timer firing while `process` handles an inbound message — queue and run one
1262
+ * at a time, in the order they were made. Distinct instances do not share the
1263
+ * lock: two instances bound to the same `secretId` and the same stores must
1264
+ * still be serialized by the caller.
1265
+ *
1266
+ * A store or transport callback must not await a call on the instance that
1267
+ * invoked it: that call queues behind the one waiting on the callback, and
1268
+ * neither settles. Calling `free()` while a call is in flight throws.
1269
+ */
1128
1270
  export declare class DeRecProtocol {
1129
1271
  /** Use {@link DeRecProtocolBuilder} to construct instances. */
1130
1272
  private constructor();
1131
1273
 
1274
+ /**
1275
+ * Release this protocol's memory in the library, and its references to the
1276
+ * stores and transport. The library's memory is not reclaimed by the
1277
+ * JavaScript garbage collector in time to rely on, so call this when done.
1278
+ * Safe to call more than once; any other method called afterwards throws,
1279
+ * as does calling this while a call is in flight.
1280
+ */
1281
+ free(): void;
1282
+ /** Same as {@link DeRecProtocol.free}, for `using`. */
1283
+ [Symbol.dispose](): void;
1284
+
1132
1285
  /** The secret identifier this protocol instance is bound to. */
1133
1286
  secretId(): bigint;
1134
1287
 
@@ -1141,8 +1294,8 @@ export declare class DeRecProtocol {
1141
1294
  * directly in the contact. `ContactMode.HashedKeys`
1142
1295
  * embeds only a SHA-384 binding hash (keys are
1143
1296
  * fetched later via the `PrePair` round-trip).
1144
- * `HashedKeys` requires `ownTransportUri` to be
1145
- * ephemeral.
1297
+ * `HashedKeys` requires the advertised own
1298
+ * transports to be ephemeral.
1146
1299
  */
1147
1300
  /**
1148
1301
  * Single entry point for all three `ContactMode` variants.
@@ -1186,29 +1339,11 @@ export declare class DeRecProtocol {
1186
1339
  * contact peers — follow up with
1187
1340
  * <c>start(FlowKind.UpdateChannelInfo, ...)</c> to propagate.
1188
1341
  */
1189
- setCommunicationInfo(info: Record<string, string>): void;
1190
-
1191
- /**
1192
- * Replace this node's endpoint for one protocol, leaving the others
1193
- * alone. A node serves at most one endpoint per protocol, so the
1194
- * `(uri, protocol)` pair identifies the entry it replaces; an entry for
1195
- * a protocol not yet served is appended, and a replaced one keeps its
1196
- * position in the preference order.
1197
- *
1198
- * IMPORTANT: keep the old endpoint operational during the changeover
1199
- * (see the Rust docs on the matching setter for the discipline).
1200
- *
1201
- * @deprecated Use {@link setOwnTransports}, which takes the whole
1202
- * preference list and is the only way to change which protocols this
1203
- * node serves, or their order. Removed at 0.0.5.
1204
- */
1205
- setOwnTransport(uri: string, protocol: string): void;
1342
+ setCommunicationInfo(info: Record<string, string>): Promise<void>;
1206
1343
 
1207
1344
  /**
1208
1345
  * Replace every endpoint this node advertises, in preference order —
1209
- * the runtime counterpart to <c>withOwnTransports</c>, and the way to
1210
- * change the whole set (<c>setOwnTransport</c> replaces only the entry
1211
- * for the protocol its URI names).
1346
+ * the runtime counterpart to `withOwnTransports`.
1212
1347
  *
1213
1348
  * A node serves at most one endpoint per protocol, so this list is a
1214
1349
  * preference order over distinct protocols. Two entries of the same
@@ -1217,7 +1352,7 @@ export declare class DeRecProtocol {
1217
1352
  * Every entry is validated before any is stored, so a malformed URI
1218
1353
  * leaves the previous set intact. An empty array is rejected.
1219
1354
  */
1220
- setOwnTransports(transports: { uri: string; protocol: string }[]): void;
1355
+ setOwnTransports(transports: Endpoint[]): Promise<void>;
1221
1356
 
1222
1357
  process(message: Uint8Array): Promise<DeRecEvent[]>;
1223
1358
 
@@ -1231,14 +1366,14 @@ export declare class DeRecProtocol {
1231
1366
  * shorter than the configured timeout.
1232
1367
  *
1233
1368
  * Safe to call at any time; with nothing in flight it resolves to an empty
1234
- * array. It mutates the same round state an inbound response does, so it
1235
- * must be serialized against `process` for the same `secretId`.
1369
+ * array. Overlapping calls with `process` on the same instance queue
1370
+ * rather than collide.
1236
1371
  */
1237
1372
  tick(): Promise<DeRecEvent[]>;
1238
1373
 
1239
1374
  accept(actionBytes: Uint8Array): Promise<DeRecEvent[]>;
1240
1375
 
1241
- reject(actionBytes: Uint8Array, status: number, memo: string): Promise<void>;
1376
+ reject(actionBytes: Uint8Array, status: StatusEnum, memo: string): Promise<void>;
1242
1377
 
1243
1378
  /**
1244
1379
  * Derive the human-readable fingerprint for a paired channel. Both sides
@@ -1263,23 +1398,32 @@ export declare class DeRecProtocol {
1263
1398
  * threshold given even when that policy is disabled. The age comparison
1264
1399
  * is strict, so a channel created within the current second survives
1265
1400
  * even `0`.
1401
+ *
1402
+ * `olderThanSecs` is a `u64`: a `bigint`, a non-negative safe-integer
1403
+ * `number`, or a decimal string. Anything else throws `decode_error`.
1266
1404
  */
1267
- removeExpiredChannels(olderThanSecs: number): Promise<string[]>;
1405
+ removeExpiredChannels(olderThanSecs: bigint | number | string): Promise<string[]>;
1268
1406
 
1269
1407
  /**
1270
1408
  * Rebuild this protocol's `secret_id` namespace from a recovered
1271
1409
  * `Secret`. Mirrors the Rust `DeRecProtocol::restore` — pass the
1272
1410
  * typed `secret` carried by the `SecretRecovered` event verbatim.
1273
1411
  *
1274
- * Errors surface as structured objects with a `code` field:
1412
+ * A helper or member whose `transports` is empty gets no channel: it is
1413
+ * reported as a `PeerNotRestored` event in the returned array and the rest
1414
+ * of the roster is restored.
1415
+ *
1416
+ * Errors surface as a `DeRecError` (`category`, `code`, `message`):
1275
1417
  *
1276
1418
  * | code | meaning |
1277
1419
  * |--------------------|------------------------------------------------------------------|
1278
- * | `ALREADY_RESTORED` | A user-secret snapshot already exists for this `secret_id`. |
1279
- * | `CONFLICT` | Channels live at canonical helper / replica ids. The error |
1420
+ * | `already_restored` | A user-secret snapshot already exists for this `secret_id`. |
1421
+ * | `restore_conflict` | Channels live at ids restore is about to write. The error |
1280
1422
  * | | carries `channel_ids: string[]` listing the collisions. |
1281
- * | `INVARIANT` | The recovered `Secret` is internally inconsistent. |
1282
- * | `STORAGE` | A store I/O call failed mid-restore. |
1423
+ * | `invariant` | The recovered `Secret` is internally inconsistent. |
1424
+ * | `invalid_recovered_secret` | `recoveredSecret` is malformed — e.g. a missing or |
1425
+ * | | non-decimal `channel_id` / `replica_id`. |
1426
+ * | `store_error` | A store call failed mid-restore; `category` names the store. |
1283
1427
  */
1284
1428
  restore(
1285
1429
  recoveredSecret: Extract<DeRecEvent, { type: "SecretRecovered" }>["secret"],
@@ -1386,6 +1530,14 @@ export interface CommunicationInfo {
1386
1530
  * protocol can raise. Matches the Rust `PendingActionKind` discriminants
1387
1531
  * one-for-one.
1388
1532
  */
1533
+ /** Why a `MessageIgnored` event dropped a message. Matches the Rust
1534
+ * `IgnoreReason` discriminants one-for-one. */
1535
+ export type IgnoreReason = "PendingVerification" | "Expired";
1536
+
1537
+ /** Why a `PeerNotRestored` event left a roster entry without a channel.
1538
+ * Matches the Rust `NotRestoredReason` discriminants one-for-one. */
1539
+ export type NotRestoredReason = "NoTransports";
1540
+
1389
1541
  export type PendingActionKind =
1390
1542
  | "Pairing"
1391
1543
  | "PrePair"
@@ -1416,17 +1568,9 @@ export interface PairRequestMessage {
1416
1568
  nonce: bigint;
1417
1569
  communication_info?: CommunicationInfo;
1418
1570
  parameter_range?: ParameterRange;
1419
- /**
1420
- * @deprecated Reading this field directly is incorrect: its meaning narrowed
1421
- * to "one entry of a list, and possibly absent", so a peer advertising only
1422
- * `supported_transports` looks unreachable to a reader that was correct
1423
- * before 0.0.3. Call {@link advertisedEndpoints}, which resolves both
1424
- * spellings. Removed at 0.0.5.
1425
- */
1426
- transport_protocol?: TransportProtocol;
1427
1571
  timestamp?: Timestamp;
1428
1572
  /** Every transport endpoint the initiator can be reached on, in its own
1429
- * preference order. Empty means "only `transport_protocol` is offered". */
1573
+ * preference order. */
1430
1574
  supported_transports: TransportProtocol[];
1431
1575
  }
1432
1576
 
@@ -1448,21 +1592,12 @@ export interface PairResponseMessage {
1448
1592
 
1449
1593
  export interface PrePairRequestMessage {
1450
1594
  nonce: bigint;
1451
- /**
1452
- * @deprecated Reading this field directly is incorrect: its meaning narrowed
1453
- * to "one entry of a list, and possibly absent", so a peer advertising only
1454
- * `supported_transports` looks unreachable to a reader that was correct
1455
- * before 0.0.3. Call {@link advertisedEndpoints}, which resolves both
1456
- * spellings. Removed at 0.0.5.
1457
- */
1458
- transport_protocol?: TransportProtocol;
1459
1595
  timestamp?: Timestamp;
1460
1596
  /**
1461
1597
  * Every endpoint the sender can be reached on for the PrePair reply, in
1462
- * its own preference order. At least one of this and `transport_protocol`
1463
- * must be present.
1598
+ * its own preference order.
1464
1599
  */
1465
- supported_transports?: TransportProtocol[];
1600
+ supported_transports: TransportProtocol[];
1466
1601
  }
1467
1602
 
1468
1603
  export interface PrePairResponseMessage {
@@ -1648,6 +1783,15 @@ export interface ProducePrePairResult {
1648
1783
  envelope: Uint8Array;
1649
1784
  }
1650
1785
 
1786
+ export interface ProducePrePairNoKeysResult {
1787
+
1788
+ envelope: Uint8Array;
1789
+
1790
+ /** Secret key material generated for this pairing. The caller MUST persist
1791
+ * it: the `PairRequest` that follows is encrypted to it. */
1792
+ secret_key_material: Uint8Array;
1793
+ }
1794
+
1651
1795
  export interface PrePairRequestExtractResult {
1652
1796
 
1653
1797
  request: PrePairRequestMessage;
@@ -1700,6 +1844,7 @@ export type DeRecErrorCategory =
1700
1844
  | "secret_store"
1701
1845
  | "channel_store"
1702
1846
  | "share_store"
1847
+ | "state_store"
1703
1848
  | "input"
1704
1849
  | "protobuf"
1705
1850
  | "invariant"
@@ -1713,6 +1858,10 @@ export interface DeRecError {
1713
1858
  memo?: string;
1714
1859
  expected?: number;
1715
1860
  got?: number;
1861
+ /** The channel the failing inbound message arrived on, when `process()` could tell. */
1862
+ channel_id?: string;
1863
+ /** On a `restore` `CONFLICT`: the pre-existing channels at canonical ids. */
1864
+ channel_ids?: string[];
1716
1865
  }
1717
1866
 
1718
1867
  export declare const primitives: {
@@ -1747,16 +1896,32 @@ export declare const primitives: {
1747
1896
  * commitment and the scanner must complete a
1748
1897
  * `PrePair` round-trip first.
1749
1898
  * @param transport_protocols Every endpoint this initiator serves, in
1750
- * preference order. The first also fills the
1751
- * legacy singular field. For `HashedKeys`
1752
- * mode they MUST be ephemeral.
1899
+ * preference order. For `HashedKeys` mode
1900
+ * they MUST be ephemeral.
1901
+ * @param nonce Correlation nonce embedded in the contact. Omitted or
1902
+ * `null`, the library draws a random `u64` — the right
1903
+ * choice for `InlineKeys` / `HashedKeys`, where the nonce
1904
+ * is a security parameter. Required for `ContactMode.NoKeys`,
1905
+ * where the caller typically picks a short human-typable
1906
+ * value for manual entry. Must fit in a `u64`.
1753
1907
  */
1754
1908
  create_contact(
1755
1909
  channel_id: bigint,
1756
1910
  contact_mode: ContactMode | number,
1757
1911
  transport_protocols: TransportProtocol[],
1912
+ nonce?: bigint | number | null,
1758
1913
  ): CreateContactResult;
1914
+ /**
1915
+ * Serializes a `ContactMessage` to the bytes delivered out of band.
1916
+ * Throws on a contact that violates the invariants of its contact mode
1917
+ * or advertises no endpoint.
1918
+ */
1759
1919
  encode_contact(contact_message: ContactMessage): Uint8Array;
1920
+ /**
1921
+ * Parses out-of-band contact bytes back into a `ContactMessage`. Throws
1922
+ * on bytes that are not a contact, or a contact that violates the
1923
+ * invariants of its contact mode.
1924
+ */
1760
1925
  decode_contact(bytes: Uint8Array): ContactMessage;
1761
1926
  produce(
1762
1927
  kind: SenderKind,
@@ -1766,7 +1931,17 @@ export declare const primitives: {
1766
1931
  parameter_range: ParameterRange | null,
1767
1932
  ): PairingRequestProduceResult;
1768
1933
 
1769
- extract(envelope_bytes: Uint8Array, secret_key: Uint8Array): { request: PairRequestMessage };
1934
+ /**
1935
+ * @param parameter_range The range this side accepts, or `null` for
1936
+ * none. A request advertising a range that does
1937
+ * not overlap it is refused with
1938
+ * `incompatible_parameter_range`.
1939
+ */
1940
+ extract(
1941
+ envelope_bytes: Uint8Array,
1942
+ secret_key: Uint8Array,
1943
+ parameter_range: ParameterRange | null,
1944
+ ): { request: PairRequestMessage };
1770
1945
 
1771
1946
  /**
1772
1947
  * Scanner-side: build a plaintext `PrePairRequest` envelope when the
@@ -1778,8 +1953,6 @@ export declare const primitives: {
1778
1953
  /**
1779
1954
  * @param own_transports Every endpoint this scanner serves for the
1780
1955
  * PrePair reply, in its own preference order.
1781
- * The first entry also fills the deprecated
1782
- * singular field for peers predating the list.
1783
1956
  */
1784
1957
  produce_pre_pair(
1785
1958
  own_transports: TransportProtocol[],
@@ -1794,6 +1967,10 @@ export declare const primitives: {
1794
1967
  };
1795
1968
  response: {
1796
1969
  /**
1970
+ * @param parameter_range The range this side accepts and advertises,
1971
+ * or `null` for none. A request advertising a
1972
+ * range that does not overlap it is refused
1973
+ * with `incompatible_parameter_range`.
1797
1974
  * @param unsafe_connection Accept plaintext peer endpoints
1798
1975
  * (`http://`, `grpc://`). Development only.
1799
1976
  */
@@ -1807,10 +1984,18 @@ export declare const primitives: {
1807
1984
  ): PairingResponseProduceResult;
1808
1985
 
1809
1986
  extract(envelope_bytes: Uint8Array, secret_key: Uint8Array): { response: PairResponseMessage };
1987
+ /**
1988
+ * @param parameter_range The range this side accepts, or `null` for
1989
+ * none. A response advertising a range that
1990
+ * does not overlap it is refused with
1991
+ * `incompatible_parameter_range` before any key
1992
+ * is derived.
1993
+ */
1810
1994
  process(
1811
1995
  contact_message: ContactMessage,
1812
1996
  response: PairResponseMessage,
1813
1997
  secret_key: Uint8Array,
1998
+ parameter_range: ParameterRange | null,
1814
1999
  ): PairingProcessResult;
1815
2000
 
1816
2001
  /**
@@ -1838,7 +2023,41 @@ export declare const primitives: {
1838
2023
  contact_message: ContactMessage,
1839
2024
  response: PrePairResponseMessage,
1840
2025
  ): ProcessPrePairResult;
2026
+
2027
+ /**
2028
+ * Contact-creator side of a `NoKeys` pairing: generate key material and
2029
+ * answer the `PrePairRequest` with its public half.
2030
+ *
2031
+ * The caller MUST first match the request's `nonce` against the contact
2032
+ * it issued — the only thing that authenticates a `NoKeys` request — and
2033
+ * MUST persist `secret_key_material`. The resulting channel MUST stay
2034
+ * unusable until both sides confirm `pairing.fingerprint` out of band.
2035
+ */
2036
+ produce_pre_pair_no_keys(
2037
+ channel_id: bigint,
2038
+ request: PrePairRequestMessage,
2039
+ ): ProducePrePairNoKeysResult;
2040
+
2041
+ /**
2042
+ * Scanner side of a `NoKeys` pairing: accept the contact creator's
2043
+ * public keys. There is no binding hash to check them against, so the
2044
+ * resulting channel MUST stay unusable until both sides confirm
2045
+ * `pairing.fingerprint` out of band. Throws on a non-`Ok` status, a
2046
+ * missing key or a `nonce` mismatch.
2047
+ */
2048
+ process_pre_pair_no_keys(
2049
+ contact_message: ContactMessage,
2050
+ response: PrePairResponseMessage,
2051
+ ): ProcessPrePairResult;
1841
2052
  };
2053
+
2054
+ /**
2055
+ * The human-readable fingerprint of a pairing's 32-byte shared key. Both
2056
+ * ends derive the same value; comparing it out of band confirms the
2057
+ * pairing. A `NoKeys` pairing MUST be confirmed this way before use.
2058
+ * Throws on a key that is not 32 bytes.
2059
+ */
2060
+ fingerprint(shared_key: Uint8Array): string;
1842
2061
  };
1843
2062
  recovery: {
1844
2063
  request: {