@aztec/cli-wallet 0.86.0-starknet.1 → 0.87.0

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.
Files changed (51) hide show
  1. package/dest/bin/index.js +1 -1
  2. package/dest/cmds/create_account.d.ts +1 -1
  3. package/dest/cmds/create_account.d.ts.map +1 -1
  4. package/dest/cmds/create_account.js +25 -15
  5. package/dest/cmds/deploy.d.ts +1 -1
  6. package/dest/cmds/deploy.d.ts.map +1 -1
  7. package/dest/cmds/deploy.js +7 -2
  8. package/dest/cmds/deploy_account.d.ts +1 -1
  9. package/dest/cmds/deploy_account.d.ts.map +1 -1
  10. package/dest/cmds/deploy_account.js +25 -16
  11. package/dest/cmds/index.d.ts.map +1 -1
  12. package/dest/cmds/index.js +17 -16
  13. package/dest/cmds/profile.d.ts.map +1 -1
  14. package/dest/cmds/profile.js +2 -22
  15. package/dest/cmds/register_contract.d.ts +1 -1
  16. package/dest/cmds/register_contract.d.ts.map +1 -1
  17. package/dest/cmds/send.d.ts +1 -1
  18. package/dest/cmds/send.d.ts.map +1 -1
  19. package/dest/cmds/send.js +7 -2
  20. package/dest/cmds/simulate.d.ts +2 -1
  21. package/dest/cmds/simulate.d.ts.map +1 -1
  22. package/dest/cmds/simulate.js +10 -4
  23. package/dest/storage/wallet_db.d.ts +1 -3
  24. package/dest/storage/wallet_db.d.ts.map +1 -1
  25. package/dest/storage/wallet_db.js +1 -1
  26. package/dest/utils/accounts.d.ts +1 -1
  27. package/dest/utils/accounts.d.ts.map +1 -1
  28. package/dest/utils/ecdsa.d.ts +0 -2
  29. package/dest/utils/ecdsa.d.ts.map +1 -1
  30. package/dest/utils/options/fees.d.ts.map +1 -1
  31. package/dest/utils/options/options.d.ts +1 -0
  32. package/dest/utils/options/options.d.ts.map +1 -1
  33. package/dest/utils/options/options.js +6 -3
  34. package/dest/utils/profiling.d.ts +5 -0
  35. package/dest/utils/profiling.d.ts.map +1 -0
  36. package/dest/utils/profiling.js +32 -0
  37. package/package.json +15 -15
  38. package/src/bin/index.ts +1 -1
  39. package/src/cmds/create_account.ts +24 -14
  40. package/src/cmds/deploy.ts +8 -1
  41. package/src/cmds/deploy_account.ts +24 -15
  42. package/src/cmds/index.ts +51 -26
  43. package/src/cmds/profile.ts +3 -60
  44. package/src/cmds/register_contract.ts +1 -1
  45. package/src/cmds/send.ts +8 -1
  46. package/src/cmds/simulate.ts +14 -2
  47. package/src/storage/wallet_db.ts +1 -1
  48. package/src/utils/accounts.ts +1 -1
  49. package/src/utils/options/fees.ts +24 -15
  50. package/src/utils/options/options.ts +10 -3
  51. package/src/utils/profiling.ts +87 -0
@@ -18,7 +18,7 @@ export function integerArgParser(value, argName, min = Number.MIN_SAFE_INTEGER,
18
18
  export function aliasedTxHashParser(txHash, db) {
19
19
  try {
20
20
  return parseTxHash(txHash);
21
- } catch (err) {
21
+ } catch {
22
22
  const prefixed = txHash.includes(':') ? txHash : `transactions:${txHash}`;
23
23
  const rawTxHash = db ? db.tryRetrieveAlias(prefixed) : txHash;
24
24
  return parseTxHash(rawTxHash);
@@ -28,7 +28,7 @@ export function aliasedAuthWitParser(witnesses, db) {
28
28
  const parsedWitnesses = witnesses.split(',').map((witness)=>{
29
29
  try {
30
30
  return AuthWitness.fromString(witness);
31
- } catch (err) {
31
+ } catch {
32
32
  const prefixed = witness.includes(':') ? witness : `authwits:${witness}`;
33
33
  const rawAuthWitness = db ? db.tryRetrieveAlias(prefixed) : witness;
34
34
  return AuthWitness.fromString(rawAuthWitness);
@@ -79,6 +79,9 @@ export function createContractAddressOption(db) {
79
79
  export function createDebugExecutionStepsDirOption() {
80
80
  return new Option('--debug-execution-steps-dir <address>', 'Directory to write execution step artifacts for bb profiling/debugging.').makeOptionMandatory(false);
81
81
  }
82
+ export function createVerboseOption() {
83
+ return new Option('-v, --verbose', 'Provide timings on all executed operations (synching, simulating, proving)').default(false);
84
+ }
82
85
  export function artifactPathParser(filePath, db) {
83
86
  if (filePath.includes('@')) {
84
87
  const [pkg, contractName] = filePath.split('@');
@@ -108,7 +111,7 @@ async function contractArtifactFromWorkspace(pkg, contractName) {
108
111
  const cwd = process.cwd();
109
112
  try {
110
113
  await stat(`${cwd}/Nargo.toml`);
111
- } catch (e) {
114
+ } catch {
112
115
  throw new Error('Invalid contract artifact argument provided. To use this option, command should be called from a nargo workspace');
113
116
  }
114
117
  const filesInTarget = await readdir(`${cwd}/${TARGET_DIR}`);
@@ -0,0 +1,5 @@
1
+ import type { LogFn } from '@aztec/foundation/log';
2
+ import type { PrivateExecutionStep } from '@aztec/stdlib/kernel';
3
+ import type { ProvingTimings, SimulationTimings } from '@aztec/stdlib/tx';
4
+ export declare function printProfileResult(timings: ProvingTimings | SimulationTimings, log: LogFn, executionSteps?: PrivateExecutionStep[]): void;
5
+ //# sourceMappingURL=profiling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiling.d.ts","sourceRoot":"","sources":["../../src/utils/profiling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAI1E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,cAAc,GAAG,iBAAiB,EAC3C,GAAG,EAAE,KAAK,EACV,cAAc,CAAC,EAAE,oBAAoB,EAAE,QA6ExC"}
@@ -0,0 +1,32 @@
1
+ import { format } from 'util';
2
+ export function printProfileResult(timings, log, executionSteps) {
3
+ log(format('\nPer circuit breakdown:\n'));
4
+ log(format(' ', 'Function name'.padEnd(50), 'Time'.padStart(13).padEnd(15), executionSteps ? 'Gates'.padStart(13).padEnd(15) : '', executionSteps ? 'Subtotal'.padStart(13).padEnd(15) : ''));
5
+ log(format(''.padEnd(50 + 15 + 15 + (executionSteps ? 15 + 15 : 0), '-')));
6
+ let acc = 0;
7
+ let biggest = executionSteps?.[0];
8
+ timings.perFunction.forEach((fn, i)=>{
9
+ const currentExecutionStep = executionSteps?.[i];
10
+ if (currentExecutionStep && biggest && currentExecutionStep.gateCount > biggest.gateCount) {
11
+ biggest = currentExecutionStep;
12
+ }
13
+ acc += currentExecutionStep ? currentExecutionStep.gateCount : 0;
14
+ log(format(' ', fn.functionName.padEnd(50), `${fn.time.toFixed(2)}ms`.padStart(13).padEnd(15), currentExecutionStep ? currentExecutionStep.gateCount.toLocaleString().padStart(13).padEnd(15) : '', currentExecutionStep ? acc.toLocaleString().padStart(15) : ''));
15
+ });
16
+ if (biggest) {
17
+ log(format('\nTotal gates:', acc.toLocaleString(), `(Biggest circuit: ${biggest.functionName} -> ${biggest.gateCount.toLocaleString()})`));
18
+ }
19
+ log(format('\nSync time:'.padEnd(25), `${timings.sync?.toFixed(2)}ms`.padStart(16)));
20
+ log(format('Private simulation time:'.padEnd(25), `${timings.perFunction.reduce((acc, { time })=>acc + time, 0).toFixed(2)}ms`.padStart(15)));
21
+ if (timings.proving) {
22
+ log(format('Proving time:'.padEnd(25), `${timings.proving?.toFixed(2)}ms`.padStart(15)));
23
+ }
24
+ if (timings.publicSimulation) {
25
+ log(format('Public simulation time:'.padEnd(25), `${timings.publicSimulation?.toFixed(2)}ms`.padStart(15)));
26
+ }
27
+ if (timings.validation) {
28
+ log(format('Validation time:'.padEnd(25), `${timings.validation?.toFixed(2)}ms`.padStart(15)));
29
+ }
30
+ log(format('Total time:'.padEnd(25), `${timings.total.toFixed(2)}ms`.padStart(15), `(${timings.unaccounted.toFixed(2)}ms unaccounted)`));
31
+ log('\n');
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/cli-wallet",
3
- "version": "0.86.0-starknet.1",
3
+ "version": "0.87.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/cmds/index.js",
@@ -63,17 +63,17 @@
63
63
  ]
64
64
  },
65
65
  "dependencies": {
66
- "@aztec/accounts": "0.86.0-starknet.1",
67
- "@aztec/aztec.js": "0.86.0-starknet.1",
68
- "@aztec/cli": "0.86.0-starknet.1",
69
- "@aztec/entrypoints": "0.86.0-starknet.1",
70
- "@aztec/ethereum": "0.86.0-starknet.1",
71
- "@aztec/foundation": "0.86.0-starknet.1",
72
- "@aztec/kv-store": "0.86.0-starknet.1",
73
- "@aztec/noir-contracts.js": "0.86.0-starknet.1",
74
- "@aztec/noir-noirc_abi": "0.86.0-starknet.1",
75
- "@aztec/pxe": "0.86.0-starknet.1",
76
- "@aztec/stdlib": "0.86.0-starknet.1",
66
+ "@aztec/accounts": "0.87.0",
67
+ "@aztec/aztec.js": "0.87.0",
68
+ "@aztec/cli": "0.87.0",
69
+ "@aztec/entrypoints": "0.87.0",
70
+ "@aztec/ethereum": "0.87.0",
71
+ "@aztec/foundation": "0.87.0",
72
+ "@aztec/kv-store": "0.87.0",
73
+ "@aztec/noir-contracts.js": "0.87.0",
74
+ "@aztec/noir-noirc_abi": "0.87.0",
75
+ "@aztec/pxe": "0.87.0",
76
+ "@aztec/stdlib": "0.87.0",
77
77
  "commander": "^12.1.0",
78
78
  "inquirer": "^10.1.8",
79
79
  "source-map-support": "^0.5.21",
@@ -82,13 +82,13 @@
82
82
  "devDependencies": {
83
83
  "@jest/globals": "^29.5.0",
84
84
  "@types/jest": "^29.5.0",
85
- "@types/node": "^18.7.23",
85
+ "@types/node": "^22.15.17",
86
86
  "@types/source-map-support": "^0.5.10",
87
87
  "jest": "^29.5.0",
88
88
  "jest-mock-extended": "^3.0.5",
89
89
  "ts-jest": "^29.1.0",
90
90
  "ts-node": "^10.9.1",
91
- "typescript": "^5.0.4"
91
+ "typescript": "^5.3.3"
92
92
  },
93
93
  "files": [
94
94
  "dest",
@@ -97,6 +97,6 @@
97
97
  ],
98
98
  "types": "./dest/index.d.ts",
99
99
  "engines": {
100
- "node": ">=18"
100
+ "node": ">=20.10"
101
101
  }
102
102
  }
package/src/bin/index.ts CHANGED
@@ -55,7 +55,7 @@ function injectInternalCommands(program: Command, log: LogFn, db: WalletDB) {
55
55
  const options = command.optsWithGlobals();
56
56
  const { alias } = options;
57
57
  const value = Fr.random();
58
- const hash = computeSecretHash(value);
58
+ const hash = await computeSecretHash(value);
59
59
 
60
60
  await db.storeAlias('secrets', alias, Buffer.from(value.toString()), log);
61
61
  await db.storeAlias('secrets', `${alias}:hash`, Buffer.from(hash.toString()), log);
@@ -5,6 +5,7 @@ import type { LogFn, Logger } from '@aztec/foundation/log';
5
5
 
6
6
  import { type AccountType, createOrRetrieveAccount } from '../utils/accounts.js';
7
7
  import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
8
+ import { printProfileResult } from '../utils/profiling.js';
8
9
 
9
10
  export async function createAccount(
10
11
  client: PXE,
@@ -18,6 +19,7 @@ export async function createAccount(
18
19
  wait: boolean,
19
20
  feeOpts: IFeeOpts,
20
21
  json: boolean,
22
+ verbose: boolean,
21
23
  debugLogger: Logger,
22
24
  log: LogFn,
23
25
  ) {
@@ -71,20 +73,23 @@ export async function createAccount(
71
73
  skipInitialization: skipInitialization,
72
74
  ...(await feeOpts.toDeployAccountOpts(wallet)),
73
75
  };
76
+ /*
77
+ * This is usually handled by accountManager.deploy(), but we're accessing the lower
78
+ * level method to get gas and timings. That means we have to replicate some of the logic here.
79
+ * In case we're deploying our own account, we need to hijack the payment method for the fee,
80
+ * wrapping it in the one that will make use of the freshly deployed account's
81
+ * entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
82
+ * Also, salt and universalDeploy have to be explicitly provided
83
+ */
84
+ deployOpts.fee =
85
+ !deployOpts?.deployWallet && deployOpts?.fee
86
+ ? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
87
+ : deployOpts?.fee;
88
+
89
+ const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
90
+
74
91
  if (feeOpts.estimateOnly) {
75
- /*
76
- * This is usually handled by accountManager.deploy(), but we're accessing the lower
77
- * level method to get the gas estimates. That means we have to replicate some of the logic here.
78
- * In case we're deploying our own account, we need to hijack the payment method for the fee,
79
- * wrapping it in the one that will make use of the freshly deployed account's
80
- * entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
81
- */
82
- const fee =
83
- !deployOpts?.deployWallet && deployOpts?.fee
84
- ? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
85
- : deployOpts?.fee;
86
- const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
87
- const gas = await deployMethod.estimateGas({ ...deployOpts, fee, universalDeploy: true });
92
+ const gas = await deployMethod.estimateGas({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
88
93
  if (json) {
89
94
  out.fee = {
90
95
  gasLimits: {
@@ -100,7 +105,12 @@ export async function createAccount(
100
105
  printGasEstimates(feeOpts, gas, log);
101
106
  }
102
107
  } else {
103
- tx = account.deploy(deployOpts);
108
+ const provenTx = await deployMethod.prove({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
109
+ if (verbose) {
110
+ printProfileResult(provenTx.timings!, log);
111
+ }
112
+ tx = provenTx.send();
113
+
104
114
  const txHash = await tx.getTxHash();
105
115
  debugLogger.debug(`Account contract tx sent with hash ${txHash}`);
106
116
  out.txHash = txHash;
@@ -5,6 +5,7 @@ import { getAllFunctionAbis, getInitializer } from '@aztec/stdlib/abi';
5
5
  import { PublicKeys } from '@aztec/stdlib/keys';
6
6
 
7
7
  import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
8
+ import { printProfileResult } from '../utils/profiling.js';
8
9
 
9
10
  export async function deploy(
10
11
  wallet: AccountWalletWithSecretKey,
@@ -20,6 +21,7 @@ export async function deploy(
20
21
  universalDeploy: boolean | undefined,
21
22
  wait: boolean,
22
23
  feeOpts: IFeeOpts,
24
+ verbose: boolean,
23
25
  debugLogger: Logger,
24
26
  log: LogFn,
25
27
  logJson: (output: any) => void,
@@ -59,7 +61,12 @@ export async function deploy(
59
61
  return;
60
62
  }
61
63
 
62
- const tx = deploy.send(deployOpts);
64
+ const provenTx = await deploy.prove(deployOpts);
65
+ if (verbose) {
66
+ printProfileResult(provenTx.timings!, log);
67
+ }
68
+
69
+ const tx = provenTx.send();
63
70
 
64
71
  const txHash = await tx.getTxHash();
65
72
  debugLogger.debug(`Deploy tx sent with hash ${txHash}`);
@@ -3,6 +3,7 @@ import { prettyPrintJSON } from '@aztec/cli/cli-utils';
3
3
  import type { LogFn, Logger } from '@aztec/foundation/log';
4
4
 
5
5
  import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
6
+ import { printProfileResult } from '../utils/profiling.js';
6
7
 
7
8
  export async function deployAccount(
8
9
  account: AccountManager,
@@ -11,6 +12,7 @@ export async function deployAccount(
11
12
  publicDeploy: boolean,
12
13
  feeOpts: IFeeOpts,
13
14
  json: boolean,
15
+ verbose: boolean,
14
16
  debugLogger: Logger,
15
17
  log: LogFn,
16
18
  ) {
@@ -43,26 +45,28 @@ export async function deployAccount(
43
45
  let txReceipt;
44
46
 
45
47
  const deployOpts: DeployAccountOptions = {
46
- skipInitialization: false,
47
48
  skipPublicDeployment: !publicDeploy,
48
49
  skipClassRegistration: !registerClass,
49
50
  ...(await feeOpts.toDeployAccountOpts(wallet)),
50
51
  };
51
52
 
53
+ /*
54
+ * This is usually handled by accountManager.deploy(), but we're accessing the lower
55
+ * level method to get gas and timings. That means we have to replicate some of the logic here.
56
+ * In case we're deploying our own account, we need to hijack the payment method for the fee,
57
+ * wrapping it in the one that will make use of the freshly deployed account's
58
+ * entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
59
+ * Also, salt and universalDeploy have to be explicitly provided
60
+ */
61
+ deployOpts.fee =
62
+ !deployOpts?.deployWallet && deployOpts?.fee
63
+ ? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
64
+ : deployOpts?.fee;
65
+
66
+ const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
67
+
52
68
  if (feeOpts.estimateOnly) {
53
- /*
54
- * This is usually handled by accountManager.deploy(), but we're accessing the lower
55
- * level method to get the gas estimates. That means we have to replicate some of the logic here.
56
- * In case we're deploying our own account, we need to hijack the payment method for the fee,
57
- * wrapping it in the one that will make use of the freshly deployed account's
58
- * entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
59
- */
60
- const fee =
61
- !deployOpts?.deployWallet && deployOpts?.fee
62
- ? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
63
- : deployOpts?.fee;
64
- const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
65
- const gas = await deployMethod.estimateGas({ ...deployOpts, fee, universalDeploy: true });
69
+ const gas = await deployMethod.estimateGas({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
66
70
  if (json) {
67
71
  out.fee = {
68
72
  gasLimits: {
@@ -78,7 +82,12 @@ export async function deployAccount(
78
82
  printGasEstimates(feeOpts, gas, log);
79
83
  }
80
84
  } else {
81
- tx = account.deploy(deployOpts);
85
+ const provenTx = await deployMethod.prove({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
86
+ if (verbose) {
87
+ printProfileResult(provenTx.timings!, log);
88
+ }
89
+ tx = provenTx.send();
90
+
82
91
  const txHash = await tx.getTxHash();
83
92
  debugLogger.debug(`Account contract tx sent with hash ${txHash}`);
84
93
  out.txHash = txHash;
package/src/cmds/index.ts CHANGED
@@ -39,6 +39,7 @@ import {
39
39
  createContractAddressOption,
40
40
  createDebugExecutionStepsDirOption,
41
41
  createTypeOption,
42
+ createVerboseOption,
42
43
  integerArgParser,
43
44
  parseGasFees,
44
45
  parsePaymentMethod,
@@ -99,12 +100,14 @@ export function injectCommands(
99
100
  .option('--json', 'Emit output as json')
100
101
  // `options.wait` is default true. Passing `--no-wait` will set it to false.
101
102
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
102
- .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction');
103
+ .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
104
+ .addOption(createVerboseOption());
103
105
 
104
106
  addOptions(createAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
105
107
  const { createAccount } = await import('./create_account.js');
106
108
  const options = command.optsWithGlobals();
107
- const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, rpcUrl, alias, json } = options;
109
+ const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, rpcUrl, alias, json, verbose } =
110
+ options;
108
111
  let { publicKey } = options;
109
112
  if ((type as AccountType) === 'ecdsasecp256r1ssh' && !publicKey) {
110
113
  const identities = await getIdentities();
@@ -132,6 +135,7 @@ export function injectCommands(
132
135
  wait,
133
136
  await FeeOptsWithFeePayer.fromCli(options, client, log, db),
134
137
  json,
138
+ verbose,
135
139
  debugLogger,
136
140
  log,
137
141
  );
@@ -154,12 +158,13 @@ export function injectCommands(
154
158
  '--register-class',
155
159
  'Register the contract class (useful for when the contract class has not been deployed yet).',
156
160
  )
157
- .option('--public-deploy', 'Publicly deploy this account contract (only useful if it contains public functions');
161
+ .option('--public-deploy', 'Publicly deploy this account contract (only useful if it contains public functions')
162
+ .addOption(createVerboseOption());
158
163
 
159
164
  addOptions(deployAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
160
165
  const { deployAccount } = await import('./deploy_account.js');
161
166
  const options = command.optsWithGlobals();
162
- const { rpcUrl, wait, from: parsedFromAddress, json, registerClass, publicDeploy } = options;
167
+ const { rpcUrl, wait, from: parsedFromAddress, json, registerClass, publicDeploy, verbose } = options;
163
168
 
164
169
  const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
165
170
  const account = await createOrRetrieveAccount(client, parsedFromAddress, db);
@@ -171,6 +176,7 @@ export function injectCommands(
171
176
  publicDeploy,
172
177
  await FeeOptsWithFeePayer.fromCli(options, client, log, db),
173
178
  json,
179
+ verbose,
174
180
  debugLogger,
175
181
  log,
176
182
  );
@@ -205,7 +211,8 @@ export function injectCommands(
205
211
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
206
212
  .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
207
213
  .option('--no-class-registration', "Don't register this contract class")
208
- .option('--no-public-deployment', "Don't emit this contract's public bytecode");
214
+ .option('--no-public-deployment', "Don't emit this contract's public bytecode")
215
+ .addOption(createVerboseOption());
209
216
 
210
217
  addOptions(deployCommand, FeeOpts.getOptions()).action(async (artifactPathPromise, _options, command) => {
211
218
  const { deploy } = await import('./deploy.js');
@@ -224,6 +231,7 @@ export function injectCommands(
224
231
  rpcUrl,
225
232
  from: parsedFromAddress,
226
233
  alias,
234
+ verbose,
227
235
  } = options;
228
236
  const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
229
237
  const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
@@ -246,6 +254,7 @@ export function injectCommands(
246
254
  universal,
247
255
  wait,
248
256
  await FeeOpts.fromCli(options, client, log, db),
257
+ verbose,
249
258
  debugLogger,
250
259
  log,
251
260
  logJson(log),
@@ -278,7 +287,8 @@ export function injectCommands(
278
287
  )
279
288
  .addOption(createAccountOption('Alias or address of the account to send the transaction from', !db, db))
280
289
  .option('--no-wait', 'Print transaction hash without waiting for it to be mined')
281
- .option('--no-cancel', 'Do not allow the transaction to be cancelled. This makes for cheaper transactions.');
290
+ .option('--no-cancel', 'Do not allow the transaction to be cancelled. This makes for cheaper transactions.')
291
+ .addOption(createVerboseOption());
282
292
 
283
293
  addOptions(sendCommand, FeeOpts.getOptions()).action(async (functionName, _options, command) => {
284
294
  const { send } = await import('./send.js');
@@ -294,6 +304,7 @@ export function injectCommands(
294
304
  alias,
295
305
  cancel,
296
306
  authWitness: authWitnessArray,
307
+ verbose,
297
308
  } = options;
298
309
  const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
299
310
  const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
@@ -313,6 +324,7 @@ export function injectCommands(
313
324
  cancel,
314
325
  await FeeOpts.fromCli(options, client, log, db),
315
326
  authWitnesses,
327
+ verbose,
316
328
  log,
317
329
  );
318
330
  if (db && sentTx) {
@@ -321,7 +333,7 @@ export function injectCommands(
321
333
  }
322
334
  });
323
335
 
324
- program
336
+ const simulateCommand = program
325
337
  .command('simulate')
326
338
  .description('Simulates the execution of a function on an Aztec contract.')
327
339
  .argument('<functionName>', 'Name of function to simulate')
@@ -334,26 +346,39 @@ export function injectCommands(
334
346
  )
335
347
  .addOption(createAuthwitnessOption('Authorization witness to use for the simulation', !db, db))
336
348
  .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
337
- .action(async (functionName, _options, command) => {
338
- const { simulate } = await import('./simulate.js');
339
- const options = command.optsWithGlobals();
340
- const {
341
- args,
342
- contractArtifact: artifactPathPromise,
343
- contractAddress,
344
- from: parsedFromAddress,
345
- rpcUrl,
346
- secretKey,
347
- authWitness,
348
- } = options;
349
+ .addOption(createVerboseOption());
349
350
 
350
- const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
351
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
352
- const wallet = await account.getWallet();
353
- const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
354
- const authWitnesses = cleanupAuthWitnesses(authWitness);
355
- await simulate(wallet, functionName, args, artifactPath, contractAddress, authWitnesses, log);
356
- });
351
+ addOptions(simulateCommand, FeeOpts.getOptions()).action(async (functionName, _options, command) => {
352
+ const { simulate } = await import('./simulate.js');
353
+ const options = command.optsWithGlobals();
354
+ const {
355
+ args,
356
+ contractArtifact: artifactPathPromise,
357
+ contractAddress,
358
+ from: parsedFromAddress,
359
+ rpcUrl,
360
+ secretKey,
361
+ verbose,
362
+ authWitness,
363
+ } = options;
364
+
365
+ const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
366
+ const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
367
+ const wallet = await account.getWallet();
368
+ const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
369
+ const authWitnesses = cleanupAuthWitnesses(authWitness);
370
+ await simulate(
371
+ wallet,
372
+ functionName,
373
+ args,
374
+ artifactPath,
375
+ contractAddress,
376
+ await FeeOpts.fromCli(options, client, log, db),
377
+ authWitnesses,
378
+ verbose,
379
+ log,
380
+ );
381
+ });
357
382
 
358
383
  const profileCommand = program
359
384
  .command('profile')
@@ -1,70 +1,13 @@
1
1
  import { type AccountWalletWithSecretKey, AuthWitness, type AztecAddress, Contract } from '@aztec/aztec.js';
2
2
  import { prepTx } from '@aztec/cli/utils';
3
3
  import type { LogFn } from '@aztec/foundation/log';
4
- import { type PrivateExecutionStep, serializePrivateExecutionSteps } from '@aztec/stdlib/kernel';
5
- import type { TxProfileResult } from '@aztec/stdlib/tx';
4
+ import { serializePrivateExecutionSteps } from '@aztec/stdlib/kernel';
6
5
 
7
6
  import { promises as fs } from 'fs';
8
7
  import path from 'path';
9
- import { format } from 'util';
10
8
 
11
9
  import type { IFeeOpts } from '../utils/options/fees.js';
12
-
13
- function printProfileResult(result: TxProfileResult, log: LogFn) {
14
- log(format('\nPer circuit breakdown:\n'));
15
- log(
16
- format(
17
- ' ',
18
- 'Function name'.padEnd(50),
19
- 'Time'.padStart(13).padEnd(15),
20
- 'Gates'.padStart(13).padEnd(15),
21
- 'Subtotal'.padStart(13).padEnd(15),
22
- ),
23
- );
24
- log(format(''.padEnd(50 + 15 + 15 + 15 + 15, '-')));
25
- let acc = 0;
26
- let biggest: PrivateExecutionStep = result.executionSteps[0] ?? 0;
27
-
28
- result.executionSteps.forEach(r => {
29
- if (r.gateCount! > biggest.gateCount!) {
30
- biggest = r;
31
- }
32
- acc += r.gateCount!;
33
- log(
34
- format(
35
- ' ',
36
- r.functionName.padEnd(50),
37
- `${r.timings.witgen.toFixed(2)}ms`.padStart(13).padEnd(15),
38
- r.gateCount!.toLocaleString().padStart(13).padEnd(15),
39
- acc.toLocaleString().padStart(15),
40
- ),
41
- );
42
- });
43
- log(
44
- format(
45
- '\nTotal gates:',
46
- acc.toLocaleString(),
47
- `(Biggest circuit: ${biggest.functionName} -> ${biggest.gateCount!.toLocaleString()})`,
48
- ),
49
- );
50
-
51
- log(format('\nSync time:'.padEnd(25), `${result.timings.sync?.toFixed(2)}ms`.padStart(16)));
52
- log(
53
- format(
54
- 'Total simulation time:'.padEnd(25),
55
- `${result.timings.perFunction.reduce((acc, { time }) => acc + time, 0).toFixed(2)}ms`.padStart(15),
56
- ),
57
- );
58
- log(format('Proving time:'.padEnd(25), `${result.timings.proving?.toFixed(2)}ms`.padStart(15)));
59
- log(
60
- format(
61
- 'Total time:'.padEnd(25),
62
- `${result.timings.total.toFixed(2)}ms`.padStart(15),
63
- `(${result.timings.unaccounted.toFixed(2)}ms unaccounted)`,
64
- ),
65
- );
66
- log('\n');
67
- }
10
+ import { printProfileResult } from '../utils/profiling.js';
68
11
 
69
12
  export async function profile(
70
13
  wallet: AccountWalletWithSecretKey,
@@ -88,7 +31,7 @@ export async function profile(
88
31
  authWitnesses,
89
32
  skipProofGeneration: false,
90
33
  });
91
- printProfileResult(result, log);
34
+ printProfileResult(result.timings, log, result.executionSteps);
92
35
  if (debugOutputPath) {
93
36
  const ivcInputsPath = path.join(debugOutputPath, 'ivc-inputs.msgpack');
94
37
  log(`Debug output written to ${ivcInputsPath}.`);
@@ -20,7 +20,7 @@ export async function registerContract(
20
20
  publicKeys?: PublicKeys,
21
21
  rawArgs?: any[],
22
22
  salt?: Fr,
23
- deployer?: AztecAddress | undefined,
23
+ deployer?: AztecAddress,
24
24
  ) {
25
25
  const contractArtifact = await getContractArtifact(artifactPath, log);
26
26
  const hasInitializer = getAllFunctionAbis(contractArtifact).some(fn => fn.isInitializer);
package/src/cmds/send.ts CHANGED
@@ -11,6 +11,7 @@ import type { LogFn } from '@aztec/foundation/log';
11
11
  import { GasSettings } from '@aztec/stdlib/gas';
12
12
 
13
13
  import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
14
+ import { printProfileResult } from '../utils/profiling.js';
14
15
 
15
16
  export async function send(
16
17
  wallet: AccountWalletWithSecretKey,
@@ -22,6 +23,7 @@ export async function send(
22
23
  cancellable: boolean,
23
24
  feeOpts: IFeeOpts,
24
25
  authWitnesses: AuthWitness[],
26
+ verbose: boolean,
25
27
  log: LogFn,
26
28
  ) {
27
29
  const { functionArgs, contractArtifact } = await prepTx(contractArtifactPath, functionName, functionArgsIn, log);
@@ -45,7 +47,12 @@ export async function send(
45
47
  return;
46
48
  }
47
49
 
48
- const tx = call.send(sendOptions);
50
+ const provenTx = await call.prove(sendOptions);
51
+ if (verbose) {
52
+ printProfileResult(provenTx.timings!, log);
53
+ }
54
+
55
+ const tx = provenTx.send();
49
56
  const txHash = await tx.getTxHash();
50
57
  log(`\nTransaction hash: ${txHash.toString()}`);
51
58
  if (wait) {
@@ -4,19 +4,31 @@ import type { LogFn } from '@aztec/foundation/log';
4
4
 
5
5
  import { format } from 'util';
6
6
 
7
+ import type { IFeeOpts } from '../utils/options/fees.js';
8
+ import { printProfileResult } from '../utils/profiling.js';
9
+
7
10
  export async function simulate(
8
11
  wallet: AccountWalletWithSecretKey,
9
12
  functionName: string,
10
13
  functionArgsIn: any[],
11
14
  contractArtifactPath: string,
12
15
  contractAddress: AztecAddress,
16
+ feeOpts: IFeeOpts,
13
17
  authWitnesses: AuthWitness[],
18
+ verbose: boolean,
14
19
  log: LogFn,
15
20
  ) {
16
21
  const { functionArgs, contractArtifact } = await prepTx(contractArtifactPath, functionName, functionArgsIn, log);
17
22
 
18
23
  const contract = await Contract.at(contractAddress, contractArtifact, wallet);
19
24
  const call = contract.methods[functionName](...functionArgs);
20
- const result = await call.simulate({ authWitnesses });
21
- log(format('\nSimulation result: ', result, '\n'));
25
+ const simulationResult = await call.simulate({
26
+ ...(await feeOpts.toSendOpts(wallet)),
27
+ authWitnesses,
28
+ includeMetadata: true,
29
+ });
30
+ if (verbose) {
31
+ printProfileResult(simulationResult.meta.timings!, log);
32
+ }
33
+ log(format('\nSimulation result: ', simulationResult.result, '\n'));
22
34
  }
@@ -163,7 +163,7 @@ export class WalletDB {
163
163
  tryRetrieveAlias(arg: string) {
164
164
  try {
165
165
  return this.retrieveAliasFromCache(arg);
166
- } catch (e) {
166
+ } catch {
167
167
  return arg;
168
168
  }
169
169
  }