@genation/bridge-peer 0.1.0

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 (72) hide show
  1. package/GenationBridgePeer.podspec +17 -0
  2. package/LICENSE +190 -0
  3. package/README.md +66 -0
  4. package/package.json +59 -0
  5. package/react-native/android/build.gradle +24 -0
  6. package/react-native/android/src/main/java/com/genation/bridge/GenationBridgePeerModule.kt +182 -0
  7. package/react-native/android/src/main/java/com/genation/bridge/GenationBridgePeerPackage.kt +15 -0
  8. package/react-native/android/src/main/jniLibs/arm64-v8a/libgenation_bridge_crypto_uniffi.so +0 -0
  9. package/react-native/android/src/main/jniLibs/armeabi-v7a/libgenation_bridge_crypto_uniffi.so +0 -0
  10. package/react-native/android/src/main/jniLibs/x86/libgenation_bridge_crypto_uniffi.so +0 -0
  11. package/react-native/android/src/main/jniLibs/x86_64/libgenation_bridge_crypto_uniffi.so +0 -0
  12. package/react-native/generated/kotlin/uniffi/genation_bridge_crypto_uniffi/genation_bridge_crypto_uniffi.kt +2006 -0
  13. package/react-native/generated/swift/GenationBridgeCryptoMobile.swift +1072 -0
  14. package/react-native/generated/swift/GenationBridgeCryptoMobileFFI.h +703 -0
  15. package/react-native/generated/swift/GenationBridgeCryptoMobileFFI.modulemap +7 -0
  16. package/react-native/ios/GenationBridgePeer.m +14 -0
  17. package/react-native/ios/GenationBridgePeer.swift +234 -0
  18. package/react-native/native/GenationBridgeCryptoMobile.xcframework/Info.plist +48 -0
  19. package/react-native/native/GenationBridgeCryptoMobile.xcframework/ios-arm64/Headers/GenationBridgeCryptoMobileFFI.h +703 -0
  20. package/react-native/native/GenationBridgeCryptoMobile.xcframework/ios-arm64/Headers/module.modulemap +7 -0
  21. package/react-native/native/GenationBridgeCryptoMobile.xcframework/ios-arm64/libgenation_bridge_crypto_uniffi.a +0 -0
  22. package/react-native/native/GenationBridgeCryptoMobile.xcframework/ios-arm64_x86_64-simulator/Headers/GenationBridgeCryptoMobileFFI.h +703 -0
  23. package/react-native/native/GenationBridgeCryptoMobile.xcframework/ios-arm64_x86_64-simulator/Headers/module.modulemap +7 -0
  24. package/react-native/native/GenationBridgeCryptoMobile.xcframework/ios-arm64_x86_64-simulator/libgenation_bridge_crypto_uniffi.a +0 -0
  25. package/react-native.config.js +8 -0
  26. package/src/core/codec.d.ts +5 -0
  27. package/src/core/codec.js +46 -0
  28. package/src/core/errors.d.ts +11 -0
  29. package/src/core/errors.js +27 -0
  30. package/src/core/identity.d.ts +16 -0
  31. package/src/core/identity.js +1 -0
  32. package/src/core/lifecycle.d.ts +4 -0
  33. package/src/core/lifecycle.js +1 -0
  34. package/src/core/mod.d.ts +6 -0
  35. package/src/core/mod.js +3 -0
  36. package/src/core/peer.d.ts +67 -0
  37. package/src/core/peer.js +373 -0
  38. package/src/core/runtime.d.ts +78 -0
  39. package/src/core/runtime.js +0 -0
  40. package/src/node/crypto-core/javascript/mod.d.ts +8 -0
  41. package/src/node/crypto-core/javascript/mod.js +24 -0
  42. package/src/node/crypto-core/javascript/provider.d.ts +2 -0
  43. package/src/node/crypto-core/javascript/provider.js +43 -0
  44. package/src/node/crypto-core/pkg/wasm/genation_bridge_crypto_wasm.d.ts +122 -0
  45. package/src/node/crypto-core/pkg/wasm/genation_bridge_crypto_wasm.js +433 -0
  46. package/src/node/crypto-core/pkg/wasm/genation_bridge_crypto_wasm_bg.wasm +0 -0
  47. package/src/node/crypto-core/pkg/wasm/genation_bridge_crypto_wasm_bg.wasm.d.ts +25 -0
  48. package/src/node/encoding.js +1 -0
  49. package/src/node/file-key-store.d.ts +6 -0
  50. package/src/node/file-key-store.js +111 -0
  51. package/src/node/identity-provider.d.ts +8 -0
  52. package/src/node/identity-provider.js +57 -0
  53. package/src/node/identity.js +45 -0
  54. package/src/node/mod.d.ts +16 -0
  55. package/src/node/mod.js +17 -0
  56. package/src/node/relay-runtime.d.ts +11 -0
  57. package/src/node/relay-runtime.js +11 -0
  58. package/src/react-native/identity-provider.d.ts +4 -0
  59. package/src/react-native/identity-provider.js +125 -0
  60. package/src/react-native/lifecycle.d.ts +8 -0
  61. package/src/react-native/lifecycle.js +9 -0
  62. package/src/react-native/mod.d.ts +20 -0
  63. package/src/react-native/mod.js +36 -0
  64. package/src/react-native/native-module.d.ts +17 -0
  65. package/src/react-native/native-module.js +9 -0
  66. package/src/relay/encoding.js +32 -0
  67. package/src/relay/frame-channel.d.ts +1 -0
  68. package/src/relay/frame-channel.js +110 -0
  69. package/src/relay/identity.d.ts +27 -0
  70. package/src/relay/identity.js +0 -0
  71. package/src/relay/runtime.d.ts +8 -0
  72. package/src/relay/runtime.js +900 -0
@@ -0,0 +1,110 @@
1
+ import { bridgeFrameSchema } from "@genation/bridge-contracts";
2
+ import { BridgePeerError } from "../core/mod.js";
3
+ /** Strict FIFO relay frame channel with bounded cancellable waits. */ export class RelayFrameChannel {
4
+ #socket;
5
+ #pending = [];
6
+ #waiters = [];
7
+ #unhandled;
8
+ #onUnexpectedClose;
9
+ #closing = false;
10
+ #closed = false;
11
+ /** Opens one physical socket using the selected platform factory. */ constructor(url, factory){
12
+ this.#socket = factory(url);
13
+ this.#socket.addEventListener("message", (event)=>this.#receive(event.data));
14
+ this.#socket.addEventListener("error", ()=>this.#fail());
15
+ this.#socket.addEventListener("close", ()=>this.#fail());
16
+ }
17
+ /** Installs the handler for unsolicited incoming sessions and control frames. */ setUnhandled(handler) {
18
+ this.#unhandled = handler;
19
+ const retained = this.#pending.splice(0);
20
+ for (const frame of retained)this.#dispatch(frame);
21
+ }
22
+ /** Installs the one-shot notification used to enter SDK reconnect. */ setUnexpectedClose(handler) {
23
+ this.#onUnexpectedClose = handler;
24
+ }
25
+ /** Sends one schema-valid public frame or fails with a sanitized transport error. */ send(frame) {
26
+ try {
27
+ if (this.#closed || this.#socket.readyState !== WebSocket.OPEN) {
28
+ throw new Error("socket_not_open");
29
+ }
30
+ this.#socket.send(JSON.stringify(bridgeFrameSchema.parse(frame)));
31
+ } catch {
32
+ throw new BridgePeerError("CONNECTION_LOST");
33
+ }
34
+ }
35
+ /** Waits for one matching frame with an absolute bounded timeout and cancellation. */ waitFor(predicate, timeoutMs, signal) {
36
+ const index = this.#pending.findIndex(predicate);
37
+ if (index >= 0) return Promise.resolve(this.#pending.splice(index, 1)[0]);
38
+ if (this.#closed) return Promise.reject(new BridgePeerError("CONNECTION_LOST"));
39
+ if (signal?.aborted) return Promise.reject(new BridgePeerError("CANCELLED"));
40
+ return new Promise((resolve, reject)=>{
41
+ const waiter = {
42
+ predicate,
43
+ resolve: (frame)=>resolve(frame),
44
+ reject,
45
+ timer: setTimeout(()=>{
46
+ this.#remove(waiter);
47
+ reject(new BridgePeerError("DEADLINE_EXCEEDED"));
48
+ }, Math.max(1, timeoutMs)),
49
+ signal
50
+ };
51
+ if (signal !== undefined) {
52
+ waiter.abort = ()=>{
53
+ this.#remove(waiter);
54
+ reject(new BridgePeerError("CANCELLED"));
55
+ };
56
+ signal.addEventListener("abort", waiter.abort, {
57
+ once: true
58
+ });
59
+ }
60
+ this.#waiters.push(waiter);
61
+ });
62
+ }
63
+ /** Closes the physical socket and rejects every outstanding operation once. */ close() {
64
+ if (this.#closing || this.#closed) return;
65
+ this.#closing = true;
66
+ if (this.#socket.readyState < WebSocket.CLOSING) {
67
+ this.#socket.close(1000, "bridge_peer_close");
68
+ }
69
+ this.#fail();
70
+ }
71
+ #receive(value) {
72
+ try {
73
+ const frame = bridgeFrameSchema.parse(JSON.parse(String(value)));
74
+ this.#dispatch(frame);
75
+ } catch {
76
+ this.close();
77
+ }
78
+ }
79
+ #dispatch(frame) {
80
+ const index = this.#waiters.findIndex((waiter)=>waiter.predicate(frame));
81
+ if (index >= 0) {
82
+ const waiter = this.#waiters.splice(index, 1)[0];
83
+ this.#cleanup(waiter);
84
+ waiter.resolve(frame);
85
+ return;
86
+ }
87
+ if (this.#unhandled?.(frame) !== true) this.#pending.push(frame);
88
+ }
89
+ #remove(waiter) {
90
+ const index = this.#waiters.indexOf(waiter);
91
+ if (index >= 0) this.#waiters.splice(index, 1);
92
+ this.#cleanup(waiter);
93
+ }
94
+ #cleanup(waiter) {
95
+ clearTimeout(waiter.timer);
96
+ if (waiter.signal !== undefined && waiter.abort !== undefined) {
97
+ waiter.signal.removeEventListener("abort", waiter.abort);
98
+ }
99
+ }
100
+ #fail() {
101
+ if (this.#closed) return;
102
+ this.#closed = true;
103
+ this.#pending.length = 0;
104
+ for (const waiter of this.#waiters.splice(0)){
105
+ this.#cleanup(waiter);
106
+ waiter.reject(new BridgePeerError("CONNECTION_LOST"));
107
+ }
108
+ if (!this.#closing) this.#onUnexpectedClose?.();
109
+ }
110
+ }
@@ -0,0 +1,27 @@
1
+ import type { BridgeE2eeInitiator, BridgeE2eeResponder } from "@genation/bridge-contracts/sdk";
2
+ import type { BridgePeerPublicIdentity } from "../core/mod.js";
3
+ /** Public admission fields supplied to one opaque platform proof operation. */ export type BridgeConnectionProofSigningInput = Readonly<{
4
+ projectId: string;
5
+ peerId: string;
6
+ connectionId: string;
7
+ challenge: string;
8
+ challengeExpiresAt: number;
9
+ grant: string;
10
+ }>;
11
+ /** Opaque initiator creation input with no local private key. */ export type BridgeRelayInitiatorInput = Readonly<{
12
+ prologue: Uint8Array;
13
+ responderPublicKey: Uint8Array;
14
+ }>;
15
+ /** Opaque responder creation input with no local private key. */ export type BridgeRelayResponderInput = Readonly<{
16
+ prologue: Uint8Array;
17
+ initiatorPublicKey: Uint8Array;
18
+ }>;
19
+ /** One platform-owned peer identity exposed only through safe operations. */ export type BridgeRelayIdentity = Readonly<{
20
+ publicIdentity: BridgePeerPublicIdentity;
21
+ signConnectionProof(input: BridgeConnectionProofSigningInput): Promise<string>;
22
+ createInitiator(input: BridgeRelayInitiatorInput): BridgeE2eeInitiator;
23
+ createResponder(input: BridgeRelayResponderInput): BridgeE2eeResponder;
24
+ }>;
25
+ /** Platform identity loader keyed by the exact Bridge project and peer pair. */ export type BridgeRelayIdentityProvider = Readonly<{
26
+ load(projectId: string, peerId: string): Promise<BridgeRelayIdentity>;
27
+ }>;
File without changes
@@ -0,0 +1,8 @@
1
+ import { type BridgeWebSocketFactory } from "./frame-channel.js";
2
+ import type { BridgeRelayIdentityProvider } from "./identity.js";
3
+ /** Platform-neutral relay runtime dependencies selected before composition. */ export type BridgeRelayRuntimeOptions = Readonly<{
4
+ relayUrl: string;
5
+ identityProvider: BridgeRelayIdentityProvider;
6
+ webSocketFactory?: BridgeWebSocketFactory;
7
+ operationTimeoutMs?: number;
8
+ }>;