@derec-alliance/react-native 0.0.5 → 0.0.7
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 +33 -15
- package/android/CMakeLists.txt +1 -1
- package/android/src/main/jniLibs/arm64-v8a/libderec_library.a +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libderec_library.a +0 -0
- package/android/src/main/jniLibs/x86_64/libderec_library.a +0 -0
- package/cpp/Convert.cpp +125 -0
- package/cpp/Convert.h +35 -0
- package/cpp/DeRecInstaller.cpp +0 -12
- package/cpp/Primitives.cpp +175 -26
- package/cpp/Primitives.h +33 -0
- package/cpp/ProtocolHost.cpp +38 -50
- package/cpp/StoreCallbacks.cpp +179 -301
- package/cpp/UserSecretsJson.cpp +109 -0
- package/cpp/UserSecretsJson.h +28 -0
- package/cpp/derec_ffi.h +298 -132
- package/ios/DeRecFFI.xcframework/Info.plist +5 -5
- package/ios/DeRecFFI.xcframework/ios-arm64/Headers/derec_ffi.h +298 -132
- package/ios/DeRecFFI.xcframework/ios-arm64/libderec_library.a +0 -0
- package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/Headers/derec_ffi.h +298 -132
- package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/libderec_library.a +2 -2
- package/lib/errors.d.ts +16 -0
- package/lib/native.d.ts +5 -1
- package/lib/primitives.d.ts +18 -21
- package/lib/primitives.js +48 -25
- package/lib/protocol.d.ts +65 -102
- package/lib/protocol.js +98 -171
- package/lib/types.d.ts +299 -110
- package/lib/types.js +43 -13
- package/package.json +1 -1
- package/src/errors.ts +17 -0
- package/src/native.ts +2 -1
- package/src/primitives.ts +82 -25
- package/src/protocol.ts +105 -189
- package/src/types.ts +304 -99
package/src/protocol.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
ContactMessage,
|
|
12
12
|
ContactMode,
|
|
13
13
|
DeRecEvent,
|
|
14
|
+
Endpoint,
|
|
14
15
|
DiscoveryParams,
|
|
15
16
|
PairingParams,
|
|
16
17
|
ParameterRange,
|
|
@@ -20,6 +21,7 @@ import type {
|
|
|
20
21
|
SecretStore,
|
|
21
22
|
ShareStore,
|
|
22
23
|
StateStore,
|
|
24
|
+
StatusEnum,
|
|
23
25
|
ReplicaDiscoveryParams,
|
|
24
26
|
Target,
|
|
25
27
|
Timeouts,
|
|
@@ -81,25 +83,6 @@ function decodeEvents(buffer: ArrayBuffer): DeRecEvent[] {
|
|
|
81
83
|
return reviveEventBytes(jsonFromBytes(buffer)) as DeRecEvent[];
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
/**
|
|
85
|
-
* Maps a transport protocol name to the `derec_proto::Protocol` discriminant.
|
|
86
|
-
* The shared enum fixture every other numeric mapping in this SDK is checked
|
|
87
|
-
* against does not carry this enum (it
|
|
88
|
-
* only covers the Rust-internal serde enums listed under its `"enums"` key);
|
|
89
|
-
* the transport `Protocol` enum lives in `protobufs/transportprotocol.proto`
|
|
90
|
-
* instead, where `HTTPS = 0` and `GRPC = 1` are defined.
|
|
91
|
-
*/
|
|
92
|
-
export function protocolDiscriminant(protocol: string): number {
|
|
93
|
-
switch (protocol.toLowerCase()) {
|
|
94
|
-
case 'https':
|
|
95
|
-
return 0;
|
|
96
|
-
case 'grpc':
|
|
97
|
-
return 1;
|
|
98
|
-
default:
|
|
99
|
-
throw new Error(`DeRec: unknown transport protocol "${protocol}"`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
86
|
function encodeTarget(target: Target): unknown {
|
|
104
87
|
if (target === null) {
|
|
105
88
|
return null;
|
|
@@ -261,13 +244,8 @@ function buildStartParams(flowKind: FlowKind, params: unknown): Uint8Array {
|
|
|
261
244
|
if (p.communication_info !== undefined) {
|
|
262
245
|
out.communication_info = p.communication_info;
|
|
263
246
|
}
|
|
264
|
-
if (p.own_transports !== undefined
|
|
247
|
+
if (p.own_transports !== undefined) {
|
|
265
248
|
out.own_transports = p.own_transports;
|
|
266
|
-
// The first entry also fills the deprecated singular field so a peer
|
|
267
|
-
// predating `supported_transports` still learns the new address.
|
|
268
|
-
out.transport_protocol = p.own_transports[0];
|
|
269
|
-
} else if (p.transport_protocol !== undefined) {
|
|
270
|
-
out.transport_protocol = p.transport_protocol;
|
|
271
249
|
}
|
|
272
250
|
return jsonToBytes(out);
|
|
273
251
|
}
|
|
@@ -302,9 +280,9 @@ function toBigInt(id: bigint | number): bigint {
|
|
|
302
280
|
*
|
|
303
281
|
* Every value the caller supplies is forwarded verbatim — defaults, clamping
|
|
304
282
|
* and the meaning of a disabled cleanup policy are library decisions.
|
|
305
|
-
* `threshold`, `
|
|
306
|
-
*
|
|
307
|
-
*
|
|
283
|
+
* `threshold`, `auto_respond_on_failure`, `unpair_ack`, `auto_reply_to`
|
|
284
|
+
* and `auto_accept` are omitted entirely from the emitted config unless
|
|
285
|
+
* their setter was called: `ProtocolConfig` has a
|
|
308
286
|
* `#[serde(default = "...")]` on each of them, reading the same constants
|
|
309
287
|
* `DeRecProtocolBuilder::new` uses, so an absent key resolves to the
|
|
310
288
|
* library's own default rather than one frozen into this shim.
|
|
@@ -313,7 +291,6 @@ export class DeRecProtocolBuilder {
|
|
|
313
291
|
private readonly secretIdValue: bigint;
|
|
314
292
|
private config: Record<string, unknown> = {};
|
|
315
293
|
private stores: Record<string, unknown> = {};
|
|
316
|
-
private communicationInfo: Record<string, string> | undefined;
|
|
317
294
|
|
|
318
295
|
constructor(secretId: bigint | number) {
|
|
319
296
|
this.secretIdValue = BigInt(secretId);
|
|
@@ -349,23 +326,10 @@ export class DeRecProtocolBuilder {
|
|
|
349
326
|
return this;
|
|
350
327
|
}
|
|
351
328
|
|
|
352
|
-
/**
|
|
353
|
-
* @deprecated Use {@link withOwnTransports}, which takes the whole
|
|
354
|
-
* preference list — `withOwnTransports([endpoint])` is the direct
|
|
355
|
-
* replacement. Removed at 0.0.5.
|
|
356
|
-
*/
|
|
357
|
-
withOwnTransport(endpoint: { uri: string; protocol: string }): this {
|
|
358
|
-
this.config.own_transport_uri = endpoint.uri;
|
|
359
|
-
this.config.own_transport_protocol = protocolDiscriminant(endpoint.protocol);
|
|
360
|
-
return this;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
329
|
/**
|
|
364
330
|
* Set every transport endpoint this application serves, in preference
|
|
365
|
-
* order. Written to the config's `own_transports` array
|
|
366
|
-
*
|
|
367
|
-
* Rust side when non-empty — see `ProtocolConfig` in
|
|
368
|
-
* `library/src/interop/ffi/protocol/handle/mod.rs`.
|
|
331
|
+
* order. Written to the config's `own_transports` array — see
|
|
332
|
+
* `ProtocolConfig` in `library/src/interop/ffi/protocol/handle/mod.rs`.
|
|
369
333
|
*
|
|
370
334
|
* The order given is forwarded verbatim: it is not sorted, deduplicated,
|
|
371
335
|
* or reordered here. It is this application's own preference and
|
|
@@ -374,15 +338,11 @@ export class DeRecProtocolBuilder {
|
|
|
374
338
|
* listing an endpoint this application does not serve makes pairing
|
|
375
339
|
* succeed and replies vanish.
|
|
376
340
|
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
* supported.
|
|
341
|
+
* Required: `build()` with no own transport is refused by the library,
|
|
342
|
+
* since a node with no endpoint cannot be reached by any peer.
|
|
380
343
|
*/
|
|
381
|
-
withOwnTransports(transports:
|
|
382
|
-
this.config.own_transports = transports.map((
|
|
383
|
-
uri: t.uri,
|
|
384
|
-
protocol: protocolDiscriminant(t.protocol),
|
|
385
|
-
}));
|
|
344
|
+
withOwnTransports(transports: Endpoint[]): this {
|
|
345
|
+
this.config.own_transports = transports.map(({ uri, protocol }) => ({ uri, protocol }));
|
|
386
346
|
return this;
|
|
387
347
|
}
|
|
388
348
|
|
|
@@ -392,12 +352,6 @@ export class DeRecProtocolBuilder {
|
|
|
392
352
|
return this;
|
|
393
353
|
}
|
|
394
354
|
|
|
395
|
-
/** Default: 3. */
|
|
396
|
-
withKeepVersionsCount(count: number): this {
|
|
397
|
-
this.config.keep_versions_count = count;
|
|
398
|
-
return this;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
355
|
/**
|
|
402
356
|
* Every field is optional; not calling this at all leaves all four at the
|
|
403
357
|
* library's defaults — `timeouts` is genuinely absent from the JSON in
|
|
@@ -410,24 +364,9 @@ export class DeRecProtocolBuilder {
|
|
|
410
364
|
return this;
|
|
411
365
|
}
|
|
412
366
|
|
|
413
|
-
/**
|
|
414
|
-
* @deprecated Use {@link withUnsafeConnection}, which names both gated
|
|
415
|
-
* schemes. Removed at 0.0.5. Default: false.
|
|
416
|
-
*/
|
|
417
|
-
withUnsafeHttp(allow: boolean): this {
|
|
418
|
-
this.config.unsafe_http = allow;
|
|
419
|
-
return this;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
367
|
/**
|
|
423
368
|
* Accept plaintext `http://` and `grpc://` transport endpoints.
|
|
424
|
-
* **Development only.** Default: false.
|
|
425
|
-
* {@link withUnsafeHttp}, which names only the HTTP scheme.
|
|
426
|
-
*
|
|
427
|
-
* Either flag alone is honored. Setting both to disagreeing values fails
|
|
428
|
-
* construction with the error code `CONFLICTING_PLAINTEXT_OPT_IN` rather
|
|
429
|
-
* than resolving silently, because precedence would hand the decision to
|
|
430
|
-
* the flag being removed.
|
|
369
|
+
* **Development only.** Default: false.
|
|
431
370
|
*/
|
|
432
371
|
withUnsafeConnection(allow: boolean): this {
|
|
433
372
|
this.config.unsafe_connection = allow;
|
|
@@ -435,24 +374,11 @@ export class DeRecProtocolBuilder {
|
|
|
435
374
|
}
|
|
436
375
|
|
|
437
376
|
/**
|
|
438
|
-
* Default: empty.
|
|
439
|
-
* is
|
|
440
|
-
* no encoder for that message — the C ABI exposes one only for
|
|
441
|
-
* `ContactMessage`. Hand-rolling one here would be SDK-side protocol logic
|
|
442
|
-
* with no test coverage — exactly what this codebase's "Rust decides, the
|
|
443
|
-
* SDK only marshals" rule forbids. Instead,
|
|
444
|
-
* `build()` constructs the protocol with an empty `communication_info`
|
|
445
|
-
* (a legitimate, always-accepted value — see `decode_communication_info`
|
|
446
|
-
* in `library/src/interop/ffi/protocol/handle/mod.rs`, which treats a zero-length
|
|
447
|
-
* buffer as "no entries") and then calls the already-bound
|
|
448
|
-
* {@link DeRecProtocol.setCommunicationInfo}, which takes the same map as
|
|
449
|
-
* plain JSON (`derec_protocol_set_communication_info` in
|
|
450
|
-
* `library/src/interop/ffi/protocol/handle/config.rs`). That setter is queued on
|
|
451
|
-
* the protocol's serial worker before `build()` returns, so it is ordered
|
|
452
|
-
* ahead of every call the caller can subsequently make.
|
|
377
|
+
* Default: empty. Written to the config's `communication_info` key, so the
|
|
378
|
+
* map is part of the protocol from construction.
|
|
453
379
|
*/
|
|
454
380
|
withCommunicationInfo(info: Record<string, string>): this {
|
|
455
|
-
this.
|
|
381
|
+
this.config.communication_info = info;
|
|
456
382
|
return this;
|
|
457
383
|
}
|
|
458
384
|
|
|
@@ -464,13 +390,7 @@ export class DeRecProtocolBuilder {
|
|
|
464
390
|
|
|
465
391
|
/** Default: "required". */
|
|
466
392
|
withUnpairAck(ack: UnpairAck): this {
|
|
467
|
-
|
|
468
|
-
this.config.unpair_ack = 0;
|
|
469
|
-
} else if (ack === 'not_required') {
|
|
470
|
-
this.config.unpair_ack = 1;
|
|
471
|
-
} else {
|
|
472
|
-
throw new Error(`DeRec: unknown unpair ack "${ack as string}"`);
|
|
473
|
-
}
|
|
393
|
+
this.config.unpair_ack = ack;
|
|
474
394
|
return this;
|
|
475
395
|
}
|
|
476
396
|
|
|
@@ -480,17 +400,20 @@ export class DeRecProtocolBuilder {
|
|
|
480
400
|
return this;
|
|
481
401
|
}
|
|
482
402
|
|
|
483
|
-
/**
|
|
403
|
+
/**
|
|
404
|
+
* Default: empty policy (every flow off). A flow left out of `policy` is
|
|
405
|
+
* left out of the config, and the library applies its own default to it.
|
|
406
|
+
*/
|
|
484
407
|
withAutoAccept(policy: AutoAcceptPolicy): this {
|
|
485
408
|
this.config.auto_accept = {
|
|
486
|
-
pairing: policy.pairing
|
|
487
|
-
pre_pair: policy.prePair
|
|
488
|
-
store_share: policy.storeShare
|
|
489
|
-
verify_share: policy.verifyShare
|
|
490
|
-
discovery: policy.discovery
|
|
491
|
-
get_share: policy.getShare
|
|
492
|
-
unpair: policy.unpair
|
|
493
|
-
update_channel_info: policy.updateChannelInfo
|
|
409
|
+
pairing: policy.pairing,
|
|
410
|
+
pre_pair: policy.prePair,
|
|
411
|
+
store_share: policy.storeShare,
|
|
412
|
+
verify_share: policy.verifyShare,
|
|
413
|
+
discovery: policy.discovery,
|
|
414
|
+
get_share: policy.getShare,
|
|
415
|
+
unpair: policy.unpair,
|
|
416
|
+
update_channel_info: policy.updateChannelInfo,
|
|
494
417
|
};
|
|
495
418
|
return this;
|
|
496
419
|
}
|
|
@@ -508,30 +431,26 @@ export class DeRecProtocolBuilder {
|
|
|
508
431
|
* against the peer's range on inbound ones: a range that fails to
|
|
509
432
|
* intersect rejects the pairing. Every bound is optional and defaults to
|
|
510
433
|
* `0`, which the protocol reads as "no constraint on this dimension".
|
|
434
|
+
* Bounds cross to the library as decimal strings, so the full `i64` range
|
|
435
|
+
* survives; a bound left out is left out of the config, and the library
|
|
436
|
+
* applies its default.
|
|
511
437
|
*
|
|
512
438
|
* Default: unset — no constraints advertised, every peer range accepted.
|
|
513
439
|
*/
|
|
514
440
|
withParameterRange(range: Partial<ParameterRange>): this {
|
|
515
|
-
const n = (v: bigint | undefined) => Number(v ?? 0n);
|
|
516
441
|
this.config.parameter_range = {
|
|
517
|
-
min_share_size:
|
|
518
|
-
max_share_size:
|
|
519
|
-
min_time_between_verifications:
|
|
520
|
-
max_time_between_verifications:
|
|
521
|
-
min_time_between_share_updates:
|
|
522
|
-
max_time_between_share_updates:
|
|
523
|
-
min_unresponsive_deletion_timeout:
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
min_unresponsive_deactivation_timeout: n(
|
|
530
|
-
range.min_unresponsive_deactivation_timeout,
|
|
531
|
-
),
|
|
532
|
-
max_unresponsive_deactivation_timeout: n(
|
|
533
|
-
range.max_unresponsive_deactivation_timeout,
|
|
534
|
-
),
|
|
442
|
+
min_share_size: range.min_share_size?.toString(),
|
|
443
|
+
max_share_size: range.max_share_size?.toString(),
|
|
444
|
+
min_time_between_verifications: range.min_time_between_verifications?.toString(),
|
|
445
|
+
max_time_between_verifications: range.max_time_between_verifications?.toString(),
|
|
446
|
+
min_time_between_share_updates: range.min_time_between_share_updates?.toString(),
|
|
447
|
+
max_time_between_share_updates: range.max_time_between_share_updates?.toString(),
|
|
448
|
+
min_unresponsive_deletion_timeout: range.min_unresponsive_deletion_timeout?.toString(),
|
|
449
|
+
max_unresponsive_deletion_timeout: range.max_unresponsive_deletion_timeout?.toString(),
|
|
450
|
+
min_unresponsive_deactivation_timeout:
|
|
451
|
+
range.min_unresponsive_deactivation_timeout?.toString(),
|
|
452
|
+
max_unresponsive_deactivation_timeout:
|
|
453
|
+
range.max_unresponsive_deactivation_timeout?.toString(),
|
|
535
454
|
};
|
|
536
455
|
return this;
|
|
537
456
|
}
|
|
@@ -540,8 +459,6 @@ export class DeRecProtocolBuilder {
|
|
|
540
459
|
const config = {
|
|
541
460
|
secret_id: this.secretIdValue.toString(),
|
|
542
461
|
replica_id: null,
|
|
543
|
-
own_transport_uri: '',
|
|
544
|
-
own_transport_protocol: 0,
|
|
545
462
|
...this.config,
|
|
546
463
|
};
|
|
547
464
|
const host = (getNative() as unknown as NativeHost).protocol_new(
|
|
@@ -549,29 +466,15 @@ export class DeRecProtocolBuilder {
|
|
|
549
466
|
new Uint8Array(0),
|
|
550
467
|
this.stores,
|
|
551
468
|
) as NativeHost;
|
|
552
|
-
|
|
553
|
-
if (this.communicationInfo !== undefined) {
|
|
554
|
-
// `setCommunicationInfo` is asynchronous, but `build()` stays
|
|
555
|
-
// synchronous: the guarantee callers need is not that the map has been
|
|
556
|
-
// applied by the time `build()` returns, it is that no flow can run
|
|
557
|
-
// before it. Posting it here puts it on the protocol's serial worker
|
|
558
|
-
// queue ahead of anything the caller has had the chance to start, so
|
|
559
|
-
// every subsequent call observes it. Left unhandled deliberately — a
|
|
560
|
-
// failure reaches the runtime's unhandled-rejection reporting rather
|
|
561
|
-
// than being silently discarded, and `build()` has no synchronous
|
|
562
|
-
// channel to raise it on.
|
|
563
|
-
void protocol.setCommunicationInfo(this.communicationInfo);
|
|
564
|
-
}
|
|
565
|
-
return protocol;
|
|
469
|
+
return DeRecProtocol.fromHost(host);
|
|
566
470
|
}
|
|
567
471
|
}
|
|
568
472
|
|
|
569
473
|
/**
|
|
570
474
|
* Thin wrapper around the `ProtocolHost` JSI host object, mirroring
|
|
571
475
|
* `@derec-alliance/nodejs`'s `DeRecProtocol` — same methods, and the same
|
|
572
|
-
* sync/async split
|
|
573
|
-
*
|
|
574
|
-
* `secretId` is synchronous and everything else returns a `Promise`. Every method encodes its
|
|
476
|
+
* sync/async split: `secretId` is synchronous and everything else returns a
|
|
477
|
+
* `Promise`. Every method encodes its
|
|
575
478
|
* arguments into the wire shape the host function expects and decodes its
|
|
576
479
|
* result back into the typed value declared here; no protocol decision is
|
|
577
480
|
* made in this class.
|
|
@@ -601,68 +504,39 @@ export class DeRecProtocol {
|
|
|
601
504
|
}
|
|
602
505
|
|
|
603
506
|
/**
|
|
604
|
-
*
|
|
605
|
-
* `void`. The native setter takes the same handle mutex a running flow
|
|
606
|
-
* holds across its store callbacks, so calling it on the JavaScript thread
|
|
607
|
-
* would block that thread until the flow released the mutex — which it
|
|
608
|
-
* cannot do while it is waiting on the JavaScript thread. The binding
|
|
609
|
-
* therefore queues the setter onto the same serial worker every flow runs
|
|
610
|
-
* on, which orders it after any call already in flight. The nodejs SDK is
|
|
611
|
-
* WASM and single-threaded, so it has no such hazard.
|
|
507
|
+
* Replaces this node's local communication info.
|
|
612
508
|
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
509
|
+
* The native setter takes the same handle mutex a running flow holds
|
|
510
|
+
* across its store callbacks, so calling it on the JavaScript thread would
|
|
511
|
+
* block that thread until the flow released the mutex — which it cannot do
|
|
512
|
+
* while it is waiting on the JavaScript thread. The binding therefore
|
|
513
|
+
* queues the setter onto the same serial worker every flow runs on, which
|
|
514
|
+
* orders it after any call already in flight. Awaiting the returned
|
|
515
|
+
* `Promise` surfaces a failure that would otherwise be swallowed.
|
|
616
516
|
*/
|
|
617
517
|
setCommunicationInfo(info: Record<string, string>): Promise<void> {
|
|
618
518
|
return this.host.setCommunicationInfo(jsonToBytes(info)) as Promise<void>;
|
|
619
519
|
}
|
|
620
520
|
|
|
621
|
-
/**
|
|
622
|
-
* Replace this node's endpoint for one protocol, leaving the others
|
|
623
|
-
* alone. A node serves at most one endpoint per protocol, so the
|
|
624
|
-
* `(uri, protocol)` pair identifies the entry it replaces; an entry for a
|
|
625
|
-
* protocol not yet served is appended, and a replaced one keeps its
|
|
626
|
-
* position in the preference order.
|
|
627
|
-
*
|
|
628
|
-
* Returns a `Promise` for the same reason {@link setCommunicationInfo} does.
|
|
629
|
-
*
|
|
630
|
-
* @deprecated Use {@link setOwnTransports}, which takes the whole
|
|
631
|
-
* preference list and is the only way to change which protocols this node
|
|
632
|
-
* serves, or their order. Removed at 0.0.5.
|
|
633
|
-
*/
|
|
634
|
-
setOwnTransport(uri: string, protocol: string): Promise<void> {
|
|
635
|
-
return this.host.setOwnTransport(
|
|
636
|
-
uri,
|
|
637
|
-
protocolDiscriminant(protocol),
|
|
638
|
-
) as Promise<void>;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
521
|
/**
|
|
642
522
|
* Replaces every endpoint this node advertises, in preference order —
|
|
643
|
-
* the runtime counterpart to `withOwnTransports
|
|
644
|
-
* change a multi-endpoint node's set ({@link setOwnTransport} collapses
|
|
645
|
-
* it to the one endpoint it is given).
|
|
523
|
+
* the runtime counterpart to `withOwnTransports`.
|
|
646
524
|
*
|
|
647
525
|
* Every entry is validated before any is stored, so a malformed URI
|
|
648
526
|
* leaves the previous set intact. An empty array is rejected.
|
|
649
527
|
*
|
|
650
|
-
*
|
|
528
|
+
* Queued onto the serial worker for the same reason as
|
|
529
|
+
* {@link setCommunicationInfo}.
|
|
651
530
|
*/
|
|
652
|
-
setOwnTransports(
|
|
653
|
-
transports
|
|
654
|
-
): Promise<void> {
|
|
655
|
-
const wire = transports.map(({ uri, protocol }) => ({
|
|
656
|
-
uri,
|
|
657
|
-
protocol: protocolDiscriminant(protocol),
|
|
658
|
-
}));
|
|
531
|
+
setOwnTransports(transports: Endpoint[]): Promise<void> {
|
|
532
|
+
const wire = transports.map(({ uri, protocol }) => ({ uri, protocol }));
|
|
659
533
|
return this.host.setOwnTransports(jsonToBytes(wire)) as Promise<void>;
|
|
660
534
|
}
|
|
661
535
|
|
|
662
536
|
/**
|
|
663
537
|
* Decodes the `contact_wire_bytes` `derec_protocol_create_contact`
|
|
664
538
|
* produces into a typed `ContactMessage`, so an application can read the
|
|
665
|
-
* contact's `nonce`, `
|
|
539
|
+
* contact's `nonce`, `supported_transports` and mode without a protobuf
|
|
666
540
|
* codec of its own. Feed the returned object straight back into
|
|
667
541
|
* `start(FlowKind.Pairing, { contact })`, which re-encodes it.
|
|
668
542
|
*/
|
|
@@ -699,7 +573,16 @@ export class DeRecProtocol {
|
|
|
699
573
|
}
|
|
700
574
|
|
|
701
575
|
async process(message: Uint8Array): Promise<DeRecEvent[]> {
|
|
702
|
-
|
|
576
|
+
let buffer: ArrayBuffer;
|
|
577
|
+
try {
|
|
578
|
+
buffer = (await this.host.process(message)) as ArrayBuffer;
|
|
579
|
+
} catch (error) {
|
|
580
|
+
const failure = error as { events?: unknown };
|
|
581
|
+
if (Array.isArray(failure.events)) {
|
|
582
|
+
failure.events = reviveEventBytes(failure.events);
|
|
583
|
+
}
|
|
584
|
+
throw error;
|
|
585
|
+
}
|
|
703
586
|
return decodeEvents(buffer);
|
|
704
587
|
}
|
|
705
588
|
|
|
@@ -713,7 +596,7 @@ export class DeRecProtocol {
|
|
|
713
596
|
return decodeEvents(buffer);
|
|
714
597
|
}
|
|
715
598
|
|
|
716
|
-
async reject(actionBytes: Uint8Array, status:
|
|
599
|
+
async reject(actionBytes: Uint8Array, status: StatusEnum, memo: string): Promise<void> {
|
|
717
600
|
await this.host.reject(actionBytes, status, memo);
|
|
718
601
|
}
|
|
719
602
|
|
|
@@ -721,6 +604,16 @@ export class DeRecProtocol {
|
|
|
721
604
|
return (await this.host.getFingerprint(toBigInt(channelId))) as string;
|
|
722
605
|
}
|
|
723
606
|
|
|
607
|
+
/**
|
|
608
|
+
* Verify `fingerprint` against the channel's locally-derived one. On
|
|
609
|
+
* match, the channel transitions from `Pending` to `Paired`. Returns
|
|
610
|
+
* `true` on confirmation, `false` on mismatch.
|
|
611
|
+
*
|
|
612
|
+
* On a replica destination, confirming is also the decision to adopt the
|
|
613
|
+
* group's vault: the source's publish is then installed as it arrives,
|
|
614
|
+
* with no further prompt. Ask the user before calling this; to decline,
|
|
615
|
+
* never confirm.
|
|
616
|
+
*/
|
|
724
617
|
async verifyFingerprint(channelId: bigint | number, fingerprint: string): Promise<boolean> {
|
|
725
618
|
return (await this.host.verifyFingerprint(toBigInt(channelId), fingerprint)) as boolean;
|
|
726
619
|
}
|
|
@@ -730,6 +623,24 @@ export class DeRecProtocol {
|
|
|
730
623
|
return jsonFromBytes(buffer) as string[];
|
|
731
624
|
}
|
|
732
625
|
|
|
626
|
+
/**
|
|
627
|
+
* Rebuild this protocol's `secret_id` namespace from a recovered `Secret`.
|
|
628
|
+
* Pass the `secret` carried by the `SecretRecovered` event verbatim.
|
|
629
|
+
* Recovery and restore are separate steps on purpose: `SecretRecovered`
|
|
630
|
+
* writes nothing. Show the user what was recovered, or ask them, before
|
|
631
|
+
* calling `restore`, which commits it to this device.
|
|
632
|
+
* A helper or member whose `transports` is empty gets no channel: it is
|
|
633
|
+
* reported as a `PeerNotRestored` event in the returned array and the rest
|
|
634
|
+
* of the roster is restored.
|
|
635
|
+
*
|
|
636
|
+
* Rejects with a `DeRecError`; among its codes:
|
|
637
|
+
*
|
|
638
|
+
* | code | meaning |
|
|
639
|
+
* |--------------------|-------------------------------------------------------------|
|
|
640
|
+
* | `already_restored` | A user-secret snapshot already exists for this `secret_id`. |
|
|
641
|
+
* | `restore_conflict` | Channels live at ids restore is about to write. The error |
|
|
642
|
+
* | | carries `channel_ids: string[]` listing the collisions. |
|
|
643
|
+
*/
|
|
733
644
|
async restore(
|
|
734
645
|
recoveredSecret: Extract<DeRecEvent, { type: 'SecretRecovered' }>['secret'],
|
|
735
646
|
version: number,
|
|
@@ -743,4 +654,9 @@ export class DeRecProtocol {
|
|
|
743
654
|
free(): void {
|
|
744
655
|
this.host.free();
|
|
745
656
|
}
|
|
657
|
+
|
|
658
|
+
/** Same as {@link DeRecProtocol.free}, for `using`. */
|
|
659
|
+
[Symbol.dispose](): void {
|
|
660
|
+
this.free();
|
|
661
|
+
}
|
|
746
662
|
}
|