@bananalink-sdk/protocol 1.2.7 → 1.3.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 (52) hide show
  1. package/dist/{chunk-32OWUOZ3.js → chunk-KJ7QIHAY.js} +11 -7
  2. package/dist/chunk-KJ7QIHAY.js.map +1 -0
  3. package/dist/{chunk-VXLUSU5B.cjs → chunk-MUYKP6UQ.cjs} +63 -8
  4. package/dist/chunk-MUYKP6UQ.cjs.map +1 -0
  5. package/dist/{chunk-MCZG7QEM.cjs → chunk-NGPP7HUR.cjs} +11 -7
  6. package/dist/chunk-NGPP7HUR.cjs.map +1 -0
  7. package/dist/{chunk-LELPCIE7.js → chunk-OBJR2TL4.js} +54 -4
  8. package/dist/chunk-OBJR2TL4.js.map +1 -0
  9. package/dist/crypto/providers/noble-provider.cjs +2 -3
  10. package/dist/crypto/providers/noble-provider.d.cts +0 -7
  11. package/dist/crypto/providers/noble-provider.d.ts +0 -7
  12. package/dist/crypto/providers/noble-provider.js +1 -2
  13. package/dist/crypto/providers/node-provider.cjs +7 -29
  14. package/dist/crypto/providers/node-provider.cjs.map +1 -1
  15. package/dist/crypto/providers/node-provider.d.cts +0 -7
  16. package/dist/crypto/providers/node-provider.d.ts +0 -7
  17. package/dist/crypto/providers/node-provider.js +7 -29
  18. package/dist/crypto/providers/node-provider.js.map +1 -1
  19. package/dist/crypto/providers/quickcrypto-provider.cjs +8 -46
  20. package/dist/crypto/providers/quickcrypto-provider.cjs.map +1 -1
  21. package/dist/crypto/providers/quickcrypto-provider.d.cts +0 -9
  22. package/dist/crypto/providers/quickcrypto-provider.d.ts +0 -9
  23. package/dist/crypto/providers/quickcrypto-provider.js +7 -45
  24. package/dist/crypto/providers/quickcrypto-provider.js.map +1 -1
  25. package/dist/crypto/providers/webcrypto-provider.cjs +0 -2
  26. package/dist/crypto/providers/webcrypto-provider.cjs.map +1 -1
  27. package/dist/crypto/providers/webcrypto-provider.d.cts +0 -7
  28. package/dist/crypto/providers/webcrypto-provider.d.ts +0 -7
  29. package/dist/crypto/providers/webcrypto-provider.js +0 -2
  30. package/dist/crypto/providers/webcrypto-provider.js.map +1 -1
  31. package/dist/crypto-export.cjs +50 -51
  32. package/dist/crypto-export.cjs.map +1 -1
  33. package/dist/crypto-export.js +2 -4
  34. package/dist/crypto-export.js.map +1 -1
  35. package/dist/index.cjs +3 -4
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.js +2 -3
  38. package/dist/index.js.map +1 -1
  39. package/package.json +17 -18
  40. package/src/crypto/providers/noble-provider.ts +44 -49
  41. package/src/crypto/providers/node-provider.ts +18 -59
  42. package/src/crypto/providers/quickcrypto-provider.ts +25 -84
  43. package/src/crypto/providers/registry.ts +14 -9
  44. package/src/crypto/providers/webcrypto-provider.ts +28 -43
  45. package/dist/chunk-32OWUOZ3.js.map +0 -1
  46. package/dist/chunk-A6FLEJ7R.cjs +0 -62
  47. package/dist/chunk-A6FLEJ7R.cjs.map +0 -1
  48. package/dist/chunk-LELPCIE7.js.map +0 -1
  49. package/dist/chunk-MCZG7QEM.cjs.map +0 -1
  50. package/dist/chunk-TCVKC227.js +0 -56
  51. package/dist/chunk-TCVKC227.js.map +0 -1
  52. package/dist/chunk-VXLUSU5B.cjs.map +0 -1
@@ -1,6 +1,5 @@
1
1
  import type { Logger } from '@bananalink-sdk/logger';
2
2
  import type { CryptoProvider, CryptoKeyLike, ProviderKeyPair } from '../../types/crypto-provider';
3
- import { registerCryptoProvider } from './registry';
4
3
 
5
4
  /**
6
5
  * Type definition for Node.js crypto module (loaded dynamically to prevent Metro bundling)
@@ -14,7 +13,7 @@ type NodeCrypto = typeof import('crypto');
14
13
  class NodeCryptoKeyWrapper implements CryptoKeyLike {
15
14
  constructor(
16
15
  private readonly keyObject: unknown, // crypto.KeyObject | Buffer at runtime
17
- private readonly keyType: 'public' | 'private' | 'secret'
16
+ private readonly keyType: 'public' | 'private' | 'secret',
18
17
  ) {}
19
18
 
20
19
  get type(): 'public' | 'private' | 'secret' {
@@ -101,10 +100,7 @@ export class NodeCryptoProvider implements CryptoProvider {
101
100
  // Dynamic import prevents static analysis by bundlers
102
101
  this.cryptoModule = await import('crypto');
103
102
  } catch {
104
- throw new Error(
105
- 'Failed to load Node.js crypto module. ' +
106
- 'This provider requires a Node.js environment.'
107
- );
103
+ throw new Error('Failed to load Node.js crypto module. ' + 'This provider requires a Node.js environment.');
108
104
  }
109
105
  }
110
106
  return this.cryptoModule;
@@ -138,7 +134,7 @@ export class NodeCryptoProvider implements CryptoProvider {
138
134
  publicKey: new NodeCryptoKeyWrapper(publicKey, 'public'),
139
135
  privateKey: new NodeCryptoKeyWrapper(privateKey, 'private'),
140
136
  });
141
- }
137
+ },
142
138
  );
143
139
  });
144
140
  }
@@ -152,9 +148,10 @@ export class NodeCryptoProvider implements CryptoProvider {
152
148
  const keyObject = unwrapKeyObject(publicKey);
153
149
 
154
150
  // If it's a Buffer (DER format from generateKeyPair), convert to KeyObject first
155
- const keyObj = keyObject instanceof Buffer
156
- ? cryptoModule.createPublicKey({ key: keyObject, format: 'der', type: 'spki' })
157
- : keyObject;
151
+ const keyObj =
152
+ keyObject instanceof Buffer
153
+ ? cryptoModule.createPublicKey({ key: keyObject, format: 'der', type: 'spki' })
154
+ : keyObject;
158
155
 
159
156
  // Export as JWK to get X/Y coordinates
160
157
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
@@ -168,10 +165,7 @@ export class NodeCryptoProvider implements CryptoProvider {
168
165
  const uncompressed = Buffer.concat([Buffer.from([0x04]), x, y]);
169
166
 
170
167
  return await Promise.resolve(
171
- uncompressed.buffer.slice(
172
- uncompressed.byteOffset,
173
- uncompressed.byteOffset + uncompressed.byteLength
174
- )
168
+ uncompressed.buffer.slice(uncompressed.byteOffset, uncompressed.byteOffset + uncompressed.byteLength),
175
169
  );
176
170
  }
177
171
 
@@ -195,9 +189,7 @@ export class NodeCryptoProvider implements CryptoProvider {
195
189
  const jwk = keyObj.export({ format: 'jwk' });
196
190
  const dValue = Buffer.from(jwk.d as string, 'base64url');
197
191
 
198
- return await Promise.resolve(
199
- dValue.buffer.slice(dValue.byteOffset, dValue.byteOffset + dValue.byteLength)
200
- );
192
+ return await Promise.resolve(dValue.buffer.slice(dValue.byteOffset, dValue.byteOffset + dValue.byteLength));
201
193
  }
202
194
 
203
195
  /**
@@ -279,11 +271,7 @@ export class NodeCryptoProvider implements CryptoProvider {
279
271
  /**
280
272
  * Derive AES-GCM encryption key using HKDF-SHA256
281
273
  */
282
- async deriveEncryptionKey(
283
- sharedSecret: CryptoKeyLike,
284
- salt: ArrayBuffer,
285
- info: ArrayBuffer
286
- ): Promise<CryptoKeyLike> {
274
+ async deriveEncryptionKey(sharedSecret: CryptoKeyLike, salt: ArrayBuffer, info: ArrayBuffer): Promise<CryptoKeyLike> {
287
275
  this.logger?.debug('Deriving AES-GCM encryption key');
288
276
  const cryptoModule = await this.getCrypto();
289
277
 
@@ -298,7 +286,7 @@ export class NodeCryptoProvider implements CryptoProvider {
298
286
  Buffer.isBuffer(sharedSecretRaw) ? sharedSecretRaw : Buffer.from(sharedSecretRaw),
299
287
  Buffer.from(salt),
300
288
  Buffer.from(info),
301
- 32 // 256 bits
289
+ 32, // 256 bits
302
290
  ) as Buffer;
303
291
 
304
292
  // Create secret key object
@@ -318,20 +306,13 @@ export class NodeCryptoProvider implements CryptoProvider {
318
306
  'aes-256-gcm',
319
307
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
320
308
  (keyObject as any).export(),
321
- Buffer.from(iv)
309
+ Buffer.from(iv),
322
310
  );
323
311
 
324
- const encrypted = Buffer.concat([
325
- cipher.update(Buffer.from(data)),
326
- cipher.final(),
327
- cipher.getAuthTag(),
328
- ]);
312
+ const encrypted = Buffer.concat([cipher.update(Buffer.from(data)), cipher.final(), cipher.getAuthTag()]);
329
313
 
330
314
  return await Promise.resolve(
331
- encrypted.buffer.slice(
332
- encrypted.byteOffset,
333
- encrypted.byteOffset + encrypted.byteLength
334
- )
315
+ encrypted.buffer.slice(encrypted.byteOffset, encrypted.byteOffset + encrypted.byteLength),
335
316
  );
336
317
  }
337
318
 
@@ -352,17 +333,14 @@ export class NodeCryptoProvider implements CryptoProvider {
352
333
  'aes-256-gcm',
353
334
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
354
335
  (keyObject as any).export(),
355
- Buffer.from(iv)
336
+ Buffer.from(iv),
356
337
  );
357
338
  decipher.setAuthTag(authTag);
358
339
 
359
340
  const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
360
341
 
361
342
  return await Promise.resolve(
362
- decrypted.buffer.slice(
363
- decrypted.byteOffset,
364
- decrypted.byteOffset + decrypted.byteLength
365
- )
343
+ decrypted.buffer.slice(decrypted.byteOffset, decrypted.byteOffset + decrypted.byteLength),
366
344
  );
367
345
  }
368
346
 
@@ -397,10 +375,7 @@ export class NodeCryptoProvider implements CryptoProvider {
397
375
  }
398
376
 
399
377
  // Constant-time comparison
400
- return cryptoModule.timingSafeEqual(
401
- Buffer.from(expected),
402
- Buffer.from(actual)
403
- );
378
+ return cryptoModule.timingSafeEqual(Buffer.from(expected), Buffer.from(actual));
404
379
  }
405
380
 
406
381
  /**
@@ -410,24 +385,8 @@ export class NodeCryptoProvider implements CryptoProvider {
410
385
  randomBytes(length: number): ArrayBuffer {
411
386
  // Use cached module if available, otherwise use synchronous require
412
387
  // eslint-disable-next-line @typescript-eslint/no-require-imports
413
- const cryptoModule = this.cryptoModule ?? require('crypto') as NodeCrypto;
388
+ const cryptoModule = this.cryptoModule ?? (require('crypto') as NodeCrypto);
414
389
  const buffer = cryptoModule.randomBytes(length);
415
390
  return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
416
391
  }
417
392
  }
418
-
419
- /**
420
- * Self-register Node provider on import
421
- * This allows the provider to be available when explicitly imported
422
- */
423
- registerCryptoProvider('node', (logger) => new NodeCryptoProvider(logger));
424
-
425
- // TypeScript module augmentation to track this provider is available
426
- declare global {
427
- // eslint-disable-next-line @typescript-eslint/no-namespace
428
- namespace BananaLink {
429
- interface RegisteredCryptoProviders {
430
- node: true;
431
- }
432
- }
433
- }
@@ -1,7 +1,6 @@
1
1
  import type { Logger } from '@bananalink-sdk/logger';
2
2
  import type { CryptoProvider, CryptoKeyLike, ProviderKeyPair } from '../../types/crypto-provider';
3
3
  import { NobleCryptoProvider } from './noble-provider';
4
- import { registerCryptoProvider } from './registry';
5
4
 
6
5
  // Global require function type for React Native environments
7
6
  type RequireFunction = (id: string) => unknown;
@@ -51,7 +50,7 @@ class QuickCryptoKey implements CryptoKeyLike {
51
50
  public readonly type: 'public' | 'private' | 'secret',
52
51
  public readonly algorithm: string,
53
52
  public readonly extractable: boolean = true,
54
- public readonly usages: readonly string[] = []
53
+ public readonly usages: readonly string[] = [],
55
54
  ) {}
56
55
  }
57
56
 
@@ -110,8 +109,8 @@ export class QuickCryptoProvider implements CryptoProvider {
110
109
  this.logger?.error('Failed to initialize QuickCrypto', {
111
110
  error: {
112
111
  message: error instanceof Error ? error.message : String(error),
113
- stack: error instanceof Error ? error.stack : undefined
114
- }
112
+ stack: error instanceof Error ? error.stack : undefined,
113
+ },
115
114
  });
116
115
  // Mark as unavailable if we can't actually use it
117
116
  (this as { isAvailable: boolean }).isAvailable = false;
@@ -137,20 +136,8 @@ export class QuickCryptoProvider implements CryptoProvider {
137
136
  }
138
137
 
139
138
  return {
140
- privateKey: new QuickCryptoKey(
141
- nobleKeyPair.privateKey.data,
142
- 'private',
143
- 'ECDH-P256',
144
- true,
145
- ['deriveKey']
146
- ),
147
- publicKey: new QuickCryptoKey(
148
- nobleKeyPair.publicKey.data,
149
- 'public',
150
- 'ECDH-P256',
151
- true,
152
- []
153
- )
139
+ privateKey: new QuickCryptoKey(nobleKeyPair.privateKey.data, 'private', 'ECDH-P256', true, ['deriveKey']),
140
+ publicKey: new QuickCryptoKey(nobleKeyPair.publicKey.data, 'public', 'ECDH-P256', true, []),
154
141
  };
155
142
  }
156
143
 
@@ -179,13 +166,7 @@ export class QuickCryptoProvider implements CryptoProvider {
179
166
  }
180
167
 
181
168
  // Wrap in QuickCryptoKey for consistency
182
- return new QuickCryptoKey(
183
- nobleKey.data,
184
- 'public',
185
- 'ECDH-P256',
186
- true,
187
- []
188
- );
169
+ return new QuickCryptoKey(nobleKey.data, 'public', 'ECDH-P256', true, []);
189
170
  }
190
171
 
191
172
  /**
@@ -199,13 +180,7 @@ export class QuickCryptoProvider implements CryptoProvider {
199
180
  }
200
181
 
201
182
  // Wrap in QuickCryptoKey for consistency
202
- return new QuickCryptoKey(
203
- nobleKey.data,
204
- 'private',
205
- 'ECDH-P256',
206
- true,
207
- ['deriveKey']
208
- );
183
+ return new QuickCryptoKey(nobleKey.data, 'private', 'ECDH-P256', true, ['deriveKey']);
209
184
  }
210
185
 
211
186
  /**
@@ -221,13 +196,7 @@ export class QuickCryptoProvider implements CryptoProvider {
221
196
  }
222
197
 
223
198
  // Wrap in QuickCryptoKey for consistency
224
- return new QuickCryptoKey(
225
- sharedSecret.data,
226
- 'secret',
227
- 'AES-GCM',
228
- true,
229
- ['encrypt', 'decrypt']
230
- );
199
+ return new QuickCryptoKey(sharedSecret.data, 'secret', 'AES-GCM', true, ['encrypt', 'decrypt']);
231
200
  }
232
201
 
233
202
  /**
@@ -241,13 +210,7 @@ export class QuickCryptoProvider implements CryptoProvider {
241
210
  }
242
211
 
243
212
  // Wrap in QuickCryptoKey for consistency
244
- return new QuickCryptoKey(
245
- encryptionKey.data,
246
- 'secret',
247
- 'AES-GCM',
248
- true,
249
- ['encrypt', 'decrypt']
250
- );
213
+ return new QuickCryptoKey(encryptionKey.data, 'secret', 'AES-GCM', true, ['encrypt', 'decrypt']);
251
214
  }
252
215
 
253
216
  /**
@@ -265,8 +228,8 @@ export class QuickCryptoProvider implements CryptoProvider {
265
228
  } catch (error) {
266
229
  this.logger?.error('QuickCrypto randomBytes failed, falling back to Noble', {
267
230
  error: {
268
- message: error instanceof Error ? error.message : String(error)
269
- }
231
+ message: error instanceof Error ? error.message : String(error),
232
+ },
270
233
  });
271
234
  return this.nobleProvider.randomBytes(length);
272
235
  }
@@ -283,7 +246,7 @@ export class QuickCryptoProvider implements CryptoProvider {
283
246
 
284
247
  this.logger?.debug('Encrypting data with AES-GCM using QuickCrypto', {
285
248
  dataSize: data.byteLength,
286
- ivSize: iv.byteLength
249
+ ivSize: iv.byteLength,
287
250
  });
288
251
 
289
252
  const secretKey = key as QuickCryptoKey;
@@ -291,7 +254,7 @@ export class QuickCryptoProvider implements CryptoProvider {
291
254
  if (secretKey.type !== 'secret') {
292
255
  const error = new Error('Expected secret key');
293
256
  this.logger?.error('Encryption failed - invalid key type', {
294
- actualType: secretKey.type
257
+ actualType: secretKey.type,
295
258
  });
296
259
  throw error;
297
260
  }
@@ -313,7 +276,7 @@ export class QuickCryptoProvider implements CryptoProvider {
313
276
  result.set(authTag, encrypted.length + final.length);
314
277
 
315
278
  this.logger?.debug('Encryption completed using QuickCrypto', {
316
- ciphertextSize: result.byteLength
279
+ ciphertextSize: result.byteLength,
317
280
  });
318
281
 
319
282
  return result.buffer.slice(result.byteOffset, result.byteOffset + result.byteLength);
@@ -321,8 +284,8 @@ export class QuickCryptoProvider implements CryptoProvider {
321
284
  this.logger?.error('QuickCrypto encryption failed, falling back to Noble', {
322
285
  error: {
323
286
  message: error instanceof Error ? error.message : String(error),
324
- stack: error instanceof Error ? error.stack : undefined
325
- }
287
+ stack: error instanceof Error ? error.stack : undefined,
288
+ },
326
289
  });
327
290
  return this.nobleProvider.encrypt(key, data, iv);
328
291
  }
@@ -339,7 +302,7 @@ export class QuickCryptoProvider implements CryptoProvider {
339
302
 
340
303
  this.logger?.debug('Decrypting data with AES-GCM using QuickCrypto', {
341
304
  dataSize: data.byteLength,
342
- ivSize: iv.byteLength
305
+ ivSize: iv.byteLength,
343
306
  });
344
307
 
345
308
  const secretKey = key as QuickCryptoKey;
@@ -347,7 +310,7 @@ export class QuickCryptoProvider implements CryptoProvider {
347
310
  if (secretKey.type !== 'secret') {
348
311
  const error = new Error('Expected secret key');
349
312
  this.logger?.error('Decryption failed - invalid key type', {
350
- actualType: secretKey.type
313
+ actualType: secretKey.type,
351
314
  });
352
315
  throw error;
353
316
  }
@@ -378,7 +341,7 @@ export class QuickCryptoProvider implements CryptoProvider {
378
341
  result.set(final, decrypted.length);
379
342
 
380
343
  this.logger?.debug('Decryption completed using QuickCrypto', {
381
- plaintextSize: result.byteLength
344
+ plaintextSize: result.byteLength,
382
345
  });
383
346
 
384
347
  return result.buffer.slice(result.byteOffset, result.byteOffset + result.byteLength);
@@ -386,8 +349,8 @@ export class QuickCryptoProvider implements CryptoProvider {
386
349
  this.logger?.error('QuickCrypto decryption failed, falling back to Noble', {
387
350
  error: {
388
351
  message: error instanceof Error ? error.message : String(error),
389
- stack: error instanceof Error ? error.stack : undefined
390
- }
352
+ stack: error instanceof Error ? error.stack : undefined,
353
+ },
391
354
  });
392
355
  return this.nobleProvider.decrypt(key, data, iv);
393
356
  }
@@ -417,8 +380,8 @@ export class QuickCryptoProvider implements CryptoProvider {
417
380
  } catch (error) {
418
381
  this.logger?.error('QuickCrypto HMAC failed, falling back to Noble', {
419
382
  error: {
420
- message: error instanceof Error ? error.message : String(error)
421
- }
383
+ message: error instanceof Error ? error.message : String(error),
384
+ },
422
385
  });
423
386
  return this.nobleProvider.generateHMAC(key, data);
424
387
  }
@@ -452,32 +415,10 @@ export class QuickCryptoProvider implements CryptoProvider {
452
415
  } catch (error) {
453
416
  this.logger?.error('QuickCrypto HMAC verification failed, falling back to Noble', {
454
417
  error: {
455
- message: error instanceof Error ? error.message : String(error)
456
- }
418
+ message: error instanceof Error ? error.message : String(error),
419
+ },
457
420
  });
458
421
  return this.nobleProvider.verifyHMAC(key, data, mac);
459
422
  }
460
423
  }
461
424
  }
462
-
463
- /**
464
- * Self-register QuickCrypto provider on import
465
- * This allows the provider to be available when explicitly imported
466
- *
467
- * Note: QuickCrypto depends on Noble for ECDH operations, so we auto-register
468
- * Noble as well to ensure all required functionality is available.
469
- */
470
- // Auto-register noble as a dependency (QuickCrypto delegates ECDH to Noble)
471
- import './noble-provider';
472
-
473
- registerCryptoProvider('quickcrypto', (logger) => new QuickCryptoProvider(logger));
474
-
475
- // TypeScript module augmentation to track this provider is available
476
- declare global {
477
- // eslint-disable-next-line @typescript-eslint/no-namespace
478
- namespace BananaLink {
479
- interface RegisteredCryptoProviders {
480
- quickcrypto: true;
481
- }
482
- }
483
- }
@@ -1,9 +1,17 @@
1
1
  /**
2
2
  * Global registry for crypto providers
3
3
  *
4
- * This registry allows providers to self-register when imported,
5
- * enabling explicit import patterns while maintaining the factory pattern
6
- * internally within BananaLink and BananaWallet classes.
4
+ * @deprecated This module is deprecated. Use crypto factory functions instead:
5
+ * ```typescript
6
+ * import { BananaLink, webSocketTransport, nobleCrypto } from '@bananalink-sdk/client'
7
+ *
8
+ * const client = new BananaLink({
9
+ * transport: webSocketTransport(),
10
+ * crypto: nobleCrypto(),
11
+ * })
12
+ * ```
13
+ *
14
+ * The registry is kept for backward compatibility but will be removed in a future version.
7
15
  */
8
16
 
9
17
  import type { CryptoProvider, CryptoProviderType } from '../../types/crypto-provider';
@@ -35,10 +43,7 @@ const cryptoProviders = new Map<CryptoProviderType, CryptoProviderFactory>();
35
43
  * registerCryptoProvider('noble', (logger) => new NobleCryptoProvider(logger));
36
44
  * ```
37
45
  */
38
- export function registerCryptoProvider(
39
- type: CryptoProviderType,
40
- factory: CryptoProviderFactory
41
- ): void {
46
+ export function registerCryptoProvider(type: CryptoProviderType, factory: CryptoProviderFactory): void {
42
47
  // Skip if already registered (idempotent)
43
48
  if (cryptoProviders.has(type)) {
44
49
  return;
@@ -62,8 +67,8 @@ export function getCryptoProviderFactory(type: CryptoProviderType): CryptoProvid
62
67
 
63
68
  throw new Error(
64
69
  `Crypto provider '${type}' is not registered. ${importHint}\n` +
65
- `Available providers: ${availableProviders || 'none'}\n` +
66
- `Make sure to import the provider before using it.`
70
+ `Available providers: ${availableProviders || 'none'}\n` +
71
+ `Make sure to import the provider before using it.`,
67
72
  );
68
73
  }
69
74
 
@@ -1,6 +1,5 @@
1
1
  import type { Logger } from '@bananalink-sdk/logger';
2
2
  import type { CryptoProvider, CryptoKeyLike, ProviderKeyPair } from '../../types/crypto-provider';
3
- import { registerCryptoProvider } from './registry';
4
3
 
5
4
  /**
6
5
  * WebCrypto CryptoKey wrapper to implement CryptoKeyLike interface
@@ -74,7 +73,7 @@ export class WebCryptoProvider implements CryptoProvider {
74
73
  namedCurve: 'P-256',
75
74
  },
76
75
  true, // extractable
77
- ['deriveKey']
76
+ ['deriveKey'],
78
77
  );
79
78
 
80
79
  this.logger?.debug('Key pair generation completed');
@@ -110,7 +109,9 @@ export class WebCryptoProvider implements CryptoProvider {
110
109
 
111
110
  this.logger?.debug('importPublicKey called', {
112
111
  keyLength: keyBytes.length,
113
- keyBytesFirst20: Array.from(keyBytes.slice(0, 20)).map(b => b.toString(16).padStart(2, '0')).join(' ')
112
+ keyBytesFirst20: Array.from(keyBytes.slice(0, 20))
113
+ .map((b) => b.toString(16).padStart(2, '0'))
114
+ .join(' '),
114
115
  });
115
116
 
116
117
  try {
@@ -122,7 +123,7 @@ export class WebCryptoProvider implements CryptoProvider {
122
123
  namedCurve: 'P-256',
123
124
  },
124
125
  true,
125
- []
126
+ [],
126
127
  );
127
128
 
128
129
  this.logger?.debug('Public key import successful');
@@ -131,8 +132,8 @@ export class WebCryptoProvider implements CryptoProvider {
131
132
  this.logger?.error('Public key import failed', {
132
133
  error: {
133
134
  message: error instanceof Error ? error.message : String(error),
134
- stack: error instanceof Error ? error.stack : undefined
135
- }
135
+ stack: error instanceof Error ? error.stack : undefined,
136
+ },
136
137
  });
137
138
  throw new Error(`Invalid P-256 public key: ${String(error)}`);
138
139
  }
@@ -143,7 +144,7 @@ export class WebCryptoProvider implements CryptoProvider {
143
144
  */
144
145
  async importPrivateKey(keyData: ArrayBuffer): Promise<CryptoKeyLike> {
145
146
  this.logger?.debug('Importing private key', {
146
- keyLength: keyData.byteLength
147
+ keyLength: keyData.byteLength,
147
148
  });
148
149
 
149
150
  try {
@@ -155,7 +156,7 @@ export class WebCryptoProvider implements CryptoProvider {
155
156
  namedCurve: 'P-256',
156
157
  },
157
158
  true,
158
- ['deriveKey']
159
+ ['deriveKey'],
159
160
  );
160
161
 
161
162
  this.logger?.debug('Private key import successful');
@@ -164,8 +165,8 @@ export class WebCryptoProvider implements CryptoProvider {
164
165
  this.logger?.error('Private key import failed', {
165
166
  error: {
166
167
  message: error instanceof Error ? error.message : String(error),
167
- stack: error instanceof Error ? error.stack : undefined
168
- }
168
+ stack: error instanceof Error ? error.stack : undefined,
169
+ },
169
170
  });
170
171
  throw new Error(`Invalid P-256 private key: ${String(error)}`);
171
172
  }
@@ -189,7 +190,7 @@ export class WebCryptoProvider implements CryptoProvider {
189
190
  length: 256,
190
191
  },
191
192
  true,
192
- ['encrypt', 'decrypt']
193
+ ['encrypt', 'decrypt'],
193
194
  );
194
195
 
195
196
  this.logger?.debug('Shared secret derivation completed');
@@ -198,8 +199,8 @@ export class WebCryptoProvider implements CryptoProvider {
198
199
  this.logger?.error('Shared secret derivation failed', {
199
200
  error: {
200
201
  message: error instanceof Error ? error.message : String(error),
201
- stack: error instanceof Error ? error.stack : undefined
202
- }
202
+ stack: error instanceof Error ? error.stack : undefined,
203
+ },
203
204
  });
204
205
  throw error;
205
206
  }
@@ -215,7 +216,7 @@ export class WebCryptoProvider implements CryptoProvider {
215
216
  await crypto.subtle.exportKey('raw', unwrapCryptoKey(sharedSecret)),
216
217
  { name: 'HKDF' },
217
218
  false,
218
- ['deriveKey']
219
+ ['deriveKey'],
219
220
  );
220
221
 
221
222
  // Derive encryption key using HKDF
@@ -229,7 +230,7 @@ export class WebCryptoProvider implements CryptoProvider {
229
230
  baseKey,
230
231
  { name: 'AES-GCM', length: 256 },
231
232
  true,
232
- ['encrypt', 'decrypt']
233
+ ['encrypt', 'decrypt'],
233
234
  );
234
235
  return new WebCryptoKeyWrapper(derivedKey);
235
236
  }
@@ -250,7 +251,7 @@ export class WebCryptoProvider implements CryptoProvider {
250
251
  async encrypt(key: CryptoKeyLike, data: ArrayBuffer, iv: ArrayBuffer): Promise<ArrayBuffer> {
251
252
  this.logger?.debug('Encrypting data with AES-GCM', {
252
253
  dataSize: data.byteLength,
253
- ivSize: iv.byteLength
254
+ ivSize: iv.byteLength,
254
255
  });
255
256
 
256
257
  try {
@@ -261,19 +262,19 @@ export class WebCryptoProvider implements CryptoProvider {
261
262
  tagLength: 128, // 128-bit tag
262
263
  },
263
264
  unwrapCryptoKey(key),
264
- data
265
+ data,
265
266
  );
266
267
 
267
268
  this.logger?.debug('Encryption completed', {
268
- ciphertextSize: ciphertext.byteLength
269
+ ciphertextSize: ciphertext.byteLength,
269
270
  });
270
271
  return ciphertext;
271
272
  } catch (error) {
272
273
  this.logger?.error('Encryption failed', {
273
274
  error: {
274
275
  message: error instanceof Error ? error.message : String(error),
275
- stack: error instanceof Error ? error.stack : undefined
276
- }
276
+ stack: error instanceof Error ? error.stack : undefined,
277
+ },
277
278
  });
278
279
  throw error;
279
280
  }
@@ -285,7 +286,7 @@ export class WebCryptoProvider implements CryptoProvider {
285
286
  async decrypt(key: CryptoKeyLike, data: ArrayBuffer, iv: ArrayBuffer): Promise<ArrayBuffer> {
286
287
  this.logger?.debug('Decrypting data with AES-GCM', {
287
288
  dataSize: data.byteLength,
288
- ivSize: iv.byteLength
289
+ ivSize: iv.byteLength,
289
290
  });
290
291
 
291
292
  try {
@@ -296,19 +297,19 @@ export class WebCryptoProvider implements CryptoProvider {
296
297
  tagLength: 128, // 128-bit tag
297
298
  },
298
299
  unwrapCryptoKey(key),
299
- data
300
+ data,
300
301
  );
301
302
 
302
303
  this.logger?.debug('Decryption completed', {
303
- plaintextSize: plaintext.byteLength
304
+ plaintextSize: plaintext.byteLength,
304
305
  });
305
306
  return plaintext;
306
307
  } catch (error) {
307
308
  this.logger?.error('Decryption failed', {
308
309
  error: {
309
310
  message: error instanceof Error ? error.message : String(error),
310
- stack: error instanceof Error ? error.stack : undefined
311
- }
311
+ stack: error instanceof Error ? error.stack : undefined,
312
+ },
312
313
  });
313
314
  throw error;
314
315
  }
@@ -324,7 +325,7 @@ export class WebCryptoProvider implements CryptoProvider {
324
325
  await crypto.subtle.exportKey('raw', unwrapCryptoKey(key)),
325
326
  { name: 'HMAC', hash: 'SHA-256' },
326
327
  false,
327
- ['sign']
328
+ ['sign'],
328
329
  );
329
330
 
330
331
  return crypto.subtle.sign('HMAC', hmacKey, data);
@@ -340,25 +341,9 @@ export class WebCryptoProvider implements CryptoProvider {
340
341
  await crypto.subtle.exportKey('raw', unwrapCryptoKey(key)),
341
342
  { name: 'HMAC', hash: 'SHA-256' },
342
343
  false,
343
- ['verify']
344
+ ['verify'],
344
345
  );
345
346
 
346
347
  return crypto.subtle.verify('HMAC', hmacKey, mac, data);
347
348
  }
348
349
  }
349
-
350
- /**
351
- * Self-register WebCrypto provider on import
352
- * This allows the provider to be available when explicitly imported
353
- */
354
- registerCryptoProvider('webcrypto', () => new WebCryptoProvider());
355
-
356
- // TypeScript module augmentation to track this provider is available
357
- declare global {
358
- // eslint-disable-next-line @typescript-eslint/no-namespace
359
- namespace BananaLink {
360
- interface RegisteredCryptoProviders {
361
- webcrypto: true;
362
- }
363
- }
364
- }