@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
@@ -0,0 +1,790 @@
1
+ 'use strict';
2
+
3
+ var chunkVXLUSU5B_cjs = require('./chunk-VXLUSU5B.cjs');
4
+ var chunkA6FLEJ7R_cjs = require('./chunk-A6FLEJ7R.cjs');
5
+ var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
6
+
7
+ // src/crypto/session-security.ts
8
+ var CRYPTO_CONFIG = {
9
+ ivLength: 12};
10
+ var _SessionSecurity = class _SessionSecurity {
11
+ constructor(sessionId, provider, logger) {
12
+ this.provider = provider || chunkVXLUSU5B_cjs.createCryptoProvider(void 0, logger);
13
+ this.sessionId = sessionId || this.generateSessionId();
14
+ }
15
+ /**
16
+ * Get the crypto provider used by this session
17
+ */
18
+ getCryptoProvider() {
19
+ return this.provider;
20
+ }
21
+ /**
22
+ * Establish a new session with ephemeral key generation
23
+ */
24
+ static async establishSession(sessionId, provider, logger) {
25
+ const session = new _SessionSecurity(sessionId, provider, logger);
26
+ await session.generateKeyPair();
27
+ return session;
28
+ }
29
+ /**
30
+ * Generate ECDH key pair for this session
31
+ */
32
+ async generateKeyPair() {
33
+ this.keyPair = await this.provider.generateKeyPair();
34
+ }
35
+ /**
36
+ * Get the public key for sharing (base64 encoded)
37
+ */
38
+ async getPublicKey() {
39
+ if (!this.keyPair?.publicKey) {
40
+ throw new Error("Key pair not generated. Call generateKeyPair() first.");
41
+ }
42
+ const exported = await this.provider.exportPublicKey(this.keyPair.publicKey);
43
+ return chunkVXLUSU5B_cjs.arrayBufferToBase64(exported);
44
+ }
45
+ /**
46
+ * Derive shared secret from peer's public key
47
+ */
48
+ async deriveSharedSecret(peerPublicKeyBase64) {
49
+ if (!this.keyPair?.privateKey) {
50
+ throw new Error("Key pair not generated");
51
+ }
52
+ const peerPublicKeyBuffer = chunkVXLUSU5B_cjs.base64ToArrayBuffer(peerPublicKeyBase64);
53
+ const importedPeerKey = await this.provider.importPublicKey(peerPublicKeyBuffer);
54
+ this.sharedSecret = await this.provider.deriveSharedSecret(this.keyPair.privateKey, importedPeerKey);
55
+ }
56
+ /**
57
+ * Derives an encryption key from the shared secret using HKDF.
58
+ * @param salt - A non-secret random value.
59
+ * @param info - Context-specific information.
60
+ */
61
+ async deriveEncryptionKey(salt, info) {
62
+ if (!this.sharedSecret) {
63
+ throw new Error("Shared secret not derived yet.");
64
+ }
65
+ this.encryptionKey = await this.provider.deriveEncryptionKey(this.sharedSecret, salt, info);
66
+ }
67
+ /**
68
+ * Encrypt a message using the derived session key
69
+ */
70
+ async encrypt(message) {
71
+ if (!this.encryptionKey) {
72
+ throw new Error("Encryption key not derived");
73
+ }
74
+ const iv = this.provider.randomBytes(CRYPTO_CONFIG.ivLength);
75
+ const plaintext = chunkVXLUSU5B_cjs.stringToArrayBuffer(JSON.stringify(message));
76
+ const ciphertext = await this.provider.encrypt(this.encryptionKey, plaintext, iv);
77
+ const dataToSign = new Uint8Array([
78
+ ...new Uint8Array(iv),
79
+ ...new Uint8Array(ciphertext)
80
+ ]);
81
+ const macBuffer = await this.provider.generateHMAC(this.encryptionKey, dataToSign.buffer);
82
+ return {
83
+ iv: chunkVXLUSU5B_cjs.arrayBufferToBase64(iv),
84
+ ciphertext: chunkVXLUSU5B_cjs.arrayBufferToBase64(ciphertext),
85
+ mac: chunkVXLUSU5B_cjs.arrayBufferToBase64(macBuffer)
86
+ };
87
+ }
88
+ /**
89
+ * Decrypt a message using the derived session key
90
+ */
91
+ async decrypt(encryptedMessage) {
92
+ if (!this.encryptionKey) {
93
+ throw new Error("Encryption key not derived");
94
+ }
95
+ const iv = chunkVXLUSU5B_cjs.base64ToArrayBuffer(encryptedMessage.iv);
96
+ const ciphertext = chunkVXLUSU5B_cjs.base64ToArrayBuffer(encryptedMessage.ciphertext);
97
+ const receivedMac = chunkVXLUSU5B_cjs.base64ToArrayBuffer(encryptedMessage.mac);
98
+ const dataToVerify = new Uint8Array([
99
+ ...new Uint8Array(iv),
100
+ ...new Uint8Array(ciphertext)
101
+ ]);
102
+ const isValidMac = await this.provider.verifyHMAC(this.encryptionKey, dataToVerify.buffer, receivedMac);
103
+ if (!isValidMac) {
104
+ throw new Error("Message authentication failed");
105
+ }
106
+ const plaintextBuffer = await this.provider.decrypt(this.encryptionKey, ciphertext, iv);
107
+ const plaintextString = chunkVXLUSU5B_cjs.arrayBufferToString(plaintextBuffer);
108
+ return JSON.parse(plaintextString);
109
+ }
110
+ /**
111
+ * Get session information
112
+ */
113
+ async getSessionKeys() {
114
+ if (!this.keyPair || !this.sharedSecret) {
115
+ throw new Error("Session not properly initialized");
116
+ }
117
+ return {
118
+ sessionId: this.sessionId,
119
+ publicKey: await this.getPublicKey(),
120
+ sharedSecret: this.sharedSecret
121
+ // We know it exists due to the check above
122
+ };
123
+ }
124
+ /**
125
+ * Generate a random session ID
126
+ */
127
+ generateSessionId() {
128
+ const sessionBytes = this.provider.randomBytes(16);
129
+ return chunkVXLUSU5B_cjs.arrayBufferToBase64(sessionBytes);
130
+ }
131
+ /**
132
+ * Get provider information
133
+ */
134
+ getProviderInfo() {
135
+ return {
136
+ name: this.provider.name,
137
+ isAvailable: this.provider.isAvailable
138
+ };
139
+ }
140
+ /**
141
+ * Check if session is ready for encryption/decryption
142
+ */
143
+ get isReady() {
144
+ return !!(this.keyPair && this.sharedSecret && this.encryptionKey);
145
+ }
146
+ };
147
+ chunkWGEGR3DF_cjs.__name(_SessionSecurity, "SessionSecurity");
148
+ var SessionSecurity = _SessionSecurity;
149
+
150
+ // src/crypto/payload-handler.ts
151
+ function parsePublicKey(publicKey) {
152
+ if (publicKey.byteLength !== 65 || new Uint8Array(publicKey)[0] !== 4) {
153
+ throw new Error("Invalid P-256 public key format");
154
+ }
155
+ const x = publicKey.slice(1, 33);
156
+ const y = publicKey.slice(33, 65);
157
+ return { x, y };
158
+ }
159
+ chunkWGEGR3DF_cjs.__name(parsePublicKey, "parsePublicKey");
160
+ var _CryptoPayloadHandler = class _CryptoPayloadHandler {
161
+ static createPayload(options) {
162
+ if (options.encAlgo === "plaintext") {
163
+ return {
164
+ version: "1.0",
165
+ encryption: {
166
+ algorithm: "plaintext"
167
+ },
168
+ parameters: {
169
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
170
+ sessionId: options.sessionId
171
+ }
172
+ };
173
+ }
174
+ if (options.encAlgo === "AES-GCM") {
175
+ const iv = chunkVXLUSU5B_cjs.randomBytes(12);
176
+ const salt = chunkVXLUSU5B_cjs.randomBytes(32);
177
+ const publicKeyRaw = chunkVXLUSU5B_cjs.base64ToArrayBuffer(options.publicKeyB64);
178
+ const { x, y } = parsePublicKey(publicKeyRaw);
179
+ return {
180
+ version: "1.0",
181
+ keyExchange: {
182
+ algorithm: "ECDH",
183
+ namedCurve: "P-256"
184
+ },
185
+ encryption: {
186
+ algorithm: "AES-GCM",
187
+ keyLength: 256,
188
+ tagLength: 128
189
+ },
190
+ publicKey: {
191
+ kty: "EC",
192
+ crv: "P-256",
193
+ x: chunkVXLUSU5B_cjs.arrayBufferToBase64(x),
194
+ y: chunkVXLUSU5B_cjs.arrayBufferToBase64(y),
195
+ use: "enc",
196
+ key_ops: ["deriveKey"]
197
+ },
198
+ parameters: {
199
+ iv: chunkVXLUSU5B_cjs.arrayBufferToBase64(iv.buffer),
200
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
201
+ sessionId: options.sessionId
202
+ },
203
+ derivation: {
204
+ algorithm: "HKDF",
205
+ hash: "SHA-256",
206
+ info: "message-exchange-v1",
207
+ salt: chunkVXLUSU5B_cjs.arrayBufferToBase64(salt.buffer)
208
+ }
209
+ };
210
+ }
211
+ throw new Error("Invalid encryption algorithm specified.");
212
+ }
213
+ /**
214
+ * Validate crypto payload format
215
+ */
216
+ static validatePayload(payload) {
217
+ try {
218
+ if (payload.version !== "1.0") {
219
+ return false;
220
+ }
221
+ if (!payload.parameters?.sessionId || !payload.parameters?.timestamp) {
222
+ return false;
223
+ }
224
+ if (payload.encryption?.algorithm === "AES-GCM") {
225
+ return !!(payload.keyExchange && payload.publicKey && payload.derivation);
226
+ }
227
+ if (payload.encryption?.algorithm === "plaintext") {
228
+ return true;
229
+ }
230
+ return false;
231
+ } catch {
232
+ return false;
233
+ }
234
+ }
235
+ };
236
+ chunkWGEGR3DF_cjs.__name(_CryptoPayloadHandler, "CryptoPayloadHandler");
237
+ var CryptoPayloadHandler = _CryptoPayloadHandler;
238
+
239
+ // src/crypto/diagnostics.ts
240
+ async function testProvider(providerType, logger) {
241
+ const startTime = performance.now();
242
+ const operations = [];
243
+ let provider;
244
+ try {
245
+ switch (providerType) {
246
+ case "webcrypto":
247
+ provider = new (await import('./crypto/providers/webcrypto-provider.cjs')).WebCryptoProvider();
248
+ break;
249
+ case "noble":
250
+ provider = new (await import('./crypto/providers/noble-provider.cjs')).NobleCryptoProvider(logger);
251
+ break;
252
+ case "node":
253
+ provider = new (await import('./crypto/providers/node-provider.cjs')).NodeCryptoProvider(logger);
254
+ break;
255
+ case "quickcrypto":
256
+ provider = new (await import('./crypto/providers/quickcrypto-provider.cjs')).QuickCryptoProvider(logger);
257
+ break;
258
+ default:
259
+ throw new Error(`Unknown provider type: ${String(providerType)}`);
260
+ }
261
+ if (!provider.isAvailable) {
262
+ return {
263
+ provider: providerType,
264
+ available: false,
265
+ success: false,
266
+ operations: [],
267
+ totalDurationMs: performance.now() - startTime,
268
+ unavailableReason: `Provider ${providerType} not available in this environment`
269
+ };
270
+ }
271
+ } catch (error) {
272
+ return {
273
+ provider: providerType,
274
+ available: false,
275
+ success: false,
276
+ operations: [],
277
+ totalDurationMs: performance.now() - startTime,
278
+ unavailableReason: error instanceof Error ? error.message : String(error)
279
+ };
280
+ }
281
+ try {
282
+ const opStart = performance.now();
283
+ const bytes = provider.randomBytes(32);
284
+ const duration = performance.now() - opStart;
285
+ operations.push({
286
+ operation: "randomBytes",
287
+ success: true,
288
+ durationMs: duration,
289
+ details: {
290
+ bytesLength: bytes.byteLength
291
+ }
292
+ });
293
+ } catch (error) {
294
+ operations.push({
295
+ operation: "randomBytes",
296
+ success: false,
297
+ error: error instanceof Error ? error.message : String(error)
298
+ });
299
+ }
300
+ try {
301
+ const opStart = performance.now();
302
+ const keyPair = await provider.generateKeyPair();
303
+ const duration = performance.now() - opStart;
304
+ operations.push({
305
+ operation: "generateKeyPair",
306
+ success: true,
307
+ durationMs: duration,
308
+ details: {
309
+ publicKeyType: keyPair.publicKey.type,
310
+ privateKeyType: keyPair.privateKey.type
311
+ }
312
+ });
313
+ } catch (error) {
314
+ operations.push({
315
+ operation: "generateKeyPair",
316
+ success: false,
317
+ error: error instanceof Error ? error.message : String(error)
318
+ });
319
+ }
320
+ try {
321
+ const opStart = performance.now();
322
+ const keyPair = await provider.generateKeyPair();
323
+ const publicKeyData = await provider.exportPublicKey(keyPair.publicKey);
324
+ const importedPublicKey = await provider.importPublicKey(publicKeyData);
325
+ const duration = performance.now() - opStart;
326
+ operations.push({
327
+ operation: "exportImportKey",
328
+ success: true,
329
+ durationMs: duration,
330
+ details: {
331
+ exportedKeySize: publicKeyData.byteLength,
332
+ importedKeyType: importedPublicKey.type
333
+ }
334
+ });
335
+ } catch (error) {
336
+ operations.push({
337
+ operation: "exportImportKey",
338
+ success: false,
339
+ error: error instanceof Error ? error.message : String(error)
340
+ });
341
+ }
342
+ try {
343
+ const opStart = performance.now();
344
+ const keyPair1 = await provider.generateKeyPair();
345
+ const keyPair2 = await provider.generateKeyPair();
346
+ await provider.deriveSharedSecret(keyPair1.privateKey, keyPair2.publicKey);
347
+ await provider.deriveSharedSecret(keyPair2.privateKey, keyPair1.publicKey);
348
+ const duration = performance.now() - opStart;
349
+ operations.push({
350
+ operation: "deriveSharedSecret",
351
+ success: true,
352
+ durationMs: duration,
353
+ details: {
354
+ sharedSecretsGenerated: 2
355
+ }
356
+ });
357
+ } catch (error) {
358
+ operations.push({
359
+ operation: "deriveSharedSecret",
360
+ success: false,
361
+ error: error instanceof Error ? error.message : String(error)
362
+ });
363
+ }
364
+ try {
365
+ const opStart = performance.now();
366
+ const keyPair = await provider.generateKeyPair();
367
+ const sharedSecret = await provider.deriveSharedSecret(keyPair.privateKey, keyPair.publicKey);
368
+ const salt = provider.randomBytes(32);
369
+ const info = provider.randomBytes(32);
370
+ const encryptionKey = await provider.deriveEncryptionKey(sharedSecret, salt, info);
371
+ const plaintext = new TextEncoder().encode("Hello, World!");
372
+ const iv = provider.randomBytes(12);
373
+ const ciphertext = await provider.encrypt(encryptionKey, plaintext, iv);
374
+ const decrypted = await provider.decrypt(encryptionKey, ciphertext, iv);
375
+ const decryptedText = new TextDecoder().decode(decrypted);
376
+ const duration = performance.now() - opStart;
377
+ operations.push({
378
+ operation: "aesGcmEncryptDecrypt",
379
+ success: decryptedText === "Hello, World!",
380
+ durationMs: duration,
381
+ details: {
382
+ plaintextSize: plaintext.byteLength,
383
+ ciphertextSize: ciphertext.byteLength,
384
+ decryptedCorrectly: decryptedText === "Hello, World!"
385
+ }
386
+ });
387
+ } catch (error) {
388
+ operations.push({
389
+ operation: "aesGcmEncryptDecrypt",
390
+ success: false,
391
+ error: error instanceof Error ? error.message : String(error)
392
+ });
393
+ }
394
+ const totalDuration = performance.now() - startTime;
395
+ const allSuccess = operations.every((op) => op.success);
396
+ return {
397
+ provider: providerType,
398
+ available: true,
399
+ success: allSuccess,
400
+ operations,
401
+ totalDurationMs: totalDuration
402
+ };
403
+ }
404
+ chunkWGEGR3DF_cjs.__name(testProvider, "testProvider");
405
+ async function benchmarkProvider(providerType, iterations = 10, logger) {
406
+ let provider;
407
+ try {
408
+ switch (providerType) {
409
+ case "webcrypto":
410
+ provider = new (await import('./crypto/providers/webcrypto-provider.cjs')).WebCryptoProvider();
411
+ break;
412
+ case "noble":
413
+ provider = new (await import('./crypto/providers/noble-provider.cjs')).NobleCryptoProvider(logger);
414
+ break;
415
+ case "node":
416
+ provider = new (await import('./crypto/providers/node-provider.cjs')).NodeCryptoProvider(logger);
417
+ break;
418
+ case "quickcrypto":
419
+ provider = new (await import('./crypto/providers/quickcrypto-provider.cjs')).QuickCryptoProvider(logger);
420
+ break;
421
+ default:
422
+ throw new Error(`Unknown provider type: ${String(providerType)}`);
423
+ }
424
+ } catch (error) {
425
+ throw new Error(
426
+ `Provider ${providerType} failed to initialize: ${error instanceof Error ? error.message : String(error)}`
427
+ );
428
+ }
429
+ if (!provider.isAvailable) {
430
+ throw new Error(`Provider ${providerType} not available for benchmarking`);
431
+ }
432
+ const ecdhTimes = [];
433
+ for (let i = 0; i < iterations; i++) {
434
+ const start = performance.now();
435
+ await provider.generateKeyPair();
436
+ ecdhTimes.push(performance.now() - start);
437
+ }
438
+ const randomBytesTimes = [];
439
+ for (let i = 0; i < iterations; i++) {
440
+ const start = performance.now();
441
+ provider.randomBytes(32);
442
+ randomBytesTimes.push(performance.now() - start);
443
+ }
444
+ const aesGcmTimes = [];
445
+ const keyPair = await provider.generateKeyPair();
446
+ const sharedSecret = await provider.deriveSharedSecret(keyPair.privateKey, keyPair.publicKey);
447
+ const salt = provider.randomBytes(32);
448
+ const info = provider.randomBytes(32);
449
+ const encryptionKey = await provider.deriveEncryptionKey(sharedSecret, salt, info);
450
+ const plaintext = provider.randomBytes(1024);
451
+ const iv = provider.randomBytes(12);
452
+ for (let i = 0; i < iterations; i++) {
453
+ const start = performance.now();
454
+ await provider.encrypt(encryptionKey, plaintext, iv);
455
+ aesGcmTimes.push(performance.now() - start);
456
+ }
457
+ return {
458
+ provider: providerType,
459
+ ecdh: {
460
+ avgMs: ecdhTimes.reduce((a, b) => a + b, 0) / iterations,
461
+ minMs: Math.min(...ecdhTimes),
462
+ maxMs: Math.max(...ecdhTimes),
463
+ iterations
464
+ },
465
+ randomBytes: {
466
+ avgMs: randomBytesTimes.reduce((a, b) => a + b, 0) / iterations,
467
+ minMs: Math.min(...randomBytesTimes),
468
+ maxMs: Math.max(...randomBytesTimes),
469
+ iterations
470
+ },
471
+ aesGcm: {
472
+ avgMs: aesGcmTimes.reduce((a, b) => a + b, 0) / iterations,
473
+ minMs: Math.min(...aesGcmTimes),
474
+ maxMs: Math.max(...aesGcmTimes),
475
+ iterations
476
+ }
477
+ };
478
+ }
479
+ chunkWGEGR3DF_cjs.__name(benchmarkProvider, "benchmarkProvider");
480
+ async function diagnoseEnvironment(logger) {
481
+ const platform = chunkVXLUSU5B_cjs.detectPlatform();
482
+ const registeredProviders = chunkA6FLEJ7R_cjs.getRegisteredCryptoProviders();
483
+ const warnings = [];
484
+ const recommendations = [];
485
+ const providerTests = await Promise.all(
486
+ registeredProviders.map((type) => testProvider(type, logger))
487
+ );
488
+ const recommendedProvider = providerTests.find((test) => test.success && test.available)?.provider;
489
+ const capabilities = {
490
+ webcrypto: { available: false, tested: false, success: false },
491
+ node: { available: false, tested: false, success: false },
492
+ noble: { available: false, tested: false, success: false },
493
+ quickcrypto: { available: false, tested: false, success: false }
494
+ };
495
+ providerTests.forEach((test) => {
496
+ capabilities[test.provider] = {
497
+ available: test.available,
498
+ tested: true,
499
+ success: test.success
500
+ };
501
+ });
502
+ const detectionRecommendations = [];
503
+ if (!capabilities.noble.success) {
504
+ detectionRecommendations.push("Noble provider should always work as a fallback");
505
+ }
506
+ if (platform.isNode && !capabilities.node.tested) {
507
+ detectionRecommendations.push("Consider testing 'node' provider for optimal Node.js performance");
508
+ }
509
+ if (platform.isBrowser && !capabilities.webcrypto.tested) {
510
+ detectionRecommendations.push("Consider testing 'webcrypto' provider for browser environments");
511
+ }
512
+ const detection = {
513
+ webCrypto: capabilities.webcrypto.available && capabilities.webcrypto.success,
514
+ node: capabilities.node.available && capabilities.node.success,
515
+ noble: capabilities.noble.available && capabilities.noble.success,
516
+ quickCrypto: capabilities.quickcrypto.available && capabilities.quickcrypto.success,
517
+ recommended: recommendedProvider,
518
+ capabilities,
519
+ recommendations: detectionRecommendations
520
+ };
521
+ providerTests.forEach((test) => {
522
+ if (!test.success && test.available) {
523
+ warnings.push(`${test.provider} provider registered but failed operation tests`);
524
+ }
525
+ });
526
+ if (registeredProviders.length === 0) {
527
+ warnings.push("No crypto providers registered. Import at least one provider.");
528
+ }
529
+ if (!recommendedProvider) {
530
+ warnings.push("No working crypto provider found. All registered providers failed tests.");
531
+ }
532
+ if (platform.isNode) {
533
+ if (!registeredProviders.includes("node")) {
534
+ recommendations.push("Consider importing 'node' provider for optimal Node.js performance");
535
+ }
536
+ if (!recommendedProvider) {
537
+ recommendations.push("Import '@bananalink-sdk/protocol/crypto/provider/node' for Node.js");
538
+ }
539
+ } else if (platform.isBrowser) {
540
+ if (!registeredProviders.includes("webcrypto")) {
541
+ recommendations.push("Consider importing 'webcrypto' provider for browsers");
542
+ }
543
+ if (!recommendedProvider) {
544
+ recommendations.push("Import '@bananalink-sdk/protocol/crypto/provider/webcrypto' for browsers");
545
+ }
546
+ } else if (platform.isReactNative) {
547
+ if (!registeredProviders.includes("quickcrypto")) {
548
+ recommendations.push("Consider importing 'quickcrypto' provider for React Native");
549
+ }
550
+ if (!recommendedProvider) {
551
+ recommendations.push("Import '@bananalink-sdk/protocol/crypto/provider/quickcrypto' for React Native");
552
+ }
553
+ }
554
+ if (!recommendedProvider || registeredProviders.length === 0) {
555
+ recommendations.push("Import '@bananalink-sdk/protocol/crypto/provider/noble' as a universal fallback");
556
+ }
557
+ const diagnostics = {
558
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
559
+ platform,
560
+ detection,
561
+ registeredProviders,
562
+ providerTests,
563
+ recommendedProvider,
564
+ warnings,
565
+ recommendations,
566
+ toMarkdown() {
567
+ let md = "# Crypto Environment Diagnostics\n\n";
568
+ md += `**Generated:** ${this.timestamp}
569
+
570
+ `;
571
+ md += "## Platform\n\n";
572
+ const platformType = this.platform.isNode ? "Node.js" : this.platform.isBrowser ? "Browser" : this.platform.isReactNative ? "React Native" : "Unknown";
573
+ md += `- **Type:** ${platformType}
574
+ `;
575
+ if (this.platform.platform) {
576
+ md += `- **OS:** ${this.platform.platform}
577
+ `;
578
+ }
579
+ if (this.platform.userAgent) {
580
+ const ua = this.platform.userAgent.length > 80 ? `${this.platform.userAgent.substring(0, 80)}...` : this.platform.userAgent;
581
+ md += `- **User Agent:** ${ua}
582
+ `;
583
+ }
584
+ md += "\n";
585
+ md += "## Provider Detection\n\n";
586
+ md += `- **WebCrypto:** ${this.detection.webCrypto ? "\u2705" : "\u274C"}
587
+ `;
588
+ md += `- **Node.js Crypto:** ${this.detection.node ? "\u2705" : "\u274C"}
589
+ `;
590
+ md += `- **Noble (Pure JS):** ${this.detection.noble ? "\u2705" : "\u274C"}
591
+ `;
592
+ md += `- **QuickCrypto (RN):** ${this.detection.quickCrypto ? "\u2705" : "\u274C"}
593
+ `;
594
+ if (this.detection.recommended) {
595
+ md += `- **Recommended:** ${this.detection.recommended}
596
+ `;
597
+ }
598
+ md += "\n";
599
+ md += "## Capabilities\n\n";
600
+ Object.entries(this.detection.capabilities).forEach(([provider, capability]) => {
601
+ const status = capability.tested ? capability.success ? "\u2705 Available" : "\u274C Failed" : "\u26AA Not Tested";
602
+ md += `- **${provider}:** ${status}
603
+ `;
604
+ });
605
+ md += "\n";
606
+ md += "## Registered Providers\n\n";
607
+ if (this.registeredProviders.length === 0) {
608
+ md += "No providers registered.\n\n";
609
+ } else {
610
+ this.registeredProviders.forEach((provider) => {
611
+ md += `- ${provider}${provider === this.recommendedProvider ? " (recommended)" : ""}
612
+ `;
613
+ });
614
+ md += "\n";
615
+ }
616
+ md += "## Provider Tests\n\n";
617
+ if (this.providerTests.length === 0) {
618
+ md += "No tests run (no providers registered).\n\n";
619
+ } else {
620
+ this.providerTests.forEach((test) => {
621
+ md += `### ${test.provider}
622
+
623
+ `;
624
+ md += `- **Available:** ${test.available ? "\u2705" : "\u274C"}
625
+ `;
626
+ if (!test.available) {
627
+ md += `- **Reason:** ${test.unavailableReason}
628
+ `;
629
+ } else {
630
+ md += `- **Overall Success:** ${test.success ? "\u2705" : "\u274C"}
631
+ `;
632
+ md += `- **Total Duration:** ${test.totalDurationMs.toFixed(2)}ms
633
+
634
+ `;
635
+ md += "**Operations:**\n\n";
636
+ test.operations.forEach((op) => {
637
+ md += `- **${op.operation}:** ${op.success ? "\u2705" : "\u274C"}`;
638
+ if (op.durationMs) md += ` (${op.durationMs.toFixed(2)}ms)`;
639
+ if (op.error) md += ` - ${op.error}`;
640
+ md += "\n";
641
+ });
642
+ }
643
+ md += "\n";
644
+ });
645
+ }
646
+ md += "## Recommendations\n\n";
647
+ if (this.recommendedProvider) {
648
+ md += `- Recommended: Use '${this.recommendedProvider}' provider (passed all tests)
649
+ `;
650
+ }
651
+ if (this.recommendations.length > 0) {
652
+ this.recommendations.forEach((rec) => {
653
+ md += `- ${rec}
654
+ `;
655
+ });
656
+ }
657
+ md += "\n";
658
+ if (this.warnings.length > 0) {
659
+ md += "## Warnings\n\n";
660
+ this.warnings.forEach((warning) => {
661
+ md += `\u26A0\uFE0F ${warning}
662
+
663
+ `;
664
+ });
665
+ }
666
+ return md;
667
+ },
668
+ toJSON() {
669
+ return JSON.stringify(
670
+ {
671
+ timestamp: this.timestamp,
672
+ platform: this.platform,
673
+ detection: this.detection,
674
+ registeredProviders: this.registeredProviders,
675
+ providerTests: this.providerTests,
676
+ recommendedProvider: this.recommendedProvider,
677
+ warnings: this.warnings,
678
+ recommendations: this.recommendations
679
+ },
680
+ null,
681
+ 2
682
+ );
683
+ }
684
+ };
685
+ return diagnostics;
686
+ }
687
+ chunkWGEGR3DF_cjs.__name(diagnoseEnvironment, "diagnoseEnvironment");
688
+ async function compareProviders(providers, iterations = 10, logger) {
689
+ const results = [];
690
+ for (const provider of providers) {
691
+ try {
692
+ const benchmark = await benchmarkProvider(provider, iterations, logger);
693
+ results.push(benchmark);
694
+ } catch (error) {
695
+ logger?.warn(`Failed to benchmark ${provider}:`, {
696
+ error: {
697
+ message: error instanceof Error ? error.message : String(error),
698
+ stack: error instanceof Error ? error.stack : void 0
699
+ }
700
+ });
701
+ }
702
+ }
703
+ return results;
704
+ }
705
+ chunkWGEGR3DF_cjs.__name(compareProviders, "compareProviders");
706
+
707
+ Object.defineProperty(exports, "ComplianceCryptoProvider", {
708
+ enumerable: true,
709
+ get: function () { return chunkVXLUSU5B_cjs.ComplianceCryptoProvider; }
710
+ });
711
+ Object.defineProperty(exports, "CryptoCapabilityMissingError", {
712
+ enumerable: true,
713
+ get: function () { return chunkVXLUSU5B_cjs.CryptoCapabilityMissingError; }
714
+ });
715
+ Object.defineProperty(exports, "CryptoContext", {
716
+ enumerable: true,
717
+ get: function () { return chunkVXLUSU5B_cjs.CryptoContext; }
718
+ });
719
+ Object.defineProperty(exports, "CryptoError", {
720
+ enumerable: true,
721
+ get: function () { return chunkVXLUSU5B_cjs.CryptoError; }
722
+ });
723
+ Object.defineProperty(exports, "CryptoProviderUnavailableError", {
724
+ enumerable: true,
725
+ get: function () { return chunkVXLUSU5B_cjs.CryptoProviderUnavailableError; }
726
+ });
727
+ Object.defineProperty(exports, "DefaultComplianceAuditor", {
728
+ enumerable: true,
729
+ get: function () { return chunkVXLUSU5B_cjs.DefaultComplianceAuditor; }
730
+ });
731
+ Object.defineProperty(exports, "arrayBufferToBase64", {
732
+ enumerable: true,
733
+ get: function () { return chunkVXLUSU5B_cjs.arrayBufferToBase64; }
734
+ });
735
+ Object.defineProperty(exports, "arrayBufferToString", {
736
+ enumerable: true,
737
+ get: function () { return chunkVXLUSU5B_cjs.arrayBufferToString; }
738
+ });
739
+ Object.defineProperty(exports, "base64ToArrayBuffer", {
740
+ enumerable: true,
741
+ get: function () { return chunkVXLUSU5B_cjs.base64ToArrayBuffer; }
742
+ });
743
+ Object.defineProperty(exports, "createCryptoProvider", {
744
+ enumerable: true,
745
+ get: function () { return chunkVXLUSU5B_cjs.createCryptoProvider; }
746
+ });
747
+ Object.defineProperty(exports, "generateNonce", {
748
+ enumerable: true,
749
+ get: function () { return chunkVXLUSU5B_cjs.generateNonce; }
750
+ });
751
+ Object.defineProperty(exports, "generateUUID", {
752
+ enumerable: true,
753
+ get: function () { return chunkVXLUSU5B_cjs.generateUUID; }
754
+ });
755
+ Object.defineProperty(exports, "randomBytes", {
756
+ enumerable: true,
757
+ get: function () { return chunkVXLUSU5B_cjs.randomBytes; }
758
+ });
759
+ Object.defineProperty(exports, "stringToArrayBuffer", {
760
+ enumerable: true,
761
+ get: function () { return chunkVXLUSU5B_cjs.stringToArrayBuffer; }
762
+ });
763
+ Object.defineProperty(exports, "clearCryptoProviderRegistry", {
764
+ enumerable: true,
765
+ get: function () { return chunkA6FLEJ7R_cjs.clearCryptoProviderRegistry; }
766
+ });
767
+ Object.defineProperty(exports, "getCryptoProviderFactory", {
768
+ enumerable: true,
769
+ get: function () { return chunkA6FLEJ7R_cjs.getCryptoProviderFactory; }
770
+ });
771
+ Object.defineProperty(exports, "getRegisteredCryptoProviders", {
772
+ enumerable: true,
773
+ get: function () { return chunkA6FLEJ7R_cjs.getRegisteredCryptoProviders; }
774
+ });
775
+ Object.defineProperty(exports, "isCryptoProviderRegistered", {
776
+ enumerable: true,
777
+ get: function () { return chunkA6FLEJ7R_cjs.isCryptoProviderRegistered; }
778
+ });
779
+ Object.defineProperty(exports, "registerCryptoProvider", {
780
+ enumerable: true,
781
+ get: function () { return chunkA6FLEJ7R_cjs.registerCryptoProvider; }
782
+ });
783
+ exports.CryptoPayloadHandler = CryptoPayloadHandler;
784
+ exports.SessionSecurity = SessionSecurity;
785
+ exports.benchmarkProvider = benchmarkProvider;
786
+ exports.compareProviders = compareProviders;
787
+ exports.diagnoseEnvironment = diagnoseEnvironment;
788
+ exports.testProvider = testProvider;
789
+ //# sourceMappingURL=crypto-export.cjs.map
790
+ //# sourceMappingURL=crypto-export.cjs.map