@derec-alliance/nodejs 0.0.5 → 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/README.md +31 -11
- package/derec_descriptor.bin +0 -0
- package/derec_library.d.ts +112 -118
- package/derec_library.js +173 -160
- package/derec_library_bg.wasm +0 -0
- package/derec_library_bg.wasm.d.ts +39 -38
- package/index.d.ts +372 -164
- package/index.js +33 -3
- package/package.json +1 -1
- package/proto/contact.proto +15 -48
- package/proto/getshare.proto +4 -14
- package/proto/pair.proto +5 -29
- package/proto/prepair.proto +14 -39
- package/proto/secretidsversions.proto +4 -14
- package/proto/storeshare.proto +8 -39
- package/proto/unpair.proto +4 -14
- package/proto/updatechannelinfo.proto +16 -45
- package/proto/verify.proto +4 -14
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
|
|
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, "
|
|
140
|
-
| Pick<PairRequestMessage, "
|
|
141
|
-
| Pick<PrePairRequestMessage, "
|
|
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
|
|
|
@@ -276,6 +265,10 @@ export interface UserSecrets {
|
|
|
276
265
|
version: number;
|
|
277
266
|
secrets: UserSecretEntry[];
|
|
278
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;
|
|
279
272
|
}
|
|
280
273
|
|
|
281
274
|
/**
|
|
@@ -319,6 +312,18 @@ export interface StateStore {
|
|
|
319
312
|
loadAll(secretId: string, kind: 0 | 1 | 2 | 3 | 4): Promise<Uint8Array[]>;
|
|
320
313
|
}
|
|
321
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
|
+
|
|
322
327
|
/**
|
|
323
328
|
* Outbound message delivery.
|
|
324
329
|
*
|
|
@@ -364,7 +369,7 @@ export interface Transport {
|
|
|
364
369
|
* with {@link singleEndpointTransport} rather than by indexing.
|
|
365
370
|
*/
|
|
366
371
|
send(
|
|
367
|
-
endpoints: ReadonlyArray<
|
|
372
|
+
endpoints: ReadonlyArray<Endpoint>,
|
|
368
373
|
message: Uint8Array,
|
|
369
374
|
): Promise<void>;
|
|
370
375
|
}
|
|
@@ -384,10 +389,25 @@ export interface Transport {
|
|
|
384
389
|
* a round trip; skipping one that would have worked costs the delivery.
|
|
385
390
|
*/
|
|
386
391
|
export type SendOne = (
|
|
387
|
-
endpoint:
|
|
392
|
+
endpoint: Endpoint,
|
|
388
393
|
message: Uint8Array,
|
|
389
394
|
) => Promise<void>;
|
|
390
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
|
+
|
|
391
411
|
/**
|
|
392
412
|
* Builds a {@link Transport} that tries each endpoint in the order the peer
|
|
393
413
|
* offered it and stops at the first success.
|
|
@@ -432,7 +452,7 @@ export enum SenderKind {
|
|
|
432
452
|
* the scanner must fetch the actual keys over the wire via the `PrePair`
|
|
433
453
|
* round-trip and verify them against the commitment before pairing.
|
|
434
454
|
* - `NoKeys`: no key material and no commitment. The contact carries only
|
|
435
|
-
* `channel_id`, `nonce`, and `
|
|
455
|
+
* `channel_id`, `nonce`, and `supported_transports` — small enough to be
|
|
436
456
|
* hand-typed or dictated. Keys are generated on the fly by the contact
|
|
437
457
|
* creator when the `PrePairRequest` arrives; the scanner accepts them
|
|
438
458
|
* without cryptographic verification. Trust rests entirely on the OOB
|
|
@@ -474,20 +494,33 @@ export enum FlowKind {
|
|
|
474
494
|
UnpairReplica = 8,
|
|
475
495
|
}
|
|
476
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
|
+
|
|
477
518
|
export type UnpairAck = "required" | "not_required";
|
|
478
519
|
|
|
479
520
|
export interface ContactMessage {
|
|
480
521
|
channel_id: bigint;
|
|
481
522
|
/** `ContactMode` numeric value (0 = INLINE_KEYS, 1 = HASHED_KEYS, 2 = NO_KEYS). */
|
|
482
523
|
contact_mode: number;
|
|
483
|
-
/**
|
|
484
|
-
* @deprecated Reading this field directly is incorrect: its meaning narrowed
|
|
485
|
-
* to "one entry of a list, and possibly absent", so a peer advertising only
|
|
486
|
-
* `supported_transports` looks unreachable to a reader that was correct
|
|
487
|
-
* before 0.0.3. Call {@link advertisedEndpoints}, which resolves both
|
|
488
|
-
* spellings. Removed at 0.0.5.
|
|
489
|
-
*/
|
|
490
|
-
transport_protocol?: TransportProtocol;
|
|
491
524
|
nonce: bigint;
|
|
492
525
|
/** Present only when `contact_mode === ContactMode.InlineKeys`. */
|
|
493
526
|
mlkem_encapsulation_key?: Uint8Array;
|
|
@@ -497,8 +530,7 @@ export interface ContactMessage {
|
|
|
497
530
|
contact_binding_hash?: Uint8Array;
|
|
498
531
|
timestamp?: Timestamp;
|
|
499
532
|
/** Every transport endpoint the creator of this contact can be reached
|
|
500
|
-
* on, in its own preference order.
|
|
501
|
-
* `transport_protocol` is offered". */
|
|
533
|
+
* on, in its own preference order. */
|
|
502
534
|
supported_transports: TransportProtocol[];
|
|
503
535
|
}
|
|
504
536
|
|
|
@@ -546,20 +578,11 @@ export interface UpdateChannelInfoParams {
|
|
|
546
578
|
* map untouched; pass an empty object to clear it. */
|
|
547
579
|
communication_info?: Record<string, string>;
|
|
548
580
|
|
|
549
|
-
/**
|
|
550
|
-
* New transport endpoint. Absent leaves it untouched.
|
|
551
|
-
*
|
|
552
|
-
* @deprecated Use `own_transports`, which carries every endpoint this node
|
|
553
|
-
* now serves; its first entry also fills this field for peers predating the
|
|
554
|
-
* list. Removed at 0.0.5.
|
|
555
|
-
*/
|
|
556
|
-
transport_protocol?: { uri: string; protocol: number };
|
|
557
581
|
/**
|
|
558
582
|
* Every endpoint this node now serves, in its own preference order.
|
|
559
|
-
* Omitted leaves the target(s)' stored set untouched.
|
|
560
|
-
* over `transport_protocol`, whose first entry it also fills.
|
|
583
|
+
* Omitted leaves the target(s)' stored set untouched.
|
|
561
584
|
*/
|
|
562
|
-
own_transports?:
|
|
585
|
+
own_transports?: Endpoint[];
|
|
563
586
|
}
|
|
564
587
|
|
|
565
588
|
/**
|
|
@@ -618,18 +641,34 @@ export type DeRecEvent =
|
|
|
618
641
|
action: Uint8Array;
|
|
619
642
|
|
|
620
643
|
action_kind: PendingActionKind;
|
|
644
|
+
/** Correlation token of the inbound request, decimal-encoded. */
|
|
645
|
+
trace_id: string;
|
|
646
|
+
/** Pairing only. */
|
|
621
647
|
peer_communication_info?: Record<string, string>;
|
|
622
|
-
|
|
648
|
+
/** `sender_kind` of the inbound pair request (Pairing only). */
|
|
623
649
|
sender_kind?: SenderKind;
|
|
624
|
-
|
|
650
|
+
/** Share version (StoreShare / VerifyShare / GetShare). */
|
|
625
651
|
version?: number;
|
|
652
|
+
/** Description of the secret version (StoreShare only). */
|
|
626
653
|
share_description?: string;
|
|
627
|
-
|
|
654
|
+
/** Secret identifier, decimal-encoded (StoreShare / VerifyShare /
|
|
655
|
+
* GetShare). On GetShare, with `version`, names the requested share. */
|
|
628
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[];
|
|
629
668
|
}
|
|
630
669
|
| { type: "ShareStored"; channel_id: string; version: number }
|
|
631
670
|
| { type: "ShareConfirmed"; channel_id: string; version: number }
|
|
632
|
-
| { type: "ShareRejected"; channel_id: string; version: number; status:
|
|
671
|
+
| { type: "ShareRejected"; channel_id: string; version: number; status: StatusEnum; memo: string }
|
|
633
672
|
/** A publishing round finished — every targeted helper confirmed,
|
|
634
673
|
* rejected, or timed out.
|
|
635
674
|
*
|
|
@@ -654,7 +693,7 @@ export type DeRecEvent =
|
|
|
654
693
|
replica_id: string;
|
|
655
694
|
secret_id: string;
|
|
656
695
|
version: number;
|
|
657
|
-
status:
|
|
696
|
+
status: StatusEnum;
|
|
658
697
|
memo: string;
|
|
659
698
|
}
|
|
660
699
|
/** A secret sync could not be delivered to a member at all — distinct from
|
|
@@ -707,9 +746,9 @@ export type DeRecEvent =
|
|
|
707
746
|
helpers: Array<{
|
|
708
747
|
channel_id: string;
|
|
709
748
|
/** Every endpoint this peer advertised, in the order it offered them. */
|
|
710
|
-
transports:
|
|
749
|
+
transports: Endpoint[];
|
|
711
750
|
shared_key: Uint8Array;
|
|
712
|
-
communication_info
|
|
751
|
+
communication_info?: Record<string, string>;
|
|
713
752
|
}>;
|
|
714
753
|
secrets: Array<{
|
|
715
754
|
id: Uint8Array;
|
|
@@ -729,9 +768,9 @@ export type DeRecEvent =
|
|
|
729
768
|
members: Array<{
|
|
730
769
|
replica_id: string;
|
|
731
770
|
/** Every endpoint this peer advertised, in the order it offered them. */
|
|
732
|
-
transports:
|
|
771
|
+
transports: Endpoint[];
|
|
733
772
|
role: "Source" | "Destination";
|
|
734
|
-
communication_info
|
|
773
|
+
communication_info?: Record<string, string>;
|
|
735
774
|
}>;
|
|
736
775
|
shared_key: Uint8Array;
|
|
737
776
|
};
|
|
@@ -740,12 +779,12 @@ export type DeRecEvent =
|
|
|
740
779
|
|
|
741
780
|
| { type: "Unpaired"; channel_id: string }
|
|
742
781
|
|
|
743
|
-
| { type: "UnpairRejected"; channel_id: string; status:
|
|
782
|
+
| { type: "UnpairRejected"; channel_id: string; status: StatusEnum; memo: string }
|
|
744
783
|
|
|
745
784
|
/** Contact creator answered the scanner's `PrePairRequest` with a
|
|
746
785
|
* non-Ok status (HashedKeys flow). Distinct from a cryptographic
|
|
747
786
|
* hash mismatch, which surfaces as a thrown error from `process()`. */
|
|
748
|
-
| { type: "PrePairRejected"; channel_id: string; status:
|
|
787
|
+
| { type: "PrePairRejected"; channel_id: string; status: StatusEnum; memo: string }
|
|
749
788
|
|
|
750
789
|
/** Fires alongside `PairingCompleted` on replica-mode pair handshakes.
|
|
751
790
|
* `peer_replica_id` is the peer's `u64` as a **decimal** string,
|
|
@@ -763,22 +802,28 @@ export type DeRecEvent =
|
|
|
763
802
|
/** A `ReplicaSource` peer pushed a secret sync on a
|
|
764
803
|
* `ReplicaDestination` channel. The library decoded the
|
|
765
804
|
* `ReplicaSecretPayload`; the app installs `secret.secrets` and
|
|
766
|
-
* optionally uses `shares` for recovery. `from_replica_id
|
|
767
|
-
* `replica_id` fields inside `secret` are
|
|
768
|
-
* 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. */
|
|
769
813
|
| {
|
|
770
814
|
type: "ReplicaSecretReceived";
|
|
771
815
|
channel_id: string;
|
|
772
816
|
from_replica_id: string;
|
|
817
|
+
author_replica_id: string | null;
|
|
773
818
|
secret_id: string;
|
|
774
819
|
version: number;
|
|
775
820
|
secret: {
|
|
776
821
|
helpers: Array<{
|
|
777
822
|
channel_id: string;
|
|
778
823
|
/** Every endpoint this peer advertised, in the order it offered them. */
|
|
779
|
-
transports:
|
|
824
|
+
transports: Endpoint[];
|
|
780
825
|
shared_key: Uint8Array;
|
|
781
|
-
communication_info
|
|
826
|
+
communication_info?: Record<string, string>;
|
|
782
827
|
}>;
|
|
783
828
|
secrets: Array<{
|
|
784
829
|
id: Uint8Array;
|
|
@@ -796,9 +841,9 @@ export type DeRecEvent =
|
|
|
796
841
|
members: Array<{
|
|
797
842
|
replica_id: string;
|
|
798
843
|
/** Every endpoint this peer advertised, in the order it offered them. */
|
|
799
|
-
transports:
|
|
844
|
+
transports: Endpoint[];
|
|
800
845
|
role: "Source" | "Destination";
|
|
801
|
-
communication_info
|
|
846
|
+
communication_info?: Record<string, string>;
|
|
802
847
|
}>;
|
|
803
848
|
shared_key: Uint8Array;
|
|
804
849
|
};
|
|
@@ -821,15 +866,16 @@ export type DeRecEvent =
|
|
|
821
866
|
type: "ReplicaSecretInstalled";
|
|
822
867
|
channel_id: string;
|
|
823
868
|
from_replica_id: string;
|
|
869
|
+
author_replica_id: string | null;
|
|
824
870
|
secret_id: string;
|
|
825
871
|
version: number;
|
|
826
872
|
secret: {
|
|
827
873
|
helpers: Array<{
|
|
828
874
|
channel_id: string;
|
|
829
875
|
/** Every endpoint this peer advertised, in the order it offered them. */
|
|
830
|
-
transports:
|
|
876
|
+
transports: Endpoint[];
|
|
831
877
|
shared_key: Uint8Array;
|
|
832
|
-
communication_info
|
|
878
|
+
communication_info?: Record<string, string>;
|
|
833
879
|
}>;
|
|
834
880
|
secrets: Array<{
|
|
835
881
|
id: Uint8Array;
|
|
@@ -847,9 +893,9 @@ export type DeRecEvent =
|
|
|
847
893
|
members: Array<{
|
|
848
894
|
replica_id: string;
|
|
849
895
|
/** Every endpoint this peer advertised, in the order it offered them. */
|
|
850
|
-
transports:
|
|
896
|
+
transports: Endpoint[];
|
|
851
897
|
role: "Source" | "Destination";
|
|
852
|
-
communication_info
|
|
898
|
+
communication_info?: Record<string, string>;
|
|
853
899
|
}>;
|
|
854
900
|
shared_key: Uint8Array;
|
|
855
901
|
};
|
|
@@ -859,6 +905,56 @@ export type DeRecEvent =
|
|
|
859
905
|
committed_share: Uint8Array;
|
|
860
906
|
}>;
|
|
861
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
|
+
}
|
|
862
958
|
/** Peer's ack of a secret sync we sent. `status` is the `StatusEnum`
|
|
863
959
|
* integer (0 = Ok), `memo` is the peer's explanation. */
|
|
864
960
|
| {
|
|
@@ -867,7 +963,7 @@ export type DeRecEvent =
|
|
|
867
963
|
from_replica_id: string;
|
|
868
964
|
secret_id: string;
|
|
869
965
|
version: number;
|
|
870
|
-
status:
|
|
966
|
+
status: StatusEnum;
|
|
871
967
|
memo: string;
|
|
872
968
|
}
|
|
873
969
|
/** A peer announced an updated `communication_info` map and/or
|
|
@@ -884,7 +980,7 @@ export type DeRecEvent =
|
|
|
884
980
|
| {
|
|
885
981
|
type: "ChannelInfoUpdateRejected";
|
|
886
982
|
channel_id: string;
|
|
887
|
-
status:
|
|
983
|
+
status: StatusEnum;
|
|
888
984
|
memo: string;
|
|
889
985
|
}
|
|
890
986
|
/** Emitted by `process()` in place of `ActionRequired` when the
|
|
@@ -896,6 +992,38 @@ export type DeRecEvent =
|
|
|
896
992
|
* (`"Pairing"`, `"StoreShare"`, …). */
|
|
897
993
|
| { type: "AutoAccepted"; channel_id: string; action_kind: PendingActionKind }
|
|
898
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
|
+
}
|
|
899
1027
|
/** A pairing handshake was dispatched successfully. `kind` is the
|
|
900
1028
|
* local party's role — same value the subsequent `PairingCompleted`
|
|
901
1029
|
* will carry. Emitted by `start(Pairing)`. */
|
|
@@ -964,8 +1092,8 @@ export type DeRecEvent =
|
|
|
964
1092
|
* inbound shares. The protocol enforces no size, quota or rate limit
|
|
965
1093
|
* of its own, and `maxShareSize` is checked for range overlap at
|
|
966
1094
|
* pairing time only, never against an actual share. While this is
|
|
967
|
-
* `false`, `ActionRequired` carries
|
|
968
|
-
*
|
|
1095
|
+
* `false`, `ActionRequired` carries `share_size`, so the application
|
|
1096
|
+
* can compare it to its quota and call `reject()` with
|
|
969
1097
|
* `StatusEnum.SizeLimitExceeded`. Setting it `true` removes that
|
|
970
1098
|
* opportunity entirely: every share from every paired Owner is stored
|
|
971
1099
|
* unconditionally, at whatever size it arrives. Keep off in any
|
|
@@ -993,10 +1121,23 @@ export interface AutoAcceptPolicy {
|
|
|
993
1121
|
* between them without reaching for reference docs.
|
|
994
1122
|
*
|
|
995
1123
|
* Required setters: `withChannelStore`, `withShareStore`,
|
|
996
|
-
* `withSecretStore`, `
|
|
997
|
-
* `withOwnTransports`. Calling `build()` without all
|
|
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.
|
|
998
1130
|
*/
|
|
999
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
|
+
|
|
1000
1141
|
/**
|
|
1001
1142
|
* Construct a builder bound to a specific secret. `secretId`
|
|
1002
1143
|
* identifies the single secret this protocol instance manages.
|
|
@@ -1011,32 +1152,22 @@ export declare class DeRecProtocolBuilder {
|
|
|
1011
1152
|
withUserSecretStore(store: UserSecretStore): DeRecProtocolBuilder;
|
|
1012
1153
|
withStateStore(store: StateStore): DeRecProtocolBuilder;
|
|
1013
1154
|
withTransport(transport: Transport): DeRecProtocolBuilder;
|
|
1014
|
-
/**
|
|
1015
|
-
* @deprecated Use {@link withOwnTransports}, which takes the whole
|
|
1016
|
-
* preference list — `withOwnTransports([endpoint])` is the direct
|
|
1017
|
-
* replacement. Removed at 0.0.5.
|
|
1018
|
-
*/
|
|
1019
|
-
withOwnTransport(endpoint: { uri: string; protocol: string }): DeRecProtocolBuilder;
|
|
1020
1155
|
/**
|
|
1021
1156
|
* Set every transport endpoint this application serves, in preference
|
|
1022
1157
|
* order. `protocol` is `"https"` or `"grpc"` (case-insensitive) per
|
|
1023
|
-
* entry
|
|
1158
|
+
* entry.
|
|
1024
1159
|
*
|
|
1025
1160
|
* The order is this application's own preference and decides which of
|
|
1026
1161
|
* a peer's offered endpoints is used; it is not sorted, deduplicated,
|
|
1027
1162
|
* or reordered. Every listed transport must actually be served,
|
|
1028
1163
|
* because delivery is push-only — listing an endpoint this application
|
|
1029
1164
|
* does not serve makes pairing succeed and replies vanish.
|
|
1030
|
-
*
|
|
1031
|
-
* Supersedes {@link withOwnTransport} for applications serving more
|
|
1032
|
-
* than one transport; the single-endpoint setter remains fully
|
|
1033
|
-
* supported.
|
|
1034
1165
|
*/
|
|
1035
|
-
withOwnTransports(transports:
|
|
1166
|
+
withOwnTransports(transports: Endpoint[]): DeRecProtocolBuilder;
|
|
1036
1167
|
|
|
1037
|
-
/** Default: 3. */
|
|
1168
|
+
/** Minimum number of shares required to reconstruct the secret. Default: 3. */
|
|
1038
1169
|
withThreshold(threshold: number): DeRecProtocolBuilder;
|
|
1039
|
-
/** Default: 3. */
|
|
1170
|
+
/** Number of recent versions each helper must retain. Default: 3. */
|
|
1040
1171
|
withKeepVersionsCount(count: number): DeRecProtocolBuilder;
|
|
1041
1172
|
/**
|
|
1042
1173
|
* Configure how long the protocol waits on each thing that can keep it
|
|
@@ -1055,8 +1186,8 @@ export declare class DeRecProtocolBuilder {
|
|
|
1055
1186
|
withTimeouts(timeouts: Timeouts): DeRecProtocolBuilder;
|
|
1056
1187
|
|
|
1057
1188
|
/**
|
|
1058
|
-
* Accept plaintext `http://` transport endpoints.
|
|
1059
|
-
* Default: `false`.
|
|
1189
|
+
* Accept plaintext `http://` and `grpc://` transport endpoints.
|
|
1190
|
+
* **Development only.** Default: `false`.
|
|
1060
1191
|
*
|
|
1061
1192
|
* With `false`, plaintext is accepted in exactly one situation: an endpoint
|
|
1062
1193
|
* this device configured for **itself** that names loopback (`localhost`,
|
|
@@ -1072,33 +1203,20 @@ export declare class DeRecProtocolBuilder {
|
|
|
1072
1203
|
* delivery is your `Transport`. Nothing here stops an application sending
|
|
1073
1204
|
* plaintext — it governs which endpoints the protocol will record,
|
|
1074
1205
|
* propagate to peers, and reply to.
|
|
1075
|
-
*
|
|
1076
|
-
* @deprecated Use {@link withUnsafeConnection}, which names both gated
|
|
1077
|
-
* schemes. Removed at 0.0.5.
|
|
1078
|
-
*/
|
|
1079
|
-
withUnsafeHttp(allow: boolean): DeRecProtocolBuilder;
|
|
1080
|
-
/**
|
|
1081
|
-
* Accept plaintext `http://` and `grpc://` transport endpoints.
|
|
1082
|
-
* **Development only.** Default: `false`. Supersedes
|
|
1083
|
-
* {@link withUnsafeHttp}, which names only the HTTP scheme.
|
|
1084
|
-
*
|
|
1085
|
-
* Either flag alone is honored. Setting both to disagreeing values fails
|
|
1086
|
-
* construction with the error code `CONFLICTING_PLAINTEXT_OPT_IN` rather
|
|
1087
|
-
* than resolving silently, because precedence would hand the decision to
|
|
1088
|
-
* the flag being removed.
|
|
1089
1206
|
*/
|
|
1090
1207
|
withUnsafeConnection(allow: boolean): DeRecProtocolBuilder;
|
|
1091
1208
|
/** Default: empty. */
|
|
1092
1209
|
withCommunicationInfo(info: Record<string, string>): DeRecProtocolBuilder;
|
|
1093
1210
|
/** Default: false. */
|
|
1094
1211
|
withAutoRespondOnFailure(enabled: boolean): DeRecProtocolBuilder;
|
|
1095
|
-
/**
|
|
1212
|
+
/** Exactly `"required"` or `"not_required"`; any other string throws
|
|
1213
|
+
* `invalid_unpair_ack`. Default: `"required"`. */
|
|
1096
1214
|
withUnpairAck(ack: UnpairAck): DeRecProtocolBuilder;
|
|
1097
1215
|
/**
|
|
1098
1216
|
* When `true`, every outbound channel-mode request stamps
|
|
1099
|
-
* `request.
|
|
1100
|
-
* back here even if the channel's stored peer endpoint
|
|
1101
|
-
* 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.
|
|
1102
1220
|
*/
|
|
1103
1221
|
withAutoReplyTo(enabled: boolean): DeRecProtocolBuilder;
|
|
1104
1222
|
/**
|
|
@@ -1113,7 +1231,8 @@ export declare class DeRecProtocolBuilder {
|
|
|
1113
1231
|
/**
|
|
1114
1232
|
* Stable per-device replica id. Required to participate in any
|
|
1115
1233
|
* `ReplicaSource` / `ReplicaDestination` pairing. The id must be
|
|
1116
|
-
* stable across restarts
|
|
1234
|
+
* stable across restarts: mint it once with {@link generate_replica_id}
|
|
1235
|
+
* and persist it. Default: unset.
|
|
1117
1236
|
*/
|
|
1118
1237
|
withReplicaId(id: bigint | number): DeRecProtocolBuilder;
|
|
1119
1238
|
/**
|
|
@@ -1136,10 +1255,33 @@ export declare class DeRecProtocolBuilder {
|
|
|
1136
1255
|
build(): DeRecProtocol;
|
|
1137
1256
|
}
|
|
1138
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
|
+
*/
|
|
1139
1270
|
export declare class DeRecProtocol {
|
|
1140
1271
|
/** Use {@link DeRecProtocolBuilder} to construct instances. */
|
|
1141
1272
|
private constructor();
|
|
1142
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
|
+
|
|
1143
1285
|
/** The secret identifier this protocol instance is bound to. */
|
|
1144
1286
|
secretId(): bigint;
|
|
1145
1287
|
|
|
@@ -1152,8 +1294,8 @@ export declare class DeRecProtocol {
|
|
|
1152
1294
|
* directly in the contact. `ContactMode.HashedKeys`
|
|
1153
1295
|
* embeds only a SHA-384 binding hash (keys are
|
|
1154
1296
|
* fetched later via the `PrePair` round-trip).
|
|
1155
|
-
* `HashedKeys` requires
|
|
1156
|
-
* ephemeral.
|
|
1297
|
+
* `HashedKeys` requires the advertised own
|
|
1298
|
+
* transports to be ephemeral.
|
|
1157
1299
|
*/
|
|
1158
1300
|
/**
|
|
1159
1301
|
* Single entry point for all three `ContactMode` variants.
|
|
@@ -1197,29 +1339,11 @@ export declare class DeRecProtocol {
|
|
|
1197
1339
|
* contact peers — follow up with
|
|
1198
1340
|
* <c>start(FlowKind.UpdateChannelInfo, ...)</c> to propagate.
|
|
1199
1341
|
*/
|
|
1200
|
-
setCommunicationInfo(info: Record<string, string>): void
|
|
1201
|
-
|
|
1202
|
-
/**
|
|
1203
|
-
* Replace this node's endpoint for one protocol, leaving the others
|
|
1204
|
-
* alone. A node serves at most one endpoint per protocol, so the
|
|
1205
|
-
* `(uri, protocol)` pair identifies the entry it replaces; an entry for
|
|
1206
|
-
* a protocol not yet served is appended, and a replaced one keeps its
|
|
1207
|
-
* position in the preference order.
|
|
1208
|
-
*
|
|
1209
|
-
* IMPORTANT: keep the old endpoint operational during the changeover
|
|
1210
|
-
* (see the Rust docs on the matching setter for the discipline).
|
|
1211
|
-
*
|
|
1212
|
-
* @deprecated Use {@link setOwnTransports}, which takes the whole
|
|
1213
|
-
* preference list and is the only way to change which protocols this
|
|
1214
|
-
* node serves, or their order. Removed at 0.0.5.
|
|
1215
|
-
*/
|
|
1216
|
-
setOwnTransport(uri: string, protocol: string): void;
|
|
1342
|
+
setCommunicationInfo(info: Record<string, string>): Promise<void>;
|
|
1217
1343
|
|
|
1218
1344
|
/**
|
|
1219
1345
|
* Replace every endpoint this node advertises, in preference order —
|
|
1220
|
-
* the runtime counterpart to
|
|
1221
|
-
* change the whole set (<c>setOwnTransport</c> replaces only the entry
|
|
1222
|
-
* for the protocol its URI names).
|
|
1346
|
+
* the runtime counterpart to `withOwnTransports`.
|
|
1223
1347
|
*
|
|
1224
1348
|
* A node serves at most one endpoint per protocol, so this list is a
|
|
1225
1349
|
* preference order over distinct protocols. Two entries of the same
|
|
@@ -1228,7 +1352,7 @@ export declare class DeRecProtocol {
|
|
|
1228
1352
|
* Every entry is validated before any is stored, so a malformed URI
|
|
1229
1353
|
* leaves the previous set intact. An empty array is rejected.
|
|
1230
1354
|
*/
|
|
1231
|
-
setOwnTransports(transports:
|
|
1355
|
+
setOwnTransports(transports: Endpoint[]): Promise<void>;
|
|
1232
1356
|
|
|
1233
1357
|
process(message: Uint8Array): Promise<DeRecEvent[]>;
|
|
1234
1358
|
|
|
@@ -1242,14 +1366,14 @@ export declare class DeRecProtocol {
|
|
|
1242
1366
|
* shorter than the configured timeout.
|
|
1243
1367
|
*
|
|
1244
1368
|
* Safe to call at any time; with nothing in flight it resolves to an empty
|
|
1245
|
-
* array.
|
|
1246
|
-
*
|
|
1369
|
+
* array. Overlapping calls with `process` on the same instance queue
|
|
1370
|
+
* rather than collide.
|
|
1247
1371
|
*/
|
|
1248
1372
|
tick(): Promise<DeRecEvent[]>;
|
|
1249
1373
|
|
|
1250
1374
|
accept(actionBytes: Uint8Array): Promise<DeRecEvent[]>;
|
|
1251
1375
|
|
|
1252
|
-
reject(actionBytes: Uint8Array, status:
|
|
1376
|
+
reject(actionBytes: Uint8Array, status: StatusEnum, memo: string): Promise<void>;
|
|
1253
1377
|
|
|
1254
1378
|
/**
|
|
1255
1379
|
* Derive the human-readable fingerprint for a paired channel. Both sides
|
|
@@ -1274,23 +1398,32 @@ export declare class DeRecProtocol {
|
|
|
1274
1398
|
* threshold given even when that policy is disabled. The age comparison
|
|
1275
1399
|
* is strict, so a channel created within the current second survives
|
|
1276
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`.
|
|
1277
1404
|
*/
|
|
1278
|
-
removeExpiredChannels(olderThanSecs: number): Promise<string[]>;
|
|
1405
|
+
removeExpiredChannels(olderThanSecs: bigint | number | string): Promise<string[]>;
|
|
1279
1406
|
|
|
1280
1407
|
/**
|
|
1281
1408
|
* Rebuild this protocol's `secret_id` namespace from a recovered
|
|
1282
1409
|
* `Secret`. Mirrors the Rust `DeRecProtocol::restore` — pass the
|
|
1283
1410
|
* typed `secret` carried by the `SecretRecovered` event verbatim.
|
|
1284
1411
|
*
|
|
1285
|
-
*
|
|
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`):
|
|
1286
1417
|
*
|
|
1287
1418
|
* | code | meaning |
|
|
1288
1419
|
* |--------------------|------------------------------------------------------------------|
|
|
1289
|
-
* | `
|
|
1290
|
-
* | `
|
|
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 |
|
|
1291
1422
|
* | | carries `channel_ids: string[]` listing the collisions. |
|
|
1292
|
-
* | `
|
|
1293
|
-
* | `
|
|
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. |
|
|
1294
1427
|
*/
|
|
1295
1428
|
restore(
|
|
1296
1429
|
recoveredSecret: Extract<DeRecEvent, { type: "SecretRecovered" }>["secret"],
|
|
@@ -1397,6 +1530,14 @@ export interface CommunicationInfo {
|
|
|
1397
1530
|
* protocol can raise. Matches the Rust `PendingActionKind` discriminants
|
|
1398
1531
|
* one-for-one.
|
|
1399
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
|
+
|
|
1400
1541
|
export type PendingActionKind =
|
|
1401
1542
|
| "Pairing"
|
|
1402
1543
|
| "PrePair"
|
|
@@ -1427,17 +1568,9 @@ export interface PairRequestMessage {
|
|
|
1427
1568
|
nonce: bigint;
|
|
1428
1569
|
communication_info?: CommunicationInfo;
|
|
1429
1570
|
parameter_range?: ParameterRange;
|
|
1430
|
-
/**
|
|
1431
|
-
* @deprecated Reading this field directly is incorrect: its meaning narrowed
|
|
1432
|
-
* to "one entry of a list, and possibly absent", so a peer advertising only
|
|
1433
|
-
* `supported_transports` looks unreachable to a reader that was correct
|
|
1434
|
-
* before 0.0.3. Call {@link advertisedEndpoints}, which resolves both
|
|
1435
|
-
* spellings. Removed at 0.0.5.
|
|
1436
|
-
*/
|
|
1437
|
-
transport_protocol?: TransportProtocol;
|
|
1438
1571
|
timestamp?: Timestamp;
|
|
1439
1572
|
/** Every transport endpoint the initiator can be reached on, in its own
|
|
1440
|
-
* preference order.
|
|
1573
|
+
* preference order. */
|
|
1441
1574
|
supported_transports: TransportProtocol[];
|
|
1442
1575
|
}
|
|
1443
1576
|
|
|
@@ -1459,21 +1592,12 @@ export interface PairResponseMessage {
|
|
|
1459
1592
|
|
|
1460
1593
|
export interface PrePairRequestMessage {
|
|
1461
1594
|
nonce: bigint;
|
|
1462
|
-
/**
|
|
1463
|
-
* @deprecated Reading this field directly is incorrect: its meaning narrowed
|
|
1464
|
-
* to "one entry of a list, and possibly absent", so a peer advertising only
|
|
1465
|
-
* `supported_transports` looks unreachable to a reader that was correct
|
|
1466
|
-
* before 0.0.3. Call {@link advertisedEndpoints}, which resolves both
|
|
1467
|
-
* spellings. Removed at 0.0.5.
|
|
1468
|
-
*/
|
|
1469
|
-
transport_protocol?: TransportProtocol;
|
|
1470
1595
|
timestamp?: Timestamp;
|
|
1471
1596
|
/**
|
|
1472
1597
|
* Every endpoint the sender can be reached on for the PrePair reply, in
|
|
1473
|
-
* its own preference order.
|
|
1474
|
-
* must be present.
|
|
1598
|
+
* its own preference order.
|
|
1475
1599
|
*/
|
|
1476
|
-
supported_transports
|
|
1600
|
+
supported_transports: TransportProtocol[];
|
|
1477
1601
|
}
|
|
1478
1602
|
|
|
1479
1603
|
export interface PrePairResponseMessage {
|
|
@@ -1659,6 +1783,15 @@ export interface ProducePrePairResult {
|
|
|
1659
1783
|
envelope: Uint8Array;
|
|
1660
1784
|
}
|
|
1661
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
|
+
|
|
1662
1795
|
export interface PrePairRequestExtractResult {
|
|
1663
1796
|
|
|
1664
1797
|
request: PrePairRequestMessage;
|
|
@@ -1711,6 +1844,7 @@ export type DeRecErrorCategory =
|
|
|
1711
1844
|
| "secret_store"
|
|
1712
1845
|
| "channel_store"
|
|
1713
1846
|
| "share_store"
|
|
1847
|
+
| "state_store"
|
|
1714
1848
|
| "input"
|
|
1715
1849
|
| "protobuf"
|
|
1716
1850
|
| "invariant"
|
|
@@ -1724,6 +1858,10 @@ export interface DeRecError {
|
|
|
1724
1858
|
memo?: string;
|
|
1725
1859
|
expected?: number;
|
|
1726
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[];
|
|
1727
1865
|
}
|
|
1728
1866
|
|
|
1729
1867
|
export declare const primitives: {
|
|
@@ -1758,16 +1896,32 @@ export declare const primitives: {
|
|
|
1758
1896
|
* commitment and the scanner must complete a
|
|
1759
1897
|
* `PrePair` round-trip first.
|
|
1760
1898
|
* @param transport_protocols Every endpoint this initiator serves, in
|
|
1761
|
-
* preference order.
|
|
1762
|
-
*
|
|
1763
|
-
*
|
|
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`.
|
|
1764
1907
|
*/
|
|
1765
1908
|
create_contact(
|
|
1766
1909
|
channel_id: bigint,
|
|
1767
1910
|
contact_mode: ContactMode | number,
|
|
1768
1911
|
transport_protocols: TransportProtocol[],
|
|
1912
|
+
nonce?: bigint | number | null,
|
|
1769
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
|
+
*/
|
|
1770
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
|
+
*/
|
|
1771
1925
|
decode_contact(bytes: Uint8Array): ContactMessage;
|
|
1772
1926
|
produce(
|
|
1773
1927
|
kind: SenderKind,
|
|
@@ -1777,7 +1931,17 @@ export declare const primitives: {
|
|
|
1777
1931
|
parameter_range: ParameterRange | null,
|
|
1778
1932
|
): PairingRequestProduceResult;
|
|
1779
1933
|
|
|
1780
|
-
|
|
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 };
|
|
1781
1945
|
|
|
1782
1946
|
/**
|
|
1783
1947
|
* Scanner-side: build a plaintext `PrePairRequest` envelope when the
|
|
@@ -1789,8 +1953,6 @@ export declare const primitives: {
|
|
|
1789
1953
|
/**
|
|
1790
1954
|
* @param own_transports Every endpoint this scanner serves for the
|
|
1791
1955
|
* PrePair reply, in its own preference order.
|
|
1792
|
-
* The first entry also fills the deprecated
|
|
1793
|
-
* singular field for peers predating the list.
|
|
1794
1956
|
*/
|
|
1795
1957
|
produce_pre_pair(
|
|
1796
1958
|
own_transports: TransportProtocol[],
|
|
@@ -1805,6 +1967,10 @@ export declare const primitives: {
|
|
|
1805
1967
|
};
|
|
1806
1968
|
response: {
|
|
1807
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`.
|
|
1808
1974
|
* @param unsafe_connection Accept plaintext peer endpoints
|
|
1809
1975
|
* (`http://`, `grpc://`). Development only.
|
|
1810
1976
|
*/
|
|
@@ -1818,10 +1984,18 @@ export declare const primitives: {
|
|
|
1818
1984
|
): PairingResponseProduceResult;
|
|
1819
1985
|
|
|
1820
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
|
+
*/
|
|
1821
1994
|
process(
|
|
1822
1995
|
contact_message: ContactMessage,
|
|
1823
1996
|
response: PairResponseMessage,
|
|
1824
1997
|
secret_key: Uint8Array,
|
|
1998
|
+
parameter_range: ParameterRange | null,
|
|
1825
1999
|
): PairingProcessResult;
|
|
1826
2000
|
|
|
1827
2001
|
/**
|
|
@@ -1849,7 +2023,41 @@ export declare const primitives: {
|
|
|
1849
2023
|
contact_message: ContactMessage,
|
|
1850
2024
|
response: PrePairResponseMessage,
|
|
1851
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;
|
|
1852
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;
|
|
1853
2061
|
};
|
|
1854
2062
|
recovery: {
|
|
1855
2063
|
request: {
|