@provablehq/sdk 0.9.11 → 0.9.13

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.
@@ -497,7 +497,7 @@ class AleoNetworkClient {
497
497
  else {
498
498
  this.headers = {
499
499
  // This is replaced by the actual version by a Rollup plugin
500
- "X-Aleo-SDK-Version": "0.9.11",
500
+ "X-Aleo-SDK-Version": "0.9.13",
501
501
  "X-Aleo-environment": environment(),
502
502
  };
503
503
  }
@@ -2306,7 +2306,7 @@ class AleoKeyProvider {
2306
2306
  const verifying_key = key.verifyingKey();
2307
2307
  const proving_key = await this.fetchProvingKey(key.prover, key.locator);
2308
2308
  if (this.cacheOption) {
2309
- 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()]);
2310
2310
  }
2311
2311
  return [proving_key, verifying_key];
2312
2312
  }
@@ -3703,6 +3703,22 @@ class SealanceMerkleTree {
3703
3703
  }
3704
3704
  return tree.map(element => BigInt(element.slice(0, element.length - "field".length)));
3705
3705
  }
3706
+ /** Converts an array of decimal string representations of U256 numbers to an array of BigInts.
3707
+ *
3708
+ * @param tree - Array of decimal string representations of U256 numbers.
3709
+ * @returns Array of BigInts.
3710
+ */
3711
+ convertTreeToBigInt(tree) {
3712
+ return tree.map((element) => {
3713
+ try {
3714
+ // decimal string → native bigint
3715
+ return BigInt(element);
3716
+ }
3717
+ catch {
3718
+ throw new Error(`Invalid decimal U256 string: ${element}`);
3719
+ }
3720
+ });
3721
+ }
3706
3722
  /**
3707
3723
  * Converts Aleo addresses to field elements, sorts them, pads with zero fields, and returns an array. This prepares addresses for Merkle tree construction.
3708
3724
  *
@@ -3811,6 +3827,28 @@ class SealanceMerkleTree {
3811
3827
  }
3812
3828
  return { siblings: siblingPath, leaf_index: leafIndex };
3813
3829
  }
3830
+ /**
3831
+ * Generates a formatted exclusion proof suitable for Aleo transactions.
3832
+ *
3833
+ * @param proof - An array of two {sibling path, leafindex} objects.
3834
+ * @returns String representation of the exclusion proof.
3835
+ *
3836
+ * @example
3837
+ * ```typescript
3838
+ * const tree = buildTree(leaves);
3839
+ * const proof = getSiblingPath(tree, 0, 15);
3840
+ * const proof2 = getSiblingPath(tree, 1, 15);
3841
+ * const formattedProof = formatMerkleProof([proof, proof2]);
3842
+ * // formattedProof = "[{ siblings: [0field, 1field, ...], leaf_index: 0u32 }, { siblings: [0field, 2field, ...], leaf_index: 1u32 }]"
3843
+ * ```
3844
+ */
3845
+ formatMerkleProof(proof) {
3846
+ const formatted = proof.map(item => {
3847
+ const siblings = item.siblings.map(s => `${s}field`).join(", ");
3848
+ return `{siblings: [${siblings}], leaf_index: ${item.leaf_index}u32}`;
3849
+ }).join(", ");
3850
+ return `[${formatted}]`;
3851
+ }
3814
3852
  }
3815
3853
 
3816
3854
  /**
@@ -3895,6 +3933,44 @@ class ProgramManager {
3895
3933
  setHeader(headerName, value) {
3896
3934
  this.networkClient.headers[headerName] = value;
3897
3935
  }
3936
+ /**
3937
+ * Set the inclusion prover into the wasm memory. This should be done prior to any execution of a function with a
3938
+ * private record.
3939
+ *
3940
+ * @param {ProvingKey} [provingKey]
3941
+ *
3942
+ * @example
3943
+ * import { ProgramManager, AleoKeyProvider } from "@provablehq/sdk/mainnet.js";
3944
+ *
3945
+ * const keyProvider = new AleoKeyProvider();
3946
+ * keyProvider.useCache(true);
3947
+ *
3948
+ * // Create a ProgramManager
3949
+ * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider);
3950
+ *
3951
+ * // Set the inclusion keys.
3952
+ * programManager.setInclusionProver();
3953
+ */
3954
+ async setInclusionProver(provingKey) {
3955
+ if (this.inclusionKeysLoaded) {
3956
+ return;
3957
+ }
3958
+ try {
3959
+ if (provingKey) {
3960
+ ProgramManager$1.loadInclusionProver(provingKey);
3961
+ this.inclusionKeysLoaded = true;
3962
+ }
3963
+ else {
3964
+ const inclusionKeys = await this.keyProvider.inclusionKeys();
3965
+ ProgramManager$1.loadInclusionProver(inclusionKeys[0]);
3966
+ this.inclusionKeysLoaded = true;
3967
+ }
3968
+ return;
3969
+ }
3970
+ catch {
3971
+ console.log("Setting the inclusion prover requires either a key provider to be configured for the ProgramManager OR to pass the inclusion prover directly");
3972
+ }
3973
+ }
3898
3974
  /**
3899
3975
  * Remove a header from the `AleoNetworkClient`s header map
3900
3976
  *
@@ -3987,9 +4063,23 @@ class ProgramManager {
3987
4063
  }
3988
4064
  // Get the fee record from the account if it is not provided in the parameters
3989
4065
  try {
3990
- feeRecord = privateFee
3991
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
3992
- : undefined;
4066
+ if (privateFee) {
4067
+ let fee = priorityFee;
4068
+ // If a private fee is specified, but no fee record is provided, estimate the fee and find a matching record.
4069
+ if (!feeRecord) {
4070
+ console.log("Private fee specified, but no private fee record provided, estimating fee and finding a matching fee record.");
4071
+ const programString = programObject.toString();
4072
+ const imports = await this.networkClient.getProgramImports(programString);
4073
+ const baseFee = Number(ProgramManager$1.estimateDeploymentFee(programString, imports));
4074
+ fee = baseFee + priorityFee;
4075
+ }
4076
+ // Get a credits.aleo record for the fee.
4077
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4078
+ }
4079
+ else {
4080
+ // If it's specified NOT to use a privateFee, use a public fee.
4081
+ feeRecord = undefined;
4082
+ }
3993
4083
  }
3994
4084
  catch (e) {
3995
4085
  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.`);
@@ -4016,6 +4106,118 @@ class ProgramManager {
4016
4106
  // Build a deployment transaction
4017
4107
  return await ProgramManager$1.buildDeploymentTransaction(deploymentPrivateKey, program, priorityFee, feeRecord, this.host, imports, feeProvingKey, feeVerifyingKey);
4018
4108
  }
4109
+ /**
4110
+ * Builds a deployment transaction for submission to the Aleo network that upgrades an existing program.
4111
+ *
4112
+ * @param {DeployOptions} options The deployment options.
4113
+ *
4114
+ * @example
4115
+ * /// Import the mainnet version of the sdk.
4116
+ * import { AleoKeyProvider, ProgramManager, NetworkRecordProvider } from "@provablehq/sdk/mainnet.js";
4117
+ *
4118
+ * // Create a new NetworkClient, KeyProvider, and RecordProvider
4119
+ * const keyProvider = new AleoKeyProvider();
4120
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
4121
+ * keyProvider.useCache(true);
4122
+ *
4123
+ * // Initialize a program manager with the key provider to automatically fetch keys for deployments
4124
+ * 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";
4125
+ * const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
4126
+ * programManager.setAccount(Account);
4127
+ *
4128
+ * // Define a fee in credits
4129
+ * const priorityFee = 0.0;
4130
+ *
4131
+ * // Create the deployment transaction.
4132
+ * const tx = await programManager.buildUpgradeTransaction({program: program, priorityFee: fee, privateFee: false});
4133
+ * await programManager.networkClient.submitTransaction(tx);
4134
+ *
4135
+ * // Verify the transaction was successful
4136
+ * setTimeout(async () => {
4137
+ * const transaction = await programManager.networkClient.getTransaction(tx.id());
4138
+ * assert(transaction.id() === tx.id());
4139
+ * }, 20000);
4140
+ */
4141
+ async buildUpgradeTransaction(options) {
4142
+ const { program, priorityFee, privateFee, recordSearchParams } = options;
4143
+ let feeRecord = options.feeRecord;
4144
+ let privateKey = options.privateKey;
4145
+ // Ensure the program is valid.
4146
+ let programObject;
4147
+ try {
4148
+ programObject = Program.fromString(program);
4149
+ }
4150
+ catch (e) {
4151
+ logAndThrow(`Error parsing program: '${e.message}'. Please ensure the program is valid.`);
4152
+ }
4153
+ // Ensure the program is valid and does not exist on the network
4154
+ try {
4155
+ let programSource;
4156
+ try {
4157
+ programSource = await this.networkClient.getProgram(programObject.id());
4158
+ }
4159
+ catch (e) {
4160
+ // Program does not exist on the network, deployment can proceed
4161
+ console.log(`Program ${programObject.id()} does not exist on the network...`);
4162
+ }
4163
+ }
4164
+ catch (e) {
4165
+ logAndThrow(`Error validating program: ${e.message}`);
4166
+ }
4167
+ // Get the private key from the account if it is not provided in the parameters
4168
+ let deploymentPrivateKey = privateKey;
4169
+ if (typeof privateKey === "undefined" &&
4170
+ typeof this.account !== "undefined") {
4171
+ deploymentPrivateKey = this.account.privateKey();
4172
+ }
4173
+ if (typeof deploymentPrivateKey === "undefined") {
4174
+ throw "No private key provided and no private key set in the ProgramManager";
4175
+ }
4176
+ // Get the fee record from the account if it is not provided in the parameters
4177
+ try {
4178
+ if (privateFee) {
4179
+ let fee = priorityFee;
4180
+ // If a private fee is specified, but no fee record is provided, estimate the fee and find a matching record.
4181
+ if (!feeRecord) {
4182
+ console.log("Private fee specified, but no private fee record provided, estimating fee and finding a matching fee record.");
4183
+ const programString = programObject.toString();
4184
+ const imports = await this.networkClient.getProgramImports(programString);
4185
+ const baseFee = Number(ProgramManager$1.estimateDeploymentFee(programString, imports));
4186
+ fee = baseFee + priorityFee;
4187
+ }
4188
+ // Get a credits.aleo record for the fee.
4189
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4190
+ }
4191
+ else {
4192
+ // If it's specified NOT to use a privateFee, use a public fee.
4193
+ feeRecord = undefined;
4194
+ }
4195
+ }
4196
+ catch (e) {
4197
+ 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.`);
4198
+ }
4199
+ // Get the proving and verifying keys from the key provider
4200
+ let feeKeys;
4201
+ try {
4202
+ feeKeys = privateFee
4203
+ ? await this.keyProvider.feePrivateKeys()
4204
+ : await this.keyProvider.feePublicKeys();
4205
+ }
4206
+ catch (e) {
4207
+ logAndThrow(`Error finding fee keys. Key finder response: '${e.message}'. Please ensure your key provider is configured correctly.`);
4208
+ }
4209
+ const [feeProvingKey, feeVerifyingKey] = feeKeys;
4210
+ // Resolve the program imports if they exist
4211
+ let imports;
4212
+ try {
4213
+ imports = await this.networkClient.getProgramImports(program);
4214
+ }
4215
+ catch (e) {
4216
+ 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.`);
4217
+ }
4218
+ // Build a deployment transaction
4219
+ return await ProgramManager$1.buildUpgradeTransaction(deploymentPrivateKey, program, priorityFee, feeRecord, this.host, imports, feeProvingKey, feeVerifyingKey);
4220
+ }
4019
4221
  /**
4020
4222
  * Deploy an Aleo program to the Aleo network
4021
4223
  *
@@ -4115,21 +4317,35 @@ class ProgramManager {
4115
4317
  let programName = options.programName;
4116
4318
  let imports = options.imports;
4117
4319
  let edition = options.edition;
4320
+ let programObject;
4118
4321
  // Ensure the function exists on the network
4119
4322
  if (program === undefined) {
4120
4323
  try {
4121
- program = (await this.networkClient.getProgram(programName));
4324
+ programObject = await this.networkClient.getProgramObject(programName);
4325
+ program = programObject.toString();
4122
4326
  }
4123
4327
  catch (e) {
4124
4328
  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.`);
4125
4329
  }
4126
4330
  }
4331
+ else if (typeof program == "string") {
4332
+ try {
4333
+ programObject = Program.fromString(program);
4334
+ }
4335
+ catch (e) {
4336
+ logAndThrow(`Program sources passed for ${programName} were invalid: ${e}`);
4337
+ }
4338
+ }
4127
4339
  else if (program instanceof Program) {
4340
+ programObject = program;
4128
4341
  program = program.toString();
4129
4342
  }
4343
+ if (!(programObject instanceof Program)) {
4344
+ logAndThrow(`Failed to validate program ${programName}`);
4345
+ }
4130
4346
  // Get the program name if it is not provided in the parameters.
4131
4347
  if (programName === undefined) {
4132
- programName = Program.fromString(program).id();
4348
+ programName = programObject.id();
4133
4349
  }
4134
4350
  if (edition == undefined) {
4135
4351
  try {
@@ -4149,15 +4365,6 @@ class ProgramManager {
4149
4365
  if (typeof executionPrivateKey === "undefined") {
4150
4366
  throw "No private key provided and no private key set in the ProgramManager";
4151
4367
  }
4152
- // Get the fee record from the account if it is not provided in the parameters
4153
- try {
4154
- feeRecord = privateFee
4155
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
4156
- : undefined;
4157
- }
4158
- catch (e) {
4159
- 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.`);
4160
- }
4161
4368
  // Get the fee proving and verifying keys from the key provider
4162
4369
  let feeKeys;
4163
4370
  try {
@@ -4179,7 +4386,7 @@ class ProgramManager {
4179
4386
  }
4180
4387
  }
4181
4388
  // Resolve the program imports if they exist
4182
- const numberOfImports = Program.fromString(program).getImports().length;
4389
+ const numberOfImports = programObject.getImports().length;
4183
4390
  if (numberOfImports > 0 && !imports) {
4184
4391
  try {
4185
4392
  imports = (await this.networkClient.getProgramImports(programName));
@@ -4188,6 +4395,26 @@ class ProgramManager {
4188
4395
  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.`);
4189
4396
  }
4190
4397
  }
4398
+ // Get the fee record from the account if it is not provided in the parameters
4399
+ try {
4400
+ if (privateFee) {
4401
+ let fee = priorityFee;
4402
+ // If a fee record wasn't provided, estimate the fee that needs to be paid.
4403
+ if (!feeRecord) {
4404
+ const baseFee = Number(await this.estimateExecutionFee({ programName, functionName, program, imports }));
4405
+ fee = baseFee + priorityFee;
4406
+ }
4407
+ // Get a credits.aleo record for the fee.
4408
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4409
+ }
4410
+ else {
4411
+ // If it's specified NOT to use a privateFee, use a public fee.
4412
+ feeRecord = undefined;
4413
+ }
4414
+ }
4415
+ catch (e) {
4416
+ 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.`);
4417
+ }
4191
4418
  if (offlineQuery && !this.inclusionKeysLoaded) {
4192
4419
  try {
4193
4420
  const inclusionKeys = await this.keyProvider.inclusionKeys();
@@ -4584,15 +4811,6 @@ class ProgramManager {
4584
4811
  if (typeof executionPrivateKey === "undefined") {
4585
4812
  throw "No private key provided and no private key set in the ProgramManager";
4586
4813
  }
4587
- // Get the fee record from the account if it is not provided in the parameters.
4588
- try {
4589
- feeRecord = privateFee
4590
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
4591
- : undefined;
4592
- }
4593
- catch (e) {
4594
- 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.`);
4595
- }
4596
4814
  // Resolve the program imports if they exist.
4597
4815
  const numberOfImports = Program.fromString(program).getImports().length;
4598
4816
  if (numberOfImports > 0 && !imports) {
@@ -4603,6 +4821,26 @@ class ProgramManager {
4603
4821
  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.`);
4604
4822
  }
4605
4823
  }
4824
+ // Get the fee record from the account if it is not provided in the parameters
4825
+ try {
4826
+ if (privateFee) {
4827
+ let fee = priorityFee;
4828
+ // If a fee record wasn't provided, estimate the fee that needs to be paid.
4829
+ if (!feeRecord) {
4830
+ const baseFee = Number(await this.estimateExecutionFee({ programName, functionName, program: program.toString(), imports }));
4831
+ fee = baseFee + priorityFee;
4832
+ }
4833
+ // Get a credits.aleo record for the fee.
4834
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
4835
+ }
4836
+ else {
4837
+ // If it's specified NOT to use a privateFee, use a public fee.
4838
+ feeRecord = undefined;
4839
+ }
4840
+ }
4841
+ catch (e) {
4842
+ 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.`);
4843
+ }
4606
4844
  // Build and return the `ProvingRequest`.
4607
4845
  return await ProgramManager$1.buildProvingRequest(executionPrivateKey, program, functionName, inputs, baseFee, priorityFee, feeRecord, imports, broadcast, unchecked, edition);
4608
4846
  }
@@ -4825,9 +5063,20 @@ class ProgramManager {
4825
5063
  const [joinProvingKey, joinVerifyingKey] = joinKeys;
4826
5064
  // Get the fee record from the account if it is not provided in the parameters
4827
5065
  try {
4828
- feeRecord = privateFee
4829
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams)).record_plaintext ?? '')
4830
- : undefined;
5066
+ if (privateFee) {
5067
+ let fee = priorityFee;
5068
+ // If a fee record wasn't provided, estimate the fee that needs to be paid.
5069
+ if (!feeRecord) {
5070
+ const baseFee = Number(await this.estimateExecutionFee({ programName: "credits.aleo", functionName: "join" }));
5071
+ fee = baseFee + priorityFee;
5072
+ }
5073
+ // Get a credits.aleo record for the fee.
5074
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
5075
+ }
5076
+ else {
5077
+ // If it's specified NOT to use a privateFee, use a public fee.
5078
+ feeRecord = undefined;
5079
+ }
4831
5080
  }
4832
5081
  catch (e) {
4833
5082
  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.`);
@@ -5040,15 +5289,20 @@ class ProgramManager {
5040
5289
  const nonces = [];
5041
5290
  if (requiresAmountRecord(transferType)) {
5042
5291
  // If the transfer type is private and requires an amount record, get it from the record provider
5043
- amountRecord = RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, [], amountRecord, recordSearchParams)).record_plaintext ?? '');
5292
+ amountRecord = await this.getCreditsRecord(priorityFee, [], amountRecord, recordSearchParams);
5044
5293
  nonces.push(amountRecord.nonce());
5045
5294
  }
5046
5295
  else {
5047
5296
  amountRecord = undefined;
5048
5297
  }
5049
- feeRecord = privateFee
5050
- ? RecordPlaintext.fromString((await this.getCreditsRecord(priorityFee, nonces, feeRecord, recordSearchParams)).record_plaintext ?? '')
5051
- : undefined;
5298
+ if (privateFee) {
5299
+ // Get a credits.aleo record for the fee.
5300
+ feeRecord = await this.getCreditsRecord(priorityFee, [], feeRecord, recordSearchParams);
5301
+ }
5302
+ else {
5303
+ // If it's specified NOT to use a privateFee, use a public fee.
5304
+ feeRecord = undefined;
5305
+ }
5052
5306
  }
5053
5307
  catch (e) {
5054
5308
  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.`);
@@ -5875,28 +6129,372 @@ class ProgramManager {
5875
6129
  }
5876
6130
  // Internal utility function for getting a credits.aleo record
5877
6131
  async getCreditsRecord(amount, nonces, record, params) {
6132
+ if (record) {
6133
+ try {
6134
+ return record instanceof RecordPlaintext
6135
+ ? record : RecordPlaintext.fromString(record);
6136
+ }
6137
+ catch {
6138
+ logAndThrow(`Record '${record}' could not be parsed, please ensure a valid credits.aleo record
6139
+ is passed prior to trying again`);
6140
+ }
6141
+ }
6142
+ else {
6143
+ try {
6144
+ const recordProvider = this.recordProvider;
6145
+ const record = await recordProvider.findCreditsRecord(amount, { ...params, unspent: true, nonces });
6146
+ if (record.record_plaintext) {
6147
+ return RecordPlaintext.fromString(record.record_plaintext);
6148
+ }
6149
+ else {
6150
+ logAndThrow("Failed to deserialize record returned from record provider");
6151
+ }
6152
+ }
6153
+ catch (e) {
6154
+ 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.`);
6155
+ }
6156
+ }
6157
+ }
6158
+ /**
6159
+ * Builds an execution transaction for submission to the a local devnode.
6160
+ * This method skips proof generation and is not meant for use with the mainnet or testnet Aleo networks.
6161
+ * Note: getOrInitConsensusVersionTestHeights must be called prior to using this method for this method to work properly.
6162
+ *
6163
+ * @param {ExecuteOptions} options - The options for the execution transaction.
6164
+ * @returns {Promise<Transaction>} - A promise that resolves to the transaction or an error.
6165
+ *
6166
+ * @example
6167
+ * /// Import the mainnet version of the sdk.
6168
+ * import { AleoKeyProvider, getOrInitConsensusVersionTestHeights, ProgramManager, NetworkRecordProvider } from "@provablehq/sdk/mainnet.js";
6169
+ *
6170
+ * // Initialize the development consensus heights in order to work with devnode.
6171
+ * getOrInitConsensusVersionTestHeights("0,1,2,3,4,5,6,7,8,9,10,11");
6172
+ *
6173
+ * // Create a new NetworkClient and RecordProvider.
6174
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
6175
+ * keyProvider.useCache(true);
6176
+ *
6177
+ * // Initialize a program manager.
6178
+ * const programManager = new ProgramManager("http://localhost:3030", recordProvider);
6179
+ *
6180
+ * // Build and execute the transaction.
6181
+ * const tx = await programManager.buildDevnodeExecutionTransaction({
6182
+ * programName: "hello_hello.aleo",
6183
+ * functionName: "hello_hello",
6184
+ * priorityFee: 0.0,
6185
+ * privateFee: false,
6186
+ * inputs: ["5u32", "5u32"],
6187
+ * });
6188
+ *
6189
+ * // Submit the transaction to the network
6190
+ * await programManager.networkClient.submitTransaction(tx.toString());
6191
+ *
6192
+ * // Verify the transaction was successful
6193
+ * setTimeout(async () => {
6194
+ * const transaction = await programManager.networkClient.getTransaction(tx.id());
6195
+ * assert(transaction.id() === tx.id());
6196
+ * }, 10000);
6197
+ */
6198
+ async buildDevnodeExecutionTransaction(options) {
6199
+ // Destructure the options object to access the parameters
6200
+ const { functionName, priorityFee, privateFee, inputs, recordSearchParams, privateKey, } = options;
6201
+ let feeRecord = options.feeRecord;
6202
+ let program = options.program;
6203
+ let programName = options.programName;
6204
+ let imports = options.imports;
6205
+ let edition = options.edition;
6206
+ let programObject;
6207
+ // Ensure the function exists on the network
6208
+ if (program === undefined) {
6209
+ try {
6210
+ programObject = await this.networkClient.getProgramObject(programName);
6211
+ program = programObject.toString();
6212
+ }
6213
+ catch (e) {
6214
+ 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.`);
6215
+ }
6216
+ }
6217
+ else if (typeof program == "string") {
6218
+ try {
6219
+ programObject = Program.fromString(program);
6220
+ }
6221
+ catch (e) {
6222
+ logAndThrow(`Program sources passed for ${programName} were invalid: ${e}`);
6223
+ }
6224
+ }
6225
+ else if (program instanceof Program) {
6226
+ programObject = program;
6227
+ program = program.toString();
6228
+ }
6229
+ if (!(programObject instanceof Program)) {
6230
+ logAndThrow(`Failed to validate program ${programName}`);
6231
+ }
6232
+ // Get the program name if it is not provided in the parameters.
6233
+ if (programName === undefined) {
6234
+ programName = programObject.id();
6235
+ }
6236
+ if (edition == undefined) {
6237
+ try {
6238
+ edition = await this.networkClient.getLatestProgramEdition(programName);
6239
+ }
6240
+ catch (e) {
6241
+ console.warn(`Error finding edition for ${programName}. Network response: '${e.message}'. Assuming edition 0.`);
6242
+ edition = 0;
6243
+ }
6244
+ }
6245
+ // Get the private key from the account if it is not provided in the parameters.
6246
+ let executionPrivateKey = privateKey;
6247
+ if (typeof privateKey === "undefined" &&
6248
+ typeof this.account !== "undefined") {
6249
+ executionPrivateKey = this.account.privateKey();
6250
+ }
6251
+ if (typeof executionPrivateKey === "undefined") {
6252
+ throw "No private key provided and no private key set in the ProgramManager";
6253
+ }
6254
+ // Get the fee record from the account if it is not provided in the parameters.
5878
6255
  try {
5879
- // return record instanceof RecordPlaintext
5880
- // ? record
5881
- // : RecordPlaintext.fromString(<string>record);
5882
- if (record && record instanceof RecordPlaintext) {
5883
- record = record.toString();
5884
- }
5885
- return ({
5886
- recordPlaintext: record,
5887
- programName: 'credits.aleo',
5888
- recordName: 'credits',
5889
- });
6256
+ if (privateFee) {
6257
+ let fee = priorityFee;
6258
+ // If a private fee is specified, but no fee record is provided, estimate the fee and find a matching record.
6259
+ if (!feeRecord) {
6260
+ console.log("Private fee specified, but no private fee record provided, estimating fee and finding a matching fee record.");
6261
+ const programString = programObject.toString();
6262
+ const imports = await this.networkClient.getProgramImports(programString);
6263
+ const baseFee = Number(ProgramManager$1.estimateDeploymentFee(programString, imports));
6264
+ fee = baseFee + priorityFee;
6265
+ }
6266
+ // Get a credits.aleo record for the fee.
6267
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
6268
+ }
6269
+ else {
6270
+ // If it's specified NOT to use a privateFee, use a public fee.
6271
+ feeRecord = undefined;
6272
+ }
5890
6273
  }
5891
6274
  catch (e) {
6275
+ 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.`);
6276
+ }
6277
+ // Resolve the program imports if they exist.
6278
+ const numberOfImports = programObject.getImports().length;
6279
+ if (numberOfImports > 0 && !imports) {
5892
6280
  try {
5893
- const recordProvider = this.recordProvider;
5894
- return await recordProvider.findCreditsRecord(amount, { ...params, unspent: true, nonces });
6281
+ imports = (await this.networkClient.getProgramImports(programName));
5895
6282
  }
5896
6283
  catch (e) {
5897
- 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.`);
6284
+ 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.`);
5898
6285
  }
5899
6286
  }
6287
+ // Build a transaction without a proof
6288
+ return await ProgramManager$1.buildDevnodeExecutionTransaction(executionPrivateKey, program, functionName, inputs, priorityFee, feeRecord, this.host, imports, edition);
6289
+ }
6290
+ /**
6291
+ * Builds a deployment transaction with placeholder certificates and verifying keys for each function in the program.
6292
+ * Intended for use with a local devnode.
6293
+ * `getOrInitConsensusVersionTestHeights` must be called with development heights prior to invoking this method for it to work properly.
6294
+ *
6295
+ * @param {DeployOptions} options - The options for the deployment transaction.
6296
+ * @returns {string} The transaction id of the deployed program or a failure message from the network
6297
+ *
6298
+ * @example
6299
+ * /// Import the mainnet version of the sdk.
6300
+ * import { ProgramManager, NetworkRecordProvider, getOrInitConsensusVersionTestHeights } from "@provablehq/sdk/mainnet.js";
6301
+ *
6302
+ * // Initialize the development consensus heights in order to work with a local devnode.
6303
+ * getOrInitConsensusVersionTestHeights("0,1,2,3,4,5,6,7,8,9,10,11");
6304
+ *
6305
+ * // Create a new NetworkClient, and RecordProvider
6306
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
6307
+ * keyProvider.useCache(true);
6308
+ *
6309
+ * // Initialize a program manager with the key provider to automatically fetch keys for deployments
6310
+ * 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";
6311
+ * const programManager = new ProgramManager("http://localhost:3030", recordProvider);
6312
+ * programManager.setAccount(Account);
6313
+ *
6314
+ * // Define a fee in credits
6315
+ * const priorityFee = 0.0;
6316
+ *
6317
+ * // Create the deployment transaction.
6318
+ * const tx = await programManager.buildDevnodeDeploymentTransaction({program: program, fee: priorityFee, privateFee: false});
6319
+ * await programManager.networkClient.submitTransaction(tx);
6320
+ *
6321
+ * // Verify the transaction was successful
6322
+ * setTimeout(async () => {
6323
+ * const transaction = await programManager.networkClient.getTransaction(tx.id());
6324
+ * assert(transaction.id() === tx.id());
6325
+ * }, 20000);
6326
+ */
6327
+ async buildDevnodeDeploymentTransaction(options) {
6328
+ const { program, priorityFee, privateFee, recordSearchParams } = options;
6329
+ let feeRecord = options.feeRecord;
6330
+ let privateKey = options.privateKey;
6331
+ // Ensure the program is valid.
6332
+ let programObject;
6333
+ try {
6334
+ programObject = Program.fromString(program);
6335
+ }
6336
+ catch (e) {
6337
+ logAndThrow(`Error parsing program: '${e.message}'. Please ensure the program is valid.`);
6338
+ }
6339
+ // Ensure the program is valid and does not exist on the network
6340
+ try {
6341
+ let programSource;
6342
+ try {
6343
+ programSource = await this.networkClient.getProgram(programObject.id());
6344
+ }
6345
+ catch (e) {
6346
+ // Program does not exist on the network, deployment can proceed
6347
+ console.log(`Program ${programObject.id()} does not exist on the network, deploying...`);
6348
+ }
6349
+ if (typeof programSource === "string") {
6350
+ throw Error(`Program ${programObject.id()} already exists on the network, please rename your program`);
6351
+ }
6352
+ }
6353
+ catch (e) {
6354
+ logAndThrow(`Error validating program: ${e.message}`);
6355
+ }
6356
+ // Get the private key from the account if it is not provided in the parameters
6357
+ let deploymentPrivateKey = privateKey;
6358
+ if (typeof privateKey === "undefined" &&
6359
+ typeof this.account !== "undefined") {
6360
+ deploymentPrivateKey = this.account.privateKey();
6361
+ }
6362
+ if (typeof deploymentPrivateKey === "undefined") {
6363
+ throw "No private key provided and no private key set in the ProgramManager";
6364
+ }
6365
+ // Get the fee record from the account if it is not provided in the parameters
6366
+ try {
6367
+ if (privateFee) {
6368
+ let fee = priorityFee;
6369
+ // If a private fee is specified, but no fee record is provided, estimate the fee and find a matching record.
6370
+ if (!feeRecord) {
6371
+ console.log("Private fee specified, but no private fee record provided, estimating fee and finding a matching fee record.");
6372
+ const programString = programObject.toString();
6373
+ const imports = await this.networkClient.getProgramImports(programString);
6374
+ const baseFee = Number(ProgramManager$1.estimateDeploymentFee(programString, imports));
6375
+ fee = baseFee + priorityFee;
6376
+ }
6377
+ // Get a credits.aleo record for the fee.
6378
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
6379
+ }
6380
+ else {
6381
+ // If it's specified NOT to use a privateFee, use a public fee.
6382
+ feeRecord = undefined;
6383
+ }
6384
+ }
6385
+ catch (e) {
6386
+ 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.`);
6387
+ }
6388
+ // Resolve the program imports if they exist
6389
+ let imports;
6390
+ try {
6391
+ imports = await this.networkClient.getProgramImports(program);
6392
+ }
6393
+ catch (e) {
6394
+ 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.`);
6395
+ }
6396
+ return await ProgramManager$1.buildDevnodeDeploymentTransaction(deploymentPrivateKey, program, priorityFee, feeRecord, this.host, imports);
6397
+ }
6398
+ /**
6399
+ * Builds an upgrade transaction on a local devnodewith placeholder certificates and verifying keys for each function in the program.
6400
+ * This method is only intended for use with a local devnode.
6401
+ *
6402
+ * @param {DeployOptions} options - The options for the deployment transaction.
6403
+ * @returns {string} The transaction id of the deployed program or a failure message from the network
6404
+ *
6405
+ * @example
6406
+ * /// Import the mainnet version of the sdk.
6407
+ * import { ProgramManager, NetworkRecordProvider } from "@provablehq/sdk/mainnet.js";
6408
+ *
6409
+ * // Create a new NetworkClient, and RecordProvider
6410
+ * const recordProvider = new NetworkRecordProvider(account, networkClient);
6411
+ * keyProvider.useCache(true);
6412
+ *
6413
+ * // Initialize a program manager with the key provider to automatically fetch keys for deployments
6414
+ * 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";
6415
+ * const programManager = new ProgramManager("http://localhost:3030", recordProvider);
6416
+ * programManager.setAccount(Account);
6417
+ *
6418
+ * // Define a fee in credits
6419
+ * const priorityFee = 0.0;
6420
+ *
6421
+ * // Create the deployment transaction.
6422
+ * const tx = await programManager.buildDevnodeUpgradeTransaction({program: program, fee: priorityFee, privateFee: false});
6423
+ * await programManager.networkClient.submitTransaction(tx);
6424
+ *
6425
+ * // Verify the transaction was successful
6426
+ * setTimeout(async () => {
6427
+ * const transaction = await programManager.networkClient.getTransaction(tx.id());
6428
+ * assert(transaction.id() === tx.id());
6429
+ * }, 20000);
6430
+ */
6431
+ async buildDevnodeUpgradeTransaction(options) {
6432
+ const { program, priorityFee, privateFee, recordSearchParams } = options;
6433
+ let feeRecord = options.feeRecord;
6434
+ let privateKey = options.privateKey;
6435
+ // Ensure the program is valid.
6436
+ let programObject;
6437
+ try {
6438
+ programObject = Program.fromString(program);
6439
+ }
6440
+ catch (e) {
6441
+ logAndThrow(`Error parsing program: '${e.message}'. Please ensure the program is valid.`);
6442
+ }
6443
+ // Ensure the program is valid and does not exist on the network.
6444
+ try {
6445
+ let programSource;
6446
+ try {
6447
+ programSource = await this.networkClient.getProgram(programObject.id());
6448
+ }
6449
+ catch (e) {
6450
+ // Program does not exist on the network.
6451
+ logAndThrow(`Program ${programObject.id()} does not exist on the network...`);
6452
+ }
6453
+ }
6454
+ catch (e) {
6455
+ logAndThrow(`Error validating program: ${e.message}`);
6456
+ }
6457
+ // Get the private key from the account if it is not provided in the parameters
6458
+ let deploymentPrivateKey = privateKey;
6459
+ if (typeof privateKey === "undefined" &&
6460
+ typeof this.account !== "undefined") {
6461
+ deploymentPrivateKey = this.account.privateKey();
6462
+ }
6463
+ if (typeof deploymentPrivateKey === "undefined") {
6464
+ throw "No private key provided and no private key set in the ProgramManager";
6465
+ }
6466
+ // Get the fee record from the account if it is not provided in the parameters
6467
+ try {
6468
+ if (privateFee) {
6469
+ let fee = priorityFee;
6470
+ // If a private fee is specified, but no fee record is provided, estimate the fee and find a matching record.
6471
+ if (!feeRecord) {
6472
+ console.log("Private fee specified, but no private fee record provided, estimating fee and finding a matching fee record.");
6473
+ const programString = programObject.toString();
6474
+ const imports = await this.networkClient.getProgramImports(programString);
6475
+ const baseFee = Number(ProgramManager$1.estimateDeploymentFee(programString, imports));
6476
+ fee = baseFee + priorityFee;
6477
+ }
6478
+ // Get a credits.aleo record for the fee.
6479
+ feeRecord = await this.getCreditsRecord(fee, [], feeRecord, recordSearchParams);
6480
+ }
6481
+ else {
6482
+ // If it's specified NOT to use a privateFee, use a public fee.
6483
+ feeRecord = undefined;
6484
+ }
6485
+ }
6486
+ catch (e) {
6487
+ 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.`);
6488
+ }
6489
+ // Resolve the program imports if they exist
6490
+ let imports;
6491
+ try {
6492
+ imports = await this.networkClient.getProgramImports(program);
6493
+ }
6494
+ catch (e) {
6495
+ 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.`);
6496
+ }
6497
+ return ProgramManager$1.buildDevnodeUpgradeTransaction(deploymentPrivateKey, program, priorityFee, feeRecord, this.host, imports);
5900
6498
  }
5901
6499
  }
5902
6500
  // Ensure the transfer type requires an amount record