@derec-alliance/react-native 0.0.2 → 0.0.4
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 +46 -2
- 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/Primitives.cpp +27 -18
- package/cpp/ProtocolHost.cpp +37 -0
- package/cpp/StoreCallbacks.cpp +127 -19
- package/cpp/derec_ffi.h +145 -24
- package/ios/DeRecFFI.xcframework/ios-arm64/Headers/derec_ffi.h +145 -24
- package/ios/DeRecFFI.xcframework/ios-arm64/libderec_library.a +0 -0
- package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/Headers/derec_ffi.h +145 -24
- package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/libderec_library.a +2 -2
- package/lib/primitives.d.ts +9 -9
- package/lib/primitives.js +63 -13
- package/lib/protocol.d.ts +85 -6
- package/lib/protocol.js +119 -8
- package/lib/types.d.ts +313 -29
- package/lib/types.js +109 -2
- package/package.json +2 -1
- package/src/primitives.ts +77 -21
- package/src/protocol.ts +138 -13
- package/src/types.ts +379 -35
|
@@ -26,23 +26,48 @@
|
|
|
26
26
|
*/
|
|
27
27
|
#define SHARE_ALGORITHM_REPLICA_SECRET 1
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Schema version stamped onto every channel record this build writes.
|
|
31
|
+
*
|
|
32
|
+
* Applications persist [`HelperChannel`] and [`ReplicaMember`] as opaque
|
|
33
|
+
* blobs whose shape the *library* owns, so a field change here is a
|
|
34
|
+
* migration the application cannot write without knowing a schema it does
|
|
35
|
+
* not define. The marker is what lets the library do that migration itself:
|
|
36
|
+
* a reader can tell a record apart by the shape it was written in rather
|
|
37
|
+
* than by guessing from which fields happen to be present.
|
|
38
|
+
*
|
|
39
|
+
* A record written before the marker existed deserializes as version 0 and
|
|
40
|
+
* is upgraded on read. A record claiming a version *newer* than this build
|
|
41
|
+
* understands is refused, because the alternative is silently dropping
|
|
42
|
+
* fields this build cannot see and writing the truncated result back.
|
|
43
|
+
*
|
|
44
|
+
* The value tracks the release that last changed the shape, not the release
|
|
45
|
+
* that is current: it moved to 3 when `transport` became `transports`, and
|
|
46
|
+
* stays there until the next shape change.
|
|
47
|
+
*
|
|
48
|
+
* Declared unconditionally, unlike the serde impls that stamp it: the SDK
|
|
49
|
+
* bridges mirror this number in their own encoders, and a constant they must
|
|
50
|
+
* agree with should not appear and disappear with a feature flag.
|
|
51
|
+
*/
|
|
52
|
+
#define CHANNEL_RECORD_SCHEMA_VERSION 3
|
|
53
|
+
|
|
29
54
|
/**
|
|
30
55
|
* Latest encoding major version, used for all new encodes. Bump only on a
|
|
31
56
|
* breaking format change, adding the matching `vN` module and match arm.
|
|
32
57
|
*/
|
|
33
|
-
#define LATEST
|
|
58
|
+
#define LATEST 3
|
|
34
59
|
|
|
35
60
|
/**
|
|
36
61
|
* Minimum number of shares required to reconstruct the secret, absent an
|
|
37
|
-
* explicit [`DeRecProtocolBuilder::with_threshold`] call. This is the sole
|
|
38
|
-
* definition of the value — [`DeRecProtocolBuilder::new`] and the FFI
|
|
62
|
+
* explicit [`DeRecProtocolBuilder::with_threshold`](crate::protocol::DeRecProtocolBuilder::with_threshold) call. This is the sole
|
|
63
|
+
* definition of the value — [`DeRecProtocolBuilder::new`](crate::protocol::DeRecProtocolBuilder::new) and the FFI
|
|
39
64
|
* config's serde default both read it rather than each hardcoding `3`.
|
|
40
65
|
*/
|
|
41
66
|
#define DEFAULT_THRESHOLD 3
|
|
42
67
|
|
|
43
68
|
/**
|
|
44
69
|
* Number of recent share versions each helper retains, absent an explicit
|
|
45
|
-
* [`DeRecProtocolBuilder::with_keep_versions_count`] call. Sole definition
|
|
70
|
+
* [`DeRecProtocolBuilder::with_keep_versions_count`](crate::protocol::DeRecProtocolBuilder::with_keep_versions_count) call. Sole definition
|
|
46
71
|
* of the value; see [`DEFAULT_THRESHOLD`].
|
|
47
72
|
*/
|
|
48
73
|
#define DEFAULT_KEEP_VERSIONS_COUNT 3
|
|
@@ -263,6 +288,26 @@
|
|
|
263
288
|
*/
|
|
264
289
|
#define DEREC_CODE_TRANSPORT_INVALID 120
|
|
265
290
|
|
|
291
|
+
/**
|
|
292
|
+
* No transport is shared with the peer — its offered endpoints and this
|
|
293
|
+
* application's served endpoints intersect to nothing. Always a local,
|
|
294
|
+
* terminal error: push-only delivery means an unreachable peer also
|
|
295
|
+
* cannot be told. `DEREC_CATEGORY_INVALID_INPUT`.
|
|
296
|
+
*/
|
|
297
|
+
#define DEREC_CODE_NO_USABLE_ENDPOINT 121
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Both plaintext opt-in flags were set explicitly and disagree: the
|
|
301
|
+
* deprecated `unsafe_http` says one thing and `unsafe_connection` the
|
|
302
|
+
* other. Raised at protocol construction rather than resolved by
|
|
303
|
+
* precedence, because the flag precedence would favour is the one being
|
|
304
|
+
* removed, and a configuration layer that emits every field
|
|
305
|
+
* unconditionally would otherwise let a defaulted value silently beat a
|
|
306
|
+
* deliberate one. Set only `unsafe_connection`.
|
|
307
|
+
* `DEREC_CATEGORY_INVALID_INPUT`.
|
|
308
|
+
*/
|
|
309
|
+
#define DEREC_CODE_CONFLICTING_PLAINTEXT_OPT_IN 122
|
|
310
|
+
|
|
266
311
|
/**
|
|
267
312
|
* Discriminants selecting which message [`derec_decode_message_json`] and
|
|
268
313
|
* [`derec_encode_message_json`] operate on.
|
|
@@ -301,7 +346,7 @@
|
|
|
301
346
|
/**
|
|
302
347
|
* Not a standalone message on the wire, but it crosses this FFI on its own
|
|
303
348
|
* as the `transport_protocol` argument of `create_contact_message` and the
|
|
304
|
-
* `
|
|
349
|
+
* `peer_transports` result of `produce_pair_response_message`.
|
|
305
350
|
*/
|
|
306
351
|
#define DEREC_MESSAGE_KIND_TRANSPORT_PROTOCOL 14
|
|
307
352
|
|
|
@@ -345,13 +390,13 @@
|
|
|
345
390
|
* Replica catch-up. Takes no parameters: the group and this device's own
|
|
346
391
|
* version are both read from the stores.
|
|
347
392
|
*/
|
|
348
|
-
#define
|
|
393
|
+
#define FLOW_KIND_REPLICA_DISCOVERY 7
|
|
349
394
|
|
|
350
395
|
/**
|
|
351
396
|
* Remove a member from the replica group. Params:
|
|
352
397
|
* `{ "replica_id": "<decimal>", "memo": "<optional>" }`.
|
|
353
398
|
*/
|
|
354
|
-
#define
|
|
399
|
+
#define FLOW_KIND_UNPAIR_REPLICA 8
|
|
355
400
|
|
|
356
401
|
/**
|
|
357
402
|
* Opaque handle returned by [`derec_protocol_new`] and consumed by
|
|
@@ -552,7 +597,7 @@ typedef struct ExtractPairRequestResult {
|
|
|
552
597
|
typedef struct ProducePairResponseMessageResult {
|
|
553
598
|
struct DeRecError error;
|
|
554
599
|
struct DeRecBuffer response_wire_bytes;
|
|
555
|
-
struct DeRecBuffer
|
|
600
|
+
struct DeRecBuffer peer_transports;
|
|
556
601
|
struct DeRecBuffer shared_key;
|
|
557
602
|
/**
|
|
558
603
|
* Post-handshake rekey channel id the responder is committing to.
|
|
@@ -694,6 +739,17 @@ typedef struct DeRecProtocolNewResult {
|
|
|
694
739
|
* [`crate::protocol::types::HelperChannel`] and
|
|
695
740
|
* [`crate::protocol::types::ReplicaMember`] respectively.
|
|
696
741
|
*
|
|
742
|
+
* Both listing callbacks receive a `filter` buffer holding a JSON-encoded
|
|
743
|
+
* [`crate::protocol::types::HelperFilter`] or
|
|
744
|
+
* [`crate::protocol::types::ReplicaFilter`] — an object with `ids`, `status`,
|
|
745
|
+
* `role` and `exclude`, where an empty array or a null `role` restricts
|
|
746
|
+
* nothing. A backend should apply it in its query rather than by listing
|
|
747
|
+
* everything and discarding rows; see
|
|
748
|
+
* [`crate::protocol::types::ChannelFilter`]. The library re-applies it to
|
|
749
|
+
* whatever comes back, so ignoring it is slow rather than wrong — but
|
|
750
|
+
* returning fewer rows than it selects is wrong, and undetectable. The buffer is owned
|
|
751
|
+
* by the caller and valid only for the duration of the call.
|
|
752
|
+
*
|
|
697
753
|
* The order `list_replicas` returns is significant in exactly one situation —
|
|
698
754
|
* it selects the successor when the group's source is removed. See
|
|
699
755
|
* [`crate::protocol::DeRecChannelStore::replicas`] for the full contract.
|
|
@@ -717,8 +773,18 @@ typedef struct ChannelStoreCallbacks {
|
|
|
717
773
|
uint64_t channel_id,
|
|
718
774
|
uint64_t replica_id,
|
|
719
775
|
uint32_t *out_existed);
|
|
720
|
-
int32_t (*list_helpers)(void *user_data,
|
|
721
|
-
|
|
776
|
+
int32_t (*list_helpers)(void *user_data,
|
|
777
|
+
uint64_t secret_id,
|
|
778
|
+
const uint8_t *filter,
|
|
779
|
+
size_t filter_len,
|
|
780
|
+
uint8_t **out_ptr,
|
|
781
|
+
size_t *out_len);
|
|
782
|
+
int32_t (*list_replicas)(void *user_data,
|
|
783
|
+
uint64_t secret_id,
|
|
784
|
+
const uint8_t *filter,
|
|
785
|
+
size_t filter_len,
|
|
786
|
+
uint8_t **out_ptr,
|
|
787
|
+
size_t *out_len);
|
|
722
788
|
int32_t (*link_channel)(void *user_data, uint64_t secret_id, uint64_t a, uint64_t b);
|
|
723
789
|
int32_t (*linked_channels)(void *user_data,
|
|
724
790
|
uint64_t secret_id,
|
|
@@ -861,10 +927,24 @@ typedef struct StateStoreCallbacks {
|
|
|
861
927
|
*/
|
|
862
928
|
typedef struct TransportCallbacks {
|
|
863
929
|
void *user_data;
|
|
930
|
+
/**
|
|
931
|
+
* Deliver `bytes` to a peer reachable at any of `endpoints`.
|
|
932
|
+
*
|
|
933
|
+
* `endpoints` is a length-delimited sequence of encoded
|
|
934
|
+
* `TransportProtocol` messages — each entry preceded by its protobuf
|
|
935
|
+
* varint byte length, the same framing protobuf uses for a repeated
|
|
936
|
+
* embedded message field. They are the endpoints that peer advertised,
|
|
937
|
+
* in the order it offered them, already filtered to those the library
|
|
938
|
+
* will record.
|
|
939
|
+
*
|
|
940
|
+
* The library does not rank them. Which endpoint to dial, and whether
|
|
941
|
+
* to fall back to another when one is unreachable, is the
|
|
942
|
+
* implementation's choice. Return `0` once the message has reached any
|
|
943
|
+
* one of them; non-zero only when it reached none.
|
|
944
|
+
*/
|
|
864
945
|
int32_t (*send)(void *user_data,
|
|
865
|
-
const uint8_t *
|
|
866
|
-
size_t
|
|
867
|
-
int32_t protocol,
|
|
946
|
+
const uint8_t *endpoints_ptr,
|
|
947
|
+
size_t endpoints_len,
|
|
868
948
|
const uint8_t *bytes,
|
|
869
949
|
size_t len);
|
|
870
950
|
} TransportCallbacks;
|
|
@@ -1287,8 +1367,8 @@ struct DeRecMessageJsonResult derec_encode_message_json(int32_t kind,
|
|
|
1287
1367
|
*/
|
|
1288
1368
|
struct CreateContactMessageResult create_contact_message(uint64_t channel_id,
|
|
1289
1369
|
int32_t contact_mode,
|
|
1290
|
-
const uint8_t *
|
|
1291
|
-
size_t
|
|
1370
|
+
const uint8_t *transport_protocols_ptr,
|
|
1371
|
+
size_t transport_protocols_len,
|
|
1292
1372
|
uint32_t has_nonce,
|
|
1293
1373
|
uint64_t nonce);
|
|
1294
1374
|
|
|
@@ -1362,8 +1442,8 @@ struct DecodeContactMessageResult decode_contact_message(const uint8_t *contact_
|
|
|
1362
1442
|
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1363
1443
|
*/
|
|
1364
1444
|
struct ProducePairRequestMessageResult produce_pair_request_message(int32_t sender_kind,
|
|
1365
|
-
const uint8_t *
|
|
1366
|
-
size_t
|
|
1445
|
+
const uint8_t *transport_protocols_ptr,
|
|
1446
|
+
size_t transport_protocols_len,
|
|
1367
1447
|
const uint8_t *contact_message_ptr,
|
|
1368
1448
|
size_t contact_message_len,
|
|
1369
1449
|
const uint8_t *communication_info_ptr,
|
|
@@ -1402,7 +1482,8 @@ struct ProducePairResponseMessageResult produce_pair_response_message(uint64_t c
|
|
|
1402
1482
|
const uint8_t *communication_info_ptr,
|
|
1403
1483
|
size_t communication_info_len,
|
|
1404
1484
|
const uint8_t *parameter_range_ptr,
|
|
1405
|
-
size_t parameter_range_len
|
|
1485
|
+
size_t parameter_range_len,
|
|
1486
|
+
uint32_t unsafe_connection);
|
|
1406
1487
|
|
|
1407
1488
|
/**
|
|
1408
1489
|
* # Safety
|
|
@@ -1439,8 +1520,8 @@ struct ProcessPairResponseMessageResult process_pair_response_message(const uint
|
|
|
1439
1520
|
*
|
|
1440
1521
|
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1441
1522
|
*/
|
|
1442
|
-
struct ProducePrePairRequestMessageResult produce_pre_pair_request_message(const uint8_t *
|
|
1443
|
-
size_t
|
|
1523
|
+
struct ProducePrePairRequestMessageResult produce_pre_pair_request_message(const uint8_t *transport_protocols_ptr,
|
|
1524
|
+
size_t transport_protocols_len,
|
|
1444
1525
|
const uint8_t *contact_message_ptr,
|
|
1445
1526
|
size_t contact_message_len);
|
|
1446
1527
|
|
|
@@ -1527,6 +1608,7 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
|
|
|
1527
1608
|
* "secret_id": "12345678901234567890",
|
|
1528
1609
|
* "own_transport_uri": "https://example.com/derec",
|
|
1529
1610
|
* "own_transport_protocol": 1,
|
|
1611
|
+
* "own_transports": [{ "uri": "https://example.com/derec", "protocol": 0 }],
|
|
1530
1612
|
* "threshold": 3,
|
|
1531
1613
|
* "keep_versions_count": 2,
|
|
1532
1614
|
* "timeout_in_secs": 30,
|
|
@@ -1553,6 +1635,11 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
|
|
|
1553
1635
|
* `derec_protocol_set_own_transport` must be called before pairing
|
|
1554
1636
|
* in that case.
|
|
1555
1637
|
* - `own_transport_protocol`: [`derec_proto::Protocol`] discriminant.
|
|
1638
|
+
* - `own_transports`: every endpoint this application serves, in
|
|
1639
|
+
* preference order — the order decides which of a peer's offered
|
|
1640
|
+
* endpoints is used. Optional; when non-empty it takes precedence over
|
|
1641
|
+
* `own_transport_uri` / `own_transport_protocol`, which stay fully
|
|
1642
|
+
* supported for callers that serve a single transport.
|
|
1556
1643
|
* - `threshold` / `keep_versions_count`: optional; omitted means
|
|
1557
1644
|
* [`crate::protocol::DEFAULT_THRESHOLD`] /
|
|
1558
1645
|
* [`crate::protocol::DEFAULT_KEEP_VERSIONS_COUNT`].
|
|
@@ -1634,10 +1721,17 @@ struct DeRecError derec_protocol_set_communication_info(struct DeRecProtocolHand
|
|
|
1634
1721
|
size_t info_json_len);
|
|
1635
1722
|
|
|
1636
1723
|
/**
|
|
1637
|
-
* Replace this node's
|
|
1638
|
-
*
|
|
1639
|
-
*
|
|
1640
|
-
*
|
|
1724
|
+
* Replace this node's endpoint **for one protocol**, leaving the others
|
|
1725
|
+
* alone. A node serves at most one endpoint per protocol, so the `(uri,
|
|
1726
|
+
* protocol)` pair identifies the entry it replaces; an entry for a protocol
|
|
1727
|
+
* not yet served is appended, and a replaced one keeps its position in the
|
|
1728
|
+
* preference order. See
|
|
1729
|
+
* [`crate::protocol::DeRecProtocol::set_own_transport`] for the changeover
|
|
1730
|
+
* discipline (keep the old endpoint up during the transition).
|
|
1731
|
+
*
|
|
1732
|
+
* Superseded by [`derec_protocol_set_own_transports`], which takes the
|
|
1733
|
+
* whole preference list and is the only way to change *which* protocols
|
|
1734
|
+
* this node serves, or their order.
|
|
1641
1735
|
*
|
|
1642
1736
|
* # Safety
|
|
1643
1737
|
*
|
|
@@ -1650,11 +1744,38 @@ struct DeRecError derec_protocol_set_communication_info(struct DeRecProtocolHand
|
|
|
1650
1744
|
* from different threads are safe: the handle's internal mutex
|
|
1651
1745
|
* serializes them.
|
|
1652
1746
|
*/
|
|
1747
|
+
__attribute__((deprecated("use derec_protocol_set_own_transports, which takes the whole preference list; removed at 0.0.5")))
|
|
1653
1748
|
struct DeRecError derec_protocol_set_own_transport(struct DeRecProtocolHandle *handle,
|
|
1654
1749
|
const uint8_t *uri_ptr,
|
|
1655
1750
|
size_t uri_len,
|
|
1656
1751
|
int32_t protocol);
|
|
1657
1752
|
|
|
1753
|
+
/**
|
|
1754
|
+
* Replace every endpoint this node advertises, in preference order.
|
|
1755
|
+
*
|
|
1756
|
+
* The runtime counterpart to the `own_transports` array accepted by
|
|
1757
|
+
* [`super::derec_protocol_new`], and the way to change the whole set:
|
|
1758
|
+
* `derec_protocol_set_own_transport` replaces only the entry for the
|
|
1759
|
+
* protocol its URI names. A device serves at most one endpoint per
|
|
1760
|
+
* protocol, so this list is a preference order over distinct protocols and
|
|
1761
|
+
* two entries of the same protocol are rejected. Body is the same JSON
|
|
1762
|
+
* shape that config array uses — `[{"uri": "...", "protocol": 0}, ...]`.
|
|
1763
|
+
*
|
|
1764
|
+
* Every entry is validated before any is stored, so a malformed URI
|
|
1765
|
+
* leaves the previous set intact rather than half-applied.
|
|
1766
|
+
*
|
|
1767
|
+
* # Safety
|
|
1768
|
+
*
|
|
1769
|
+
* `handle` must be a valid pointer returned by
|
|
1770
|
+
* [`super::derec_protocol_new`]. `json_ptr`/`json_len` must describe a
|
|
1771
|
+
* readable byte range. Concurrent calls on the same handle from
|
|
1772
|
+
* different threads are safe: the handle's internal mutex serializes
|
|
1773
|
+
* them.
|
|
1774
|
+
*/
|
|
1775
|
+
struct DeRecError derec_protocol_set_own_transports(struct DeRecProtocolHandle *handle,
|
|
1776
|
+
const uint8_t *json_ptr,
|
|
1777
|
+
size_t json_len);
|
|
1778
|
+
|
|
1658
1779
|
/**
|
|
1659
1780
|
* Remove `Pending` channels older than `older_than_secs`. See
|
|
1660
1781
|
* [`crate::protocol::DeRecProtocol::remove_expired_channels`] for the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/libderec_library.a
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 38499968 bytes
|
|
4
|
+
sha256: 0f0d9b66c46cfb8f2fe9557186b549831df6ee476ad5d5397428a012a027037c
|
package/lib/primitives.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ declare function decodeContact(wire: Uint8Array | ArrayBuffer): ContactMessage;
|
|
|
12
12
|
export declare const primitives: {
|
|
13
13
|
discovery: {
|
|
14
14
|
request: {
|
|
15
|
-
produce(channel_id: bigint, shared_key: Uint8Array, reply_to?: TransportProtocol
|
|
15
|
+
produce(channel_id: bigint, shared_key: Uint8Array, reply_to?: TransportProtocol[]): ProduceResult;
|
|
16
16
|
extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): {
|
|
17
17
|
request: GetSecretIdsVersionsRequestMessage;
|
|
18
18
|
};
|
|
@@ -27,22 +27,22 @@ export declare const primitives: {
|
|
|
27
27
|
};
|
|
28
28
|
pairing: {
|
|
29
29
|
request: {
|
|
30
|
-
create_contact(channel_id: bigint, contact_mode: ContactMode | number,
|
|
30
|
+
create_contact(channel_id: bigint, contact_mode: ContactMode | number, transport_protocols: TransportProtocol[]): CreateContactResult;
|
|
31
31
|
/** Proto-encodes a `ContactMessage`. Rejects a contact that violates the
|
|
32
32
|
* mode/field invariant rather than serializing it. */
|
|
33
33
|
encode_contact: typeof encodeContact;
|
|
34
34
|
/** Decodes proto `ContactMessage` bytes. Rejects a contact that violates
|
|
35
35
|
* the mode/field invariant rather than returning it. */
|
|
36
36
|
decode_contact: typeof decodeContact;
|
|
37
|
-
produce(kind: SenderKind,
|
|
37
|
+
produce(kind: SenderKind, transport_protocols: TransportProtocol[], contact_message: ContactMessage, communication_info: CommunicationInfo | null, parameter_range: ParameterRange | null): PairingRequestProduceResult;
|
|
38
38
|
extract(envelope_bytes: Uint8Array, secret_key: Uint8Array): {
|
|
39
39
|
request: PairRequestMessage;
|
|
40
40
|
};
|
|
41
|
-
produce_pre_pair(
|
|
41
|
+
produce_pre_pair(own_transports: TransportProtocol[], contact_message: ContactMessage): ProducePrePairResult;
|
|
42
42
|
extract_pre_pair(envelope_bytes: Uint8Array): PrePairRequestExtractResult;
|
|
43
43
|
};
|
|
44
44
|
response: {
|
|
45
|
-
produce(channel_id: bigint, request: PairRequestMessage, secret_key: Uint8Array, communication_info: CommunicationInfo | null, parameter_range: ParameterRange | null): PairingResponseProduceResult;
|
|
45
|
+
produce(channel_id: bigint, request: PairRequestMessage, secret_key: Uint8Array, communication_info: CommunicationInfo | null, parameter_range: ParameterRange | null, unsafe_connection?: boolean): PairingResponseProduceResult;
|
|
46
46
|
extract(envelope_bytes: Uint8Array, secret_key: Uint8Array): {
|
|
47
47
|
response: PairResponseMessage;
|
|
48
48
|
};
|
|
@@ -54,7 +54,7 @@ export declare const primitives: {
|
|
|
54
54
|
};
|
|
55
55
|
recovery: {
|
|
56
56
|
request: {
|
|
57
|
-
produce(channel_id: bigint, secret_id: bigint, version: number, shared_key: Uint8Array, reply_to?: TransportProtocol
|
|
57
|
+
produce(channel_id: bigint, secret_id: bigint, version: number, shared_key: Uint8Array, reply_to?: TransportProtocol[]): ProduceResult;
|
|
58
58
|
extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): {
|
|
59
59
|
request: GetShareRequestMessage;
|
|
60
60
|
};
|
|
@@ -70,7 +70,7 @@ export declare const primitives: {
|
|
|
70
70
|
sharing: {
|
|
71
71
|
request: {
|
|
72
72
|
split(channels: bigint[], secret_id: bigint, version: number, secret_data: Uint8Array, threshold: number): SplitResult;
|
|
73
|
-
produce(channel_id: bigint, version: number, secret_id: bigint, committed_share: CommittedDeRecShare, keep_list: number[], description: string, shared_key: Uint8Array, reply_to?: TransportProtocol
|
|
73
|
+
produce(channel_id: bigint, version: number, secret_id: bigint, committed_share: CommittedDeRecShare, keep_list: number[], description: string, shared_key: Uint8Array, reply_to?: TransportProtocol[]): ProduceResult;
|
|
74
74
|
extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): {
|
|
75
75
|
request: StoreShareRequestMessage;
|
|
76
76
|
};
|
|
@@ -85,7 +85,7 @@ export declare const primitives: {
|
|
|
85
85
|
};
|
|
86
86
|
unpairing: {
|
|
87
87
|
request: {
|
|
88
|
-
produce(channel_id: bigint, memo: string, shared_key: Uint8Array, reply_to?: TransportProtocol
|
|
88
|
+
produce(channel_id: bigint, memo: string, shared_key: Uint8Array, reply_to?: TransportProtocol[]): ProduceResult;
|
|
89
89
|
extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): {
|
|
90
90
|
request: UnpairRequestMessage;
|
|
91
91
|
};
|
|
@@ -109,7 +109,7 @@ export declare const primitives: {
|
|
|
109
109
|
};
|
|
110
110
|
verification: {
|
|
111
111
|
request: {
|
|
112
|
-
produce(channel_id: bigint, secret_id: bigint, version: number, shared_key: Uint8Array, reply_to?: TransportProtocol
|
|
112
|
+
produce(channel_id: bigint, secret_id: bigint, version: number, shared_key: Uint8Array, reply_to?: TransportProtocol[]): ProduceResult;
|
|
113
113
|
extract(envelope_bytes: Uint8Array, shared_key: Uint8Array): {
|
|
114
114
|
request: VerifyShareRequestMessage;
|
|
115
115
|
};
|
package/lib/primitives.js
CHANGED
|
@@ -28,11 +28,11 @@ function call(name, ...args) {
|
|
|
28
28
|
function bytes(value) {
|
|
29
29
|
return new Uint8Array(value);
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
/** An omitted or empty list means "no override" for every reply-to argument;
|
|
32
|
+
* the C ABI reads a zero-length buffer as absent, and the responder then
|
|
33
|
+
* routes to the endpoints already recorded for the channel. */
|
|
34
34
|
function replyTo(value) {
|
|
35
|
-
return
|
|
35
|
+
return value && value.length > 0 ? encodeTransportList(value) : new Uint8Array(0);
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* `ContactMessage` keeps its own dedicated codec rather than going through
|
|
@@ -79,14 +79,64 @@ const discovery = {
|
|
|
79
79
|
},
|
|
80
80
|
},
|
|
81
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* Frames a preference-ordered endpoint list for the native seam: each entry
|
|
84
|
+
* preceded by its protobuf varint byte length. Order is preserved exactly.
|
|
85
|
+
*/
|
|
86
|
+
function encodeTransportList(transports) {
|
|
87
|
+
const entries = transports.map((t) => new Uint8Array((0, messages_1.encodeMessage)(messages_1.MessageKind.TransportProtocol, t)));
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const entry of entries) {
|
|
90
|
+
let len = entry.length;
|
|
91
|
+
do {
|
|
92
|
+
let b = len & 0x7f;
|
|
93
|
+
len >>>= 7;
|
|
94
|
+
if (len !== 0)
|
|
95
|
+
b |= 0x80;
|
|
96
|
+
out.push(b);
|
|
97
|
+
} while (len !== 0);
|
|
98
|
+
out.push(...entry);
|
|
99
|
+
}
|
|
100
|
+
return new Uint8Array(out);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Reads the framing `encodeTransportList` writes. Order is the peer's and is
|
|
104
|
+
* preserved exactly — the library filters a peer's endpoints but never ranks
|
|
105
|
+
* them, so this order is the peer's own preference, not a recommendation.
|
|
106
|
+
*/
|
|
107
|
+
function decodeTransportList(framed) {
|
|
108
|
+
const buf = framed instanceof Uint8Array ? framed : new Uint8Array(framed);
|
|
109
|
+
const out = [];
|
|
110
|
+
let i = 0;
|
|
111
|
+
while (i < buf.length) {
|
|
112
|
+
let len = 0;
|
|
113
|
+
let shift = 0;
|
|
114
|
+
for (;;) {
|
|
115
|
+
if (i >= buf.length) {
|
|
116
|
+
throw new Error('truncated transport list: length prefix runs past the end');
|
|
117
|
+
}
|
|
118
|
+
const b = buf[i++];
|
|
119
|
+
len |= (b & 0x7f) << shift;
|
|
120
|
+
if ((b & 0x80) === 0)
|
|
121
|
+
break;
|
|
122
|
+
shift += 7;
|
|
123
|
+
}
|
|
124
|
+
if (i + len > buf.length) {
|
|
125
|
+
throw new Error('truncated transport list: entry runs past the end');
|
|
126
|
+
}
|
|
127
|
+
out.push((0, messages_1.decodeMessage)(messages_1.MessageKind.TransportProtocol, buf.subarray(i, i + len)));
|
|
128
|
+
i += len;
|
|
129
|
+
}
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
82
132
|
const pairing = {
|
|
83
133
|
request: {
|
|
84
|
-
create_contact(channel_id, contact_mode,
|
|
134
|
+
create_contact(channel_id, contact_mode, transport_protocols) {
|
|
85
135
|
// The C entry point also accepts a caller-supplied nonce behind a
|
|
86
136
|
// presence flag. `@derec-alliance/nodejs` has no such parameter, so the
|
|
87
137
|
// flag is 0 and the library generates one — the same behaviour, not a
|
|
88
138
|
// default invented here.
|
|
89
|
-
const result = call('create_contact_message', channel_id, contact_mode, (
|
|
139
|
+
const result = call('create_contact_message', channel_id, contact_mode, encodeTransportList(transport_protocols), 0, 0n);
|
|
90
140
|
return {
|
|
91
141
|
contact_message: decodeContact(result.contact_wire_bytes),
|
|
92
142
|
secret_key: bytes(result.secret_key_material),
|
|
@@ -98,8 +148,8 @@ const pairing = {
|
|
|
98
148
|
/** Decodes proto `ContactMessage` bytes. Rejects a contact that violates
|
|
99
149
|
* the mode/field invariant rather than returning it. */
|
|
100
150
|
decode_contact: decodeContact,
|
|
101
|
-
produce(kind,
|
|
102
|
-
const result = call('produce_pair_request_message', kind, (
|
|
151
|
+
produce(kind, transport_protocols, contact_message, communication_info, parameter_range) {
|
|
152
|
+
const result = call('produce_pair_request_message', kind, encodeTransportList(transport_protocols), encodeContact(contact_message), (0, messages_1.encodeOptionalMessage)(messages_1.MessageKind.CommunicationInfo, communication_info), (0, messages_1.encodeOptionalMessage)(messages_1.MessageKind.ParameterRange, parameter_range));
|
|
103
153
|
return {
|
|
104
154
|
envelope: bytes(result.request_wire_bytes),
|
|
105
155
|
initiator_contact_message: decodeContact(result.initiator_contact_message_wire_bytes),
|
|
@@ -112,8 +162,8 @@ const pairing = {
|
|
|
112
162
|
request: (0, messages_1.decodeMessage)(messages_1.MessageKind.PairRequest, result.request_proto_bytes),
|
|
113
163
|
};
|
|
114
164
|
},
|
|
115
|
-
produce_pre_pair(
|
|
116
|
-
const envelope = call('produce_pre_pair_request_message', (
|
|
165
|
+
produce_pre_pair(own_transports, contact_message) {
|
|
166
|
+
const envelope = call('produce_pre_pair_request_message', encodeTransportList(own_transports), encodeContact(contact_message));
|
|
117
167
|
return { envelope: bytes(envelope) };
|
|
118
168
|
},
|
|
119
169
|
extract_pre_pair(envelope_bytes) {
|
|
@@ -124,11 +174,11 @@ const pairing = {
|
|
|
124
174
|
},
|
|
125
175
|
},
|
|
126
176
|
response: {
|
|
127
|
-
produce(channel_id, request, secret_key, communication_info, parameter_range) {
|
|
128
|
-
const result = call('produce_pair_response_message', channel_id, (0, messages_1.encodeMessage)(messages_1.MessageKind.PairRequest, request), secret_key, (0, messages_1.encodeOptionalMessage)(messages_1.MessageKind.CommunicationInfo, communication_info), (0, messages_1.encodeOptionalMessage)(messages_1.MessageKind.ParameterRange, parameter_range));
|
|
177
|
+
produce(channel_id, request, secret_key, communication_info, parameter_range, unsafe_connection = false) {
|
|
178
|
+
const result = call('produce_pair_response_message', channel_id, (0, messages_1.encodeMessage)(messages_1.MessageKind.PairRequest, request), secret_key, (0, messages_1.encodeOptionalMessage)(messages_1.MessageKind.CommunicationInfo, communication_info), (0, messages_1.encodeOptionalMessage)(messages_1.MessageKind.ParameterRange, parameter_range), unsafe_connection);
|
|
129
179
|
return {
|
|
130
180
|
envelope: bytes(result.response_wire_bytes),
|
|
131
|
-
|
|
181
|
+
peer_transports: decodeTransportList(result.peer_transports),
|
|
132
182
|
shared_key: bytes(result.shared_key),
|
|
133
183
|
channel_id: result.channel_id,
|
|
134
184
|
};
|
package/lib/protocol.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FlowKind } from './types';
|
|
2
|
-
import type { AutoAcceptPolicy, ChannelStore, ContactMessage, ContactMode, DeRecEvent, DiscoveryParams, PairingParams, ProtectSecretParams, RecoverSecretParams,
|
|
2
|
+
import type { AutoAcceptPolicy, ChannelStore, ContactMessage, ContactMode, DeRecEvent, DiscoveryParams, PairingParams, ParameterRange, ProtectSecretParams, RecoverSecretParams, UnpairReplicaParams, SecretStore, ShareStore, StateStore, ReplicaDiscoveryParams, Timeouts, Transport, UnpairAck, UnpairParams, UpdateChannelInfoParams, UserSecretStore, VerifySharesParams } from './types';
|
|
3
3
|
/** Shape of the `__DeRec` host object as seen from this file: every member is
|
|
4
4
|
* a plain callable, since the JSI layer exposes host functions this way and
|
|
5
5
|
* TypeScript has no static knowledge of them (see `primitives.ts`'s `call`
|
|
@@ -11,7 +11,7 @@ type NativeHost = Record<string, (...args: any[]) => any>;
|
|
|
11
11
|
* against does not carry this enum (it
|
|
12
12
|
* only covers the Rust-internal serde enums listed under its `"enums"` key);
|
|
13
13
|
* the transport `Protocol` enum lives in `protobufs/transportprotocol.proto`
|
|
14
|
-
* instead, where
|
|
14
|
+
* instead, where `HTTPS = 0` and `GRPC = 1` are defined.
|
|
15
15
|
*/
|
|
16
16
|
export declare function protocolDiscriminant(protocol: string): number;
|
|
17
17
|
/**
|
|
@@ -66,10 +66,37 @@ export declare class DeRecProtocolBuilder {
|
|
|
66
66
|
withUserSecretStore(store: UserSecretStore): this;
|
|
67
67
|
withStateStore(store: StateStore): this;
|
|
68
68
|
withTransport(transport: Transport): this;
|
|
69
|
+
/**
|
|
70
|
+
* @deprecated Use {@link withOwnTransports}, which takes the whole
|
|
71
|
+
* preference list — `withOwnTransports([endpoint])` is the direct
|
|
72
|
+
* replacement. Removed at 0.0.5.
|
|
73
|
+
*/
|
|
69
74
|
withOwnTransport(endpoint: {
|
|
70
75
|
uri: string;
|
|
71
76
|
protocol: string;
|
|
72
77
|
}): this;
|
|
78
|
+
/**
|
|
79
|
+
* Set every transport endpoint this application serves, in preference
|
|
80
|
+
* order. Written to the config's `own_transports` array, which takes
|
|
81
|
+
* precedence over `own_transport_uri` / `own_transport_protocol` on the
|
|
82
|
+
* Rust side when non-empty — see `ProtocolConfig` in
|
|
83
|
+
* `library/src/interop/ffi/protocol/handle/mod.rs`.
|
|
84
|
+
*
|
|
85
|
+
* The order given is forwarded verbatim: it is not sorted, deduplicated,
|
|
86
|
+
* or reordered here. It is this application's own preference and
|
|
87
|
+
* decides which of a peer's offered endpoints is used. Every listed
|
|
88
|
+
* transport must actually be served, because delivery is push-only —
|
|
89
|
+
* listing an endpoint this application does not serve makes pairing
|
|
90
|
+
* succeed and replies vanish.
|
|
91
|
+
*
|
|
92
|
+
* Supersedes {@link withOwnTransport} for applications serving more
|
|
93
|
+
* than one transport; the single-endpoint setter remains fully
|
|
94
|
+
* supported.
|
|
95
|
+
*/
|
|
96
|
+
withOwnTransports(transports: {
|
|
97
|
+
uri: string;
|
|
98
|
+
protocol: string;
|
|
99
|
+
}[]): this;
|
|
73
100
|
/** Default: 3. */
|
|
74
101
|
withThreshold(threshold: number): this;
|
|
75
102
|
/** Default: 3. */
|
|
@@ -82,8 +109,22 @@ export declare class DeRecProtocolBuilder {
|
|
|
82
109
|
* `snake_case` keys one for one.
|
|
83
110
|
*/
|
|
84
111
|
withTimeouts(timeouts: Timeouts): this;
|
|
85
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* @deprecated Use {@link withUnsafeConnection}, which names both gated
|
|
114
|
+
* schemes. Removed at 0.0.5. Default: false.
|
|
115
|
+
*/
|
|
86
116
|
withUnsafeHttp(allow: boolean): this;
|
|
117
|
+
/**
|
|
118
|
+
* Accept plaintext `http://` and `grpc://` transport endpoints.
|
|
119
|
+
* **Development only.** Default: false. Supersedes
|
|
120
|
+
* {@link withUnsafeHttp}, which names only the HTTP scheme.
|
|
121
|
+
*
|
|
122
|
+
* Either flag alone is honored. Setting both to disagreeing values fails
|
|
123
|
+
* construction with the error code `CONFLICTING_PLAINTEXT_OPT_IN` rather
|
|
124
|
+
* than resolving silently, because precedence would hand the decision to
|
|
125
|
+
* the flag being removed.
|
|
126
|
+
*/
|
|
127
|
+
withUnsafeConnection(allow: boolean): this;
|
|
87
128
|
/**
|
|
88
129
|
* Default: empty. `derec_protocol_new`'s own `communication_info` argument
|
|
89
130
|
* is a pre-encoded `CommunicationInfo` protobuf message, and this SDK has
|
|
@@ -112,6 +153,17 @@ export declare class DeRecProtocolBuilder {
|
|
|
112
153
|
withAutoAccept(policy: AutoAcceptPolicy): this;
|
|
113
154
|
/** Default: unset. */
|
|
114
155
|
withReplicaId(replicaId: bigint | number): this;
|
|
156
|
+
/**
|
|
157
|
+
* Declare the bounds this node advertises during pair negotiation.
|
|
158
|
+
*
|
|
159
|
+
* Embedded in outbound `PairRequest`/`PairResponse` envelopes and checked
|
|
160
|
+
* against the peer's range on inbound ones: a range that fails to
|
|
161
|
+
* intersect rejects the pairing. Every bound is optional and defaults to
|
|
162
|
+
* `0`, which the protocol reads as "no constraint on this dimension".
|
|
163
|
+
*
|
|
164
|
+
* Default: unset — no constraints advertised, every peer range accepted.
|
|
165
|
+
*/
|
|
166
|
+
withParameterRange(range: Partial<ParameterRange>): this;
|
|
115
167
|
build(): DeRecProtocol;
|
|
116
168
|
}
|
|
117
169
|
/**
|
|
@@ -153,8 +205,35 @@ export declare class DeRecProtocol {
|
|
|
153
205
|
* surfaces a failure that would otherwise be swallowed.
|
|
154
206
|
*/
|
|
155
207
|
setCommunicationInfo(info: Record<string, string>): Promise<void>;
|
|
156
|
-
/**
|
|
208
|
+
/**
|
|
209
|
+
* Replace this node's endpoint for one protocol, leaving the others
|
|
210
|
+
* alone. A node serves at most one endpoint per protocol, so the
|
|
211
|
+
* `(uri, protocol)` pair identifies the entry it replaces; an entry for a
|
|
212
|
+
* protocol not yet served is appended, and a replaced one keeps its
|
|
213
|
+
* position in the preference order.
|
|
214
|
+
*
|
|
215
|
+
* Returns a `Promise` for the same reason {@link setCommunicationInfo} does.
|
|
216
|
+
*
|
|
217
|
+
* @deprecated Use {@link setOwnTransports}, which takes the whole
|
|
218
|
+
* preference list and is the only way to change which protocols this node
|
|
219
|
+
* serves, or their order. Removed at 0.0.5.
|
|
220
|
+
*/
|
|
157
221
|
setOwnTransport(uri: string, protocol: string): Promise<void>;
|
|
222
|
+
/**
|
|
223
|
+
* Replaces every endpoint this node advertises, in preference order —
|
|
224
|
+
* the runtime counterpart to `withOwnTransports`, and the only way to
|
|
225
|
+
* change a multi-endpoint node's set ({@link setOwnTransport} collapses
|
|
226
|
+
* it to the one endpoint it is given).
|
|
227
|
+
*
|
|
228
|
+
* Every entry is validated before any is stored, so a malformed URI
|
|
229
|
+
* leaves the previous set intact. An empty array is rejected.
|
|
230
|
+
*
|
|
231
|
+
* Returns a `Promise` for the same reason {@link setCommunicationInfo} does.
|
|
232
|
+
*/
|
|
233
|
+
setOwnTransports(transports: {
|
|
234
|
+
uri: string;
|
|
235
|
+
protocol: string;
|
|
236
|
+
}[]): Promise<void>;
|
|
158
237
|
/**
|
|
159
238
|
* Decodes the `contact_wire_bytes` `derec_protocol_create_contact`
|
|
160
239
|
* produces into a typed `ContactMessage`, so an application can read the
|
|
@@ -170,8 +249,8 @@ export declare class DeRecProtocol {
|
|
|
170
249
|
start(flowKind: FlowKind.RecoverSecret, params: RecoverSecretParams): Promise<DeRecEvent[]>;
|
|
171
250
|
start(flowKind: FlowKind.Unpair, params: UnpairParams): Promise<DeRecEvent[]>;
|
|
172
251
|
start(flowKind: FlowKind.UpdateChannelInfo, params: UpdateChannelInfoParams): Promise<DeRecEvent[]>;
|
|
173
|
-
start(flowKind: FlowKind.
|
|
174
|
-
start(flowKind: FlowKind.
|
|
252
|
+
start(flowKind: FlowKind.ReplicaDiscovery, params?: ReplicaDiscoveryParams): Promise<DeRecEvent[]>;
|
|
253
|
+
start(flowKind: FlowKind.UnpairReplica, params: UnpairReplicaParams): Promise<DeRecEvent[]>;
|
|
175
254
|
process(message: Uint8Array): Promise<DeRecEvent[]>;
|
|
176
255
|
tick(): Promise<DeRecEvent[]>;
|
|
177
256
|
accept(actionBytes: Uint8Array): Promise<DeRecEvent[]>;
|