@meshwhisper/sdk 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 (163) hide show
  1. package/README.md +138 -0
  2. package/dist/browser/index.d.ts +4 -0
  3. package/dist/browser/index.d.ts.map +1 -0
  4. package/dist/browser/index.js +19 -0
  5. package/dist/browser/index.js.map +1 -0
  6. package/dist/chaff/index.d.ts +91 -0
  7. package/dist/chaff/index.d.ts.map +1 -0
  8. package/dist/chaff/index.js +268 -0
  9. package/dist/chaff/index.js.map +1 -0
  10. package/dist/cluster/index.d.ts +159 -0
  11. package/dist/cluster/index.d.ts.map +1 -0
  12. package/dist/cluster/index.js +393 -0
  13. package/dist/cluster/index.js.map +1 -0
  14. package/dist/compliance/index.d.ts +129 -0
  15. package/dist/compliance/index.d.ts.map +1 -0
  16. package/dist/compliance/index.js +315 -0
  17. package/dist/compliance/index.js.map +1 -0
  18. package/dist/crypto/index.d.ts +65 -0
  19. package/dist/crypto/index.d.ts.map +1 -0
  20. package/dist/crypto/index.js +146 -0
  21. package/dist/crypto/index.js.map +1 -0
  22. package/dist/group/index.d.ts +155 -0
  23. package/dist/group/index.d.ts.map +1 -0
  24. package/dist/group/index.js +560 -0
  25. package/dist/group/index.js.map +1 -0
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +11 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/namespace/index.d.ts +155 -0
  31. package/dist/namespace/index.d.ts.map +1 -0
  32. package/dist/namespace/index.js +278 -0
  33. package/dist/namespace/index.js.map +1 -0
  34. package/dist/node/index.d.ts +4 -0
  35. package/dist/node/index.d.ts.map +1 -0
  36. package/dist/node/index.js +19 -0
  37. package/dist/node/index.js.map +1 -0
  38. package/dist/packet/index.d.ts +63 -0
  39. package/dist/packet/index.d.ts.map +1 -0
  40. package/dist/packet/index.js +244 -0
  41. package/dist/packet/index.js.map +1 -0
  42. package/dist/permissions/index.d.ts +107 -0
  43. package/dist/permissions/index.d.ts.map +1 -0
  44. package/dist/permissions/index.js +282 -0
  45. package/dist/permissions/index.js.map +1 -0
  46. package/dist/persistence/idb-storage.d.ts +27 -0
  47. package/dist/persistence/idb-storage.d.ts.map +1 -0
  48. package/dist/persistence/idb-storage.js +75 -0
  49. package/dist/persistence/idb-storage.js.map +1 -0
  50. package/dist/persistence/index.d.ts +4 -0
  51. package/dist/persistence/index.d.ts.map +1 -0
  52. package/dist/persistence/index.js +3 -0
  53. package/dist/persistence/index.js.map +1 -0
  54. package/dist/persistence/node-storage.d.ts +33 -0
  55. package/dist/persistence/node-storage.d.ts.map +1 -0
  56. package/dist/persistence/node-storage.js +90 -0
  57. package/dist/persistence/node-storage.js.map +1 -0
  58. package/dist/persistence/serialization.d.ts +4 -0
  59. package/dist/persistence/serialization.d.ts.map +1 -0
  60. package/dist/persistence/serialization.js +49 -0
  61. package/dist/persistence/serialization.js.map +1 -0
  62. package/dist/persistence/types.d.ts +29 -0
  63. package/dist/persistence/types.d.ts.map +1 -0
  64. package/dist/persistence/types.js +5 -0
  65. package/dist/persistence/types.js.map +1 -0
  66. package/dist/ratchet/index.d.ts +80 -0
  67. package/dist/ratchet/index.d.ts.map +1 -0
  68. package/dist/ratchet/index.js +259 -0
  69. package/dist/ratchet/index.js.map +1 -0
  70. package/dist/reciprocity/index.d.ts +109 -0
  71. package/dist/reciprocity/index.d.ts.map +1 -0
  72. package/dist/reciprocity/index.js +311 -0
  73. package/dist/reciprocity/index.js.map +1 -0
  74. package/dist/relay/index.d.ts +87 -0
  75. package/dist/relay/index.d.ts.map +1 -0
  76. package/dist/relay/index.js +286 -0
  77. package/dist/relay/index.js.map +1 -0
  78. package/dist/routing/index.d.ts +136 -0
  79. package/dist/routing/index.d.ts.map +1 -0
  80. package/dist/routing/index.js +478 -0
  81. package/dist/routing/index.js.map +1 -0
  82. package/dist/sdk/index.d.ts +322 -0
  83. package/dist/sdk/index.d.ts.map +1 -0
  84. package/dist/sdk/index.js +1530 -0
  85. package/dist/sdk/index.js.map +1 -0
  86. package/dist/sybil/index.d.ts +123 -0
  87. package/dist/sybil/index.d.ts.map +1 -0
  88. package/dist/sybil/index.js +491 -0
  89. package/dist/sybil/index.js.map +1 -0
  90. package/dist/transport/browser/index.d.ts +34 -0
  91. package/dist/transport/browser/index.d.ts.map +1 -0
  92. package/dist/transport/browser/index.js +176 -0
  93. package/dist/transport/browser/index.js.map +1 -0
  94. package/dist/transport/local/index.d.ts +57 -0
  95. package/dist/transport/local/index.d.ts.map +1 -0
  96. package/dist/transport/local/index.js +442 -0
  97. package/dist/transport/local/index.js.map +1 -0
  98. package/dist/transport/negotiator/index.d.ts +79 -0
  99. package/dist/transport/negotiator/index.d.ts.map +1 -0
  100. package/dist/transport/negotiator/index.js +289 -0
  101. package/dist/transport/negotiator/index.js.map +1 -0
  102. package/dist/transport/node/index.d.ts +56 -0
  103. package/dist/transport/node/index.d.ts.map +1 -0
  104. package/dist/transport/node/index.js +209 -0
  105. package/dist/transport/node/index.js.map +1 -0
  106. package/dist/transport/noop/index.d.ts +11 -0
  107. package/dist/transport/noop/index.d.ts.map +1 -0
  108. package/dist/transport/noop/index.js +20 -0
  109. package/dist/transport/noop/index.js.map +1 -0
  110. package/dist/transport/p2p/index.d.ts +109 -0
  111. package/dist/transport/p2p/index.d.ts.map +1 -0
  112. package/dist/transport/p2p/index.js +237 -0
  113. package/dist/transport/p2p/index.js.map +1 -0
  114. package/dist/transport/websocket/index.d.ts +89 -0
  115. package/dist/transport/websocket/index.d.ts.map +1 -0
  116. package/dist/transport/websocket/index.js +498 -0
  117. package/dist/transport/websocket/index.js.map +1 -0
  118. package/dist/transport/websocket/serialize.d.ts +5 -0
  119. package/dist/transport/websocket/serialize.d.ts.map +1 -0
  120. package/dist/transport/websocket/serialize.js +55 -0
  121. package/dist/transport/websocket/serialize.js.map +1 -0
  122. package/dist/types.d.ts +215 -0
  123. package/dist/types.d.ts.map +1 -0
  124. package/dist/types.js +15 -0
  125. package/dist/types.js.map +1 -0
  126. package/dist/x3dh/index.d.ts +120 -0
  127. package/dist/x3dh/index.d.ts.map +1 -0
  128. package/dist/x3dh/index.js +290 -0
  129. package/dist/x3dh/index.js.map +1 -0
  130. package/package.json +59 -0
  131. package/src/browser/index.ts +19 -0
  132. package/src/chaff/index.ts +340 -0
  133. package/src/cluster/index.ts +482 -0
  134. package/src/compliance/index.ts +407 -0
  135. package/src/crypto/index.ts +193 -0
  136. package/src/group/index.ts +719 -0
  137. package/src/index.ts +87 -0
  138. package/src/lz4js.d.ts +58 -0
  139. package/src/namespace/index.ts +336 -0
  140. package/src/node/index.ts +19 -0
  141. package/src/packet/index.ts +326 -0
  142. package/src/permissions/index.ts +405 -0
  143. package/src/persistence/idb-storage.ts +83 -0
  144. package/src/persistence/index.ts +3 -0
  145. package/src/persistence/node-storage.ts +96 -0
  146. package/src/persistence/serialization.ts +75 -0
  147. package/src/persistence/types.ts +33 -0
  148. package/src/ratchet/index.ts +363 -0
  149. package/src/reciprocity/index.ts +371 -0
  150. package/src/relay/index.ts +382 -0
  151. package/src/routing/index.ts +577 -0
  152. package/src/sdk/index.ts +1994 -0
  153. package/src/sybil/index.ts +661 -0
  154. package/src/transport/browser/index.ts +201 -0
  155. package/src/transport/local/index.ts +540 -0
  156. package/src/transport/negotiator/index.ts +397 -0
  157. package/src/transport/node/index.ts +234 -0
  158. package/src/transport/noop/index.ts +22 -0
  159. package/src/transport/p2p/index.ts +345 -0
  160. package/src/transport/websocket/index.ts +660 -0
  161. package/src/transport/websocket/serialize.ts +68 -0
  162. package/src/types.ts +275 -0
  163. package/src/x3dh/index.ts +388 -0
@@ -0,0 +1,201 @@
1
+ // ============================================================
2
+ // MeshWhisper SDK — Browser Transport
3
+ // Connects the SDK to a MeshWhisper Node using the native
4
+ // browser WebSocket API. Drop-in replacement for NodeTransport
5
+ // when running in a browser or PWA context.
6
+ // ============================================================
7
+
8
+ import type { Transport, Packet, PushConfig } from '../../types.js';
9
+ import {
10
+ serializePacket,
11
+ deserializePacket,
12
+ HEADER_SIZE,
13
+ } from '../websocket/serialize.js';
14
+
15
+ // ---- Constants ----
16
+
17
+ /** Foundation-hosted relay nodes. Used when node config is "mesh". */
18
+ export const FOUNDATION_RELAY_NODES = [
19
+ 'wss://relay.meshwhisper.io',
20
+ ];
21
+
22
+ const RECONNECT_BASE_MS = 1_000;
23
+ const RECONNECT_MAX_MS = 30_000;
24
+
25
+ // ---- BrowserTransport ----
26
+
27
+ /**
28
+ * Transport that connects to a MeshWhisper Node using the native browser
29
+ * WebSocket API. Functionally identical to NodeTransport but uses
30
+ * `globalThis.WebSocket` instead of the `ws` npm package, so it bundles
31
+ * cleanly for browsers and PWAs.
32
+ */
33
+ export class BrowserTransport implements Transport {
34
+ readonly type = 'internet' as const;
35
+
36
+ private ws: WebSocket | null = null;
37
+ private receiveCallbacks: Array<(packet: Packet, source: string) => void> = [];
38
+ private running = false;
39
+ private reconnectAttempt = 0;
40
+ private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
41
+
42
+ constructor(
43
+ private readonly nodeUrl: string,
44
+ private readonly getDestHashes: () => string[],
45
+ private pushConfig?: PushConfig,
46
+ ) {}
47
+
48
+ // ---- Transport interface ----
49
+
50
+ async start(): Promise<void> {
51
+ this.running = true;
52
+ await this.connect();
53
+ }
54
+
55
+ async stop(): Promise<void> {
56
+ this.running = false;
57
+ if (this.reconnectTimer) {
58
+ clearTimeout(this.reconnectTimer);
59
+ this.reconnectTimer = null;
60
+ }
61
+ if (this.ws) {
62
+ this.ws.close(1000, 'shutdown');
63
+ this.ws = null;
64
+ }
65
+ }
66
+
67
+ async isAvailable(): Promise<boolean> {
68
+ return this.ws?.readyState === WebSocket.OPEN;
69
+ }
70
+
71
+ async send(packet: Packet, _destination: string): Promise<void> {
72
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
73
+ throw new Error('BrowserTransport: not connected to Node');
74
+ }
75
+ const binary = serializePacket(packet);
76
+ this.ws.send(binary);
77
+ }
78
+
79
+ onReceive(callback: (packet: Packet, source: string) => void): void {
80
+ this.receiveCallbacks.push(callback);
81
+ }
82
+
83
+ // ---- Connection management ----
84
+
85
+ private resolveUrl(): string {
86
+ if (this.nodeUrl === 'mesh') {
87
+ return FOUNDATION_RELAY_NODES[0];
88
+ }
89
+ return this.nodeUrl;
90
+ }
91
+
92
+ private connect(): Promise<void> {
93
+ const url = this.resolveUrl();
94
+
95
+ return new Promise<void>((resolve, reject) => {
96
+ let resolved = false;
97
+
98
+ const ws = new WebSocket(url);
99
+ ws.binaryType = 'arraybuffer';
100
+
101
+ ws.addEventListener('open', () => {
102
+ this.ws = ws;
103
+ this.reconnectAttempt = 0;
104
+ resolved = true;
105
+ ws.send(JSON.stringify(this.buildHello()));
106
+ resolve();
107
+ });
108
+
109
+ ws.addEventListener('message', (event: MessageEvent) => {
110
+ this.handleMessage(event.data);
111
+ });
112
+
113
+ ws.addEventListener('close', () => {
114
+ this.ws = null;
115
+ if (this.running) this.scheduleReconnect();
116
+ });
117
+
118
+ ws.addEventListener('error', () => {
119
+ if (!resolved) {
120
+ resolved = true;
121
+ reject(new Error(`BrowserTransport: failed to connect to ${url}`));
122
+ }
123
+ });
124
+ });
125
+ }
126
+
127
+ private scheduleReconnect(): void {
128
+ if (!this.running) return;
129
+ const delay = Math.min(
130
+ RECONNECT_BASE_MS * Math.pow(2, this.reconnectAttempt),
131
+ RECONNECT_MAX_MS,
132
+ );
133
+ this.reconnectAttempt++;
134
+ this.reconnectTimer = setTimeout(async () => {
135
+ if (!this.running) return;
136
+ try {
137
+ await this.connect();
138
+ } catch {
139
+ this.scheduleReconnect();
140
+ }
141
+ }, delay);
142
+ }
143
+
144
+ // ---- Message handling ----
145
+
146
+ private handleMessage(data: unknown): void {
147
+ if (data instanceof ArrayBuffer && data.byteLength >= HEADER_SIZE) {
148
+ try {
149
+ const packet = deserializePacket(new Uint8Array(data));
150
+ const source = this.resolveUrl();
151
+ for (const cb of this.receiveCallbacks) {
152
+ try { cb(packet, source); } catch { /* swallow */ }
153
+ }
154
+ } catch {
155
+ // Malformed packet — discard
156
+ }
157
+ return;
158
+ }
159
+
160
+ if (typeof data === 'string') {
161
+ try {
162
+ JSON.parse(data);
163
+ // Reserved for future Node→client control messages
164
+ } catch { /* not JSON */ }
165
+ }
166
+ }
167
+
168
+ // ---- Dest hash / push token refresh ----
169
+
170
+ refreshDestHashes(): void {
171
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
172
+ this.ws.send(JSON.stringify(this.buildHello()));
173
+ }
174
+
175
+ setPushConfig(pushConfig: PushConfig | undefined): void {
176
+ this.pushConfig = pushConfig;
177
+ this.refreshDestHashes();
178
+ }
179
+
180
+ // ---- Private helpers ----
181
+
182
+ private buildHello(): object {
183
+ const msg: Record<string, unknown> = {
184
+ type: 'hello',
185
+ destHashes: this.getDestHashes(),
186
+ };
187
+ if (this.pushConfig) {
188
+ if (this.pushConfig.platform === 'webpush') {
189
+ msg['pushSubscription'] = JSON.stringify(this.pushConfig.subscription);
190
+ msg['pushPlatform'] = 'webpush';
191
+ } else {
192
+ msg['pushToken'] = this.pushConfig.token;
193
+ msg['pushPlatform'] = this.pushConfig.platform;
194
+ if ('topic' in this.pushConfig && this.pushConfig.topic) {
195
+ msg['pushTopic'] = this.pushConfig.topic;
196
+ }
197
+ }
198
+ }
199
+ return msg;
200
+ }
201
+ }