@provablehq/sdk 0.9.16-rc → 0.9.17

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 (73) hide show
  1. package/dist/mainnet/account.d.ts +18 -3
  2. package/dist/mainnet/browser.d.ts +26 -7
  3. package/dist/mainnet/browser.js +1198 -248
  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 +207 -13
  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/{testnet/keys/provider/function-key-provider.d.ts → mainnet/keys/provider/memory.d.ts} +14 -180
  10. package/dist/{testnet/keys/provider/offline-key-provider.d.ts → mainnet/keys/provider/offline.d.ts} +4 -4
  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/cryptoBoxPubkey.d.ts +4 -0
  14. package/dist/mainnet/models/encryptedProvingRequest.d.ts +4 -0
  15. package/dist/mainnet/models/provingResponse.d.ts +48 -2
  16. package/dist/mainnet/models/record-scanner/encryptedRecordsResult.d.ts +7 -0
  17. package/dist/mainnet/models/record-scanner/encryptedRegistrationRequest.d.ts +8 -0
  18. package/dist/mainnet/models/record-scanner/error.d.ts +47 -0
  19. package/dist/mainnet/models/record-scanner/ownedFilter.d.ts +0 -2
  20. package/dist/mainnet/models/record-scanner/ownedRecordsResult.d.ts +13 -0
  21. package/dist/mainnet/models/record-scanner/registrationResponse.d.ts +0 -2
  22. package/dist/mainnet/models/record-scanner/registrationResult.d.ts +9 -0
  23. package/dist/mainnet/models/record-scanner/revokeResult.d.ts +17 -0
  24. package/dist/mainnet/models/record-scanner/serialNumbersResult.d.ts +15 -0
  25. package/dist/mainnet/models/record-scanner/statusResult.d.ts +13 -0
  26. package/dist/mainnet/models/record-scanner/tagsResult.d.ts +12 -0
  27. package/dist/mainnet/network-client.d.ts +81 -35
  28. package/dist/mainnet/node.js +345 -75
  29. package/dist/mainnet/node.js.map +1 -1
  30. package/dist/mainnet/program-manager.d.ts +54 -48
  31. package/dist/mainnet/record-provider.d.ts +7 -7
  32. package/dist/mainnet/record-scanner.d.ts +247 -31
  33. package/dist/mainnet/security.d.ts +38 -0
  34. package/dist/mainnet/utils.d.ts +1 -0
  35. package/dist/testnet/account.d.ts +18 -3
  36. package/dist/testnet/browser.d.ts +26 -7
  37. package/dist/testnet/browser.js +1198 -248
  38. package/dist/testnet/browser.js.map +1 -1
  39. package/dist/testnet/keys/keystore/error.d.ts +23 -0
  40. package/dist/testnet/keys/keystore/file.d.ts +207 -13
  41. package/dist/testnet/keys/keystore/interface.d.ts +85 -0
  42. package/dist/testnet/keys/provider/interface.d.ts +170 -0
  43. package/dist/{mainnet/keys/provider/function-key-provider.d.ts → testnet/keys/provider/memory.d.ts} +14 -180
  44. package/dist/{mainnet/keys/provider/offline-key-provider.d.ts → testnet/keys/provider/offline.d.ts} +4 -4
  45. package/dist/testnet/keys/verifier/interface.d.ts +70 -0
  46. package/dist/testnet/keys/verifier/memory.d.ts +37 -0
  47. package/dist/testnet/models/cryptoBoxPubkey.d.ts +4 -0
  48. package/dist/testnet/models/encryptedProvingRequest.d.ts +4 -0
  49. package/dist/testnet/models/provingResponse.d.ts +48 -2
  50. package/dist/testnet/models/record-scanner/encryptedRecordsResult.d.ts +7 -0
  51. package/dist/testnet/models/record-scanner/encryptedRegistrationRequest.d.ts +8 -0
  52. package/dist/testnet/models/record-scanner/error.d.ts +47 -0
  53. package/dist/testnet/models/record-scanner/ownedFilter.d.ts +0 -2
  54. package/dist/testnet/models/record-scanner/ownedRecordsResult.d.ts +13 -0
  55. package/dist/testnet/models/record-scanner/registrationResponse.d.ts +0 -2
  56. package/dist/testnet/models/record-scanner/registrationResult.d.ts +9 -0
  57. package/dist/testnet/models/record-scanner/revokeResult.d.ts +17 -0
  58. package/dist/testnet/models/record-scanner/serialNumbersResult.d.ts +15 -0
  59. package/dist/testnet/models/record-scanner/statusResult.d.ts +13 -0
  60. package/dist/testnet/models/record-scanner/tagsResult.d.ts +12 -0
  61. package/dist/testnet/network-client.d.ts +81 -35
  62. package/dist/testnet/node.js +345 -75
  63. package/dist/testnet/node.js.map +1 -1
  64. package/dist/testnet/program-manager.d.ts +54 -48
  65. package/dist/testnet/record-provider.d.ts +7 -7
  66. package/dist/testnet/record-scanner.d.ts +247 -31
  67. package/dist/testnet/security.d.ts +38 -0
  68. package/dist/testnet/utils.d.ts +1 -0
  69. package/package.json +4 -3
  70. package/dist/mainnet/keys/keystore/keystore.d.ts +0 -81
  71. package/dist/mainnet/keys/keystore/memory.d.ts +0 -8
  72. package/dist/testnet/keys/keystore/keystore.d.ts +0 -81
  73. package/dist/testnet/keys/keystore/memory.d.ts +0 -8
@@ -1,6 +1,7 @@
1
1
  import 'core-js/proposals/json-parse-with-source.js';
2
2
  import { ViewKey, ComputeKey, Address, PrivateKeyCiphertext, PrivateKey, RecordCiphertext, EncryptionToolkit, Group, Metadata, VerifyingKey, Program, Plaintext, Transaction, ProvingRequest, ProvingKey, RecordPlaintext, Field, Poseidon4, ProgramManager as ProgramManager$1, verifyFunctionExecution } from '@provablehq/wasm/mainnet.js';
3
3
  export { Address, Authorization, BHP1024, BHP256, BHP512, BHP768, Boolean, Ciphertext, ComputeKey, EncryptionToolkit, ExecutionRequest, ExecutionResponse, Field, Execution as FunctionExecution, GraphKey, Group, I128, I16, I32, I64, I8, OfflineQuery, Pedersen128, Pedersen64, Plaintext, Poseidon2, Poseidon4, Poseidon8, PrivateKey, PrivateKeyCiphertext, Program, ProgramManager as ProgramManagerBase, ProvingKey, ProvingRequest, RecordCiphertext, RecordPlaintext, Scalar, Signature, Transaction, Transition, U128, U16, U32, U64, U8, VerifyingKey, ViewKey, getOrInitConsensusVersionTestHeights, initThreadPool, verifyFunctionExecution } from '@provablehq/wasm/mainnet.js';
4
+ import sodium from 'libsodium-wrappers';
4
5
  import { bech32m } from '@scure/base';
5
6
 
6
7
  /**
@@ -72,6 +73,23 @@ class Account {
72
73
  throw new Error("Wrong password or invalid ciphertext");
73
74
  }
74
75
  }
76
+ /**
77
+ * Validates whether the given input is a valid Aleo address.
78
+ * @param {string | Uint8Array} address The address to validate, either as a string or bytes
79
+ * @returns {boolean} True if the address is valid, false otherwise
80
+ *
81
+ * @example
82
+ * import { Account } from "@provablehq/sdk/testnet.js";
83
+ *
84
+ * const isValid = Account.isValidAddress("aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px");
85
+ * console.log(isValid); // true
86
+ *
87
+ * const isInvalid = Account.isValidAddress("invalid_address");
88
+ * console.log(isInvalid); // false
89
+ */
90
+ static isValidAddress(address) {
91
+ return Address.isValid(address);
92
+ }
75
93
  /**
76
94
  * Creates a PrivateKey from the provided parameters.
77
95
  * @param {AccountParam} params The parameters containing either a private key string or a seed
@@ -186,7 +204,7 @@ class Account {
186
204
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/testnet.js";
187
205
  *
188
206
  * // Create a connection to the Aleo network and an account
189
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
207
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
190
208
  * const account = Account.fromCiphertext(process.env.ciphertext!, process.env.password!);
191
209
  *
192
210
  * // Get the record ciphertexts from a transaction.
@@ -215,7 +233,7 @@ class Account {
215
233
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/testnet.js";
216
234
  *
217
235
  * // Create a connection to the Aleo network and an account
218
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
236
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
219
237
  * const account = Account.fromCiphertext(process.env.ciphertext!, process.env.password!);
220
238
  *
221
239
  * // Get the record ciphertexts from a transaction.
@@ -286,7 +304,7 @@ class Account {
286
304
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/testnet.js";
287
305
  *
288
306
  * // Create a connection to the Aleo network and an account
289
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
307
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
290
308
  * const account = Account.fromCiphertext(process.env.ciphertext!, process.env.password!);
291
309
  *
292
310
  * // Get the record ciphertexts from a transaction and check ownership of them.
@@ -387,6 +405,11 @@ function detectBrowser() {
387
405
  return "browser";
388
406
  }
389
407
  }
408
+ function isNode() {
409
+ return typeof process !== "undefined" &&
410
+ process.versions != null &&
411
+ process.versions.node != null;
412
+ }
390
413
  function environment() {
391
414
  if ((typeof process !== 'undefined') &&
392
415
  (process.release?.name === 'node')) {
@@ -466,6 +489,91 @@ async function retryWithBackoff(fn, { maxAttempts = 5, baseDelay = 100, jitter,
466
489
  throw new Error("retryWithBackoff: unreachable");
467
490
  }
468
491
 
492
+ /** Type guard: value is a ProvingResponse. */
493
+ function isProvingResponse(value) {
494
+ return (typeof value === "object" &&
495
+ value !== null &&
496
+ "transaction" in value &&
497
+ "broadcast_result" in value &&
498
+ typeof value.broadcast_result === "object");
499
+ }
500
+ /** Type guard: value is a ProveApiErrorBody. */
501
+ function isProveApiErrorBody(value) {
502
+ return (typeof value === "object" &&
503
+ value !== null &&
504
+ "message" in value);
505
+ }
506
+
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
+
469
577
  const KEY_STORE = Metadata.baseUrl();
470
578
  function convert(metadata) {
471
579
  // This looks up the method name in VerifyingKey
@@ -579,7 +687,7 @@ const FIVE_MINUTES = 5 * 60 * 1000; // 5 minutes in milliseconds
579
687
  * const account = Account.fromCiphertext(process.env.ciphertext, process.env.password);
580
688
  * const apiKey = process.env.apiKey;
581
689
  * const consumerId = process.env.consumerId;
582
- * const publicNetworkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined, account);
690
+ * const publicNetworkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined, account);
583
691
  */
584
692
  class AleoNetworkClient {
585
693
  host;
@@ -591,18 +699,37 @@ class AleoNetworkClient {
591
699
  apiKey;
592
700
  consumerId;
593
701
  jwtData;
702
+ proverUri;
703
+ recordScannerUri;
594
704
  constructor(host, options) {
595
705
  this.host = host + "/mainnet";
596
706
  this.network = "mainnet";
597
707
  this.ctx = {};
598
708
  this.verboseErrors = true;
599
- if (options && options.headers) {
600
- this.headers = options.headers;
709
+ if (options) {
710
+ if (options.headers) {
711
+ this.headers = options.headers;
712
+ }
713
+ else {
714
+ this.headers = {
715
+ // This is replaced by the actual version by a Rollup plugin
716
+ "X-Aleo-SDK-Version": "0.9.17",
717
+ "X-Aleo-environment": environment(),
718
+ };
719
+ }
720
+ // If a prover uri was specified, set the prover uri.
721
+ if (options.proverUri) {
722
+ this.proverUri = options.proverUri + "/mainnet";
723
+ }
724
+ // If a record scanner uri was specified, set the record scanner uri.
725
+ if (options.recordScannerUri) {
726
+ this.recordScannerUri = options.recordScannerUri + "/mainnet";
727
+ }
601
728
  }
602
729
  else {
603
730
  this.headers = {
604
731
  // This is replaced by the actual version by a Rollup plugin
605
- "X-Aleo-SDK-Version": "0.9.16-rc",
732
+ "X-Aleo-SDK-Version": "0.9.17",
606
733
  "X-Aleo-environment": environment(),
607
734
  };
608
735
  }
@@ -614,7 +741,7 @@ class AleoNetworkClient {
614
741
  * @example
615
742
  * import { Account, AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
616
743
  *
617
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1");
744
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
618
745
  * const account = new Account();
619
746
  * networkClient.setAccount(account);
620
747
  */
@@ -642,11 +769,45 @@ class AleoNetworkClient {
642
769
  * const networkClient = new AleoNetworkClient("http://0.0.0.0:3030", undefined);
643
770
  *
644
771
  * // Set the host to a public node.
645
- * networkClient.setHost("http://api.explorer.provable.com/v1");
772
+ * networkClient.setHost("https://api.provable.com/v2");
646
773
  */
647
774
  setHost(host) {
648
775
  this.host = host + "/mainnet";
649
776
  }
777
+ /**
778
+ * Set a new uri for a remote prover.
779
+ *
780
+ * @param {string} proverUri The uri of the remote prover.
781
+ *
782
+ * @example
783
+ * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
784
+ *
785
+ * // Create a networkClient that connects to the provable explorer api.
786
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
787
+ *
788
+ * // Set the prover uri.
789
+ * networkClient.setProverUri("https://prover.provable.prove");
790
+ */
791
+ setProverUri(proverUri) {
792
+ this.proverUri = proverUri + "/mainnet";
793
+ }
794
+ /**
795
+ * Set a new uri for a remote record scanner.
796
+ *
797
+ * @param {string} recordScannerUri The uri of the remote record scanner.
798
+ *
799
+ * @example
800
+ * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
801
+ *
802
+ * // Create a networkClient that connects to the provable explorer api.
803
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
804
+ *
805
+ * // Set the record scanner uri.
806
+ * networkClient.setRecordScannerUri("https://scanner.provable.scan");
807
+ */
808
+ setRecordScannerUri(recordScannerUri) {
809
+ this.recordScannerUri = recordScannerUri + "/mainnet";
810
+ }
650
811
  /**
651
812
  * Set verbose errors to true or false for the `AleoNetworkClient`. When set to true, if `submitTransaction` fails, the failure responses will report descriptive information as to why the transaction failed.
652
813
  *
@@ -753,7 +914,7 @@ class AleoNetworkClient {
753
914
  * const account = Account.fromCiphertext(process.env.ciphertext, process.env.password);
754
915
  *
755
916
  * // Create a network client.
756
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
917
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
757
918
  * networkClient.setAccount(account);
758
919
  *
759
920
  * // Find specific amounts
@@ -976,7 +1137,7 @@ class AleoNetworkClient {
976
1137
  * const account = Account.fromCiphertext(process.env.ciphertext, process.env.password);
977
1138
  *
978
1139
  * // Create a network client and set an account to search for records with.
979
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1140
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
980
1141
  * networkClient.setAccount(account);
981
1142
  *
982
1143
  * // Find specific amounts
@@ -1032,7 +1193,7 @@ class AleoNetworkClient {
1032
1193
  * @example
1033
1194
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1034
1195
  *
1035
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1196
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1036
1197
  * const block = networkClient.getBlockByHash("ab19dklwl9vp63zu3hwg57wyhvmqf92fx5g8x0t6dr72py8r87pxupqfne5t9");
1037
1198
  */
1038
1199
  async getBlockByHash(blockHash) {
@@ -1090,7 +1251,7 @@ class AleoNetworkClient {
1090
1251
  * import { AleoNetworkClient } from "@provablehq/sdk/testnet.js";
1091
1252
  *
1092
1253
  * // Get the transaction ID of the deployment transaction for a program.
1093
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1254
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1094
1255
  * const transactionId = networkClient.getDeploymentTransactionIDForProgram("hello_hello.aleo");
1095
1256
  *
1096
1257
  * // Get the transaction data for the deployment transaction.
@@ -1125,7 +1286,7 @@ class AleoNetworkClient {
1125
1286
  * import { AleoNetworkClient, DeploymentJSON } from "@provablehq/sdk/testnet.js";
1126
1287
  *
1127
1288
  * // Get the transaction ID of the deployment transaction for a program.
1128
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1289
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1129
1290
  * const transaction = networkClient.getDeploymentTransactionForProgram("hello_hello.aleo");
1130
1291
  *
1131
1292
  * // Get the verifying keys for each function in the deployment.
@@ -1158,7 +1319,7 @@ class AleoNetworkClient {
1158
1319
  * import { AleoNetworkClient } from "@provablehq/sdk/testnet.js";
1159
1320
  *
1160
1321
  * // Get the transaction ID of the deployment transaction for a program.
1161
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1322
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1162
1323
  * const transactionId = networkClient.getDeploymentTransactionIDForProgram("hello_hello.aleo");
1163
1324
  *
1164
1325
  * // Get the transaction data for the deployment transaction.
@@ -1189,7 +1350,7 @@ class AleoNetworkClient {
1189
1350
  * import { AleoNetworkClient } from "@provablehq/sdk/testnet.js";
1190
1351
  *
1191
1352
  * // Create a network client.
1192
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1353
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1193
1354
  *
1194
1355
  * const latestHeight = networkClient.getLatestBlock();
1195
1356
  */
@@ -1214,10 +1375,10 @@ class AleoNetworkClient {
1214
1375
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1215
1376
  *
1216
1377
  * // Create a network client.
1217
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1378
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1218
1379
  *
1219
1380
  * // Create a network client and get the latest committee.
1220
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1381
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1221
1382
  * const latestCommittee = await networkClient.getLatestCommittee();
1222
1383
  */
1223
1384
  async getLatestCommittee() {
@@ -1242,10 +1403,10 @@ class AleoNetworkClient {
1242
1403
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1243
1404
  *
1244
1405
  * // Create a network client.
1245
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1406
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1246
1407
  *
1247
1408
  * // Create a network client and get the committee for a specific block.
1248
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1409
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1249
1410
  * const committee = await networkClient.getCommitteeByBlockHeight(1234);
1250
1411
  */
1251
1412
  async getCommitteeByBlockHeight(blockHeight) {
@@ -1269,7 +1430,7 @@ class AleoNetworkClient {
1269
1430
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1270
1431
  *
1271
1432
  * // Create a network client.
1272
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1433
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1273
1434
  *
1274
1435
  * const latestHeight = networkClient.getLatestHeight();
1275
1436
  */
@@ -1294,7 +1455,7 @@ class AleoNetworkClient {
1294
1455
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1295
1456
  *
1296
1457
  * // Create a network client.
1297
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1458
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1298
1459
  *
1299
1460
  * // Get the latest block hash.
1300
1461
  * const latestHash = networkClient.getLatestBlockHash();
@@ -1322,7 +1483,7 @@ class AleoNetworkClient {
1322
1483
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1323
1484
  *
1324
1485
  * // Create a network client.
1325
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1486
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1326
1487
  *
1327
1488
  * // Get the source code of a program.)
1328
1489
  * @returns {Promise<string>} Source code of the program
@@ -1331,7 +1492,7 @@ class AleoNetworkClient {
1331
1492
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1332
1493
  *
1333
1494
  * // Create a network client.
1334
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1495
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1335
1496
  *
1336
1497
  * const program = networkClient.getProgram("hello_hello.aleo");
1337
1498
  * const expectedSource = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n"
@@ -1364,7 +1525,7 @@ class AleoNetworkClient {
1364
1525
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1365
1526
  *
1366
1527
  * // Create a network client.
1367
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1528
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1368
1529
  *
1369
1530
  * const programVersion = networkClient.getLatestProgramEdition("hello_hello.aleo");
1370
1531
  * assert.equal(programVersion, 1);
@@ -1393,7 +1554,7 @@ class AleoNetworkClient {
1393
1554
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1394
1555
  *
1395
1556
  * // Create a network client.
1396
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1557
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1397
1558
  *
1398
1559
  * const programID = "hello_hello.aleo";
1399
1560
  * const programSource = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n"
@@ -1433,7 +1594,7 @@ class AleoNetworkClient {
1433
1594
  * }
1434
1595
  *
1435
1596
  * // Create a network client.
1436
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1597
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1437
1598
  *
1438
1599
  * // Imports can be fetched using the program ID, source code, or program object
1439
1600
  * let programImports = await networkClient.getProgramImports("double_test.aleo");
@@ -1503,7 +1664,7 @@ class AleoNetworkClient {
1503
1664
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1504
1665
  *
1505
1666
  * // Create a network client.
1506
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1667
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1507
1668
  *
1508
1669
  * const programImportsNames = networkClient.getProgramImports("wrapped_credits.aleo");
1509
1670
  * const expectedImportsNames = ["credits.aleo"];
@@ -1534,7 +1695,7 @@ class AleoNetworkClient {
1534
1695
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1535
1696
  *
1536
1697
  * // Create a network client.
1537
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1698
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1538
1699
  *
1539
1700
  * const mappings = networkClient.getProgramMappingNames("credits.aleo");
1540
1701
  * const expectedMappings = [
@@ -1572,7 +1733,7 @@ class AleoNetworkClient {
1572
1733
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1573
1734
  *
1574
1735
  * // Create a network client.
1575
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1736
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1576
1737
  *
1577
1738
  * // Get public balance of an account
1578
1739
  * const mappingValue = networkClient.getMappingValue("credits.aleo", "account", "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px");
@@ -1604,7 +1765,7 @@ class AleoNetworkClient {
1604
1765
  * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
1605
1766
  *
1606
1767
  * // Create a network client.
1607
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1768
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1608
1769
  *
1609
1770
  * // Get the bond state as an account.
1610
1771
  * const unbondedState = networkClient.getMappingPlaintext("credits.aleo", "bonded", "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px");
@@ -1650,7 +1811,7 @@ class AleoNetworkClient {
1650
1811
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/mainnet.js";
1651
1812
  *
1652
1813
  * // Create a network client.
1653
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1814
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1654
1815
  *
1655
1816
  * // Get the balance of an account from either an address object or address string.
1656
1817
  * const account = Account.fromCiphertext(process.env.ciphertext, process.env.password);
@@ -1681,7 +1842,7 @@ class AleoNetworkClient {
1681
1842
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/mainnet.js";
1682
1843
  *
1683
1844
  * // Create a network client.
1684
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1845
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1685
1846
  *
1686
1847
  * // Get the latest state root.
1687
1848
  * const stateRoot = networkClient.getStateRoot();
@@ -1708,7 +1869,7 @@ class AleoNetworkClient {
1708
1869
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/mainnet.js";
1709
1870
  *
1710
1871
  * // Create a network client.
1711
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1872
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1712
1873
  *
1713
1874
  * const transaction = networkClient.getTransaction("at1handz9xjrqeynjrr0xay4pcsgtnczdksz3e584vfsgaz0dh0lyxq43a4wj");
1714
1875
  */
@@ -1734,7 +1895,7 @@ class AleoNetworkClient {
1734
1895
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/mainnet.js";
1735
1896
  *
1736
1897
  * // Create a network client.
1737
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1898
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1738
1899
  *
1739
1900
  * const transaction = networkClient.getConfirmedTransaction("at1handz9xjrqeynjrr0xay4pcsgtnczdksz3e584vfsgaz0dh0lyxq43a4wj");
1740
1901
  * assert.equal(transaction.status, "confirmed");
@@ -1799,7 +1960,7 @@ class AleoNetworkClient {
1799
1960
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/mainnet.js";
1800
1961
  *
1801
1962
  * // Create a network client.
1802
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1963
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1803
1964
  *
1804
1965
  * const transactions = networkClient.getTransactions(654);
1805
1966
  */
@@ -1825,7 +1986,7 @@ class AleoNetworkClient {
1825
1986
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/mainnet.js";
1826
1987
  *
1827
1988
  * // Create a network client.
1828
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
1989
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1829
1990
  *
1830
1991
  * const transactions = networkClient.getTransactionsByBlockHash("ab19dklwl9vp63zu3hwg57wyhvmqf92fx5g8x0t6dr72py8r87pxupqfne5t9");
1831
1992
  */
@@ -1852,7 +2013,7 @@ class AleoNetworkClient {
1852
2013
  * import { AleoNetworkClient, Account } from "@provablehq/sdk/mainnet.js";
1853
2014
  *
1854
2015
  * // Create a network client.
1855
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
2016
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
1856
2017
  *
1857
2018
  * // Get the current transactions in the mempool.
1858
2019
  * const transactions = networkClient.getTransactionsInMempool();
@@ -1972,33 +2133,87 @@ class AleoNetworkClient {
1972
2133
  };
1973
2134
  }
1974
2135
  /**
1975
- * Submit a `ProvingRequest` to a remote proving service for delegated proving. If the broadcast flag of the `ProvingRequest` is set to `true` the remote service will attempt to broadcast the result `Transaction` on behalf of the requestor.
2136
+ * Parses a /prove or /prove/encrypted response. Returns a result object (never throws for 200/400/500/503).
2137
+ */
2138
+ async handleProvingResponse(response) {
2139
+ // Get the proving response text.
2140
+ const text = await response.text();
2141
+ let body;
2142
+ // Parse the body.
2143
+ try {
2144
+ body = parseJSON(text);
2145
+ }
2146
+ catch {
2147
+ body = {};
2148
+ }
2149
+ // If the status is 200, attempt to parse the Proving Request along its expected structure.
2150
+ if (response.status === 200) {
2151
+ if (isProvingResponse(body)) {
2152
+ return { ok: true, data: body };
2153
+ }
2154
+ return {
2155
+ ok: false,
2156
+ status: response.status,
2157
+ error: { message: "Invalid response from proving service" },
2158
+ };
2159
+ }
2160
+ // If the response is non 200, return the information back to the caller so it can be handled.
2161
+ if (response.status === 400 || response.status === 500 || response.status === 503) {
2162
+ const error = isProveApiErrorBody(body)
2163
+ ? body
2164
+ : { message: text || `${response.status} error` };
2165
+ return { ok: false, status: response.status, error };
2166
+ }
2167
+ return {
2168
+ ok: false,
2169
+ status: response.status,
2170
+ error: { message: text || `${response.status} error` },
2171
+ };
2172
+ }
2173
+ /**
2174
+ * Submit a `ProvingRequest` to a remote proving service for delegated proving. If the broadcast flag of the `ProvingRequest` is set to `true` the remote service will attempt to broadcast the result `Transaction` on behalf of the requestor. Throws on HTTP 400, 500, 503 (and retries on 500/503). Callers should {@link submitProvingRequestSafe} to handle proving request failures without throwing.
1976
2175
  *
1977
2176
  * @param {DelegatedProvingParams} options - The optional parameters required to submit a proving request.
1978
2177
  * @returns {Promise<ProvingResponse>} The ProvingResponse containing the transaction result and the result of the broadcast if the `broadcast` flag was set to `true`.
1979
2178
  */
1980
2179
  async submitProvingRequest(options) {
1981
- const proverUri = options.url ?? this.host;
2180
+ const result = await this.submitProvingRequestSafe(options);
2181
+ if (result.ok) {
2182
+ return result.data;
2183
+ }
2184
+ const err = new Error(result.error.message);
2185
+ err.status = result.status;
2186
+ throw err;
2187
+ }
2188
+ /**
2189
+ * Submit a proving request and return a result object instead of throwing. This method is usable when callers want to handle HTTP status (400, 500, 503) yourself. Retries on 500/503 and returns on 200 or 400.
2190
+ *
2191
+ * @param {DelegatedProvingParams} options - The optional parameters required to submit a proving request.
2192
+ * @returns {Promise<ProvingResult>} `{ ok: true, data }` on success (200), or `{ ok: false, status, error }` on 400/500/503. Check `result.ok` and then either `result.data` or `result.status` / `result.error.message`.
2193
+ */
2194
+ async submitProvingRequestSafe(options) {
2195
+ // Attempt to get the Prover URI first from the options, then from any configured globally, or third try the main configured host.
2196
+ const proverUri = (options.url ?? this.proverUri) ?? this.host;
1982
2197
  const provingRequestString = options.provingRequest instanceof ProvingRequest
1983
2198
  ? options.provingRequest.toString()
1984
2199
  : options.provingRequest;
2200
+ // Try to get JWT data to access the Provable API.
1985
2201
  const apiKey = options.apiKey ?? this.apiKey;
1986
2202
  const consumerId = options.consumerId ?? this.consumerId;
1987
2203
  let jwtData = options.jwtData ?? this.jwtData;
1988
- // Check if JWT is expired or missing
1989
- const bufferTime = FIVE_MINUTES; // 5 minutes buffer
1990
- const isExpired = jwtData && Date.now() >= jwtData.expiration - bufferTime;
2204
+ // Check to see if the JWT needs refreshing.
2205
+ const isExpired = jwtData && Date.now() >= jwtData.expiration - FIVE_MINUTES;
1991
2206
  if (!jwtData || isExpired) {
1992
2207
  if (options.apiKey && options.consumerId) {
1993
2208
  jwtData = await this.refreshJwt(apiKey, consumerId);
1994
- // Update both the class and the options with the new JWT
1995
2209
  this.jwtData = jwtData;
1996
2210
  options.jwtData = jwtData;
1997
2211
  }
1998
2212
  else {
1999
- throw new Error('JWT or both apiKey and consumerId are required');
2213
+ console.warn('JWT or both apiKey and consumerId are required when using the Provable API');
2000
2214
  }
2001
2215
  }
2216
+ // Create the necessary headers to hit the provable api.
2002
2217
  const headers = {
2003
2218
  ...this.headers,
2004
2219
  "X-ALEO-METHOD": "submitProvingRequest",
@@ -2007,17 +2222,75 @@ class AleoNetworkClient {
2007
2222
  if (jwtData?.jwt) {
2008
2223
  headers["Authorization"] = jwtData.jwt;
2009
2224
  }
2010
- try {
2011
- const response = await retryWithBackoff(() => post(`${proverUri}`, {
2225
+ // Encapsulate the requests in a locally scoped function that can be run with a retry closure.
2226
+ const runRequest = async () => {
2227
+ // If DPS privacy is set, call invoke the encrypted flow.
2228
+ if (options.dpsPrivacy) {
2229
+ // Get an ephemeral public key from a DPS service.
2230
+ const pubKeyResponse = await get(proverUri + "/pubkey", {
2231
+ headers,
2232
+ credentials: "include",
2233
+ });
2234
+ // Encrypt the provingRequest.
2235
+ const pubkey = parseJSON(await pubKeyResponse.text());
2236
+ const ciphertext = encryptProvingRequest(pubkey.public_key, ProvingRequest.fromString(provingRequestString));
2237
+ // Form the expected query a DPS service expects (including the key_id).
2238
+ const payload = {
2239
+ key_id: pubkey.key_id,
2240
+ ciphertext: ciphertext,
2241
+ };
2242
+ // We're in node, attempt to set the cookie manually.
2243
+ const cookie = isNode() ? pubKeyResponse.headers.get("set-cookie") : undefined;
2244
+ // Send the encrypted proving request to the DPS service.
2245
+ const res = await fetch(`${proverUri}/prove/encrypted`, {
2246
+ method: "POST",
2247
+ body: JSON.stringify(payload),
2248
+ headers: {
2249
+ ...headers,
2250
+ ...(cookie ? { Cookie: cookie } : {})
2251
+ },
2252
+ credentials: "include",
2253
+ });
2254
+ // Properly handle the proving response.
2255
+ return this.handleProvingResponse(res);
2256
+ }
2257
+ // If encrypted usage is not specified use the unencrypted endpoint.
2258
+ const proveEndpoint = proverUri.endsWith("/prove")
2259
+ ? proverUri
2260
+ : proverUri + "/prove";
2261
+ const res = await fetch(proveEndpoint, {
2262
+ method: "POST",
2012
2263
  body: provingRequestString,
2013
- headers
2014
- }));
2015
- const responseText = await response.text();
2016
- return parseJSON(responseText);
2264
+ headers,
2265
+ });
2266
+ // Properly handle the proving response.
2267
+ return this.handleProvingResponse(res);
2268
+ };
2269
+ try {
2270
+ // Run the request with retries.
2271
+ return await retryWithBackoff(async () => {
2272
+ // Run the encrypted or non-encrypted flow as specified by the flags.
2273
+ const result = await runRequest();
2274
+ if (result.ok) {
2275
+ return result;
2276
+ }
2277
+ // If 500s are hit responses are returned, attempt retries.
2278
+ if (result.status === 500 || result.status === 503) {
2279
+ const err = new Error(result.error.message);
2280
+ err.status = result.status;
2281
+ throw err;
2282
+ }
2283
+ return result;
2284
+ });
2017
2285
  }
2018
- catch (error) {
2019
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
2020
- throw new Error(`Failed to submit proving request: ${errorMessage}`);
2286
+ catch (err) {
2287
+ // If an error is returned, provide usable information to the caller.
2288
+ const e = err;
2289
+ return {
2290
+ ok: false,
2291
+ status: e.status ?? 500,
2292
+ error: { message: e.message },
2293
+ };
2021
2294
  }
2022
2295
  }
2023
2296
  /**
@@ -2032,7 +2305,7 @@ class AleoNetworkClient {
2032
2305
  * import { AleoNetworkClient, Account, ProgramManager } from "@provablehq/sdk/mainnet.js";
2033
2306
  *
2034
2307
  * // Create a network client and program manager.
2035
- * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
2308
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2", undefined);
2036
2309
  * const programManager = new ProgramManager(networkClient);
2037
2310
  *
2038
2311
  * // Set the account for the program manager.
@@ -2103,45 +2376,61 @@ class AleoNetworkClient {
2103
2376
  }
2104
2377
 
2105
2378
  /**
2106
- * @param {Map<string, CachedKeyPair>} map Any interface which returns a string as cached keypair bytes.
2107
- *
2108
- * @returns {KeyStore} The map decorated as a keystore.
2379
+ * Error thrown when a record scanner request fails (e.g. /register, /register/encrypted).
2380
+ * Includes HTTP status so callers can handle 422 vs 500 etc.
2109
2381
  */
2110
- function promoteMapToKeyStore(map) {
2111
- const ks = map;
2112
- ks.getKeys = async (locator) => {
2113
- const raw = map.get(locator);
2114
- if (!raw)
2115
- return null;
2116
- const [p, v] = raw;
2117
- return [
2118
- ProvingKey.fromBytes(p),
2119
- VerifyingKey.fromBytes(v),
2120
- ];
2121
- };
2122
- ks.getKeyBytes = async (locator) => map.get(locator) ?? null;
2123
- ks.getProvingKey = async (locator) => {
2124
- const raw = map.get(locator);
2125
- return raw ? ProvingKey.fromBytes(raw[0]) : null;
2126
- };
2127
- ks.getProvingKeyBytes = async (locator) => map.get(locator)?.[0] ?? null;
2128
- ks.getVerifyingKey = async (locator) => {
2129
- const raw = map.get(locator);
2130
- return raw ? VerifyingKey.fromBytes(raw[1]) : null;
2131
- };
2132
- ks.getVerifyingKeyBytes = async (locator) => map.get(locator)?.[1] ?? null;
2133
- ks.setKeys = async (locator, [pk, vk]) => {
2134
- map.set(locator, [pk.toBytes(), vk.toBytes()]);
2135
- };
2136
- ks.setKeyBytes = async (locator, raw) => {
2137
- map.set(locator, raw);
2138
- };
2139
- ks.has = async (locator) => Map.prototype.has.call(map, locator);
2140
- ks.delete = async (locator) => {
2141
- Map.prototype.delete.call(map, locator);
2142
- };
2143
- ks.clear = async () => Map.prototype.clear.call(map);
2144
- return ks;
2382
+ class RecordScannerRequestError extends Error {
2383
+ status;
2384
+ constructor(message, status) {
2385
+ super(message);
2386
+ this.name = "RecordScannerRequestError";
2387
+ this.status = status;
2388
+ Object.setPrototypeOf(this, RecordScannerRequestError.prototype);
2389
+ }
2390
+ }
2391
+ /** Error thrown when findCreditsRecord or findCreditsRecords is called but decryption is not enabled on the record scanner. */
2392
+ class DecryptionNotEnabledError extends Error {
2393
+ filter;
2394
+ constructor(message, filter) {
2395
+ super(message);
2396
+ this.name = "DecryptionNotEnabledError";
2397
+ this.filter = filter;
2398
+ Object.setPrototypeOf(this, DecryptionNotEnabledError.prototype);
2399
+ }
2400
+ }
2401
+ /** Error thrown when findCreditsRecord or findCreditsRecords is called but no view key for the UUID is stored in viewKeys or the account. */
2402
+ class ViewKeyNotStoredError extends Error {
2403
+ uuid;
2404
+ filter;
2405
+ constructor(message, uuid, filter) {
2406
+ super(message);
2407
+ this.name = "ViewKeyNotStoredError";
2408
+ this.uuid = uuid;
2409
+ this.filter = filter;
2410
+ Object.setPrototypeOf(this, ViewKeyNotStoredError.prototype);
2411
+ }
2412
+ }
2413
+ /** Error thrown when no record matches the supplied search filter (e.g. findCreditsRecord / findCreditsRecords). */
2414
+ class RecordNotFoundError extends Error {
2415
+ filter;
2416
+ constructor(message, filter) {
2417
+ super(message);
2418
+ this.name = "RecordNotFoundError";
2419
+ this.filter = filter;
2420
+ Object.setPrototypeOf(this, RecordNotFoundError.prototype);
2421
+ }
2422
+ }
2423
+ /** Error thrown when no UUID is configured, the UUID is invalid, or a record scanner request fails due to an invalid UUID/response. */
2424
+ class UUIDError extends Error {
2425
+ uuid;
2426
+ filter;
2427
+ constructor(message, uuid, filter) {
2428
+ super(message);
2429
+ this.name = "UUIDError";
2430
+ this.uuid = uuid;
2431
+ this.filter = filter;
2432
+ Object.setPrototypeOf(this, UUIDError.prototype);
2433
+ }
2145
2434
  }
2146
2435
 
2147
2436
  /**
@@ -2169,8 +2458,8 @@ class AleoKeyProviderParams {
2169
2458
  }
2170
2459
  }
2171
2460
  /**
2172
- * AleoKeyProvider class. Implements the KeyProvider interface. Enables the retrieval of Aleo program proving and
2173
- * verifying keys for the credits.aleo program over http from official Aleo sources and storing and retrieving function
2461
+ * AleoKeyProvider class. Implements the FunctionKeyProvider 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
2174
2463
  * keys from a local memory cache.
2175
2464
  */
2176
2465
  class AleoKeyProvider {
@@ -2192,10 +2481,8 @@ class AleoKeyProvider {
2192
2481
  this.cache = new Map();
2193
2482
  this.cacheOption = false;
2194
2483
  }
2195
- keyStore() {
2196
- if (!this.cacheOption)
2197
- return Promise.resolve(undefined);
2198
- return Promise.resolve(promoteMapToKeyStore(this.cache));
2484
+ async keyStore() {
2485
+ return undefined;
2199
2486
  }
2200
2487
  /**
2201
2488
  * Use local memory to store keys
@@ -2267,12 +2554,12 @@ class AleoKeyProvider {
2267
2554
  *
2268
2555
  * @example
2269
2556
  * // Create a new object which implements the KeyProvider interface
2270
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
2557
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
2271
2558
  * const keyProvider = new AleoKeyProvider();
2272
2559
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
2273
2560
  *
2274
2561
  * // Initialize a program manager with the key provider to automatically fetch keys for value transfers
2275
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
2562
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
2276
2563
  * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
2277
2564
  *
2278
2565
  * // Keys can also be fetched manually using the key provider
@@ -2285,7 +2572,7 @@ class AleoKeyProvider {
2285
2572
  let verifierUrl;
2286
2573
  let cacheKey;
2287
2574
  if ("name" in params && typeof params["name"] == "string") {
2288
- let key = CREDITS_PROGRAM_KEYS.getKey(params["name"]);
2575
+ const key = CREDITS_PROGRAM_KEYS.getKey(params["name"]);
2289
2576
  return this.fetchCreditsKeys(key);
2290
2577
  }
2291
2578
  if ("proverUri" in params &&
@@ -2319,12 +2606,12 @@ class AleoKeyProvider {
2319
2606
  *
2320
2607
  * @example
2321
2608
  * // Create a new AleoKeyProvider object
2322
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
2609
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
2323
2610
  * const keyProvider = new AleoKeyProvider();
2324
2611
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
2325
2612
  *
2326
2613
  * // Initialize a program manager with the key provider to automatically fetch keys for value transfers
2327
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
2614
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
2328
2615
  * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
2329
2616
  *
2330
2617
  * // Keys can also be fetched manually
@@ -2442,12 +2729,12 @@ class AleoKeyProvider {
2442
2729
  *
2443
2730
  * @example
2444
2731
  * // Create a new AleoKeyProvider
2445
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
2732
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
2446
2733
  * const keyProvider = new AleoKeyProvider();
2447
2734
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
2448
2735
  *
2449
2736
  * // Initialize a program manager with the key provider to automatically fetch keys for value transfers
2450
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
2737
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
2451
2738
  * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
2452
2739
  *
2453
2740
  * // Keys can also be fetched manually
@@ -2582,6 +2869,156 @@ class AleoKeyProvider {
2582
2869
  }
2583
2870
  }
2584
2871
 
2872
+ /**
2873
+ * Error thrown when there is a mismatch between expected and actual key metadata.
2874
+ * This can occur during verification of either the checksum or size of a key.
2875
+ *
2876
+ * @extends Error
2877
+ */
2878
+ class KeyVerificationError extends Error {
2879
+ locator;
2880
+ field;
2881
+ expected;
2882
+ actual;
2883
+ /**
2884
+ * Creates a new KeyVerificationError instance (error.name is "ChecksumMismatchError").
2885
+ *
2886
+ * @param {string} locator - The key locator where the mismatch occurred.
2887
+ * @param {"checksum" | "size"} field - The field that failed verification (either "checksum" or "size").
2888
+ * @param {string} expected - The expected value of the field.
2889
+ * @param {string} actual - The actual value encountered.
2890
+ */
2891
+ constructor(locator, field, expected, actual) {
2892
+ super(`Key verification ${locator} ${field} mismatch: expected ${expected}, got ${actual}`);
2893
+ this.locator = locator;
2894
+ this.field = field;
2895
+ this.expected = expected;
2896
+ this.actual = actual;
2897
+ this.name = "ChecksumMismatchError";
2898
+ Object.setPrototypeOf(this, KeyVerificationError.prototype);
2899
+ }
2900
+ }
2901
+ /**
2902
+ * Computes the SHA-256 checksum of a given set of bytes.
2903
+ *
2904
+ * @param {Uint8Array} bytes - The bytes to compute the checksum of.
2905
+ */
2906
+ async function sha256Hex(bytes) {
2907
+ const hash = await crypto.subtle.digest("SHA-256", bytes);
2908
+ return Array.from(new Uint8Array(hash))
2909
+ .map((b) => b.toString(16).padStart(2, "0"))
2910
+ .join("");
2911
+ }
2912
+
2913
+ /**
2914
+ * In-memory implementation of KeyVerifier that stores and verifies key fingerprints.
2915
+ * Provides functionality to compute and verify cryptographic checksums of keys, storing them
2916
+ * in memory for subsequent verification. This implementation is primarily used for testing
2917
+ * and development purposes where persistence is not required.
2918
+ *
2919
+ * Key features:
2920
+ * - Computes SHA-256 checksums and sizes for key bytes.
2921
+ * - Stores key fingerprints in memory using string locators.
2922
+ * - Verifies key bytes against stored or provided fingerprints.
2923
+ *
2924
+ * @implements {KeyVerifier}
2925
+ */
2926
+ class MemKeyVerifier {
2927
+ keyStore = {};
2928
+ /**
2929
+ * Computes and optionally stores key metadata. If a keyFingerprint is provided, this function will verify the computed checksum against it before storing it.
2930
+ *
2931
+ * @param {KeyMetadata} keyMetadata - Object containing key bytes and optional verification data.
2932
+ * @throws {KeyVerificationError} When provided keyFingerprint doesn't match computed values.
2933
+ * @returns {Promise<KeyFingerprint>} Computed key metadata.
2934
+ */
2935
+ async computeKeyMetadata(keyMetadata) {
2936
+ // Compute the metadata from the key bytes
2937
+ const computedFingerprint = {
2938
+ checksum: await sha256Hex(keyMetadata.keyBytes),
2939
+ size: keyMetadata.keyBytes.length
2940
+ };
2941
+ // If a KeyFingerprint is provided, verify it matches computed values.
2942
+ if (keyMetadata.fingerprint) {
2943
+ if (keyMetadata.fingerprint.size !== computedFingerprint.size) {
2944
+ throw new KeyVerificationError(keyMetadata.locator ? keyMetadata.locator : "", "size", String(keyMetadata.fingerprint.size), String(computedFingerprint.size));
2945
+ }
2946
+ if (keyMetadata.fingerprint.checksum !== computedFingerprint.checksum) {
2947
+ throw new KeyVerificationError(keyMetadata.locator ? keyMetadata.locator : "", "checksum", keyMetadata.fingerprint.checksum, computedFingerprint.checksum);
2948
+ }
2949
+ }
2950
+ // If locator is provided, store only the fingerprint
2951
+ if (keyMetadata.locator) {
2952
+ this.keyStore[keyMetadata.locator] = computedFingerprint;
2953
+ }
2954
+ return computedFingerprint;
2955
+ }
2956
+ /**
2957
+ * Verifies key bytes against stored or provided metadata. Follows a priority verification scheme:
2958
+ * 1. If KeyFingerprint is provided in the metadata, this method verifies against that first.
2959
+ * 2. If a locator is provided, attempts to verify against stored fingerprint.
2960
+ * 3. If neither is available, throws an error.
2961
+ *
2962
+ * @param {KeyMetadata} keyMetadata - Object containing the key bytes and optional verification metadata.
2963
+ * @throws {Error} When neither fingerprint nor valid locator is provided for verification.
2964
+ * @throws {KeyVerificationError} When size or checksum verification fails.
2965
+ * @returns {Promise<void>} Promise that resolves when verification succeeds.
2966
+ */
2967
+ async verifyKeyBytes(keyMetadata) {
2968
+ if (!keyMetadata.keyBytes) {
2969
+ throw new Error("Key bytes must be provided for verification.");
2970
+ }
2971
+ // Compute the fingerprint for the provided bytes.
2972
+ const computedFingerprint = await this.computeKeyMetadata({
2973
+ keyBytes: keyMetadata.keyBytes
2974
+ });
2975
+ // Determine which fingerprint to verify against.
2976
+ let fingerprintToVerify;
2977
+ if (keyMetadata.fingerprint) {
2978
+ // If a key fingerprint is provided, use it.
2979
+ fingerprintToVerify = keyMetadata.fingerprint;
2980
+ }
2981
+ else if (keyMetadata.locator) {
2982
+ // Otherwise try to get stored fingerprint by locator.
2983
+ fingerprintToVerify = this.keyStore[keyMetadata.locator];
2984
+ }
2985
+ if (!fingerprintToVerify) {
2986
+ throw new Error("Either fingerprint or a valid locator must be provided for verification.");
2987
+ }
2988
+ // Verify the key size.
2989
+ if (fingerprintToVerify.size !== computedFingerprint.size) {
2990
+ throw new KeyVerificationError(keyMetadata.locator || "", "size", String(fingerprintToVerify.size), String(computedFingerprint.size));
2991
+ }
2992
+ // Verify the key checksum.
2993
+ if (fingerprintToVerify.checksum !== computedFingerprint.checksum) {
2994
+ throw new KeyVerificationError(keyMetadata.locator || "", "checksum", fingerprintToVerify.checksum, computedFingerprint.checksum);
2995
+ }
2996
+ }
2997
+ }
2998
+
2999
+ /**
3000
+ * Error thrown when a key locator is invalid for filesystem use.
3001
+ * Used to prevent path traversal and other filesystem injection when deriving paths from locators.
3002
+ *
3003
+ * @extends Error
3004
+ */
3005
+ class InvalidLocatorError extends Error {
3006
+ locator;
3007
+ reason;
3008
+ /**
3009
+ * @param message - Human-readable description of the validation failure.
3010
+ * @param locator - The invalid locator string that failed validation.
3011
+ * @param reason - Machine-readable reason code for the failure.
3012
+ */
3013
+ constructor(message, locator, reason) {
3014
+ super(message);
3015
+ this.locator = locator;
3016
+ this.reason = reason;
3017
+ this.name = "InvalidLocatorError";
3018
+ Object.setPrototypeOf(this, InvalidLocatorError.prototype);
3019
+ }
3020
+ }
3021
+
2585
3022
  /**
2586
3023
  * Search parameters for the offline key provider. This class implements the KeySearchParams interface and includes
2587
3024
  * a convenience method for creating a new instance of this class for each function of the credits.aleo program.
@@ -2621,7 +3058,7 @@ class OfflineSearchParams {
2621
3058
  return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.bond_validator.locator, true);
2622
3059
  }
2623
3060
  /**
2624
- * Create a new OfflineSearchParams instance for the claim_unbond_public function of the
3061
+ * Create a new OfflineSearchParams instance for the claim_unbond_public function of the credits.aleo program.
2625
3062
  */
2626
3063
  static claimUnbondPublicKeyParams() {
2627
3064
  return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.claim_unbond_public.locator, true);
@@ -2747,7 +3184,7 @@ class OfflineSearchParams {
2747
3184
  * const offlineExecuteTx = <Transaction>await this.buildExecutionTransaction("hello_hello.aleo", "hello", 1, false, ["5u32", "5u32"], undefined, offlineSearchParams, undefined, undefined, undefined, undefined, offlineQuery, program);
2748
3185
  *
2749
3186
  * // Broadcast the transaction later on a machine with internet access
2750
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
3187
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
2751
3188
  * const txId = await networkClient.broadcastTransaction(offlineExecuteTx);
2752
3189
  */
2753
3190
  class OfflineKeyProvider {
@@ -2756,7 +3193,7 @@ class OfflineKeyProvider {
2756
3193
  this.cache = new Map();
2757
3194
  }
2758
3195
  keyStore() {
2759
- return Promise.resolve(promoteMapToKeyStore(this.cache));
3196
+ return Promise.resolve(undefined);
2760
3197
  }
2761
3198
  /**
2762
3199
  * Get bond_public function keys from the credits.aleo program. The keys must be cached prior to calling this
@@ -3207,7 +3644,7 @@ class NetworkRecordProvider {
3207
3644
  *
3208
3645
  * @example
3209
3646
  * // Create a new NetworkRecordProvider
3210
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
3647
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
3211
3648
  * const keyProvider = new AleoKeyProvider();
3212
3649
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
3213
3650
  *
@@ -3220,7 +3657,7 @@ class NetworkRecordProvider {
3220
3657
  *
3221
3658
  * // When the program manager is initialized with the record provider it will be used to find automatically find
3222
3659
  * // fee records and amount records for value transfers so that they do not need to be specified manually
3223
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
3660
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
3224
3661
  * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
3225
3662
  *
3226
3663
  * */
@@ -3254,9 +3691,9 @@ class NetworkRecordProvider {
3254
3691
  const recordsPts = await this.networkClient.findRecords(startHeight, endHeight, searchParameters.unspent, ["credits.aleo"], microcredits, maxAmount, searchParameters.nonces, this.account.privateKey());
3255
3692
  return recordsPts.map((record) => ({
3256
3693
  owner: record.owner().toString(),
3257
- programName: 'credits.aleo',
3258
- recordName: 'credits',
3259
- recordPlaintext: record.toString(),
3694
+ program_name: 'credits.aleo',
3695
+ record_name: 'credits',
3696
+ record_plaintext: record.toString(),
3260
3697
  }));
3261
3698
  }
3262
3699
  /**
@@ -3268,7 +3705,7 @@ class NetworkRecordProvider {
3268
3705
  *
3269
3706
  * @example
3270
3707
  * // Create a new NetworkRecordProvider
3271
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
3708
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
3272
3709
  * const keyProvider = new AleoKeyProvider();
3273
3710
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
3274
3711
  *
@@ -3281,7 +3718,7 @@ class NetworkRecordProvider {
3281
3718
  *
3282
3719
  * // When the program manager is initialized with the record provider it will be used to find automatically find
3283
3720
  * // fee records and amount records for value transfers so that they do not need to be specified manually
3284
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
3721
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
3285
3722
  * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
3286
3723
  */
3287
3724
  async findCreditsRecord(microcredits, searchParameters) {
@@ -3377,7 +3814,7 @@ class NetworkRecordProvider {
3377
3814
  * const params = new BlockHeightSearch(89995, 99995);
3378
3815
  *
3379
3816
  * // Create a new NetworkRecordProvider
3380
- * const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
3817
+ * const networkClient = new AleoNetworkClient("https://api.provable.com/v2");
3381
3818
  * const keyProvider = new AleoKeyProvider();
3382
3819
  * const recordProvider = new NetworkRecordProvider(account, networkClient);
3383
3820
  *
@@ -3398,15 +3835,17 @@ class BlockHeightSearch {
3398
3835
  }
3399
3836
 
3400
3837
  /**
3401
- * RecordScanner is a RecordProvider implementation that uses the record scanner service to find records.
3838
+ * RecordScanner is a RecordProvider implementation that uses Provable's confidential record scanning service to find
3839
+ * records.
3402
3840
  *
3403
3841
  * @example
3404
3842
  * const account = new Account({ privateKey: 'APrivateKey1...' });
3405
3843
  *
3406
3844
  * const recordScanner = new RecordScanner({ url: "https://record-scanner.aleo.org" });
3407
3845
  * recordScanner.setAccount(account);
3408
- * recordScanner.setApiKey("your-api-key");
3409
- * const uuid = await recordScanner.register(0);
3846
+ * recordScanner.setApiKey("example-api-key");
3847
+ * const result = await recordScanner.register(viewKey, 0);
3848
+ * if (result.ok) { const uuid = result.data.uuid; }
3410
3849
  *
3411
3850
  * const filter = {
3412
3851
  * uuid,
@@ -3439,38 +3878,231 @@ class BlockHeightSearch {
3439
3878
  * const records = await recordScanner.findRecords(filter);
3440
3879
  */
3441
3880
  class RecordScanner {
3881
+ cacheViewKeysOnRegister;
3442
3882
  url;
3443
3883
  apiKey;
3884
+ consumerId;
3885
+ jwtData;
3444
3886
  uuid;
3887
+ viewKeys;
3888
+ autoReRegister;
3889
+ decryptEnabled;
3890
+ account;
3891
+ /**
3892
+ * @param {RecordScannerOptions} options Configuration for the record scanner.
3893
+ */
3445
3894
  constructor(options) {
3446
- this.url = options.url;
3447
- this.apiKey = typeof options.apiKey === "string" ? { header: "X-Provable-API-Key", value: options.apiKey } : options.apiKey;
3895
+ // Set the network by detecting which version of the SDK is being used.
3896
+ const network = "/mainnet";
3897
+ // If the user has configured a network in their uri, throw.
3898
+ if (options.url.endsWith("/mainnet") || options.url.endsWith("/testnet")) {
3899
+ throw new Error("The record scanning url should not include the specific network, this is automatically configured by the Provable SDK.");
3900
+ }
3901
+ // Configure the url to use the network the SDK is using.
3902
+ this.url = options.url + network;
3903
+ // Get any view keys passed in the options.
3904
+ this.viewKeys = options.viewKeys ?
3905
+ Object.fromEntries(options.viewKeys.map(viewKey => [this.computeUUID(viewKey), viewKey]))
3906
+ : undefined;
3907
+ // Set the view key caching flag if provided (default: true).
3908
+ this.cacheViewKeysOnRegister = options.cacheViewKeysOnRegister ??= true;
3909
+ // Set the account if provided.
3910
+ this.account = options.account;
3911
+ if (this.account) {
3912
+ // Compute the UUID from the view key and set it on the scanner.
3913
+ this.setUuid(this.account.viewKey());
3914
+ // Add the view key to the scanner's view keys.
3915
+ this.addViewKey(this.account.viewKey());
3916
+ }
3917
+ // Configure authentication options.
3918
+ this.apiKey = typeof options.apiKey === "string" ? {
3919
+ header: "X-Provable-API-Key",
3920
+ value: options.apiKey
3921
+ } : options.apiKey;
3922
+ this.consumerId = options.consumerId;
3923
+ this.jwtData = options.jwtData;
3924
+ this.autoReRegister = options.autoReRegister;
3925
+ this.decryptEnabled = options.decryptEnabled;
3448
3926
  }
3449
3927
  /**
3450
3928
  * Set the API key to use for the record scanner.
3451
3929
  *
3452
- * @param {string} apiKey The API key to use for the record scanner.
3930
+ * @param {string | { header: string, value: string }} apiKey The API key to use for the record scanner.
3453
3931
  */
3454
- async setApiKey(apiKey) {
3932
+ setApiKey(apiKey) {
3455
3933
  this.apiKey = typeof apiKey === "string" ? { header: "X-Provable-API-Key", value: apiKey } : apiKey;
3456
3934
  }
3457
3935
  /**
3458
- * Set the UUID to use for the record scanner.
3936
+ * Set the consumer ID used for JWT refresh when using authenticated record scanner (e.g. Provable API).
3937
+ *
3938
+ * @param {string} consumerId The consumer ID to use for JWT refresh.
3939
+ */
3940
+ setConsumerId(consumerId) {
3941
+ this.consumerId = consumerId;
3942
+ }
3943
+ /**
3944
+ * Set JWT data for authentication. Optional; when not set, JWT can be refreshed from apiKey + consumerId if provided.
3945
+ *
3946
+ * @param {RecordScannerJWTData | undefined} jwtData The JWT data to use, or undefined to clear.
3947
+ */
3948
+ setJwtData(jwtData) {
3949
+ this.jwtData = jwtData;
3950
+ }
3951
+ /**
3952
+ * Set whether /owned should automatically re-register on 422 (when a view key for the UUID is in viewKeys or account) and retry once.
3953
+ *
3954
+ * @param {boolean} enabled Whether to enable auto re-register on 422.
3955
+ */
3956
+ setAutoReRegister(enabled) {
3957
+ this.autoReRegister = enabled;
3958
+ }
3959
+ /**
3960
+ * Set whether decryption of owned records is enabled (e.g. for use with the decrypt method).
3961
+ *
3962
+ * @param {boolean} enabled Whether to enable decryption of owned records received from the scanner using the `owned` or any `findRecords` methods.
3963
+ */
3964
+ setDecryptEnabled(enabled) {
3965
+ this.decryptEnabled = enabled;
3966
+ }
3967
+ /**
3968
+ * Add a view key to the record scanner for usage in local decryption. This is REQUIRED for findCreditsRecord/findCreditsRecords to work properly.
3969
+ *
3970
+ * @param {ViewKey} viewKey The view key to add.
3971
+ */
3972
+ addViewKey(viewKey) {
3973
+ const uuid = this.computeUUID(viewKey).toString();
3974
+ this.viewKeys = this.viewKeys ? { ...this.viewKeys, [uuid]: viewKey } : { [uuid]: viewKey };
3975
+ }
3976
+ /**
3977
+ * Remove a view key from the record scanner.
3978
+ *
3979
+ * @param {string} uuid The uuid of the view key to remove.
3980
+ */
3981
+ removeViewKey(uuid) {
3982
+ if (this.viewKeys) {
3983
+ delete this.viewKeys[uuid];
3984
+ }
3985
+ }
3986
+ /**
3987
+ * Return the view key for the given record-scanner UUID if one is configured
3988
+ * (in viewKeys or as the account's view key). Used to decide if re-registration on 422 is possible.
3989
+ *
3990
+ * @param {string} uuid The record-scanner UUID to look up.
3991
+ * @returns {ViewKey | undefined} The view key for that UUID, or undefined.
3992
+ */
3993
+ getViewKeyForUuid(uuid) {
3994
+ // Prefer view key from the cached map (keyed by UUID string).
3995
+ const cachedVk = this.viewKeys?.[uuid];
3996
+ if (cachedVk)
3997
+ return cachedVk;
3998
+ // Otherwise use the account's view key if it matches this UUID.
3999
+ const accountVk = this.account?.viewKey();
4000
+ if (accountVk && this.computeUUID(accountVk).toString() === uuid)
4001
+ return accountVk;
4002
+ return undefined;
4003
+ }
4004
+ /**
4005
+ * Set the primary account for the record scanner.
4006
+ *
4007
+ * @param {Account} account The account to set as the primary account.
4008
+ */
4009
+ setAccount(account) {
4010
+ const existingVk = this.account?.viewKey();
4011
+ // Set the account on the scanner.
4012
+ this.account = account;
4013
+ // Set the uuid on the scanner using the view key from the account.
4014
+ this.setUuid(account.viewKey());
4015
+ // Add the view key to the scanner's view keys.
4016
+ this.addViewKey(account.viewKey());
4017
+ // Remove the existing view key from the scanner's view keys if it exists.
4018
+ if (existingVk) {
4019
+ this.removeViewKey(this.computeUUID(existingVk).toString());
4020
+ }
4021
+ }
4022
+ /**
4023
+ * Refreshes the JWT by making a POST request to /jwts/{consumer_id}. Used when authentication is required.
4024
+ *
4025
+ * @param {string} apiKey The API key to use for the refresh request.
4026
+ * @param {string} consumerId The consumer ID for the JWT endpoint.
4027
+ * @returns {Promise<RecordScannerJWTData>} The new JWT data.
4028
+ */
4029
+ async refreshJwt(apiKey, consumerId) {
4030
+ const response = await post(`${this.url}/jwts/${consumerId}`, {
4031
+ headers: {
4032
+ "X-Provable-API-Key": apiKey,
4033
+ },
4034
+ });
4035
+ const authHeader = response.headers.get("authorization");
4036
+ if (!authHeader) {
4037
+ throw new Error("No authorization header in JWT refresh response");
4038
+ }
4039
+ const body = await response.json();
4040
+ return {
4041
+ jwt: authHeader,
4042
+ expiration: body.exp * 1000, // Convert to milliseconds
4043
+ };
4044
+ }
4045
+ /**
4046
+ * Returns auth headers (e.g. Authorization with JWT). Refreshes JWT if expired and apiKey + consumerId are set. Empty when auth is not configured.
4047
+ *
4048
+ * @returns {Promise<Record<string, string>>} Auth headers to add to requests, or empty object when not configured.
4049
+ */
4050
+ async getAuthHeaders() {
4051
+ let jwtData = this.jwtData;
4052
+ // Consider JWT expired a few minutes early to avoid race at boundary.
4053
+ const isExpired = jwtData && Date.now() >= jwtData.expiration - FIVE_MINUTES;
4054
+ if (!jwtData || isExpired) {
4055
+ const apiKey = this.apiKey?.value;
4056
+ if (apiKey && this.consumerId) {
4057
+ jwtData = await this.refreshJwt(apiKey, this.consumerId);
4058
+ this.jwtData = jwtData;
4059
+ }
4060
+ else if (jwtData?.jwt) {
4061
+ // Use existing JWT even if expired when refresh is not possible.
4062
+ return { Authorization: jwtData.jwt };
4063
+ }
4064
+ else {
4065
+ return {};
4066
+ }
4067
+ }
4068
+ return jwtData?.jwt ? { Authorization: jwtData.jwt } : {};
4069
+ }
4070
+ /**
4071
+ * Set the UUID for the record scanner.
4072
+ *
4073
+ * @param {Field | ViewKey} keyMaterial The UUID to use for the record scanner. If a ViewKey is provided, the UUID will be computed from the key.
4074
+ */
4075
+ setUuid(keyMaterial) {
4076
+ this.uuid = keyMaterial instanceof ViewKey ? this.computeUUID(keyMaterial) : keyMaterial;
4077
+ }
4078
+ /**
4079
+ * If the error is a RecordScannerRequestError (from request()), return a RecordScannerFailure result;
4080
+ * otherwise re-throw the error.
3459
4081
  *
3460
- * @param {Field} uuid The UUID to use for the record scanner.
4082
+ * @param {unknown} err The error from a failed request (e.g. from request() or from a catch after calling it).
4083
+ * @returns {RecordScannerFailure} When err is RecordScannerRequestError.
4084
+ * @throws Re-throws err when it is not a RecordScannerRequestError.
3461
4085
  */
3462
- async setUuid(uuidOrViewKey) {
3463
- this.uuid = uuidOrViewKey instanceof ViewKey ? this.computeUUID(uuidOrViewKey) : uuidOrViewKey;
4086
+ handleRequestError(err) {
4087
+ if (err instanceof RecordScannerRequestError) {
4088
+ return {
4089
+ ok: false,
4090
+ status: err.status,
4091
+ error: { message: err.message, status: err.status },
4092
+ };
4093
+ }
4094
+ throw err;
3464
4095
  }
3465
4096
  /**
3466
- * Register the account with the record scanner service.
4097
+ * Register the account with the record scanning service (unencrypted POST /register). Does not throw if a valid error response from the record scanner is received; returns a result object instead.
3467
4098
  *
4099
+ * @param {ViewKey} viewKey The view key to register.
3468
4100
  * @param {number} startBlock The block height to start scanning from.
3469
- * @returns {Promise<RegistrationResponse>} The response from the record scanner service.
4101
+ * @returns {Promise<RegisterResult>} `{ ok: true, data }` on success, or `{ ok: false, status, error }` on failure.
3470
4102
  */
3471
4103
  async register(viewKey, startBlock) {
3472
4104
  try {
3473
- let request = {
4105
+ const request = {
3474
4106
  view_key: viewKey.to_string(),
3475
4107
  start: startBlock,
3476
4108
  };
@@ -3480,96 +4112,249 @@ class RecordScanner {
3480
4112
  body: JSON.stringify(request),
3481
4113
  }));
3482
4114
  const data = await response.json();
3483
- this.uuid = data.uuid;
3484
- return data;
4115
+ // If the uuid is not set, set it on the scanner.
4116
+ if (!this.uuid) {
4117
+ this.uuid = data.uuid;
4118
+ }
4119
+ // Add the view key to the local scanner's view keys if configured to do so.
4120
+ if (this.cacheViewKeysOnRegister) {
4121
+ this.addViewKey(viewKey);
4122
+ }
4123
+ return { ok: true, data };
3485
4124
  }
3486
- catch (error) {
3487
- console.error(`Failed to register view key: ${error}`);
3488
- throw error;
4125
+ catch (err) {
4126
+ console.error(`Failed to register view key: ${err}`);
4127
+ return this.handleRequestError(err);
3489
4128
  }
3490
4129
  }
3491
4130
  /**
3492
- * Get encrypted records from the record scanner service.
4131
+ * Fetches an ephemeral public key from the record scanning service for use with registerEncrypted.
4132
+ * Follows the same pattern as the delegated proving service /pubkey endpoint.
4133
+ *
4134
+ * @returns {Promise<CryptoBoxPubKey>} The service's ephemeral public key and key_id.
4135
+ */
4136
+ async getPubkey() {
4137
+ const response = await this.request(new Request(`${this.url}/pubkey`, { method: "GET" }));
4138
+ return parseJSON(await response.text());
4139
+ }
4140
+ /**
4141
+ * Registers the account with the record scanning service using the encrypted flow: 1. fetches an ephemeral public key from /pubkey - 2. encrypts the registration request (view key + start block) - 3. POSTs to /register/encrypted. Does not HTTP error on a proper error response from the record scanner; returns a result object instead.
4142
+ *
4143
+ * @param {ViewKey} viewKey The view key to register.
4144
+ * @param {number} startBlock The block height to start scanning from.
4145
+ * @returns {Promise<RegisterResult>} `{ ok: true, data }` on success, or `{ ok: false, status, error }` on failure.
4146
+ */
4147
+ async registerEncrypted(viewKey, startBlock) {
4148
+ try {
4149
+ // Get the ephemeral public key from the record scanner.
4150
+ const pubkey = await this.getPubkey();
4151
+ // Encrypt the registration request using the ephemeral public key.
4152
+ const ciphertext = encryptRegistrationRequest(pubkey.public_key, viewKey, startBlock);
4153
+ const payload = {
4154
+ key_id: pubkey.key_id,
4155
+ ciphertext,
4156
+ };
4157
+ // Send the encrypted registration request to the record scanner.
4158
+ const response = await this.request(new Request(`${this.url}/register/encrypted`, {
4159
+ method: "POST",
4160
+ headers: { "Content-Type": "application/json" },
4161
+ body: JSON.stringify(payload),
4162
+ }));
4163
+ const data = await response.json();
4164
+ // If the uuid is not set, set it on the scanner.
4165
+ if (!this.uuid) {
4166
+ this.uuid = data.uuid;
4167
+ }
4168
+ // Add the view key to the local scanner's view keys if configured to do so.
4169
+ if (this.cacheViewKeysOnRegister) {
4170
+ this.addViewKey(viewKey);
4171
+ }
4172
+ return { ok: true, data };
4173
+ }
4174
+ catch (err) {
4175
+ return this.handleRequestError(err);
4176
+ }
4177
+ }
4178
+ /**
4179
+ * Remove all local scanner state associated with the given UUID (stored uuid, viewKeys entry, account if it matches).
4180
+ * Called after a successful revoke so the scanner does not retain view keys or account for a revoked registration.
4181
+ */
4182
+ clearLocalStateForUuid(uuidStr) {
4183
+ if (this.uuid != null && this.uuid.toString() === uuidStr) {
4184
+ this.uuid = undefined;
4185
+ }
4186
+ if (this.viewKeys != null) {
4187
+ delete this.viewKeys[uuidStr];
4188
+ if (Object.keys(this.viewKeys).length === 0) {
4189
+ this.viewKeys = undefined;
4190
+ }
4191
+ }
4192
+ if (this.account != null && this.computeUUID(this.account.viewKey()).toString() === uuidStr) {
4193
+ this.account = undefined;
4194
+ }
4195
+ }
4196
+ /**
4197
+ * Revoke the account registration with the record scanning service (POST /revoke). On success, also removes
4198
+ * all local state for that UUID: the stored UUID (if it matches), the view key for that UUID, and the
4199
+ * account (if its view key corresponds to that UUID).
4200
+ *
4201
+ * @param {string | Field | undefined} uuid The UUID to revoke. If omitted, uses the UUID configured on the scanner.
4202
+ * @returns {Promise<RevokeResult>} `{ ok: true, data: { status } }` on success, or `{ ok: false, status, error }` on failure.
4203
+ * @throws {UUIDError} When no UUID is configured and none provided, or when the UUID string is invalid.
4204
+ */
4205
+ async revoke(uuid) {
4206
+ const resolvedUuid = uuid ?? this.uuid;
4207
+ if (!resolvedUuid) {
4208
+ throw new UUIDError("No UUID configured for the record scanner and no UUID provided.");
4209
+ }
4210
+ const uuidStr = typeof resolvedUuid === "string" ? resolvedUuid : resolvedUuid.toString();
4211
+ if (!this.uuidIsValid(uuidStr)) {
4212
+ throw new UUIDError(`UUID provided ${uuidStr} is invalid`, uuidStr);
4213
+ }
4214
+ try {
4215
+ const response = await this.request(new Request(`${this.url}/revoke`, {
4216
+ method: "POST",
4217
+ headers: { "Content-Type": "application/json" },
4218
+ body: JSON.stringify(uuidStr),
4219
+ }));
4220
+ const data = await response.json();
4221
+ this.clearLocalStateForUuid(uuidStr);
4222
+ return { ok: true, data };
4223
+ }
4224
+ catch (err) {
4225
+ return this.handleRequestError(err);
4226
+ }
4227
+ }
4228
+ /**
4229
+ * Get encrypted records from the record scanning service. This is a safe variant of /records/encrypted that returns
4230
+ * a result instead of throwing on HTTP error.
3493
4231
  *
3494
4232
  * @param {RecordsFilter} recordsFilter The filter to use to find the records and filter the response.
3495
- * @returns {Promise<EncryptedRecord[]>} The encrypted records.
4233
+ * @returns {Promise<EncryptedRecordsResult>} The encrypted records or an error if the request failed.
3496
4234
  */
3497
- async encryptedRecords(recordsFilter) {
4235
+ async encrypted(recordsFilter) {
3498
4236
  try {
3499
4237
  const response = await this.request(new Request(`${this.url}/records/encrypted`, {
3500
4238
  method: "POST",
3501
4239
  headers: { "Content-Type": "application/json" },
3502
4240
  body: JSON.stringify(recordsFilter),
3503
4241
  }));
3504
- return await response.json();
4242
+ const data = await response.json();
4243
+ return { ok: true, data };
3505
4244
  }
3506
- catch (error) {
3507
- console.error(`Failed to get encrypted records: ${error}`);
3508
- throw error;
4245
+ catch (err) {
4246
+ return this.handleRequestError(err);
3509
4247
  }
3510
4248
  }
3511
4249
  /**
3512
- * Check if a list of serial numbers exist in the record scanner service.
4250
+ * Get encrypted records from the record scanning service.
4251
+ *
4252
+ * @param {RecordsFilter} recordsFilter The filter to use to find the records and filter the response.
4253
+ * @returns {Promise<EncryptedRecord[]>} The encrypted records.
4254
+ */
4255
+ async encryptedRecords(recordsFilter) {
4256
+ const result = await this.encrypted(recordsFilter);
4257
+ if (result.ok)
4258
+ return result.data;
4259
+ throw new RecordScannerRequestError(result.error.message, result.status);
4260
+ }
4261
+ /**
4262
+ * Check if serial numbers appear in any record inputs on-chain, indicating that the records they belong to have been spent. This is a safe variant of /records/sns that returns a result instead of throwing on HTTP error.
3513
4263
  *
3514
4264
  * @param {string[]} serialNumbers The serial numbers to check.
3515
- * @returns {Promise<Record<string, boolean>>} Map of Aleo Record serial numbers and whether they appeared in any inputs on chain. If boolean corresponding to the Serial Number has a true value, that Record is considered spent by the Aleo Network.
4265
+ * @returns {Promise<SerialNumbersResult>} Map of Aleo Record serial numbers and whether they appeared in any inputs on chain. If a boolean corresponding to the Serial Number has a true value, that Record is considered spent by the Aleo Network.
3516
4266
  */
3517
- async checkSerialNumbers(serialNumbers) {
4267
+ async serialNumbers(serialNumbers) {
3518
4268
  try {
3519
4269
  const response = await this.request(new Request(`${this.url}/records/sns`, {
3520
4270
  method: "POST",
3521
4271
  headers: { "Content-Type": "application/json" },
3522
4272
  body: JSON.stringify(serialNumbers),
3523
4273
  }));
3524
- return await response.json();
4274
+ const data = await response.json();
4275
+ return { ok: true, data };
3525
4276
  }
3526
- catch (error) {
3527
- console.error(`Failed to check if serial numbers exist: ${error}`);
3528
- throw error;
4277
+ catch (err) {
4278
+ return this.handleRequestError(err);
3529
4279
  }
3530
4280
  }
3531
4281
  /**
3532
- * Check if a list of tags exist in the record scanner service.
4282
+ * Check if serial numbers appear in any record inputs on-chain, indicating that the records they belong to have been spent.
4283
+ *
4284
+ * @param {string[]} serialNumbers The serial numbers to check.
4285
+ * @returns {Promise<Record<string, boolean>>} Map of Aleo Record serial numbers and whether they appeared in any inputs on chain. If boolean corresponding to the Serial Number has a true value, that Record is considered spent by the Aleo Network.
4286
+ */
4287
+ async checkSerialNumbers(serialNumbers) {
4288
+ const result = await this.serialNumbers(serialNumbers);
4289
+ if (result.ok)
4290
+ return result.data;
4291
+ throw new RecordScannerRequestError(result.error.message, result.status);
4292
+ }
4293
+ /**
4294
+ * Check if tags appear in any record inputs on-chain, indicating that the records they belong to have been spent. This is a safe variant of /records/tags that returns a result instead of throwing on HTTP error.
3533
4295
  *
4296
+ * *
3534
4297
  * @param {string[]} tags The tags to check.
3535
- * @returns {Promise<Record<string, boolean>>} Map of Aleo Record tags and whether they appeared in any inputs on chain. If boolean corresponding to the tag has a true value, that Record is considered spent by the Aleo Network.
4298
+ * @returns {Promise<TagsResult>} Map of Aleo Record tags and whether they appeared in any inputs on chain. If a boolean corresponding to the tag has a true value, that Record is considered spent by the Aleo Network.
3536
4299
  */
3537
- async checkTags(tags) {
4300
+ async tags(tags) {
3538
4301
  try {
3539
4302
  const response = await this.request(new Request(`${this.url}/records/tags`, {
3540
4303
  method: "POST",
3541
4304
  headers: { "Content-Type": "application/json" },
3542
4305
  body: JSON.stringify(tags),
3543
4306
  }));
3544
- return await response.json();
4307
+ const data = await response.json();
4308
+ return { ok: true, data };
3545
4309
  }
3546
- catch (error) {
3547
- console.error(`Failed to check if tags exist: ${error}`);
3548
- throw error;
4310
+ catch (err) {
4311
+ return this.handleRequestError(err);
3549
4312
  }
3550
4313
  }
3551
4314
  /**
3552
- * Check the status of a record scanner indexing job.
4315
+ * Check if tags appear in any record inputs on-chain, indicating that the records they belong to have been spent.
3553
4316
  *
3554
- * @param {string} jobId The job id to check.
3555
- * @returns {Promise<StatusResponse>} The status of the job.
4317
+ * @param {string[]} tags The tags to check.
4318
+ * @returns {Promise<Record<string, boolean>>} Map of Aleo Record tags and whether they appeared in any inputs on chain. If boolean corresponding to the tag has a true value, that Record is considered spent by the Aleo Network.
3556
4319
  */
3557
- async checkStatus() {
4320
+ async checkTags(tags) {
4321
+ const result = await this.tags(tags);
4322
+ if (result.ok)
4323
+ return result.data;
4324
+ throw new RecordScannerRequestError(result.error.message, result.status);
4325
+ }
4326
+ /**
4327
+ * Check the scan completion job status for a specific UUID.
4328
+ *
4329
+ * @param {string | Field | undefined} uuid The UUID of the job to check. If no UUID is provided as input, the UUID configured for the scanner will be used.
4330
+ * @returns {Promise<StatusResult>} The status of the job or an error if the job could not be found.
4331
+ */
4332
+ async status(uuid) {
4333
+ // Attempt to get the UUID from the parameter or use the configured UUID within the scanner.
4334
+ uuid = uuid ?? this.uuid;
4335
+ if (!uuid) {
4336
+ throw new UUIDError("No UUID configured for the record scanner.");
4337
+ }
4338
+ // If the UUID is a string, verify that it is valid.
4339
+ if (typeof uuid === "string" && !this.uuidIsValid(uuid)) {
4340
+ throw new UUIDError(`UUID ${uuid} is invalid`, uuid);
4341
+ }
4342
+ // Check the status of the job for the specified UUID.
3558
4343
  try {
3559
4344
  const response = await this.request(new Request(`${this.url}/status`, {
3560
4345
  method: "POST",
3561
4346
  headers: { "Content-Type": "application/json" },
3562
- body: JSON.stringify(this.uuid?.toString()),
4347
+ body: JSON.stringify(uuid.toString()),
3563
4348
  }));
3564
- return await response.json();
4349
+ const data = await response.json();
4350
+ return { ok: true, data };
3565
4351
  }
3566
- catch (error) {
3567
- console.error(`Failed to check status of job: ${error}`);
3568
- throw error;
4352
+ catch (err) {
4353
+ return this.handleRequestError(err);
3569
4354
  }
3570
4355
  }
3571
4356
  /**
3572
- * Find a record in the record scanner service.
4357
+ * Find a record in the record scanning service.
3573
4358
  *
3574
4359
  * @param {OwnedFilter} searchParameters The filter to use to find the record.
3575
4360
  * @returns {Promise<OwnedRecord>} The record.
@@ -3588,56 +4373,158 @@ class RecordScanner {
3588
4373
  }
3589
4374
  }
3590
4375
  /**
3591
- * Find records in the record scanner service.
4376
+ * Get owned records. Throws if the UUID passed in the OwnedFilter is invalid or is not configured in the record scanner otherwise returns the RESTFUL response from the record scanner.
3592
4377
  *
3593
- * @param {OwnedFilter} filter The filter to use to find the records.
3594
- * @returns {Promise<OwnedRecord[]>} The records.
4378
+ * @param {OwnedFilter} filter The OwnedFilter used to specify the subset of owned records to select.
4379
+ * @returns {Promise<OwnedRecordsResult>} Record belonging to the uuid passed in the filter or set on the Record Scanner.
3595
4380
  */
3596
- async findRecords(filter) {
3597
- if (!this.uuid) {
3598
- throw new Error("You are using the RecordScanner implementation of the RecordProvider. No account has been registered with the RecordScanner which is required to use the findRecords method. Please set an with the setAccount method before calling the findRecords method again.");
4381
+ async owned(filter) {
4382
+ // Extract and verify the correctness of the UUID from the filter or get the configured UUID within the scanner.
4383
+ const uuid = this.getUUID(filter);
4384
+ // Throw an error if none could be found, otherwise set the UUID on the filter with either the UUID configured
4385
+ // within the filter or the UUID configured within the scanner.
4386
+ if (!uuid) {
4387
+ 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);
3599
4388
  }
3600
- filter.uuid = this.uuid?.toString();
3601
- try {
4389
+ filter.uuid = uuid;
4390
+ // Inner request used to retry once after 422 re-register without duplicating logic.
4391
+ const ownedRequest = async () => {
3602
4392
  const response = await this.request(new Request(`${this.url}/records/owned`, {
3603
4393
  method: "POST",
3604
4394
  headers: { "Content-Type": "application/json" },
3605
4395
  body: JSON.stringify(filter),
3606
4396
  }));
3607
- return await response.json();
4397
+ const data = await response.json();
4398
+ return { ok: true, data };
4399
+ };
4400
+ // When decryption is enabled and a view key exists for this UUID, decrypt records in place before returning.
4401
+ const attemptDecrypt = (result) => {
4402
+ if (result.ok && this.decryptEnabled) {
4403
+ const viewKey = this.getViewKeyForUuid(uuid);
4404
+ if (viewKey)
4405
+ this.decrypt(viewKey, result.data);
4406
+ }
4407
+ return result;
4408
+ };
4409
+ try {
4410
+ return attemptDecrypt(await ownedRequest());
3608
4411
  }
3609
- catch (error) {
3610
- console.error(`Failed to get owned records: ${error}`);
3611
- throw error;
4412
+ catch (err) {
4413
+ const failure = this.handleRequestError(err);
4414
+ // On 422 (e.g. not registered), optionally re-register with registerEncrypted and retry once.
4415
+ if (failure.status === 422 && this.autoReRegister) {
4416
+ const viewKey = this.getViewKeyForUuid(uuid);
4417
+ if (viewKey) {
4418
+ const regResult = await this.registerEncrypted(viewKey, 0);
4419
+ if (regResult.ok) {
4420
+ try {
4421
+ return attemptDecrypt(await ownedRequest());
4422
+ }
4423
+ catch (retryErr) {
4424
+ return this.handleRequestError(retryErr);
4425
+ }
4426
+ }
4427
+ }
4428
+ }
4429
+ return failure;
4430
+ }
4431
+ }
4432
+ /**
4433
+ * Find records using the record scanning service.
4434
+ *
4435
+ * @param {OwnedFilter} searchParameters The filter to use to find the records.
4436
+ * @returns {Promise<OwnedRecord[]>} The records.
4437
+ */
4438
+ async findRecords(searchParameters) {
4439
+ // Get the records from the record scanner.
4440
+ const result = await this.owned(searchParameters);
4441
+ // If the request was successful, return the records otherwise throw an error.
4442
+ if (result.ok)
4443
+ return result.data;
4444
+ throw new RecordScannerRequestError(result.error.message, result.status);
4445
+ }
4446
+ /**
4447
+ * Get RecordPlaintext from an OwnedRecord by parsing record_plaintext (trimmed). Returns null if missing or parse fails. Does not decrypt; decryption is handled only in owned().
4448
+ */
4449
+ getPlaintext(record) {
4450
+ // Only read record_plaintext (decrypted by the owned() callwhen decryptEnabled is true).
4451
+ const plaintextStr = record.record_plaintext?.trim();
4452
+ if (!plaintextStr)
4453
+ return null;
4454
+ try {
4455
+ return RecordPlaintext.fromString(plaintextStr);
4456
+ }
4457
+ catch {
4458
+ return null;
4459
+ }
4460
+ }
4461
+ /**
4462
+ * For each owned record provided, attempt to decrypt with the given view key. On success, sets record_plaintext on that record to the decrypted plaintext string. Records that fail to decrypt (e.g. wrong view key) or have no record_ciphertext are left unchanged.
4463
+ *
4464
+ * @param {ViewKey} viewKey The view key to use for decryption.
4465
+ * @param {OwnedRecord[]} records The owned records to decrypt (mutated in place).
4466
+ */
4467
+ decrypt(viewKey, records) {
4468
+ for (const record of records) {
4469
+ const ciphertextStr = record.record_ciphertext?.trim();
4470
+ if (!ciphertextStr)
4471
+ continue;
4472
+ try {
4473
+ const ciphertext = RecordCiphertext.fromString(ciphertextStr);
4474
+ const plaintext = ciphertext.decrypt(viewKey);
4475
+ record.record_plaintext = plaintext.toString();
4476
+ }
4477
+ catch {
4478
+ // Wrong view key or invalid ciphertext; leave this record unchanged.
4479
+ }
3612
4480
  }
3613
4481
  }
3614
4482
  /**
3615
- * Find a credits record in the record scanner service.
4483
+ * Find a credits.aleo record in the record scanning service.
3616
4484
  *
3617
4485
  * @param {number} microcredits The amount of microcredits to find.
3618
4486
  * @param {OwnedFilter} searchParameters The filter to use to find the record.
3619
4487
  * @returns {Promise<OwnedRecord>} The record.
3620
4488
  */
3621
4489
  async findCreditsRecord(microcredits, searchParameters) {
4490
+ const uuid = this.getUUID(searchParameters);
4491
+ if (!uuid) {
4492
+ throw new UUIDError(`No uuid found in the record scanner filter`, uuid, searchParameters);
4493
+ }
4494
+ if (!this.decryptEnabled) {
4495
+ throw new DecryptionNotEnabledError("Decryption of owned records must be enabled (set decryptEnabled in options or call setDecryptEnabled(true)) to use findCreditsRecord.", searchParameters);
4496
+ }
4497
+ if (!this.getViewKeyForUuid(uuid)) {
4498
+ throw new ViewKeyNotStoredError(`No view key for UUID ${uuid} is stored in the record scanner. Add the view key via viewKeys in options, addViewKey(), or setAccount().`, uuid, searchParameters);
4499
+ }
3622
4500
  try {
4501
+ // Fetch credits records (owned() will decrypt when decryptEnabled and view key are set).
3623
4502
  const records = await this.findRecords({
3624
- decrypt: true,
3625
- unspent: searchParameters.unspent,
4503
+ unspent: searchParameters.unspent ?? true,
3626
4504
  filter: {
3627
- start: searchParameters.filter?.start ?? 0,
3628
4505
  program: "credits.aleo",
3629
4506
  record: "credits",
4507
+ ...(searchParameters.filter ? searchParameters.filter : {}),
3630
4508
  },
3631
- uuid: this.uuid?.toString(),
4509
+ responseFilter: searchParameters.responseFilter,
4510
+ uuid,
3632
4511
  });
3633
- const record = records.find(record => {
3634
- const plaintext = RecordPlaintext.fromString(record.record_plaintext ?? '');
3635
- const amountStr = plaintext.getMember("microcredits").toString();
3636
- const amount = parseInt(amountStr.replace("u64", ""));
3637
- return amount >= microcredits;
4512
+ // First record whose plaintext microcredits >= requested amount.
4513
+ const record = records.find(r => {
4514
+ const plaintext = this.getPlaintext(r);
4515
+ if (!plaintext)
4516
+ return false;
4517
+ try {
4518
+ const amountStr = plaintext.getMember("microcredits").toString();
4519
+ const amount = parseInt(amountStr.replace("u64", ""));
4520
+ return amount >= microcredits;
4521
+ }
4522
+ catch {
4523
+ return false;
4524
+ }
3638
4525
  });
3639
4526
  if (!record) {
3640
- throw new Error(`No records found matching the supplied search filter:\n${JSON.stringify(searchParameters, null, 2)}`);
4527
+ throw new RecordNotFoundError(`No records found matching the supplied search filter:\n${JSON.stringify(searchParameters, null, 2)}. Decryption of owned records MUST be enabled and the ViewKey matching the UUID must be stored in the RecordScanner object to perform decryption.`, searchParameters);
3641
4528
  }
3642
4529
  return record;
3643
4530
  }
@@ -3647,28 +4534,47 @@ class RecordScanner {
3647
4534
  }
3648
4535
  }
3649
4536
  /**
3650
- * Find credits records using a record scanning service.
4537
+ * Find credits records greater than or equal to the specified amounts using the record scanning service.
3651
4538
  *
3652
4539
  * @param {number[]} microcreditAmounts The amounts of microcredits to find.
3653
4540
  * @param {OwnedFilter} searchParameters The filter to use to find the records.
3654
4541
  * @returns {Promise<OwnedRecord[]>} The records
3655
4542
  */
3656
4543
  async findCreditsRecords(microcreditAmounts, searchParameters) {
4544
+ const uuid = this.getUUID(searchParameters);
4545
+ if (!uuid) {
4546
+ throw new UUIDError(`No uuid found in the record scanner filter, and none configured within the record scanner`, uuid, searchParameters);
4547
+ }
4548
+ if (!this.decryptEnabled) {
4549
+ throw new DecryptionNotEnabledError("Decryption of owned records must be enabled (set decryptEnabled in options or call setDecryptEnabled(true)) to use findCreditsRecords.", searchParameters);
4550
+ }
4551
+ if (!this.getViewKeyForUuid(uuid)) {
4552
+ throw new ViewKeyNotStoredError(`No view key for UUID ${uuid} is stored in the record scanner. Add the view key via viewKeys in options, addViewKey(), or setAccount().`, uuid, searchParameters);
4553
+ }
3657
4554
  try {
4555
+ // Fetch credits records (owned() decrypts when decryptEnabled and a view key matching the UUID are set).
3658
4556
  const records = await this.findRecords({
3659
- decrypt: true,
3660
- unspent: searchParameters.unspent,
4557
+ unspent: searchParameters.unspent ?? true,
3661
4558
  filter: {
3662
- start: searchParameters.filter?.start ?? 0,
3663
4559
  program: "credits.aleo",
3664
4560
  record: "credits",
4561
+ ...(searchParameters.filter ? searchParameters.filter : {}),
3665
4562
  },
3666
- uuid: this.uuid?.toString(),
4563
+ responseFilter: searchParameters.responseFilter,
4564
+ uuid,
3667
4565
  });
3668
- return records.filter(record => {
3669
- const plaintext = RecordPlaintext.fromString(record.record_plaintext ?? '');
3670
- const amount = plaintext.getMember("microcredits").toString();
3671
- return microcreditAmounts.includes(parseInt(amount.replace("u64", "")));
4566
+ // Keep only records whose plaintext microcredits match one of the requested amounts.
4567
+ return records.filter(r => {
4568
+ const plaintext = this.getPlaintext(r);
4569
+ if (!plaintext)
4570
+ return false;
4571
+ try {
4572
+ const amount = plaintext.getMember("microcredits").toString();
4573
+ return microcreditAmounts.includes(parseInt(amount.replace("u64", "")));
4574
+ }
4575
+ catch {
4576
+ return false;
4577
+ }
3672
4578
  });
3673
4579
  }
3674
4580
  catch (error) {
@@ -3677,19 +4583,28 @@ class RecordScanner {
3677
4583
  }
3678
4584
  }
3679
4585
  /**
3680
- * Wrapper function to make a request to the record scanner service and handle any errors.
4586
+ * Wrapper function to make a request to the record scanning service and handle any errors. Optionally adds JWT Authorization header when consumerId/jwtData (or apiKey+consumerId) are configured.
3681
4587
  *
3682
4588
  * @param {Request} req The request to make.
3683
- * @returns {Promise<Response>} The response.
4589
+ * @returns {Promise<Response>} The response when the request succeeds.
4590
+ * @throws {RecordScannerRequestError} When the server returns a non-2xx status (e.g. 4xx, 5xx).
4591
+ * @throws Re-throws any error from fetch (e.g. network failure) or from getAuthHeaders().
3684
4592
  */
3685
4593
  async request(req) {
3686
4594
  try {
4595
+ // Attach JWT (if configured) and API key before sending.
4596
+ const authHeaders = await this.getAuthHeaders();
4597
+ for (const [key, value] of Object.entries(authHeaders)) {
4598
+ req.headers.set(key, value);
4599
+ }
3687
4600
  if (this.apiKey) {
3688
4601
  req.headers.set(this.apiKey.header, this.apiKey.value);
3689
4602
  }
3690
4603
  const response = await fetch(req);
4604
+ // Non-2xx: throw so callers can handleRequestError or re-register on 422 if autoReRegister is enabled.
3691
4605
  if (!response.ok) {
3692
- throw new Error(await response.text() ?? `Request to ${req.url} failed with status ${response.status}`);
4606
+ const text = await response.text();
4607
+ throw new RecordScannerRequestError(text || `Request to ${req.url} failed with status ${response.status}`, response.status);
3693
4608
  }
3694
4609
  return response;
3695
4610
  }
@@ -3698,13 +4613,47 @@ class RecordScanner {
3698
4613
  throw error;
3699
4614
  }
3700
4615
  }
3701
- computeUUID(vk) {
4616
+ /**
4617
+ * Compute the record scanner UUID for a view key.
4618
+ *
4619
+ * @param {ViewKey} viewKey The view key to compute the UUID for.
4620
+ * @returns {Field} The computed UUID corresponding to the view key.
4621
+ */
4622
+ computeUUID(viewKey) {
3702
4623
  // Construct the material needed for the Poseidon oracle.
3703
- const inputs = [Field.newDomainSeparator(RECORD_DOMAIN), vk.toField(), Field.one()];
4624
+ const inputs = [Field.newDomainSeparator(RECORD_DOMAIN), viewKey.toField(), Field.one()];
3704
4625
  // Calculate the uuid.
3705
4626
  const hasher = new Poseidon4();
3706
4627
  return hasher.hash(inputs);
3707
4628
  }
4629
+ /**
4630
+ * Validate a UUID string to ensure it represents a valid Aleo Record Scanner UUID.
4631
+ *
4632
+ * @param {string} uuid The UUID to validate.
4633
+ * @returns {boolean} Whether the UUID is valid.
4634
+ */
4635
+ uuidIsValid(uuid) {
4636
+ try {
4637
+ Field.fromString(uuid);
4638
+ return true;
4639
+ }
4640
+ catch {
4641
+ return false;
4642
+ }
4643
+ }
4644
+ /**
4645
+ * Get the uuid for the filter, first by extracting the UUID from the filter, then falling back to the uuid configured within the record scanner.
4646
+ *
4647
+ * @param {OwnedFilter} filter The filter to extract the UUID from.
4648
+ * @returns {string | undefined} The UUID for the filter, or undefined if the filter does not contain a UUID.
4649
+ */
4650
+ getUUID(filter) {
4651
+ // Filter may specify a UUID; otherwise use the scanner's configured UUID.
4652
+ if (filter.uuid && this.uuidIsValid(filter.uuid)) {
4653
+ return filter.uuid;
4654
+ }
4655
+ return this.uuid?.toString();
4656
+ }
3708
4657
  }
3709
4658
 
3710
4659
  /**
@@ -4024,7 +4973,7 @@ class ProgramManager {
4024
4973
  * @param { RecordProvider | undefined } recordProvider A record provider that implements {@link RecordProvider} interface
4025
4974
  */
4026
4975
  constructor(host, keyProvider, recordProvider, networkClientOptions) {
4027
- this.host = host ? host : "https://api.explorer.provable.com/v1";
4976
+ this.host = host ? host : "https://api.provable.com/v2";
4028
4977
  this.networkClient = new AleoNetworkClient(this.host, networkClientOptions);
4029
4978
  this.keyProvider = keyProvider ? keyProvider : new AleoKeyProvider();
4030
4979
  this.recordProvider = recordProvider;
@@ -4081,7 +5030,7 @@ class ProgramManager {
4081
5030
  * import { ProgramManager } from "@provablehq/sdk/mainnet.js";
4082
5031
  *
4083
5032
  * // Create a ProgramManager
4084
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1");
5033
+ * const programManager = new ProgramManager("https://api.provable.com/v2");
4085
5034
  *
4086
5035
  * // Set the value of the `Accept-Language` header to `en-US`
4087
5036
  * programManager.setHeader('Accept-Language', 'en-US');
@@ -4102,7 +5051,7 @@ class ProgramManager {
4102
5051
  * keyProvider.useCache(true);
4103
5052
  *
4104
5053
  * // Create a ProgramManager
4105
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
5054
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider);
4106
5055
  *
4107
5056
  * // Set the inclusion keys.
4108
5057
  * programManager.setInclusionProver();
@@ -4136,7 +5085,7 @@ class ProgramManager {
4136
5085
  * import { ProgramManager } from "@provablehq/sdk/mainnet.js";
4137
5086
  *
4138
5087
  * // Create a ProgramManager
4139
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1");
5088
+ * const programManager = new ProgramManager("https://api.provable.com/v2");
4140
5089
  *
4141
5090
  * // Remove the default `X-Aleo-SDK-Version` header
4142
5091
  * programManager.removeHeader('X-Aleo-SDK-Version');
@@ -4166,7 +5115,7 @@ class ProgramManager {
4166
5115
  *
4167
5116
  * // Initialize a program manager with the key provider to automatically fetch keys for deployments
4168
5117
  * const program = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n";
4169
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5118
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
4170
5119
  * programManager.setAccount(Account);
4171
5120
  *
4172
5121
  * // Define a fee in credits
@@ -4278,7 +5227,7 @@ class ProgramManager {
4278
5227
  *
4279
5228
  * // Initialize a program manager with the key provider to automatically fetch keys for deployments
4280
5229
  * const program = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n";
4281
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5230
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
4282
5231
  * programManager.setAccount(Account);
4283
5232
  *
4284
5233
  * // Define a fee in credits
@@ -4396,7 +5345,7 @@ class ProgramManager {
4396
5345
  *
4397
5346
  * // Initialize a program manager with the key provider to automatically fetch keys for deployments
4398
5347
  * const program = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n";
4399
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5348
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
4400
5349
  *
4401
5350
  * // Define a fee in credits
4402
5351
  * const priorityFee = 0.0;
@@ -4444,7 +5393,7 @@ class ProgramManager {
4444
5393
  * keyProvider.useCache(true);
4445
5394
  *
4446
5395
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
4447
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5396
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
4448
5397
  *
4449
5398
  * // Build and execute the transaction
4450
5399
  * const tx = await programManager.buildExecutionTransaction({
@@ -4510,8 +5459,8 @@ class ProgramManager {
4510
5459
  edition = await this.networkClient.getLatestProgramEdition(programName);
4511
5460
  }
4512
5461
  catch (e) {
4513
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
4514
- edition = 1;
5462
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
5463
+ edition = 0;
4515
5464
  }
4516
5465
  }
4517
5466
  // Get the private key from the account if it is not provided in the parameters
@@ -4605,7 +5554,7 @@ class ProgramManager {
4605
5554
  * keyProvider.useCache(true);
4606
5555
  *
4607
5556
  * // Initialize a program manager with the key provider to automatically fetch keys for executions.
4608
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
5557
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider);
4609
5558
  *
4610
5559
  * // Build the `Authorization`.
4611
5560
  * const privateKey = new PrivateKey(); // Change this to a private key that has an aleo credit balance.
@@ -4744,7 +5693,7 @@ class ProgramManager {
4744
5693
  * keyProvider.useCache(true);
4745
5694
  *
4746
5695
  * // Initialize a ProgramManager with the key and record providers.
4747
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5696
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
4748
5697
  *
4749
5698
  * // Build the `Authorization`.
4750
5699
  * const authorization = await programManager.buildAuthorization({
@@ -4794,8 +5743,8 @@ class ProgramManager {
4794
5743
  edition = await this.networkClient.getLatestProgramEdition(programName);
4795
5744
  }
4796
5745
  catch (e) {
4797
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
4798
- edition = 1;
5746
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
5747
+ edition = 0;
4799
5748
  }
4800
5749
  }
4801
5750
  // Resolve the program imports if they exist.
@@ -4827,7 +5776,7 @@ class ProgramManager {
4827
5776
  * keyProvider.useCache(true);
4828
5777
  *
4829
5778
  * // Initialize a ProgramManager with the key and record providers.
4830
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5779
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
4831
5780
  *
4832
5781
  * // Build the unchecked `Authorization`.
4833
5782
  * const authorization = await programManager.buildAuthorizationUnchecked({
@@ -4887,8 +5836,8 @@ class ProgramManager {
4887
5836
  edition = await this.networkClient.getLatestProgramEdition(programName);
4888
5837
  }
4889
5838
  catch (e) {
4890
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
4891
- edition = 1;
5839
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
5840
+ edition = 0;
4892
5841
  }
4893
5842
  }
4894
5843
  // Build and return an `Authorization` for the desired function.
@@ -4910,7 +5859,7 @@ class ProgramManager {
4910
5859
  * keyProvider.useCache(true);
4911
5860
  *
4912
5861
  * // Initialize a ProgramManager with the key and record providers.
4913
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5862
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
4914
5863
  *
4915
5864
  * // Build the proving request.
4916
5865
  * const provingRequest = await programManager.provingRequest({
@@ -4928,8 +5877,9 @@ class ProgramManager {
4928
5877
  async provingRequest(options) {
4929
5878
  // Destructure the options object to access the parameters.
4930
5879
  const { functionName, priorityFee, privateFee, inputs, recordSearchParams, broadcast = false, unchecked = false, } = options;
4931
- const privateKey = options.privateKey;
4932
5880
  const baseFee = options.baseFee ? options.baseFee : 0;
5881
+ const privateKey = options.privateKey;
5882
+ const useFeeMaster = options.useFeeMaster ? options.useFeeMaster : false;
4933
5883
  let program = options.programSource;
4934
5884
  let programName = options.programName;
4935
5885
  let feeRecord = options.feeRecord;
@@ -4956,8 +5906,8 @@ class ProgramManager {
4956
5906
  edition = await this.networkClient.getLatestProgramEdition(programName);
4957
5907
  }
4958
5908
  catch (e) {
4959
- console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 1.`);
4960
- edition = 1;
5909
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
5910
+ edition = 0;
4961
5911
  }
4962
5912
  }
4963
5913
  // Get the private key from the account if it is not provided in the parameters.
@@ -4981,7 +5931,7 @@ class ProgramManager {
4981
5931
  }
4982
5932
  // Get the fee record from the account if it is not provided in the parameters
4983
5933
  try {
4984
- if (privateFee) {
5934
+ if (privateFee && !useFeeMaster) {
4985
5935
  let fee = priorityFee;
4986
5936
  // If a fee record wasn't provided, estimate the fee that needs to be paid.
4987
5937
  if (!feeRecord) {
@@ -5000,7 +5950,7 @@ class ProgramManager {
5000
5950
  logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
5001
5951
  }
5002
5952
  // Build and return the `ProvingRequest`.
5003
- return await ProgramManager$1.buildProvingRequest(executionPrivateKey, program, functionName, inputs, baseFee, priorityFee, feeRecord, imports, broadcast, unchecked, edition);
5953
+ return await ProgramManager$1.buildProvingRequest(executionPrivateKey, program, functionName, inputs, baseFee, priorityFee, feeRecord, imports, broadcast, unchecked, edition, useFeeMaster);
5004
5954
  }
5005
5955
  /**
5006
5956
  * Builds a SnarkVM fee `Authorization` for `credits.aleo/fee_private` or `credits.aleo/fee_public`. If a record is provided `fee_private` will be executed, otherwise `fee_public` will be executed.
@@ -5018,7 +5968,7 @@ class ProgramManager {
5018
5968
  * keyProvider.useCache(true);
5019
5969
  *
5020
5970
  * // Initialize a ProgramManager with the key and record providers.
5021
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
5971
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5022
5972
  *
5023
5973
  * // Build a credits.aleo/fee_public `Authorization`.
5024
5974
  * const feePublicAuthorization = await programManager.buildFeeAuthorization({
@@ -5065,7 +6015,7 @@ class ProgramManager {
5065
6015
  * keyProvider.useCache(true);
5066
6016
  *
5067
6017
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
5068
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
6018
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5069
6019
  *
5070
6020
  * // Build and execute the transaction
5071
6021
  * const tx_id = await programManager.execute({
@@ -5181,7 +6131,7 @@ class ProgramManager {
5181
6131
  * keyProvider.useCache(true);
5182
6132
  *
5183
6133
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
5184
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
6134
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5185
6135
  * const record_1 = "{ owner: aleo184vuwr5u7u0ha5f5k44067dd2uaqewxx6pe5ltha5pv99wvhfqxqv339h4.private, microcredits: 45000000u64.private, _nonce: 4106205762862305308495708971985748592380064201230396559307556388725936304984group.public}"
5186
6136
  * const record_2 = "{ owner: aleo184vuwr5u7u0ha5f5k44067dd2uaqewxx6pe5ltha5pv99wvhfqxqv339h4.private, microcredits: 45000000u64.private, _nonce: 1540945439182663264862696551825005342995406165131907382295858612069623286213group.public}"
5187
6137
  * const tx_id = await programManager.join(record_1, record_2, 0.05, false);
@@ -5294,7 +6244,7 @@ class ProgramManager {
5294
6244
  * keyProvider.useCache(true);
5295
6245
  *
5296
6246
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
5297
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
6247
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5298
6248
  * const record = "{ owner: aleo184vuwr5u7u0ha5f5k44067dd2uaqewxx6pe5ltha5pv99wvhfqxqv339h4.private, microcredits: 45000000u64.private, _nonce: 4106205762862305308495708971985748592380064201230396559307556388725936304984group.public}"
5299
6249
  * const tx_id = await programManager.split(25000000, record);
5300
6250
  *
@@ -5409,7 +6359,7 @@ class ProgramManager {
5409
6359
  * keyProvider.useCache(true);
5410
6360
  *
5411
6361
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
5412
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
6362
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5413
6363
  * const tx = await programManager.buildTransferTransaction(1, "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "public", 0.2, false);
5414
6364
  * await programManager.networkClient.submitTransaction(tx.toString());
5415
6365
  *
@@ -5506,7 +6456,7 @@ class ProgramManager {
5506
6456
  * keyProvider.useCache(true);
5507
6457
  *
5508
6458
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
5509
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
6459
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5510
6460
  * const tx = await programManager.buildTransferPublicTransaction(1, "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", 0.2);
5511
6461
  * await programManager.networkClient.submitTransaction(tx.toString());
5512
6462
  *
@@ -5539,7 +6489,7 @@ class ProgramManager {
5539
6489
  * keyProvider.useCache(true);
5540
6490
  *
5541
6491
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
5542
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
6492
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5543
6493
  * const tx = await programManager.buildTransferPublicAsSignerTransaction(1, "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", 0.2);
5544
6494
  * await programManager.networkClient.submitTransaction(tx.toString());
5545
6495
  *
@@ -5577,7 +6527,7 @@ class ProgramManager {
5577
6527
  * keyProvider.useCache(true);
5578
6528
  *
5579
6529
  * // Initialize a program manager with the key provider to automatically fetch keys for executions
5580
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
6530
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, recordProvider);
5581
6531
  * const tx_id = await programManager.transfer(1, "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "public", 0.2, false);
5582
6532
  *
5583
6533
  * // Verify the transaction was successful
@@ -5622,7 +6572,7 @@ class ProgramManager {
5622
6572
  * keyProvider.useCache(true);
5623
6573
  *
5624
6574
  * // Create a new ProgramManager with the key that will be used to bond credits
5625
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6575
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5626
6576
  * programManager.setAccount(new Account("YourPrivateKey"));
5627
6577
  *
5628
6578
  * // Create the bonding transaction object for later submission
@@ -5678,7 +6628,7 @@ class ProgramManager {
5678
6628
  * keyProvider.useCache(true);
5679
6629
  *
5680
6630
  * // Create a new ProgramManager with the key that will be used to bond credits
5681
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6631
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5682
6632
  *
5683
6633
  * // Create the bonding transaction
5684
6634
  * tx_id = await programManager.bondPublic("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j", "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "aleo1feya8sjy9k2zflvl2dx39pdsq5tju28elnp2ektnn588uu9ghv8s84msv9", 2000000);
@@ -5726,7 +6676,7 @@ class ProgramManager {
5726
6676
  * keyProvider.useCache(true);
5727
6677
  *
5728
6678
  * // Create a new ProgramManager with the key that will be used to bond credits
5729
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6679
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5730
6680
  * programManager.setAccount(new Account("YourPrivateKey"));
5731
6681
  *
5732
6682
  * // Create the bond validator transaction object for later use.
@@ -5785,7 +6735,7 @@ class ProgramManager {
5785
6735
  * keyProvider.useCache(true);
5786
6736
  *
5787
6737
  * // Create a new ProgramManager with the key that will be used to bond credits
5788
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6738
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5789
6739
  * programManager.setAccount(new Account("YourPrivateKey"));
5790
6740
  *
5791
6741
  * // Create the bonding transaction
@@ -5832,7 +6782,7 @@ class ProgramManager {
5832
6782
  * keyProvider.useCache(true);
5833
6783
  *
5834
6784
  * // Create a new ProgramManager with the key that will be used to unbond credits.
5835
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6785
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5836
6786
  * const tx = await programManager.buildUnbondPublicTransaction("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j", 2000000);
5837
6787
  *
5838
6788
  * // The transaction can be submitted later to the network using the network client.
@@ -5885,7 +6835,7 @@ class ProgramManager {
5885
6835
  * keyProvider.useCache(true);
5886
6836
  *
5887
6837
  * // Create a new ProgramManager with the key that will be used to bond credits
5888
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6838
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5889
6839
  * programManager.setAccount(new Account("YourPrivateKey"));
5890
6840
  *
5891
6841
  * // Create the unbond_public transaction and send it to the network
@@ -5931,7 +6881,7 @@ class ProgramManager {
5931
6881
  * keyProvider.useCache(true);
5932
6882
  *
5933
6883
  * // Create a new ProgramManager with the key that will be used to claim unbonded credits.
5934
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6884
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5935
6885
  *
5936
6886
  * // Create the claim_unbond_public transaction object for later use.
5937
6887
  * const tx = await programManager.buildClaimUnbondPublicTransaction("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j");
@@ -5981,7 +6931,7 @@ class ProgramManager {
5981
6931
  * keyProvider.useCache(true);
5982
6932
  *
5983
6933
  * // Create a new ProgramManager with the key that will be used to bond credits
5984
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6934
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
5985
6935
  * programManager.setAccount(new Account("YourPrivateKey"));
5986
6936
  *
5987
6937
  * // Create the claim_unbond_public transaction
@@ -6035,7 +6985,7 @@ class ProgramManager {
6035
6985
  * keyProvider.useCache(true);
6036
6986
  *
6037
6987
  * // Create a new ProgramManager with the key that will be used to bond credits
6038
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
6988
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
6039
6989
  *
6040
6990
  * // Create the set_validator_state transaction
6041
6991
  * const tx = await programManager.buildSetValidatorStateTransaction(true);
@@ -6091,7 +7041,7 @@ class ProgramManager {
6091
7041
  * keyProvider.useCache(true);
6092
7042
  *
6093
7043
  * // Create a new ProgramManager with the key that will be used to bond credits
6094
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, undefined);
7044
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider, undefined);
6095
7045
  *
6096
7046
  * // Create the set_validator_state transaction
6097
7047
  * const tx_id = await programManager.setValidatorState(true);
@@ -6213,7 +7163,7 @@ class ProgramManager {
6213
7163
  * keyProvider.useCache(true);
6214
7164
  *
6215
7165
  * // Initialize a program manager with the key provider to automatically fetch keys for executions.
6216
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
7166
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider);
6217
7167
  *
6218
7168
  * // Build the `Authorization`.
6219
7169
  * const privateKey = new PrivateKey(); // Change this to a private key that has an aleo credit balance.
@@ -6274,7 +7224,7 @@ class ProgramManager {
6274
7224
  * import { AleoKeyProvider, PrivateKey, initThreadPool, ProgramManager } from "@provablehq/sdk";
6275
7225
  *
6276
7226
  * // Initialize a program manager with the key provider to automatically fetch keys for executions.
6277
- * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
7227
+ * const programManager = new ProgramManager("https://api.provable.com/v2", keyProvider);
6278
7228
  *
6279
7229
  * // Get the base fee in microcredits.
6280
7230
  * const baseFeeMicrocredits = await programManager.estimateExecutionFee({programName: "credits.aleo"});
@@ -6687,5 +7637,5 @@ async function initializeWasm() {
6687
7637
  console.warn("initializeWasm is deprecated, you no longer need to use it");
6688
7638
  }
6689
7639
 
6690
- export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoNetworkClient, BlockHeightSearch, CREDITS_PROGRAM_KEYS, 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, RecordScanner, SealanceMerkleTree, VALID_TRANSFER_TYPES, initializeWasm, logAndThrow, promoteMapToKeyStore };
7640
+ 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 };
6691
7641
  //# sourceMappingURL=browser.js.map