@provablehq/sdk 0.9.16 → 0.9.18

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 (45) hide show
  1. package/dist/mainnet/account.d.ts +43 -3
  2. package/dist/mainnet/browser.d.ts +11 -4
  3. package/dist/mainnet/browser.js +460 -109
  4. package/dist/mainnet/browser.js.map +1 -1
  5. package/dist/mainnet/keys/keystore/error.d.ts +23 -0
  6. package/dist/mainnet/keys/keystore/file.d.ts +217 -0
  7. package/dist/mainnet/keys/keystore/interface.d.ts +85 -0
  8. package/dist/mainnet/keys/provider/interface.d.ts +170 -0
  9. package/dist/mainnet/{function-key-provider.d.ts → keys/provider/memory.d.ts} +9 -167
  10. package/dist/mainnet/{offline-key-provider.d.ts → keys/provider/offline.d.ts} +6 -3
  11. package/dist/mainnet/keys/verifier/interface.d.ts +70 -0
  12. package/dist/mainnet/keys/verifier/memory.d.ts +37 -0
  13. package/dist/mainnet/models/keyHolder.d.ts +2 -0
  14. package/dist/mainnet/models/keyPair.d.ts +4 -0
  15. package/dist/mainnet/models/record-scanner/error.d.ts +1 -1
  16. package/dist/mainnet/models/record-scanner/revokeResult.d.ts +17 -0
  17. package/dist/mainnet/node.d.ts +1 -0
  18. package/dist/mainnet/node.js +399 -2
  19. package/dist/mainnet/node.js.map +1 -1
  20. package/dist/mainnet/program-manager.d.ts +4 -3
  21. package/dist/mainnet/record-scanner.d.ts +16 -0
  22. package/dist/mainnet/security.d.ts +24 -0
  23. package/dist/testnet/account.d.ts +43 -3
  24. package/dist/testnet/browser.d.ts +11 -4
  25. package/dist/testnet/browser.js +460 -109
  26. package/dist/testnet/browser.js.map +1 -1
  27. package/dist/testnet/keys/keystore/error.d.ts +23 -0
  28. package/dist/testnet/keys/keystore/file.d.ts +217 -0
  29. package/dist/testnet/keys/keystore/interface.d.ts +85 -0
  30. package/dist/testnet/keys/provider/interface.d.ts +170 -0
  31. package/dist/testnet/{function-key-provider.d.ts → keys/provider/memory.d.ts} +9 -167
  32. package/dist/testnet/{offline-key-provider.d.ts → keys/provider/offline.d.ts} +6 -3
  33. package/dist/testnet/keys/verifier/interface.d.ts +70 -0
  34. package/dist/testnet/keys/verifier/memory.d.ts +37 -0
  35. package/dist/testnet/models/keyHolder.d.ts +2 -0
  36. package/dist/testnet/models/keyPair.d.ts +4 -0
  37. package/dist/testnet/models/record-scanner/error.d.ts +1 -1
  38. package/dist/testnet/models/record-scanner/revokeResult.d.ts +17 -0
  39. package/dist/testnet/node.d.ts +1 -0
  40. package/dist/testnet/node.js +399 -2
  41. package/dist/testnet/node.js.map +1 -1
  42. package/dist/testnet/program-manager.d.ts +4 -3
  43. package/dist/testnet/record-scanner.d.ts +16 -0
  44. package/dist/testnet/security.d.ts +24 -0
  45. package/package.json +3 -3
@@ -4,6 +4,109 @@ export { Address, Authorization, BHP1024, BHP256, BHP512, BHP768, Boolean, Ciphe
4
4
  import sodium from 'libsodium-wrappers';
5
5
  import { bech32m } from '@scure/base';
6
6
 
7
+ await sodium.ready;
8
+ /**
9
+ * Encrypt an authorization with a libsodium cryptobox public key.
10
+ *
11
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
12
+ * @param {Authorization} authorization the authorization to encrypt.
13
+ *
14
+ * @returns {string} the encrypted authorization in RFC 4648 standard Base64.
15
+ */
16
+ function encryptAuthorization(publicKey, authorization) {
17
+ // Ready the cryptobox lib.
18
+ return encryptMessage(publicKey, authorization.toBytesLe());
19
+ }
20
+ /**
21
+ * Encrypt a ProvingRequest with a libsodium cryptobox public key.
22
+ *
23
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
24
+ * @param {Authorization} provingRequest the ProvingRequest to encrypt.
25
+ *
26
+ * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
27
+ */
28
+ function encryptProvingRequest(publicKey, provingRequest) {
29
+ return encryptMessage(publicKey, provingRequest.toBytesLe());
30
+ }
31
+ /**
32
+ * Encrypt a view key with a libsodium cryptobox public key.
33
+ *
34
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
35
+ * @param {ViewKey} viewKey the view key to encrypt.
36
+ *
37
+ * @returns {string} the encrypted view key in RFC 4648 standard Base64.
38
+ */
39
+ function encryptViewKey(publicKey, viewKey) {
40
+ return encryptMessage(publicKey, viewKey.toBytesLe());
41
+ }
42
+ /**
43
+ * Encrypt a record scanner registration request.
44
+ *
45
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
46
+ * @param {ViewKey} viewKey the view key to encrypt.
47
+ * @param {number} start the start height of the registration request.
48
+ *
49
+ * @returns {string} the encrypted view key in RFC 4648 standard Base64.
50
+ */
51
+ function encryptRegistrationRequest(publicKey, viewKey, start) {
52
+ // Turn the view key into a Uint8Array.
53
+ const vk_bytes = viewKey.toBytesLe();
54
+ // Create a new array to hold the original bytes and the 4-byte start height.
55
+ const bytes = new Uint8Array(vk_bytes.length + 4);
56
+ // Copy existing bytes.
57
+ bytes.set(vk_bytes, 0);
58
+ // Write the 4-byte number in LE format at the end of the array.
59
+ const view = new DataView(bytes.buffer);
60
+ view.setUint32(vk_bytes.length, start, true);
61
+ // Encrypt the encoded bytes, ensuring sensitive intermediate
62
+ // byte arrays are zeroized regardless of success or failure.
63
+ try {
64
+ return encryptMessage(publicKey, bytes);
65
+ }
66
+ finally {
67
+ zeroizeBytes(vk_bytes);
68
+ zeroizeBytes(bytes);
69
+ }
70
+ }
71
+ /**
72
+ * Best-effort zeroization of a byte array by overwriting all bytes with zeros.
73
+ * Use this to clear sensitive data (e.g., key bytes) from memory when working
74
+ * with Uint8Array representations of keys or other secrets.
75
+ *
76
+ * This is best-effort in JavaScript — the JIT compiler could theoretically
77
+ * elide the fill if the array is never read again (though current engines
78
+ * do not). For deterministic zeroization of key material, use
79
+ * `Account.destroy()` or call `.free()` on key objects (PrivateKey, ViewKey,
80
+ * ComputeKey, GraphKey) whose Rust Drop implementations zeroize memory
81
+ * before deallocation.
82
+ *
83
+ * Note: This cannot zeroize JavaScript strings, which are immutable and managed
84
+ * by the garbage collector. Prefer using byte array representations of sensitive
85
+ * data over strings whenever possible.
86
+ *
87
+ * @param {Uint8Array} bytes The byte array to zeroize
88
+ *
89
+ * @example
90
+ * const keyBytes = privateKey.toBytesLe();
91
+ * // ... use keyBytes ...
92
+ * zeroizeBytes(keyBytes); // Overwrite with zeros when done
93
+ */
94
+ function zeroizeBytes(bytes) {
95
+ bytes.fill(0);
96
+ }
97
+ /**
98
+ * Encrypt arbitrary bytes with a libsodium cryptobox public key.
99
+ *
100
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
101
+ * @param {Uint8Array} message the bytes to encrypt.
102
+ *
103
+ * @returns {string} the encrypted bytes in RFC 4648 standard Base64.
104
+ */
105
+ function encryptMessage(publicKey, message) {
106
+ const publicKeyBytes = sodium.from_base64(publicKey, sodium.base64_variants.ORIGINAL);
107
+ return sodium.to_base64(sodium.crypto_box_seal(message, publicKeyBytes), sodium.base64_variants.ORIGINAL);
108
+ }
109
+
7
110
  /**
8
111
  * Key Management class. Enables the creation of a new Aleo Account, importation of an existing account from
9
112
  * an existing private key or seed, and message signing and verification functionality. An Aleo Account is generated
@@ -14,6 +117,9 @@ import { bech32m } from '@scure/base';
14
117
  * credits and other records to. This class should only be used in environments where the safety of the underlying key
15
118
  * material can be assured.
16
119
  *
120
+ * When an Account is no longer needed, call {@link destroy} to securely zeroize and free all sensitive key material
121
+ * from WASM memory. Alternatively, use `[Symbol.dispose]()` with the `using` declaration in ES2024+ environments.
122
+ *
17
123
  * @example
18
124
  * import { Account } from "@provablehq/sdk/testnet.js";
19
125
  *
@@ -33,12 +139,16 @@ import { bech32m } from '@scure/base';
33
139
  *
34
140
  * // Verify a signature
35
141
  * assert(myRandomAccount.verify(hello_world, signature));
142
+ *
143
+ * // Securely destroy the account when done
144
+ * myRandomAccount.destroy();
36
145
  */
37
146
  class Account {
38
147
  _privateKey;
39
148
  _viewKey;
40
149
  _computeKey;
41
150
  _address;
151
+ _destroyed = false;
42
152
  constructor(params = {}) {
43
153
  try {
44
154
  this._privateKey = this.privateKeyFromParams(params);
@@ -67,7 +177,12 @@ class Account {
67
177
  try {
68
178
  ciphertext = (typeof ciphertext === "string") ? PrivateKeyCiphertext.fromString(ciphertext) : ciphertext;
69
179
  const _privateKey = PrivateKey.fromPrivateKeyCiphertext(ciphertext, password);
70
- return new Account({ privateKey: _privateKey.to_string() });
180
+ try {
181
+ return new Account({ privateKey: _privateKey });
182
+ }
183
+ finally {
184
+ _privateKey.free(); // Zeroize + free the temporary; Account owns its own clone
185
+ }
71
186
  }
72
187
  catch (e) {
73
188
  throw new Error("Wrong password or invalid ciphertext");
@@ -92,7 +207,7 @@ class Account {
92
207
  }
93
208
  /**
94
209
  * Creates a PrivateKey from the provided parameters.
95
- * @param {AccountParam} params The parameters containing either a private key string or a seed
210
+ * @param {AccountParam} params The parameters containing either a private key string, PrivateKey object, or a seed
96
211
  * @returns {PrivateKey} A PrivateKey instance derived from the provided parameters
97
212
  */
98
213
  privateKeyFromParams(params) {
@@ -100,10 +215,29 @@ class Account {
100
215
  return PrivateKey.from_seed_unchecked(params.seed);
101
216
  }
102
217
  if (params.privateKey) {
103
- return PrivateKey.from_string(params.privateKey);
218
+ if (typeof params.privateKey === 'string') {
219
+ return PrivateKey.from_string(params.privateKey);
220
+ }
221
+ // Clone the PrivateKey WASM object via byte serialization to avoid
222
+ // creating an immutable JS string of the private key.
223
+ const bytes = params.privateKey.toBytesLe();
224
+ try {
225
+ return PrivateKey.fromBytesLe(bytes);
226
+ }
227
+ finally {
228
+ zeroizeBytes(bytes);
229
+ }
104
230
  }
105
231
  return new PrivateKey();
106
232
  }
233
+ /**
234
+ * Throws an error if this account has been destroyed.
235
+ */
236
+ assertNotDestroyed() {
237
+ if (this._destroyed) {
238
+ throw new Error("Account has been destroyed. Create a new Account instance.");
239
+ }
240
+ }
107
241
  /**
108
242
  * Returns the PrivateKey associated with the account.
109
243
  * @returns {PrivateKey} The private key of the account
@@ -115,6 +249,7 @@ class Account {
115
249
  * const privateKey = account.privateKey();
116
250
  */
117
251
  privateKey() {
252
+ this.assertNotDestroyed();
118
253
  return this._privateKey;
119
254
  }
120
255
  /**
@@ -128,6 +263,7 @@ class Account {
128
263
  * const viewKey = account.viewKey();
129
264
  */
130
265
  viewKey() {
266
+ this.assertNotDestroyed();
131
267
  return this._viewKey;
132
268
  }
133
269
  /**
@@ -141,6 +277,7 @@ class Account {
141
277
  * const computeKey = account.computeKey();
142
278
  */
143
279
  computeKey() {
280
+ this.assertNotDestroyed();
144
281
  return this._computeKey;
145
282
  }
146
283
  /**
@@ -154,10 +291,12 @@ class Account {
154
291
  * const address = account.address();
155
292
  */
156
293
  address() {
294
+ this.assertNotDestroyed();
157
295
  return this._address;
158
296
  }
159
297
  /**
160
- * Deep clones the Account.
298
+ * Deep clones the Account via byte serialization of the private key,
299
+ * avoiding creation of immutable JS string representations of the private key.
161
300
  * @returns {Account} A new Account instance with the same private key
162
301
  *
163
302
  * @example
@@ -167,7 +306,8 @@ class Account {
167
306
  * const clonedAccount = account.clone();
168
307
  */
169
308
  clone() {
170
- return new Account({ privateKey: this._privateKey.to_string() });
309
+ this.assertNotDestroyed();
310
+ return new Account({ privateKey: this._privateKey });
171
311
  }
172
312
  /**
173
313
  * Returns the address of the account in a string representation.
@@ -175,6 +315,7 @@ class Account {
175
315
  * @returns {string} The string representation of the account address
176
316
  */
177
317
  toString() {
318
+ this.assertNotDestroyed();
178
319
  return this.address().to_string();
179
320
  }
180
321
  /**
@@ -191,6 +332,7 @@ class Account {
191
332
  * process.env.ciphertext = ciphertext.toString();
192
333
  */
193
334
  encryptAccount(password) {
335
+ this.assertNotDestroyed();
194
336
  return this._privateKey.toCiphertext(password);
195
337
  }
196
338
  /**
@@ -220,6 +362,7 @@ class Account {
220
362
  * }
221
363
  */
222
364
  decryptRecord(ciphertext) {
365
+ this.assertNotDestroyed();
223
366
  return this._viewKey.decrypt(ciphertext);
224
367
  }
225
368
  /**
@@ -244,6 +387,7 @@ class Account {
244
387
  * const decryptedRecords = account.decryptRecords(records);
245
388
  */
246
389
  decryptRecords(ciphertexts) {
390
+ this.assertNotDestroyed();
247
391
  return ciphertexts.map((ciphertext) => this._viewKey.decrypt(ciphertext));
248
392
  }
249
393
  /**
@@ -264,6 +408,7 @@ class Account {
264
408
  * const recordViewKey = account.generateRecordViewKey(recordCiphertext);
265
409
  */
266
410
  generateRecordViewKey(recordCiphertext) {
411
+ this.assertNotDestroyed();
267
412
  if (typeof recordCiphertext === 'string') {
268
413
  recordCiphertext = RecordCiphertext.fromString(recordCiphertext);
269
414
  }
@@ -289,6 +434,7 @@ class Account {
289
434
  * const transitionViewKey = account.generateTransitionViewKey(tpk);
290
435
  */
291
436
  generateTransitionViewKey(tpk) {
437
+ this.assertNotDestroyed();
292
438
  if (typeof tpk === 'string') {
293
439
  tpk = Group.fromString(tpk);
294
440
  }
@@ -320,6 +466,7 @@ class Account {
320
466
  * }
321
467
  */
322
468
  ownsRecordCiphertext(ciphertext) {
469
+ this.assertNotDestroyed();
323
470
  if (typeof ciphertext === 'string') {
324
471
  try {
325
472
  const ciphertextObject = RecordCiphertext.fromString(ciphertext);
@@ -356,6 +503,7 @@ class Account {
356
503
  * assert(account.verify(message, signature));
357
504
  */
358
505
  sign(message) {
506
+ this.assertNotDestroyed();
359
507
  return this._privateKey.sign(message);
360
508
  }
361
509
  /**
@@ -380,8 +528,62 @@ class Account {
380
528
  * assert(account.verify(message, signature));
381
529
  */
382
530
  verify(message, signature) {
531
+ this.assertNotDestroyed();
383
532
  return this._address.verify(message, signature);
384
533
  }
534
+ /**
535
+ * Securely destroys the account by zeroizing and freeing all sensitive key material
536
+ * from WASM memory. After calling this method, the account object should not be used.
537
+ *
538
+ * This triggers the Rust-level zeroizing Drop implementation which overwrites private key,
539
+ * view key, and compute key bytes with zeros in WASM linear memory before deallocation.
540
+ *
541
+ * Note: If destroy() is never called, the FinalizationRegistry (set up by wasm-bindgen)
542
+ * will eventually trigger cleanup via GC, but the timing is non-deterministic. For security-
543
+ * sensitive applications, always call destroy() explicitly when the account is no longer needed.
544
+ *
545
+ * @example
546
+ * const account = new Account();
547
+ * // ... use account ...
548
+ * account.destroy(); // Securely cleans up key material
549
+ */
550
+ destroy() {
551
+ if (this._destroyed)
552
+ return;
553
+ this._destroyed = true;
554
+ // Free sensitive WASM objects (triggers Rust Drop -> zeroization).
555
+ // try/catch guards against double-free if FinalizationRegistry already ran.
556
+ try {
557
+ this._privateKey.free();
558
+ }
559
+ catch (_) { /* already freed */ }
560
+ try {
561
+ this._viewKey.free();
562
+ }
563
+ catch (_) { /* already freed */ }
564
+ try {
565
+ this._computeKey.free();
566
+ }
567
+ catch (_) { /* already freed */ }
568
+ // Address is public data but free it for completeness.
569
+ try {
570
+ this._address.free();
571
+ }
572
+ catch (_) { /* already freed */ }
573
+ }
574
+ /**
575
+ * Implements the Disposable interface for use with `using` declarations (ES2024+).
576
+ * Calls {@link destroy} to securely clean up key material.
577
+ *
578
+ * @example
579
+ * {
580
+ * using account = new Account();
581
+ * // ... use account ...
582
+ * } // account is automatically destroyed here
583
+ */
584
+ [Symbol.dispose]() {
585
+ this.destroy();
586
+ }
385
587
  }
386
588
 
387
589
  function detectBrowser() {
@@ -504,76 +706,6 @@ function isProveApiErrorBody(value) {
504
706
  "message" in value);
505
707
  }
506
708
 
507
- await sodium.ready;
508
- /**
509
- * Encrypt an authorization with a libsodium cryptobox public key.
510
- *
511
- * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
512
- * @param {Authorization} authorization the authorization to encrypt.
513
- *
514
- * @returns {string} the encrypted authorization in RFC 4648 standard Base64.
515
- */
516
- function encryptAuthorization(publicKey, authorization) {
517
- // Ready the cryptobox lib.
518
- return encryptMessage(publicKey, authorization.toBytesLe());
519
- }
520
- /**
521
- * Encrypt a ProvingRequest with a libsodium cryptobox public key.
522
- *
523
- * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
524
- * @param {Authorization} provingRequest the ProvingRequest to encrypt.
525
- *
526
- * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
527
- */
528
- function encryptProvingRequest(publicKey, provingRequest) {
529
- return encryptMessage(publicKey, provingRequest.toBytesLe());
530
- }
531
- /**
532
- * Encrypt a view key with a libsodium cryptobox public key.
533
- *
534
- * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
535
- * @param {ViewKey} viewKey the view key to encrypt.
536
- *
537
- * @returns {string} the encrypted view key in RFC 4648 standard Base64.
538
- */
539
- function encryptViewKey(publicKey, viewKey) {
540
- return encryptMessage(publicKey, viewKey.toBytesLe());
541
- }
542
- /**
543
- * Encrypt a record scanner registration request.
544
- *
545
- * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
546
- * @param {ViewKey} viewKey the view key to encrypt.
547
- * @param {number} start the start height of the registration request.
548
- *
549
- * @returns {string} the encrypted view key in RFC 4648 standard Base64.
550
- */
551
- function encryptRegistrationRequest(publicKey, viewKey, start) {
552
- // Turn the view key into a Uint8Array.
553
- const vk_bytes = viewKey.toBytesLe();
554
- // Create a new array to hold the original bytes and the 4-byte start height.
555
- const bytes = new Uint8Array(vk_bytes.length + 4);
556
- // Copy existing bytes.
557
- bytes.set(vk_bytes, 0);
558
- // Write the 4-byte number in LE format at the end of the array.
559
- const view = new DataView(bytes.buffer);
560
- view.setUint32(vk_bytes.length, start, true);
561
- // Encrypt the encoded bytes.
562
- return encryptMessage(publicKey, bytes);
563
- }
564
- /**
565
- * Encrypt arbitrary bytes with a libsodium cryptobox public key.
566
- *
567
- * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
568
- * @param {Uint8Array} message the bytes to encrypt.
569
- *
570
- * @returns {string} the encrypted bytes in RFC 4648 standard Base64.
571
- */
572
- function encryptMessage(publicKey, message) {
573
- const publicKeyBytes = sodium.from_base64(publicKey, sodium.base64_variants.ORIGINAL);
574
- return sodium.to_base64(sodium.crypto_box_seal(message, publicKeyBytes), sodium.base64_variants.ORIGINAL);
575
- }
576
-
577
709
  const KEY_STORE = Metadata.baseUrl();
578
710
  function convert(metadata) {
579
711
  // This looks up the method name in VerifyingKey
@@ -713,7 +845,7 @@ class AleoNetworkClient {
713
845
  else {
714
846
  this.headers = {
715
847
  // This is replaced by the actual version by a Rollup plugin
716
- "X-Aleo-SDK-Version": "0.9.16",
848
+ "X-Aleo-SDK-Version": "0.9.18",
717
849
  "X-Aleo-environment": environment(),
718
850
  };
719
851
  }
@@ -729,7 +861,7 @@ class AleoNetworkClient {
729
861
  else {
730
862
  this.headers = {
731
863
  // This is replaced by the actual version by a Rollup plugin
732
- "X-Aleo-SDK-Version": "0.9.16",
864
+ "X-Aleo-SDK-Version": "0.9.18",
733
865
  "X-Aleo-environment": environment(),
734
866
  };
735
867
  }
@@ -2420,13 +2552,13 @@ class RecordNotFoundError extends Error {
2420
2552
  Object.setPrototypeOf(this, RecordNotFoundError.prototype);
2421
2553
  }
2422
2554
  }
2423
- /** Error thrown when a record scanner request fails due to an invalid response. */
2555
+ /** Error thrown when no UUID is configured, the UUID is invalid, or a record scanner request fails due to an invalid UUID/response. */
2424
2556
  class UUIDError extends Error {
2425
2557
  uuid;
2426
2558
  filter;
2427
2559
  constructor(message, uuid, filter) {
2428
2560
  super(message);
2429
- this.name = "InvalidResponseError";
2561
+ this.name = "UUIDError";
2430
2562
  this.uuid = uuid;
2431
2563
  this.filter = filter;
2432
2564
  Object.setPrototypeOf(this, UUIDError.prototype);
@@ -2458,8 +2590,8 @@ class AleoKeyProviderParams {
2458
2590
  }
2459
2591
  }
2460
2592
  /**
2461
- * AleoKeyProvider class. Implements the KeyProvider interface. Enables the retrieval of Aleo program proving and
2462
- * verifying keys for the credits.aleo program over http from official Aleo sources and storing and retrieving function
2593
+ * AleoKeyProvider class. Implements the FunctionKeyProvider interface. Enables the retrieval of Aleo program proving and
2594
+ * verifying keys for the credits.aleo program over HTTP from official Aleo sources and storing and retrieving function
2463
2595
  * keys from a local memory cache.
2464
2596
  */
2465
2597
  class AleoKeyProvider {
@@ -2481,6 +2613,9 @@ class AleoKeyProvider {
2481
2613
  this.cache = new Map();
2482
2614
  this.cacheOption = false;
2483
2615
  }
2616
+ async keyStore() {
2617
+ return undefined;
2618
+ }
2484
2619
  /**
2485
2620
  * Use local memory to store keys
2486
2621
  *
@@ -2533,8 +2668,11 @@ class AleoKeyProvider {
2533
2668
  getKeys(keyId) {
2534
2669
  console.debug(`Checking if key exists in cache. KeyId: ${keyId}`);
2535
2670
  if (this.cache.has(keyId)) {
2536
- const [provingKeyBytes, verifyingKeyBytes] = this.cache.get(keyId);
2537
- return [ProvingKey.fromBytes(provingKeyBytes), VerifyingKey.fromBytes(verifyingKeyBytes)];
2671
+ const [provingKeyBytes, verifyingKeyBytes] = (this.cache.get(keyId));
2672
+ return [
2673
+ ProvingKey.fromBytes(provingKeyBytes),
2674
+ VerifyingKey.fromBytes(verifyingKeyBytes),
2675
+ ];
2538
2676
  }
2539
2677
  else {
2540
2678
  throw new Error("Key not found in cache.");
@@ -2566,13 +2704,15 @@ class AleoKeyProvider {
2566
2704
  let verifierUrl;
2567
2705
  let cacheKey;
2568
2706
  if ("name" in params && typeof params["name"] == "string") {
2569
- let key = CREDITS_PROGRAM_KEYS.getKey(params["name"]);
2707
+ const key = CREDITS_PROGRAM_KEYS.getKey(params["name"]);
2570
2708
  return this.fetchCreditsKeys(key);
2571
2709
  }
2572
- if ("proverUri" in params && typeof params["proverUri"] == "string") {
2710
+ if ("proverUri" in params &&
2711
+ typeof params["proverUri"] == "string") {
2573
2712
  proverUrl = params["proverUri"];
2574
2713
  }
2575
- if ("verifierUri" in params && typeof params["verifierUri"] == "string") {
2714
+ if ("verifierUri" in params &&
2715
+ typeof params["verifierUri"] == "string") {
2576
2716
  verifierUrl = params["verifierUri"];
2577
2717
  }
2578
2718
  if ("cacheKey" in params && typeof params["cacheKey"] == "string") {
@@ -2621,20 +2761,26 @@ class AleoKeyProvider {
2621
2761
  }
2622
2762
  const value = this.cache.get(cacheKey);
2623
2763
  if (typeof value !== "undefined") {
2624
- return [ProvingKey.fromBytes(value[0]), VerifyingKey.fromBytes(value[1])];
2764
+ return [
2765
+ ProvingKey.fromBytes(value[0]),
2766
+ VerifyingKey.fromBytes(value[1]),
2767
+ ];
2625
2768
  }
2626
2769
  else {
2627
2770
  console.debug("Fetching proving keys from url " + proverUrl);
2628
- const provingKey = ProvingKey.fromBytes(await this.fetchBytes(proverUrl));
2771
+ const provingKey = (ProvingKey.fromBytes(await this.fetchBytes(proverUrl)));
2629
2772
  console.debug("Fetching verifying keys " + verifierUrl);
2630
2773
  const verifyingKey = (await this.getVerifyingKey(verifierUrl));
2631
- this.cache.set(cacheKey, [provingKey.toBytes(), verifyingKey.toBytes()]);
2774
+ this.cache.set(cacheKey, [
2775
+ provingKey.toBytes(),
2776
+ verifyingKey.toBytes(),
2777
+ ]);
2632
2778
  return [provingKey, verifyingKey];
2633
2779
  }
2634
2780
  }
2635
2781
  else {
2636
2782
  // If cache is disabled, fetch the keys and return them
2637
- const provingKey = ProvingKey.fromBytes(await this.fetchBytes(proverUrl));
2783
+ const provingKey = (ProvingKey.fromBytes(await this.fetchBytes(proverUrl)));
2638
2784
  const verifyingKey = (await this.getVerifyingKey(verifierUrl));
2639
2785
  return [provingKey, verifyingKey];
2640
2786
  }
@@ -2664,12 +2810,12 @@ class AleoKeyProvider {
2664
2810
  }
2665
2811
  else {
2666
2812
  console.debug("Fetching proving keys from url " + proverUrl);
2667
- const provingKey = ProvingKey.fromBytes(await this.fetchBytes(proverUrl));
2813
+ const provingKey = (ProvingKey.fromBytes(await this.fetchBytes(proverUrl)));
2668
2814
  return provingKey;
2669
2815
  }
2670
2816
  }
2671
2817
  else {
2672
- const provingKey = ProvingKey.fromBytes(await this.fetchBytes(proverUrl));
2818
+ const provingKey = (ProvingKey.fromBytes(await this.fetchBytes(proverUrl)));
2673
2819
  return provingKey;
2674
2820
  }
2675
2821
  }
@@ -2681,7 +2827,7 @@ class AleoKeyProvider {
2681
2827
  try {
2682
2828
  if (!this.cache.has(key.locator) || !this.cacheOption) {
2683
2829
  const verifying_key = key.verifyingKey();
2684
- const proving_key = await this.fetchProvingKey(key.prover, key.locator);
2830
+ const proving_key = (await this.fetchProvingKey(key.prover, key.locator));
2685
2831
  if (this.cacheOption) {
2686
2832
  this.cache.set(CREDITS_PROGRAM_KEYS.getKey(key.name).locator, [proving_key.toBytes(), verifying_key.toBytes()]);
2687
2833
  }
@@ -2689,7 +2835,10 @@ class AleoKeyProvider {
2689
2835
  }
2690
2836
  else {
2691
2837
  const keyPair = this.cache.get(key.locator);
2692
- return [ProvingKey.fromBytes(keyPair[0]), VerifyingKey.fromBytes(keyPair[1])];
2838
+ return [
2839
+ ProvingKey.fromBytes(keyPair[0]),
2840
+ VerifyingKey.fromBytes(keyPair[1]),
2841
+ ];
2693
2842
  }
2694
2843
  }
2695
2844
  catch (error) {
@@ -2839,7 +2988,7 @@ class AleoKeyProvider {
2839
2988
  catch (e) {
2840
2989
  /// If that fails, try to fetch the verifying key from the network as bytes
2841
2990
  try {
2842
- return VerifyingKey.fromBytes(await this.fetchBytes(verifierUri));
2991
+ return (VerifyingKey.fromBytes(await this.fetchBytes(verifierUri)));
2843
2992
  }
2844
2993
  catch (inner) {
2845
2994
  throw new Error("Invalid verifying key. Error: " + inner.message);
@@ -2852,6 +3001,156 @@ class AleoKeyProvider {
2852
3001
  }
2853
3002
  }
2854
3003
 
3004
+ /**
3005
+ * Error thrown when there is a mismatch between expected and actual key metadata.
3006
+ * This can occur during verification of either the checksum or size of a key.
3007
+ *
3008
+ * @extends Error
3009
+ */
3010
+ class KeyVerificationError extends Error {
3011
+ locator;
3012
+ field;
3013
+ expected;
3014
+ actual;
3015
+ /**
3016
+ * Creates a new KeyVerificationError instance (error.name is "ChecksumMismatchError").
3017
+ *
3018
+ * @param {string} locator - The key locator where the mismatch occurred.
3019
+ * @param {"checksum" | "size"} field - The field that failed verification (either "checksum" or "size").
3020
+ * @param {string} expected - The expected value of the field.
3021
+ * @param {string} actual - The actual value encountered.
3022
+ */
3023
+ constructor(locator, field, expected, actual) {
3024
+ super(`Key verification ${locator} ${field} mismatch: expected ${expected}, got ${actual}`);
3025
+ this.locator = locator;
3026
+ this.field = field;
3027
+ this.expected = expected;
3028
+ this.actual = actual;
3029
+ this.name = "ChecksumMismatchError";
3030
+ Object.setPrototypeOf(this, KeyVerificationError.prototype);
3031
+ }
3032
+ }
3033
+ /**
3034
+ * Computes the SHA-256 checksum of a given set of bytes.
3035
+ *
3036
+ * @param {Uint8Array} bytes - The bytes to compute the checksum of.
3037
+ */
3038
+ async function sha256Hex(bytes) {
3039
+ const hash = await crypto.subtle.digest("SHA-256", bytes);
3040
+ return Array.from(new Uint8Array(hash))
3041
+ .map((b) => b.toString(16).padStart(2, "0"))
3042
+ .join("");
3043
+ }
3044
+
3045
+ /**
3046
+ * In-memory implementation of KeyVerifier that stores and verifies key fingerprints.
3047
+ * Provides functionality to compute and verify cryptographic checksums of keys, storing them
3048
+ * in memory for subsequent verification. This implementation is primarily used for testing
3049
+ * and development purposes where persistence is not required.
3050
+ *
3051
+ * Key features:
3052
+ * - Computes SHA-256 checksums and sizes for key bytes.
3053
+ * - Stores key fingerprints in memory using string locators.
3054
+ * - Verifies key bytes against stored or provided fingerprints.
3055
+ *
3056
+ * @implements {KeyVerifier}
3057
+ */
3058
+ class MemKeyVerifier {
3059
+ keyStore = {};
3060
+ /**
3061
+ * Computes and optionally stores key metadata. If a keyFingerprint is provided, this function will verify the computed checksum against it before storing it.
3062
+ *
3063
+ * @param {KeyMetadata} keyMetadata - Object containing key bytes and optional verification data.
3064
+ * @throws {KeyVerificationError} When provided keyFingerprint doesn't match computed values.
3065
+ * @returns {Promise<KeyFingerprint>} Computed key metadata.
3066
+ */
3067
+ async computeKeyMetadata(keyMetadata) {
3068
+ // Compute the metadata from the key bytes
3069
+ const computedFingerprint = {
3070
+ checksum: await sha256Hex(keyMetadata.keyBytes),
3071
+ size: keyMetadata.keyBytes.length
3072
+ };
3073
+ // If a KeyFingerprint is provided, verify it matches computed values.
3074
+ if (keyMetadata.fingerprint) {
3075
+ if (keyMetadata.fingerprint.size !== computedFingerprint.size) {
3076
+ throw new KeyVerificationError(keyMetadata.locator ? keyMetadata.locator : "", "size", String(keyMetadata.fingerprint.size), String(computedFingerprint.size));
3077
+ }
3078
+ if (keyMetadata.fingerprint.checksum !== computedFingerprint.checksum) {
3079
+ throw new KeyVerificationError(keyMetadata.locator ? keyMetadata.locator : "", "checksum", keyMetadata.fingerprint.checksum, computedFingerprint.checksum);
3080
+ }
3081
+ }
3082
+ // If locator is provided, store only the fingerprint
3083
+ if (keyMetadata.locator) {
3084
+ this.keyStore[keyMetadata.locator] = computedFingerprint;
3085
+ }
3086
+ return computedFingerprint;
3087
+ }
3088
+ /**
3089
+ * Verifies key bytes against stored or provided metadata. Follows a priority verification scheme:
3090
+ * 1. If KeyFingerprint is provided in the metadata, this method verifies against that first.
3091
+ * 2. If a locator is provided, attempts to verify against stored fingerprint.
3092
+ * 3. If neither is available, throws an error.
3093
+ *
3094
+ * @param {KeyMetadata} keyMetadata - Object containing the key bytes and optional verification metadata.
3095
+ * @throws {Error} When neither fingerprint nor valid locator is provided for verification.
3096
+ * @throws {KeyVerificationError} When size or checksum verification fails.
3097
+ * @returns {Promise<void>} Promise that resolves when verification succeeds.
3098
+ */
3099
+ async verifyKeyBytes(keyMetadata) {
3100
+ if (!keyMetadata.keyBytes) {
3101
+ throw new Error("Key bytes must be provided for verification.");
3102
+ }
3103
+ // Compute the fingerprint for the provided bytes.
3104
+ const computedFingerprint = await this.computeKeyMetadata({
3105
+ keyBytes: keyMetadata.keyBytes
3106
+ });
3107
+ // Determine which fingerprint to verify against.
3108
+ let fingerprintToVerify;
3109
+ if (keyMetadata.fingerprint) {
3110
+ // If a key fingerprint is provided, use it.
3111
+ fingerprintToVerify = keyMetadata.fingerprint;
3112
+ }
3113
+ else if (keyMetadata.locator) {
3114
+ // Otherwise try to get stored fingerprint by locator.
3115
+ fingerprintToVerify = this.keyStore[keyMetadata.locator];
3116
+ }
3117
+ if (!fingerprintToVerify) {
3118
+ throw new Error("Either fingerprint or a valid locator must be provided for verification.");
3119
+ }
3120
+ // Verify the key size.
3121
+ if (fingerprintToVerify.size !== computedFingerprint.size) {
3122
+ throw new KeyVerificationError(keyMetadata.locator || "", "size", String(fingerprintToVerify.size), String(computedFingerprint.size));
3123
+ }
3124
+ // Verify the key checksum.
3125
+ if (fingerprintToVerify.checksum !== computedFingerprint.checksum) {
3126
+ throw new KeyVerificationError(keyMetadata.locator || "", "checksum", fingerprintToVerify.checksum, computedFingerprint.checksum);
3127
+ }
3128
+ }
3129
+ }
3130
+
3131
+ /**
3132
+ * Error thrown when a key locator is invalid for filesystem use.
3133
+ * Used to prevent path traversal and other filesystem injection when deriving paths from locators.
3134
+ *
3135
+ * @extends Error
3136
+ */
3137
+ class InvalidLocatorError extends Error {
3138
+ locator;
3139
+ reason;
3140
+ /**
3141
+ * @param message - Human-readable description of the validation failure.
3142
+ * @param locator - The invalid locator string that failed validation.
3143
+ * @param reason - Machine-readable reason code for the failure.
3144
+ */
3145
+ constructor(message, locator, reason) {
3146
+ super(message);
3147
+ this.locator = locator;
3148
+ this.reason = reason;
3149
+ this.name = "InvalidLocatorError";
3150
+ Object.setPrototypeOf(this, InvalidLocatorError.prototype);
3151
+ }
3152
+ }
3153
+
2855
3154
  /**
2856
3155
  * Search parameters for the offline key provider. This class implements the KeySearchParams interface and includes
2857
3156
  * a convenience method for creating a new instance of this class for each function of the credits.aleo program.
@@ -2891,7 +3190,7 @@ class OfflineSearchParams {
2891
3190
  return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.bond_validator.locator, true);
2892
3191
  }
2893
3192
  /**
2894
- * Create a new OfflineSearchParams instance for the claim_unbond_public function of the
3193
+ * Create a new OfflineSearchParams instance for the claim_unbond_public function of the credits.aleo program.
2895
3194
  */
2896
3195
  static claimUnbondPublicKeyParams() {
2897
3196
  return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.claim_unbond_public.locator, true);
@@ -3025,6 +3324,9 @@ class OfflineKeyProvider {
3025
3324
  constructor() {
3026
3325
  this.cache = new Map();
3027
3326
  }
3327
+ keyStore() {
3328
+ return Promise.resolve(undefined);
3329
+ }
3028
3330
  /**
3029
3331
  * Get bond_public function keys from the credits.aleo program. The keys must be cached prior to calling this
3030
3332
  * method for it to work.
@@ -4005,6 +4307,56 @@ class RecordScanner {
4005
4307
  return this.handleRequestError(err);
4006
4308
  }
4007
4309
  }
4310
+ /**
4311
+ * Remove all local scanner state associated with the given UUID (stored uuid, viewKeys entry, account if it matches).
4312
+ * Called after a successful revoke so the scanner does not retain view keys or account for a revoked registration.
4313
+ */
4314
+ clearLocalStateForUuid(uuidStr) {
4315
+ if (this.uuid != null && this.uuid.toString() === uuidStr) {
4316
+ this.uuid = undefined;
4317
+ }
4318
+ if (this.viewKeys != null) {
4319
+ delete this.viewKeys[uuidStr];
4320
+ if (Object.keys(this.viewKeys).length === 0) {
4321
+ this.viewKeys = undefined;
4322
+ }
4323
+ }
4324
+ if (this.account != null && this.computeUUID(this.account.viewKey()).toString() === uuidStr) {
4325
+ this.account = undefined;
4326
+ }
4327
+ }
4328
+ /**
4329
+ * Revoke the account registration with the record scanning service (POST /revoke). On success, also removes
4330
+ * all local state for that UUID: the stored UUID (if it matches), the view key for that UUID, and the
4331
+ * account (if its view key corresponds to that UUID).
4332
+ *
4333
+ * @param {string | Field | undefined} uuid The UUID to revoke. If omitted, uses the UUID configured on the scanner.
4334
+ * @returns {Promise<RevokeResult>} `{ ok: true, data: { status } }` on success, or `{ ok: false, status, error }` on failure.
4335
+ * @throws {UUIDError} When no UUID is configured and none provided, or when the UUID string is invalid.
4336
+ */
4337
+ async revoke(uuid) {
4338
+ const resolvedUuid = uuid ?? this.uuid;
4339
+ if (!resolvedUuid) {
4340
+ throw new UUIDError("No UUID configured for the record scanner and no UUID provided.");
4341
+ }
4342
+ const uuidStr = typeof resolvedUuid === "string" ? resolvedUuid : resolvedUuid.toString();
4343
+ if (!this.uuidIsValid(uuidStr)) {
4344
+ throw new UUIDError(`UUID provided ${uuidStr} is invalid`, uuidStr);
4345
+ }
4346
+ try {
4347
+ const response = await this.request(new Request(`${this.url}/revoke`, {
4348
+ method: "POST",
4349
+ headers: { "Content-Type": "application/json" },
4350
+ body: JSON.stringify(uuidStr),
4351
+ }));
4352
+ const data = await response.json();
4353
+ this.clearLocalStateForUuid(uuidStr);
4354
+ return { ok: true, data };
4355
+ }
4356
+ catch (err) {
4357
+ return this.handleRequestError(err);
4358
+ }
4359
+ }
4008
4360
  /**
4009
4361
  * Get encrypted records from the record scanning service. This is a safe variant of /records/encrypted that returns
4010
4362
  * a result instead of throwing on HTTP error.
@@ -4164,8 +4516,7 @@ class RecordScanner {
4164
4516
  // Throw an error if none could be found, otherwise set the UUID on the filter with either the UUID configured
4165
4517
  // within the filter or the UUID configured within the scanner.
4166
4518
  if (!uuid) {
4167
- throw new Error("Error while using the record scanner. UUID is not set on the scanner and the UUID " +
4168
- "provided in the record filter was invalid.");
4519
+ throw new UUIDError("Error while using the record scanner. UUID is not set on the scanner and the UUID provided in the record filter was invalid.", undefined, filter);
4169
4520
  }
4170
4521
  filter.uuid = uuid;
4171
4522
  // Inner request used to retry once after 422 re-register without duplicating logic.
@@ -5240,8 +5591,8 @@ class ProgramManager {
5240
5591
  edition = await this.networkClient.getLatestProgramEdition(programName);
5241
5592
  }
5242
5593
  catch (e) {
5243
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
5244
- edition = 1;
5594
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
5595
+ edition = 0;
5245
5596
  }
5246
5597
  }
5247
5598
  // Get the private key from the account if it is not provided in the parameters
@@ -5524,8 +5875,8 @@ class ProgramManager {
5524
5875
  edition = await this.networkClient.getLatestProgramEdition(programName);
5525
5876
  }
5526
5877
  catch (e) {
5527
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
5528
- edition = 1;
5878
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
5879
+ edition = 0;
5529
5880
  }
5530
5881
  }
5531
5882
  // Resolve the program imports if they exist.
@@ -5617,8 +5968,8 @@ class ProgramManager {
5617
5968
  edition = await this.networkClient.getLatestProgramEdition(programName);
5618
5969
  }
5619
5970
  catch (e) {
5620
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
5621
- edition = 1;
5971
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
5972
+ edition = 0;
5622
5973
  }
5623
5974
  }
5624
5975
  // Build and return an `Authorization` for the desired function.
@@ -5687,8 +6038,8 @@ class ProgramManager {
5687
6038
  edition = await this.networkClient.getLatestProgramEdition(programName);
5688
6039
  }
5689
6040
  catch (e) {
5690
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
5691
- edition = 1;
6041
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
6042
+ edition = 0;
5692
6043
  }
5693
6044
  }
5694
6045
  // Get the private key from the account if it is not provided in the parameters.
@@ -7073,7 +7424,7 @@ class ProgramManager {
7073
7424
  * import { AleoKeyProvider, getOrInitConsensusVersionTestHeights, ProgramManager, NetworkRecordProvider } from "@provablehq/sdk/mainnet.js";
7074
7425
  *
7075
7426
  * // Initialize the development consensus heights in order to work with devnode.
7076
- * getOrInitConsensusVersionTestHeights("0,1,2,3,4,5,6,7,8,9,10,11");
7427
+ * getOrInitConsensusVersionTestHeights("0,1,2,3,4,5,6,7,8,9,10,11,12");
7077
7428
  *
7078
7429
  * // Create a new NetworkClient and RecordProvider.
7079
7430
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
@@ -7205,7 +7556,7 @@ class ProgramManager {
7205
7556
  * import { ProgramManager, NetworkRecordProvider, getOrInitConsensusVersionTestHeights } from "@provablehq/sdk/mainnet.js";
7206
7557
  *
7207
7558
  * // Initialize the development consensus heights in order to work with a local devnode.
7208
- * getOrInitConsensusVersionTestHeights("0,1,2,3,4,5,6,7,8,9,10,11");
7559
+ * getOrInitConsensusVersionTestHeights("0,1,2,3,4,5,6,7,8,9,10,11,12");
7209
7560
  *
7210
7561
  * // Create a new NetworkClient, and RecordProvider
7211
7562
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
@@ -7418,5 +7769,5 @@ async function initializeWasm() {
7418
7769
  console.warn("initializeWasm is deprecated, you no longer need to use it");
7419
7770
  }
7420
7771
 
7421
- export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoNetworkClient, BlockHeightSearch, CREDITS_PROGRAM_KEYS, DecryptionNotEnabledError, KEY_STORE, NetworkRecordProvider, OfflineKeyProvider, OfflineSearchParams, PRIVATE_TO_PUBLIC_TRANSFER, PRIVATE_TRANSFER, PRIVATE_TRANSFER_TYPES, PUBLIC_TO_PRIVATE_TRANSFER, PUBLIC_TRANSFER, PUBLIC_TRANSFER_AS_SIGNER, ProgramManager, RECORD_DOMAIN, RecordNotFoundError, RecordScanner, RecordScannerRequestError, SealanceMerkleTree, UUIDError, VALID_TRANSFER_TYPES, ViewKeyNotStoredError, encryptAuthorization, encryptProvingRequest, encryptRegistrationRequest, encryptViewKey, initializeWasm, isProveApiErrorBody, isProvingResponse, logAndThrow };
7772
+ export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoNetworkClient, BlockHeightSearch, CREDITS_PROGRAM_KEYS, KeyVerificationError as ChecksumMismatchError, DecryptionNotEnabledError, InvalidLocatorError, KEY_STORE, KeyVerificationError, MemKeyVerifier, NetworkRecordProvider, OfflineKeyProvider, OfflineSearchParams, PRIVATE_TO_PUBLIC_TRANSFER, PRIVATE_TRANSFER, PRIVATE_TRANSFER_TYPES, PUBLIC_TO_PRIVATE_TRANSFER, PUBLIC_TRANSFER, PUBLIC_TRANSFER_AS_SIGNER, ProgramManager, RECORD_DOMAIN, RecordNotFoundError, RecordScanner, RecordScannerRequestError, SealanceMerkleTree, UUIDError, VALID_TRANSFER_TYPES, ViewKeyNotStoredError, encryptAuthorization, encryptProvingRequest, encryptRegistrationRequest, encryptViewKey, initializeWasm, isProveApiErrorBody, isProvingResponse, logAndThrow, sha256Hex, zeroizeBytes };
7422
7773
  //# sourceMappingURL=browser.js.map