@derec-alliance/react-native 0.0.1

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.
Files changed (65) hide show
  1. package/DeRec.podspec +25 -0
  2. package/LICENSE +201 -0
  3. package/README.md +222 -0
  4. package/android/CMakeLists.txt +38 -0
  5. package/android/build.gradle +79 -0
  6. package/android/src/main/AndroidManifest.xml +12 -0
  7. package/android/src/main/java/org/derec/DeRecModule.kt +56 -0
  8. package/android/src/main/java/org/derec/DeRecPackage.kt +24 -0
  9. package/android/src/main/jni/OnLoad.cpp +39 -0
  10. package/android/src/main/jniLibs/arm64-v8a/libderec_library.a +0 -0
  11. package/android/src/main/jniLibs/armeabi-v7a/libderec_library.a +0 -0
  12. package/android/src/main/jniLibs/x86_64/libderec_library.a +0 -0
  13. package/cpp/Convert.cpp +50 -0
  14. package/cpp/Convert.h +38 -0
  15. package/cpp/DeRecInstaller.cpp +186 -0
  16. package/cpp/DeRecInstaller.h +28 -0
  17. package/cpp/Invoker.h +20 -0
  18. package/cpp/JsCallbackBridge.cpp +144 -0
  19. package/cpp/JsCallbackBridge.h +148 -0
  20. package/cpp/Primitives.cpp +1193 -0
  21. package/cpp/Primitives.h +39 -0
  22. package/cpp/ProtocolHost.cpp +613 -0
  23. package/cpp/ProtocolHost.h +88 -0
  24. package/cpp/RuntimeInvoker.h +29 -0
  25. package/cpp/StoreCallbacks.cpp +1293 -0
  26. package/cpp/StoreCallbacks.h +111 -0
  27. package/cpp/WorkerThread.cpp +74 -0
  28. package/cpp/WorkerThread.h +54 -0
  29. package/cpp/derec_ffi.h +2145 -0
  30. package/ios/DeRec.h +23 -0
  31. package/ios/DeRec.mm +39 -0
  32. package/ios/DeRecFFI.xcframework/Info.plist +48 -0
  33. package/ios/DeRecFFI.xcframework/ios-arm64/Headers/derec_ffi.h +2145 -0
  34. package/ios/DeRecFFI.xcframework/ios-arm64/libderec_library.a +0 -0
  35. package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/Headers/derec_ffi.h +2145 -0
  36. package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/libderec_library.a +0 -0
  37. package/lib/binary.d.ts +19 -0
  38. package/lib/binary.js +164 -0
  39. package/lib/codec.d.ts +16 -0
  40. package/lib/codec.js +80 -0
  41. package/lib/errors.d.ts +23 -0
  42. package/lib/errors.js +35 -0
  43. package/lib/index.d.ts +4 -0
  44. package/lib/index.js +27 -0
  45. package/lib/messages.d.ts +41 -0
  46. package/lib/messages.js +192 -0
  47. package/lib/native.d.ts +11 -0
  48. package/lib/native.js +40 -0
  49. package/lib/primitives.d.ts +137 -0
  50. package/lib/primitives.js +329 -0
  51. package/lib/protocol.d.ts +188 -0
  52. package/lib/protocol.js +514 -0
  53. package/lib/types.d.ts +1014 -0
  54. package/lib/types.js +63 -0
  55. package/package.json +55 -0
  56. package/react-native.config.js +19 -0
  57. package/src/binary.ts +182 -0
  58. package/src/codec.ts +79 -0
  59. package/src/errors.ts +45 -0
  60. package/src/index.ts +7 -0
  61. package/src/messages.ts +192 -0
  62. package/src/native.ts +52 -0
  63. package/src/primitives.ts +770 -0
  64. package/src/protocol.ts +621 -0
  65. package/src/types.ts +1040 -0
@@ -0,0 +1,514 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Copyright (c) 2026 DeRec Alliance. All rights reserved.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.DeRecProtocol = exports.DeRecProtocolBuilder = void 0;
6
+ exports.protocolDiscriminant = protocolDiscriminant;
7
+ exports.buildProtectSecretParams = buildProtectSecretParams;
8
+ exports.buildRestoreParams = buildRestoreParams;
9
+ const codec_1 = require("./codec");
10
+ const native_1 = require("./native");
11
+ const primitives_1 = require("./primitives");
12
+ const types_1 = require("./types");
13
+ /**
14
+ * Event fields carrying `Vec<u8>`.
15
+ *
16
+ * `serde_json` writes them as arrays of decimal byte values, while
17
+ * {@link DeRecEvent} declares them `Uint8Array` — the shape
18
+ * `@derec-alliance/nodejs` produces, where `serde-wasm-bindgen` makes the
19
+ * conversion natively. Without the conversion below the declared type is a
20
+ * lie, and the first thing an application does with `ActionRequired.action` is
21
+ * hand it back to `accept()`, where the native layer reads `.buffer` off it
22
+ * and finds nothing.
23
+ *
24
+ * Unlike the message codec in `./messages`, ids are deliberately left alone:
25
+ * every id on an event is declared as a decimal `string`, not a `bigint`.
26
+ */
27
+ const EVENT_BYTE_FIELDS = new Set([
28
+ 'action',
29
+ 'shared_key',
30
+ 'committed_share',
31
+ 'id',
32
+ 'data',
33
+ ]);
34
+ function reviveEventBytes(value) {
35
+ if (Array.isArray(value)) {
36
+ return value.map(reviveEventBytes);
37
+ }
38
+ if (value === null || typeof value !== 'object') {
39
+ return value;
40
+ }
41
+ const out = {};
42
+ for (const [key, field] of Object.entries(value)) {
43
+ out[key] =
44
+ EVENT_BYTE_FIELDS.has(key) && Array.isArray(field)
45
+ ? Uint8Array.from(field)
46
+ : reviveEventBytes(field);
47
+ }
48
+ return out;
49
+ }
50
+ function decodeEvents(buffer) {
51
+ return reviveEventBytes((0, codec_1.jsonFromBytes)(buffer));
52
+ }
53
+ /**
54
+ * Maps a transport protocol name to the `derec_proto::Protocol` discriminant.
55
+ * `bindings/test_fixture/enums.json` — the shared enum fixture every other
56
+ * numeric mapping in this SDK is read from — does not carry this enum (it
57
+ * only covers the Rust-internal serde enums listed under its `"enums"` key);
58
+ * the transport `Protocol` enum lives in `protobufs/transportprotocol.proto`
59
+ * instead, where only `HTTPS = 0` is currently defined.
60
+ */
61
+ function protocolDiscriminant(protocol) {
62
+ switch (protocol.toLowerCase()) {
63
+ case 'https':
64
+ return 0;
65
+ default:
66
+ throw new Error(`DeRec: unknown transport protocol "${protocol}"`);
67
+ }
68
+ }
69
+ function encodeTarget(target) {
70
+ if (target === null) {
71
+ return null;
72
+ }
73
+ if (Array.isArray(target)) {
74
+ return target.map((id) => id.toString());
75
+ }
76
+ return target.toString();
77
+ }
78
+ /**
79
+ * `ProtectSecretParamsJson` (`library/src/interop/ffi/protocol/flow.rs`): every
80
+ * `UserSecret.id`/`.data` byte array travels as a bare JSON array of decimal
81
+ * byte values, matching `UserSecretJson`'s plain `Vec<u8>` fields — no
82
+ * base64, no wrapping.
83
+ *
84
+ * Exported so it can be golden-tested against
85
+ * `bindings/test_fixture/wire_golden.json` without a native module.
86
+ */
87
+ function buildProtectSecretParams(params) {
88
+ const out = {
89
+ secrets: params.secrets.map((secret) => ({
90
+ id: Array.from(secret.id),
91
+ name: secret.name,
92
+ data: Array.from(secret.data),
93
+ })),
94
+ };
95
+ if (params.description !== undefined) {
96
+ out.description = params.description;
97
+ }
98
+ return out;
99
+ }
100
+ function communicationInfoOrOmit(info) {
101
+ return info !== undefined && Object.keys(info).length > 0 ? info : undefined;
102
+ }
103
+ /**
104
+ * `RestoreParamsJson` (`library/src/interop/ffi/protocol/handle/flow.rs`). Mirrors
105
+ * `SecretWire`'s own shape: `channel_id`/`replica_id` are the decimal `u64`
106
+ * strings the `SecretRecovered` event already carries, forwarded verbatim;
107
+ * `communication_info` is omitted per-entry (not sent as `{}`) whenever a
108
+ * helper or replica member has none, matching the Go SDK's `omitempty` and
109
+ * the shared golden fixture byte-for-byte; `replicas` is omitted entirely
110
+ * when the recovered secret has no replica group.
111
+ *
112
+ * Exported so it can be golden-tested against
113
+ * `bindings/test_fixture/wire_golden.json` without a native module.
114
+ */
115
+ function buildRestoreParams(recoveredSecret, version) {
116
+ const recovered = {
117
+ helpers: recoveredSecret.helpers.map((helper) => {
118
+ const out = {
119
+ channel_id: helper.channel_id,
120
+ transport_uri: helper.transport_uri,
121
+ shared_key: Array.from(helper.shared_key),
122
+ };
123
+ const info = communicationInfoOrOmit(helper.communication_info);
124
+ if (info !== undefined) {
125
+ out.communication_info = info;
126
+ }
127
+ return out;
128
+ }),
129
+ secrets: recoveredSecret.secrets.map((secret) => ({
130
+ id: Array.from(secret.id),
131
+ name: secret.name,
132
+ data: Array.from(secret.data),
133
+ })),
134
+ };
135
+ if (recoveredSecret.replicas !== undefined) {
136
+ recovered.replicas = {
137
+ channel_id: recoveredSecret.replicas.channel_id,
138
+ members: recoveredSecret.replicas.members.map((member) => {
139
+ const out = {
140
+ replica_id: member.replica_id,
141
+ transport_uri: member.transport_uri,
142
+ role: member.role,
143
+ };
144
+ const info = communicationInfoOrOmit(member.communication_info);
145
+ if (info !== undefined) {
146
+ out.communication_info = info;
147
+ }
148
+ return out;
149
+ }),
150
+ shared_key: Array.from(recoveredSecret.replicas.shared_key),
151
+ };
152
+ }
153
+ return { version, recovered_secret: recovered };
154
+ }
155
+ /**
156
+ * `PairingParamsJson.contact` (`library/src/interop/ffi/protocol/flow.rs`) is a
157
+ * `Vec<u8>` of proto-encoded `ContactMessage` bytes, so the typed contact the
158
+ * caller holds is re-encoded through the library's own codec on the way in.
159
+ * Encoding in Rust also means the contact is structurally validated before
160
+ * the pairing flow ever sees it.
161
+ */
162
+ function contactToByteArray(contact) {
163
+ return Array.from(primitives_1.primitives.pairing.request.encode_contact(contact));
164
+ }
165
+ function buildStartParams(flowKind, params) {
166
+ switch (flowKind) {
167
+ case types_1.FlowKind.Pairing: {
168
+ const p = params;
169
+ const out = {
170
+ kind: p.kind,
171
+ contact: contactToByteArray(p.contact),
172
+ };
173
+ if (p.peerCommunicationInfo !== undefined) {
174
+ out.peer_communication_info = p.peerCommunicationInfo;
175
+ }
176
+ return (0, codec_1.jsonToBytes)(out);
177
+ }
178
+ case types_1.FlowKind.Discovery: {
179
+ const p = (params ?? {});
180
+ const out = {};
181
+ if (p.target !== undefined) {
182
+ out.target = encodeTarget(p.target);
183
+ }
184
+ return (0, codec_1.jsonToBytes)(out);
185
+ }
186
+ case types_1.FlowKind.ProtectSecret:
187
+ return (0, codec_1.jsonToBytes)(buildProtectSecretParams(params));
188
+ case types_1.FlowKind.VerifyShares: {
189
+ const p = params;
190
+ const out = {
191
+ secret_id: p.secretId.toString(),
192
+ version: p.version,
193
+ };
194
+ if (p.target !== undefined) {
195
+ out.target = encodeTarget(p.target);
196
+ }
197
+ return (0, codec_1.jsonToBytes)(out);
198
+ }
199
+ case types_1.FlowKind.RecoverSecret: {
200
+ const p = params;
201
+ return (0, codec_1.jsonToBytes)({ secret_id: p.secretId.toString(), version: p.version });
202
+ }
203
+ case types_1.FlowKind.Unpair: {
204
+ const p = params;
205
+ const out = { channel_id: p.channel_id };
206
+ if (p.memo !== undefined) {
207
+ out.memo = p.memo;
208
+ }
209
+ return (0, codec_1.jsonToBytes)(out);
210
+ }
211
+ case types_1.FlowKind.UpdateChannelInfo: {
212
+ const p = (params ?? {});
213
+ const out = {};
214
+ if (p.target !== undefined) {
215
+ out.target = encodeTarget(p.target);
216
+ }
217
+ if (p.communication_info !== undefined) {
218
+ out.communication_info = p.communication_info;
219
+ }
220
+ if (p.transport_protocol !== undefined) {
221
+ out.transport_protocol = p.transport_protocol;
222
+ }
223
+ return (0, codec_1.jsonToBytes)(out);
224
+ }
225
+ case types_1.FlowKind.SyncCheck:
226
+ // No parameters: the group and this device's own version both come
227
+ // from the stores.
228
+ return (0, codec_1.jsonToBytes)({});
229
+ case types_1.FlowKind.RemoveReplica: {
230
+ const p = params;
231
+ const out = { replica_id: p.replica_id };
232
+ if (p.memo !== undefined) {
233
+ out.memo = p.memo;
234
+ }
235
+ return (0, codec_1.jsonToBytes)(out);
236
+ }
237
+ default: {
238
+ const exhaustive = flowKind;
239
+ throw new Error(`DeRec: unknown FlowKind ${exhaustive}`);
240
+ }
241
+ }
242
+ }
243
+ function toBigInt(id) {
244
+ return typeof id === 'bigint' ? id : BigInt(id);
245
+ }
246
+ /**
247
+ * Builder for {@link DeRecProtocol}, mirroring `@derec-alliance/nodejs`'s
248
+ * `DeRecProtocolBuilder` method-for-method. The config JSON shape is dictated
249
+ * by the Rust `ProtocolConfig` struct (`library/src/interop/ffi/protocol/handle/mod.rs`);
250
+ * every field here writes exactly the `snake_case` key that struct expects.
251
+ *
252
+ * Every value the caller supplies is forwarded verbatim — defaults, clamping
253
+ * and the meaning of a disabled cleanup policy are library decisions.
254
+ * `threshold`, `keep_versions_count`, `auto_respond_on_failure`,
255
+ * `unpair_ack`, `auto_reply_to` and `auto_accept` are omitted entirely from
256
+ * the emitted config unless their setter was called: `ProtocolConfig` has a
257
+ * `#[serde(default = "...")]` on each of them, reading the same constants
258
+ * `DeRecProtocolBuilder::new` uses, so an absent key resolves to the
259
+ * library's own default rather than one frozen into this shim.
260
+ */
261
+ class DeRecProtocolBuilder {
262
+ constructor(secretId) {
263
+ this.config = {};
264
+ this.stores = {};
265
+ this.secretIdValue = BigInt(secretId);
266
+ }
267
+ withChannelStore(store) {
268
+ this.stores.channelStore = store;
269
+ return this;
270
+ }
271
+ withShareStore(store) {
272
+ this.stores.shareStore = store;
273
+ return this;
274
+ }
275
+ withSecretStore(store) {
276
+ this.stores.secretStore = store;
277
+ return this;
278
+ }
279
+ withUserSecretStore(store) {
280
+ this.stores.userSecretStore = store;
281
+ return this;
282
+ }
283
+ withStateStore(store) {
284
+ this.stores.stateStore = store;
285
+ return this;
286
+ }
287
+ withTransport(transport) {
288
+ this.stores.transport = transport;
289
+ return this;
290
+ }
291
+ withOwnTransport(endpoint) {
292
+ this.config.own_transport_uri = endpoint.uri;
293
+ this.config.own_transport_protocol = protocolDiscriminant(endpoint.protocol);
294
+ return this;
295
+ }
296
+ /** Default: 3. */
297
+ withThreshold(threshold) {
298
+ this.config.threshold = threshold;
299
+ return this;
300
+ }
301
+ /** Default: 3. */
302
+ withKeepVersionsCount(count) {
303
+ this.config.keep_versions_count = count;
304
+ return this;
305
+ }
306
+ /**
307
+ * Every field is optional; not calling this at all leaves all four at the
308
+ * library's defaults — `timeouts` is genuinely absent from the JSON in
309
+ * that case, not filled in with a synthesized object. Values are forwarded
310
+ * verbatim; `Timeouts`'s field names already match `TimeoutsConfig`'s
311
+ * `snake_case` keys one for one.
312
+ */
313
+ withTimeouts(timeouts) {
314
+ this.config.timeouts = { ...timeouts };
315
+ return this;
316
+ }
317
+ /** Default: false. */
318
+ withUnsafeHttp(allow) {
319
+ this.config.unsafe_http = allow;
320
+ return this;
321
+ }
322
+ /**
323
+ * Default: empty. `derec_protocol_new`'s own `communication_info` argument
324
+ * is a pre-encoded `CommunicationInfo` protobuf message, and this SDK has
325
+ * no encoder for that message — the C ABI exposes one only for
326
+ * `ContactMessage`. Hand-rolling one here would be SDK-side protocol logic
327
+ * with no test coverage — exactly what this codebase's "Rust decides, the
328
+ * SDK only marshals" rule forbids. Instead,
329
+ * `build()` constructs the protocol with an empty `communication_info`
330
+ * (a legitimate, always-accepted value — see `decode_communication_info`
331
+ * in `library/src/interop/ffi/protocol/handle/mod.rs`, which treats a zero-length
332
+ * buffer as "no entries") and then calls the already-bound
333
+ * {@link DeRecProtocol.setCommunicationInfo}, which takes the same map as
334
+ * plain JSON (`derec_protocol_set_communication_info` in
335
+ * `library/src/interop/ffi/protocol/handle/config.rs`). That setter is queued on
336
+ * the protocol's serial worker before `build()` returns, so it is ordered
337
+ * ahead of every call the caller can subsequently make.
338
+ */
339
+ withCommunicationInfo(info) {
340
+ this.communicationInfo = info;
341
+ return this;
342
+ }
343
+ /** Default: false. */
344
+ withAutoRespondOnFailure(enabled) {
345
+ this.config.auto_respond_on_failure = enabled;
346
+ return this;
347
+ }
348
+ /** Default: "required". */
349
+ withUnpairAck(ack) {
350
+ if (ack === 'required') {
351
+ this.config.unpair_ack = 0;
352
+ }
353
+ else if (ack === 'not_required') {
354
+ this.config.unpair_ack = 1;
355
+ }
356
+ else {
357
+ throw new Error(`DeRec: unknown unpair ack "${ack}"`);
358
+ }
359
+ return this;
360
+ }
361
+ /** Default: false. */
362
+ withAutoReplyTo(enabled) {
363
+ this.config.auto_reply_to = enabled;
364
+ return this;
365
+ }
366
+ /** Default: empty policy (every flow off). */
367
+ withAutoAccept(policy) {
368
+ this.config.auto_accept = {
369
+ pairing: policy.pairing ?? false,
370
+ pre_pair: policy.prePair ?? false,
371
+ store_share: policy.storeShare ?? false,
372
+ verify_share: policy.verifyShare ?? false,
373
+ discovery: policy.discovery ?? false,
374
+ get_share: policy.getShare ?? false,
375
+ unpair: policy.unpair ?? false,
376
+ update_channel_info: policy.updateChannelInfo ?? false,
377
+ };
378
+ return this;
379
+ }
380
+ /** Default: unset. */
381
+ withReplicaId(replicaId) {
382
+ this.config.replica_id = BigInt(replicaId).toString();
383
+ return this;
384
+ }
385
+ build() {
386
+ const config = {
387
+ secret_id: this.secretIdValue.toString(),
388
+ replica_id: null,
389
+ own_transport_uri: '',
390
+ own_transport_protocol: 0,
391
+ ...this.config,
392
+ };
393
+ const host = (0, native_1.getNative)().protocol_new(JSON.stringify(config), new Uint8Array(0), this.stores);
394
+ const protocol = DeRecProtocol.fromHost(host);
395
+ if (this.communicationInfo !== undefined) {
396
+ // `setCommunicationInfo` is asynchronous, but `build()` stays
397
+ // synchronous: the guarantee callers need is not that the map has been
398
+ // applied by the time `build()` returns, it is that no flow can run
399
+ // before it. Posting it here puts it on the protocol's serial worker
400
+ // queue ahead of anything the caller has had the chance to start, so
401
+ // every subsequent call observes it. Left unhandled deliberately — a
402
+ // failure reaches the runtime's unhandled-rejection reporting rather
403
+ // than being silently discarded, and `build()` has no synchronous
404
+ // channel to raise it on.
405
+ void protocol.setCommunicationInfo(this.communicationInfo);
406
+ }
407
+ return protocol;
408
+ }
409
+ }
410
+ exports.DeRecProtocolBuilder = DeRecProtocolBuilder;
411
+ /**
412
+ * Thin wrapper around the `ProtocolHost` JSI host object, mirroring
413
+ * `@derec-alliance/nodejs`'s `DeRecProtocol` — same methods, and the same
414
+ * sync/async split except for `setCommunicationInfo` and `setOwnTransport`,
415
+ * which return a `Promise` here (see their own doc comments for why);
416
+ * `secretId` is synchronous and everything else returns a `Promise`. Every method encodes its
417
+ * arguments into the wire shape the host function expects and decodes its
418
+ * result back into the typed value declared here; no protocol decision is
419
+ * made in this class.
420
+ */
421
+ class DeRecProtocol {
422
+ /** Use {@link DeRecProtocolBuilder} to construct instances. */
423
+ constructor(host) {
424
+ this.host = host;
425
+ }
426
+ /**
427
+ * @internal Constructs an instance from a native `ProtocolHost`. Not part
428
+ * of the public surface — {@link DeRecProtocolBuilder.build} is the only
429
+ * caller. Exists because the constructor is `private` (matching
430
+ * `@derec-alliance/nodejs`'s `index.d.ts`), and a private constructor is
431
+ * only callable from within this class's own body, not from
432
+ * `DeRecProtocolBuilder`.
433
+ */
434
+ static fromHost(host) {
435
+ return new DeRecProtocol(host);
436
+ }
437
+ secretId() {
438
+ return this.host.secretId();
439
+ }
440
+ /**
441
+ * Returns a `Promise`, where `@derec-alliance/nodejs` declares this
442
+ * `void`. The native setter takes the same handle mutex a running flow
443
+ * holds across its store callbacks, so calling it on the JavaScript thread
444
+ * would block that thread until the flow released the mutex — which it
445
+ * cannot do while it is waiting on the JavaScript thread. The binding
446
+ * therefore queues the setter onto the same serial worker every flow runs
447
+ * on, which orders it after any call already in flight. The nodejs SDK is
448
+ * WASM and single-threaded, so it has no such hazard.
449
+ *
450
+ * Callers that ignore the result behave exactly as before, so this stays
451
+ * source-compatible with nodejs-shaped code; awaiting it additionally
452
+ * surfaces a failure that would otherwise be swallowed.
453
+ */
454
+ setCommunicationInfo(info) {
455
+ return this.host.setCommunicationInfo((0, codec_1.jsonToBytes)(info));
456
+ }
457
+ /** Returns a `Promise` for the same reason {@link setCommunicationInfo} does. */
458
+ setOwnTransport(uri, protocol) {
459
+ return this.host.setOwnTransport(uri, protocolDiscriminant(protocol));
460
+ }
461
+ /**
462
+ * Decodes the `contact_wire_bytes` `derec_protocol_create_contact`
463
+ * produces into a typed `ContactMessage`, so an application can read the
464
+ * contact's `nonce`, `transport_protocol` and mode without a protobuf
465
+ * codec of its own. Feed the returned object straight back into
466
+ * `start(FlowKind.Pairing, { contact })`, which re-encodes it.
467
+ */
468
+ async createContact(channelId, contactMode, nonce) {
469
+ const hasChannelId = channelId !== null && channelId !== undefined ? 1 : 0;
470
+ const hasNonce = nonce !== null && nonce !== undefined ? 1 : 0;
471
+ const buffer = (await this.host.createContact(hasChannelId, toBigInt(channelId ?? 0), contactMode, hasNonce, toBigInt(nonce ?? 0)));
472
+ return primitives_1.primitives.pairing.request.decode_contact(new Uint8Array(buffer));
473
+ }
474
+ async start(flowKind, params) {
475
+ const paramsBytes = buildStartParams(flowKind, params);
476
+ const buffer = (await this.host.start(flowKind, paramsBytes));
477
+ return decodeEvents(buffer);
478
+ }
479
+ async process(message) {
480
+ const buffer = (await this.host.process(message));
481
+ return decodeEvents(buffer);
482
+ }
483
+ async tick() {
484
+ const buffer = (await this.host.tick());
485
+ return decodeEvents(buffer);
486
+ }
487
+ async accept(actionBytes) {
488
+ const buffer = (await this.host.accept(actionBytes));
489
+ return decodeEvents(buffer);
490
+ }
491
+ async reject(actionBytes, status, memo) {
492
+ await this.host.reject(actionBytes, status, memo);
493
+ }
494
+ async getFingerprint(channelId) {
495
+ return (await this.host.getFingerprint(toBigInt(channelId)));
496
+ }
497
+ async verifyFingerprint(channelId, fingerprint) {
498
+ return (await this.host.verifyFingerprint(toBigInt(channelId), fingerprint));
499
+ }
500
+ async removeExpiredChannels(olderThanSecs) {
501
+ const buffer = (await this.host.removeExpiredChannels(olderThanSecs));
502
+ return (0, codec_1.jsonFromBytes)(buffer);
503
+ }
504
+ async restore(recoveredSecret, version) {
505
+ const params = buildRestoreParams(recoveredSecret, version);
506
+ const buffer = (await this.host.restore((0, codec_1.jsonToBytes)(params)));
507
+ return decodeEvents(buffer);
508
+ }
509
+ /** Release the native handle. Safe to call more than once. */
510
+ free() {
511
+ this.host.free();
512
+ }
513
+ }
514
+ exports.DeRecProtocol = DeRecProtocol;