@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/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 +33 -32
- package/index.d.ts +383 -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
|
|
|
@@ -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<
|
|
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:
|
|
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 `
|
|
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.
|
|
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.
|
|
549
|
-
* over `transport_protocol`, whose first entry it also fills.
|
|
583
|
+
* Omitted leaves the target(s)' stored set untouched.
|
|
550
584
|
*/
|
|
551
|
-
own_transports?:
|
|
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:
|
|
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:
|
|
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:
|
|
749
|
+
transports: Endpoint[];
|
|
700
750
|
shared_key: Uint8Array;
|
|
701
|
-
communication_info
|
|
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:
|
|
771
|
+
transports: Endpoint[];
|
|
722
772
|
role: "Source" | "Destination";
|
|
723
|
-
communication_info
|
|
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:
|
|
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:
|
|
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
|
|
756
|
-
* `replica_id` fields inside `secret` are
|
|
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:
|
|
824
|
+
transports: Endpoint[];
|
|
769
825
|
shared_key: Uint8Array;
|
|
770
|
-
communication_info
|
|
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:
|
|
844
|
+
transports: Endpoint[];
|
|
789
845
|
role: "Source" | "Destination";
|
|
790
|
-
communication_info
|
|
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:
|
|
876
|
+
transports: Endpoint[];
|
|
820
877
|
shared_key: Uint8Array;
|
|
821
|
-
communication_info
|
|
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:
|
|
896
|
+
transports: Endpoint[];
|
|
840
897
|
role: "Source" | "Destination";
|
|
841
|
-
communication_info
|
|
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:
|
|
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:
|
|
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
|
|
957
|
-
*
|
|
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`, `
|
|
986
|
-
* `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.
|
|
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
|
|
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:
|
|
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.
|
|
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
|
-
/**
|
|
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.
|
|
1089
|
-
* back here even if the channel's stored peer endpoint
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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.
|
|
1235
|
-
*
|
|
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:
|
|
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
|
-
*
|
|
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
|
-
* | `
|
|
1279
|
-
* | `
|
|
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
|
-
* | `
|
|
1282
|
-
* | `
|
|
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.
|
|
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.
|
|
1463
|
-
* must be present.
|
|
1598
|
+
* its own preference order.
|
|
1464
1599
|
*/
|
|
1465
|
-
supported_transports
|
|
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.
|
|
1751
|
-
*
|
|
1752
|
-
*
|
|
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
|
-
|
|
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: {
|