@opendatalabs/vana-sdk 0.1.0-alpha.5f8458e → 0.1.0-alpha.606fa2d

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 (50) hide show
  1. package/README.md +55 -4
  2. package/dist/{browser-cRpdLQ3-.d.ts → browser-Bb8gLWHp.d.ts} +61 -10
  3. package/dist/browser.d.ts +1 -1
  4. package/dist/browser.js +745 -113
  5. package/dist/browser.js.map +1 -1
  6. package/dist/chains.browser.cjs +2 -2
  7. package/dist/chains.browser.cjs.map +1 -1
  8. package/dist/chains.browser.js +2 -2
  9. package/dist/chains.browser.js.map +1 -1
  10. package/dist/chains.cjs +2 -2
  11. package/dist/chains.cjs.map +1 -1
  12. package/dist/chains.js +2 -2
  13. package/dist/chains.js.map +1 -1
  14. package/dist/chains.node.cjs +2 -2
  15. package/dist/chains.node.cjs.map +1 -1
  16. package/dist/chains.node.js +2 -2
  17. package/dist/chains.node.js.map +1 -1
  18. package/dist/index.browser.d.ts +1348 -243
  19. package/dist/index.browser.js +35080 -32770
  20. package/dist/index.browser.js.map +1 -1
  21. package/dist/index.node.cjs +35587 -33174
  22. package/dist/index.node.cjs.map +1 -1
  23. package/dist/index.node.d.cts +1136 -250
  24. package/dist/index.node.d.ts +1136 -250
  25. package/dist/index.node.js +35459 -33037
  26. package/dist/index.node.js.map +1 -1
  27. package/dist/{node-CkdgwBiv.d.cts → node-D9-F9uEP.d.cts} +3 -2
  28. package/dist/{node-CkdgwBiv.d.ts → node-D9-F9uEP.d.ts} +3 -2
  29. package/dist/node.cjs +704 -67
  30. package/dist/node.cjs.map +1 -1
  31. package/dist/node.d.cts +1 -1
  32. package/dist/node.d.ts +1 -1
  33. package/dist/node.js +716 -66
  34. package/dist/node.js.map +1 -1
  35. package/dist/platform.browser.d.ts +2 -2
  36. package/dist/platform.browser.js +808 -121
  37. package/dist/platform.browser.js.map +1 -1
  38. package/dist/platform.cjs +973 -186
  39. package/dist/platform.cjs.map +1 -1
  40. package/dist/platform.d.cts +1 -1
  41. package/dist/platform.d.ts +1 -1
  42. package/dist/platform.js +985 -186
  43. package/dist/platform.js.map +1 -1
  44. package/dist/platform.node.cjs +973 -186
  45. package/dist/platform.node.cjs.map +1 -1
  46. package/dist/platform.node.d.cts +63 -12
  47. package/dist/platform.node.d.ts +63 -12
  48. package/dist/platform.node.js +985 -186
  49. package/dist/platform.node.js.map +1 -1
  50. package/package.json +40 -23
@@ -6,31 +6,6 @@ var __esm = (fn, res) => function __init() {
6
6
  };
7
7
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
8
 
9
- // src/platform/shared/crypto-utils.ts
10
- function processWalletPublicKey(publicKey) {
11
- const publicKeyHex = publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
12
- const publicKeyBytes = Buffer.from(publicKeyHex, "hex");
13
- return publicKeyBytes.length === 64 ? Buffer.concat([Buffer.from([4]), publicKeyBytes]) : publicKeyBytes;
14
- }
15
- function processWalletPrivateKey(privateKey) {
16
- const privateKeyHex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
17
- return Buffer.from(privateKeyHex, "hex");
18
- }
19
- function parseEncryptedDataBuffer(encryptedBuffer) {
20
- return {
21
- iv: encryptedBuffer.slice(0, 16),
22
- ephemPublicKey: encryptedBuffer.slice(16, 81),
23
- // 65 bytes for uncompressed public key
24
- ciphertext: encryptedBuffer.slice(81, -32),
25
- mac: encryptedBuffer.slice(-32)
26
- };
27
- }
28
- var init_crypto_utils = __esm({
29
- "src/platform/shared/crypto-utils.ts"() {
30
- "use strict";
31
- }
32
- });
33
-
34
9
  // src/platform/shared/pgp-utils.ts
35
10
  function processPGPKeyOptions(options) {
36
11
  return {
@@ -73,139 +48,853 @@ var init_error_utils = __esm({
73
48
  }
74
49
  });
75
50
 
76
- // src/platform/browser.ts
77
- import * as openpgp from "openpgp";
78
- var BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserCacheAdapter, BrowserPlatformAdapter, browserPlatformAdapter;
51
+ // src/utils/lazy-import.ts
52
+ function lazyImport(importFn) {
53
+ let cached = null;
54
+ return () => {
55
+ if (!cached) {
56
+ cached = importFn().catch((err) => {
57
+ cached = null;
58
+ throw new Error("Failed to load module", { cause: err });
59
+ });
60
+ }
61
+ return cached;
62
+ };
63
+ }
64
+ var init_lazy_import = __esm({
65
+ "src/utils/lazy-import.ts"() {
66
+ "use strict";
67
+ }
68
+ });
69
+
70
+ // src/utils/encoding.ts
71
+ function toHex(data) {
72
+ if (typeof Buffer !== "undefined" && Buffer.from) {
73
+ return Buffer.from(data).toString("hex");
74
+ }
75
+ return Array.from(data, (byte) => byte.toString(16).padStart(2, "0")).join(
76
+ ""
77
+ );
78
+ }
79
+ function fromHex(hex) {
80
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
81
+ if (cleanHex.length % 2 !== 0) {
82
+ throw new Error("Invalid hex string: odd length");
83
+ }
84
+ if (!/^[0-9a-fA-F]*$/.test(cleanHex)) {
85
+ throw new Error("Invalid hex string: contains non-hex characters");
86
+ }
87
+ if (typeof Buffer !== "undefined" && Buffer.from) {
88
+ return new Uint8Array(Buffer.from(cleanHex, "hex"));
89
+ }
90
+ const bytes = new Uint8Array(cleanHex.length / 2);
91
+ for (let i = 0; i < cleanHex.length; i += 2) {
92
+ bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16);
93
+ }
94
+ return bytes;
95
+ }
96
+ function stringToBytes(str) {
97
+ if (typeof Buffer !== "undefined" && Buffer.from) {
98
+ return new Uint8Array(Buffer.from(str, "utf8"));
99
+ }
100
+ if (typeof TextEncoder !== "undefined") {
101
+ return new TextEncoder().encode(str);
102
+ }
103
+ const bytes = [];
104
+ for (let i = 0; i < str.length; i++) {
105
+ const char = str.charCodeAt(i);
106
+ if (char < 128) {
107
+ bytes.push(char);
108
+ } else if (char < 2048) {
109
+ bytes.push(192 | char >> 6, 128 | char & 63);
110
+ } else if (char < 55296 || char >= 57344) {
111
+ bytes.push(
112
+ 224 | char >> 12,
113
+ 128 | char >> 6 & 63,
114
+ 128 | char & 63
115
+ );
116
+ } else {
117
+ i++;
118
+ const char2 = str.charCodeAt(i);
119
+ const codePoint = 65536 + ((char & 1023) << 10 | char2 & 1023);
120
+ bytes.push(
121
+ 240 | codePoint >> 18,
122
+ 128 | codePoint >> 12 & 63,
123
+ 128 | codePoint >> 6 & 63,
124
+ 128 | codePoint & 63
125
+ );
126
+ }
127
+ }
128
+ return new Uint8Array(bytes);
129
+ }
130
+ function bytesToString(bytes) {
131
+ if (typeof Buffer !== "undefined" && Buffer.from) {
132
+ return Buffer.from(bytes).toString("utf8");
133
+ }
134
+ if (typeof TextDecoder !== "undefined") {
135
+ return new TextDecoder().decode(bytes);
136
+ }
137
+ let str = "";
138
+ let i = 0;
139
+ while (i < bytes.length) {
140
+ const byte = bytes[i];
141
+ if (byte < 128) {
142
+ str += String.fromCharCode(byte);
143
+ i++;
144
+ } else if ((byte & 224) === 192) {
145
+ str += String.fromCharCode((byte & 31) << 6 | bytes[i + 1] & 63);
146
+ i += 2;
147
+ } else if ((byte & 240) === 224) {
148
+ str += String.fromCharCode(
149
+ (byte & 15) << 12 | (bytes[i + 1] & 63) << 6 | bytes[i + 2] & 63
150
+ );
151
+ i += 3;
152
+ } else {
153
+ const codePoint = ((byte & 7) << 18 | (bytes[i + 1] & 63) << 12 | (bytes[i + 2] & 63) << 6 | bytes[i + 3] & 63) - 65536;
154
+ str += String.fromCharCode(
155
+ 55296 + (codePoint >> 10),
156
+ 56320 + (codePoint & 1023)
157
+ );
158
+ i += 4;
159
+ }
160
+ }
161
+ return str;
162
+ }
163
+ var init_encoding = __esm({
164
+ "src/utils/encoding.ts"() {
165
+ "use strict";
166
+ }
167
+ });
168
+
169
+ // src/utils/crypto-utils.ts
170
+ function concatBytes(...arrays) {
171
+ const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
172
+ const result = new Uint8Array(totalLength);
173
+ let offset = 0;
174
+ for (const arr of arrays) {
175
+ result.set(arr, offset);
176
+ offset += arr.length;
177
+ }
178
+ return result;
179
+ }
180
+ function hexToBytes(hex) {
181
+ return fromHex(hex);
182
+ }
183
+ function bytesToHex(bytes) {
184
+ return toHex(bytes);
185
+ }
186
+ function processWalletPublicKey(publicKey) {
187
+ const publicKeyHex = typeof publicKey === "string" ? publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey : bytesToHex(publicKey);
188
+ const publicKeyBytes = hexToBytes(publicKeyHex);
189
+ return publicKeyBytes.length === 64 ? concatBytes(new Uint8Array([4]), publicKeyBytes) : publicKeyBytes;
190
+ }
191
+ function processWalletPrivateKey(privateKey) {
192
+ const privateKeyHex = typeof privateKey === "string" ? privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey : bytesToHex(privateKey);
193
+ return hexToBytes(privateKeyHex);
194
+ }
195
+ function parseEncryptedDataBuffer(encryptedBuffer) {
196
+ return {
197
+ iv: encryptedBuffer.slice(0, 16),
198
+ ephemPublicKey: encryptedBuffer.slice(16, 81),
199
+ // 65 bytes for uncompressed public key
200
+ ciphertext: encryptedBuffer.slice(81, -32),
201
+ mac: encryptedBuffer.slice(-32)
202
+ };
203
+ }
204
+ var init_crypto_utils = __esm({
205
+ "src/utils/crypto-utils.ts"() {
206
+ "use strict";
207
+ init_encoding();
208
+ }
209
+ });
210
+
211
+ // src/crypto/services/WalletKeyEncryptionService.ts
212
+ var WalletKeyEncryptionService;
213
+ var init_WalletKeyEncryptionService = __esm({
214
+ "src/crypto/services/WalletKeyEncryptionService.ts"() {
215
+ "use strict";
216
+ init_crypto_utils();
217
+ init_encoding();
218
+ WalletKeyEncryptionService = class {
219
+ constructor(config) {
220
+ __publicField(this, "eciesProvider");
221
+ this.eciesProvider = config.eciesProvider;
222
+ }
223
+ /**
224
+ * Encrypts data using a wallet's public key.
225
+ *
226
+ * @param data - The plaintext message to encrypt for the wallet owner.
227
+ * @param publicKey - The recipient wallet's public key for encryption.
228
+ * @returns A promise that resolves to the encrypted data as a hex string.
229
+ * @throws {Error} When encryption fails due to invalid key format.
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * const encrypted = await processor.encryptWithWalletPublicKey(
234
+ * "Secret message",
235
+ * "0x04..." // 65-byte uncompressed public key
236
+ * );
237
+ * console.log(`Encrypted: ${encrypted}`);
238
+ * ```
239
+ */
240
+ async encryptWithWalletPublicKey(data, publicKey) {
241
+ const publicKeyBytes = processWalletPublicKey(publicKey);
242
+ const dataBytes = stringToBytes(data);
243
+ const encrypted = await this.eciesProvider.encrypt(
244
+ publicKeyBytes,
245
+ dataBytes
246
+ );
247
+ const result = concatBytes(
248
+ encrypted.iv,
249
+ encrypted.ephemPublicKey,
250
+ encrypted.ciphertext,
251
+ encrypted.mac
252
+ );
253
+ return bytesToHex(result);
254
+ }
255
+ /**
256
+ * Decrypts data using a wallet's private key.
257
+ *
258
+ * @param encryptedData - The hex-encoded encrypted data to decrypt.
259
+ * @param privateKey - The wallet's private key for decryption.
260
+ * @returns A promise that resolves to the decrypted plaintext message.
261
+ * @throws {Error} When decryption fails due to invalid data or key format.
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * const decrypted = await processor.decryptWithWalletPrivateKey(
266
+ * encryptedHexString,
267
+ * "0x..." // 32-byte private key
268
+ * );
269
+ * console.log(`Decrypted: ${decrypted}`);
270
+ * ```
271
+ */
272
+ async decryptWithWalletPrivateKey(encryptedData, privateKey) {
273
+ const privateKeyBytes = processWalletPrivateKey(privateKey);
274
+ const encryptedBytes = hexToBytes(encryptedData);
275
+ const encrypted = parseEncryptedDataBuffer(encryptedBytes);
276
+ const decrypted = await this.eciesProvider.decrypt(
277
+ privateKeyBytes,
278
+ encrypted
279
+ );
280
+ return bytesToString(decrypted);
281
+ }
282
+ /**
283
+ * Encrypts a Uint8Array with a wallet public key
284
+ *
285
+ * @param data - Binary data to encrypt
286
+ * @param publicKey - Public key as hex string or Uint8Array
287
+ * @returns Encrypted data structure
288
+ */
289
+ async encryptBinary(data, publicKey) {
290
+ const publicKeyBytes = processWalletPublicKey(publicKey);
291
+ return this.eciesProvider.encrypt(publicKeyBytes, data);
292
+ }
293
+ /**
294
+ * Decrypts to a Uint8Array with a wallet private key
295
+ *
296
+ * @param encrypted - Encrypted data structure
297
+ * @param privateKey - Private key as hex string or Uint8Array
298
+ * @returns Decrypted binary data
299
+ */
300
+ async decryptBinary(encrypted, privateKey) {
301
+ const privateKeyBytes = processWalletPrivateKey(privateKey);
302
+ return this.eciesProvider.decrypt(privateKeyBytes, encrypted);
303
+ }
304
+ /**
305
+ * Gets the underlying ECIES provider
306
+ *
307
+ * @returns The ECIES provider instance
308
+ */
309
+ getECIESProvider() {
310
+ return this.eciesProvider;
311
+ }
312
+ };
313
+ }
314
+ });
315
+
316
+ // src/crypto/ecies/utils.ts
317
+ function hexToBytes2(hex) {
318
+ if (hex.length % 2 !== 0) {
319
+ throw new Error("Hex string must have even length");
320
+ }
321
+ const bytes = new Uint8Array(hex.length / 2);
322
+ for (let i = 0; i < hex.length; i += 2) {
323
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
324
+ }
325
+ return bytes;
326
+ }
327
+ function bytesToHex2(bytes) {
328
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
329
+ }
330
+ function stringToBytes2(str) {
331
+ return new TextEncoder().encode(str);
332
+ }
333
+ function bytesToString2(bytes) {
334
+ return new TextDecoder().decode(bytes);
335
+ }
336
+ function concatBytes2(...arrays) {
337
+ const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
338
+ const result = new Uint8Array(totalLength);
339
+ let offset = 0;
340
+ for (const arr of arrays) {
341
+ result.set(arr, offset);
342
+ offset += arr.length;
343
+ }
344
+ return result;
345
+ }
346
+ function constantTimeEqual(a, b) {
347
+ if (a.length !== b.length) return false;
348
+ let result = 0;
349
+ for (let i = 0; i < a.length; i++) {
350
+ result |= a[i] ^ b[i];
351
+ }
352
+ return result === 0;
353
+ }
354
+ var init_utils = __esm({
355
+ "src/crypto/ecies/utils.ts"() {
356
+ "use strict";
357
+ }
358
+ });
359
+
360
+ // src/crypto/ecies/constants.ts
361
+ var CURVE, CIPHER, KDF, MAC, FORMAT;
362
+ var init_constants = __esm({
363
+ "src/crypto/ecies/constants.ts"() {
364
+ "use strict";
365
+ CURVE = {
366
+ /** The elliptic curve used (secp256k1 - same as Bitcoin/Ethereum) */
367
+ name: "secp256k1",
368
+ /** Private key length in bytes */
369
+ PRIVATE_KEY_LENGTH: 32,
370
+ /** Compressed public key length in bytes (0x02 or 0x03 prefix + 32 bytes) */
371
+ COMPRESSED_PUBLIC_KEY_LENGTH: 33,
372
+ /** Uncompressed public key length in bytes (0x04 prefix + 64 bytes) */
373
+ UNCOMPRESSED_PUBLIC_KEY_LENGTH: 65,
374
+ /** ECDH shared secret X coordinate length */
375
+ SHARED_SECRET_LENGTH: 32,
376
+ /** Public key prefixes */
377
+ PREFIX: {
378
+ /** Uncompressed public key prefix */
379
+ UNCOMPRESSED: 4,
380
+ /** Compressed public key prefix for even Y */
381
+ COMPRESSED_EVEN: 2,
382
+ /** Compressed public key prefix for odd Y */
383
+ COMPRESSED_ODD: 3
384
+ },
385
+ /** X coordinate starts at byte 1 (after prefix) */
386
+ X_COORDINATE_OFFSET: 1,
387
+ /** X coordinate ends at byte 33 (1 + 32) */
388
+ X_COORDINATE_END: 33
389
+ };
390
+ CIPHER = {
391
+ /** Cipher algorithm - must match eccrypto */
392
+ algorithm: "aes-256-cbc",
393
+ /** AES key length in bytes */
394
+ KEY_LENGTH: 32,
395
+ /** Initialization vector length in bytes */
396
+ IV_LENGTH: 16,
397
+ /** Block size for AES */
398
+ BLOCK_SIZE: 16
399
+ };
400
+ KDF = {
401
+ /** Hash algorithm for key derivation - must match eccrypto */
402
+ algorithm: "sha512",
403
+ /** Output length of SHA-512 in bytes */
404
+ OUTPUT_LENGTH: 64,
405
+ /** Encryption key slice (first 32 bytes of KDF output) */
406
+ ENCRYPTION_KEY_OFFSET: 0,
407
+ ENCRYPTION_KEY_LENGTH: 32,
408
+ /** MAC key slice (last 32 bytes of KDF output) */
409
+ MAC_KEY_OFFSET: 32,
410
+ MAC_KEY_LENGTH: 32
411
+ };
412
+ MAC = {
413
+ /** MAC algorithm - must match eccrypto */
414
+ algorithm: "sha256",
415
+ /** HMAC-SHA256 output length in bytes */
416
+ LENGTH: 32
417
+ };
418
+ FORMAT = {
419
+ /** Offsets for each component in serialized format */
420
+ IV_OFFSET: 0,
421
+ IV_LENGTH: CIPHER.IV_LENGTH,
422
+ /** Ephemeral public key (always uncompressed in eccrypto format) */
423
+ EPHEMERAL_KEY_OFFSET: CIPHER.IV_LENGTH,
424
+ EPHEMERAL_KEY_LENGTH: CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH,
425
+ /** Ciphertext starts after IV and ephemeral key */
426
+ CIPHERTEXT_OFFSET: CIPHER.IV_LENGTH + CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH,
427
+ /** MAC is always the last 32 bytes */
428
+ MAC_LENGTH: MAC.LENGTH,
429
+ /** Minimum size of encrypted data (IV + ephemKey + MAC, no ciphertext) */
430
+ MIN_ENCRYPTED_LENGTH: CIPHER.IV_LENGTH + CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH + MAC.LENGTH,
431
+ /**
432
+ * Helper to calculate total length of encrypted data
433
+ *
434
+ * @param ciphertextLength - Length of the ciphertext portion
435
+ * @returns Total length including all components
436
+ */
437
+ getTotalLength: (ciphertextLength) => CIPHER.IV_LENGTH + CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH + ciphertextLength + MAC.LENGTH
438
+ };
439
+ }
440
+ });
441
+
442
+ // src/crypto/ecies/interface.ts
443
+ function isECIESEncrypted(obj) {
444
+ if (!obj || typeof obj !== "object") return false;
445
+ const enc = obj;
446
+ const isUint8Array = (value) => {
447
+ return value instanceof Uint8Array || typeof Buffer !== "undefined" && Buffer.isBuffer(value);
448
+ };
449
+ return isUint8Array(enc.iv) && enc.iv.length === CIPHER.IV_LENGTH && isUint8Array(enc.ephemPublicKey) && (enc.ephemPublicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH || enc.ephemPublicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) && isUint8Array(enc.ciphertext) && enc.ciphertext.length > 0 && isUint8Array(enc.mac) && enc.mac.length === MAC.LENGTH;
450
+ }
451
+ var ECIESError;
452
+ var init_interface = __esm({
453
+ "src/crypto/ecies/interface.ts"() {
454
+ "use strict";
455
+ init_constants();
456
+ ECIESError = class extends Error {
457
+ constructor(message, code, cause) {
458
+ super(message);
459
+ this.code = code;
460
+ this.cause = cause;
461
+ this.name = "ECIESError";
462
+ }
463
+ };
464
+ }
465
+ });
466
+
467
+ // src/crypto/ecies/base.ts
468
+ var _BaseECIESUint8, BaseECIESUint8;
469
+ var init_base = __esm({
470
+ "src/crypto/ecies/base.ts"() {
471
+ "use strict";
472
+ init_interface();
473
+ init_constants();
474
+ init_utils();
475
+ _BaseECIESUint8 = class _BaseECIESUint8 {
476
+ /**
477
+ * Normalizes a public key to uncompressed format.
478
+ *
479
+ * @param publicKey - Public key in any format.
480
+ * @returns Uncompressed public key (65 bytes).
481
+ * @throws {ECIESError} If key format is invalid.
482
+ */
483
+ normalizePublicKey(publicKey) {
484
+ if (_BaseECIESUint8.validatedKeys.has(publicKey)) {
485
+ return publicKey;
486
+ }
487
+ if (publicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
488
+ if (publicKey[0] !== CURVE.PREFIX.UNCOMPRESSED) {
489
+ throw new ECIESError(
490
+ "Invalid uncompressed public key prefix",
491
+ "INVALID_KEY"
492
+ );
493
+ }
494
+ if (!this.validatePublicKey(publicKey)) {
495
+ throw new ECIESError("Invalid public key", "INVALID_KEY");
496
+ }
497
+ _BaseECIESUint8.validatedKeys.set(publicKey, true);
498
+ return publicKey;
499
+ }
500
+ if (publicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) {
501
+ const decompressed = this.decompressPublicKey(publicKey);
502
+ if (!decompressed) {
503
+ throw new ECIESError("Failed to decompress public key", "INVALID_KEY");
504
+ }
505
+ _BaseECIESUint8.validatedKeys.set(decompressed, true);
506
+ return decompressed;
507
+ }
508
+ throw new ECIESError(
509
+ `Invalid public key length: ${publicKey.length}`,
510
+ "INVALID_KEY"
511
+ );
512
+ }
513
+ /**
514
+ * Encrypts data using ECIES.
515
+ *
516
+ * @param publicKey - The recipient's public key (compressed or uncompressed)
517
+ * @param message - The data to encrypt
518
+ * @returns Promise resolving to encrypted data structure
519
+ */
520
+ async encrypt(publicKey, message) {
521
+ try {
522
+ if (!(publicKey instanceof Uint8Array)) {
523
+ throw new ECIESError("Public key must be a Uint8Array", "INVALID_KEY");
524
+ }
525
+ if (!(message instanceof Uint8Array)) {
526
+ throw new ECIESError(
527
+ "Message must be a Uint8Array",
528
+ "ENCRYPTION_FAILED"
529
+ );
530
+ }
531
+ if (publicKey.length === 0) {
532
+ throw new ECIESError("Public key cannot be empty", "INVALID_KEY");
533
+ }
534
+ const pubKey = this.normalizePublicKey(publicKey);
535
+ let ephemeralPrivateKey;
536
+ do {
537
+ ephemeralPrivateKey = this.generateRandomBytes(
538
+ CURVE.PRIVATE_KEY_LENGTH
539
+ );
540
+ } while (!this.verifyPrivateKey(ephemeralPrivateKey));
541
+ const ephemeralPublicKey = this.createPublicKey(
542
+ ephemeralPrivateKey,
543
+ false
544
+ );
545
+ if (!ephemeralPublicKey) {
546
+ throw new ECIESError(
547
+ "Failed to generate ephemeral public key",
548
+ "ENCRYPTION_FAILED"
549
+ );
550
+ }
551
+ const sharedSecret = this.performECDH(pubKey, ephemeralPrivateKey);
552
+ const kdf = this.sha512(sharedSecret);
553
+ const encryptionKey = kdf.slice(
554
+ KDF.ENCRYPTION_KEY_OFFSET,
555
+ KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH
556
+ );
557
+ const macKey = kdf.slice(
558
+ KDF.MAC_KEY_OFFSET,
559
+ KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH
560
+ );
561
+ const iv = this.generateRandomBytes(CIPHER.IV_LENGTH);
562
+ const ciphertext = await this.aesEncrypt(encryptionKey, iv, message);
563
+ const macData = concatBytes2(iv, ephemeralPublicKey, ciphertext);
564
+ const mac = this.hmacSha256(macKey, macData);
565
+ this.clearBuffer(ephemeralPrivateKey);
566
+ this.clearBuffer(sharedSecret);
567
+ this.clearBuffer(kdf);
568
+ return {
569
+ iv,
570
+ ephemPublicKey: ephemeralPublicKey,
571
+ ciphertext,
572
+ mac
573
+ };
574
+ } catch (error) {
575
+ if (error instanceof ECIESError) throw error;
576
+ throw new ECIESError(
577
+ `Encryption failed: ${error instanceof Error ? error.message : "Unknown error"}`,
578
+ "ENCRYPTION_FAILED",
579
+ error instanceof Error ? error : void 0
580
+ );
581
+ }
582
+ }
583
+ /**
584
+ * Decrypts ECIES encrypted data.
585
+ *
586
+ * @param privateKey - The recipient's private key (32 bytes)
587
+ * @param encrypted - The encrypted data structure from encrypt()
588
+ * @returns Promise resolving to the original plaintext
589
+ */
590
+ async decrypt(privateKey, encrypted) {
591
+ try {
592
+ if (!(privateKey instanceof Uint8Array)) {
593
+ throw new ECIESError("Private key must be a Uint8Array", "INVALID_KEY");
594
+ }
595
+ if (!isECIESEncrypted(encrypted)) {
596
+ throw new ECIESError(
597
+ "Invalid encrypted data structure",
598
+ "DECRYPTION_FAILED"
599
+ );
600
+ }
601
+ if (privateKey.length !== CURVE.PRIVATE_KEY_LENGTH) {
602
+ throw new ECIESError(
603
+ `Invalid private key length: ${privateKey.length}`,
604
+ "INVALID_KEY"
605
+ );
606
+ }
607
+ if (!this.verifyPrivateKey(privateKey)) {
608
+ throw new ECIESError("Invalid private key", "INVALID_KEY");
609
+ }
610
+ const ephemeralPublicKey = this.normalizePublicKey(
611
+ encrypted.ephemPublicKey
612
+ );
613
+ const sharedSecret = this.performECDH(ephemeralPublicKey, privateKey);
614
+ const kdf = this.sha512(sharedSecret);
615
+ const encryptionKey = kdf.slice(
616
+ KDF.ENCRYPTION_KEY_OFFSET,
617
+ KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH
618
+ );
619
+ const macKey = kdf.slice(
620
+ KDF.MAC_KEY_OFFSET,
621
+ KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH
622
+ );
623
+ const macData = concatBytes2(
624
+ encrypted.iv,
625
+ encrypted.ephemPublicKey,
626
+ encrypted.ciphertext
627
+ );
628
+ const expectedMac = this.hmacSha256(macKey, macData);
629
+ if (!constantTimeEqual(encrypted.mac, expectedMac)) {
630
+ throw new ECIESError("MAC verification failed", "MAC_MISMATCH");
631
+ }
632
+ const decrypted = await this.aesDecrypt(
633
+ encryptionKey,
634
+ encrypted.iv,
635
+ encrypted.ciphertext
636
+ );
637
+ this.clearBuffer(sharedSecret);
638
+ this.clearBuffer(kdf);
639
+ return decrypted;
640
+ } catch (error) {
641
+ if (error instanceof ECIESError) throw error;
642
+ throw new ECIESError(
643
+ `Decryption failed: ${error instanceof Error ? error.message : "Unknown error"}`,
644
+ "DECRYPTION_FAILED",
645
+ error instanceof Error ? error : void 0
646
+ );
647
+ }
648
+ }
649
+ /**
650
+ * Clears sensitive data from memory using multi-pass overwrite.
651
+ *
652
+ * @remarks
653
+ * Uses multiple passes with different patterns to make it harder
654
+ * for JIT compilers to optimize away the operation. While not
655
+ * guaranteed in JavaScript, this is a best-effort approach to
656
+ * clear sensitive data from memory.
657
+ *
658
+ * @param buffer - The buffer to clear
659
+ */
660
+ clearBuffer(buffer) {
661
+ if (buffer && buffer.length > 0) {
662
+ buffer.fill(0);
663
+ buffer.fill(255);
664
+ buffer.fill(170);
665
+ buffer.fill(0);
666
+ for (let i = 0; i < buffer.length; i++) {
667
+ buffer[i] = i & 255 ^ 90;
668
+ }
669
+ buffer.fill(0);
670
+ }
671
+ }
672
+ };
673
+ // Cache for validated public keys to avoid repeated validation
674
+ __publicField(_BaseECIESUint8, "validatedKeys", /* @__PURE__ */ new WeakMap());
675
+ BaseECIESUint8 = _BaseECIESUint8;
676
+ }
677
+ });
678
+
679
+ // src/crypto/ecies/browser.ts
680
+ import * as secp256k1 from "@noble/secp256k1";
681
+ import { hmac } from "@noble/hashes/hmac";
682
+ import { sha256, sha512 as nobleSha512 } from "@noble/hashes/sha2";
683
+ var BrowserECIESUint8Provider;
79
684
  var init_browser = __esm({
685
+ "src/crypto/ecies/browser.ts"() {
686
+ "use strict";
687
+ init_base();
688
+ BrowserECIESUint8Provider = class extends BaseECIESUint8 {
689
+ generateRandomBytes(length) {
690
+ const bytes = new Uint8Array(length);
691
+ crypto.getRandomValues(bytes);
692
+ return bytes;
693
+ }
694
+ verifyPrivateKey(privateKey) {
695
+ try {
696
+ return secp256k1.utils.isValidPrivateKey(privateKey);
697
+ } catch {
698
+ return false;
699
+ }
700
+ }
701
+ createPublicKey(privateKey, compressed) {
702
+ try {
703
+ return secp256k1.getPublicKey(privateKey, compressed);
704
+ } catch {
705
+ return null;
706
+ }
707
+ }
708
+ validatePublicKey(publicKey) {
709
+ try {
710
+ secp256k1.Point.fromHex(publicKey);
711
+ return true;
712
+ } catch {
713
+ return false;
714
+ }
715
+ }
716
+ decompressPublicKey(publicKey) {
717
+ try {
718
+ const point = secp256k1.Point.fromHex(publicKey);
719
+ return point.toRawBytes(false);
720
+ } catch {
721
+ return null;
722
+ }
723
+ }
724
+ performECDH(publicKey, privateKey) {
725
+ try {
726
+ const sharedPoint = secp256k1.getSharedSecret(
727
+ privateKey,
728
+ publicKey,
729
+ true
730
+ );
731
+ return sharedPoint.slice(1);
732
+ } catch (error) {
733
+ throw new Error(
734
+ `ECDH failed: ${error instanceof Error ? error.message : "Unknown error"}`
735
+ );
736
+ }
737
+ }
738
+ sha512(data) {
739
+ return nobleSha512(data);
740
+ }
741
+ hmacSha256(key, data) {
742
+ return hmac(sha256, key, data);
743
+ }
744
+ async aesEncrypt(key, iv, plaintext) {
745
+ const cryptoKey = await crypto.subtle.importKey(
746
+ "raw",
747
+ key,
748
+ { name: "AES-CBC" },
749
+ false,
750
+ ["encrypt"]
751
+ );
752
+ const encrypted = await crypto.subtle.encrypt(
753
+ { name: "AES-CBC", iv },
754
+ cryptoKey,
755
+ plaintext
756
+ );
757
+ return new Uint8Array(encrypted);
758
+ }
759
+ async aesDecrypt(key, iv, ciphertext) {
760
+ const cryptoKey = await crypto.subtle.importKey(
761
+ "raw",
762
+ key,
763
+ { name: "AES-CBC" },
764
+ false,
765
+ ["decrypt"]
766
+ );
767
+ const decrypted = await crypto.subtle.decrypt(
768
+ { name: "AES-CBC", iv },
769
+ cryptoKey,
770
+ ciphertext
771
+ );
772
+ return new Uint8Array(decrypted);
773
+ }
774
+ };
775
+ }
776
+ });
777
+
778
+ // src/platform/browser.ts
779
+ import * as secp256k12 from "@noble/secp256k1";
780
+ var getOpenPGP, BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserCacheAdapter, BrowserPlatformAdapter;
781
+ var init_browser2 = __esm({
80
782
  "src/platform/browser.ts"() {
81
783
  "use strict";
82
- init_crypto_utils();
83
784
  init_pgp_utils();
84
785
  init_error_utils();
786
+ init_lazy_import();
787
+ init_WalletKeyEncryptionService();
788
+ init_crypto_utils();
789
+ init_utils();
790
+ init_browser();
791
+ getOpenPGP = lazyImport(() => import("openpgp"));
85
792
  BrowserCryptoAdapter = class {
793
+ constructor() {
794
+ __publicField(this, "eciesProvider", new BrowserECIESUint8Provider());
795
+ __publicField(this, "walletKeyEncryptionService", new WalletKeyEncryptionService({
796
+ eciesProvider: this.eciesProvider
797
+ }));
798
+ }
86
799
  async encryptWithPublicKey(data, publicKeyHex) {
87
800
  try {
88
- const eccrypto = await import("eccrypto-js");
89
- const publicKeyBuffer = Buffer.from(publicKeyHex, "hex");
90
- const encrypted = await eccrypto.encrypt(
91
- publicKeyBuffer,
92
- Buffer.from(data, "utf8")
801
+ const publicKeyBytes = hexToBytes2(publicKeyHex);
802
+ const encrypted = await this.eciesProvider.encrypt(
803
+ publicKeyBytes,
804
+ stringToBytes2(data)
93
805
  );
94
- const result = Buffer.concat([
806
+ const result = concatBytes2(
95
807
  encrypted.iv,
96
808
  encrypted.ephemPublicKey,
97
809
  encrypted.ciphertext,
98
810
  encrypted.mac
99
- ]);
100
- return result.toString("hex");
811
+ );
812
+ return bytesToHex2(result);
101
813
  } catch (error) {
102
- throw new Error(`Encryption failed: ${error}`);
814
+ throw wrapCryptoError("encryptWithPublicKey", error);
103
815
  }
104
816
  }
105
817
  async decryptWithPrivateKey(encryptedData, privateKeyHex) {
106
818
  try {
107
- const eccrypto = await import("eccrypto-js");
108
- const privateKeyBuffer = processWalletPrivateKey(privateKeyHex);
109
- const encryptedBuffer = Buffer.from(encryptedData, "hex");
110
- const { iv, ephemPublicKey, ciphertext, mac } = parseEncryptedDataBuffer(encryptedBuffer);
111
- const encryptedObj = { iv, ephemPublicKey, ciphertext, mac };
112
- const decryptedBuffer = await eccrypto.decrypt(
113
- privateKeyBuffer,
114
- encryptedObj
819
+ const encryptedBytes = hexToBytes2(encryptedData);
820
+ const privateKeyBytes = hexToBytes2(privateKeyHex);
821
+ const encrypted = parseEncryptedDataBuffer(encryptedBytes);
822
+ const decrypted = await this.eciesProvider.decrypt(
823
+ privateKeyBytes,
824
+ encrypted
115
825
  );
116
- return decryptedBuffer.toString("utf8");
826
+ return bytesToString2(decrypted);
117
827
  } catch (error) {
118
- throw new Error(`Decryption failed: ${error}`);
828
+ throw wrapCryptoError("decryptWithPrivateKey", error);
119
829
  }
120
830
  }
121
- async generateKeyPair() {
831
+ async encryptWithWalletPublicKey(data, publicKey) {
122
832
  try {
123
- const eccrypto = await import("eccrypto-js");
124
- const privateKeyBytes = new Uint8Array(32);
125
- crypto.getRandomValues(privateKeyBytes);
126
- const privateKey = Buffer.from(privateKeyBytes);
127
- const publicKey = eccrypto.getPublicCompressed(privateKey);
128
- return {
129
- privateKey: privateKey.toString("hex"),
130
- publicKey: publicKey.toString("hex")
131
- };
833
+ return await this.walletKeyEncryptionService.encryptWithWalletPublicKey(
834
+ data,
835
+ publicKey
836
+ );
132
837
  } catch (error) {
133
- throw wrapCryptoError("key generation", error);
838
+ throw wrapCryptoError("encryptWithWalletPublicKey", error);
134
839
  }
135
840
  }
136
- async encryptWithWalletPublicKey(data, publicKey) {
841
+ async decryptWithWalletPrivateKey(encryptedData, privateKey) {
137
842
  try {
138
- const eccrypto = await import("eccrypto-js");
139
- const uncompressedKey = processWalletPublicKey(publicKey);
140
- const encryptedBuffer = await eccrypto.encrypt(
141
- uncompressedKey,
142
- Buffer.from(data)
843
+ return await this.walletKeyEncryptionService.decryptWithWalletPrivateKey(
844
+ encryptedData,
845
+ privateKey
143
846
  );
144
- const result = Buffer.concat([
145
- encryptedBuffer.iv,
146
- encryptedBuffer.ephemPublicKey,
147
- encryptedBuffer.ciphertext,
148
- encryptedBuffer.mac
149
- ]);
150
- return result.toString("hex");
151
847
  } catch (error) {
152
- throw wrapCryptoError("encrypt with wallet public key", error);
848
+ throw wrapCryptoError("decryptWithWalletPrivateKey", error);
153
849
  }
154
850
  }
155
- async decryptWithWalletPrivateKey(encryptedData, privateKey) {
851
+ async generateKeyPair() {
156
852
  try {
157
- const eccrypto = await import("eccrypto-js");
158
- const privateKeyBuffer = processWalletPrivateKey(privateKey);
159
- const encryptedBuffer = Buffer.from(encryptedData, "hex");
160
- const { iv, ephemPublicKey, ciphertext, mac } = parseEncryptedDataBuffer(encryptedBuffer);
161
- const encryptedObj = { iv, ephemPublicKey, ciphertext, mac };
162
- const decryptedBuffer = await eccrypto.decrypt(
163
- privateKeyBuffer,
164
- encryptedObj
165
- );
166
- return decryptedBuffer.toString("utf8");
853
+ const privateKeyBytes = secp256k12.utils.randomPrivateKey();
854
+ const publicKeyBytes = secp256k12.getPublicKey(privateKeyBytes, true);
855
+ return {
856
+ privateKey: bytesToHex2(privateKeyBytes),
857
+ publicKey: bytesToHex2(publicKeyBytes)
858
+ };
167
859
  } catch (error) {
168
- throw wrapCryptoError("decrypt with wallet private key", error);
860
+ throw wrapCryptoError("generateKeyPair", error);
169
861
  }
170
862
  }
171
863
  async encryptWithPassword(data, password) {
172
864
  try {
173
- const openpgp2 = await import("openpgp");
174
- const message = await openpgp2.createMessage({
175
- binary: data
176
- });
177
- const encrypted = await openpgp2.encrypt({
865
+ const openpgp = await getOpenPGP();
866
+ const message = await openpgp.createMessage({ binary: data });
867
+ const encrypted = await openpgp.encrypt({
178
868
  message,
179
869
  passwords: [password],
180
870
  format: "binary"
181
871
  });
182
- const response = new Response(encrypted);
183
- const arrayBuffer = await response.arrayBuffer();
184
- return new Uint8Array(arrayBuffer);
872
+ return new Uint8Array(encrypted);
185
873
  } catch (error) {
186
- throw new Error(`Failed to encrypt with password: ${error}`);
874
+ throw wrapCryptoError("encryptWithPassword", error);
187
875
  }
188
876
  }
189
877
  async decryptWithPassword(encryptedData, password) {
190
878
  try {
191
- const openpgp2 = await import("openpgp");
192
- const message = await openpgp2.readMessage({
879
+ const openpgp = await getOpenPGP();
880
+ const message = await openpgp.readMessage({
193
881
  binaryMessage: encryptedData
194
882
  });
195
- const { data: decrypted } = await openpgp2.decrypt({
883
+ const { data } = await openpgp.decrypt({
196
884
  message,
197
885
  passwords: [password],
198
886
  format: "binary"
199
887
  });
200
- return new Uint8Array(decrypted);
888
+ return new Uint8Array(data);
201
889
  } catch (error) {
202
- throw new Error(`Failed to decrypt with password: ${error}`);
890
+ throw wrapCryptoError("decryptWithPassword", error);
203
891
  }
204
892
  }
205
893
  };
206
894
  BrowserPGPAdapter = class {
207
895
  async encrypt(data, publicKeyArmored) {
208
896
  try {
897
+ const openpgp = await getOpenPGP();
209
898
  const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });
210
899
  const encrypted = await openpgp.encrypt({
211
900
  message: await openpgp.createMessage({ text: data }),
@@ -221,6 +910,7 @@ var init_browser = __esm({
221
910
  }
222
911
  async decrypt(encryptedData, privateKeyArmored) {
223
912
  try {
913
+ const openpgp = await getOpenPGP();
224
914
  const privateKey = await openpgp.readPrivateKey({
225
915
  armoredKey: privateKeyArmored
226
916
  });
@@ -238,6 +928,7 @@ var init_browser = __esm({
238
928
  }
239
929
  async generateKeyPair(options) {
240
930
  try {
931
+ const openpgp = await getOpenPGP();
241
932
  const keyGenParams = getPGPKeyGenParams(options);
242
933
  const { privateKey, publicKey } = await openpgp.generateKey(keyGenParams);
243
934
  return { publicKey, privateKey };
@@ -248,9 +939,6 @@ var init_browser = __esm({
248
939
  };
249
940
  BrowserHttpAdapter = class {
250
941
  async fetch(url, options) {
251
- if (typeof fetch === "undefined") {
252
- throw new Error("Fetch API not available in this browser environment");
253
- }
254
942
  return fetch(url, options);
255
943
  }
256
944
  };
@@ -270,17 +958,19 @@ var init_browser = __esm({
270
958
  }
271
959
  set(key, value) {
272
960
  try {
273
- if (typeof sessionStorage !== "undefined") {
274
- sessionStorage.setItem(this.prefix + key, value);
961
+ if (typeof sessionStorage === "undefined") {
962
+ return;
275
963
  }
964
+ sessionStorage.setItem(this.prefix + key, value);
276
965
  } catch {
277
966
  }
278
967
  }
279
968
  delete(key) {
280
969
  try {
281
- if (typeof sessionStorage !== "undefined") {
282
- sessionStorage.removeItem(this.prefix + key);
970
+ if (typeof sessionStorage === "undefined") {
971
+ return;
283
972
  }
973
+ sessionStorage.removeItem(this.prefix + key);
284
974
  } catch {
285
975
  }
286
976
  }
@@ -289,38 +979,35 @@ var init_browser = __esm({
289
979
  if (typeof sessionStorage === "undefined") {
290
980
  return;
291
981
  }
292
- const keys = Object.keys(sessionStorage);
293
- for (const key of keys) {
294
- if (key.startsWith(this.prefix)) {
295
- sessionStorage.removeItem(key);
982
+ const keysToRemove = [];
983
+ for (let i = 0; i < sessionStorage.length; i++) {
984
+ const key = sessionStorage.key(i);
985
+ if (key?.startsWith(this.prefix)) {
986
+ keysToRemove.push(key);
296
987
  }
297
988
  }
989
+ keysToRemove.forEach((key) => sessionStorage.removeItem(key));
298
990
  } catch {
299
991
  }
300
992
  }
301
993
  };
302
994
  BrowserPlatformAdapter = class {
303
995
  constructor() {
304
- __publicField(this, "crypto");
305
- __publicField(this, "pgp");
306
- __publicField(this, "http");
307
- __publicField(this, "cache");
996
+ __publicField(this, "crypto", new BrowserCryptoAdapter());
997
+ __publicField(this, "pgp", new BrowserPGPAdapter());
998
+ __publicField(this, "http", new BrowserHttpAdapter());
999
+ __publicField(this, "cache", new BrowserCacheAdapter());
308
1000
  __publicField(this, "platform", "browser");
309
- this.crypto = new BrowserCryptoAdapter();
310
- this.pgp = new BrowserPGPAdapter();
311
- this.http = new BrowserHttpAdapter();
312
- this.cache = new BrowserCacheAdapter();
313
1001
  }
314
1002
  };
315
- browserPlatformAdapter = new BrowserPlatformAdapter();
316
1003
  }
317
1004
  });
318
1005
 
319
1006
  // src/platform.browser.ts
320
- init_browser();
1007
+ init_browser2();
321
1008
 
322
1009
  // src/platform/browser-only.ts
323
- init_browser();
1010
+ init_browser2();
324
1011
  function createBrowserPlatformAdapter() {
325
1012
  return new BrowserPlatformAdapter();
326
1013
  }