@provablehq/sdk 0.9.10 → 0.9.12

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.
@@ -9,6 +9,7 @@ import { EncryptedRecord } from "./models/record-provider/encryptedRecord.js";
9
9
  import { ExecutionJSON, FeeExecutionJSON } from "./models/execution/executionJSON.js";
10
10
  import { ExecutionObject, FeeExecutionObject } from "./models/execution/executionObject.js";
11
11
  import { FinalizeJSON } from "./models/finalizeJSON.js";
12
+ import { FunctionInput } from "./models/functionInput";
12
13
  import { FunctionObject } from "./models/functionObject.js";
13
14
  import { ImportedVerifyingKeys, ImportedPrograms } from "./models/imports.js";
14
15
  import { InputJSON } from "./models/input/inputJSON.js";
@@ -44,4 +45,4 @@ export { logAndThrow } from "./utils.js";
44
45
  export { Address, Authorization, Boolean, BHP256, BHP512, BHP768, BHP1024, Ciphertext, ComputeKey, Execution as FunctionExecution, ExecutionRequest, ExecutionResponse, EncryptionToolkit, Field, GraphKey, Group, I8, I16, I32, I64, I128, OfflineQuery, Pedersen64, Pedersen128, Plaintext, Poseidon2, Poseidon4, Poseidon8, PrivateKey, PrivateKeyCiphertext, Program, ProgramManager as ProgramManagerBase, ProvingKey, ProvingRequest, RecordCiphertext, RecordPlaintext, Signature, Scalar, Transaction, Transition, U8, U16, U32, U64, U128, VerifyingKey, ViewKey, initThreadPool, getOrInitConsensusVersionTestHeights, verifyFunctionExecution, } from "./wasm.js";
45
46
  export { initializeWasm };
46
47
  export { Key, CREDITS_PROGRAM_KEYS, KEY_STORE, PRIVATE_TRANSFER, PRIVATE_TO_PUBLIC_TRANSFER, PRIVATE_TRANSFER_TYPES, PUBLIC_TRANSFER, PUBLIC_TRANSFER_AS_SIGNER, PUBLIC_TO_PRIVATE_TRANSFER, RECORD_DOMAIN, VALID_TRANSFER_TYPES, } from "./constants.js";
47
- export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoKeyProviderInitParams, AleoNetworkClient, BlockJSON, BlockHeightSearch, CachedKeyPair, ConfirmedTransactionJSON, DeploymentJSON, DeploymentObject, EncryptedRecord, ExecutionJSON, ExecutionObject, FeeExecutionJSON, FeeExecutionObject, FinalizeJSON, FunctionObject, FunctionKeyPair, FunctionKeyProvider, Header, ImportedPrograms, ImportedVerifyingKeys, InputJSON, InputObject, KeySearchParams, Metadata, NetworkRecordProvider, OfflineKeyProvider, OfflineSearchParams, OutputJSON, OutputObject, OwnedFilter, OwnedRecord, OwnerJSON, PartialSolutionJSON, PlaintextArray, PlaintextLiteral, PlaintextObject, PlaintextStruct, ProgramImports, ProvingRequestJSON, ProvingResponse, RatificationJSON, RecordsFilter, RecordsResponseFilter, RecordProvider, RecordScanner, RecordSearchParams, SealanceMerkleTree, SolutionJSON, SolutionsJSON, TransactionJSON, TransactionObject, TransitionJSON, TransitionObject, VerifyingKeys, };
48
+ export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoKeyProviderInitParams, AleoNetworkClient, BlockJSON, BlockHeightSearch, CachedKeyPair, ConfirmedTransactionJSON, DeploymentJSON, DeploymentObject, EncryptedRecord, ExecutionJSON, ExecutionObject, FeeExecutionJSON, FeeExecutionObject, FinalizeJSON, FunctionInput, FunctionObject, FunctionKeyPair, FunctionKeyProvider, Header, ImportedPrograms, ImportedVerifyingKeys, InputJSON, InputObject, KeySearchParams, Metadata, NetworkRecordProvider, OfflineKeyProvider, OfflineSearchParams, OutputJSON, OutputObject, OwnedFilter, OwnedRecord, OwnerJSON, PartialSolutionJSON, PlaintextArray, PlaintextLiteral, PlaintextObject, PlaintextStruct, ProgramImports, ProvingRequestJSON, ProvingResponse, RatificationJSON, RecordsFilter, RecordsResponseFilter, RecordProvider, RecordScanner, RecordSearchParams, SealanceMerkleTree, SolutionJSON, SolutionsJSON, TransactionJSON, TransactionObject, TransitionJSON, TransitionObject, VerifyingKeys, };
@@ -425,7 +425,12 @@ async function post(url, options) {
425
425
  options.method = "POST";
426
426
  const response = await fetch(url, options);
427
427
  if (!response.ok) {
428
- throw new Error(response.status + " could not post URL " + url);
428
+ const error = await response.text();
429
+ let message = `${response.status} error received from ${url}`;
430
+ if (error) {
431
+ message = `${error}`;
432
+ }
433
+ throw new Error(message);
429
434
  }
430
435
  return response;
431
436
  }
@@ -492,7 +497,7 @@ class AleoNetworkClient {
492
497
  else {
493
498
  this.headers = {
494
499
  // This is replaced by the actual version by a Rollup plugin
495
- "X-Aleo-SDK-Version": "0.9.10",
500
+ "X-Aleo-SDK-Version": "0.9.12",
496
501
  "X-Aleo-environment": environment(),
497
502
  };
498
503
  }
@@ -1807,7 +1812,7 @@ class AleoNetworkClient {
1807
1812
  }
1808
1813
  }
1809
1814
  catch (error) {
1810
- throw new Error(`Error posting transaction: No response received: ${error.message}`);
1815
+ throw new Error(`Error posting transaction: ${error}`);
1811
1816
  }
1812
1817
  }
1813
1818
  /**
@@ -2301,7 +2306,7 @@ class AleoKeyProvider {
2301
2306
  const verifying_key = key.verifyingKey();
2302
2307
  const proving_key = await this.fetchProvingKey(key.prover, key.locator);
2303
2308
  if (this.cacheOption) {
2304
- this.cache.set(CREDITS_PROGRAM_KEYS.bond_public.locator, [proving_key.toBytes(), verifying_key.toBytes()]);
2309
+ this.cache.set(CREDITS_PROGRAM_KEYS.getKey(key.name).locator, [proving_key.toBytes(), verifying_key.toBytes()]);
2305
2310
  }
2306
2311
  return [proving_key, verifying_key];
2307
2312
  }
@@ -3890,6 +3895,44 @@ class ProgramManager {
3890
3895
  setHeader(headerName, value) {
3891
3896
  this.networkClient.headers[headerName] = value;
3892
3897
  }
3898
+ /**
3899
+ * Set the inclusion prover into the wasm memory. This should be done prior to any execution of a function with a
3900
+ * private record.
3901
+ *
3902
+ * @param {ProvingKey} [provingKey]
3903
+ *
3904
+ * @example
3905
+ * import { ProgramManager, AleoKeyProvider } from "@provablehq/sdk/mainnet.js";
3906
+ *
3907
+ * const keyProvider = new AleoKeyProvider();
3908
+ * keyProvider.useCache(true);
3909
+ *
3910
+ * // Create a ProgramManager
3911
+ * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
3912
+ *
3913
+ * // Set the inclusion keys.
3914
+ * programManager.setInclusionProver();
3915
+ */
3916
+ async setInclusionProver(provingKey) {
3917
+ if (this.inclusionKeysLoaded) {
3918
+ return;
3919
+ }
3920
+ try {
3921
+ if (provingKey) {
3922
+ ProgramManager$1.loadInclusionProver(provingKey);
3923
+ this.inclusionKeysLoaded = true;
3924
+ }
3925
+ else {
3926
+ const inclusionKeys = await this.keyProvider.inclusionKeys();
3927
+ ProgramManager$1.loadInclusionProver(inclusionKeys[0]);
3928
+ this.inclusionKeysLoaded = true;
3929
+ }
3930
+ return;
3931
+ }
3932
+ catch {
3933
+ console.log("Setting the inclusion prover requires either a key provider to be configured for the ProgramManager OR to pass the inclusion prover directly");
3934
+ }
3935
+ }
3893
3936
  /**
3894
3937
  * Remove a header from the `AleoNetworkClient`s header map
3895
3938
  *
@@ -3982,9 +4025,23 @@ class ProgramManager {
3982
4025
  }
3983
4026
  // Get the fee record from the account if it is not provided in the parameters
3984
4027
  try {
3985
- feeRecord = privateFee
3986
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
3987
- : undefined;
4028
+ if (privateFee) {
4029
+ let fee = priorityFee;
4030
+ // If a private fee is specified, but no fee record is provided, estimate the fee and find a matching record.
4031
+ if (!feeRecord) {
4032
+ console.log("Private fee specified, but no private fee record provided, estimating fee and finding a matching fee record.");
4033
+ const programString = programObject.toString();
4034
+ const imports = await this.networkClient.getProgramImports(programString);
4035
+ const baseFee = Number(ProgramManager$1.estimateDeploymentFee(programString, imports));
4036
+ fee = baseFee + priorityFee;
4037
+ }
4038
+ // Get a credits.aleo record for the fee.
4039
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4040
+ }
4041
+ else {
4042
+ // If it's specified NOT to use a privateFee, use a public fee.
4043
+ feeRecord = undefined;
4044
+ }
3988
4045
  }
3989
4046
  catch (e) {
3990
4047
  logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
@@ -4110,21 +4167,35 @@ class ProgramManager {
4110
4167
  let programName = options.programName;
4111
4168
  let imports = options.imports;
4112
4169
  let edition = options.edition;
4170
+ let programObject;
4113
4171
  // Ensure the function exists on the network
4114
4172
  if (program === undefined) {
4115
4173
  try {
4116
- program = (await this.networkClient.getProgram(programName));
4174
+ programObject = await this.networkClient.getProgramObject(programName);
4175
+ program = programObject.toString();
4117
4176
  }
4118
4177
  catch (e) {
4119
4178
  logAndThrow(`Error finding ${programName}. Network response: '${e.message}'. Please ensure you're connected to a valid Aleo network the program is deployed to the network.`);
4120
4179
  }
4121
4180
  }
4181
+ else if (typeof program == "string") {
4182
+ try {
4183
+ programObject = Program.fromString(program);
4184
+ }
4185
+ catch (e) {
4186
+ logAndThrow(`Program sources passed for ${programName} were invalid: ${e}`);
4187
+ }
4188
+ }
4122
4189
  else if (program instanceof Program) {
4190
+ programObject = program;
4123
4191
  program = program.toString();
4124
4192
  }
4193
+ if (!(programObject instanceof Program)) {
4194
+ logAndThrow(`Failed to validate program ${programName}`);
4195
+ }
4125
4196
  // Get the program name if it is not provided in the parameters.
4126
4197
  if (programName === undefined) {
4127
- programName = Program.fromString(program).id();
4198
+ programName = programObject.id();
4128
4199
  }
4129
4200
  if (edition == undefined) {
4130
4201
  try {
@@ -4144,15 +4215,6 @@ class ProgramManager {
4144
4215
  if (typeof executionPrivateKey === "undefined") {
4145
4216
  throw "No private key provided and no private key set in the ProgramManager";
4146
4217
  }
4147
- // Get the fee record from the account if it is not provided in the parameters
4148
- try {
4149
- feeRecord = privateFee
4150
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
4151
- : undefined;
4152
- }
4153
- catch (e) {
4154
- logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
4155
- }
4156
4218
  // Get the fee proving and verifying keys from the key provider
4157
4219
  let feeKeys;
4158
4220
  try {
@@ -4174,7 +4236,7 @@ class ProgramManager {
4174
4236
  }
4175
4237
  }
4176
4238
  // Resolve the program imports if they exist
4177
- const numberOfImports = Program.fromString(program).getImports().length;
4239
+ const numberOfImports = programObject.getImports().length;
4178
4240
  if (numberOfImports > 0 && !imports) {
4179
4241
  try {
4180
4242
  imports = (await this.networkClient.getProgramImports(programName));
@@ -4183,6 +4245,26 @@ class ProgramManager {
4183
4245
  logAndThrow(`Error finding program imports. Network response: '${e.message}'. Please ensure you're connected to a valid Aleo network and the program is deployed to the network.`);
4184
4246
  }
4185
4247
  }
4248
+ // Get the fee record from the account if it is not provided in the parameters
4249
+ try {
4250
+ if (privateFee) {
4251
+ let fee = priorityFee;
4252
+ // If a fee record wasn't provided, estimate the fee that needs to be paid.
4253
+ if (!feeRecord) {
4254
+ const baseFee = Number(await this.estimateExecutionFee({ programName, functionName, program, imports }));
4255
+ fee = baseFee + priorityFee;
4256
+ }
4257
+ // Get a credits.aleo record for the fee.
4258
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4259
+ }
4260
+ else {
4261
+ // If it's specified NOT to use a privateFee, use a public fee.
4262
+ feeRecord = undefined;
4263
+ }
4264
+ }
4265
+ catch (e) {
4266
+ logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
4267
+ }
4186
4268
  if (offlineQuery && !this.inclusionKeysLoaded) {
4187
4269
  try {
4188
4270
  const inclusionKeys = await this.keyProvider.inclusionKeys();
@@ -4206,53 +4288,65 @@ class ProgramManager {
4206
4288
  * @returns {Promise<Transaction>} - A promise that resolves to the transaction or an error.
4207
4289
  *
4208
4290
  * @example
4209
- * /// Import the mainnet version of the sdk.
4210
- * import { AleoKeyProvider, ProgramManager, NetworkRecordProvider } from "@provablehq/sdk/mainnet.js";
4291
+ * import { AleoKeyProvider, PrivateKey, initThreadPool, ProgramManager } from "@provablehq/sdk";
4211
4292
  *
4212
- * // Create a new NetworkClient, KeyProvider, and RecordProvider.
4293
+ * await initThreadPool();
4294
+ *
4295
+ * // Create a new KeyProvider.
4213
4296
  * const keyProvider = new AleoKeyProvider();
4214
4297
  * keyProvider.useCache(true);
4215
4298
  *
4216
- * // Initialize a program manager with the key provider to automatically fetch keys for executions
4299
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions.
4217
4300
  * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
4218
4301
  *
4219
4302
  * // Build the `Authorization`.
4303
+ * const privateKey = new PrivateKey(); // Change this to a private key that has an aleo credit balance.
4220
4304
  * const authorization = await programManager.buildAuthorization({
4221
- * programName: "credits.aleo",
4222
- * functionName: "transfer_public",
4223
- * inputs: [
4224
- * "aleo1vwls2ete8dk8uu2kmkmzumd7q38fvshrht8hlc0a5362uq8ftgyqnm3w08",
4225
- * "10000000u64",
4226
- * ],
4305
+ * programName: "credits.aleo",
4306
+ * functionName: "transfer_public",
4307
+ * privateKey,
4308
+ * inputs: [
4309
+ * "aleo1vwls2ete8dk8uu2kmkmzumd7q38fvshrht8hlc0a5362uq8ftgyqnm3w08",
4310
+ * "10000000u64",
4311
+ * ],
4227
4312
  * });
4228
4313
  *
4314
+ * console.log("Getting execution id");
4315
+ *
4229
4316
  * // Derive the execution ID and base fee.
4230
4317
  * const executionId = authorization.toExecutionId().toString();
4231
4318
  *
4319
+ * console.log("Estimating fee");
4320
+ *
4232
4321
  * // Get the base fee in microcredits.
4233
- * const baseFeeMicrocredits = ProgramManager.estimateFeeForAuthorization(authorization, "credits.aleo");
4234
- * const baseFeeCredits = baseFeeMicrocredits/1000000;
4322
+ * const baseFeeMicrocredits = await programManager.estimateFeeForAuthorization(authorization, "credits.aleo");
4323
+ * const baseFeeCredits = Number(baseFeeMicrocredits)/1000000;
4324
+ *
4325
+ * console.log("Building fee authorization");
4235
4326
  *
4236
4327
  * // Build a credits.aleo/fee_public `Authorization`.
4237
4328
  * const feeAuthorization = await programManager.buildFeeAuthorization({
4238
- * deploymentOrExecutionId: executionId,
4239
- * baseFeeCredits,
4329
+ * deploymentOrExecutionId: executionId,
4330
+ * baseFeeCredits,
4331
+ * privateKey
4240
4332
  * });
4241
4333
  *
4242
- * // Build and execute the transaction
4334
+ * console.log("Executing authorizations");
4335
+ *
4336
+ * // Build and execute the transaction.
4243
4337
  * const tx = await programManager.buildTransactionFromAuthorization({
4244
- * programName: "hello_hello.aleo",
4245
- * authorization,
4246
- * feeAuthorization,
4338
+ * programName: "credits.aleo",
4339
+ * authorization,
4340
+ * feeAuthorization,
4247
4341
  * });
4248
4342
  *
4249
- * // Submit the transaction to the network
4343
+ * // Submit the transaction to the network.
4250
4344
  * await programManager.networkClient.submitTransaction(tx.toString());
4251
4345
  *
4252
- * // Verify the transaction was successful
4346
+ * // Verify the transaction was successful.
4253
4347
  * setTimeout(async () => {
4254
- * const transaction = await programManager.networkClient.getTransaction(tx.id());
4255
- * assert(transaction.id() === tx.id());
4348
+ * const transaction = await programManager.networkClient.getTransaction(tx.id());
4349
+ * console.log(transaction);
4256
4350
  * }, 10000);
4257
4351
  */
4258
4352
  async buildTransactionFromAuthorization(options) {
@@ -4299,6 +4393,7 @@ class ProgramManager {
4299
4393
  }
4300
4394
  }
4301
4395
  // Resolve the program imports if they exist.
4396
+ console.log("Resolving program imports");
4302
4397
  const numberOfImports = Program.fromString(program).getImports().length;
4303
4398
  if (numberOfImports > 0 && !imports) {
4304
4399
  try {
@@ -4310,6 +4405,7 @@ class ProgramManager {
4310
4405
  }
4311
4406
  // If the offline query exists, add the inclusion key.
4312
4407
  if (offlineQuery && !this.inclusionKeysLoaded) {
4408
+ console.log("Loading inclusion keys for offline proving.");
4313
4409
  try {
4314
4410
  const inclusionKeys = await this.keyProvider.inclusionKeys();
4315
4411
  ProgramManager$1.loadInclusionProver(inclusionKeys[0]);
@@ -4321,6 +4417,7 @@ class ProgramManager {
4321
4417
  }
4322
4418
  }
4323
4419
  // Build an execution transaction from the authorization.
4420
+ console.log("Executing authorizations");
4324
4421
  return await ProgramManager$1.executeAuthorization(authorization, feeAuthorization, program, provingKey, verifyingKey, feeProvingKey, feeVerifyingKey, imports, this.host, offlineQuery);
4325
4422
  }
4326
4423
  /**
@@ -4511,7 +4608,6 @@ class ProgramManager {
4511
4608
  * const provingRequest = await programManager.provingRequest({
4512
4609
  * programName: "credits.aleo",
4513
4610
  * functionName: "transfer_public",
4514
- * baseFee: 100000,
4515
4611
  * priorityFee: 0,
4516
4612
  * privateFee: false,
4517
4613
  * inputs: [
@@ -4523,8 +4619,9 @@ class ProgramManager {
4523
4619
  */
4524
4620
  async provingRequest(options) {
4525
4621
  // Destructure the options object to access the parameters.
4526
- const { functionName, baseFee, priorityFee, privateFee, inputs, recordSearchParams, broadcast = false, unchecked = false, } = options;
4622
+ const { functionName, priorityFee, privateFee, inputs, recordSearchParams, broadcast = false, unchecked = false, } = options;
4527
4623
  const privateKey = options.privateKey;
4624
+ const baseFee = options.baseFee ? options.baseFee : 0;
4528
4625
  let program = options.programSource;
4529
4626
  let programName = options.programName;
4530
4627
  let feeRecord = options.feeRecord;
@@ -4564,15 +4661,6 @@ class ProgramManager {
4564
4661
  if (typeof executionPrivateKey === "undefined") {
4565
4662
  throw "No private key provided and no private key set in the ProgramManager";
4566
4663
  }
4567
- // Get the fee record from the account if it is not provided in the parameters.
4568
- try {
4569
- feeRecord = privateFee
4570
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
4571
- : undefined;
4572
- }
4573
- catch (e) {
4574
- logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
4575
- }
4576
4664
  // Resolve the program imports if they exist.
4577
4665
  const numberOfImports = Program.fromString(program).getImports().length;
4578
4666
  if (numberOfImports > 0 && !imports) {
@@ -4583,6 +4671,26 @@ class ProgramManager {
4583
4671
  logAndThrow(`Error finding program imports. Network response: '${e.message}'. Please ensure you're connected to a valid Aleo network and the program is deployed to the network.`);
4584
4672
  }
4585
4673
  }
4674
+ // Get the fee record from the account if it is not provided in the parameters
4675
+ try {
4676
+ if (privateFee) {
4677
+ let fee = priorityFee;
4678
+ // If a fee record wasn't provided, estimate the fee that needs to be paid.
4679
+ if (!feeRecord) {
4680
+ const baseFee = Number(await this.estimateExecutionFee({ programName, functionName, program: program.toString(), imports }));
4681
+ fee = baseFee + priorityFee;
4682
+ }
4683
+ // Get a credits.aleo record for the fee.
4684
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4685
+ }
4686
+ else {
4687
+ // If it's specified NOT to use a privateFee, use a public fee.
4688
+ feeRecord = undefined;
4689
+ }
4690
+ }
4691
+ catch (e) {
4692
+ logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
4693
+ }
4586
4694
  // Build and return the `ProvingRequest`.
4587
4695
  return await ProgramManager$1.buildProvingRequest(executionPrivateKey, program, functionName, inputs, baseFee, priorityFee, feeRecord, imports, broadcast, unchecked, edition);
4588
4696
  }
@@ -4805,9 +4913,20 @@ class ProgramManager {
4805
4913
  const [joinProvingKey, joinVerifyingKey] = joinKeys;
4806
4914
  // Get the fee record from the account if it is not provided in the parameters
4807
4915
  try {
4808
- feeRecord = privateFee
4809
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
4810
- : undefined;
4916
+ if (privateFee) {
4917
+ let fee = priorityFee;
4918
+ // If a fee record wasn't provided, estimate the fee that needs to be paid.
4919
+ if (!feeRecord) {
4920
+ const baseFee = Number(await this.estimateExecutionFee({ programName: "credits.aleo", functionName: "join" }));
4921
+ fee = baseFee + priorityFee;
4922
+ }
4923
+ // Get a credits.aleo record for the fee.
4924
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4925
+ }
4926
+ else {
4927
+ // If it's specified NOT to use a privateFee, use a public fee.
4928
+ feeRecord = undefined;
4929
+ }
4811
4930
  }
4812
4931
  catch (e) {
4813
4932
  logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
@@ -5020,15 +5139,20 @@ class ProgramManager {
5020
5139
  const nonces = [];
5021
5140
  if (requiresAmountRecord(transferType)) {
5022
5141
  // If the transfer type is private and requires an amount record, get it from the record provider
5023
- amountRecord = RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], amountRecord, recordSearchParams)).record_plaintext ?? '');
5142
+ amountRecord = await this.getCreditsRecord(priorityFee, [], amountRecord, recordSearchParams);
5024
5143
  nonces.push(amountRecord.nonce());
5025
5144
  }
5026
5145
  else {
5027
5146
  amountRecord = undefined;
5028
5147
  }
5029
- feeRecord = privateFee
5030
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, nonces, feeRecord, recordSearchParams)).record_plaintext ?? '')
5031
- : undefined;
5148
+ if (privateFee) {
5149
+ // Get a credits.aleo record for the fee.
5150
+ feeRecord = await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams);
5151
+ }
5152
+ else {
5153
+ // If it's specified NOT to use a privateFee, use a public fee.
5154
+ feeRecord = undefined;
5155
+ }
5032
5156
  }
5033
5157
  catch (e) {
5034
5158
  logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
@@ -5719,15 +5843,6 @@ class ProgramManager {
5719
5843
  return false;
5720
5844
  }
5721
5845
  }
5722
- /**
5723
- * Set the inclusion key bytes.
5724
- *
5725
- * @param {executionResponse} executionResponse The response from an offline function execution (via the `programManager.run` method)
5726
- * @param {ImportedPrograms} imports The imported programs used in the execution. Specified as { "programName": "programSourceCode", ... }
5727
- * @param {ImportedVerifyingKeys} importedVerifyingKeys The verifying keys in the execution. Specified as { "programName": [["functionName", "verifyingKey"], ...], ... }
5728
- * @returns {boolean} True if the proof is valid, false otherwise
5729
- *
5730
-
5731
5846
  /**
5732
5847
  * Create a program object from a program's source code
5733
5848
  *
@@ -5759,28 +5874,134 @@ class ProgramManager {
5759
5874
  return false;
5760
5875
  }
5761
5876
  }
5877
+ /**
5878
+ * Estimate the execution fee for an authorization.
5879
+ *
5880
+ * @param {FeeEstimateOptions} options Options for fee estimate.
5881
+ *
5882
+ * @example
5883
+ * import { AleoKeyProvider, PrivateKey, initThreadPool, ProgramManager } from "@provablehq/sdk";
5884
+ *
5885
+ * await initThreadPool();
5886
+ *
5887
+ * // Create a new KeyProvider.
5888
+ * const keyProvider = new AleoKeyProvider();
5889
+ * keyProvider.useCache(true);
5890
+ *
5891
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions.
5892
+ * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
5893
+ *
5894
+ * // Build the `Authorization`.
5895
+ * const privateKey = new PrivateKey(); // Change this to a private key that has an aleo credit balance.
5896
+ * const authorization = await programManager.buildAuthorization({
5897
+ * programName: "credits.aleo",
5898
+ * functionName: "transfer_public",
5899
+ * privateKey,
5900
+ * inputs: [
5901
+ * "aleo1vwls2ete8dk8uu2kmkmzumd7q38fvshrht8hlc0a5362uq8ftgyqnm3w08",
5902
+ * "10000000u64",
5903
+ * ],
5904
+ * });
5905
+ *
5906
+ * console.log("Getting execution id");
5907
+ *
5908
+ * // Derive the execution ID and base fee.
5909
+ * const executionId = authorization.toExecutionId().toString();
5910
+ *
5911
+ * console.log("Estimating fee");
5912
+ *
5913
+ * // Get the base fee in microcredits.
5914
+ * const baseFeeMicrocredits = await programManager.estimateFeeForAuthorization({
5915
+ * authorization,
5916
+ * programName: "credits.aleo"
5917
+ * });
5918
+ * const baseFeeCredits = Number(baseFeeMicrocredits)/1000000;
5919
+ *
5920
+ * console.log("Building fee authorization");
5921
+ *
5922
+ * // Build a credits.aleo/fee_public `Authorization`.
5923
+ * const feeAuthorization = await programManager.buildFeeAuthorization({
5924
+ * deploymentOrExecutionId: executionId,
5925
+ * baseFeeCredits,
5926
+ * privateKey
5927
+ * });
5928
+ */
5929
+ async estimateFeeForAuthorization(options) {
5930
+ const { authorization, programName, program, imports, edition } = options;
5931
+ if (!authorization) {
5932
+ throw new Error("Authorization must be provided if estimating fee for Authorization.");
5933
+ }
5934
+ const programSource = program ? program.toString() : await this.networkClient.getProgram(programName, edition);
5935
+ const programImports = imports ? imports : await this.networkClient.getProgramImports(programSource);
5936
+ console.log(JSON.stringify(programImports));
5937
+ if (Object.keys(programImports)) {
5938
+ return ProgramManager$1.estimateFeeForAuthorization(authorization, programSource, programImports, edition);
5939
+ }
5940
+ return ProgramManager$1.estimateFeeForAuthorization(authorization, programSource, imports, edition);
5941
+ }
5942
+ /**
5943
+ * Estimate the execution fee for an Aleo function.
5944
+ *
5945
+ * @param {FeeEstimateOptions} options Options for the fee estimate.
5946
+ *
5947
+ * @returns {Promise<bigint>} Execution fee in microcredits for the authorization.
5948
+ *
5949
+ * @example
5950
+ * import { AleoKeyProvider, PrivateKey, initThreadPool, ProgramManager } from "@provablehq/sdk";
5951
+ *
5952
+ * // Initialize a program manager with the key provider to automatically fetch keys for executions.
5953
+ * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
5954
+ *
5955
+ * // Get the base fee in microcredits.
5956
+ * const baseFeeMicrocredits = await programManager.estimateExecutionFee({programName: "credits.aleo"});
5957
+ * const baseFeeCredits = Number(baseFeeMicrocredits)/1000000;
5958
+ *
5959
+ * console.log("Building fee authorization");
5960
+ *
5961
+ * // Build a credits.aleo/fee_public `Authorization`.
5962
+ * const baseFeeMicrocredits = await programManager.estimateFeeForAuthorization({
5963
+ * programName: "credits.aleo",
5964
+ * functionName: "transfer_public",
5965
+ * });
5966
+ * const baseFeeCredits = Number(baseFeeMicrocredits)/1000000;
5967
+ */
5968
+ async estimateExecutionFee(options) {
5969
+ const { functionName, programName, program, imports, edition } = options;
5970
+ if (!functionName) {
5971
+ throw new Error("Function name must be specified when estimating fee.");
5972
+ }
5973
+ const programSource = program ? program.toString() : await this.networkClient.getProgram(programName, edition);
5974
+ const programImports = imports ? imports : await this.networkClient.getProgramImports(programSource);
5975
+ if (Object.keys(programImports)) {
5976
+ return ProgramManager$1.estimateExecutionFee(programSource, functionName, programImports, edition);
5977
+ }
5978
+ return ProgramManager$1.estimateExecutionFee(programSource, functionName, imports, edition);
5979
+ }
5762
5980
  // Internal utility function for getting a credits.aleo record
5763
5981
  async getCreditsRecord(amount, nonces, record, params) {
5764
- try {
5765
- // return record instanceof RecordPlaintext
5766
- // ? record
5767
- // : RecordPlaintext.fromString(<string>record);
5768
- if (record && record instanceof RecordPlaintext) {
5769
- record = record.toString();
5982
+ if (record) {
5983
+ try {
5984
+ return record instanceof RecordPlaintext
5985
+ ? record : RecordPlaintext.fromString(record);
5986
+ }
5987
+ catch {
5988
+ logAndThrow(`Record '${record}' could not be parsed, please ensure a valid credits.aleo record
5989
+ is passed prior to trying again`);
5770
5990
  }
5771
- return ({
5772
- recordPlaintext: record,
5773
- programName: 'credits.aleo',
5774
- recordName: 'credits',
5775
- });
5776
5991
  }
5777
- catch (e) {
5992
+ else {
5778
5993
  try {
5779
5994
  const recordProvider = this.recordProvider;
5780
- return await recordProvider.findCreditsRecord(amount, { ...params, unspent: true, nonces });
5995
+ const record = await recordProvider.findCreditsRecord(amount, { ...params, unspent: true, nonces });
5996
+ if (record.record_plaintext) {
5997
+ return RecordPlaintext.fromString(record.record_plaintext);
5998
+ }
5999
+ else {
6000
+ logAndThrow("Failed to deserialize record returned from record provider");
6001
+ }
5781
6002
  }
5782
6003
  catch (e) {
5783
- logAndThrow(`Error finding fee record. Record finder response: '${e.message}'. Please ensure you're connected to a valid Aleo network and a record with enough balance exists.`);
6004
+ 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.`);
5784
6005
  }
5785
6006
  }
5786
6007
  }