@bananalink-sdk/protocol 1.2.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.
Files changed (158) hide show
  1. package/README.md +604 -0
  2. package/dist/chunk-32OWUOZ3.js +308 -0
  3. package/dist/chunk-32OWUOZ3.js.map +1 -0
  4. package/dist/chunk-65HNHRJK.cjs +123 -0
  5. package/dist/chunk-65HNHRJK.cjs.map +1 -0
  6. package/dist/chunk-7KYDLL3B.js +480 -0
  7. package/dist/chunk-7KYDLL3B.js.map +1 -0
  8. package/dist/chunk-A6FLEJ7R.cjs +62 -0
  9. package/dist/chunk-A6FLEJ7R.cjs.map +1 -0
  10. package/dist/chunk-CUJK7ZTS.js +217 -0
  11. package/dist/chunk-CUJK7ZTS.js.map +1 -0
  12. package/dist/chunk-GI3BUPIH.cjs +236 -0
  13. package/dist/chunk-GI3BUPIH.cjs.map +1 -0
  14. package/dist/chunk-JXHV66Q4.js +106 -0
  15. package/dist/chunk-JXHV66Q4.js.map +1 -0
  16. package/dist/chunk-KNGZKGRS.cjs +552 -0
  17. package/dist/chunk-KNGZKGRS.cjs.map +1 -0
  18. package/dist/chunk-LELPCIE7.js +840 -0
  19. package/dist/chunk-LELPCIE7.js.map +1 -0
  20. package/dist/chunk-MCZG7QEM.cjs +310 -0
  21. package/dist/chunk-MCZG7QEM.cjs.map +1 -0
  22. package/dist/chunk-TCVKC227.js +56 -0
  23. package/dist/chunk-TCVKC227.js.map +1 -0
  24. package/dist/chunk-VXLUSU5B.cjs +856 -0
  25. package/dist/chunk-VXLUSU5B.cjs.map +1 -0
  26. package/dist/chunk-WCQVDF3K.js +12 -0
  27. package/dist/chunk-WCQVDF3K.js.map +1 -0
  28. package/dist/chunk-WGEGR3DF.cjs +15 -0
  29. package/dist/chunk-WGEGR3DF.cjs.map +1 -0
  30. package/dist/client-session-claim-3QF3noOr.d.ts +197 -0
  31. package/dist/client-session-claim-C4lUik3b.d.cts +197 -0
  32. package/dist/core-DMhuNfoz.d.cts +62 -0
  33. package/dist/core-DMhuNfoz.d.ts +62 -0
  34. package/dist/crypto/providers/noble-provider.cjs +14 -0
  35. package/dist/crypto/providers/noble-provider.cjs.map +1 -0
  36. package/dist/crypto/providers/noble-provider.d.cts +30 -0
  37. package/dist/crypto/providers/noble-provider.d.ts +30 -0
  38. package/dist/crypto/providers/noble-provider.js +5 -0
  39. package/dist/crypto/providers/noble-provider.js.map +1 -0
  40. package/dist/crypto/providers/node-provider.cjs +308 -0
  41. package/dist/crypto/providers/node-provider.cjs.map +1 -0
  42. package/dist/crypto/providers/node-provider.d.cts +32 -0
  43. package/dist/crypto/providers/node-provider.d.ts +32 -0
  44. package/dist/crypto/providers/node-provider.js +306 -0
  45. package/dist/crypto/providers/node-provider.js.map +1 -0
  46. package/dist/crypto/providers/quickcrypto-provider.cjs +339 -0
  47. package/dist/crypto/providers/quickcrypto-provider.cjs.map +1 -0
  48. package/dist/crypto/providers/quickcrypto-provider.d.cts +34 -0
  49. package/dist/crypto/providers/quickcrypto-provider.d.ts +34 -0
  50. package/dist/crypto/providers/quickcrypto-provider.js +337 -0
  51. package/dist/crypto/providers/quickcrypto-provider.js.map +1 -0
  52. package/dist/crypto/providers/webcrypto-provider.cjs +310 -0
  53. package/dist/crypto/providers/webcrypto-provider.cjs.map +1 -0
  54. package/dist/crypto/providers/webcrypto-provider.d.cts +30 -0
  55. package/dist/crypto/providers/webcrypto-provider.d.ts +30 -0
  56. package/dist/crypto/providers/webcrypto-provider.js +308 -0
  57. package/dist/crypto/providers/webcrypto-provider.js.map +1 -0
  58. package/dist/crypto-BUS06Qz-.d.cts +40 -0
  59. package/dist/crypto-BUS06Qz-.d.ts +40 -0
  60. package/dist/crypto-export.cjs +790 -0
  61. package/dist/crypto-export.cjs.map +1 -0
  62. package/dist/crypto-export.d.cts +257 -0
  63. package/dist/crypto-export.d.ts +257 -0
  64. package/dist/crypto-export.js +709 -0
  65. package/dist/crypto-export.js.map +1 -0
  66. package/dist/crypto-provider-deYoVIxi.d.cts +36 -0
  67. package/dist/crypto-provider-deYoVIxi.d.ts +36 -0
  68. package/dist/index.cjs +615 -0
  69. package/dist/index.cjs.map +1 -0
  70. package/dist/index.d.cts +379 -0
  71. package/dist/index.d.ts +379 -0
  72. package/dist/index.js +504 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/schemas-export.cjs +294 -0
  75. package/dist/schemas-export.cjs.map +1 -0
  76. package/dist/schemas-export.d.cts +1598 -0
  77. package/dist/schemas-export.d.ts +1598 -0
  78. package/dist/schemas-export.js +5 -0
  79. package/dist/schemas-export.js.map +1 -0
  80. package/dist/siwe-export.cjs +237 -0
  81. package/dist/siwe-export.cjs.map +1 -0
  82. package/dist/siwe-export.d.cts +27 -0
  83. package/dist/siwe-export.d.ts +27 -0
  84. package/dist/siwe-export.js +228 -0
  85. package/dist/siwe-export.js.map +1 -0
  86. package/dist/testing.cjs +54 -0
  87. package/dist/testing.cjs.map +1 -0
  88. package/dist/testing.d.cts +20 -0
  89. package/dist/testing.d.ts +20 -0
  90. package/dist/testing.js +51 -0
  91. package/dist/testing.js.map +1 -0
  92. package/dist/validation-export.cjs +359 -0
  93. package/dist/validation-export.cjs.map +1 -0
  94. package/dist/validation-export.d.cts +3 -0
  95. package/dist/validation-export.d.ts +3 -0
  96. package/dist/validation-export.js +6 -0
  97. package/dist/validation-export.js.map +1 -0
  98. package/dist/validators-export.cjs +73 -0
  99. package/dist/validators-export.cjs.map +1 -0
  100. package/dist/validators-export.d.cts +37 -0
  101. package/dist/validators-export.d.ts +37 -0
  102. package/dist/validators-export.js +4 -0
  103. package/dist/validators-export.js.map +1 -0
  104. package/package.json +140 -0
  105. package/src/constants/index.ts +205 -0
  106. package/src/crypto/context.ts +228 -0
  107. package/src/crypto/diagnostics.ts +772 -0
  108. package/src/crypto/errors.ts +114 -0
  109. package/src/crypto/index.ts +89 -0
  110. package/src/crypto/payload-handler.ts +102 -0
  111. package/src/crypto/providers/compliance-provider.ts +579 -0
  112. package/src/crypto/providers/factory.ts +204 -0
  113. package/src/crypto/providers/index.ts +44 -0
  114. package/src/crypto/providers/noble-provider.ts +392 -0
  115. package/src/crypto/providers/node-provider.ts +433 -0
  116. package/src/crypto/providers/quickcrypto-provider.ts +483 -0
  117. package/src/crypto/providers/registry.ts +129 -0
  118. package/src/crypto/providers/webcrypto-provider.ts +364 -0
  119. package/src/crypto/session-security.ts +185 -0
  120. package/src/crypto/types.ts +93 -0
  121. package/src/crypto/utils.ts +190 -0
  122. package/src/crypto-export.ts +21 -0
  123. package/src/index.ts +38 -0
  124. package/src/schemas/auth.ts +60 -0
  125. package/src/schemas/client-messages.ts +57 -0
  126. package/src/schemas/core.ts +144 -0
  127. package/src/schemas/crypto.ts +65 -0
  128. package/src/schemas/discovery.ts +79 -0
  129. package/src/schemas/index.ts +239 -0
  130. package/src/schemas/relay-messages.ts +45 -0
  131. package/src/schemas/wallet-messages.ts +177 -0
  132. package/src/schemas-export.ts +23 -0
  133. package/src/siwe-export.ts +27 -0
  134. package/src/testing.ts +71 -0
  135. package/src/types/auth.ts +60 -0
  136. package/src/types/client-messages.ts +84 -0
  137. package/src/types/core.ts +131 -0
  138. package/src/types/crypto-provider.ts +264 -0
  139. package/src/types/crypto.ts +90 -0
  140. package/src/types/discovery.ts +50 -0
  141. package/src/types/errors.ts +87 -0
  142. package/src/types/index.ts +197 -0
  143. package/src/types/post-auth-operations.ts +363 -0
  144. package/src/types/providers.ts +72 -0
  145. package/src/types/relay-messages.ts +60 -0
  146. package/src/types/request-lifecycle.ts +161 -0
  147. package/src/types/signing-operations.ts +99 -0
  148. package/src/types/wallet-messages.ts +251 -0
  149. package/src/utils/client-session-claim.ts +188 -0
  150. package/src/utils/index.ts +54 -0
  151. package/src/utils/public-keys.ts +49 -0
  152. package/src/utils/siwe.ts +362 -0
  153. package/src/utils/url-decoding.ts +126 -0
  154. package/src/utils/url-encoding.ts +144 -0
  155. package/src/utils/wallet-session-claim.ts +188 -0
  156. package/src/validation-export.ts +32 -0
  157. package/src/validators/index.ts +222 -0
  158. package/src/validators-export.ts +8 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,615 @@
1
+ 'use strict';
2
+
3
+ var chunkVXLUSU5B_cjs = require('./chunk-VXLUSU5B.cjs');
4
+ var chunkGI3BUPIH_cjs = require('./chunk-GI3BUPIH.cjs');
5
+ require('./chunk-A6FLEJ7R.cjs');
6
+ var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
7
+
8
+ // src/types/wallet-messages.ts
9
+ function isClaimSessionPayload(payload) {
10
+ return payload?.type === "claim_session";
11
+ }
12
+ chunkWGEGR3DF_cjs.__name(isClaimSessionPayload, "isClaimSessionPayload");
13
+ function isPrefetchMetadataPayload(payload) {
14
+ return payload?.type === "prefetch_metadata";
15
+ }
16
+ chunkWGEGR3DF_cjs.__name(isPrefetchMetadataPayload, "isPrefetchMetadataPayload");
17
+ function isConnectionRejectedPayload(payload) {
18
+ return payload?.type === "connection_rejected";
19
+ }
20
+ chunkWGEGR3DF_cjs.__name(isConnectionRejectedPayload, "isConnectionRejectedPayload");
21
+ function isAuthenticateConnectionPayload(payload) {
22
+ return payload?.type === "authenticate_connection";
23
+ }
24
+ chunkWGEGR3DF_cjs.__name(isAuthenticateConnectionPayload, "isAuthenticateConnectionPayload");
25
+ function isWalletReconnectPayload(payload) {
26
+ return payload?.type === "wallet_reconnect";
27
+ }
28
+ chunkWGEGR3DF_cjs.__name(isWalletReconnectPayload, "isWalletReconnectPayload");
29
+ function isWalletHandshakeMessage(message) {
30
+ return message?.type === "wallet_handshake";
31
+ }
32
+ chunkWGEGR3DF_cjs.__name(isWalletHandshakeMessage, "isWalletHandshakeMessage");
33
+ function isConnectionRejectedMessage(message) {
34
+ return message?.type === "connection_rejected";
35
+ }
36
+ chunkWGEGR3DF_cjs.__name(isConnectionRejectedMessage, "isConnectionRejectedMessage");
37
+ function isConnectionAuthenticatedMessage(message) {
38
+ return message?.type === "connection_authenticated";
39
+ }
40
+ chunkWGEGR3DF_cjs.__name(isConnectionAuthenticatedMessage, "isConnectionAuthenticatedMessage");
41
+
42
+ // src/types/client-messages.ts
43
+ function isClientReconnectPayload(payload) {
44
+ return payload?.type === "client_reconnect";
45
+ }
46
+ chunkWGEGR3DF_cjs.__name(isClientReconnectPayload, "isClientReconnectPayload");
47
+ function isCloseSessionPayload(payload) {
48
+ return payload?.type === "close_session";
49
+ }
50
+ chunkWGEGR3DF_cjs.__name(isCloseSessionPayload, "isCloseSessionPayload");
51
+
52
+ // src/types/relay-messages.ts
53
+ function isSessionClosedAck(message) {
54
+ return message?.type === "session_closed_ack";
55
+ }
56
+ chunkWGEGR3DF_cjs.__name(isSessionClosedAck, "isSessionClosedAck");
57
+ function isSessionClosedNotification(message) {
58
+ return message?.type === "session_closed_notification";
59
+ }
60
+ chunkWGEGR3DF_cjs.__name(isSessionClosedNotification, "isSessionClosedNotification");
61
+ function isReconnectedMessage(message) {
62
+ return message?.type === "reconnected";
63
+ }
64
+ chunkWGEGR3DF_cjs.__name(isReconnectedMessage, "isReconnectedMessage");
65
+
66
+ // src/utils/public-keys.ts
67
+ function compressPublicKey(publicKey) {
68
+ const keyWithoutPrefix = publicKey.startsWith("AES-GCM:") ? publicKey.slice(8) : publicKey;
69
+ return keyWithoutPrefix.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
70
+ }
71
+ chunkWGEGR3DF_cjs.__name(compressPublicKey, "compressPublicKey");
72
+ function decompressPublicKey(compressedKey) {
73
+ let base64Key = compressedKey.replace(/-/g, "+").replace(/_/g, "/");
74
+ const padding = base64Key.length % 4;
75
+ if (padding > 0) {
76
+ base64Key += "=".repeat(4 - padding);
77
+ }
78
+ return base64Key.startsWith("AES-GCM:") ? base64Key : `AES-GCM:${base64Key}`;
79
+ }
80
+ chunkWGEGR3DF_cjs.__name(decompressPublicKey, "decompressPublicKey");
81
+
82
+ // src/utils/url-encoding.ts
83
+ var PROVIDER_SHORTCODES = {
84
+ "uwebsockets": "u",
85
+ // Legacy - API may still return this
86
+ "websocket": "w",
87
+ "pusher": "p",
88
+ "ably": "a"
89
+ };
90
+ var PRODUCTION_RELAY_URLS = [
91
+ "wss://relay.banana.link/v1",
92
+ "https://relay.banana.link/v1"
93
+ ];
94
+ var RELAY_SHORTCODES = {
95
+ "wss://relay.dev.banana.link/v1": "d",
96
+ "https://relay.dev.banana.link/v1": "d",
97
+ "wss://relay.staging.banana.link/v1": "s",
98
+ // Future staging environment
99
+ "https://relay.staging.banana.link/v1": "s"
100
+ };
101
+ function encodeUrlParameter(value) {
102
+ return encodeURIComponent(value);
103
+ }
104
+ chunkWGEGR3DF_cjs.__name(encodeUrlParameter, "encodeUrlParameter");
105
+ function buildQueryString(params) {
106
+ const pairs = [];
107
+ for (const [key, value] of Object.entries(params)) {
108
+ if (value !== void 0) {
109
+ pairs.push(`${encodeUrlParameter(key)}=${encodeUrlParameter(value)}`);
110
+ }
111
+ }
112
+ return pairs.join("&");
113
+ }
114
+ chunkWGEGR3DF_cjs.__name(buildQueryString, "buildQueryString");
115
+ function encodeCompactConnectionString(payload) {
116
+ const params = {
117
+ s: payload.sessionId,
118
+ // sessionId -> s
119
+ k: compressPublicKey(payload.publicKey)
120
+ // publicKey -> k (compressed)
121
+ };
122
+ if (payload.providerId) {
123
+ params.p = PROVIDER_SHORTCODES[payload.providerId] || payload.providerId;
124
+ }
125
+ if (payload.relayUrl) {
126
+ if (PRODUCTION_RELAY_URLS.includes(payload.relayUrl)) ; else if (RELAY_SHORTCODES[payload.relayUrl]) {
127
+ params.r = RELAY_SHORTCODES[payload.relayUrl];
128
+ } else {
129
+ params.r = payload.relayUrl;
130
+ }
131
+ }
132
+ const queryString = buildQueryString(params);
133
+ return `${chunkGI3BUPIH_cjs.DEEPLINK_SCHEME}://connect?${queryString}`;
134
+ }
135
+ chunkWGEGR3DF_cjs.__name(encodeCompactConnectionString, "encodeCompactConnectionString");
136
+ function encodeConnectionString(payload) {
137
+ const params = {
138
+ sessionId: payload.sessionId,
139
+ publicKey: payload.publicKey
140
+ };
141
+ if (payload.providerId) {
142
+ params.providerId = payload.providerId;
143
+ }
144
+ if (payload.relayUrl) {
145
+ params.relay = payload.relayUrl;
146
+ }
147
+ const queryString = buildQueryString(params);
148
+ return `${chunkGI3BUPIH_cjs.DEEPLINK_SCHEME}://connect?${queryString}`;
149
+ }
150
+ chunkWGEGR3DF_cjs.__name(encodeConnectionString, "encodeConnectionString");
151
+ function encodeUniversalLink(payload, options = {}) {
152
+ const {
153
+ baseUrl = "https://banana.link",
154
+ fallbackUrl = "https://banana.link/download"
155
+ } = options;
156
+ const params = {
157
+ sessionId: payload.sessionId,
158
+ key: payload.publicKey,
159
+ // Use 'key' instead of 'publicKey' for universal links
160
+ fallback: fallbackUrl
161
+ };
162
+ if (payload.providerId) {
163
+ params.provider = payload.providerId;
164
+ }
165
+ if (payload.relayUrl) {
166
+ params.relay = payload.relayUrl;
167
+ }
168
+ const queryString = buildQueryString(params);
169
+ return `${baseUrl}/connect?${queryString}`;
170
+ }
171
+ chunkWGEGR3DF_cjs.__name(encodeUniversalLink, "encodeUniversalLink");
172
+
173
+ // src/utils/url-decoding.ts
174
+ var PROVIDER_SHORTCODES_REVERSE = {
175
+ "u": "websocket",
176
+ // Decode legacy 'u' to new 'websocket' name
177
+ "w": "websocket",
178
+ "p": "pusher",
179
+ "a": "ably"
180
+ };
181
+ var RELAY_SHORTCODES_REVERSE = {
182
+ "d": "wss://relay.dev.banana.link/v1",
183
+ "s": "wss://relay.staging.banana.link/v1"
184
+ };
185
+ function decodeUrlParameter(value) {
186
+ return decodeURIComponent(value);
187
+ }
188
+ chunkWGEGR3DF_cjs.__name(decodeUrlParameter, "decodeUrlParameter");
189
+ function parseQueryString(query) {
190
+ const params = {};
191
+ const cleanQuery = query.startsWith("?") ? query.slice(1) : query;
192
+ if (!cleanQuery) {
193
+ return params;
194
+ }
195
+ for (const pair of cleanQuery.split("&")) {
196
+ const [key, ...valueParts] = pair.split("=");
197
+ if (key) {
198
+ const value = valueParts.join("=");
199
+ params[decodeUrlParameter(key)] = decodeUrlParameter(value);
200
+ }
201
+ }
202
+ return params;
203
+ }
204
+ chunkWGEGR3DF_cjs.__name(parseQueryString, "parseQueryString");
205
+ function decodeConnectionString(connectionString) {
206
+ let url;
207
+ try {
208
+ url = new URL(connectionString);
209
+ } catch {
210
+ throw new Error(`Invalid connection string format: ${connectionString}`);
211
+ }
212
+ const params = parseQueryString(url.search);
213
+ const sessionId = params.sessionId || params.s;
214
+ let publicKey = params.publicKey || params.key || params.k;
215
+ let providerId = params.providerId || params.provider || params.p;
216
+ let relayUrl = params.relay || params.r;
217
+ if (!sessionId || !publicKey) {
218
+ throw new Error("Missing required parameters: sessionId and publicKey");
219
+ }
220
+ if (params.k && !params.publicKey && !params.key) {
221
+ publicKey = decompressPublicKey(params.k);
222
+ }
223
+ if (params.p && !params.providerId && !params.provider) {
224
+ providerId = PROVIDER_SHORTCODES_REVERSE[params.p] || params.p;
225
+ }
226
+ if (!relayUrl) {
227
+ relayUrl = "wss://relay.banana.link/v1";
228
+ } else if (RELAY_SHORTCODES_REVERSE[relayUrl]) {
229
+ relayUrl = RELAY_SHORTCODES_REVERSE[relayUrl];
230
+ }
231
+ if (publicKey && !publicKey.startsWith("AES-GCM:")) {
232
+ publicKey = `AES-GCM:${publicKey}`;
233
+ }
234
+ return {
235
+ sessionId,
236
+ publicKey,
237
+ providerId: providerId || void 0,
238
+ relayUrl: relayUrl || void 0
239
+ };
240
+ }
241
+ chunkWGEGR3DF_cjs.__name(decodeConnectionString, "decodeConnectionString");
242
+ function isValidConnectionString(connectionString) {
243
+ try {
244
+ decodeConnectionString(connectionString);
245
+ return true;
246
+ } catch {
247
+ return false;
248
+ }
249
+ }
250
+ chunkWGEGR3DF_cjs.__name(isValidConnectionString, "isValidConnectionString");
251
+
252
+ // src/utils/wallet-session-claim.ts
253
+ var _WalletSessionClaimManager = class _WalletSessionClaimManager {
254
+ constructor(storage) {
255
+ this.storage = storage;
256
+ }
257
+ /**
258
+ * Generate a new wallet session claim with provided nonce
259
+ * @param sessionId - Session identifier
260
+ * @param sessionNonce - Pre-generated cryptographically secure nonce (use @bananalink-sdk/crypto)
261
+ * @returns Generated wallet session claim
262
+ */
263
+ async generateClaim(sessionId, sessionNonce) {
264
+ const claim = {
265
+ sessionNonce,
266
+ timestamp: Date.now()
267
+ };
268
+ await this.storage.store(sessionId, claim);
269
+ return claim;
270
+ }
271
+ /**
272
+ * Retrieve an existing wallet session claim
273
+ * @param sessionId - Session identifier
274
+ * @returns Stored wallet session claim or null if not found
275
+ */
276
+ async getClaim(sessionId) {
277
+ return this.storage.retrieve(sessionId);
278
+ }
279
+ /**
280
+ * Validate a wallet session claim for reconnection
281
+ * @param claim - Claim to validate
282
+ * @param storedClaim - Previously stored claim
283
+ * @returns Validation result
284
+ */
285
+ validateReconnectionClaim(claim, storedClaim) {
286
+ if (claim.sessionNonce !== storedClaim.sessionNonce) {
287
+ return {
288
+ valid: false,
289
+ reason: "Session nonce mismatch - invalid reconnection attempt"
290
+ };
291
+ }
292
+ const MAX_RECONNECTION_AGE = 24 * 60 * 60 * 1e3;
293
+ const claimAge = Date.now() - claim.timestamp;
294
+ if (claimAge > MAX_RECONNECTION_AGE) {
295
+ return {
296
+ valid: false,
297
+ reason: "Session claim too old - please create a new session"
298
+ };
299
+ }
300
+ return { valid: true };
301
+ }
302
+ /**
303
+ * Remove a wallet session claim (on session end)
304
+ * @param sessionId - Session identifier
305
+ */
306
+ async removeClaim(sessionId) {
307
+ await this.storage.remove(sessionId);
308
+ }
309
+ /**
310
+ * Clear all stored claims
311
+ */
312
+ async clearAllClaims() {
313
+ await this.storage.clear();
314
+ }
315
+ };
316
+ chunkWGEGR3DF_cjs.__name(_WalletSessionClaimManager, "WalletSessionClaimManager");
317
+ var WalletSessionClaimManager = _WalletSessionClaimManager;
318
+ function createWalletMessageEnvelope(sessionId, claim, payload) {
319
+ return {
320
+ sessionId,
321
+ walletSessionClaim: claim,
322
+ payload
323
+ };
324
+ }
325
+ chunkWGEGR3DF_cjs.__name(createWalletMessageEnvelope, "createWalletMessageEnvelope");
326
+ function stripWalletSessionClaim(envelope) {
327
+ const { walletSessionClaim, ...messageWithoutClaim } = envelope;
328
+ return messageWithoutClaim;
329
+ }
330
+ chunkWGEGR3DF_cjs.__name(stripWalletSessionClaim, "stripWalletSessionClaim");
331
+ function validateClaimTimestamp(timestamp, maxAge = 30 * 1e3) {
332
+ const now = Date.now();
333
+ const age = Math.abs(now - timestamp);
334
+ return age <= maxAge;
335
+ }
336
+ chunkWGEGR3DF_cjs.__name(validateClaimTimestamp, "validateClaimTimestamp");
337
+ function validateWalletMessageEnvelope(envelope) {
338
+ const errors = [];
339
+ if (!envelope.sessionId) {
340
+ errors.push("Missing session ID");
341
+ }
342
+ if (!envelope.walletSessionClaim) {
343
+ errors.push("Missing wallet session claim");
344
+ } else {
345
+ if (!envelope.walletSessionClaim.sessionNonce) {
346
+ errors.push("Missing session nonce in wallet session claim");
347
+ }
348
+ if (!envelope.walletSessionClaim.timestamp) {
349
+ errors.push("Missing timestamp in wallet session claim");
350
+ } else if (!validateClaimTimestamp(envelope.walletSessionClaim.timestamp)) {
351
+ errors.push("Wallet session claim timestamp is too old or invalid");
352
+ }
353
+ }
354
+ if (!envelope.payload) {
355
+ errors.push("Missing message payload");
356
+ } else if (!envelope.payload.type) {
357
+ errors.push("Missing payload type");
358
+ }
359
+ return {
360
+ valid: errors.length === 0,
361
+ errors
362
+ };
363
+ }
364
+ chunkWGEGR3DF_cjs.__name(validateWalletMessageEnvelope, "validateWalletMessageEnvelope");
365
+
366
+ // src/utils/client-session-claim.ts
367
+ var _ClientSessionClaimManager = class _ClientSessionClaimManager {
368
+ constructor(storage) {
369
+ this.storage = storage;
370
+ }
371
+ /**
372
+ * Generate a new client session claim with provided nonce
373
+ * @param sessionId - Session identifier
374
+ * @param claimNonce - Pre-generated cryptographically secure nonce (use @bananalink-sdk/crypto)
375
+ * @returns Generated client session claim
376
+ */
377
+ async generateClaim(sessionId, claimNonce) {
378
+ const claim = {
379
+ claimNonce,
380
+ timestamp: Date.now()
381
+ };
382
+ await this.storage.store(sessionId, claim);
383
+ return claim;
384
+ }
385
+ /**
386
+ * Retrieve an existing client session claim
387
+ * @param sessionId - Session identifier
388
+ * @returns Stored client session claim or null if not found
389
+ */
390
+ async getClaim(sessionId) {
391
+ return this.storage.retrieve(sessionId);
392
+ }
393
+ /**
394
+ * Validate a client session claim for reconnection
395
+ * @param claim - Claim to validate
396
+ * @param storedClaim - Previously stored claim
397
+ * @returns Validation result
398
+ */
399
+ validateReconnectionClaim(claim, storedClaim) {
400
+ if (claim.claimNonce !== storedClaim.claimNonce) {
401
+ return {
402
+ valid: false,
403
+ reason: "Client claim nonce mismatch - invalid reconnection attempt"
404
+ };
405
+ }
406
+ const MAX_RECONNECTION_AGE = 24 * 60 * 60 * 1e3;
407
+ const claimAge = Date.now() - claim.timestamp;
408
+ if (claimAge > MAX_RECONNECTION_AGE) {
409
+ return {
410
+ valid: false,
411
+ reason: "Client session claim too old - please create a new session"
412
+ };
413
+ }
414
+ return { valid: true };
415
+ }
416
+ /**
417
+ * Remove a client session claim (on session end)
418
+ * @param sessionId - Session identifier
419
+ */
420
+ async removeClaim(sessionId) {
421
+ await this.storage.remove(sessionId);
422
+ }
423
+ /**
424
+ * Clear all stored claims
425
+ */
426
+ async clearAllClaims() {
427
+ await this.storage.clear();
428
+ }
429
+ };
430
+ chunkWGEGR3DF_cjs.__name(_ClientSessionClaimManager, "ClientSessionClaimManager");
431
+ var ClientSessionClaimManager = _ClientSessionClaimManager;
432
+ function createClientMessageEnvelope(sessionId, claim, payload) {
433
+ return {
434
+ sessionId,
435
+ clientSessionClaim: claim,
436
+ payload
437
+ };
438
+ }
439
+ chunkWGEGR3DF_cjs.__name(createClientMessageEnvelope, "createClientMessageEnvelope");
440
+ function stripClientSessionClaim(envelope) {
441
+ const { clientSessionClaim, ...messageWithoutClaim } = envelope;
442
+ return messageWithoutClaim;
443
+ }
444
+ chunkWGEGR3DF_cjs.__name(stripClientSessionClaim, "stripClientSessionClaim");
445
+ function validateClientClaimTimestamp(timestamp, maxAge = 30 * 1e3) {
446
+ const now = Date.now();
447
+ const age = Math.abs(now - timestamp);
448
+ return age <= maxAge;
449
+ }
450
+ chunkWGEGR3DF_cjs.__name(validateClientClaimTimestamp, "validateClientClaimTimestamp");
451
+ function validateClientMessageEnvelope(envelope) {
452
+ const errors = [];
453
+ if (!envelope.sessionId) {
454
+ errors.push("Missing session ID");
455
+ }
456
+ if (!envelope.clientSessionClaim) {
457
+ errors.push("Missing client session claim");
458
+ } else {
459
+ if (!envelope.clientSessionClaim.claimNonce) {
460
+ errors.push("Missing claim nonce in client session claim");
461
+ }
462
+ if (!envelope.clientSessionClaim.timestamp) {
463
+ errors.push("Missing timestamp in client session claim");
464
+ } else if (!validateClientClaimTimestamp(envelope.clientSessionClaim.timestamp)) {
465
+ errors.push("Client session claim timestamp is too old or invalid");
466
+ }
467
+ }
468
+ if (!envelope.payload) {
469
+ errors.push("Missing message payload");
470
+ } else if (!envelope.payload.type) {
471
+ errors.push("Missing payload type");
472
+ }
473
+ return {
474
+ valid: errors.length === 0,
475
+ errors
476
+ };
477
+ }
478
+ chunkWGEGR3DF_cjs.__name(validateClientMessageEnvelope, "validateClientMessageEnvelope");
479
+
480
+ // src/utils/index.ts
481
+ function generateSessionId() {
482
+ return chunkVXLUSU5B_cjs.generateUUID();
483
+ }
484
+ chunkWGEGR3DF_cjs.__name(generateSessionId, "generateSessionId");
485
+ function isValidProtocolVersion(version) {
486
+ return version === "1";
487
+ }
488
+ chunkWGEGR3DF_cjs.__name(isValidProtocolVersion, "isValidProtocolVersion");
489
+ function isValidSessionId(sessionId) {
490
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
491
+ return uuidRegex.test(sessionId);
492
+ }
493
+ chunkWGEGR3DF_cjs.__name(isValidSessionId, "isValidSessionId");
494
+
495
+ // package.json
496
+ var package_default = {
497
+ version: "1.2.7"};
498
+
499
+ // src/index.ts
500
+ var VERSION = package_default.version;
501
+ var PACKAGE_NAME = "@bananalink-sdk/protocol";
502
+
503
+ Object.defineProperty(exports, "BANANALINK_CONSTANTS", {
504
+ enumerable: true,
505
+ get: function () { return chunkGI3BUPIH_cjs.BANANALINK_CONSTANTS; }
506
+ });
507
+ Object.defineProperty(exports, "CRYPTO_CONSTANTS", {
508
+ enumerable: true,
509
+ get: function () { return chunkGI3BUPIH_cjs.CRYPTO_CONSTANTS; }
510
+ });
511
+ Object.defineProperty(exports, "DEEPLINK_SCHEME", {
512
+ enumerable: true,
513
+ get: function () { return chunkGI3BUPIH_cjs.DEEPLINK_SCHEME; }
514
+ });
515
+ Object.defineProperty(exports, "DEEP_LINK_CONFIG", {
516
+ enumerable: true,
517
+ get: function () { return chunkGI3BUPIH_cjs.DEEP_LINK_CONFIG; }
518
+ });
519
+ Object.defineProperty(exports, "DEFAULT_RELAY_URL", {
520
+ enumerable: true,
521
+ get: function () { return chunkGI3BUPIH_cjs.DEFAULT_RELAY_URL; }
522
+ });
523
+ Object.defineProperty(exports, "DEFAULT_TIMEOUTS", {
524
+ enumerable: true,
525
+ get: function () { return chunkGI3BUPIH_cjs.DEFAULT_TIMEOUTS; }
526
+ });
527
+ Object.defineProperty(exports, "DEV_CONFIG", {
528
+ enumerable: true,
529
+ get: function () { return chunkGI3BUPIH_cjs.DEV_CONFIG; }
530
+ });
531
+ Object.defineProperty(exports, "ERROR_MESSAGES", {
532
+ enumerable: true,
533
+ get: function () { return chunkGI3BUPIH_cjs.ERROR_MESSAGES; }
534
+ });
535
+ Object.defineProperty(exports, "FRUITS", {
536
+ enumerable: true,
537
+ get: function () { return chunkGI3BUPIH_cjs.FRUITS; }
538
+ });
539
+ Object.defineProperty(exports, "HTTP_ENDPOINTS", {
540
+ enumerable: true,
541
+ get: function () { return chunkGI3BUPIH_cjs.HTTP_ENDPOINTS; }
542
+ });
543
+ Object.defineProperty(exports, "MESSAGE_FORMAT", {
544
+ enumerable: true,
545
+ get: function () { return chunkGI3BUPIH_cjs.MESSAGE_FORMAT; }
546
+ });
547
+ Object.defineProperty(exports, "MESSAGE_QUEUE_CONFIG", {
548
+ enumerable: true,
549
+ get: function () { return chunkGI3BUPIH_cjs.MESSAGE_QUEUE_CONFIG; }
550
+ });
551
+ Object.defineProperty(exports, "NETWORK_CONFIG", {
552
+ enumerable: true,
553
+ get: function () { return chunkGI3BUPIH_cjs.NETWORK_CONFIG; }
554
+ });
555
+ Object.defineProperty(exports, "PROTOCOL_V2_TIMEOUTS", {
556
+ enumerable: true,
557
+ get: function () { return chunkGI3BUPIH_cjs.PROTOCOL_V2_TIMEOUTS; }
558
+ });
559
+ Object.defineProperty(exports, "PROTOCOL_VERSION", {
560
+ enumerable: true,
561
+ get: function () { return chunkGI3BUPIH_cjs.PROTOCOL_VERSION; }
562
+ });
563
+ Object.defineProperty(exports, "QR_CONFIG", {
564
+ enumerable: true,
565
+ get: function () { return chunkGI3BUPIH_cjs.QR_CONFIG; }
566
+ });
567
+ Object.defineProperty(exports, "SECURITY_LIMITS", {
568
+ enumerable: true,
569
+ get: function () { return chunkGI3BUPIH_cjs.SECURITY_LIMITS; }
570
+ });
571
+ Object.defineProperty(exports, "WS_MESSAGE_TYPES", {
572
+ enumerable: true,
573
+ get: function () { return chunkGI3BUPIH_cjs.WS_MESSAGE_TYPES; }
574
+ });
575
+ exports.ClientSessionClaimManager = ClientSessionClaimManager;
576
+ exports.PACKAGE_NAME = PACKAGE_NAME;
577
+ exports.VERSION = VERSION;
578
+ exports.WalletSessionClaimManager = WalletSessionClaimManager;
579
+ exports.buildQueryString = buildQueryString;
580
+ exports.compressPublicKey = compressPublicKey;
581
+ exports.createClientMessageEnvelope = createClientMessageEnvelope;
582
+ exports.createWalletMessageEnvelope = createWalletMessageEnvelope;
583
+ exports.decodeConnectionString = decodeConnectionString;
584
+ exports.decodeUrlParameter = decodeUrlParameter;
585
+ exports.decompressPublicKey = decompressPublicKey;
586
+ exports.encodeCompactConnectionString = encodeCompactConnectionString;
587
+ exports.encodeConnectionString = encodeConnectionString;
588
+ exports.encodeUniversalLink = encodeUniversalLink;
589
+ exports.encodeUrlParameter = encodeUrlParameter;
590
+ exports.generateSessionId = generateSessionId;
591
+ exports.isAuthenticateConnectionPayload = isAuthenticateConnectionPayload;
592
+ exports.isClaimSessionPayload = isClaimSessionPayload;
593
+ exports.isClientReconnectPayload = isClientReconnectPayload;
594
+ exports.isCloseSessionPayload = isCloseSessionPayload;
595
+ exports.isConnectionAuthenticatedMessage = isConnectionAuthenticatedMessage;
596
+ exports.isConnectionRejectedMessage = isConnectionRejectedMessage;
597
+ exports.isConnectionRejectedPayload = isConnectionRejectedPayload;
598
+ exports.isPrefetchMetadataPayload = isPrefetchMetadataPayload;
599
+ exports.isReconnectedMessage = isReconnectedMessage;
600
+ exports.isSessionClosedAck = isSessionClosedAck;
601
+ exports.isSessionClosedNotification = isSessionClosedNotification;
602
+ exports.isValidConnectionString = isValidConnectionString;
603
+ exports.isValidProtocolVersion = isValidProtocolVersion;
604
+ exports.isValidSessionId = isValidSessionId;
605
+ exports.isWalletHandshakeMessage = isWalletHandshakeMessage;
606
+ exports.isWalletReconnectPayload = isWalletReconnectPayload;
607
+ exports.parseQueryString = parseQueryString;
608
+ exports.stripClientSessionClaim = stripClientSessionClaim;
609
+ exports.stripWalletSessionClaim = stripWalletSessionClaim;
610
+ exports.validateClaimTimestamp = validateClaimTimestamp;
611
+ exports.validateClientClaimTimestamp = validateClientClaimTimestamp;
612
+ exports.validateClientMessageEnvelope = validateClientMessageEnvelope;
613
+ exports.validateWalletMessageEnvelope = validateWalletMessageEnvelope;
614
+ //# sourceMappingURL=index.cjs.map
615
+ //# sourceMappingURL=index.cjs.map