@provablehq/sdk 0.6.9

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/index.js ADDED
@@ -0,0 +1,3049 @@
1
+ import { ViewKey, Address, PrivateKeyCiphertext, PrivateKey, RecordCiphertext, Program, Transaction, ProvingKey, VerifyingKey, ProgramManager as ProgramManager$1, RecordPlaintext, verifyFunctionExecution, Metadata } from '@provablehq/wasm';
2
+ export { Address, ExecutionResponse, Field, Execution as FunctionExecution, OfflineQuery, PrivateKey, PrivateKeyCiphertext, Program, ProgramManager as ProgramManagerBase, ProvingKey, RecordCiphertext, RecordPlaintext, Signature, Transaction, VerifyingKey, ViewKey, initThreadPool, verifyFunctionExecution } from '@provablehq/wasm';
3
+ import { wrap } from 'comlink';
4
+
5
+ /**
6
+ * Key Management class. Enables the creation of a new Aleo Account, importation of an existing account from
7
+ * an existing private key or seed, and message signing and verification functionality.
8
+ *
9
+ * An Aleo Account is generated from a randomly generated seed (number) from which an account private key, view key,
10
+ * and a public account address are derived. The private key lies at the root of an Aleo account. It is a highly
11
+ * sensitive secret and should be protected as it allows for creation of Aleo Program executions and arbitrary value
12
+ * transfers. The View Key allows for decryption of a user's activity on the blockchain. The Address is the public
13
+ * address to which other users of Aleo can send Aleo credits and other records to. This class should only be used
14
+ * environments where the safety of the underlying key material can be assured.
15
+ *
16
+ * @example
17
+ * // Create a new account
18
+ * const myRandomAccount = new Account();
19
+ *
20
+ * // Create an account from a randomly generated seed
21
+ * const seed = new Uint8Array([94, 91, 52, 251, 240, 230, 226, 35, 117, 253, 224, 210, 175, 13, 205, 120, 155, 214, 7, 169, 66, 62, 206, 50, 188, 40, 29, 122, 40, 250, 54, 18]);
22
+ * const mySeededAccount = new Account({seed: seed});
23
+ *
24
+ * // Create an account from an existing private key
25
+ * const myExistingAccount = new Account({privateKey: 'myExistingPrivateKey'})
26
+ *
27
+ * // Sign a message
28
+ * const hello_world = Uint8Array.from([104, 101, 108, 108, 111 119, 111, 114, 108, 100])
29
+ * const signature = myRandomAccount.sign(hello_world)
30
+ *
31
+ * // Verify a signature
32
+ * myRandomAccount.verify(hello_world, signature)
33
+ */
34
+ class Account {
35
+ _privateKey;
36
+ _viewKey;
37
+ _address;
38
+ constructor(params = {}) {
39
+ try {
40
+ this._privateKey = this.privateKeyFromParams(params);
41
+ }
42
+ catch (e) {
43
+ console.error("Wrong parameter", e);
44
+ throw new Error("Wrong Parameter");
45
+ }
46
+ this._viewKey = ViewKey.from_private_key(this._privateKey);
47
+ this._address = Address.from_private_key(this._privateKey);
48
+ }
49
+ /**
50
+ * Attempts to create an account from a private key ciphertext
51
+ * @param {PrivateKeyCiphertext | string} ciphertext
52
+ * @param {string} password
53
+ * @returns {PrivateKey | Error}
54
+ *
55
+ * @example
56
+ * const ciphertext = PrivateKey.newEncrypted("password");
57
+ * const account = Account.fromCiphertext(ciphertext, "password");
58
+ */
59
+ static fromCiphertext(ciphertext, password) {
60
+ try {
61
+ ciphertext = (typeof ciphertext === "string") ? PrivateKeyCiphertext.fromString(ciphertext) : ciphertext;
62
+ const _privateKey = PrivateKey.fromPrivateKeyCiphertext(ciphertext, password);
63
+ return new Account({ privateKey: _privateKey.to_string() });
64
+ }
65
+ catch (e) {
66
+ throw new Error("Wrong password or invalid ciphertext");
67
+ }
68
+ }
69
+ privateKeyFromParams(params) {
70
+ if (params.seed) {
71
+ return PrivateKey.from_seed_unchecked(params.seed);
72
+ }
73
+ if (params.privateKey) {
74
+ return PrivateKey.from_string(params.privateKey);
75
+ }
76
+ return new PrivateKey();
77
+ }
78
+ privateKey() {
79
+ return this._privateKey;
80
+ }
81
+ viewKey() {
82
+ return this._viewKey;
83
+ }
84
+ address() {
85
+ return this._address;
86
+ }
87
+ toString() {
88
+ return this.address().to_string();
89
+ }
90
+ /**
91
+ * Encrypt the account's private key with a password
92
+ * @param {string} ciphertext
93
+ * @returns {PrivateKeyCiphertext}
94
+ *
95
+ * @example
96
+ * const account = new Account();
97
+ * const ciphertext = account.encryptAccount("password");
98
+ */
99
+ encryptAccount(password) {
100
+ return this._privateKey.toCiphertext(password);
101
+ }
102
+ /**
103
+ * Decrypts a Record in ciphertext form into plaintext
104
+ * @param {string} ciphertext
105
+ * @returns {Record}
106
+ *
107
+ * @example
108
+ * const account = new Account();
109
+ * const record = account.decryptRecord("record1ciphertext");
110
+ */
111
+ decryptRecord(ciphertext) {
112
+ return this._viewKey.decrypt(ciphertext);
113
+ }
114
+ /**
115
+ * Decrypts an array of Records in ciphertext form into plaintext
116
+ * @param {string[]} ciphertexts
117
+ * @returns {Record[]}
118
+ *
119
+ * @example
120
+ * const account = new Account();
121
+ * const record = account.decryptRecords(["record1ciphertext", "record2ciphertext"]);
122
+ */
123
+ decryptRecords(ciphertexts) {
124
+ return ciphertexts.map((ciphertext) => this._viewKey.decrypt(ciphertext));
125
+ }
126
+ /**
127
+ * Determines whether the account owns a ciphertext record
128
+ * @param {RecordCipherText | string} ciphertext
129
+ * @returns {boolean}
130
+ *
131
+ * @example
132
+ * // Create a connection to the Aleo network and an account
133
+ * const connection = new NodeConnection("vm.aleo.org/api");
134
+ * const account = Account.fromCiphertext("ciphertext", "password");
135
+ *
136
+ * // Get a record from the network
137
+ * const record = connection.getBlock(1234);
138
+ * const recordCipherText = record.transactions[0].execution.transitions[0].id;
139
+ *
140
+ * // Check if the account owns the record
141
+ * if account.ownsRecord(recordCipherText) {
142
+ * // Then one can do something like:
143
+ * // Decrypt the record and check if it's spent
144
+ * // Store the record in a local database
145
+ * // Etc.
146
+ * }
147
+ */
148
+ ownsRecordCiphertext(ciphertext) {
149
+ if (typeof ciphertext === 'string') {
150
+ try {
151
+ const ciphertextObject = RecordCiphertext.fromString(ciphertext);
152
+ return ciphertextObject.isOwner(this._viewKey);
153
+ }
154
+ catch (e) {
155
+ return false;
156
+ }
157
+ }
158
+ else {
159
+ return ciphertext.isOwner(this._viewKey);
160
+ }
161
+ }
162
+ /**
163
+ * Signs a message with the account's private key.
164
+ * Returns a Signature.
165
+ *
166
+ * @param {Uint8Array} message
167
+ * @returns {Signature}
168
+ *
169
+ * @example
170
+ * const account = new Account();
171
+ * const message = Uint8Array.from([104, 101, 108, 108, 111 119, 111, 114, 108, 100])
172
+ * account.sign(message);
173
+ */
174
+ sign(message) {
175
+ return this._privateKey.sign(message);
176
+ }
177
+ /**
178
+ * Verifies the Signature on a message.
179
+ *
180
+ * @param {Uint8Array} message
181
+ * @param {Signature} signature
182
+ * @returns {boolean}
183
+ *
184
+ * @example
185
+ * const account = new Account();
186
+ * const message = Uint8Array.from([104, 101, 108, 108, 111 119, 111, 114, 108, 100])
187
+ * const signature = account.sign(message);
188
+ * account.verify(message, signature);
189
+ */
190
+ verify(message, signature) {
191
+ return this._address.verify(message, signature);
192
+ }
193
+ }
194
+
195
+ async function get(url, options) {
196
+ const response = await fetch(url, options);
197
+ if (!response.ok) {
198
+ throw new Error(response.status + " could not get URL " + url);
199
+ }
200
+ return response;
201
+ }
202
+ async function post(url, options) {
203
+ options.method = "POST";
204
+ const response = await fetch(url, options);
205
+ if (!response.ok) {
206
+ throw new Error(response.status + " could not post URL " + url);
207
+ }
208
+ return response;
209
+ }
210
+
211
+ /**
212
+ * Client library that encapsulates REST calls to publicly exposed endpoints of Aleo nodes. The methods provided in this
213
+ * allow users to query public information from the Aleo blockchain and submit transactions to the network.
214
+ *
215
+ * @param {string} host
216
+ * @example
217
+ * // Connection to a local node
218
+ * const localNetworkClient = new AleoNetworkClient("http://localhost:3030");
219
+ *
220
+ * // Connection to a public beacon node
221
+ * const publicnetworkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
222
+ */
223
+ class AleoNetworkClient {
224
+ host;
225
+ headers;
226
+ account;
227
+ constructor(host, options) {
228
+ this.host = host + "/testnet";
229
+ if (options && options.headers) {
230
+ this.headers = options.headers;
231
+ }
232
+ else {
233
+ this.headers = {
234
+ // This is replaced by the actual version by a Rollup plugin
235
+ "X-Aleo-SDK-Version": "0.6.9",
236
+ };
237
+ }
238
+ }
239
+ /**
240
+ * Set an account to use in networkClient calls
241
+ *
242
+ * @param {Account} account
243
+ * @example
244
+ * const account = new Account();
245
+ * networkClient.setAccount(account);
246
+ */
247
+ setAccount(account) {
248
+ this.account = account;
249
+ }
250
+ /**
251
+ * Return the Aleo account used in the networkClient
252
+ *
253
+ * @example
254
+ * const account = networkClient.getAccount();
255
+ */
256
+ getAccount() {
257
+ return this.account;
258
+ }
259
+ /**
260
+ * Set a new host for the networkClient
261
+ *
262
+ * @param {string} host The address of a node hosting the Aleo API
263
+ * @param host
264
+ */
265
+ setHost(host) {
266
+ this.host = host + "/testnet";
267
+ }
268
+ async fetchData(url = "/") {
269
+ try {
270
+ const response = await get(this.host + url, {
271
+ headers: this.headers
272
+ });
273
+ return await response.json();
274
+ }
275
+ catch (error) {
276
+ throw new Error("Error fetching data.");
277
+ }
278
+ }
279
+ /**
280
+ * Attempts to find unspent records in the Aleo blockchain for a specified private key
281
+ * @param {number} startHeight - The height at which to start searching for unspent records
282
+ * @param {number} endHeight - The height at which to stop searching for unspent records
283
+ * @param {string | PrivateKey} privateKey - The private key to use to find unspent records
284
+ * @param {number[]} amounts - The amounts (in microcredits) to search for (eg. [100, 200, 3000])
285
+ * @param {number} maxMicrocredits - The maximum number of microcredits to search for
286
+ * @param {string[]} nonces - The nonces of already found records to exclude from the search
287
+ *
288
+ * @example
289
+ * // Find all unspent records
290
+ * const privateKey = "[PRIVATE_KEY]";
291
+ * const records = networkClient.findUnspentRecords(0, undefined, privateKey);
292
+ *
293
+ * // Find specific amounts
294
+ * const startHeight = 500000;
295
+ * const amounts = [600000, 1000000];
296
+ * const records = networkClient.findUnspentRecords(startHeight, undefined, privateKey, amounts);
297
+ *
298
+ * // Find specific amounts with a maximum number of cumulative microcredits
299
+ * const maxMicrocredits = 100000;
300
+ * const records = networkClient.findUnspentRecords(startHeight, undefined, privateKey, undefined, maxMicrocredits);
301
+ */
302
+ async findUnspentRecords(startHeight, endHeight, privateKey, amounts, maxMicrocredits, nonces) {
303
+ nonces = nonces || [];
304
+ // Ensure start height is not negative
305
+ if (startHeight < 0) {
306
+ throw new Error("Start height must be greater than or equal to 0");
307
+ }
308
+ // Initialize search parameters
309
+ const records = new Array();
310
+ let start;
311
+ let end;
312
+ let resolvedPrivateKey;
313
+ let failures = 0;
314
+ let totalRecordValue = BigInt(0);
315
+ let latestHeight;
316
+ // Ensure a private key is present to find owned records
317
+ if (typeof privateKey === "undefined") {
318
+ if (typeof this.account === "undefined") {
319
+ throw new Error("Private key must be specified in an argument to findOwnedRecords or set in the AleoNetworkClient");
320
+ }
321
+ else {
322
+ resolvedPrivateKey = this.account._privateKey;
323
+ }
324
+ }
325
+ else {
326
+ try {
327
+ resolvedPrivateKey = privateKey instanceof PrivateKey ? privateKey : PrivateKey.from_string(privateKey);
328
+ }
329
+ catch (error) {
330
+ throw new Error("Error parsing private key provided.");
331
+ }
332
+ }
333
+ const viewKey = resolvedPrivateKey.to_view_key();
334
+ // Get the latest height to ensure the range being searched is valid
335
+ try {
336
+ const blockHeight = await this.getLatestHeight();
337
+ if (typeof blockHeight === "number") {
338
+ latestHeight = blockHeight;
339
+ }
340
+ else {
341
+ throw new Error("Error fetching latest block height.");
342
+ }
343
+ }
344
+ catch (error) {
345
+ throw new Error("Error fetching latest block height.");
346
+ }
347
+ // If no end height is specified or is greater than the latest height, set the end height to the latest height
348
+ if (typeof endHeight === "number" && endHeight <= latestHeight) {
349
+ end = endHeight;
350
+ }
351
+ else {
352
+ end = latestHeight;
353
+ }
354
+ // If the starting is greater than the ending height, return an error
355
+ if (startHeight > end) {
356
+ throw new Error("Start height must be less than or equal to end height.");
357
+ }
358
+ // Iterate through blocks in reverse order in chunks of 50
359
+ while (end > startHeight) {
360
+ start = end - 50;
361
+ if (start < startHeight) {
362
+ start = startHeight;
363
+ }
364
+ try {
365
+ // Get 50 blocks (or the difference between the start and end if less than 50)
366
+ const blocks = await this.getBlockRange(start, end);
367
+ end = start;
368
+ if (!(blocks instanceof Error)) {
369
+ // Iterate through blocks to find unspent records
370
+ for (let i = 0; i < blocks.length; i++) {
371
+ const block = blocks[i];
372
+ const transactions = block.transactions;
373
+ if (!(typeof transactions === "undefined")) {
374
+ for (let j = 0; j < transactions.length; j++) {
375
+ const confirmedTransaction = transactions[j];
376
+ // Search for unspent records in execute transactions of credits.aleo
377
+ if (confirmedTransaction.type == "execute") {
378
+ const transaction = confirmedTransaction.transaction;
379
+ if (transaction.execution && !(typeof transaction.execution.transitions == "undefined")) {
380
+ for (let k = 0; k < transaction.execution.transitions.length; k++) {
381
+ const transition = transaction.execution.transitions[k];
382
+ // Only search for unspent records in credits.aleo (for now)
383
+ if (transition.program !== "credits.aleo") {
384
+ continue;
385
+ }
386
+ if (!(typeof transition.outputs == "undefined")) {
387
+ for (let l = 0; l < transition.outputs.length; l++) {
388
+ const output = transition.outputs[l];
389
+ if (output.type === "record") {
390
+ try {
391
+ // Create a wasm record ciphertext object from the found output
392
+ const record = RecordCiphertext.fromString(output.value);
393
+ // Determine if the record is owned by the specified view key
394
+ if (record.isOwner(viewKey)) {
395
+ // Decrypt the record and get the serial number
396
+ const recordPlaintext = record.decrypt(viewKey);
397
+ // If the record has already been found, skip it
398
+ const nonce = recordPlaintext.nonce();
399
+ if (nonces.includes(nonce)) {
400
+ continue;
401
+ }
402
+ // Otherwise record the nonce that has been found
403
+ const serialNumber = recordPlaintext.serialNumberString(resolvedPrivateKey, "credits.aleo", "credits");
404
+ // Attempt to see if the serial number is spent
405
+ try {
406
+ await this.getTransitionId(serialNumber);
407
+ }
408
+ catch (error) {
409
+ // If it's not found, add it to the list of unspent records
410
+ if (!amounts) {
411
+ records.push(recordPlaintext);
412
+ // If the user specified a maximum number of microcredits, check if the search has found enough
413
+ if (typeof maxMicrocredits === "number") {
414
+ totalRecordValue += recordPlaintext.microcredits();
415
+ // Exit if the search has found the amount specified
416
+ if (totalRecordValue >= BigInt(maxMicrocredits)) {
417
+ return records;
418
+ }
419
+ }
420
+ }
421
+ // If the user specified a list of amounts, check if the search has found them
422
+ if (!(typeof amounts === "undefined") && amounts.length > 0) {
423
+ let amounts_found = 0;
424
+ if (recordPlaintext.microcredits() > amounts[amounts_found]) {
425
+ amounts_found += 1;
426
+ records.push(recordPlaintext);
427
+ // If the user specified a maximum number of microcredits, check if the search has found enough
428
+ if (typeof maxMicrocredits === "number") {
429
+ totalRecordValue += recordPlaintext.microcredits();
430
+ // Exit if the search has found the amount specified
431
+ if (totalRecordValue >= BigInt(maxMicrocredits)) {
432
+ return records;
433
+ }
434
+ }
435
+ if (records.length >= amounts.length) {
436
+ return records;
437
+ }
438
+ }
439
+ }
440
+ }
441
+ }
442
+ }
443
+ catch (error) {
444
+ }
445
+ }
446
+ }
447
+ }
448
+ }
449
+ }
450
+ }
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }
456
+ catch (error) {
457
+ // If there is an error fetching blocks, log it and keep searching
458
+ console.warn("Error fetching blocks in range: " + start.toString() + "-" + end.toString());
459
+ console.warn("Error: ", error);
460
+ failures += 1;
461
+ if (failures > 10) {
462
+ console.warn("10 failures fetching records reached. Returning records fetched so far");
463
+ return records;
464
+ }
465
+ }
466
+ }
467
+ return records;
468
+ }
469
+ /**
470
+ * Returns the contents of the block at the specified block height
471
+ *
472
+ * @param {number} height
473
+ * @example
474
+ * const block = networkClient.getBlock(1234);
475
+ */
476
+ async getBlock(height) {
477
+ try {
478
+ const block = await this.fetchData("/block/" + height);
479
+ return block;
480
+ }
481
+ catch (error) {
482
+ throw new Error("Error fetching block.");
483
+ }
484
+ }
485
+ /**
486
+ * Returns a range of blocks between the specified block heights
487
+ *
488
+ * @param {number} start
489
+ * @param {number} end
490
+ * @example
491
+ * const blockRange = networkClient.getBlockRange(2050, 2100);
492
+ */
493
+ async getBlockRange(start, end) {
494
+ try {
495
+ return await this.fetchData("/blocks?start=" + start + "&end=" + end);
496
+ }
497
+ catch (error) {
498
+ const errorMessage = "Error fetching blocks between " + start + " and " + end + ".";
499
+ throw new Error(errorMessage);
500
+ }
501
+ }
502
+ /**
503
+ * Returns the deployment transaction id associated with the specified program
504
+ *
505
+ * @param {Program | string} program
506
+ * @returns {TransactionModel | Error}
507
+ */
508
+ async getDeploymentTransactionIDForProgram(program) {
509
+ if (program instanceof Program) {
510
+ program = program.toString();
511
+ }
512
+ try {
513
+ const id = await this.fetchData("/find/transactionID/deployment/" + program);
514
+ return id.replace("\"", "");
515
+ }
516
+ catch (error) {
517
+ throw new Error("Error fetching deployment transaction for program.");
518
+ }
519
+ }
520
+ /**
521
+ * Returns the deployment transaction associated with a specified program
522
+ *
523
+ * @param {Program | string} program
524
+ * @returns {TransactionModel | Error}
525
+ */
526
+ async getDeploymentTransactionForProgram(program) {
527
+ try {
528
+ const transaction_id = await this.getDeploymentTransactionIDForProgram(program);
529
+ return await this.getTransaction(transaction_id);
530
+ }
531
+ catch (error) {
532
+ throw new Error("Error fetching deployment transaction for program.");
533
+ }
534
+ }
535
+ /**
536
+ * Returns the contents of the latest block
537
+ *
538
+ * @example
539
+ * const latestHeight = networkClient.getLatestBlock();
540
+ */
541
+ async getLatestBlock() {
542
+ try {
543
+ return await this.fetchData("/latest/block");
544
+ }
545
+ catch (error) {
546
+ throw new Error("Error fetching latest block.");
547
+ }
548
+ }
549
+ /**
550
+ * Returns the latest committee
551
+ *
552
+ * @returns {Promise<object>} A javascript object containing the latest committee
553
+ */
554
+ async getLatestCommittee() {
555
+ try {
556
+ return await this.fetchData("/committee/latest");
557
+ }
558
+ catch (error) {
559
+ throw new Error("Error fetching latest block.");
560
+ }
561
+ }
562
+ /**
563
+ * Returns the latest block height
564
+ *
565
+ * @example
566
+ * const latestHeight = networkClient.getLatestHeight();
567
+ */
568
+ async getLatestHeight() {
569
+ try {
570
+ return await this.fetchData("/latest/height");
571
+ }
572
+ catch (error) {
573
+ throw new Error("Error fetching latest height.");
574
+ }
575
+ }
576
+ /**
577
+ * Returns the source code of a program given a program ID
578
+ *
579
+ * @param {string} programId The program ID of a program deployed to the Aleo Network
580
+ * @return {Promise<string>} Source code of the program
581
+ *
582
+ * @example
583
+ * const program = networkClient.getProgram("hello_hello.aleo");
584
+ * const expectedSource = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n"
585
+ * assert.equal(program, expectedSource);
586
+ */
587
+ async getProgram(programId) {
588
+ try {
589
+ return await this.fetchData("/program/" + programId);
590
+ }
591
+ catch (error) {
592
+ throw new Error("Error fetching program");
593
+ }
594
+ }
595
+ /**
596
+ * Returns a program object from a program ID or program source code
597
+ *
598
+ * @param {string} inputProgram The program ID or program source code of a program deployed to the Aleo Network
599
+ * @return {Promise<Program | Error>} Source code of the program
600
+ *
601
+ * @example
602
+ * const programID = "hello_hello.aleo";
603
+ * const programSource = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n"
604
+ *
605
+ * // Get program object from program ID or program source code
606
+ * const programObjectFromID = await networkClient.getProgramObject(programID);
607
+ * const programObjectFromSource = await networkClient.getProgramObject(programSource);
608
+ *
609
+ * // Both program objects should be equal
610
+ * assert.equal(programObjectFromID.to_string(), programObjectFromSource.to_string());
611
+ */
612
+ async getProgramObject(inputProgram) {
613
+ try {
614
+ return Program.fromString(inputProgram);
615
+ }
616
+ catch (error) {
617
+ try {
618
+ return Program.fromString((await this.getProgram(inputProgram)));
619
+ }
620
+ catch (error) {
621
+ throw new Error(`${inputProgram} is neither a program name or a valid program`);
622
+ }
623
+ }
624
+ }
625
+ /**
626
+ * Returns an object containing the source code of a program and the source code of all programs it imports
627
+ *
628
+ * @param {Program | string} inputProgram The program ID or program source code of a program deployed to the Aleo Network
629
+ * @returns {Promise<ProgramImports>} Object of the form { "program_id": "program_source", .. } containing program id & source code for all program imports
630
+ *
631
+ * @example
632
+ * const double_test_source = "import multiply_test.aleo;\n\nprogram double_test.aleo;\n\nfunction double_it:\n input r0 as u32.private;\n call multiply_test.aleo/multiply 2u32 r0 into r1;\n output r1 as u32.private;\n"
633
+ * const double_test = Program.fromString(double_test_source);
634
+ * const expectedImports = {
635
+ * "multiply_test.aleo": "program multiply_test.aleo;\n\nfunction multiply:\n input r0 as u32.public;\n input r1 as u32.private;\n mul r0 r1 into r2;\n output r2 as u32.private;\n"
636
+ * }
637
+ *
638
+ * // Imports can be fetched using the program ID, source code, or program object
639
+ * let programImports = await networkClient.getProgramImports("double_test.aleo");
640
+ * assert.deepStrictEqual(programImports, expectedImports);
641
+ *
642
+ * // Using the program source code
643
+ * programImports = await networkClient.getProgramImports(double_test_source);
644
+ * assert.deepStrictEqual(programImports, expectedImports);
645
+ *
646
+ * // Using the program object
647
+ * programImports = await networkClient.getProgramImports(double_test);
648
+ * assert.deepStrictEqual(programImports, expectedImports);
649
+ */
650
+ async getProgramImports(inputProgram) {
651
+ try {
652
+ const imports = {};
653
+ // Get the program object or fail if the program is not valid or does not exist
654
+ const program = inputProgram instanceof Program ? inputProgram : (await this.getProgramObject(inputProgram));
655
+ // Get the list of programs that the program imports
656
+ const importList = program.getImports();
657
+ // Recursively get any imports that the imported programs have in a depth first search order
658
+ for (let i = 0; i < importList.length; i++) {
659
+ const import_id = importList[i];
660
+ if (!imports.hasOwnProperty(import_id)) {
661
+ const programSource = await this.getProgram(import_id);
662
+ const nestedImports = await this.getProgramImports(import_id);
663
+ for (const key in nestedImports) {
664
+ if (!imports.hasOwnProperty(key)) {
665
+ imports[key] = nestedImports[key];
666
+ }
667
+ }
668
+ imports[import_id] = programSource;
669
+ }
670
+ }
671
+ return imports;
672
+ }
673
+ catch (error) {
674
+ throw logAndThrow("Error fetching program imports: " + error);
675
+ }
676
+ }
677
+ /**
678
+ * Get a list of the program names that a program imports
679
+ *
680
+ * @param {Program | string} inputProgram - The program id or program source code to get the imports of
681
+ * @returns {string[]} - The list of program names that the program imports
682
+ *
683
+ * @example
684
+ * const programImportsNames = networkClient.getProgramImports("double_test.aleo");
685
+ * const expectedImportsNames = ["multiply_test.aleo"];
686
+ * assert.deepStrictEqual(programImportsNames, expectedImportsNames);
687
+ */
688
+ async getProgramImportNames(inputProgram) {
689
+ try {
690
+ const program = inputProgram instanceof Program ? inputProgram : (await this.getProgramObject(inputProgram));
691
+ return program.getImports();
692
+ }
693
+ catch (error) {
694
+ throw new Error("Error fetching program imports with error: " + error);
695
+ }
696
+ }
697
+ /**
698
+ * Returns the names of the mappings of a program
699
+ *
700
+ * @param {string} programId - The program ID to get the mappings of (e.g. "credits.aleo")
701
+ * @example
702
+ * const mappings = networkClient.getProgramMappingNames("credits.aleo");
703
+ * const expectedMappings = ["account"];
704
+ * assert.deepStrictEqual(mappings, expectedMappings);
705
+ */
706
+ async getProgramMappingNames(programId) {
707
+ try {
708
+ return await this.fetchData("/program/" + programId + "/mappings");
709
+ }
710
+ catch (error) {
711
+ throw new Error("Error fetching program mappings - ensure the program exists on chain before trying again");
712
+ }
713
+ }
714
+ /**
715
+ * Returns the value of a program's mapping for a specific key
716
+ *
717
+ * @param {string} programId - The program ID to get the mapping value of (e.g. "credits.aleo")
718
+ * @param {string} mappingName - The name of the mapping to get the value of (e.g. "account")
719
+ * @param {string} key - The key of the mapping to get the value of (e.g. "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px")
720
+ * @return {Promise<string>} String representation of the value of the mapping
721
+ *
722
+ * @example
723
+ * // Get public balance of an account
724
+ * const mappingValue = networkClient.getMappingValue("credits.aleo", "account", "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px");
725
+ * const expectedValue = "0u64";
726
+ * assert.equal(mappingValue, expectedValue);
727
+ */
728
+ async getProgramMappingValue(programId, mappingName, key) {
729
+ try {
730
+ return await this.fetchData("/program/" + programId + "/mapping/" + mappingName + "/" + key);
731
+ }
732
+ catch (error) {
733
+ throw new Error("Error fetching mapping value - ensure the mapping exists and the key is correct");
734
+ }
735
+ }
736
+ /**
737
+ * Returns the latest state/merkle root of the Aleo blockchain
738
+ *
739
+ * @example
740
+ * const stateRoot = networkClient.getStateRoot();
741
+ */
742
+ async getStateRoot() {
743
+ try {
744
+ return await this.fetchData("/latest/stateRoot");
745
+ }
746
+ catch (error) {
747
+ throw new Error("Error fetching Aleo state root");
748
+ }
749
+ }
750
+ /**
751
+ * Returns a transaction by its unique identifier
752
+ *
753
+ * @param {string} id
754
+ * @example
755
+ * const transaction = networkClient.getTransaction("at1handz9xjrqeynjrr0xay4pcsgtnczdksz3e584vfsgaz0dh0lyxq43a4wj");
756
+ */
757
+ async getTransaction(id) {
758
+ try {
759
+ return await this.fetchData("/transaction/" + id);
760
+ }
761
+ catch (error) {
762
+ throw new Error("Error fetching transaction.");
763
+ }
764
+ }
765
+ /**
766
+ * Returns the transactions present at the specified block height
767
+ *
768
+ * @param {number} height
769
+ * @example
770
+ * const transactions = networkClient.getTransactions(654);
771
+ */
772
+ async getTransactions(height) {
773
+ try {
774
+ return await this.fetchData("/block/" + height.toString() + "/transactions");
775
+ }
776
+ catch (error) {
777
+ throw new Error("Error fetching transactions.");
778
+ }
779
+ }
780
+ /**
781
+ * Returns the transactions in the memory pool.
782
+ *
783
+ * @example
784
+ * const transactions = networkClient.getTransactionsInMempool();
785
+ */
786
+ async getTransactionsInMempool() {
787
+ try {
788
+ return await this.fetchData("/memoryPool/transactions");
789
+ }
790
+ catch (error) {
791
+ throw new Error("Error fetching transactions from mempool.");
792
+ }
793
+ }
794
+ /**
795
+ * Returns the transition ID of the transition corresponding to the ID of the input or output.
796
+ * @param {string} inputOrOutputID - ID of the input or output.
797
+ *
798
+ * @example
799
+ * const transitionId = networkClient.getTransitionId("2429232855236830926144356377868449890830704336664550203176918782554219952323field");
800
+ */
801
+ async getTransitionId(inputOrOutputID) {
802
+ try {
803
+ return await this.fetchData("/find/transitionID/" + inputOrOutputID);
804
+ }
805
+ catch (error) {
806
+ throw new Error("Error fetching transition ID.");
807
+ }
808
+ }
809
+ /**
810
+ * Submit an execute or deployment transaction to the Aleo network
811
+ *
812
+ * @param {Transaction | string} transaction - The transaction to submit to the network
813
+ * @returns {string | Error} - The transaction id of the submitted transaction or the resulting error
814
+ */
815
+ async submitTransaction(transaction) {
816
+ const transaction_string = transaction instanceof Transaction ? transaction.toString() : transaction;
817
+ try {
818
+ const response = await post(this.host + "/transaction/broadcast", {
819
+ body: transaction_string,
820
+ headers: Object.assign({}, this.headers, {
821
+ "Content-Type": "application/json",
822
+ }),
823
+ });
824
+ try {
825
+ return await response.json();
826
+ }
827
+ catch (error) {
828
+ throw new Error(`Error posting transaction. Aleo network response: ${error.message}`);
829
+ }
830
+ }
831
+ catch (error) {
832
+ throw new Error(`Error posting transaction: No response received: ${error.message}`);
833
+ }
834
+ }
835
+ }
836
+
837
+ /**
838
+ * AleoKeyProviderParams search parameter for the AleoKeyProvider. It allows for the specification of a proverUri and
839
+ * verifierUri to fetch keys via HTTP from a remote resource as well as a unique cacheKey to store the keys in memory.
840
+ */
841
+ class AleoKeyProviderParams {
842
+ proverUri;
843
+ verifierUri;
844
+ cacheKey;
845
+ /**
846
+ * Create a new AleoKeyProviderParams object which implements the KeySearchParams interface. Users can optionally
847
+ * specify a url for the proverUri & verifierUri to fetch keys via HTTP from a remote resource as well as a unique
848
+ * cacheKey to store the keys in memory for future use. If no proverUri or verifierUri is specified, a cachekey must
849
+ * be provided.
850
+ *
851
+ * @param { AleoKeyProviderInitParams } params - Optional search parameters
852
+ */
853
+ constructor(params) {
854
+ this.proverUri = params.proverUri;
855
+ this.verifierUri = params.verifierUri;
856
+ this.cacheKey = params.cacheKey;
857
+ }
858
+ }
859
+ /**
860
+ * AleoKeyProvider class. Implements the KeyProvider interface. Enables the retrieval of Aleo program proving and
861
+ * verifying keys for the credits.aleo program over http from official Aleo sources and storing and retrieving function
862
+ * keys from a local memory cache.
863
+ */
864
+ class AleoKeyProvider {
865
+ cache;
866
+ cacheOption;
867
+ keyUris;
868
+ async fetchBytes(url = "/") {
869
+ try {
870
+ const response = await get(url);
871
+ const data = await response.arrayBuffer();
872
+ return new Uint8Array(data);
873
+ }
874
+ catch (error) {
875
+ throw new Error("Error fetching data." + error);
876
+ }
877
+ }
878
+ constructor() {
879
+ this.keyUris = KEY_STORE;
880
+ this.cache = new Map();
881
+ this.cacheOption = false;
882
+ }
883
+ /**
884
+ * Use local memory to store keys
885
+ *
886
+ * @param {boolean} useCache whether to store keys in local memory
887
+ */
888
+ useCache(useCache) {
889
+ this.cacheOption = useCache;
890
+ }
891
+ /**
892
+ * Clear the key cache
893
+ */
894
+ clearCache() {
895
+ this.cache.clear();
896
+ }
897
+ /**
898
+ * Cache a set of keys. This will overwrite any existing keys with the same keyId. The user can check if a keyId
899
+ * exists in the cache using the containsKeys method prior to calling this method if overwriting is not desired.
900
+ *
901
+ * @param {string} keyId access key for the cache
902
+ * @param {FunctionKeyPair} keys keys to cache
903
+ */
904
+ cacheKeys(keyId, keys) {
905
+ const [provingKey, verifyingKey] = keys;
906
+ this.cache.set(keyId, [provingKey.toBytes(), verifyingKey.toBytes()]);
907
+ }
908
+ /**
909
+ * Determine if a keyId exists in the cache
910
+ *
911
+ * @param {string} keyId keyId of a proving and verifying key pair
912
+ * @returns {boolean} true if the keyId exists in the cache, false otherwise
913
+ */
914
+ containsKeys(keyId) {
915
+ return this.cache.has(keyId);
916
+ }
917
+ /**
918
+ * Delete a set of keys from the cache
919
+ *
920
+ * @param {string} keyId keyId of a proving and verifying key pair to delete from memory
921
+ * @returns {boolean} true if the keyId exists in the cache and was deleted, false if the key did not exist
922
+ */
923
+ deleteKeys(keyId) {
924
+ return this.cache.delete(keyId);
925
+ }
926
+ /**
927
+ * Get a set of keys from the cache
928
+ * @param keyId keyId of a proving and verifying key pair
929
+ *
930
+ * @returns {FunctionKeyPair | Error} Proving and verifying keys for the specified program
931
+ */
932
+ getKeys(keyId) {
933
+ console.debug(`Checking if key exists in cache. KeyId: ${keyId}`);
934
+ if (this.cache.has(keyId)) {
935
+ const [provingKeyBytes, verifyingKeyBytes] = this.cache.get(keyId);
936
+ return [ProvingKey.fromBytes(provingKeyBytes), VerifyingKey.fromBytes(verifyingKeyBytes)];
937
+ }
938
+ else {
939
+ return new Error("Key not found in cache.");
940
+ }
941
+ }
942
+ /**
943
+ * Get arbitrary function keys from a provider
944
+ *
945
+ * @param {KeySearchParams} params parameters for the key search in form of: {proverUri: string, verifierUri: string, cacheKey: string}
946
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the specified program
947
+ *
948
+ * @example
949
+ * // Create a new object which implements the KeyProvider interface
950
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
951
+ * const keyProvider = new AleoKeyProvider();
952
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
953
+ *
954
+ * // Initialize a program manager with the key provider to automatically fetch keys for value transfers
955
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
956
+ * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
957
+ *
958
+ * // Keys can also be fetched manually using the key provider
959
+ * const keySearchParams = { "cacheKey": "myProgram:myFunction" };
960
+ * const [transferPrivateProvingKey, transferPrivateVerifyingKey] = await keyProvider.functionKeys(keySearchParams);
961
+ */
962
+ async functionKeys(params) {
963
+ if (params) {
964
+ let proverUrl;
965
+ let verifierUrl;
966
+ let cacheKey;
967
+ if ("proverUri" in params && typeof params["proverUri"] == "string") {
968
+ proverUrl = params["proverUri"];
969
+ }
970
+ if ("verifierUri" in params && typeof params["verifierUri"] == "string") {
971
+ verifierUrl = params["verifierUri"];
972
+ }
973
+ if ("cacheKey" in params && typeof params["cacheKey"] == "string") {
974
+ cacheKey = params["cacheKey"];
975
+ }
976
+ if (proverUrl && verifierUrl) {
977
+ return await this.fetchKeys(proverUrl, verifierUrl, cacheKey);
978
+ }
979
+ if (cacheKey) {
980
+ return this.getKeys(cacheKey);
981
+ }
982
+ }
983
+ throw Error("Invalid parameters provided, must provide either a cacheKey and/or a proverUrl and a verifierUrl");
984
+ }
985
+ /**
986
+ * Returns the proving and verifying keys for a specified program from a specified url.
987
+ *
988
+ * @param {string} verifierUrl Url of the proving key
989
+ * @param {string} proverUrl Url the verifying key
990
+ * @param {string} cacheKey Key to store the keys in the cache
991
+ *
992
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the specified program
993
+ *
994
+ * @example
995
+ * // Create a new AleoKeyProvider object
996
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
997
+ * const keyProvider = new AleoKeyProvider();
998
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
999
+ *
1000
+ * // Initialize a program manager with the key provider to automatically fetch keys for value transfers
1001
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
1002
+ * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
1003
+ *
1004
+ * // Keys can also be fetched manually
1005
+ * const [transferPrivateProvingKey, transferPrivateVerifyingKey] = await keyProvider.fetchKeys(
1006
+ * CREDITS_PROGRAM_KEYS.transfer_private.prover,
1007
+ * CREDITS_PROGRAM_KEYS.transfer_private.verifier,
1008
+ * );
1009
+ */
1010
+ async fetchKeys(proverUrl, verifierUrl, cacheKey) {
1011
+ try {
1012
+ // If cache is enabled, check if the keys have already been fetched and return them if they have
1013
+ if (this.cacheOption) {
1014
+ if (!cacheKey) {
1015
+ cacheKey = proverUrl;
1016
+ }
1017
+ const value = this.cache.get(cacheKey);
1018
+ if (typeof value !== "undefined") {
1019
+ return [ProvingKey.fromBytes(value[0]), VerifyingKey.fromBytes(value[1])];
1020
+ }
1021
+ else {
1022
+ console.debug("Fetching proving keys from url " + proverUrl);
1023
+ const provingKey = ProvingKey.fromBytes(await this.fetchBytes(proverUrl));
1024
+ console.debug("Fetching verifying keys " + verifierUrl);
1025
+ const verifyingKey = (await this.getVerifyingKey(verifierUrl));
1026
+ this.cache.set(cacheKey, [provingKey.toBytes(), verifyingKey.toBytes()]);
1027
+ return [provingKey, verifyingKey];
1028
+ }
1029
+ }
1030
+ else {
1031
+ // If cache is disabled, fetch the keys and return them
1032
+ const provingKey = ProvingKey.fromBytes(await this.fetchBytes(proverUrl));
1033
+ const verifyingKey = (await this.getVerifyingKey(verifierUrl));
1034
+ return [provingKey, verifyingKey];
1035
+ }
1036
+ }
1037
+ catch (error) {
1038
+ throw new Error(`Error: ${error} fetching fee proving and verifying keys from ${proverUrl} and ${verifierUrl}.`);
1039
+ }
1040
+ }
1041
+ bondPublicKeys() {
1042
+ return this.fetchKeys(CREDITS_PROGRAM_KEYS.bond_public.prover, CREDITS_PROGRAM_KEYS.bond_public.verifier, CREDITS_PROGRAM_KEYS.bond_public.locator);
1043
+ }
1044
+ bondValidatorKeys() {
1045
+ return this.fetchKeys(CREDITS_PROGRAM_KEYS.bond_validator.prover, CREDITS_PROGRAM_KEYS.bond_validator.verifier, CREDITS_PROGRAM_KEYS.bond_validator.locator);
1046
+ }
1047
+ claimUnbondPublicKeys() {
1048
+ return this.fetchKeys(CREDITS_PROGRAM_KEYS.claim_unbond_public.prover, CREDITS_PROGRAM_KEYS.claim_unbond_public.verifier, CREDITS_PROGRAM_KEYS.claim_unbond_public.locator);
1049
+ }
1050
+ /**
1051
+ * Returns the proving and verifying keys for the transfer functions in the credits.aleo program
1052
+ * @param {string} visibility Visibility of the transfer function
1053
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the transfer functions
1054
+ *
1055
+ * @example
1056
+ * // Create a new AleoKeyProvider
1057
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1058
+ * const keyProvider = new AleoKeyProvider();
1059
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
1060
+ *
1061
+ * // Initialize a program manager with the key provider to automatically fetch keys for value transfers
1062
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
1063
+ * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
1064
+ *
1065
+ * // Keys can also be fetched manually
1066
+ * const [transferPublicProvingKey, transferPublicVerifyingKey] = await keyProvider.transferKeys("public");
1067
+ */
1068
+ async transferKeys(visibility) {
1069
+ if (PRIVATE_TRANSFER.has(visibility)) {
1070
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.transfer_private.prover, CREDITS_PROGRAM_KEYS.transfer_private.verifier, CREDITS_PROGRAM_KEYS.transfer_private.locator);
1071
+ }
1072
+ else if (PRIVATE_TO_PUBLIC_TRANSFER.has(visibility)) {
1073
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.transfer_private_to_public.prover, CREDITS_PROGRAM_KEYS.transfer_private_to_public.verifier, CREDITS_PROGRAM_KEYS.transfer_private_to_public.locator);
1074
+ }
1075
+ else if (PUBLIC_TRANSFER.has(visibility)) {
1076
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.transfer_public.prover, CREDITS_PROGRAM_KEYS.transfer_public.verifier, CREDITS_PROGRAM_KEYS.transfer_public.locator);
1077
+ }
1078
+ else if (PUBLIC_TRANSFER_AS_SIGNER.has(visibility)) {
1079
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.transfer_public_as_signer.prover, CREDITS_PROGRAM_KEYS.transfer_public_as_signer.verifier, CREDITS_PROGRAM_KEYS.transfer_public_as_signer.locator);
1080
+ }
1081
+ else if (PUBLIC_TO_PRIVATE_TRANSFER.has(visibility)) {
1082
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.transfer_public_to_private.prover, CREDITS_PROGRAM_KEYS.transfer_public_to_private.verifier, CREDITS_PROGRAM_KEYS.transfer_public_to_private.locator);
1083
+ }
1084
+ else {
1085
+ throw new Error("Invalid visibility type");
1086
+ }
1087
+ }
1088
+ /**
1089
+ * Returns the proving and verifying keys for the join function in the credits.aleo program
1090
+ *
1091
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the join function
1092
+ */
1093
+ async joinKeys() {
1094
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.join.prover, CREDITS_PROGRAM_KEYS.join.verifier, CREDITS_PROGRAM_KEYS.join.locator);
1095
+ }
1096
+ /**
1097
+ * Returns the proving and verifying keys for the split function in the credits.aleo program
1098
+ *
1099
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the split function
1100
+ * */
1101
+ async splitKeys() {
1102
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.split.prover, CREDITS_PROGRAM_KEYS.split.verifier, CREDITS_PROGRAM_KEYS.split.locator);
1103
+ }
1104
+ /**
1105
+ * Returns the proving and verifying keys for the fee_private function in the credits.aleo program
1106
+ *
1107
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the fee function
1108
+ */
1109
+ async feePrivateKeys() {
1110
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.fee_private.prover, CREDITS_PROGRAM_KEYS.fee_private.verifier, CREDITS_PROGRAM_KEYS.fee_private.locator);
1111
+ }
1112
+ /**
1113
+ * Returns the proving and verifying keys for the fee_public function in the credits.aleo program
1114
+ *
1115
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the fee function
1116
+ */
1117
+ async feePublicKeys() {
1118
+ return await this.fetchKeys(CREDITS_PROGRAM_KEYS.fee_public.prover, CREDITS_PROGRAM_KEYS.fee_public.verifier, CREDITS_PROGRAM_KEYS.fee_public.locator);
1119
+ }
1120
+ /**
1121
+ * Gets a verifying key. If the verifying key is for a credits.aleo function, get it from the wasm cache otherwise
1122
+ *
1123
+ * @returns {Promise<VerifyingKey | Error>} Verifying key for the function
1124
+ */
1125
+ // attempt to fetch it from the network
1126
+ async getVerifyingKey(verifierUri) {
1127
+ switch (verifierUri) {
1128
+ case CREDITS_PROGRAM_KEYS.bond_public.verifier:
1129
+ return CREDITS_PROGRAM_KEYS.bond_public.verifyingKey();
1130
+ case CREDITS_PROGRAM_KEYS.bond_validator.verifier:
1131
+ return CREDITS_PROGRAM_KEYS.bond_validator.verifyingKey();
1132
+ case CREDITS_PROGRAM_KEYS.claim_unbond_public.verifier:
1133
+ return CREDITS_PROGRAM_KEYS.claim_unbond_public.verifyingKey();
1134
+ case CREDITS_PROGRAM_KEYS.fee_private.verifier:
1135
+ return CREDITS_PROGRAM_KEYS.fee_private.verifyingKey();
1136
+ case CREDITS_PROGRAM_KEYS.fee_public.verifier:
1137
+ return CREDITS_PROGRAM_KEYS.fee_public.verifyingKey();
1138
+ case CREDITS_PROGRAM_KEYS.inclusion.verifier:
1139
+ return CREDITS_PROGRAM_KEYS.inclusion.verifyingKey();
1140
+ case CREDITS_PROGRAM_KEYS.join.verifier:
1141
+ return CREDITS_PROGRAM_KEYS.join.verifyingKey();
1142
+ case CREDITS_PROGRAM_KEYS.set_validator_state.verifier:
1143
+ return CREDITS_PROGRAM_KEYS.set_validator_state.verifyingKey();
1144
+ case CREDITS_PROGRAM_KEYS.split.verifier:
1145
+ return CREDITS_PROGRAM_KEYS.split.verifyingKey();
1146
+ case CREDITS_PROGRAM_KEYS.transfer_private.verifier:
1147
+ return CREDITS_PROGRAM_KEYS.transfer_private.verifyingKey();
1148
+ case CREDITS_PROGRAM_KEYS.transfer_private_to_public.verifier:
1149
+ return CREDITS_PROGRAM_KEYS.transfer_private_to_public.verifyingKey();
1150
+ case CREDITS_PROGRAM_KEYS.transfer_public.verifier:
1151
+ return CREDITS_PROGRAM_KEYS.transfer_public.verifyingKey();
1152
+ case CREDITS_PROGRAM_KEYS.transfer_public_as_signer.verifier:
1153
+ return CREDITS_PROGRAM_KEYS.transfer_public_as_signer.verifyingKey();
1154
+ case CREDITS_PROGRAM_KEYS.transfer_public_to_private.verifier:
1155
+ return CREDITS_PROGRAM_KEYS.transfer_public_to_private.verifyingKey();
1156
+ case CREDITS_PROGRAM_KEYS.unbond_public.verifier:
1157
+ return CREDITS_PROGRAM_KEYS.unbond_public.verifyingKey();
1158
+ default:
1159
+ try {
1160
+ /// Try to fetch the verifying key from the network as a string
1161
+ const response = await get(verifierUri);
1162
+ const text = await response.text();
1163
+ return VerifyingKey.fromString(text);
1164
+ }
1165
+ catch (e) {
1166
+ /// If that fails, try to fetch the verifying key from the network as bytes
1167
+ try {
1168
+ return VerifyingKey.fromBytes(await this.fetchBytes(verifierUri));
1169
+ }
1170
+ catch (inner) {
1171
+ return new Error("Invalid verifying key. Error: " + inner);
1172
+ }
1173
+ }
1174
+ }
1175
+ }
1176
+ unBondPublicKeys() {
1177
+ return this.fetchKeys(CREDITS_PROGRAM_KEYS.unbond_public.prover, CREDITS_PROGRAM_KEYS.unbond_public.verifier, CREDITS_PROGRAM_KEYS.unbond_public.locator);
1178
+ }
1179
+ }
1180
+
1181
+ /**
1182
+ * Search parameters for the offline key provider. This class implements the KeySearchParams interface and includes
1183
+ * a convenience method for creating a new instance of this class for each function of the credits.aleo program.
1184
+ *
1185
+ * @example
1186
+ * // If storing a key for a custom program function
1187
+ * offlineSearchParams = new OfflineSearchParams("myprogram.aleo/myfunction");
1188
+ *
1189
+ * // If storing a key for a credits.aleo program function
1190
+ * bondPublicKeyParams = OfflineSearchParams.bondPublicKeyParams();
1191
+ */
1192
+ class OfflineSearchParams {
1193
+ cacheKey;
1194
+ verifyCreditsKeys;
1195
+ /**
1196
+ * Create a new OfflineSearchParams instance.
1197
+ *
1198
+ * @param {string} cacheKey - Key used to store the local function proving & verifying keys. This should be stored
1199
+ * under the naming convention "programName/functionName" (i.e. "myprogram.aleo/myfunction")
1200
+ * @param {boolean} verifyCreditsKeys - Whether to verify the keys against the credits.aleo program,
1201
+ * defaults to false, but should be set to true if using keys from the credits.aleo program
1202
+ */
1203
+ constructor(cacheKey, verifyCreditsKeys = false) {
1204
+ this.cacheKey = cacheKey;
1205
+ this.verifyCreditsKeys = verifyCreditsKeys;
1206
+ }
1207
+ /**
1208
+ * Create a new OfflineSearchParams instance for the bond_public function of the credits.aleo program.
1209
+ */
1210
+ static bondPublicKeyParams() {
1211
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.bond_public.locator, true);
1212
+ }
1213
+ /**
1214
+ * Create a new OfflineSearchParams instance for the bond_validator function of the credits.aleo program.
1215
+ */
1216
+ static bondValidatorKeyParams() {
1217
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.bond_validator.locator, true);
1218
+ }
1219
+ /**
1220
+ * Create a new OfflineSearchParams instance for the claim_unbond_public function of the
1221
+ */
1222
+ static claimUnbondPublicKeyParams() {
1223
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.claim_unbond_public.locator, true);
1224
+ }
1225
+ /**
1226
+ * Create a new OfflineSearchParams instance for the fee_private function of the credits.aleo program.
1227
+ */
1228
+ static feePrivateKeyParams() {
1229
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.fee_private.locator, true);
1230
+ }
1231
+ /**
1232
+ * Create a new OfflineSearchParams instance for the fee_public function of the credits.aleo program.
1233
+ */
1234
+ static feePublicKeyParams() {
1235
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.fee_public.locator, true);
1236
+ }
1237
+ /**
1238
+ * Create a new OfflineSearchParams instance for the inclusion prover function.
1239
+ */
1240
+ static inclusionKeyParams() {
1241
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.inclusion.locator, true);
1242
+ }
1243
+ /**
1244
+ * Create a new OfflineSearchParams instance for the join function of the credits.aleo program.
1245
+ */
1246
+ static joinKeyParams() {
1247
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.join.locator, true);
1248
+ }
1249
+ /**
1250
+ * Create a new OfflineSearchParams instance for the set_validator_state function of the credits.aleo program.
1251
+ */
1252
+ static setValidatorStateKeyParams() {
1253
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.set_validator_state.locator, true);
1254
+ }
1255
+ /**
1256
+ * Create a new OfflineSearchParams instance for the split function of the credits.aleo program.
1257
+ */
1258
+ static splitKeyParams() {
1259
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.split.locator, true);
1260
+ }
1261
+ /**
1262
+ * Create a new OfflineSearchParams instance for the transfer_private function of the credits.aleo program.
1263
+ */
1264
+ static transferPrivateKeyParams() {
1265
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.transfer_private.locator, true);
1266
+ }
1267
+ /**
1268
+ * Create a new OfflineSearchParams instance for the transfer_private_to_public function of the credits.aleo program.
1269
+ */
1270
+ static transferPrivateToPublicKeyParams() {
1271
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.transfer_private_to_public.locator, true);
1272
+ }
1273
+ /**
1274
+ * Create a new OfflineSearchParams instance for the transfer_public function of the credits.aleo program.
1275
+ */
1276
+ static transferPublicKeyParams() {
1277
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.transfer_public.locator, true);
1278
+ }
1279
+ /**
1280
+ * Create a new OfflineSearchParams instance for the transfer_public_as_signer function of the credits.aleo program.
1281
+ */
1282
+ static transferPublicAsSignerKeyParams() {
1283
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.transfer_public_as_signer.locator, true);
1284
+ }
1285
+ /**
1286
+ * Create a new OfflineSearchParams instance for the transfer_public_to_private function of the credits.aleo program.
1287
+ */
1288
+ static transferPublicToPrivateKeyParams() {
1289
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.transfer_public_to_private.locator, true);
1290
+ }
1291
+ /**
1292
+ * Create a new OfflineSearchParams instance for the unbond_public function of the credits.aleo program.
1293
+ */
1294
+ static unbondPublicKeyParams() {
1295
+ return new OfflineSearchParams(CREDITS_PROGRAM_KEYS.unbond_public.locator, true);
1296
+ }
1297
+ }
1298
+ /**
1299
+ * A key provider meant for building transactions offline on devices such as hardware wallets. This key provider is not
1300
+ * able to contact the internet for key material and instead relies on the user to insert Aleo function proving &
1301
+ * verifying keys from local storage prior to usage.
1302
+ *
1303
+ * @example
1304
+ * // Create an offline program manager
1305
+ * const programManager = new ProgramManager();
1306
+ *
1307
+ * // Create a temporary account for the execution of the program
1308
+ * const account = new Account();
1309
+ * programManager.setAccount(account);
1310
+ *
1311
+ * // Create the proving keys from the key bytes on the offline machine
1312
+ * console.log("Creating proving keys from local key files");
1313
+ * const program = "program hello_hello.aleo; function hello: input r0 as u32.public; input r1 as u32.private; add r0 r1 into r2; output r2 as u32.private;";
1314
+ * const myFunctionProver = await getLocalKey("/path/to/my/function/hello_hello.prover");
1315
+ * const myFunctionVerifier = await getLocalKey("/path/to/my/function/hello_hello.verifier");
1316
+ * const feePublicProvingKeyBytes = await getLocalKey("/path/to/credits.aleo/feePublic.prover");
1317
+ *
1318
+ * myFunctionProvingKey = ProvingKey.fromBytes(myFunctionProver);
1319
+ * myFunctionVerifyingKey = VerifyingKey.fromBytes(myFunctionVerifier);
1320
+ * const feePublicProvingKey = ProvingKey.fromBytes(feePublicKeyBytes);
1321
+ *
1322
+ * // Create an offline key provider
1323
+ * console.log("Creating offline key provider");
1324
+ * const offlineKeyProvider = new OfflineKeyProvider();
1325
+ *
1326
+ * // Cache the keys
1327
+ * // Cache the proving and verifying keys for the custom hello function
1328
+ * OfflineKeyProvider.cacheKeys("hello_hello.aleo/hello", myFunctionProvingKey, myFunctionVerifyingKey);
1329
+ *
1330
+ * // Cache the proving key for the fee_public function (the verifying key is automatically cached)
1331
+ * OfflineKeyProvider.insertFeePublicKey(feePublicProvingKey);
1332
+ *
1333
+ * // Create an offline query using the latest state root in order to create the inclusion proof
1334
+ * const offlineQuery = new OfflineQuery("latestStateRoot");
1335
+ *
1336
+ * // Insert the key provider into the program manager
1337
+ * programManager.setKeyProvider(offlineKeyProvider);
1338
+ *
1339
+ * // Create the offline search params
1340
+ * const offlineSearchParams = new OfflineSearchParams("hello_hello.aleo/hello");
1341
+ *
1342
+ * // Create the offline transaction
1343
+ * const offlineExecuteTx = <Transaction>await this.buildExecutionTransaction("hello_hello.aleo", "hello", 1, false, ["5u32", "5u32"], undefined, offlineSearchParams, undefined, undefined, undefined, undefined, offlineQuery, program);
1344
+ *
1345
+ * // Broadcast the transaction later on a machine with internet access
1346
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1347
+ * const txId = await networkClient.broadcastTransaction(offlineExecuteTx);
1348
+ */
1349
+ class OfflineKeyProvider {
1350
+ cache;
1351
+ constructor() {
1352
+ this.cache = new Map();
1353
+ }
1354
+ /**
1355
+ * Get bond_public function keys from the credits.aleo program. The keys must be cached prior to calling this
1356
+ * method for it to work.
1357
+ *
1358
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the bond_public function
1359
+ */
1360
+ bondPublicKeys() {
1361
+ return this.functionKeys(OfflineSearchParams.bondPublicKeyParams());
1362
+ }
1363
+ ;
1364
+ /**
1365
+ * Get bond_validator function keys from the credits.aleo program. The keys must be cached prior to calling this
1366
+ * method for it to work.
1367
+ *
1368
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the bond_public function
1369
+ */
1370
+ bondValidatorKeys() {
1371
+ return this.functionKeys(OfflineSearchParams.bondValidatorKeyParams());
1372
+ }
1373
+ ;
1374
+ /**
1375
+ * Cache a set of keys. This will overwrite any existing keys with the same keyId. The user can check if a keyId
1376
+ * exists in the cache using the containsKeys method prior to calling this method if overwriting is not desired.
1377
+ *
1378
+ * @param {string} keyId access key for the cache
1379
+ * @param {FunctionKeyPair} keys keys to cache
1380
+ */
1381
+ cacheKeys(keyId, keys) {
1382
+ const [provingKey, verifyingKey] = keys;
1383
+ this.cache.set(keyId, [provingKey.toBytes(), verifyingKey.toBytes()]);
1384
+ }
1385
+ ;
1386
+ /**
1387
+ * Get unbond_public function keys from the credits.aleo program. The keys must be cached prior to calling this
1388
+ * method for it to work.
1389
+ *
1390
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the unbond_public function
1391
+ */
1392
+ claimUnbondPublicKeys() {
1393
+ return this.functionKeys(OfflineSearchParams.claimUnbondPublicKeyParams());
1394
+ }
1395
+ ;
1396
+ /**
1397
+ * Get arbitrary function key from the offline key provider cache.
1398
+ *
1399
+ * @param {KeySearchParams | undefined} params - Optional search parameters for the key provider
1400
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the specified program
1401
+ *
1402
+ * @example
1403
+ * /// First cache the keys from local offline resources
1404
+ * const offlineKeyProvider = new OfflineKeyProvider();
1405
+ * const myFunctionVerifyingKey = VerifyingKey.fromString("verifier...");
1406
+ * const myFunctionProvingKeyBytes = await readBinaryFile('./resources/myfunction.prover');
1407
+ * const myFunctionProvingKey = ProvingKey.fromBytes(myFunctionProvingKeyBytes);
1408
+ *
1409
+ * /// Cache the keys for future use with a memorable locator
1410
+ * offlineKeyProvider.cacheKeys("myprogram.aleo/myfunction", [myFunctionProvingKey, myFunctionVerifyingKey]);
1411
+ *
1412
+ * /// When they're needed, retrieve the keys from the cache
1413
+ *
1414
+ * /// First create a search parameter object with the same locator used to cache the keys
1415
+ * const keyParams = new OfflineSearchParams("myprogram.aleo/myfunction");
1416
+ *
1417
+ * /// Then retrieve the keys
1418
+ * const [myFunctionProver, myFunctionVerifier] = await offlineKeyProvider.functionKeys(keyParams);
1419
+ */
1420
+ functionKeys(params) {
1421
+ return new Promise((resolve, reject) => {
1422
+ if (params === undefined) {
1423
+ reject(new Error("No search parameters provided, cannot retrieve keys"));
1424
+ }
1425
+ else {
1426
+ const keyId = params.cacheKey;
1427
+ const verifyCreditsKeys = params.verifyCreditsKeys;
1428
+ if (this.cache.has(keyId)) {
1429
+ const [provingKeyBytes, verifyingKeyBytes] = this.cache.get(keyId);
1430
+ const provingKey = ProvingKey.fromBytes(provingKeyBytes);
1431
+ const verifyingKey = VerifyingKey.fromBytes(verifyingKeyBytes);
1432
+ if (verifyCreditsKeys) {
1433
+ const keysMatchExpected = this.verifyCreditsKeys(keyId, provingKey, verifyingKey);
1434
+ if (!keysMatchExpected) {
1435
+ reject(new Error(`Cached keys do not match expected keys for ${keyId}`));
1436
+ }
1437
+ }
1438
+ resolve([provingKey, verifyingKey]);
1439
+ }
1440
+ else {
1441
+ reject(new Error("Keys not found in cache for " + keyId));
1442
+ }
1443
+ }
1444
+ });
1445
+ }
1446
+ ;
1447
+ /**
1448
+ * Determines if the keys for a given credits function match the expected keys.
1449
+ *
1450
+ * @returns {boolean} Whether the keys match the expected keys
1451
+ */
1452
+ verifyCreditsKeys(locator, provingKey, verifyingKey) {
1453
+ switch (locator) {
1454
+ case CREDITS_PROGRAM_KEYS.bond_public.locator:
1455
+ return provingKey.isBondPublicProver() && verifyingKey.isBondPublicVerifier();
1456
+ case CREDITS_PROGRAM_KEYS.claim_unbond_public.locator:
1457
+ return provingKey.isClaimUnbondPublicProver() && verifyingKey.isClaimUnbondPublicVerifier();
1458
+ case CREDITS_PROGRAM_KEYS.fee_private.locator:
1459
+ return provingKey.isFeePrivateProver() && verifyingKey.isFeePrivateVerifier();
1460
+ case CREDITS_PROGRAM_KEYS.fee_public.locator:
1461
+ return provingKey.isFeePublicProver() && verifyingKey.isFeePublicVerifier();
1462
+ case CREDITS_PROGRAM_KEYS.inclusion.locator:
1463
+ return provingKey.isInclusionProver() && verifyingKey.isInclusionVerifier();
1464
+ case CREDITS_PROGRAM_KEYS.join.locator:
1465
+ return provingKey.isJoinProver() && verifyingKey.isJoinVerifier();
1466
+ case CREDITS_PROGRAM_KEYS.set_validator_state.locator:
1467
+ return provingKey.isSetValidatorStateProver() && verifyingKey.isSetValidatorStateVerifier();
1468
+ case CREDITS_PROGRAM_KEYS.split.locator:
1469
+ return provingKey.isSplitProver() && verifyingKey.isSplitVerifier();
1470
+ case CREDITS_PROGRAM_KEYS.transfer_private.locator:
1471
+ return provingKey.isTransferPrivateProver() && verifyingKey.isTransferPrivateVerifier();
1472
+ case CREDITS_PROGRAM_KEYS.transfer_private_to_public.locator:
1473
+ return provingKey.isTransferPrivateToPublicProver() && verifyingKey.isTransferPrivateToPublicVerifier();
1474
+ case CREDITS_PROGRAM_KEYS.transfer_public.locator:
1475
+ return provingKey.isTransferPublicProver() && verifyingKey.isTransferPublicVerifier();
1476
+ case CREDITS_PROGRAM_KEYS.transfer_public_to_private.locator:
1477
+ return provingKey.isTransferPublicToPrivateProver() && verifyingKey.isTransferPublicToPrivateVerifier();
1478
+ case CREDITS_PROGRAM_KEYS.unbond_public.locator:
1479
+ return provingKey.isUnbondPublicProver() && verifyingKey.isUnbondPublicVerifier();
1480
+ default:
1481
+ return false;
1482
+ }
1483
+ }
1484
+ /**
1485
+ * Get fee_private function keys from the credits.aleo program. The keys must be cached prior to calling this
1486
+ * method for it to work.
1487
+ *
1488
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the join function
1489
+ */
1490
+ feePrivateKeys() {
1491
+ return this.functionKeys(OfflineSearchParams.feePrivateKeyParams());
1492
+ }
1493
+ ;
1494
+ /**
1495
+ * Get fee_public function keys from the credits.aleo program. The keys must be cached prior to calling this
1496
+ * method for it to work.
1497
+ *
1498
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the join function
1499
+ */
1500
+ feePublicKeys() {
1501
+ return this.functionKeys(OfflineSearchParams.feePublicKeyParams());
1502
+ }
1503
+ ;
1504
+ /**
1505
+ * Get join function keys from the credits.aleo program. The keys must be cached prior to calling this
1506
+ * method for it to work.
1507
+ *
1508
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the join function
1509
+ */
1510
+ joinKeys() {
1511
+ return this.functionKeys(OfflineSearchParams.joinKeyParams());
1512
+ }
1513
+ ;
1514
+ /**
1515
+ * Get split function keys from the credits.aleo program. The keys must be cached prior to calling this
1516
+ * method for it to work.
1517
+ *
1518
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the join function
1519
+ */
1520
+ splitKeys() {
1521
+ return this.functionKeys(OfflineSearchParams.splitKeyParams());
1522
+ }
1523
+ ;
1524
+ /**
1525
+ * Get keys for a variant of the transfer function from the credits.aleo program.
1526
+ *
1527
+ *
1528
+ * @param {string} visibility Visibility of the transfer function (private, public, privateToPublic, publicToPrivate)
1529
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the specified transfer function
1530
+ *
1531
+ * @example
1532
+ * // Create a new OfflineKeyProvider
1533
+ * const offlineKeyProvider = new OfflineKeyProvider();
1534
+ *
1535
+ * // Cache the keys for future use with the official locator
1536
+ * const transferPublicProvingKeyBytes = await readBinaryFile('./resources/transfer_public.prover.a74565e');
1537
+ * const transferPublicProvingKey = ProvingKey.fromBytes(transferPublicProvingKeyBytes);
1538
+ *
1539
+ * // Cache the transfer_public keys for future use with the OfflinKeyProvider's convenience method for
1540
+ * // transfer_public (the verifying key will be cached automatically)
1541
+ * offlineKeyProvider.insertTransferPublicKeys(transferPublicProvingKey);
1542
+ *
1543
+ * /// When they're needed, retrieve the keys from the cache
1544
+ * const [transferPublicProvingKey, transferPublicVerifyingKey] = await keyProvider.transferKeys("public");
1545
+ */
1546
+ transferKeys(visibility) {
1547
+ if (PRIVATE_TRANSFER.has(visibility)) {
1548
+ return this.functionKeys(OfflineSearchParams.transferPrivateKeyParams());
1549
+ }
1550
+ else if (PRIVATE_TO_PUBLIC_TRANSFER.has(visibility)) {
1551
+ return this.functionKeys(OfflineSearchParams.transferPrivateToPublicKeyParams());
1552
+ }
1553
+ else if (PUBLIC_TRANSFER.has(visibility)) {
1554
+ return this.functionKeys(OfflineSearchParams.transferPublicKeyParams());
1555
+ }
1556
+ else if (PUBLIC_TRANSFER_AS_SIGNER.has(visibility)) {
1557
+ return this.functionKeys(OfflineSearchParams.transferPublicAsSignerKeyParams());
1558
+ }
1559
+ else if (PUBLIC_TO_PRIVATE_TRANSFER.has(visibility)) {
1560
+ return this.functionKeys(OfflineSearchParams.transferPublicToPrivateKeyParams());
1561
+ }
1562
+ else {
1563
+ throw new Error("Invalid visibility type");
1564
+ }
1565
+ }
1566
+ ;
1567
+ /**
1568
+ * Get unbond_public function keys from the credits.aleo program
1569
+ *
1570
+ * @returns {Promise<FunctionKeyPair | Error>} Proving and verifying keys for the join function
1571
+ */
1572
+ async unBondPublicKeys() {
1573
+ return this.functionKeys(OfflineSearchParams.unbondPublicKeyParams());
1574
+ }
1575
+ ;
1576
+ /**
1577
+ * Insert the proving and verifying keys for the bond_public function into the cache. Only the proving key needs
1578
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1579
+ * that the keys match the expected checksum for bond_public before inserting them into the cache.
1580
+ *
1581
+ * @param provingKey
1582
+ */
1583
+ insertBondPublicKeys(provingKey) {
1584
+ if (provingKey.isBondPublicProver()) {
1585
+ this.cache.set(CREDITS_PROGRAM_KEYS.bond_public.locator, [provingKey.toBytes(), VerifyingKey.bondPublicVerifier().toBytes()]);
1586
+ }
1587
+ else {
1588
+ throw new Error("Attempted to insert invalid proving keys for bond_public");
1589
+ }
1590
+ }
1591
+ /**
1592
+ * Insert the proving and verifying keys for the claim_unbond_public function into the cache. Only the proving key needs
1593
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1594
+ * that the keys match the expected checksum for claim_unbond_public before inserting them into the cache.
1595
+ *
1596
+ * @param provingKey
1597
+ */
1598
+ insertClaimUnbondPublicKeys(provingKey) {
1599
+ if (provingKey.isClaimUnbondPublicProver()) {
1600
+ this.cache.set(CREDITS_PROGRAM_KEYS.claim_unbond_public.locator, [provingKey.toBytes(), VerifyingKey.claimUnbondPublicVerifier().toBytes()]);
1601
+ }
1602
+ else {
1603
+ throw new Error("Attempted to insert invalid proving keys for claim_unbond_public");
1604
+ }
1605
+ }
1606
+ /**
1607
+ * Insert the proving and verifying keys for the fee_private function into the cache. Only the proving key needs
1608
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1609
+ * that the keys match the expected checksum for fee_private before inserting them into the cache.
1610
+ *
1611
+ * @param provingKey
1612
+ */
1613
+ insertFeePrivateKeys(provingKey) {
1614
+ if (provingKey.isFeePrivateProver()) {
1615
+ this.cache.set(CREDITS_PROGRAM_KEYS.fee_private.locator, [provingKey.toBytes(), VerifyingKey.feePrivateVerifier().toBytes()]);
1616
+ }
1617
+ else {
1618
+ throw new Error("Attempted to insert invalid proving keys for fee_private");
1619
+ }
1620
+ }
1621
+ /**
1622
+ * Insert the proving and verifying keys for the fee_public function into the cache. Only the proving key needs
1623
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1624
+ * that the keys match the expected checksum for fee_public before inserting them into the cache.
1625
+ *
1626
+ * @param provingKey
1627
+ */
1628
+ insertFeePublicKeys(provingKey) {
1629
+ if (provingKey.isFeePublicProver()) {
1630
+ this.cache.set(CREDITS_PROGRAM_KEYS.fee_public.locator, [provingKey.toBytes(), VerifyingKey.feePublicVerifier().toBytes()]);
1631
+ }
1632
+ else {
1633
+ throw new Error("Attempted to insert invalid proving keys for fee_public");
1634
+ }
1635
+ }
1636
+ /**
1637
+ * Insert the proving and verifying keys for the join function into the cache. Only the proving key needs
1638
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1639
+ * that the keys match the expected checksum for join before inserting them into the cache.
1640
+ *
1641
+ * @param provingKey
1642
+ */
1643
+ insertJoinKeys(provingKey) {
1644
+ if (provingKey.isJoinProver()) {
1645
+ this.cache.set(CREDITS_PROGRAM_KEYS.join.locator, [provingKey.toBytes(), VerifyingKey.joinVerifier().toBytes()]);
1646
+ }
1647
+ else {
1648
+ throw new Error("Attempted to insert invalid proving keys for join");
1649
+ }
1650
+ }
1651
+ /**
1652
+ * Insert the proving and verifying keys for the set_validator_state function into the cache. Only the proving key needs
1653
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1654
+ * that the keys match the expected checksum for set_validator_state before inserting them into the cache.
1655
+ *
1656
+ * @param provingKey
1657
+ */
1658
+ insertSetValidatorStateKeys(provingKey) {
1659
+ if (provingKey.isSetValidatorStateProver()) {
1660
+ this.cache.set(CREDITS_PROGRAM_KEYS.set_validator_state.locator, [provingKey.toBytes(), VerifyingKey.setValidatorStateVerifier().toBytes()]);
1661
+ }
1662
+ else {
1663
+ throw new Error("Attempted to insert invalid proving keys for set_validator_state");
1664
+ }
1665
+ }
1666
+ /**
1667
+ * Insert the proving and verifying keys for the split function into the cache. Only the proving key needs
1668
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1669
+ * that the keys match the expected checksum for split before inserting them into the cache.
1670
+ *
1671
+ * @param provingKey
1672
+ */
1673
+ insertSplitKeys(provingKey) {
1674
+ if (provingKey.isSplitProver()) {
1675
+ this.cache.set(CREDITS_PROGRAM_KEYS.split.locator, [provingKey.toBytes(), VerifyingKey.splitVerifier().toBytes()]);
1676
+ }
1677
+ else {
1678
+ throw new Error("Attempted to insert invalid proving keys for split");
1679
+ }
1680
+ }
1681
+ /**
1682
+ * Insert the proving and verifying keys for the transfer_private function into the cache. Only the proving key needs
1683
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1684
+ * that the keys match the expected checksum for transfer_private before inserting them into the cache.
1685
+ *
1686
+ * @param provingKey
1687
+ */
1688
+ insertTransferPrivateKeys(provingKey) {
1689
+ if (provingKey.isTransferPrivateProver()) {
1690
+ this.cache.set(CREDITS_PROGRAM_KEYS.transfer_private.locator, [provingKey.toBytes(), VerifyingKey.transferPrivateVerifier().toBytes()]);
1691
+ }
1692
+ else {
1693
+ throw new Error("Attempted to insert invalid proving keys for transfer_private");
1694
+ }
1695
+ }
1696
+ /**
1697
+ * Insert the proving and verifying keys for the transfer_private_to_public function into the cache. Only the proving key needs
1698
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1699
+ * that the keys match the expected checksum for transfer_private_to_public before inserting them into the cache.
1700
+ *
1701
+ * @param provingKey
1702
+ */
1703
+ insertTransferPrivateToPublicKeys(provingKey) {
1704
+ if (provingKey.isTransferPrivateToPublicProver()) {
1705
+ this.cache.set(CREDITS_PROGRAM_KEYS.transfer_private_to_public.locator, [provingKey.toBytes(), VerifyingKey.transferPrivateToPublicVerifier().toBytes()]);
1706
+ }
1707
+ else {
1708
+ throw new Error("Attempted to insert invalid proving keys for transfer_private_to_public");
1709
+ }
1710
+ }
1711
+ /**
1712
+ * Insert the proving and verifying keys for the transfer_public function into the cache. Only the proving key needs
1713
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1714
+ * that the keys match the expected checksum for transfer_public before inserting them into the cache.
1715
+ *
1716
+ * @param provingKey
1717
+ */
1718
+ insertTransferPublicKeys(provingKey) {
1719
+ if (provingKey.isTransferPublicProver()) {
1720
+ this.cache.set(CREDITS_PROGRAM_KEYS.transfer_public.locator, [provingKey.toBytes(), VerifyingKey.transferPublicVerifier().toBytes()]);
1721
+ }
1722
+ else {
1723
+ throw new Error("Attempted to insert invalid proving keys for transfer_public");
1724
+ }
1725
+ }
1726
+ /**
1727
+ * Insert the proving and verifying keys for the transfer_public_to_private function into the cache. Only the proving key needs
1728
+ * to be inserted, the verifying key is automatically inserted by the SDK. This function will automatically check
1729
+ * that the keys match the expected checksum for transfer_public_to_private before inserting them into the cache.
1730
+ *
1731
+ * @param provingKey
1732
+ */
1733
+ insertTransferPublicToPrivateKeys(provingKey) {
1734
+ if (provingKey.isTransferPublicToPrivateProver()) {
1735
+ this.cache.set(CREDITS_PROGRAM_KEYS.transfer_public_to_private.locator, [provingKey.toBytes(), VerifyingKey.transferPublicToPrivateVerifier().toBytes()]);
1736
+ }
1737
+ else {
1738
+ throw new Error("Attempted to insert invalid proving keys for transfer_public_to_private");
1739
+ }
1740
+ }
1741
+ insertUnbondPublicKeys(provingKey) {
1742
+ if (provingKey.isUnbondPublicProver()) {
1743
+ this.cache.set(CREDITS_PROGRAM_KEYS.unbond_public.locator, [provingKey.toBytes(), VerifyingKey.unbondPublicVerifier().toBytes()]);
1744
+ }
1745
+ else {
1746
+ throw new Error("Attempted to insert invalid proving keys for unbond_public");
1747
+ }
1748
+ }
1749
+ }
1750
+
1751
+ /**
1752
+ * A record provider implementation that uses the official Aleo API to find records for usage in program execution and
1753
+ * deployment, wallet functionality, and other use cases.
1754
+ */
1755
+ class NetworkRecordProvider {
1756
+ account;
1757
+ networkClient;
1758
+ constructor(account, networkClient) {
1759
+ this.account = account;
1760
+ this.networkClient = networkClient;
1761
+ }
1762
+ /**
1763
+ * Set the account used to search for records
1764
+ *
1765
+ * @param {Account} account The account to use for searching for records
1766
+ */
1767
+ setAccount(account) {
1768
+ this.account = account;
1769
+ }
1770
+ /**
1771
+ * Find a list of credit records with a given number of microcredits by via the official Aleo API
1772
+ *
1773
+ * @param {number[]} microcredits The number of microcredits to search for
1774
+ * @param {boolean} unspent Whether or not the record is unspent
1775
+ * @param {string[]} nonces Nonces of records already found so that they are not found again
1776
+ * @param {RecordSearchParams} searchParameters Additional parameters to search for
1777
+ * @returns {Promise<RecordPlaintext | Error>} The record if found, otherwise an error
1778
+ *
1779
+ * @example
1780
+ * // Create a new NetworkRecordProvider
1781
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1782
+ * const keyProvider = new AleoKeyProvider();
1783
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
1784
+ *
1785
+ * // The record provider can be used to find records with a given number of microcredits
1786
+ * const record = await recordProvider.findCreditsRecord(5000, true, []);
1787
+ *
1788
+ * // When a record is found but not yet used, it's nonce should be added to the nonces parameter so that it is not
1789
+ * // found again if a subsequent search is performed
1790
+ * const records = await recordProvider.findCreditsRecords(5000, true, [record.nonce()]);
1791
+ *
1792
+ * // When the program manager is initialized with the record provider it will be used to find automatically find
1793
+ * // fee records and amount records for value transfers so that they do not need to be specified manually
1794
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
1795
+ * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
1796
+ *
1797
+ * */
1798
+ async findCreditsRecords(microcredits, unspent, nonces, searchParameters) {
1799
+ let startHeight = 0;
1800
+ let endHeight = 0;
1801
+ if (searchParameters) {
1802
+ if ("startHeight" in searchParameters && typeof searchParameters["endHeight"] == "number") {
1803
+ startHeight = searchParameters["startHeight"];
1804
+ }
1805
+ if ("endHeight" in searchParameters && typeof searchParameters["endHeight"] == "number") {
1806
+ endHeight = searchParameters["endHeight"];
1807
+ }
1808
+ }
1809
+ // If the end height is not specified, use the current block height
1810
+ if (endHeight == 0) {
1811
+ const end = await this.networkClient.getLatestHeight();
1812
+ if (end instanceof Error) {
1813
+ throw logAndThrow("Unable to get current block height from the network");
1814
+ }
1815
+ endHeight = end;
1816
+ }
1817
+ // If the start height is greater than the end height, throw an error
1818
+ if (startHeight >= endHeight) {
1819
+ throw logAndThrow("Start height must be less than end height");
1820
+ }
1821
+ return await this.networkClient.findUnspentRecords(startHeight, endHeight, this.account.privateKey(), microcredits, undefined, nonces);
1822
+ }
1823
+ /**
1824
+ * Find a credit record with a given number of microcredits by via the official Aleo API
1825
+ *
1826
+ * @param {number} microcredits The number of microcredits to search for
1827
+ * @param {boolean} unspent Whether or not the record is unspent
1828
+ * @param {string[]} nonces Nonces of records already found so that they are not found again
1829
+ * @param {RecordSearchParams} searchParameters Additional parameters to search for
1830
+ * @returns {Promise<RecordPlaintext | Error>} The record if found, otherwise an error
1831
+ *
1832
+ * @example
1833
+ * // Create a new NetworkRecordProvider
1834
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1835
+ * const keyProvider = new AleoKeyProvider();
1836
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
1837
+ *
1838
+ * // The record provider can be used to find records with a given number of microcredits
1839
+ * const record = await recordProvider.findCreditsRecord(5000, true, []);
1840
+ *
1841
+ * // When a record is found but not yet used, it's nonce should be added to the nonces parameter so that it is not
1842
+ * // found again if a subsequent search is performed
1843
+ * const records = await recordProvider.findCreditsRecords(5000, true, [record.nonce()]);
1844
+ *
1845
+ * // When the program manager is initialized with the record provider it will be used to find automatically find
1846
+ * // fee records and amount records for value transfers so that they do not need to be specified manually
1847
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
1848
+ * programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
1849
+ */
1850
+ async findCreditsRecord(microcredits, unspent, nonces, searchParameters) {
1851
+ const records = await this.findCreditsRecords([microcredits], unspent, nonces, searchParameters);
1852
+ if (!(records instanceof Error) && records.length > 0) {
1853
+ return records[0];
1854
+ }
1855
+ console.error("Record not found with error:", records);
1856
+ return new Error("Record not found");
1857
+ }
1858
+ /**
1859
+ * Find an arbitrary record. WARNING: This function is not implemented yet and will throw an error.
1860
+ */
1861
+ async findRecord(unspent, nonces, searchParameters) {
1862
+ throw new Error("Method not implemented.");
1863
+ }
1864
+ /**
1865
+ * Find multiple arbitrary records. WARNING: This function is not implemented yet and will throw an error.
1866
+ */
1867
+ async findRecords(unspent, nonces, searchParameters) {
1868
+ throw new Error("Method not implemented.");
1869
+ }
1870
+ }
1871
+ /**
1872
+ * BlockHeightSearch is a RecordSearchParams implementation that allows for searching for records within a given
1873
+ * block height range.
1874
+ *
1875
+ * @example
1876
+ * // Create a new BlockHeightSearch
1877
+ * const params = new BlockHeightSearch(89995, 99995);
1878
+ *
1879
+ * // Create a new NetworkRecordProvider
1880
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1881
+ * const keyProvider = new AleoKeyProvider();
1882
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
1883
+ *
1884
+ * // The record provider can be used to find records with a given number of microcredits and the block height search
1885
+ * // can be used to find records within a given block height range
1886
+ * const record = await recordProvider.findCreditsRecord(5000, true, [], params);
1887
+ *
1888
+ */
1889
+ class BlockHeightSearch {
1890
+ startHeight;
1891
+ endHeight;
1892
+ constructor(startHeight, endHeight) {
1893
+ this.startHeight = startHeight;
1894
+ this.endHeight = endHeight;
1895
+ }
1896
+ }
1897
+
1898
+ // Experimental example where SDK manages worker
1899
+ let singletonWorker = null;
1900
+ const createAleoWorker = () => {
1901
+ if (!singletonWorker) {
1902
+ const worker = new Worker(new URL("worker.js", import.meta.url), {
1903
+ type: "module",
1904
+ });
1905
+ singletonWorker = wrap(worker);
1906
+ }
1907
+ return singletonWorker;
1908
+ };
1909
+
1910
+ /**
1911
+ * The ProgramManager class is used to execute and deploy programs on the Aleo network and create value transfers.
1912
+ */
1913
+ class ProgramManager {
1914
+ account;
1915
+ keyProvider;
1916
+ host;
1917
+ networkClient;
1918
+ recordProvider;
1919
+ /** Create a new instance of the ProgramManager
1920
+ *
1921
+ * @param { string | undefined } host A host uri running the official Aleo API
1922
+ * @param { FunctionKeyProvider | undefined } keyProvider A key provider that implements {@link FunctionKeyProvider} interface
1923
+ * @param { RecordProvider | undefined } recordProvider A record provider that implements {@link RecordProvider} interface
1924
+ */
1925
+ constructor(host, keyProvider, recordProvider) {
1926
+ this.host = host ? host : 'https://api.explorer.aleo.org/v1';
1927
+ this.networkClient = new AleoNetworkClient(this.host);
1928
+ this.keyProvider = keyProvider ? keyProvider : new AleoKeyProvider();
1929
+ this.recordProvider = recordProvider;
1930
+ }
1931
+ /**
1932
+ * Set the account to use for transaction submission to the Aleo network
1933
+ *
1934
+ * @param {Account} account Account to use for transaction submission
1935
+ */
1936
+ setAccount(account) {
1937
+ this.account = account;
1938
+ }
1939
+ /**
1940
+ * Set the key provider that provides the proving and verifying keys for programs
1941
+ *
1942
+ * @param {FunctionKeyProvider} keyProvider
1943
+ */
1944
+ setKeyProvider(keyProvider) {
1945
+ this.keyProvider = keyProvider;
1946
+ }
1947
+ /**
1948
+ * Set the host peer to use for transaction submission to the Aleo network
1949
+ *
1950
+ * @param host {string} Peer url to use for transaction submission
1951
+ */
1952
+ setHost(host) {
1953
+ this.host = host;
1954
+ this.networkClient.setHost(host);
1955
+ }
1956
+ /**
1957
+ * Set the record provider that provides records for transactions
1958
+ *
1959
+ * @param {RecordProvider} recordProvider
1960
+ */
1961
+ setRecordProvider(recordProvider) {
1962
+ this.recordProvider = recordProvider;
1963
+ }
1964
+ /**
1965
+ * Deploy an Aleo program to the Aleo network
1966
+ *
1967
+ * @param {string} program Program source code
1968
+ * @param {number} fee Fee to pay for the transaction
1969
+ * @param {boolean} privateFee Use a private record to pay the fee. If false this will use the account's public credit balance
1970
+ * @param {RecordSearchParams | undefined} recordSearchParams Optional parameters for searching for a record to use
1971
+ * pay the deployment fee
1972
+ * @param {string | RecordPlaintext | undefined} feeRecord Optional Fee record to use for the transaction
1973
+ * @param {PrivateKey | undefined} privateKey Optional private key to use for the transaction
1974
+ * @returns {string | Error} The transaction id of the deployed program or a failure message from the network
1975
+ *
1976
+ * @example
1977
+ * // Create a new NetworkClient, KeyProvider, and RecordProvider
1978
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1979
+ * const keyProvider = new AleoKeyProvider();
1980
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
1981
+ *
1982
+ * // Initialize a program manager with the key provider to automatically fetch keys for deployments
1983
+ * const program = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n";
1984
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
1985
+ *
1986
+ * // Define a fee in credits
1987
+ * const fee = 1.2;
1988
+ *
1989
+ * // Deploy the program
1990
+ * const tx_id = await programManager.deploy(program, fee);
1991
+ *
1992
+ * // Verify the transaction was successful
1993
+ * const transaction = await programManager.networkClient.getTransaction(tx_id);
1994
+ */
1995
+ async deploy(program, fee, privateFee, recordSearchParams, feeRecord, privateKey) {
1996
+ // Ensure the program is valid and does not exist on the network
1997
+ try {
1998
+ const programObject = Program.fromString(program);
1999
+ let programSource;
2000
+ try {
2001
+ programSource = await this.networkClient.getProgram(programObject.id());
2002
+ }
2003
+ catch (e) {
2004
+ // Program does not exist on the network, deployment can proceed
2005
+ console.log(`Program ${programObject.id()} does not exist on the network, deploying...`);
2006
+ }
2007
+ if (typeof programSource == "string") {
2008
+ throw (`Program ${programObject.id()} already exists on the network, please rename your program`);
2009
+ }
2010
+ }
2011
+ catch (e) {
2012
+ throw logAndThrow(`Error validating program: ${e}`);
2013
+ }
2014
+ // Get the private key from the account if it is not provided in the parameters
2015
+ let deploymentPrivateKey = privateKey;
2016
+ if (typeof privateKey === "undefined" && typeof this.account !== "undefined") {
2017
+ deploymentPrivateKey = this.account.privateKey();
2018
+ }
2019
+ if (typeof deploymentPrivateKey === "undefined") {
2020
+ throw ("No private key provided and no private key set in the ProgramManager");
2021
+ }
2022
+ // Get the fee record from the account if it is not provided in the parameters
2023
+ try {
2024
+ feeRecord = privateFee ? await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams) : undefined;
2025
+ }
2026
+ catch (e) {
2027
+ throw logAndThrow(`Error finding fee record. Record finder response: '${e}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
2028
+ }
2029
+ // Get the proving and verifying keys from the key provider
2030
+ let feeKeys;
2031
+ try {
2032
+ feeKeys = privateFee ? await this.keyProvider.feePrivateKeys() : await this.keyProvider.feePublicKeys();
2033
+ }
2034
+ catch (e) {
2035
+ throw logAndThrow(`Error finding fee keys. Key finder response: '${e}'. Please ensure your key provider is configured correctly.`);
2036
+ }
2037
+ const [feeProvingKey, feeVerifyingKey] = feeKeys;
2038
+ // Resolve the program imports if they exist
2039
+ let imports;
2040
+ try {
2041
+ imports = await this.networkClient.getProgramImports(program);
2042
+ }
2043
+ catch (e) {
2044
+ throw logAndThrow(`Error finding program imports. Network response: '${e}'. Please ensure you're connected to a valid Aleo network and the program is deployed to the network.`);
2045
+ }
2046
+ // Build a deployment transaction and submit it to the network
2047
+ const tx = await ProgramManager$1.buildDeploymentTransaction(deploymentPrivateKey, program, fee, feeRecord, this.host, imports, feeProvingKey, feeVerifyingKey);
2048
+ return await this.networkClient.submitTransaction(tx);
2049
+ }
2050
+ /**
2051
+ * Builds an execution transaction for submission to the Aleo network.
2052
+ *
2053
+ * @param {ExecuteOptions} options - The options for the execution transaction.
2054
+ * @returns {Promise<Transaction | Error>} - A promise that resolves to the transaction or an error.
2055
+ *
2056
+ * @example
2057
+ * // Create a new NetworkClient, KeyProvider, and RecordProvider using official Aleo record, key, and network providers
2058
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
2059
+ * const keyProvider = new AleoKeyProvider();
2060
+ * keyProvider.useCache = true;
2061
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
2062
+ *
2063
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions
2064
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
2065
+ *
2066
+ * // Build and execute the transaction
2067
+ * const transaction = await programManager.buildExecutionTransaction({
2068
+ * programName: "hello_hello.aleo",
2069
+ * functionName: "hello_hello",
2070
+ * fee: 0.020,
2071
+ * privateFee: false,
2072
+ * inputs: ["5u32", "5u32"],
2073
+ * keySearchParams: { "cacheKey": "hello_hello:hello" }
2074
+ * });
2075
+ * const result = await programManager.networkClient.submitTransaction(transaction);
2076
+ */
2077
+ async buildExecutionTransaction(options) {
2078
+ // Destructure the options object to access the parameters
2079
+ const { programName, functionName, fee, privateFee, inputs, recordSearchParams, keySearchParams, privateKey, offlineQuery } = options;
2080
+ let feeRecord = options.feeRecord;
2081
+ let provingKey = options.provingKey;
2082
+ let verifyingKey = options.verifyingKey;
2083
+ let program = options.program;
2084
+ let imports = options.imports;
2085
+ // Ensure the function exists on the network
2086
+ if (program === undefined) {
2087
+ try {
2088
+ program = (await this.networkClient.getProgram(programName));
2089
+ }
2090
+ catch (e) {
2091
+ throw logAndThrow(`Error finding ${programName}. Network response: '${e}'. Please ensure you're connected to a valid Aleo network the program is deployed to the network.`);
2092
+ }
2093
+ }
2094
+ else if (program instanceof Program) {
2095
+ program = program.toString();
2096
+ }
2097
+ // Get the private key from the account if it is not provided in the parameters
2098
+ let executionPrivateKey = privateKey;
2099
+ if (typeof privateKey === "undefined" && typeof this.account !== "undefined") {
2100
+ executionPrivateKey = this.account.privateKey();
2101
+ }
2102
+ if (typeof executionPrivateKey === "undefined") {
2103
+ throw ("No private key provided and no private key set in the ProgramManager");
2104
+ }
2105
+ // Get the fee record from the account if it is not provided in the parameters
2106
+ try {
2107
+ feeRecord = privateFee ? await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams) : undefined;
2108
+ }
2109
+ catch (e) {
2110
+ throw logAndThrow(`Error finding fee record. Record finder response: '${e}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
2111
+ }
2112
+ // Get the fee proving and verifying keys from the key provider
2113
+ let feeKeys;
2114
+ try {
2115
+ feeKeys = privateFee ? await this.keyProvider.feePrivateKeys() : await this.keyProvider.feePublicKeys();
2116
+ }
2117
+ catch (e) {
2118
+ throw logAndThrow(`Error finding fee keys. Key finder response: '${e}'. Please ensure your key provider is configured correctly.`);
2119
+ }
2120
+ const [feeProvingKey, feeVerifyingKey] = feeKeys;
2121
+ // If the function proving and verifying keys are not provided, attempt to find them using the key provider
2122
+ if (!provingKey || !verifyingKey) {
2123
+ try {
2124
+ [provingKey, verifyingKey] = await this.keyProvider.functionKeys(keySearchParams);
2125
+ }
2126
+ catch (e) {
2127
+ console.log(`Function keys not found. Key finder response: '${e}'. The function keys will be synthesized`);
2128
+ }
2129
+ }
2130
+ // Resolve the program imports if they exist
2131
+ const numberOfImports = Program.fromString(program).getImports().length;
2132
+ if (numberOfImports > 0 && !imports) {
2133
+ try {
2134
+ imports = await this.networkClient.getProgramImports(programName);
2135
+ }
2136
+ catch (e) {
2137
+ throw logAndThrow(`Error finding program imports. Network response: '${e}'. Please ensure you're connected to a valid Aleo network and the program is deployed to the network.`);
2138
+ }
2139
+ }
2140
+ // Build an execution transaction and submit it to the network
2141
+ return await ProgramManager$1.buildExecutionTransaction(executionPrivateKey, program, functionName, inputs, fee, feeRecord, this.host, imports, provingKey, verifyingKey, feeProvingKey, feeVerifyingKey, offlineQuery);
2142
+ }
2143
+ /**
2144
+ * Builds an execution transaction for submission to the Aleo network.
2145
+ *
2146
+ * @param {ExecuteOptions} options - The options for the execution transaction.
2147
+ * @returns {Promise<Transaction | Error>} - A promise that resolves to the transaction or an error.
2148
+ *
2149
+ * @example
2150
+ * // Create a new NetworkClient, KeyProvider, and RecordProvider using official Aleo record, key, and network providers
2151
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
2152
+ * const keyProvider = new AleoKeyProvider();
2153
+ * keyProvider.useCache = true;
2154
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
2155
+ *
2156
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions
2157
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
2158
+ *
2159
+ * // Build and execute the transaction
2160
+ * const transaction = await programManager.execute({
2161
+ * programName: "hello_hello.aleo",
2162
+ * functionName: "hello_hello",
2163
+ * fee: 0.020,
2164
+ * privateFee: false,
2165
+ * inputs: ["5u32", "5u32"],
2166
+ * keySearchParams: { "cacheKey": "hello_hello:hello" }
2167
+ * });
2168
+ * const result = await programManager.networkClient.submitTransaction(transaction);
2169
+ */
2170
+ async execute(options) {
2171
+ const tx = await this.buildExecutionTransaction(options);
2172
+ return await this.networkClient.submitTransaction(tx);
2173
+ }
2174
+ /**
2175
+ * Run an Aleo program in offline mode
2176
+ *
2177
+ * @param {string} program Program source code containing the function to be executed
2178
+ * @param {string} function_name Function name to execute
2179
+ * @param {string[]} inputs Inputs to the function
2180
+ * @param {number} proveExecution Whether to prove the execution of the function and return an execution transcript
2181
+ * that contains the proof.
2182
+ * @param {string[] | undefined} imports Optional imports to the program
2183
+ * @param {KeySearchParams | undefined} keySearchParams Optional parameters for finding the matching proving &
2184
+ * verifying keys for the function
2185
+ * @param {ProvingKey | undefined} provingKey Optional proving key to use for the transaction
2186
+ * @param {VerifyingKey | undefined} verifyingKey Optional verifying key to use for the transaction
2187
+ * @param {PrivateKey | undefined} privateKey Optional private key to use for the transaction
2188
+ * @param {OfflineQuery | undefined} offlineQuery Optional offline query if creating transactions in an offline environment
2189
+ * @returns {Promise<string | Error>}
2190
+ *
2191
+ * @example
2192
+ * import { Account, Program } from '@provablehq/sdk';
2193
+ *
2194
+ * /// Create the source for the "helloworld" program
2195
+ * const program = "program helloworld.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n";
2196
+ * const programManager = new ProgramManager();
2197
+ *
2198
+ * /// Create a temporary account for the execution of the program
2199
+ * const account = new Account();
2200
+ * programManager.setAccount(account);
2201
+ *
2202
+ * /// Get the response and ensure that the program executed correctly
2203
+ * const executionResponse = await programManager.executeOffline(program, "hello", ["5u32", "5u32"]);
2204
+ * const result = executionResponse.getOutputs();
2205
+ * assert(result === ["10u32"]);
2206
+ */
2207
+ async run(program, function_name, inputs, proveExecution, imports, keySearchParams, provingKey, verifyingKey, privateKey, offlineQuery) {
2208
+ // Get the private key from the account if it is not provided in the parameters
2209
+ let executionPrivateKey = privateKey;
2210
+ if (typeof privateKey === "undefined" && typeof this.account !== "undefined") {
2211
+ executionPrivateKey = this.account.privateKey();
2212
+ }
2213
+ if (typeof executionPrivateKey === "undefined") {
2214
+ throw ("No private key provided and no private key set in the ProgramManager");
2215
+ }
2216
+ // If the function proving and verifying keys are not provided, attempt to find them using the key provider
2217
+ if (!provingKey || !verifyingKey) {
2218
+ try {
2219
+ [provingKey, verifyingKey] = await this.keyProvider.functionKeys(keySearchParams);
2220
+ }
2221
+ catch (e) {
2222
+ console.log(`Function keys not found. Key finder response: '${e}'. The function keys will be synthesized`);
2223
+ }
2224
+ }
2225
+ // Run the program offline and return the result
2226
+ console.log("Running program offline");
2227
+ console.log("Proving key: ", provingKey);
2228
+ console.log("Verifying key: ", verifyingKey);
2229
+ return ProgramManager$1.executeFunctionOffline(executionPrivateKey, program, function_name, inputs, proveExecution, false, imports, provingKey, verifyingKey, this.host, offlineQuery);
2230
+ }
2231
+ /**
2232
+ * Join two credits records into a single credits record
2233
+ *
2234
+ * @param {RecordPlaintext | string} recordOne First credits record to join
2235
+ * @param {RecordPlaintext | string} recordTwo Second credits record to join
2236
+ * @param {number} fee Fee in credits pay for the join transaction
2237
+ * @param {boolean} privateFee Use a private record to pay the fee. If false this will use the account's public credit balance
2238
+ * @param {RecordSearchParams | undefined} recordSearchParams Optional parameters for finding the fee record to use
2239
+ * to pay the fee for the join transaction
2240
+ * @param {RecordPlaintext | string | undefined} feeRecord Fee record to use for the join transaction
2241
+ * @param {PrivateKey | undefined} privateKey Private key to use for the join transaction
2242
+ * @param {OfflineQuery | undefined} offlineQuery Optional offline query if creating transactions in an offline environment
2243
+ * @returns {Promise<string | Error>}
2244
+ */
2245
+ async join(recordOne, recordTwo, fee, privateFee, recordSearchParams, feeRecord, privateKey, offlineQuery) {
2246
+ // Get the private key from the account if it is not provided in the parameters
2247
+ let executionPrivateKey = privateKey;
2248
+ if (typeof privateKey === "undefined" && typeof this.account !== "undefined") {
2249
+ executionPrivateKey = this.account.privateKey();
2250
+ }
2251
+ if (typeof executionPrivateKey === "undefined") {
2252
+ throw ("No private key provided and no private key set in the ProgramManager");
2253
+ }
2254
+ // Get the proving and verifying keys from the key provider
2255
+ let feeKeys;
2256
+ let joinKeys;
2257
+ try {
2258
+ feeKeys = privateFee ? await this.keyProvider.feePrivateKeys() : await this.keyProvider.feePublicKeys();
2259
+ joinKeys = await this.keyProvider.joinKeys();
2260
+ }
2261
+ catch (e) {
2262
+ throw logAndThrow(`Error finding fee keys. Key finder response: '${e}'. Please ensure your key provider is configured correctly.`);
2263
+ }
2264
+ const [feeProvingKey, feeVerifyingKey] = feeKeys;
2265
+ const [joinProvingKey, joinVerifyingKey] = joinKeys;
2266
+ // Get the fee record from the account if it is not provided in the parameters
2267
+ try {
2268
+ feeRecord = privateFee ? await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams) : undefined;
2269
+ }
2270
+ catch (e) {
2271
+ throw logAndThrow(`Error finding fee record. Record finder response: '${e}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
2272
+ }
2273
+ // Validate the records provided are valid plaintext records
2274
+ try {
2275
+ recordOne = recordOne instanceof RecordPlaintext ? recordOne : RecordPlaintext.fromString(recordOne);
2276
+ recordTwo = recordTwo instanceof RecordPlaintext ? recordTwo : RecordPlaintext.fromString(recordTwo);
2277
+ }
2278
+ catch (e) {
2279
+ throw logAndThrow('Records provided are not valid. Please ensure they are valid plaintext records.');
2280
+ }
2281
+ // Build an execution transaction and submit it to the network
2282
+ const tx = await ProgramManager$1.buildJoinTransaction(executionPrivateKey, recordOne, recordTwo, fee, feeRecord, this.host, joinProvingKey, joinVerifyingKey, feeProvingKey, feeVerifyingKey, offlineQuery);
2283
+ return await this.networkClient.submitTransaction(tx);
2284
+ }
2285
+ /**
2286
+ * Split credits into two new credits records
2287
+ *
2288
+ * @param {number} splitAmount Amount in microcredits to split from the original credits record
2289
+ * @param {RecordPlaintext | string} amountRecord Amount record to use for the split transaction
2290
+ * @param {PrivateKey | undefined} privateKey Optional private key to use for the split transaction
2291
+ * @param {OfflineQuery | undefined} offlineQuery Optional offline query if creating transactions in an offline environment
2292
+ * @returns {Promise<string | Error>}
2293
+ *
2294
+ * @example
2295
+ * // Create a new NetworkClient, KeyProvider, and RecordProvider
2296
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
2297
+ * const keyProvider = new AleoKeyProvider();
2298
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
2299
+ *
2300
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions
2301
+ * const programName = "hello_hello.aleo";
2302
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
2303
+ * const record = "{ owner: aleo184vuwr5u7u0ha5f5k44067dd2uaqewxx6pe5ltha5pv99wvhfqxqv339h4.private, microcredits: 45000000u64.private, _nonce: 4106205762862305308495708971985748592380064201230396559307556388725936304984group.public}"
2304
+ * const tx_id = await programManager.split(25000000, record);
2305
+ * const transaction = await programManager.networkClient.getTransaction(tx_id);
2306
+ */
2307
+ async split(splitAmount, amountRecord, privateKey, offlineQuery) {
2308
+ // Get the private key from the account if it is not provided in the parameters
2309
+ let executionPrivateKey = privateKey;
2310
+ if (typeof executionPrivateKey === "undefined" && typeof this.account !== "undefined") {
2311
+ executionPrivateKey = this.account.privateKey();
2312
+ }
2313
+ if (typeof executionPrivateKey === "undefined") {
2314
+ throw ("No private key provided and no private key set in the ProgramManager");
2315
+ }
2316
+ // Get the split keys from the key provider
2317
+ let splitKeys;
2318
+ try {
2319
+ splitKeys = await this.keyProvider.splitKeys();
2320
+ }
2321
+ catch (e) {
2322
+ throw logAndThrow(`Error finding fee keys. Key finder response: '${e}'. Please ensure your key provider is configured correctly.`);
2323
+ }
2324
+ const [splitProvingKey, splitVerifyingKey] = splitKeys;
2325
+ // Validate the record to be split
2326
+ try {
2327
+ amountRecord = amountRecord instanceof RecordPlaintext ? amountRecord : RecordPlaintext.fromString(amountRecord);
2328
+ }
2329
+ catch (e) {
2330
+ throw logAndThrow("Record provided is not valid. Please ensure it is a valid plaintext record.");
2331
+ }
2332
+ // Build an execution transaction and submit it to the network
2333
+ const tx = await ProgramManager$1.buildSplitTransaction(executionPrivateKey, splitAmount, amountRecord, this.host, splitProvingKey, splitVerifyingKey, offlineQuery);
2334
+ return await this.networkClient.submitTransaction(tx);
2335
+ }
2336
+ /**
2337
+ * Pre-synthesize proving and verifying keys for a program
2338
+ *
2339
+ * @param program {string} The program source code to synthesize keys for
2340
+ * @param function_id {string} The function id to synthesize keys for
2341
+ * @param inputs {Array<string>} Sample inputs to the function
2342
+ * @param privateKey {PrivateKey | undefined} Optional private key to use for the key synthesis
2343
+ *
2344
+ * @returns {Promise<FunctionKeyPair | Error>}
2345
+ */
2346
+ async synthesizeKeys(program, function_id, inputs, privateKey) {
2347
+ // Resolve the program imports if they exist
2348
+ let imports;
2349
+ let executionPrivateKey = privateKey;
2350
+ if (typeof executionPrivateKey === "undefined") {
2351
+ if (typeof this.account !== "undefined") {
2352
+ executionPrivateKey = this.account.privateKey();
2353
+ }
2354
+ else {
2355
+ executionPrivateKey = new PrivateKey();
2356
+ }
2357
+ }
2358
+ // Attempt to run an offline execution of the program and extract the proving and verifying keys
2359
+ try {
2360
+ imports = await this.networkClient.getProgramImports(program);
2361
+ const keyPair = await ProgramManager$1.synthesizeKeyPair(executionPrivateKey, program, function_id, inputs, imports);
2362
+ return [keyPair.provingKey(), keyPair.verifyingKey()];
2363
+ }
2364
+ catch (e) {
2365
+ throw logAndThrow(`Could not synthesize keys - error ${e}. Please ensure the program is valid and the inputs are correct.`);
2366
+ }
2367
+ }
2368
+ /**
2369
+ * Build a transaction to transfer credits to another account for later submission to the Aleo network
2370
+ *
2371
+ * @param {number} amount The amount of credits to transfer
2372
+ * @param {string} recipient The recipient of the transfer
2373
+ * @param {string} transferType The type of transfer to perform - options: 'private', 'privateToPublic', 'public', 'publicToPrivate'
2374
+ * @param {number} fee The fee to pay for the transfer
2375
+ * @param {boolean} privateFee Use a private record to pay the fee. If false this will use the account's public credit balance
2376
+ * @param {string | undefined} caller The caller of the function (if calling transfer_public)
2377
+ * @param {RecordSearchParams | undefined} recordSearchParams Optional parameters for finding the amount and fee
2378
+ * records for the transfer transaction
2379
+ * @param {RecordPlaintext | string} amountRecord Optional amount record to use for the transfer
2380
+ * @param {RecordPlaintext | string} feeRecord Optional fee record to use for the transfer
2381
+ * @param {PrivateKey | undefined} privateKey Optional private key to use for the transfer transaction
2382
+ * @param {OfflineQuery | undefined} offlineQuery Optional offline query if creating transactions in an offline environment
2383
+ * @returns {Promise<string | Error>} The transaction id of the transfer transaction
2384
+ *
2385
+ * @example
2386
+ * // Create a new NetworkClient, KeyProvider, and RecordProvider
2387
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
2388
+ * const keyProvider = new AleoKeyProvider();
2389
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
2390
+ *
2391
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions
2392
+ * const programName = "hello_hello.aleo";
2393
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
2394
+ * await programManager.initialize();
2395
+ * const tx_id = await programManager.transfer(1, "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "private", 0.2)
2396
+ * const transaction = await programManager.networkClient.getTransaction(tx_id);
2397
+ */
2398
+ async buildTransferTransaction(amount, recipient, transferType, fee, privateFee, caller, recordSearchParams, amountRecord, feeRecord, privateKey, offlineQuery) {
2399
+ // Validate the transfer type
2400
+ transferType = validateTransferType(transferType);
2401
+ // Get the private key from the account if it is not provided in the parameters
2402
+ let executionPrivateKey = privateKey;
2403
+ if (typeof executionPrivateKey === "undefined" && typeof this.account !== "undefined") {
2404
+ executionPrivateKey = this.account.privateKey();
2405
+ }
2406
+ if (typeof executionPrivateKey === "undefined") {
2407
+ throw ("No private key provided and no private key set in the ProgramManager");
2408
+ }
2409
+ // Get the proving and verifying keys from the key provider
2410
+ let feeKeys;
2411
+ let transferKeys;
2412
+ try {
2413
+ feeKeys = privateFee ? await this.keyProvider.feePrivateKeys() : await this.keyProvider.feePublicKeys();
2414
+ transferKeys = await this.keyProvider.transferKeys(transferType);
2415
+ }
2416
+ catch (e) {
2417
+ throw logAndThrow(`Error finding fee keys. Key finder response: '${e}'. Please ensure your key provider is configured correctly.`);
2418
+ }
2419
+ const [feeProvingKey, feeVerifyingKey] = feeKeys;
2420
+ const [transferProvingKey, transferVerifyingKey] = transferKeys;
2421
+ // Get the amount and fee record from the account if it is not provided in the parameters
2422
+ try {
2423
+ // Track the nonces of the records found so no duplicate records are used
2424
+ const nonces = [];
2425
+ if (requiresAmountRecord(transferType)) {
2426
+ // If the transfer type is private and requires an amount record, get it from the record provider
2427
+ amountRecord = await this.getCreditsRecord(fee, [], amountRecord, recordSearchParams);
2428
+ nonces.push(amountRecord.nonce());
2429
+ }
2430
+ else {
2431
+ amountRecord = undefined;
2432
+ }
2433
+ feeRecord = privateFee ? await this.getCreditsRecord(fee, nonces, feeRecord, recordSearchParams) : undefined;
2434
+ }
2435
+ catch (e) {
2436
+ throw logAndThrow(`Error finding fee record. Record finder response: '${e}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
2437
+ }
2438
+ // Build an execution transaction and submit it to the network
2439
+ return await ProgramManager$1.buildTransferTransaction(executionPrivateKey, amount, recipient, transferType, caller, amountRecord, fee, feeRecord, this.host, transferProvingKey, transferVerifyingKey, feeProvingKey, feeVerifyingKey, offlineQuery);
2440
+ }
2441
+ /**
2442
+ * Build a transfer_public transaction to transfer credits to another account for later submission to the Aleo network
2443
+ *
2444
+ * @param {number} amount The amount of credits to transfer
2445
+ * @param {string} caller The caller of the transfer (may be different from the signer)
2446
+ * @param {string} recipient The recipient of the transfer
2447
+ * @param {string} transferType The type of transfer to perform - options: 'private', 'privateToPublic', 'public', 'publicToPrivate'
2448
+ * @param {number} fee The fee to pay for the transfer
2449
+ * @param {boolean} privateFee Use a private record to pay the fee. If false this will use the account's public credit balance
2450
+ * @param {RecordSearchParams | undefined} recordSearchParams Optional parameters for finding the amount and fee
2451
+ * records for the transfer transaction
2452
+ * @param {RecordPlaintext | string} amountRecord Optional amount record to use for the transfer
2453
+ * @param {RecordPlaintext | string} feeRecord Optional fee record to use for the transfer
2454
+ * @param {PrivateKey | undefined} privateKey Optional private key to use for the transfer transaction
2455
+ * @param {OfflineQuery | undefined} offlineQuery Optional offline query if creating transactions in an offline environment
2456
+ * @returns {Promise<string | Error>} The transaction id of the transfer transaction
2457
+ */
2458
+ async buildTransferPublicTransaction(amount, caller, recipient, fee, privateKey, offlineQuery) {
2459
+ return this.buildTransferTransaction(amount, recipient, "public", fee, false, caller, undefined, undefined, undefined, privateKey, offlineQuery);
2460
+ }
2461
+ /**
2462
+ * Build a transfer_public_as_signer transaction to transfer credits to another account for later submission to the Aleo network
2463
+ *
2464
+ * @param {number} amount The amount of credits to transfer
2465
+ * @param {string} recipient The recipient of the transfer
2466
+ * @param {string} transferType The type of transfer to perform - options: 'private', 'privateToPublic', 'public', 'publicToPrivate'
2467
+ * @param {number} fee The fee to pay for the transfer
2468
+ * @param {boolean} privateFee Use a private record to pay the fee. If false this will use the account's public credit balance
2469
+ * @param {RecordSearchParams | undefined} recordSearchParams Optional parameters for finding the amount and fee
2470
+ * records for the transfer transaction
2471
+ * @param {RecordPlaintext | string} amountRecord Optional amount record to use for the transfer
2472
+ * @param {RecordPlaintext | string} feeRecord Optional fee record to use for the transfer
2473
+ * @param {PrivateKey | undefined} privateKey Optional private key to use for the transfer transaction
2474
+ * @param {OfflineQuery | undefined} offlineQuery Optional offline query if creating transactions in an offline environment
2475
+ * @returns {Promise<string | Error>} The transaction id of the transfer transaction
2476
+ */
2477
+ async buildTransferPublicAsSignerTransaction(amount, recipient, fee, privateKey, offlineQuery) {
2478
+ return this.buildTransferTransaction(amount, recipient, "public", fee, false, undefined, undefined, undefined, undefined, privateKey, offlineQuery);
2479
+ }
2480
+ /**
2481
+ * Transfer credits to another account
2482
+ *
2483
+ * @param {number} amount The amount of credits to transfer
2484
+ * @param {string} recipient The recipient of the transfer
2485
+ * @param {string} transferType The type of transfer to perform - options: 'private', 'privateToPublic', 'public', 'publicToPrivate'
2486
+ * @param {number} fee The fee to pay for the transfer
2487
+ * @param {boolean} privateFee Use a private record to pay the fee. If false this will use the account's public credit balance
2488
+ * @param {string | undefined} caller The caller of the function (if calling transfer_public)
2489
+ * @param {RecordSearchParams | undefined} recordSearchParams Optional parameters for finding the amount and fee
2490
+ * records for the transfer transaction
2491
+ * @param {RecordPlaintext | string} amountRecord Optional amount record to use for the transfer
2492
+ * @param {RecordPlaintext | string} feeRecord Optional fee record to use for the transfer
2493
+ * @param {PrivateKey | undefined} privateKey Optional private key to use for the transfer transaction
2494
+ * @param {OfflineQuery | undefined} offlineQuery Optional offline query if creating transactions in an offline environment
2495
+ * @returns {Promise<string | Error>} The transaction id of the transfer transaction
2496
+ *
2497
+ * @example
2498
+ * // Create a new NetworkClient, KeyProvider, and RecordProvider
2499
+ * const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
2500
+ * const keyProvider = new AleoKeyProvider();
2501
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
2502
+ *
2503
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions
2504
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
2505
+ * await programManager.initialize();
2506
+ * const tx_id = await programManager.transfer(1, "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "private", 0.2)
2507
+ * const transaction = await programManager.networkClient.getTransaction(tx_id);
2508
+ */
2509
+ async transfer(amount, recipient, transferType, fee, privateFee, caller, recordSearchParams, amountRecord, feeRecord, privateKey, offlineQuery) {
2510
+ const tx = await this.buildTransferTransaction(amount, recipient, transferType, fee, privateFee, caller, recordSearchParams, amountRecord, feeRecord, privateKey, offlineQuery);
2511
+ return await this.networkClient.submitTransaction(tx);
2512
+ }
2513
+ /**
2514
+ * Build transaction to bond credits to a validator for later submission to the Aleo Network
2515
+ *
2516
+ * @example
2517
+ * // Create a keyProvider to handle key management
2518
+ * const keyProvider = new AleoKeyProvider();
2519
+ * keyProvider.useCache = true;
2520
+ *
2521
+ * // Create a new ProgramManager with the key that will be used to bond credits
2522
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2523
+ * programManager.setAccount(new Account("YourPrivateKey"));
2524
+ *
2525
+ * // Create the bonding transaction object for later submission
2526
+ * const tx = await programManager.buildBondPublicTransaction("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j", "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "aleo1feya8sjy9k2zflvl2dx39pdsq5tju28elnp2ektnn588uu9ghv8s84msv9", 2000000);
2527
+ * console.log(tx);
2528
+ *
2529
+ * // The transaction can be later submitted to the network using the network client.
2530
+ * const result = await programManager.networkClient.submitTransaction(tx);
2531
+ *
2532
+ * @returns string
2533
+ * @param {string} staker_address Address of the staker who is bonding the credits
2534
+ * @param {string} validator_address Address of the validator to bond to, if this address is the same as the staker (i.e. the
2535
+ * executor of this function), it will attempt to bond the credits as a validator. Bonding as a validator currently
2536
+ * requires a minimum of 10,000,000 credits to bond (subject to change). If the address is specified is an existing
2537
+ * validator and is different from the address of the executor of this function, it will bond the credits to that
2538
+ * validator's staking committee as a delegator. A minimum of 10 credits is required to bond as a delegator.
2539
+ * @param {string} withdrawal_address Address to withdraw the staked credits to when unbond_public is called.
2540
+ * @param {number} amount The amount of credits to bond
2541
+ * @param {Partial<ExecuteOptions>} options - Override default execution options.
2542
+ */
2543
+ async buildBondPublicTransaction(staker_address, validator_address, withdrawal_address, amount, options = {}) {
2544
+ const scaledAmount = Math.trunc(amount * 1000000);
2545
+ const { programName = "credits.aleo", functionName = "bond_public", fee = options.fee || 0.86, privateFee = false, inputs = [staker_address, validator_address, withdrawal_address, `${scaledAmount.toString()}u64`], keySearchParams = new AleoKeyProviderParams({
2546
+ proverUri: CREDITS_PROGRAM_KEYS.bond_public.prover,
2547
+ verifierUri: CREDITS_PROGRAM_KEYS.bond_public.verifier,
2548
+ cacheKey: "credits.aleo/bond_public"
2549
+ }), program = this.creditsProgram(), ...additionalOptions } = options;
2550
+ const executeOptions = {
2551
+ programName,
2552
+ functionName,
2553
+ fee,
2554
+ privateFee,
2555
+ inputs,
2556
+ keySearchParams,
2557
+ ...additionalOptions
2558
+ };
2559
+ return await this.buildExecutionTransaction(executeOptions);
2560
+ }
2561
+ /**
2562
+ * Bond credits to validator.
2563
+ *
2564
+ * @example
2565
+ * // Create a keyProvider to handle key management
2566
+ * const keyProvider = new AleoKeyProvider();
2567
+ * keyProvider.useCache = true;
2568
+ *
2569
+ * // Create a new ProgramManager with the key that will be used to bond credits
2570
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2571
+ * programManager.setAccount(new Account("YourPrivateKey"));
2572
+ *
2573
+ * // Create the bonding transaction
2574
+ * const tx_id = await programManager.bondPublic("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j", "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "aleo1feya8sjy9k2zflvl2dx39pdsq5tju28elnp2ektnn588uu9ghv8s84msv9", 2000000);
2575
+ *
2576
+ * @returns string
2577
+ * @param {string} staker_address Address of the staker who is bonding the credits
2578
+ * @param {string} validator_address Address of the validator to bond to, if this address is the same as the signer (i.e. the
2579
+ * executor of this function), it will attempt to bond the credits as a validator. Bonding as a validator currently
2580
+ * requires a minimum of 1,000,000 credits to bond (subject to change). If the address is specified is an existing
2581
+ * validator and is different from the address of the executor of this function, it will bond the credits to that
2582
+ * validator's staking committee as a delegator. A minimum of 10 credits is required to bond as a delegator.
2583
+ * @param {string} withdrawal_address Address to withdraw the staked credits to when unbond_public is called.
2584
+ * @param {number} amount The amount of credits to bond
2585
+ * @param {Options} options Options for the execution
2586
+ */
2587
+ async bondPublic(staker_address, validator_address, withdrawal_address, amount, options = {}) {
2588
+ const tx = await this.buildBondPublicTransaction(staker_address, validator_address, withdrawal_address, amount, options);
2589
+ return await this.networkClient.submitTransaction(tx);
2590
+ }
2591
+ /**
2592
+ * Build a bond_validator transaction for later submission to the Aleo Network.
2593
+ *
2594
+ * @example
2595
+ * // Create a keyProvider to handle key management
2596
+ * const keyProvider = new AleoKeyProvider();
2597
+ * keyProvider.useCache = true;
2598
+ *
2599
+ * // Create a new ProgramManager with the key that will be used to bond credits
2600
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2601
+ * programManager.setAccount(new Account("YourPrivateKey"));
2602
+ *
2603
+ * // Create the bond validator transaction object for later use.
2604
+ * const tx = await programManager.buildBondValidatorTransaction("aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "aleo1feya8sjy9k2zflvl2dx39pdsq5tju28elnp2ektnn588uu9ghv8s84msv9", 2000000);
2605
+ * console.log(tx);
2606
+ *
2607
+ * // The transaction can later be submitted to the network using the network client.
2608
+ * const tx_id = await programManager.networkClient.submitTransaction(tx);
2609
+ *
2610
+ * @returns string
2611
+ * @param {string} validator_address Address of the validator to bond to, if this address is the same as the staker (i.e. the
2612
+ * executor of this function), it will attempt to bond the credits as a validator. Bonding as a validator currently
2613
+ * requires a minimum of 10,000,000 credits to bond (subject to change). If the address is specified is an existing
2614
+ * validator and is different from the address of the executor of this function, it will bond the credits to that
2615
+ * validator's staking committee as a delegator. A minimum of 10 credits is required to bond as a delegator.
2616
+ * @param {string} withdrawal_address Address to withdraw the staked credits to when unbond_public is called.
2617
+ * @param {number} amount The amount of credits to bond
2618
+ * @param {number} commission The commission rate for the validator (must be between 0 and 100 - an error will be thrown if it is not)
2619
+ * @param {Partial<ExecuteOptions>} options - Override default execution options.
2620
+ */
2621
+ async buildBondValidatorTransaction(validator_address, withdrawal_address, amount, commission, options = {}) {
2622
+ const scaledAmount = Math.trunc(amount * 1000000);
2623
+ const adjustedCommission = Math.trunc(commission);
2624
+ const { programName = "credits.aleo", functionName = "bond_validator", fee = options.fee || 0.86, privateFee = false, inputs = [validator_address, withdrawal_address, `${scaledAmount.toString()}u64`, `${adjustedCommission.toString()}u8`], keySearchParams = new AleoKeyProviderParams({
2625
+ proverUri: CREDITS_PROGRAM_KEYS.bond_validator.prover,
2626
+ verifierUri: CREDITS_PROGRAM_KEYS.bond_validator.verifier,
2627
+ cacheKey: "credits.aleo/bond_validator"
2628
+ }), program = this.creditsProgram(), ...additionalOptions } = options;
2629
+ const executeOptions = {
2630
+ programName,
2631
+ functionName,
2632
+ fee,
2633
+ privateFee,
2634
+ inputs,
2635
+ keySearchParams,
2636
+ ...additionalOptions
2637
+ };
2638
+ return await this.buildExecutionTransaction(executeOptions);
2639
+ }
2640
+ /**
2641
+ * Build transaction to bond a validator.
2642
+ *
2643
+ * @example
2644
+ * // Create a keyProvider to handle key management
2645
+ * const keyProvider = new AleoKeyProvider();
2646
+ * keyProvider.useCache = true;
2647
+ *
2648
+ * // Create a new ProgramManager with the key that will be used to bond credits
2649
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2650
+ * programManager.setAccount(new Account("YourPrivateKey"));
2651
+ *
2652
+ * // Create the bonding transaction
2653
+ * const tx_id = await programManager.bondValidator("aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px", "aleo1feya8sjy9k2zflvl2dx39pdsq5tju28elnp2ektnn588uu9ghv8s84msv9", 2000000);
2654
+ *
2655
+ * @returns string
2656
+ * @param {string} validator_address Address of the validator to bond to, if this address is the same as the staker (i.e. the
2657
+ * executor of this function), it will attempt to bond the credits as a validator. Bonding as a validator currently
2658
+ * requires a minimum of 10,000,000 credits to bond (subject to change). If the address is specified is an existing
2659
+ * validator and is different from the address of the executor of this function, it will bond the credits to that
2660
+ * validator's staking committee as a delegator. A minimum of 10 credits is required to bond as a delegator.
2661
+ * @param {string} withdrawal_address Address to withdraw the staked credits to when unbond_public is called.
2662
+ * @param {number} amount The amount of credits to bond
2663
+ * @param {number} commission The commission rate for the validator (must be between 0 and 100 - an error will be thrown if it is not)
2664
+ * @param {Partial<ExecuteOptions>} options - Override default execution options.
2665
+ */
2666
+ async bondValidator(validator_address, withdrawal_address, amount, commission, options = {}) {
2667
+ const tx = await this.buildBondValidatorTransaction(validator_address, withdrawal_address, amount, commission, options);
2668
+ return await this.networkClient.submitTransaction(tx);
2669
+ }
2670
+ /**
2671
+ * Build a transaction to unbond public credits from a validator in the Aleo network.
2672
+ *
2673
+ * @param {string} staker_address - The address of the staker who is unbonding the credits.
2674
+ * @param {number} amount - The amount of credits to unbond (scaled by 1,000,000).
2675
+ * @param {Partial<ExecuteOptions>} options - Override default execution options.
2676
+ * @returns {Promise<Transaction | Error>} - A promise that resolves to the transaction or an error message.
2677
+ *
2678
+ * @example
2679
+ * // Create a keyProvider to handle key management.
2680
+ * const keyProvider = new AleoKeyProvider();
2681
+ * keyProvider.useCache = true;
2682
+ *
2683
+ * // Create a new ProgramManager with the key that will be used to unbond credits.
2684
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2685
+ * const tx = await programManager.buildUnbondPublicTransaction("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j", 2000000);
2686
+ * console.log(tx);
2687
+ *
2688
+ * // The transaction can be submitted later to the network using the network client.
2689
+ * programManager.networkClient.submitTransaction(tx);
2690
+ */
2691
+ async buildUnbondPublicTransaction(staker_address, amount, options = {}) {
2692
+ const scaledAmount = Math.trunc(amount * 1000000);
2693
+ const { programName = "credits.aleo", functionName = "unbond_public", fee = options.fee || 1.3, privateFee = false, inputs = [staker_address, `${scaledAmount.toString()}u64`], keySearchParams = new AleoKeyProviderParams({
2694
+ proverUri: CREDITS_PROGRAM_KEYS.unbond_public.prover,
2695
+ verifierUri: CREDITS_PROGRAM_KEYS.unbond_public.verifier,
2696
+ cacheKey: "credits.aleo/unbond_public"
2697
+ }), program = this.creditsProgram(), ...additionalOptions } = options;
2698
+ const executeOptions = {
2699
+ programName,
2700
+ functionName,
2701
+ fee,
2702
+ privateFee,
2703
+ inputs,
2704
+ keySearchParams,
2705
+ ...additionalOptions
2706
+ };
2707
+ return this.buildExecutionTransaction(executeOptions);
2708
+ }
2709
+ /**
2710
+ * Unbond a specified amount of staked credits.
2711
+ *
2712
+ * @example
2713
+ * // Create a keyProvider to handle key management
2714
+ * const keyProvider = new AleoKeyProvider();
2715
+ * keyProvider.useCache = true;
2716
+ *
2717
+ * // Create a new ProgramManager with the key that will be used to bond credits
2718
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2719
+ * programManager.setAccount(new Account("YourPrivateKey"));
2720
+ *
2721
+ * // Create the bonding transaction and send it to the network
2722
+ * const tx_id = await programManager.unbondPublic("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j", 10);
2723
+ *
2724
+ * @returns string
2725
+ * @param {string} staker_address Address of the staker who is unbonding the credits
2726
+ * @param {number} amount Amount of credits to unbond. If the address of the executor of this function is an
2727
+ * existing validator, it will subtract this amount of credits from the validator's staked credits. If there are
2728
+ * less than 1,000,000 credits staked pool after the unbond, the validator will be removed from the validator set.
2729
+ * If the address of the executor of this function is not a validator and has credits bonded as a delegator, it will
2730
+ * subtract this amount of credits from the delegator's staked credits. If there are less than 10 credits bonded
2731
+ * after the unbond operation, the delegator will be removed from the validator's staking pool.
2732
+ * @param {ExecuteOptions} options Options for the execution
2733
+ */
2734
+ async unbondPublic(staker_address, amount, options = {}) {
2735
+ const tx = await this.buildUnbondPublicTransaction(staker_address, amount, options);
2736
+ return await this.networkClient.submitTransaction(tx);
2737
+ }
2738
+ /**
2739
+ * Build a transaction to claim unbonded public credits in the Aleo network.
2740
+ *
2741
+ * @param {string} staker_address - The address of the staker who is claiming the credits.
2742
+ * @param {Partial<ExecuteOptions>} options - Override default execution options.
2743
+ * @returns {Promise<Transaction | Error>} - A promise that resolves to the transaction or an error message.
2744
+ *
2745
+ * @example
2746
+ * // Create a keyProvider to handle key management
2747
+ * const keyProvider = new AleoKeyProvider();
2748
+ * keyProvider.useCache = true;
2749
+ *
2750
+ * // Create a new ProgramManager with the key that will be used to claim unbonded credits.
2751
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2752
+ *
2753
+ * // Create the claim unbonded transaction object for later use.
2754
+ * const tx = await programManager.buildClaimUnbondPublicTransaction("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j");
2755
+ * console.log(tx);
2756
+ *
2757
+ * // The transaction can be submitted later to the network using the network client.
2758
+ * programManager.networkClient.submitTransaction(tx);
2759
+ */
2760
+ async buildClaimUnbondPublicTransaction(staker_address, options = {}) {
2761
+ const { programName = "credits.aleo", functionName = "claim_unbond_public", fee = options.fee || 2, privateFee = false, inputs = [staker_address], keySearchParams = new AleoKeyProviderParams({
2762
+ proverUri: CREDITS_PROGRAM_KEYS.claim_unbond_public.prover,
2763
+ verifierUri: CREDITS_PROGRAM_KEYS.claim_unbond_public.verifier,
2764
+ cacheKey: "credits.aleo/claim_unbond_public"
2765
+ }), program = this.creditsProgram(), ...additionalOptions } = options;
2766
+ const executeOptions = {
2767
+ programName,
2768
+ functionName,
2769
+ fee,
2770
+ privateFee,
2771
+ inputs,
2772
+ keySearchParams,
2773
+ ...additionalOptions
2774
+ };
2775
+ return await this.buildExecutionTransaction(executeOptions);
2776
+ }
2777
+ /**
2778
+ * Claim unbonded credits. If credits have been unbonded by the account executing this function, this method will
2779
+ * claim them and add them to the public balance of the account.
2780
+ *
2781
+ * @example
2782
+ * // Create a keyProvider to handle key management
2783
+ * const keyProvider = new AleoKeyProvider();
2784
+ * keyProvider.useCache = true;
2785
+ *
2786
+ * // Create a new ProgramManager with the key that will be used to bond credits
2787
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2788
+ * programManager.setAccount(new Account("YourPrivateKey"));
2789
+ *
2790
+ * // Create the bonding transaction
2791
+ * const tx_id = await programManager.claimUnbondPublic("aleo1jx8s4dvjepculny4wfrzwyhs3tlyv65r58ns3g6q2gm2esh7ps8sqy9s5j");
2792
+ *
2793
+ * @param {string} staker_address Address of the staker who is claiming the credits
2794
+ * @param {ExecuteOptions} options
2795
+ * @returns string
2796
+ */
2797
+ async claimUnbondPublic(staker_address, options = {}) {
2798
+ const tx = await this.buildClaimUnbondPublicTransaction(staker_address, options);
2799
+ return await this.networkClient.submitTransaction(tx);
2800
+ }
2801
+ /**
2802
+ * Build a set_validator_state transaction for later usage.
2803
+ *
2804
+ * This function allows a validator to set their state to be either opened or closed to new stakers.
2805
+ * When the validator is open to new stakers, any staker (including the validator) can bond or unbond from the validator.
2806
+ * When the validator is closed to new stakers, existing stakers can still bond or unbond from the validator, but new stakers cannot bond.
2807
+ *
2808
+ * This function serves two primary purposes:
2809
+ * 1. Allow a validator to leave the committee, by closing themselves to stakers and then unbonding all of their stakers.
2810
+ * 2. Allow a validator to maintain their % of stake, by closing themselves to allowing more stakers to bond to them.
2811
+ *
2812
+ * @example
2813
+ * // Create a keyProvider to handle key management
2814
+ * const keyProvider = new AleoKeyProvider();
2815
+ * keyProvider.useCache = true;
2816
+ *
2817
+ * // Create a new ProgramManager with the key that will be used to bond credits
2818
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2819
+ * programManager.setAccount(new Account("ValidatorPrivateKey"));
2820
+ *
2821
+ * // Create the bonding transaction
2822
+ * const tx = await programManager.buildSetValidatorStateTransaction(true);
2823
+ *
2824
+ * // The transaction can be submitted later to the network using the network client.
2825
+ * programManager.networkClient.submitTransaction(tx);
2826
+ *
2827
+ * @returns string
2828
+ * @param {boolean} validator_state
2829
+ * @param {Partial<ExecuteOptions>} options - Override default execution options
2830
+ */
2831
+ async buildSetValidatorStateTransaction(validator_state, options = {}) {
2832
+ const { programName = "credits.aleo", functionName = "set_validator_state", fee = 1, privateFee = false, inputs = [validator_state.toString()], keySearchParams = new AleoKeyProviderParams({
2833
+ proverUri: CREDITS_PROGRAM_KEYS.set_validator_state.prover,
2834
+ verifierUri: CREDITS_PROGRAM_KEYS.set_validator_state.verifier,
2835
+ cacheKey: "credits.aleo/set_validator_state"
2836
+ }), ...additionalOptions } = options;
2837
+ const executeOptions = {
2838
+ programName,
2839
+ functionName,
2840
+ fee,
2841
+ privateFee,
2842
+ inputs,
2843
+ keySearchParams,
2844
+ ...additionalOptions
2845
+ };
2846
+ return await this.execute(executeOptions);
2847
+ }
2848
+ /**
2849
+ * Submit a set_validator_state transaction to the Aleo Network.
2850
+ *
2851
+ * This function allows a validator to set their state to be either opened or closed to new stakers.
2852
+ * When the validator is open to new stakers, any staker (including the validator) can bond or unbond from the validator.
2853
+ * When the validator is closed to new stakers, existing stakers can still bond or unbond from the validator, but new stakers cannot bond.
2854
+ *
2855
+ * This function serves two primary purposes:
2856
+ * 1. Allow a validator to leave the committee, by closing themselves to stakers and then unbonding all of their stakers.
2857
+ * 2. Allow a validator to maintain their % of stake, by closing themselves to allowing more stakers to bond to them.
2858
+ *
2859
+ * @example
2860
+ * // Create a keyProvider to handle key management
2861
+ * const keyProvider = new AleoKeyProvider();
2862
+ * keyProvider.useCache = true;
2863
+ *
2864
+ * // Create a new ProgramManager with the key that will be used to bond credits
2865
+ * const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, undefined);
2866
+ * programManager.setAccount(new Account("ValidatorPrivateKey"));
2867
+ *
2868
+ * // Create the bonding transaction
2869
+ * const tx_id = await programManager.setValidatorState(true);
2870
+ *
2871
+ * @returns string
2872
+ * @param {boolean} validator_state
2873
+ * @param {Partial<ExecuteOptions>} options - Override default execution options
2874
+ */
2875
+ async setValidatorState(validator_state, options = {}) {
2876
+ const tx = await this.buildSetValidatorStateTransaction(validator_state, options);
2877
+ return this.networkClient.submitTransaction(tx);
2878
+ }
2879
+ /**
2880
+ * Verify a proof of execution from an offline execution
2881
+ *
2882
+ * @param {executionResponse} executionResponse
2883
+ * @returns {boolean} True if the proof is valid, false otherwise
2884
+ */
2885
+ verifyExecution(executionResponse) {
2886
+ try {
2887
+ const execution = executionResponse.getExecution();
2888
+ const function_id = executionResponse.getFunctionId();
2889
+ const program = executionResponse.getProgram();
2890
+ const verifyingKey = executionResponse.getVerifyingKey();
2891
+ return verifyFunctionExecution(execution, verifyingKey, program, function_id);
2892
+ }
2893
+ catch (e) {
2894
+ console.warn("The execution was not found in the response, cannot verify the execution");
2895
+ return false;
2896
+ }
2897
+ }
2898
+ /**
2899
+ * Create a program object from a program's source code
2900
+ *
2901
+ * @param {string} program Program source code
2902
+ * @returns {Program | Error} The program object
2903
+ */
2904
+ createProgramFromSource(program) {
2905
+ return Program.fromString(program);
2906
+ }
2907
+ /**
2908
+ * Get the credits program object
2909
+ *
2910
+ * @returns {Program} The credits program object
2911
+ */
2912
+ creditsProgram() {
2913
+ return Program.getCreditsProgram();
2914
+ }
2915
+ /**
2916
+ * Verify a program is valid
2917
+ *
2918
+ * @param {string} program The program source code
2919
+ */
2920
+ verifyProgram(program) {
2921
+ try {
2922
+ Program.fromString(program);
2923
+ return true;
2924
+ }
2925
+ catch (e) {
2926
+ return false;
2927
+ }
2928
+ }
2929
+ // Internal utility function for getting a credits.aleo record
2930
+ async getCreditsRecord(amount, nonces, record, params) {
2931
+ try {
2932
+ return record instanceof RecordPlaintext ? record : RecordPlaintext.fromString(record);
2933
+ }
2934
+ catch (e) {
2935
+ try {
2936
+ const recordProvider = this.recordProvider;
2937
+ return (await recordProvider.findCreditsRecord(amount, true, nonces, params));
2938
+ }
2939
+ catch (e) {
2940
+ throw logAndThrow(`Error finding fee record. Record finder response: '${e}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
2941
+ }
2942
+ }
2943
+ }
2944
+ }
2945
+ // Ensure the transfer type requires an amount record
2946
+ function requiresAmountRecord(transferType) {
2947
+ return PRIVATE_TRANSFER_TYPES.has(transferType);
2948
+ }
2949
+ // Validate the transfer type
2950
+ function validateTransferType(transferType) {
2951
+ return VALID_TRANSFER_TYPES.has(transferType) ? transferType :
2952
+ logAndThrow(`Invalid transfer type '${transferType}'. Valid transfer types are 'private', 'privateToPublic', 'public', and 'publicToPrivate'.`);
2953
+ }
2954
+
2955
+ const KEY_STORE = Metadata.baseUrl();
2956
+ function convert(metadata) {
2957
+ // This looks up the method name in VerifyingKey
2958
+ const verifyingKey = VerifyingKey[metadata.verifyingKey];
2959
+ if (!verifyingKey) {
2960
+ throw new Error("Invalid method name: " + metadata.verifyingKey);
2961
+ }
2962
+ return {
2963
+ locator: metadata.locator,
2964
+ prover: metadata.prover,
2965
+ verifier: metadata.verifier,
2966
+ verifyingKey,
2967
+ };
2968
+ }
2969
+ const CREDITS_PROGRAM_KEYS = {
2970
+ bond_public: convert(Metadata.bond_public()),
2971
+ bond_validator: convert(Metadata.bond_validator()),
2972
+ claim_unbond_public: convert(Metadata.claim_unbond_public()),
2973
+ fee_private: convert(Metadata.fee_private()),
2974
+ fee_public: convert(Metadata.fee_public()),
2975
+ inclusion: convert(Metadata.inclusion()),
2976
+ join: convert(Metadata.join()),
2977
+ set_validator_state: convert(Metadata.set_validator_state()),
2978
+ split: convert(Metadata.split()),
2979
+ transfer_private: convert(Metadata.transfer_private()),
2980
+ transfer_private_to_public: convert(Metadata.transfer_private_to_public()),
2981
+ transfer_public: convert(Metadata.transfer_public()),
2982
+ transfer_public_as_signer: convert(Metadata.transfer_public_as_signer()),
2983
+ transfer_public_to_private: convert(Metadata.transfer_public_to_private()),
2984
+ unbond_public: convert(Metadata.unbond_public()),
2985
+ };
2986
+ const PRIVATE_TRANSFER_TYPES = new Set([
2987
+ "transfer_private",
2988
+ "private",
2989
+ "transferPrivate",
2990
+ "transfer_private_to_public",
2991
+ "privateToPublic",
2992
+ "transferPrivateToPublic",
2993
+ ]);
2994
+ const VALID_TRANSFER_TYPES = new Set([
2995
+ "transfer_private",
2996
+ "private",
2997
+ "transferPrivate",
2998
+ "transfer_private_to_public",
2999
+ "privateToPublic",
3000
+ "transferPrivateToPublic",
3001
+ "transfer_public",
3002
+ "transfer_public_as_signer",
3003
+ "public",
3004
+ "public_as_signer",
3005
+ "transferPublic",
3006
+ "transferPublicAsSigner",
3007
+ "transfer_public_to_private",
3008
+ "publicToPrivate",
3009
+ "publicAsSigner",
3010
+ "transferPublicToPrivate",
3011
+ ]);
3012
+ const PRIVATE_TRANSFER = new Set([
3013
+ "private",
3014
+ "transfer_private",
3015
+ "transferPrivate",
3016
+ ]);
3017
+ const PRIVATE_TO_PUBLIC_TRANSFER = new Set([
3018
+ "private_to_public",
3019
+ "privateToPublic",
3020
+ "transfer_private_to_public",
3021
+ "transferPrivateToPublic",
3022
+ ]);
3023
+ const PUBLIC_TRANSFER = new Set([
3024
+ "public",
3025
+ "transfer_public",
3026
+ "transferPublic",
3027
+ ]);
3028
+ const PUBLIC_TRANSFER_AS_SIGNER = new Set([
3029
+ "public_as_signer",
3030
+ "transfer_public_as_signer",
3031
+ "transferPublicAsSigner",
3032
+ ]);
3033
+ const PUBLIC_TO_PRIVATE_TRANSFER = new Set([
3034
+ "public_to_private",
3035
+ "publicToPrivate",
3036
+ "transfer_public_to_private",
3037
+ "transferPublicToPrivate",
3038
+ ]);
3039
+ function logAndThrow(message) {
3040
+ console.error(message);
3041
+ throw message;
3042
+ }
3043
+ // @TODO: This function is no longer needed, remove it.
3044
+ async function initializeWasm() {
3045
+ console.warn("initializeWasm is deprecated, you no longer need to use it");
3046
+ }
3047
+
3048
+ 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, VALID_TRANSFER_TYPES, createAleoWorker, initializeWasm, logAndThrow };
3049
+ //# sourceMappingURL=index.js.map