@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.
- package/dist/mainnet/account.d.ts +18 -3
- package/dist/mainnet/browser.d.ts +26 -7
- package/dist/mainnet/browser.js +1198 -248
- package/dist/mainnet/browser.js.map +1 -1
- package/dist/mainnet/keys/keystore/error.d.ts +23 -0
- package/dist/mainnet/keys/keystore/file.d.ts +207 -13
- package/dist/mainnet/keys/keystore/interface.d.ts +85 -0
- package/dist/mainnet/keys/provider/interface.d.ts +170 -0
- package/dist/{testnet/keys/provider/function-key-provider.d.ts → mainnet/keys/provider/memory.d.ts} +14 -180
- package/dist/{testnet/keys/provider/offline-key-provider.d.ts → mainnet/keys/provider/offline.d.ts} +4 -4
- package/dist/mainnet/keys/verifier/interface.d.ts +70 -0
- package/dist/mainnet/keys/verifier/memory.d.ts +37 -0
- package/dist/mainnet/models/cryptoBoxPubkey.d.ts +4 -0
- package/dist/mainnet/models/encryptedProvingRequest.d.ts +4 -0
- package/dist/mainnet/models/provingResponse.d.ts +48 -2
- package/dist/mainnet/models/record-scanner/encryptedRecordsResult.d.ts +7 -0
- package/dist/mainnet/models/record-scanner/encryptedRegistrationRequest.d.ts +8 -0
- package/dist/mainnet/models/record-scanner/error.d.ts +47 -0
- package/dist/mainnet/models/record-scanner/ownedFilter.d.ts +0 -2
- package/dist/mainnet/models/record-scanner/ownedRecordsResult.d.ts +13 -0
- package/dist/mainnet/models/record-scanner/registrationResponse.d.ts +0 -2
- package/dist/mainnet/models/record-scanner/registrationResult.d.ts +9 -0
- package/dist/mainnet/models/record-scanner/revokeResult.d.ts +17 -0
- package/dist/mainnet/models/record-scanner/serialNumbersResult.d.ts +15 -0
- package/dist/mainnet/models/record-scanner/statusResult.d.ts +13 -0
- package/dist/mainnet/models/record-scanner/tagsResult.d.ts +12 -0
- package/dist/mainnet/network-client.d.ts +81 -35
- package/dist/mainnet/node.js +345 -75
- package/dist/mainnet/node.js.map +1 -1
- package/dist/mainnet/program-manager.d.ts +54 -48
- package/dist/mainnet/record-provider.d.ts +7 -7
- package/dist/mainnet/record-scanner.d.ts +247 -31
- package/dist/mainnet/security.d.ts +38 -0
- package/dist/mainnet/utils.d.ts +1 -0
- package/dist/testnet/account.d.ts +18 -3
- package/dist/testnet/browser.d.ts +26 -7
- package/dist/testnet/browser.js +1198 -248
- package/dist/testnet/browser.js.map +1 -1
- package/dist/testnet/keys/keystore/error.d.ts +23 -0
- package/dist/testnet/keys/keystore/file.d.ts +207 -13
- package/dist/testnet/keys/keystore/interface.d.ts +85 -0
- package/dist/testnet/keys/provider/interface.d.ts +170 -0
- package/dist/{mainnet/keys/provider/function-key-provider.d.ts → testnet/keys/provider/memory.d.ts} +14 -180
- package/dist/{mainnet/keys/provider/offline-key-provider.d.ts → testnet/keys/provider/offline.d.ts} +4 -4
- package/dist/testnet/keys/verifier/interface.d.ts +70 -0
- package/dist/testnet/keys/verifier/memory.d.ts +37 -0
- package/dist/testnet/models/cryptoBoxPubkey.d.ts +4 -0
- package/dist/testnet/models/encryptedProvingRequest.d.ts +4 -0
- package/dist/testnet/models/provingResponse.d.ts +48 -2
- package/dist/testnet/models/record-scanner/encryptedRecordsResult.d.ts +7 -0
- package/dist/testnet/models/record-scanner/encryptedRegistrationRequest.d.ts +8 -0
- package/dist/testnet/models/record-scanner/error.d.ts +47 -0
- package/dist/testnet/models/record-scanner/ownedFilter.d.ts +0 -2
- package/dist/testnet/models/record-scanner/ownedRecordsResult.d.ts +13 -0
- package/dist/testnet/models/record-scanner/registrationResponse.d.ts +0 -2
- package/dist/testnet/models/record-scanner/registrationResult.d.ts +9 -0
- package/dist/testnet/models/record-scanner/revokeResult.d.ts +17 -0
- package/dist/testnet/models/record-scanner/serialNumbersResult.d.ts +15 -0
- package/dist/testnet/models/record-scanner/statusResult.d.ts +13 -0
- package/dist/testnet/models/record-scanner/tagsResult.d.ts +12 -0
- package/dist/testnet/network-client.d.ts +81 -35
- package/dist/testnet/node.js +345 -75
- package/dist/testnet/node.js.map +1 -1
- package/dist/testnet/program-manager.d.ts +54 -48
- package/dist/testnet/record-provider.d.ts +7 -7
- package/dist/testnet/record-scanner.d.ts +247 -31
- package/dist/testnet/security.d.ts +38 -0
- package/dist/testnet/utils.d.ts +1 -0
- package/package.json +4 -3
- package/dist/mainnet/keys/keystore/keystore.d.ts +0 -81
- package/dist/mainnet/keys/keystore/memory.d.ts +0 -8
- package/dist/testnet/keys/keystore/keystore.d.ts +0 -81
- package/dist/testnet/keys/keystore/memory.d.ts +0 -8
package/dist/mainnet/browser.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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("
|
|
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
|
|
600
|
-
|
|
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.
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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
|
-
*
|
|
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
|
|
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
|
|
1989
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
2011
|
-
|
|
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
|
-
|
|
2016
|
-
return
|
|
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 (
|
|
2019
|
-
|
|
2020
|
-
|
|
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("
|
|
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
|
-
*
|
|
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
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
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
|
|
2173
|
-
* verifying keys for the credits.aleo program over
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
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.
|
|
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.
|
|
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
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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("
|
|
3409
|
-
* const
|
|
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
|
-
|
|
3447
|
-
|
|
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
|
-
|
|
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
|
|
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 {
|
|
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
|
-
|
|
3463
|
-
|
|
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
|
|
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<
|
|
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
|
-
|
|
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
|
-
|
|
3484
|
-
|
|
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 (
|
|
3487
|
-
console.error(`Failed to register view key: ${
|
|
3488
|
-
|
|
4125
|
+
catch (err) {
|
|
4126
|
+
console.error(`Failed to register view key: ${err}`);
|
|
4127
|
+
return this.handleRequestError(err);
|
|
3489
4128
|
}
|
|
3490
4129
|
}
|
|
3491
4130
|
/**
|
|
3492
|
-
*
|
|
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<
|
|
4233
|
+
* @returns {Promise<EncryptedRecordsResult>} The encrypted records or an error if the request failed.
|
|
3496
4234
|
*/
|
|
3497
|
-
async
|
|
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
|
-
|
|
4242
|
+
const data = await response.json();
|
|
4243
|
+
return { ok: true, data };
|
|
3505
4244
|
}
|
|
3506
|
-
catch (
|
|
3507
|
-
|
|
3508
|
-
throw error;
|
|
4245
|
+
catch (err) {
|
|
4246
|
+
return this.handleRequestError(err);
|
|
3509
4247
|
}
|
|
3510
4248
|
}
|
|
3511
4249
|
/**
|
|
3512
|
-
*
|
|
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<
|
|
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
|
|
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
|
-
|
|
4274
|
+
const data = await response.json();
|
|
4275
|
+
return { ok: true, data };
|
|
3525
4276
|
}
|
|
3526
|
-
catch (
|
|
3527
|
-
|
|
3528
|
-
throw error;
|
|
4277
|
+
catch (err) {
|
|
4278
|
+
return this.handleRequestError(err);
|
|
3529
4279
|
}
|
|
3530
4280
|
}
|
|
3531
4281
|
/**
|
|
3532
|
-
* Check if
|
|
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<
|
|
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
|
|
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
|
-
|
|
4307
|
+
const data = await response.json();
|
|
4308
|
+
return { ok: true, data };
|
|
3545
4309
|
}
|
|
3546
|
-
catch (
|
|
3547
|
-
|
|
3548
|
-
throw error;
|
|
4310
|
+
catch (err) {
|
|
4311
|
+
return this.handleRequestError(err);
|
|
3549
4312
|
}
|
|
3550
4313
|
}
|
|
3551
4314
|
/**
|
|
3552
|
-
* Check
|
|
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}
|
|
3555
|
-
* @returns {Promise<
|
|
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
|
|
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(
|
|
4347
|
+
body: JSON.stringify(uuid.toString()),
|
|
3563
4348
|
}));
|
|
3564
|
-
|
|
4349
|
+
const data = await response.json();
|
|
4350
|
+
return { ok: true, data };
|
|
3565
4351
|
}
|
|
3566
|
-
catch (
|
|
3567
|
-
|
|
3568
|
-
throw error;
|
|
4352
|
+
catch (err) {
|
|
4353
|
+
return this.handleRequestError(err);
|
|
3569
4354
|
}
|
|
3570
4355
|
}
|
|
3571
4356
|
/**
|
|
3572
|
-
* Find a record in the record
|
|
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
|
-
*
|
|
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
|
|
3594
|
-
* @returns {Promise<
|
|
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
|
|
3597
|
-
|
|
3598
|
-
|
|
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 =
|
|
3601
|
-
|
|
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
|
-
|
|
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 (
|
|
3610
|
-
|
|
3611
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
4509
|
+
responseFilter: searchParameters.responseFilter,
|
|
4510
|
+
uuid,
|
|
3632
4511
|
});
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
const
|
|
3636
|
-
|
|
3637
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
4563
|
+
responseFilter: searchParameters.responseFilter,
|
|
4564
|
+
uuid,
|
|
3667
4565
|
});
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
const
|
|
3671
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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),
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
4514
|
-
edition =
|
|
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.
|
|
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.
|
|
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
|
|
4798
|
-
edition =
|
|
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.
|
|
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
|
|
4891
|
-
edition =
|
|
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.
|
|
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
|
|
4960
|
-
edition =
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|
|
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
|