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