@provablehq/sdk 0.9.15-enc → 0.9.15-experimental
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 +0 -15
- package/dist/mainnet/browser.d.ts +2 -5
- package/dist/mainnet/browser.js +30 -429
- package/dist/mainnet/browser.js.map +1 -1
- package/dist/mainnet/models/provingResponse.d.ts +2 -48
- package/dist/mainnet/network-client.d.ts +2 -48
- package/dist/mainnet/node.js +1 -2
- package/dist/mainnet/node.js.map +1 -1
- package/dist/mainnet/record-scanner.d.ts +5 -53
- package/dist/testnet/account.d.ts +0 -15
- package/dist/testnet/browser.d.ts +2 -5
- package/dist/testnet/browser.js +30 -429
- package/dist/testnet/browser.js.map +1 -1
- package/dist/testnet/models/provingResponse.d.ts +2 -48
- package/dist/testnet/network-client.d.ts +2 -48
- package/dist/testnet/node.js +1 -2
- package/dist/testnet/node.js.map +1 -1
- package/dist/testnet/record-scanner.d.ts +5 -53
- package/package.json +2 -3
- package/dist/mainnet/models/cryptoBoxPubkey.d.ts +0 -4
- package/dist/mainnet/models/encryptedProvingRequest.d.ts +0 -4
- package/dist/mainnet/models/record-scanner/encryptedRegistrationRequest.d.ts +0 -8
- package/dist/mainnet/models/record-scanner/registrationResult.d.ts +0 -26
- package/dist/mainnet/security.d.ts +0 -38
- package/dist/testnet/models/cryptoBoxPubkey.d.ts +0 -4
- package/dist/testnet/models/encryptedProvingRequest.d.ts +0 -4
- package/dist/testnet/models/record-scanner/encryptedRegistrationRequest.d.ts +0 -8
- package/dist/testnet/models/record-scanner/registrationResult.d.ts +0 -26
- package/dist/testnet/security.d.ts +0 -38
package/dist/testnet/browser.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
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/testnet.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/testnet.js';
|
|
4
|
-
import sodium from 'libsodium-wrappers';
|
|
5
4
|
import { bech32m } from '@scure/base';
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -73,23 +72,6 @@ class Account {
|
|
|
73
72
|
throw new Error("Wrong password or invalid ciphertext");
|
|
74
73
|
}
|
|
75
74
|
}
|
|
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
|
-
}
|
|
93
75
|
/**
|
|
94
76
|
* Creates a PrivateKey from the provided parameters.
|
|
95
77
|
* @param {AccountParam} params The parameters containing either a private key string or a seed
|
|
@@ -484,91 +466,6 @@ async function retryWithBackoff(fn, { maxAttempts = 5, baseDelay = 100, jitter,
|
|
|
484
466
|
throw new Error("retryWithBackoff: unreachable");
|
|
485
467
|
}
|
|
486
468
|
|
|
487
|
-
/** Type guard: value is a ProvingResponse. */
|
|
488
|
-
function isProvingResponse(value) {
|
|
489
|
-
return (typeof value === "object" &&
|
|
490
|
-
value !== null &&
|
|
491
|
-
"transaction" in value &&
|
|
492
|
-
"broadcast_result" in value &&
|
|
493
|
-
typeof value.broadcast_result === "object");
|
|
494
|
-
}
|
|
495
|
-
/** Type guard: value is a ProveApiErrorBody. */
|
|
496
|
-
function isProveApiErrorBody(value) {
|
|
497
|
-
return (typeof value === "object" &&
|
|
498
|
-
value !== null &&
|
|
499
|
-
"message" in value);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
await sodium.ready;
|
|
503
|
-
/**
|
|
504
|
-
* Encrypt an authorization with a libsodium cryptobox public key.
|
|
505
|
-
*
|
|
506
|
-
* @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
|
|
507
|
-
* @param {Authorization} authorization the authorization to encrypt.
|
|
508
|
-
*
|
|
509
|
-
* @returns {string} the encrypted authorization in RFC 4648 standard Base64.
|
|
510
|
-
*/
|
|
511
|
-
function encryptAuthorization(publicKey, authorization) {
|
|
512
|
-
// Ready the cryptobox lib.
|
|
513
|
-
return encryptMessage(publicKey, authorization.toBytesLe());
|
|
514
|
-
}
|
|
515
|
-
/**
|
|
516
|
-
* Encrypt a ProvingRequest with a libsodium cryptobox public key.
|
|
517
|
-
*
|
|
518
|
-
* @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
|
|
519
|
-
* @param {Authorization} provingRequest the ProvingRequest to encrypt.
|
|
520
|
-
*
|
|
521
|
-
* @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
|
|
522
|
-
*/
|
|
523
|
-
function encryptProvingRequest(publicKey, provingRequest) {
|
|
524
|
-
return encryptMessage(publicKey, provingRequest.toBytesLe());
|
|
525
|
-
}
|
|
526
|
-
/**
|
|
527
|
-
* Encrypt a view key with a libsodium cryptobox public key.
|
|
528
|
-
*
|
|
529
|
-
* @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
|
|
530
|
-
* @param {ViewKey} viewKey the view key to encrypt.
|
|
531
|
-
*
|
|
532
|
-
* @returns {string} the encrypted view key in RFC 4648 standard Base64.
|
|
533
|
-
*/
|
|
534
|
-
function encryptViewKey(publicKey, viewKey) {
|
|
535
|
-
return encryptMessage(publicKey, viewKey.toBytesLe());
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Encrypt a record scanner registration request.
|
|
539
|
-
*
|
|
540
|
-
* @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
|
|
541
|
-
* @param {ViewKey} viewKey the view key to encrypt.
|
|
542
|
-
* @param {number} start the start height of the registration request.
|
|
543
|
-
*
|
|
544
|
-
* @returns {string} the encrypted view key in RFC 4648 standard Base64.
|
|
545
|
-
*/
|
|
546
|
-
function encryptRegistrationRequest(publicKey, viewKey, start) {
|
|
547
|
-
// Turn the view key into a Uint8Array.
|
|
548
|
-
const vk_bytes = viewKey.toBytesLe();
|
|
549
|
-
// Create a new array to hold the original bytes and the 4-byte start height.
|
|
550
|
-
const bytes = new Uint8Array(vk_bytes.length + 4);
|
|
551
|
-
// Copy existing bytes.
|
|
552
|
-
bytes.set(vk_bytes, 0);
|
|
553
|
-
// Write the 4-byte number in LE format at the end of the array.
|
|
554
|
-
const view = new DataView(bytes.buffer);
|
|
555
|
-
view.setUint32(vk_bytes.length, start, true);
|
|
556
|
-
// Encrypt the encoded bytes.
|
|
557
|
-
return encryptMessage(publicKey, bytes);
|
|
558
|
-
}
|
|
559
|
-
/**
|
|
560
|
-
* Encrypt arbitrary bytes with a libsodium cryptobox public key.
|
|
561
|
-
*
|
|
562
|
-
* @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
|
|
563
|
-
* @param {Uint8Array} message the bytes to encrypt.
|
|
564
|
-
*
|
|
565
|
-
* @returns {string} the encrypted bytes in RFC 4648 standard Base64.
|
|
566
|
-
*/
|
|
567
|
-
function encryptMessage(publicKey, message) {
|
|
568
|
-
const publicKeyBytes = sodium.from_base64(publicKey, sodium.base64_variants.ORIGINAL);
|
|
569
|
-
return sodium.to_base64(sodium.crypto_box_seal(message, publicKeyBytes), sodium.base64_variants.ORIGINAL);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
469
|
const KEY_STORE = Metadata.baseUrl();
|
|
573
470
|
function convert(metadata) {
|
|
574
471
|
// This looks up the method name in VerifyingKey
|
|
@@ -694,37 +591,18 @@ class AleoNetworkClient {
|
|
|
694
591
|
apiKey;
|
|
695
592
|
consumerId;
|
|
696
593
|
jwtData;
|
|
697
|
-
proverUri;
|
|
698
|
-
recordScannerUri;
|
|
699
594
|
constructor(host, options) {
|
|
700
595
|
this.host = host + "/testnet";
|
|
701
596
|
this.network = "testnet";
|
|
702
597
|
this.ctx = {};
|
|
703
598
|
this.verboseErrors = true;
|
|
704
|
-
if (options) {
|
|
705
|
-
|
|
706
|
-
this.headers = options.headers;
|
|
707
|
-
}
|
|
708
|
-
else {
|
|
709
|
-
this.headers = {
|
|
710
|
-
// This is replaced by the actual version by a Rollup plugin
|
|
711
|
-
"X-Aleo-SDK-Version": "0.9.15-enc",
|
|
712
|
-
"X-Aleo-environment": environment(),
|
|
713
|
-
};
|
|
714
|
-
}
|
|
715
|
-
// If a prover uri was specified, set the prover uri.
|
|
716
|
-
if (options.proverUri) {
|
|
717
|
-
this.proverUri = options.proverUri + "/testnet";
|
|
718
|
-
}
|
|
719
|
-
// If a record scanner uri was specified, set the record scanner uri.
|
|
720
|
-
if (options.recordScannerUri) {
|
|
721
|
-
this.recordScannerUri = options.recordScannerUri + "/testnet";
|
|
722
|
-
}
|
|
599
|
+
if (options && options.headers) {
|
|
600
|
+
this.headers = options.headers;
|
|
723
601
|
}
|
|
724
602
|
else {
|
|
725
603
|
this.headers = {
|
|
726
604
|
// This is replaced by the actual version by a Rollup plugin
|
|
727
|
-
"X-Aleo-SDK-Version": "0.9.15-
|
|
605
|
+
"X-Aleo-SDK-Version": "0.9.15-experimental",
|
|
728
606
|
"X-Aleo-environment": environment(),
|
|
729
607
|
};
|
|
730
608
|
}
|
|
@@ -769,40 +647,6 @@ class AleoNetworkClient {
|
|
|
769
647
|
setHost(host) {
|
|
770
648
|
this.host = host + "/testnet";
|
|
771
649
|
}
|
|
772
|
-
/**
|
|
773
|
-
* Set a new uri for a remote prover.
|
|
774
|
-
*
|
|
775
|
-
* @param {string} proverUri The uri of the remote prover.
|
|
776
|
-
*
|
|
777
|
-
* @example
|
|
778
|
-
* import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
|
|
779
|
-
*
|
|
780
|
-
* // Create a networkClient that connects to the provable explorer api.
|
|
781
|
-
* const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
|
|
782
|
-
*
|
|
783
|
-
* // Set the prover uri.
|
|
784
|
-
* networkClient.setProverUri("https://prover.provable.prove");
|
|
785
|
-
*/
|
|
786
|
-
setProverUri(proverUri) {
|
|
787
|
-
this.proverUri = proverUri + "/testnet";
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Set a new uri for a remote record scanner.
|
|
791
|
-
*
|
|
792
|
-
* @param {string} recordScannerUri The uri of the remote record scanner.
|
|
793
|
-
*
|
|
794
|
-
* @example
|
|
795
|
-
* import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
|
|
796
|
-
*
|
|
797
|
-
* // Create a networkClient that connects to the provable explorer api.
|
|
798
|
-
* const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
|
|
799
|
-
*
|
|
800
|
-
* // Set the record scanner uri.
|
|
801
|
-
* networkClient.setRecordScannerUri("https://scanner.provable.scan");
|
|
802
|
-
*/
|
|
803
|
-
setRecordScannerUri(recordScannerUri) {
|
|
804
|
-
this.recordScannerUri = recordScannerUri + "/testnet";
|
|
805
|
-
}
|
|
806
650
|
/**
|
|
807
651
|
* 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.
|
|
808
652
|
*
|
|
@@ -2128,87 +1972,33 @@ class AleoNetworkClient {
|
|
|
2128
1972
|
};
|
|
2129
1973
|
}
|
|
2130
1974
|
/**
|
|
2131
|
-
*
|
|
2132
|
-
*/
|
|
2133
|
-
async handleProvingResponse(response) {
|
|
2134
|
-
// Get the proving response text.
|
|
2135
|
-
const text = await response.text();
|
|
2136
|
-
let body;
|
|
2137
|
-
// Parse the body.
|
|
2138
|
-
try {
|
|
2139
|
-
body = parseJSON(text);
|
|
2140
|
-
}
|
|
2141
|
-
catch {
|
|
2142
|
-
body = {};
|
|
2143
|
-
}
|
|
2144
|
-
// If the status is 200, attempt to parse the Proving Request along its expected structure.
|
|
2145
|
-
if (response.status === 200) {
|
|
2146
|
-
if (isProvingResponse(body)) {
|
|
2147
|
-
return { ok: true, data: body };
|
|
2148
|
-
}
|
|
2149
|
-
return {
|
|
2150
|
-
ok: false,
|
|
2151
|
-
status: response.status,
|
|
2152
|
-
error: { message: "Invalid response from proving service" },
|
|
2153
|
-
};
|
|
2154
|
-
}
|
|
2155
|
-
// If the response is non 200, return the information back to the caller so it can be handled.
|
|
2156
|
-
if (response.status === 400 || response.status === 500 || response.status === 503) {
|
|
2157
|
-
const error = isProveApiErrorBody(body)
|
|
2158
|
-
? body
|
|
2159
|
-
: { message: text || `${response.status} error` };
|
|
2160
|
-
return { ok: false, status: response.status, error };
|
|
2161
|
-
}
|
|
2162
|
-
return {
|
|
2163
|
-
ok: false,
|
|
2164
|
-
status: response.status,
|
|
2165
|
-
error: { message: text || `${response.status} error` },
|
|
2166
|
-
};
|
|
2167
|
-
}
|
|
2168
|
-
/**
|
|
2169
|
-
* 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.
|
|
1975
|
+
* Submit a `ProvingRequest` to a remote proving service for delegated proving. If the broadcast flag of the `ProvingRequest` is set to `true` the remote service will attempt to broadcast the result `Transaction` on behalf of the requestor.
|
|
2170
1976
|
*
|
|
2171
1977
|
* @param {DelegatedProvingParams} options - The optional parameters required to submit a proving request.
|
|
2172
1978
|
* @returns {Promise<ProvingResponse>} The ProvingResponse containing the transaction result and the result of the broadcast if the `broadcast` flag was set to `true`.
|
|
2173
1979
|
*/
|
|
2174
1980
|
async submitProvingRequest(options) {
|
|
2175
|
-
const
|
|
2176
|
-
if (result.ok) {
|
|
2177
|
-
return result.data;
|
|
2178
|
-
}
|
|
2179
|
-
const err = new Error(result.error.message);
|
|
2180
|
-
err.status = result.status;
|
|
2181
|
-
throw err;
|
|
2182
|
-
}
|
|
2183
|
-
/**
|
|
2184
|
-
* 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.
|
|
2185
|
-
*
|
|
2186
|
-
* @param {DelegatedProvingParams} options - The optional parameters required to submit a proving request.
|
|
2187
|
-
* @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`.
|
|
2188
|
-
*/
|
|
2189
|
-
async submitProvingRequestSafe(options) {
|
|
2190
|
-
// Attempt to get the Prover URI first from the options, then from any configured globally, or third try the main configured host.
|
|
2191
|
-
const proverUri = (options.url ?? this.proverUri) ?? this.host;
|
|
1981
|
+
const proverUri = options.url ?? this.host;
|
|
2192
1982
|
const provingRequestString = options.provingRequest instanceof ProvingRequest
|
|
2193
1983
|
? options.provingRequest.toString()
|
|
2194
1984
|
: options.provingRequest;
|
|
2195
|
-
// Try to get JWT data to access the Provable API.
|
|
2196
1985
|
const apiKey = options.apiKey ?? this.apiKey;
|
|
2197
1986
|
const consumerId = options.consumerId ?? this.consumerId;
|
|
2198
1987
|
let jwtData = options.jwtData ?? this.jwtData;
|
|
2199
|
-
// Check
|
|
2200
|
-
const
|
|
1988
|
+
// Check if JWT is expired or missing
|
|
1989
|
+
const bufferTime = FIVE_MINUTES; // 5 minutes buffer
|
|
1990
|
+
const isExpired = jwtData && Date.now() >= jwtData.expiration - bufferTime;
|
|
2201
1991
|
if (!jwtData || isExpired) {
|
|
2202
1992
|
if (options.apiKey && options.consumerId) {
|
|
2203
1993
|
jwtData = await this.refreshJwt(apiKey, consumerId);
|
|
1994
|
+
// Update both the class and the options with the new JWT
|
|
2204
1995
|
this.jwtData = jwtData;
|
|
2205
1996
|
options.jwtData = jwtData;
|
|
2206
1997
|
}
|
|
2207
1998
|
else {
|
|
2208
|
-
|
|
1999
|
+
throw new Error('JWT or both apiKey and consumerId are required');
|
|
2209
2000
|
}
|
|
2210
2001
|
}
|
|
2211
|
-
// Create the necessary headers to hit the provable api.
|
|
2212
2002
|
const headers = {
|
|
2213
2003
|
...this.headers,
|
|
2214
2004
|
"X-ALEO-METHOD": "submitProvingRequest",
|
|
@@ -2217,67 +2007,17 @@ class AleoNetworkClient {
|
|
|
2217
2007
|
if (jwtData?.jwt) {
|
|
2218
2008
|
headers["Authorization"] = jwtData.jwt;
|
|
2219
2009
|
}
|
|
2220
|
-
// Encapsulate the requests in a locally scoped function that can be run with a retry closure.
|
|
2221
|
-
const runRequest = async () => {
|
|
2222
|
-
// If DPS privacy is set, call invoke the encrypted flow.
|
|
2223
|
-
if (options.dpsPrivacy) {
|
|
2224
|
-
// Get an ephemeral public key from a DPS service.
|
|
2225
|
-
const pubKeyResponse = await get(proverUri + "/pubkey", {
|
|
2226
|
-
headers,
|
|
2227
|
-
});
|
|
2228
|
-
// Encrypt the provingRequest.
|
|
2229
|
-
const pubkey = parseJSON(await pubKeyResponse.text());
|
|
2230
|
-
const ciphertext = encryptProvingRequest(pubkey.public_key, ProvingRequest.fromString(provingRequestString));
|
|
2231
|
-
// Form the expected query a DPS service expects (including the key_id).
|
|
2232
|
-
const payload = {
|
|
2233
|
-
key_id: pubkey.key_id,
|
|
2234
|
-
ciphertext: ciphertext,
|
|
2235
|
-
};
|
|
2236
|
-
const res = await fetch(`${proverUri}/prove/encrypted`, {
|
|
2237
|
-
method: "POST",
|
|
2238
|
-
body: JSON.stringify(payload),
|
|
2239
|
-
headers,
|
|
2240
|
-
});
|
|
2241
|
-
// Properly handle the proving response.
|
|
2242
|
-
return this.handleProvingResponse(res);
|
|
2243
|
-
}
|
|
2244
|
-
// If encrypted usage is not specified use the unencrypted endpoint.
|
|
2245
|
-
const proveEndpoint = proverUri.endsWith("/prove")
|
|
2246
|
-
? proverUri
|
|
2247
|
-
: proverUri + "/prove";
|
|
2248
|
-
const res = await fetch(proveEndpoint, {
|
|
2249
|
-
method: "POST",
|
|
2250
|
-
body: provingRequestString,
|
|
2251
|
-
headers,
|
|
2252
|
-
});
|
|
2253
|
-
// Properly handle the proving response.
|
|
2254
|
-
return this.handleProvingResponse(res);
|
|
2255
|
-
};
|
|
2256
2010
|
try {
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
}
|
|
2264
|
-
// If 500s are hit responses are returned, attempt retries.
|
|
2265
|
-
if (result.status === 500 || result.status === 503) {
|
|
2266
|
-
const err = new Error(result.error.message);
|
|
2267
|
-
err.status = result.status;
|
|
2268
|
-
throw err;
|
|
2269
|
-
}
|
|
2270
|
-
return result;
|
|
2271
|
-
});
|
|
2011
|
+
const response = await retryWithBackoff(() => post(`${proverUri}`, {
|
|
2012
|
+
body: provingRequestString,
|
|
2013
|
+
headers
|
|
2014
|
+
}));
|
|
2015
|
+
const responseText = await response.text();
|
|
2016
|
+
return parseJSON(responseText);
|
|
2272
2017
|
}
|
|
2273
|
-
catch (
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
return {
|
|
2277
|
-
ok: false,
|
|
2278
|
-
status: e.status ?? 500,
|
|
2279
|
-
error: { message: e.message },
|
|
2280
|
-
};
|
|
2018
|
+
catch (error) {
|
|
2019
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
2020
|
+
throw new Error(`Failed to submit proving request: ${errorMessage}`);
|
|
2281
2021
|
}
|
|
2282
2022
|
}
|
|
2283
2023
|
/**
|
|
@@ -3593,20 +3333,6 @@ class BlockHeightSearch {
|
|
|
3593
3333
|
}
|
|
3594
3334
|
}
|
|
3595
3335
|
|
|
3596
|
-
/**
|
|
3597
|
-
* Error thrown when a record scanner request fails (e.g. /register, /register/encrypted).
|
|
3598
|
-
* Includes HTTP status so callers can handle 422 vs 500 etc.
|
|
3599
|
-
*/
|
|
3600
|
-
class RecordScannerRequestError extends Error {
|
|
3601
|
-
status;
|
|
3602
|
-
constructor(message, status) {
|
|
3603
|
-
super(message);
|
|
3604
|
-
this.name = "RecordScannerRequestError";
|
|
3605
|
-
this.status = status;
|
|
3606
|
-
Object.setPrototypeOf(this, RecordScannerRequestError.prototype);
|
|
3607
|
-
}
|
|
3608
|
-
}
|
|
3609
|
-
|
|
3610
3336
|
/**
|
|
3611
3337
|
* RecordScanner is a RecordProvider implementation that uses the record scanner service to find records.
|
|
3612
3338
|
*
|
|
@@ -3616,8 +3342,7 @@ class RecordScannerRequestError extends Error {
|
|
|
3616
3342
|
* const recordScanner = new RecordScanner({ url: "https://record-scanner.aleo.org" });
|
|
3617
3343
|
* recordScanner.setAccount(account);
|
|
3618
3344
|
* recordScanner.setApiKey("your-api-key");
|
|
3619
|
-
* const
|
|
3620
|
-
* if (result.ok) { const uuid = result.data.uuid; }
|
|
3345
|
+
* const uuid = await recordScanner.register(0);
|
|
3621
3346
|
*
|
|
3622
3347
|
* const filter = {
|
|
3623
3348
|
* uuid,
|
|
@@ -3653,21 +3378,9 @@ class RecordScanner {
|
|
|
3653
3378
|
url;
|
|
3654
3379
|
apiKey;
|
|
3655
3380
|
uuid;
|
|
3656
|
-
consumerId;
|
|
3657
|
-
jwtData;
|
|
3658
3381
|
constructor(options) {
|
|
3659
|
-
|
|
3660
|
-
const network = "/testnet";
|
|
3661
|
-
// If the user has configured a network in their uri, throw
|
|
3662
|
-
if (options.url.endsWith("/mainnet") || options.url.endsWith("/testnet")) {
|
|
3663
|
-
throw new Error("The record scanning url should not include the specific network, this is automatically configured by the Provable SDK.");
|
|
3664
|
-
}
|
|
3665
|
-
// Configure the url to use the network the SDK is using.
|
|
3666
|
-
this.url = options.url + network;
|
|
3667
|
-
// Configure authentication options/
|
|
3382
|
+
this.url = options.url;
|
|
3668
3383
|
this.apiKey = typeof options.apiKey === "string" ? { header: "X-Provable-API-Key", value: options.apiKey } : options.apiKey;
|
|
3669
|
-
this.consumerId = options.consumerId;
|
|
3670
|
-
this.jwtData = options.jwtData;
|
|
3671
3384
|
}
|
|
3672
3385
|
/**
|
|
3673
3386
|
* Set the API key to use for the record scanner.
|
|
@@ -3677,59 +3390,6 @@ class RecordScanner {
|
|
|
3677
3390
|
async setApiKey(apiKey) {
|
|
3678
3391
|
this.apiKey = typeof apiKey === "string" ? { header: "X-Provable-API-Key", value: apiKey } : apiKey;
|
|
3679
3392
|
}
|
|
3680
|
-
/**
|
|
3681
|
-
* Set the consumer ID used for JWT refresh when using authenticated record scanner (e.g. Provable API).
|
|
3682
|
-
*/
|
|
3683
|
-
async setConsumerId(consumerId) {
|
|
3684
|
-
this.consumerId = consumerId;
|
|
3685
|
-
}
|
|
3686
|
-
/**
|
|
3687
|
-
* Set JWT data for authentication. Optional; when not set, JWT can be refreshed from apiKey + consumerId if provided.
|
|
3688
|
-
*/
|
|
3689
|
-
async setJwtData(jwtData) {
|
|
3690
|
-
this.jwtData = jwtData;
|
|
3691
|
-
}
|
|
3692
|
-
/**
|
|
3693
|
-
* Refreshes the JWT by making a POST request to /jwts/{consumer_id}. Used when authentication is required.
|
|
3694
|
-
*/
|
|
3695
|
-
async refreshJwt(apiKey, consumerId) {
|
|
3696
|
-
const response = await post(`https://api.provable.com/jwts/${consumerId}`, {
|
|
3697
|
-
headers: {
|
|
3698
|
-
"X-Provable-API-Key": apiKey,
|
|
3699
|
-
},
|
|
3700
|
-
});
|
|
3701
|
-
const authHeader = response.headers.get("authorization");
|
|
3702
|
-
if (!authHeader) {
|
|
3703
|
-
throw new Error("No authorization header in JWT refresh response");
|
|
3704
|
-
}
|
|
3705
|
-
const body = await response.json();
|
|
3706
|
-
return {
|
|
3707
|
-
jwt: authHeader,
|
|
3708
|
-
expiration: body.exp * 1000, // Convert to milliseconds
|
|
3709
|
-
};
|
|
3710
|
-
}
|
|
3711
|
-
/**
|
|
3712
|
-
* Returns auth headers (e.g. Authorization with JWT). Refreshes JWT if expired and apiKey + consumerId are set. Empty when auth is not configured.
|
|
3713
|
-
*/
|
|
3714
|
-
async getAuthHeaders() {
|
|
3715
|
-
let jwtData = this.jwtData;
|
|
3716
|
-
const isExpired = jwtData && Date.now() >= jwtData.expiration - FIVE_MINUTES;
|
|
3717
|
-
if (!jwtData || isExpired) {
|
|
3718
|
-
const apiKey = this.apiKey?.value;
|
|
3719
|
-
if (apiKey && this.consumerId) {
|
|
3720
|
-
jwtData = await this.refreshJwt(apiKey, this.consumerId);
|
|
3721
|
-
this.jwtData = jwtData;
|
|
3722
|
-
}
|
|
3723
|
-
else if (jwtData?.jwt) {
|
|
3724
|
-
// Use existing JWT even if expired when we can't refresh
|
|
3725
|
-
return { Authorization: jwtData.jwt };
|
|
3726
|
-
}
|
|
3727
|
-
else {
|
|
3728
|
-
return {};
|
|
3729
|
-
}
|
|
3730
|
-
}
|
|
3731
|
-
return jwtData?.jwt ? { Authorization: jwtData.jwt } : {};
|
|
3732
|
-
}
|
|
3733
3393
|
/**
|
|
3734
3394
|
* Set the UUID to use for the record scanner.
|
|
3735
3395
|
*
|
|
@@ -3739,15 +3399,14 @@ class RecordScanner {
|
|
|
3739
3399
|
this.uuid = uuidOrViewKey instanceof ViewKey ? this.computeUUID(uuidOrViewKey) : uuidOrViewKey;
|
|
3740
3400
|
}
|
|
3741
3401
|
/**
|
|
3742
|
-
* Register the account with the record scanner service
|
|
3402
|
+
* Register the account with the record scanner service.
|
|
3743
3403
|
*
|
|
3744
|
-
* @param {ViewKey} viewKey The view key to register.
|
|
3745
3404
|
* @param {number} startBlock The block height to start scanning from.
|
|
3746
|
-
* @returns {Promise<
|
|
3405
|
+
* @returns {Promise<RegistrationResponse>} The response from the record scanner service.
|
|
3747
3406
|
*/
|
|
3748
3407
|
async register(viewKey, startBlock) {
|
|
3749
3408
|
try {
|
|
3750
|
-
|
|
3409
|
+
let request = {
|
|
3751
3410
|
view_key: viewKey.to_string(),
|
|
3752
3411
|
start: startBlock,
|
|
3753
3412
|
};
|
|
@@ -3758,63 +3417,11 @@ class RecordScanner {
|
|
|
3758
3417
|
}));
|
|
3759
3418
|
const data = await response.json();
|
|
3760
3419
|
this.uuid = data.uuid;
|
|
3761
|
-
return
|
|
3762
|
-
}
|
|
3763
|
-
catch (err) {
|
|
3764
|
-
if (err instanceof RecordScannerRequestError) {
|
|
3765
|
-
return {
|
|
3766
|
-
ok: false,
|
|
3767
|
-
status: err.status,
|
|
3768
|
-
error: { message: err.message },
|
|
3769
|
-
};
|
|
3770
|
-
}
|
|
3771
|
-
console.error(`Failed to register view key: ${err}`);
|
|
3772
|
-
throw err;
|
|
3420
|
+
return data;
|
|
3773
3421
|
}
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
* Follows the same pattern as the delegated proving service /pubkey endpoint.
|
|
3778
|
-
*
|
|
3779
|
-
* @returns {Promise<CryptoBoxPubKey>} The service's ephemeral public key and key_id.
|
|
3780
|
-
*/
|
|
3781
|
-
async getPubkey() {
|
|
3782
|
-
const response = await this.request(new Request(`${this.url}/pubkey`, { method: "GET" }));
|
|
3783
|
-
return parseJSON(await response.text());
|
|
3784
|
-
}
|
|
3785
|
-
/**
|
|
3786
|
-
* Registers the account with the record scanner 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.
|
|
3787
|
-
*
|
|
3788
|
-
* @param {ViewKey} viewKey The view key to register.
|
|
3789
|
-
* @param {number} startBlock The block height to start scanning from.
|
|
3790
|
-
* @returns {Promise<RegisterResult>} `{ ok: true, data }` on success, or `{ ok: false, status, error }` on failure.
|
|
3791
|
-
*/
|
|
3792
|
-
async registerEncrypted(viewKey, startBlock) {
|
|
3793
|
-
try {
|
|
3794
|
-
const pubkey = await this.getPubkey();
|
|
3795
|
-
const ciphertext = encryptRegistrationRequest(pubkey.public_key, viewKey, startBlock);
|
|
3796
|
-
const payload = {
|
|
3797
|
-
key_id: pubkey.key_id,
|
|
3798
|
-
ciphertext,
|
|
3799
|
-
};
|
|
3800
|
-
const response = await this.request(new Request(`${this.url}/register/encrypted`, {
|
|
3801
|
-
method: "POST",
|
|
3802
|
-
headers: { "Content-Type": "application/json" },
|
|
3803
|
-
body: JSON.stringify(payload),
|
|
3804
|
-
}));
|
|
3805
|
-
const data = await response.json();
|
|
3806
|
-
this.uuid = data.uuid;
|
|
3807
|
-
return { ok: true, data };
|
|
3808
|
-
}
|
|
3809
|
-
catch (err) {
|
|
3810
|
-
if (err instanceof RecordScannerRequestError) {
|
|
3811
|
-
return {
|
|
3812
|
-
ok: false,
|
|
3813
|
-
status: err.status,
|
|
3814
|
-
error: { message: err.message },
|
|
3815
|
-
};
|
|
3816
|
-
}
|
|
3817
|
-
throw err;
|
|
3422
|
+
catch (error) {
|
|
3423
|
+
console.error(`Failed to register view key: ${error}`);
|
|
3424
|
+
throw error;
|
|
3818
3425
|
}
|
|
3819
3426
|
}
|
|
3820
3427
|
/**
|
|
@@ -4007,24 +3614,18 @@ class RecordScanner {
|
|
|
4007
3614
|
}
|
|
4008
3615
|
/**
|
|
4009
3616
|
* Wrapper function to make a request to the record scanner service and handle any errors.
|
|
4010
|
-
* Optionally adds JWT Authorization header when consumerId/jwtData (or apiKey+consumerId) are configured.
|
|
4011
3617
|
*
|
|
4012
3618
|
* @param {Request} req The request to make.
|
|
4013
3619
|
* @returns {Promise<Response>} The response.
|
|
4014
3620
|
*/
|
|
4015
3621
|
async request(req) {
|
|
4016
3622
|
try {
|
|
4017
|
-
const authHeaders = await this.getAuthHeaders();
|
|
4018
|
-
for (const [key, value] of Object.entries(authHeaders)) {
|
|
4019
|
-
req.headers.set(key, value);
|
|
4020
|
-
}
|
|
4021
3623
|
if (this.apiKey) {
|
|
4022
3624
|
req.headers.set(this.apiKey.header, this.apiKey.value);
|
|
4023
3625
|
}
|
|
4024
3626
|
const response = await fetch(req);
|
|
4025
3627
|
if (!response.ok) {
|
|
4026
|
-
|
|
4027
|
-
throw new RecordScannerRequestError(text || `Request to ${req.url} failed with status ${response.status}`, response.status);
|
|
3628
|
+
throw new Error(await response.text() ?? `Request to ${req.url} failed with status ${response.status}`);
|
|
4028
3629
|
}
|
|
4029
3630
|
return response;
|
|
4030
3631
|
}
|
|
@@ -7022,5 +6623,5 @@ async function initializeWasm() {
|
|
|
7022
6623
|
console.warn("initializeWasm is deprecated, you no longer need to use it");
|
|
7023
6624
|
}
|
|
7024
6625
|
|
|
7025
|
-
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,
|
|
6626
|
+
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 };
|
|
7026
6627
|
//# sourceMappingURL=browser.js.map
|