@opendatalabs/vana-sdk 0.1.0-alpha.d6bebb0 → 0.1.0-alpha.e0e85d7

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