@provablehq/sdk 0.9.17 → 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 +1 -1
- package/dist/mainnet/browser.js +212 -80
- package/dist/mainnet/browser.js.map +1 -1
- package/dist/mainnet/models/keyHolder.d.ts +2 -0
- package/dist/mainnet/node.js +1 -1
- package/dist/mainnet/program-manager.d.ts +2 -2
- package/dist/mainnet/security.d.ts +24 -0
- package/dist/testnet/account.d.ts +43 -3
- package/dist/testnet/browser.d.ts +1 -1
- package/dist/testnet/browser.js +212 -80
- package/dist/testnet/browser.js.map +1 -1
- package/dist/testnet/models/keyHolder.d.ts +2 -0
- package/dist/testnet/node.js +1 -1
- package/dist/testnet/program-manager.d.ts +2 -2
- package/dist/testnet/security.d.ts +24 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Address, ComputeKey, Field, Group, PrivateKey, Signature, ViewKey, PrivateKeyCiphertext, RecordCiphertext, RecordPlaintext } from "./wasm.js";
|
|
2
2
|
interface AccountParam {
|
|
3
|
-
privateKey?: string;
|
|
3
|
+
privateKey?: string | PrivateKey;
|
|
4
4
|
seed?: Uint8Array;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
@@ -13,6 +13,9 @@ interface AccountParam {
|
|
|
13
13
|
* credits and other records to. This class should only be used in environments where the safety of the underlying key
|
|
14
14
|
* material can be assured.
|
|
15
15
|
*
|
|
16
|
+
* When an Account is no longer needed, call {@link destroy} to securely zeroize and free all sensitive key material
|
|
17
|
+
* from WASM memory. Alternatively, use `[Symbol.dispose]()` with the `using` declaration in ES2024+ environments.
|
|
18
|
+
*
|
|
16
19
|
* @example
|
|
17
20
|
* import { Account } from "@provablehq/sdk/testnet.js";
|
|
18
21
|
*
|
|
@@ -32,12 +35,16 @@ interface AccountParam {
|
|
|
32
35
|
*
|
|
33
36
|
* // Verify a signature
|
|
34
37
|
* assert(myRandomAccount.verify(hello_world, signature));
|
|
38
|
+
*
|
|
39
|
+
* // Securely destroy the account when done
|
|
40
|
+
* myRandomAccount.destroy();
|
|
35
41
|
*/
|
|
36
42
|
export declare class Account {
|
|
37
43
|
_privateKey: PrivateKey;
|
|
38
44
|
_viewKey: ViewKey;
|
|
39
45
|
_computeKey: ComputeKey;
|
|
40
46
|
_address: Address;
|
|
47
|
+
private _destroyed;
|
|
41
48
|
constructor(params?: AccountParam);
|
|
42
49
|
/**
|
|
43
50
|
* Attempts to create an account from a private key ciphertext
|
|
@@ -69,10 +76,14 @@ export declare class Account {
|
|
|
69
76
|
static isValidAddress(address: string | Uint8Array): boolean;
|
|
70
77
|
/**
|
|
71
78
|
* Creates a PrivateKey from the provided parameters.
|
|
72
|
-
* @param {AccountParam} params The parameters containing either a private key string or a seed
|
|
79
|
+
* @param {AccountParam} params The parameters containing either a private key string, PrivateKey object, or a seed
|
|
73
80
|
* @returns {PrivateKey} A PrivateKey instance derived from the provided parameters
|
|
74
81
|
*/
|
|
75
82
|
private privateKeyFromParams;
|
|
83
|
+
/**
|
|
84
|
+
* Throws an error if this account has been destroyed.
|
|
85
|
+
*/
|
|
86
|
+
private assertNotDestroyed;
|
|
76
87
|
/**
|
|
77
88
|
* Returns the PrivateKey associated with the account.
|
|
78
89
|
* @returns {PrivateKey} The private key of the account
|
|
@@ -118,7 +129,8 @@ export declare class Account {
|
|
|
118
129
|
*/
|
|
119
130
|
address(): Address;
|
|
120
131
|
/**
|
|
121
|
-
* Deep clones the Account
|
|
132
|
+
* Deep clones the Account via byte serialization of the private key,
|
|
133
|
+
* avoiding creation of immutable JS string representations of the private key.
|
|
122
134
|
* @returns {Account} A new Account instance with the same private key
|
|
123
135
|
*
|
|
124
136
|
* @example
|
|
@@ -303,5 +315,33 @@ export declare class Account {
|
|
|
303
315
|
* assert(account.verify(message, signature));
|
|
304
316
|
*/
|
|
305
317
|
verify(message: Uint8Array, signature: Signature): boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Securely destroys the account by zeroizing and freeing all sensitive key material
|
|
320
|
+
* from WASM memory. After calling this method, the account object should not be used.
|
|
321
|
+
*
|
|
322
|
+
* This triggers the Rust-level zeroizing Drop implementation which overwrites private key,
|
|
323
|
+
* view key, and compute key bytes with zeros in WASM linear memory before deallocation.
|
|
324
|
+
*
|
|
325
|
+
* Note: If destroy() is never called, the FinalizationRegistry (set up by wasm-bindgen)
|
|
326
|
+
* will eventually trigger cleanup via GC, but the timing is non-deterministic. For security-
|
|
327
|
+
* sensitive applications, always call destroy() explicitly when the account is no longer needed.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* const account = new Account();
|
|
331
|
+
* // ... use account ...
|
|
332
|
+
* account.destroy(); // Securely cleans up key material
|
|
333
|
+
*/
|
|
334
|
+
destroy(): void;
|
|
335
|
+
/**
|
|
336
|
+
* Implements the Disposable interface for use with `using` declarations (ES2024+).
|
|
337
|
+
* Calls {@link destroy} to securely clean up key material.
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* {
|
|
341
|
+
* using account = new Account();
|
|
342
|
+
* // ... use account ...
|
|
343
|
+
* } // account is automatically destroyed here
|
|
344
|
+
*/
|
|
345
|
+
[Symbol.dispose](): void;
|
|
306
346
|
}
|
|
307
347
|
export {};
|
|
@@ -67,4 +67,4 @@ export { initializeWasm };
|
|
|
67
67
|
export { Key, CREDITS_PROGRAM_KEYS, KEY_STORE, PRIVATE_TRANSFER, PRIVATE_TO_PUBLIC_TRANSFER, PRIVATE_TRANSFER_TYPES, PUBLIC_TRANSFER, PUBLIC_TRANSFER_AS_SIGNER, PUBLIC_TO_PRIVATE_TRANSFER, RECORD_DOMAIN, VALID_TRANSFER_TYPES, } from "./constants.js";
|
|
68
68
|
export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoKeyProviderInitParams, AleoNetworkClient, BlockJSON, BlockHeightSearch, BroadcastResponse, BroadcastResult, CachedKeyPair, ConfirmedTransactionJSON, CryptoBoxPubKey, DeploymentJSON, DeploymentObject, EncryptedProvingRequest, EncryptedRecord, EncryptedRegistrationRequest, EncryptedRecordsResult, EncryptedRecordsSuccess, ExecutionJSON, ExecutionObject, FeeExecutionJSON, FeeExecutionObject, FinalizeJSON, FunctionInput, FunctionObject, FunctionKeyPair, FunctionKeyProvider, Header, isProvingResponse, isProveApiErrorBody, ImportedPrograms, ImportedVerifyingKeys, InputJSON, InputObject, InvalidLocatorError, InvalidLocatorReason, KeyFingerprint, KeyLocator, KeyMetadata, KeyStore, KeyVerificationError, KeyVerifier, MemKeyVerifier, KeySearchParams, Metadata, NetworkRecordProvider, OfflineKeyProvider, OfflineSearchParams, OutputJSON, OutputObject, OwnedFilter, OwnedRecord, OwnedRecordsResult, OwnedRecordsResponseFilter, OwnedRecordsSuccess, OwnerJSON, PartialSolutionJSON, PlaintextArray, PlaintextLiteral, PlaintextObject, PlaintextStruct, ProgramImports, ProveApiErrorBody, ProvingFailure, ProvingRequestError, ProvingRequestJSON, ProvingResult, ProvingSuccess, ProvingResponse, RatificationJSON, RecordsFilter, RecordsResponseFilter, RecordProvider, RecordScanner, RecordScannerErrorBody, RecordScannerFailure, RecordScannerJWTData, RecordScannerOptions, DecryptionNotEnabledError, RecordNotFoundError, RecordScannerRequestError, ViewKeyNotStoredError, RecordSearchParams, RegisterResult, RegisterSuccess, RegistrationRequest, RegistrationResponse, RevokeResult, RevokeSuccess, RevokeResponse, SealanceMerkleTree, SerialNumbersResult, SerialNumbersSuccess, sha256Hex, SolutionJSON, SolutionsJSON, StatusResponse, StatusResult, StatusSuccess, TagsResult, TagsSuccess, TransactionJSON, TransactionObject, TransitionJSON, TransitionObject, UUIDError, VerifyingKeys, };
|
|
69
69
|
export { KeyVerificationError as ChecksumMismatchError, KeyVerifier as FunctionKeyVerifier, } from "./keys/verifier/interface.js";
|
|
70
|
-
export { encryptAuthorization, encryptProvingRequest, encryptViewKey, encryptRegistrationRequest } from "./security.js";
|
|
70
|
+
export { encryptAuthorization, encryptProvingRequest, encryptViewKey, encryptRegistrationRequest, zeroizeBytes } from "./security.js";
|
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
|
}
|
|
@@ -7292,7 +7424,7 @@ class ProgramManager {
|
|
|
7292
7424
|
* import { AleoKeyProvider, getOrInitConsensusVersionTestHeights, ProgramManager, NetworkRecordProvider } from "@provablehq/sdk/mainnet.js";
|
|
7293
7425
|
*
|
|
7294
7426
|
* // Initialize the development consensus heights in order to work with devnode.
|
|
7295
|
-
* 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");
|
|
7296
7428
|
*
|
|
7297
7429
|
* // Create a new NetworkClient and RecordProvider.
|
|
7298
7430
|
* const recordProvider = new NetworkRecordProvider(account, networkClient);
|
|
@@ -7424,7 +7556,7 @@ class ProgramManager {
|
|
|
7424
7556
|
* import { ProgramManager, NetworkRecordProvider, getOrInitConsensusVersionTestHeights } from "@provablehq/sdk/mainnet.js";
|
|
7425
7557
|
*
|
|
7426
7558
|
* // Initialize the development consensus heights in order to work with a local devnode.
|
|
7427
|
-
* 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");
|
|
7428
7560
|
*
|
|
7429
7561
|
* // Create a new NetworkClient, and RecordProvider
|
|
7430
7562
|
* const recordProvider = new NetworkRecordProvider(account, networkClient);
|
|
@@ -7637,5 +7769,5 @@ async function initializeWasm() {
|
|
|
7637
7769
|
console.warn("initializeWasm is deprecated, you no longer need to use it");
|
|
7638
7770
|
}
|
|
7639
7771
|
|
|
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 };
|
|
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 };
|
|
7641
7773
|
//# sourceMappingURL=browser.js.map
|