@aztec/cli-wallet 0.0.0-test.1 → 0.0.1-commit.b655e406

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 (105) hide show
  1. package/README.md +30 -0
  2. package/dest/bin/index.js +48 -26
  3. package/dest/cmds/authorize_action.d.ts +3 -2
  4. package/dest/cmds/authorize_action.d.ts.map +1 -1
  5. package/dest/cmds/authorize_action.js +8 -4
  6. package/dest/cmds/bridge_fee_juice.d.ts +2 -2
  7. package/dest/cmds/bridge_fee_juice.d.ts.map +1 -1
  8. package/dest/cmds/bridge_fee_juice.js +8 -7
  9. package/dest/cmds/check_tx.d.ts +4 -2
  10. package/dest/cmds/check_tx.d.ts.map +1 -1
  11. package/dest/cmds/check_tx.js +145 -6
  12. package/dest/cmds/create_account.d.ts +6 -5
  13. package/dest/cmds/create_account.d.ts.map +1 -1
  14. package/dest/cmds/create_account.js +46 -27
  15. package/dest/cmds/create_authwit.d.ts +3 -2
  16. package/dest/cmds/create_authwit.d.ts.map +1 -1
  17. package/dest/cmds/create_authwit.js +5 -5
  18. package/dest/cmds/deploy.d.ts +6 -3
  19. package/dest/cmds/deploy.d.ts.map +1 -1
  20. package/dest/cmds/deploy.js +71 -54
  21. package/dest/cmds/deploy_account.d.ts +5 -7
  22. package/dest/cmds/deploy_account.d.ts.map +1 -1
  23. package/dest/cmds/deploy_account.js +46 -29
  24. package/dest/cmds/import_test_accounts.d.ts +2 -2
  25. package/dest/cmds/import_test_accounts.d.ts.map +1 -1
  26. package/dest/cmds/import_test_accounts.js +6 -9
  27. package/dest/cmds/index.d.ts +2 -2
  28. package/dest/cmds/index.d.ts.map +1 -1
  29. package/dest/cmds/index.js +83 -115
  30. package/dest/cmds/profile.d.ts +8 -0
  31. package/dest/cmds/profile.d.ts.map +1 -0
  32. package/dest/cmds/profile.js +28 -0
  33. package/dest/cmds/register_contract.d.ts +6 -2
  34. package/dest/cmds/register_contract.d.ts.map +1 -1
  35. package/dest/cmds/register_contract.js +20 -7
  36. package/dest/cmds/register_sender.d.ts +3 -2
  37. package/dest/cmds/register_sender.d.ts.map +1 -1
  38. package/dest/cmds/send.d.ts +7 -8
  39. package/dest/cmds/send.d.ts.map +1 -1
  40. package/dest/cmds/send.js +31 -20
  41. package/dest/cmds/simulate.d.ts +6 -2
  42. package/dest/cmds/simulate.d.ts.map +1 -1
  43. package/dest/cmds/simulate.js +25 -19
  44. package/dest/storage/wallet_db.d.ts +4 -16
  45. package/dest/storage/wallet_db.d.ts.map +1 -1
  46. package/dest/storage/wallet_db.js +2 -23
  47. package/dest/utils/authorizations.d.ts +6 -0
  48. package/dest/utils/authorizations.d.ts.map +1 -0
  49. package/dest/utils/authorizations.js +28 -0
  50. package/dest/utils/cli_wallet_and_node_wrapper.d.ts +12 -0
  51. package/dest/utils/cli_wallet_and_node_wrapper.d.ts.map +1 -0
  52. package/dest/utils/cli_wallet_and_node_wrapper.js +25 -0
  53. package/dest/utils/ecdsa.d.ts +0 -2
  54. package/dest/utils/ecdsa.d.ts.map +1 -1
  55. package/dest/utils/options/fees.d.ts +20 -27
  56. package/dest/utils/options/fees.d.ts.map +1 -1
  57. package/dest/utils/options/fees.js +85 -144
  58. package/dest/utils/options/options.d.ts +8 -4
  59. package/dest/utils/options/options.d.ts.map +1 -1
  60. package/dest/utils/options/options.js +26 -14
  61. package/dest/utils/profiling.d.ts +5 -0
  62. package/dest/utils/profiling.d.ts.map +1 -0
  63. package/dest/utils/profiling.js +60 -0
  64. package/dest/utils/wallet.d.ts +35 -0
  65. package/dest/utils/wallet.d.ts.map +1 -0
  66. package/dest/utils/wallet.js +193 -0
  67. package/package.json +24 -20
  68. package/src/bin/index.ts +56 -32
  69. package/src/cmds/authorize_action.ts +15 -4
  70. package/src/cmds/bridge_fee_juice.ts +14 -11
  71. package/src/cmds/check_tx.ts +182 -5
  72. package/src/cmds/create_account.ts +55 -32
  73. package/src/cmds/create_authwit.ts +8 -4
  74. package/src/cmds/deploy.ts +79 -62
  75. package/src/cmds/deploy_account.ts +57 -28
  76. package/src/cmds/import_test_accounts.ts +7 -11
  77. package/src/cmds/index.ts +256 -220
  78. package/src/cmds/profile.ts +48 -0
  79. package/src/cmds/register_contract.ts +28 -5
  80. package/src/cmds/register_sender.ts +3 -2
  81. package/src/cmds/send.ts +31 -17
  82. package/src/cmds/simulate.ts +39 -23
  83. package/src/storage/wallet_db.ts +3 -31
  84. package/src/utils/authorizations.ts +51 -0
  85. package/src/utils/cli_wallet_and_node_wrapper.ts +35 -0
  86. package/src/utils/options/fees.ts +134 -206
  87. package/src/utils/options/options.ts +41 -19
  88. package/src/utils/profiling.ts +158 -0
  89. package/src/utils/wallet.ts +264 -0
  90. package/dest/cmds/add_authwit.d.ts +0 -4
  91. package/dest/cmds/add_authwit.d.ts.map +0 -1
  92. package/dest/cmds/add_authwit.js +0 -4
  93. package/dest/cmds/cancel_tx.d.ts +0 -11
  94. package/dest/cmds/cancel_tx.d.ts.map +0 -1
  95. package/dest/cmds/cancel_tx.js +0 -38
  96. package/dest/utils/accounts.d.ts +0 -11
  97. package/dest/utils/accounts.d.ts.map +0 -1
  98. package/dest/utils/accounts.js +0 -87
  99. package/dest/utils/pxe_wrapper.d.ts +0 -10
  100. package/dest/utils/pxe_wrapper.d.ts.map +0 -1
  101. package/dest/utils/pxe_wrapper.js +0 -21
  102. package/src/cmds/add_authwit.ts +0 -13
  103. package/src/cmds/cancel_tx.ts +0 -62
  104. package/src/utils/accounts.ts +0 -102
  105. package/src/utils/pxe_wrapper.ts +0 -26
package/src/cmds/index.ts CHANGED
@@ -1,71 +1,63 @@
1
1
  import { getIdentities } from '@aztec/accounts/utils';
2
- import { createCompatibleClient } from '@aztec/aztec.js/rpc';
3
- import { TxHash } from '@aztec/aztec.js/tx_hash';
2
+ import { TxHash } from '@aztec/aztec.js/tx';
4
3
  import {
5
4
  ETHEREUM_HOSTS,
6
5
  PRIVATE_KEY,
7
6
  addOptions,
8
7
  createSecretKeyOption,
9
8
  l1ChainIdOption,
10
- logJson,
11
9
  parseBigint,
12
10
  parseFieldFromHexString,
13
11
  parsePublicKey,
14
- pxeOption,
15
12
  } from '@aztec/cli/utils';
13
+ import { randomBytes } from '@aztec/foundation/crypto';
16
14
  import type { LogFn, Logger } from '@aztec/foundation/log';
17
- import { GasFees } from '@aztec/stdlib/gas';
18
- import { createAztecNodeClient } from '@aztec/stdlib/interfaces/client';
19
15
 
20
16
  import { type Command, Option } from 'commander';
21
17
  import inquirer from 'inquirer';
22
18
 
23
19
  import type { WalletDB } from '../storage/wallet_db.js';
24
- import { type AccountType, addScopeToWallet, createOrRetrieveAccount, getWalletWithScopes } from '../utils/accounts.js';
25
- import { FeeOpts, FeeOptsWithFeePayer } from '../utils/options/fees.js';
20
+ import type { CliWalletAndNodeWrapper } from '../utils/cli_wallet_and_node_wrapper.js';
26
21
  import {
27
22
  ARTIFACT_DESCRIPTION,
23
+ CLIFeeArgs,
28
24
  aliasedAddressParser,
29
- aliasedAuthWitParser,
30
25
  aliasedSecretKeyParser,
31
26
  aliasedTxHashParser,
32
27
  artifactPathFromPromiseOrAlias,
33
28
  artifactPathParser,
29
+ cleanupAuthWitnesses,
34
30
  createAccountOption,
35
31
  createAliasOption,
36
32
  createArgsOption,
37
33
  createArtifactOption,
34
+ createAuthwitnessOption,
38
35
  createContractAddressOption,
39
- createProfileOption,
36
+ createDebugExecutionStepsDirOption,
40
37
  createTypeOption,
38
+ createVerboseOption,
41
39
  integerArgParser,
42
- parseGasFees,
43
- parsePaymentMethod,
44
40
  } from '../utils/options/index.js';
45
- import type { PXEWrapper } from '../utils/pxe_wrapper.js';
41
+ import type { AccountType } from '../utils/wallet.js';
46
42
 
43
+ // TODO: This function is only used in 1 place so we could just inline this
47
44
  export function injectCommands(
48
45
  program: Command,
49
46
  log: LogFn,
50
47
  debugLogger: Logger,
51
- db?: WalletDB,
52
- pxeWrapper?: PXEWrapper,
48
+ walletAndNodeWrapper: CliWalletAndNodeWrapper,
49
+ db: WalletDB,
53
50
  ) {
54
51
  program
55
52
  .command('import-test-accounts')
56
53
  .description('Import test accounts from pxe.')
57
- .addOption(pxeOption)
58
54
  .option('--json', 'Emit output as json')
59
55
  .action(async options => {
60
- if (!db) {
61
- throw new Error(`A db is required to store the imported test accounts.`);
62
- }
63
-
56
+ const { json } = options;
57
+ const wallet = walletAndNodeWrapper.wallet;
64
58
  const { importTestAccounts } = await import('./import_test_accounts.js');
65
- const { rpcUrl, json } = options;
66
59
 
67
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
68
- await importTestAccounts(client, db, json, log);
60
+ await importTestAccounts(wallet, db, json, log);
69
61
  });
70
62
 
71
63
  const createAccountCommand = program
@@ -74,16 +66,23 @@ export function injectCommands(
74
66
  'Creates an aztec account that can be used for sending transactions. Registers the account on the PXE and deploys an account contract. Uses a Schnorr single-key account which uses the same key for encryption and authentication (not secure for production usage).',
75
67
  )
76
68
  .summary('Creates an aztec account that can be used for sending transactions.')
69
+ .addOption(createAccountOption('Alias or address of the account performing the deployment', !db, db))
77
70
  .option(
78
71
  '--skip-initialization',
79
72
  'Skip initializing the account contract. Useful for publicly deploying an existing account.',
80
73
  )
81
- .option('--public-deploy', 'Publicly deploys the account and registers the class if needed.')
74
+ .option(
75
+ '--public-deploy',
76
+ 'Publishes the account contract instance (and the class, if needed). Needed if the contract contains public functions.',
77
+ )
78
+ .option(
79
+ '--register-class',
80
+ 'Register the contract class (useful for when the contract class has not been deployed yet).',
81
+ )
82
82
  .option(
83
83
  '-p, --public-key <string>',
84
84
  'Public key that identifies a private signing key stored outside of the wallet. Used for ECDSA SSH accounts over the secp256r1 curve.',
85
85
  )
86
- .addOption(pxeOption)
87
86
  .addOption(
88
87
  createSecretKeyOption('Secret key for account. Uses random by default.', false, sk =>
89
88
  aliasedSecretKeyParser(sk, db),
@@ -93,17 +92,30 @@ export function injectCommands(
93
92
  .addOption(createTypeOption(true))
94
93
  .option(
95
94
  '--register-only',
96
- 'Just register the account on the PXE. Do not deploy or initialize the account contract.',
95
+ 'Just register the account on the Wallet. Do not deploy or initialize the account contract.',
97
96
  )
98
97
  .option('--json', 'Emit output as json')
99
98
  // `options.wait` is default true. Passing `--no-wait` will set it to false.
100
99
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
101
- .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction');
100
+ .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
101
+ .addOption(createVerboseOption());
102
102
 
103
- addOptions(createAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
103
+ addOptions(createAccountCommand, CLIFeeArgs.getOptions()).action(async (_options, command) => {
104
104
  const { createAccount } = await import('./create_account.js');
105
105
  const options = command.optsWithGlobals();
106
- const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, rpcUrl, alias, json } = options;
106
+ const {
107
+ type,
108
+ from: parsedFromAddress,
109
+ secretKey,
110
+ wait,
111
+ registerOnly,
112
+ skipInitialization,
113
+ publicDeploy,
114
+ registerClass,
115
+ alias,
116
+ json,
117
+ verbose,
118
+ } = options;
107
119
  let { publicKey } = options;
108
120
  if ((type as AccountType) === 'ecdsasecp256r1ssh' && !publicKey) {
109
121
  const identities = await getIdentities();
@@ -118,19 +130,24 @@ export function injectCommands(
118
130
  ]);
119
131
  publicKey = answers.identity.split(' ')[1];
120
132
  }
121
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
133
+
134
+ const { wallet, node } = walletAndNodeWrapper;
122
135
  const accountCreationResult = await createAccount(
123
- client,
136
+ wallet,
137
+ node,
124
138
  type,
125
139
  secretKey,
126
140
  publicKey,
127
141
  alias,
142
+ parsedFromAddress,
128
143
  registerOnly,
129
144
  skipInitialization,
130
145
  publicDeploy,
146
+ registerClass,
131
147
  wait,
132
- await FeeOptsWithFeePayer.fromCli(options, client, log, db),
148
+ CLIFeeArgs.parse(options, log, db),
133
149
  json,
150
+ verbose,
134
151
  debugLogger,
135
152
  log,
136
153
  );
@@ -143,26 +160,47 @@ export function injectCommands(
143
160
  const deployAccountCommand = program
144
161
  .command('deploy-account')
145
162
  .description('Deploys an already registered aztec account that can be used for sending transactions.')
146
- .addOption(createAccountOption('Alias or address of the account to deploy', !db, db))
147
- .addOption(pxeOption)
163
+ .argument('<address>', 'The address of the contract to register', address =>
164
+ aliasedAddressParser('accounts', address, db),
165
+ )
166
+ .addOption(createAccountOption('Alias or address of the account performing the deployment', !db, db))
148
167
  .option('--json', 'Emit output as json')
149
168
  // `options.wait` is default true. Passing `--no-wait` will set it to false.
150
169
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
151
- .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction');
170
+ .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
171
+ .option(
172
+ '--register-class',
173
+ 'Register the contract class (useful for when the contract class has not been deployed yet).',
174
+ )
175
+ .option(
176
+ '--public-deploy',
177
+ 'Publishes the account contract instance (and the class, if needed). Needed if the contract contains public functions.',
178
+ )
179
+ .option(
180
+ '--skip-initialization',
181
+ 'Skip initializing the account contract. Useful for publicly deploying an existing account.',
182
+ )
183
+ .addOption(createVerboseOption());
152
184
 
153
- addOptions(deployAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
185
+ addOptions(deployAccountCommand, CLIFeeArgs.getOptions()).action(async (parsedAccount, _options, command) => {
154
186
  const { deployAccount } = await import('./deploy_account.js');
155
187
  const options = command.optsWithGlobals();
156
- const { rpcUrl, wait, from: parsedFromAddress, json } = options;
188
+ const { wait, from: parsedFromAddress, json, registerClass, skipInitialization, publicDeploy, verbose } = options;
157
189
 
158
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
159
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db);
190
+ const { wallet, node } = walletAndNodeWrapper;
160
191
 
161
192
  await deployAccount(
162
- account,
193
+ wallet,
194
+ node,
195
+ parsedAccount,
163
196
  wait,
164
- await FeeOptsWithFeePayer.fromCli(options, client, log, db),
197
+ parsedFromAddress,
198
+ registerClass,
199
+ publicDeploy,
200
+ skipInitialization,
201
+ CLIFeeArgs.parse(options, log, db),
165
202
  json,
203
+ verbose,
166
204
  debugLogger,
167
205
  log,
168
206
  );
@@ -185,11 +223,7 @@ export function injectCommands(
185
223
  parseFieldFromHexString,
186
224
  )
187
225
  .option('--universal', 'Do not mix the sender address into the deployment.')
188
- .addOption(pxeOption)
189
226
  .addOption(createArgsOption(true, db))
190
- .addOption(
191
- createSecretKeyOption("The sender's secret key", !db, sk => aliasedSecretKeyParser(sk, db)).conflicts('account'),
192
- )
193
227
  .addOption(createAccountOption('Alias or address of the account to deploy from', !db, db))
194
228
  .addOption(createAliasOption('Alias for the contract. Used for easy reference subsequent commands.', !db))
195
229
  .option('--json', 'Emit output as json')
@@ -197,9 +231,16 @@ export function injectCommands(
197
231
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
198
232
  .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
199
233
  .option('--no-class-registration', "Don't register this contract class")
200
- .option('--no-public-deployment', "Don't emit this contract's public bytecode");
234
+ .option('--no-public-deployment', "Don't emit this contract's public bytecode")
235
+ .addOption(
236
+ new Option(
237
+ '--timeout <number>',
238
+ 'The amount of time in seconds to wait for the deployment to post to L2',
239
+ ).conflicts('wait'),
240
+ )
241
+ .addOption(createVerboseOption());
201
242
 
202
- addOptions(deployCommand, FeeOpts.getOptions()).action(async (artifactPathPromise, _options, command) => {
243
+ addOptions(deployCommand, CLIFeeArgs.getOptions()).action(async (artifactPathPromise, _options, command) => {
203
244
  const { deploy } = await import('./deploy.js');
204
245
  const options = command.optsWithGlobals();
205
246
  const {
@@ -208,25 +249,25 @@ export function injectCommands(
208
249
  args,
209
250
  salt,
210
251
  wait,
211
- secretKey,
212
252
  classRegistration,
213
253
  init,
214
254
  publicDeployment,
215
255
  universal,
216
- rpcUrl,
217
256
  from: parsedFromAddress,
218
257
  alias,
258
+ timeout,
259
+ verbose,
219
260
  } = options;
220
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
221
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
222
- const wallet = await getWalletWithScopes(account, db);
261
+
262
+ const { wallet, node } = walletAndNodeWrapper;
223
263
  const artifactPath = await artifactPathPromise;
224
264
 
225
- debugLogger.info(`Using wallet with address ${wallet.getCompleteAddress().address.toString()}`);
265
+ debugLogger.info(`Using wallet with address ${parsedFromAddress.toString()}`);
226
266
 
227
267
  const address = await deploy(
228
- client,
229
268
  wallet,
269
+ node,
270
+ universal ? undefined : parsedFromAddress,
230
271
  artifactPath,
231
272
  json,
232
273
  publicKey,
@@ -236,12 +277,12 @@ export function injectCommands(
236
277
  !publicDeployment,
237
278
  !classRegistration,
238
279
  typeof init === 'string' ? false : init,
239
- universal,
240
280
  wait,
241
- await FeeOpts.fromCli(options, client, log, db),
281
+ CLIFeeArgs.parse(options, log, db),
282
+ timeout,
283
+ verbose,
242
284
  debugLogger,
243
285
  log,
244
- logJson(log),
245
286
  );
246
287
  if (db && address) {
247
288
  await db.storeContract(address, artifactPath, log, alias);
@@ -252,7 +293,6 @@ export function injectCommands(
252
293
  .command('send')
253
294
  .description('Calls a function on an Aztec contract.')
254
295
  .argument('<functionName>', 'Name of function to execute')
255
- .addOption(pxeOption)
256
296
  .addOption(createArgsOption(false, db))
257
297
  .addOption(createArtifactOption(db))
258
298
  .addOption(createContractAddressOption(db))
@@ -260,13 +300,17 @@ export function injectCommands(
260
300
  createAliasOption('Alias for the transaction hash. Used for easy reference in subsequent commands.', !db),
261
301
  )
262
302
  .addOption(
263
- createSecretKeyOption("The sender's secret key", !db, sk => aliasedSecretKeyParser(sk, db)).conflicts('account'),
303
+ createAuthwitnessOption(
304
+ 'Authorization witness to use for the transaction. If using multiple, pass a comma separated string',
305
+ !db,
306
+ db,
307
+ ),
264
308
  )
265
309
  .addOption(createAccountOption('Alias or address of the account to send the transaction from', !db, db))
266
310
  .option('--no-wait', 'Print transaction hash without waiting for it to be mined')
267
- .option('--no-cancel', 'Do not allow the transaction to be cancelled. This makes for cheaper transactions.');
311
+ .addOption(createVerboseOption());
268
312
 
269
- addOptions(sendCommand, FeeOpts.getOptions()).action(async (functionName, _options, command) => {
313
+ addOptions(sendCommand, CLIFeeArgs.getOptions()).action(async (functionName, _options, command) => {
270
314
  const { send } = await import('./send.js');
271
315
  const options = command.optsWithGlobals();
272
316
  const {
@@ -275,67 +319,124 @@ export function injectCommands(
275
319
  contractAddress,
276
320
  from: parsedFromAddress,
277
321
  wait,
278
- rpcUrl,
279
- secretKey,
280
322
  alias,
281
- cancel,
323
+ authWitness: authWitnessArray,
324
+ verbose,
282
325
  } = options;
283
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
284
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
285
- const wallet = await getWalletWithScopes(account, db);
326
+
327
+ const { wallet, node } = walletAndNodeWrapper;
286
328
  const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
287
329
 
288
- debugLogger.info(`Using wallet with address ${wallet.getCompleteAddress().address.toString()}`);
330
+ debugLogger.info(`Using wallet with address ${parsedFromAddress.toString()}`);
289
331
 
332
+ const authWitnesses = cleanupAuthWitnesses(authWitnessArray);
290
333
  const sentTx = await send(
291
334
  wallet,
335
+ node,
336
+ parsedFromAddress,
292
337
  functionName,
293
338
  args,
294
339
  artifactPath,
295
340
  contractAddress,
296
341
  wait,
297
- cancel,
298
- await FeeOpts.fromCli(options, client, log, db),
342
+ alias,
343
+ CLIFeeArgs.parse(options, log, db),
344
+ authWitnesses,
345
+ verbose,
299
346
  log,
300
347
  );
301
348
  if (db && sentTx) {
302
- const txAlias = alias ? alias : `${functionName}-${sentTx.nonce.toString().slice(-4)}`;
349
+ const txAlias = alias ? alias : `${functionName}-${randomBytes(16).toString()}`;
303
350
  await db.storeTx(sentTx, log, txAlias);
304
351
  }
305
352
  });
306
353
 
307
- program
354
+ const simulateCommand = program
308
355
  .command('simulate')
309
356
  .description('Simulates the execution of a function on an Aztec contract.')
310
357
  .argument('<functionName>', 'Name of function to simulate')
311
- .addOption(pxeOption)
312
358
  .addOption(createArgsOption(false, db))
313
359
  .addOption(createContractAddressOption(db))
314
360
  .addOption(createArtifactOption(db))
315
361
  .addOption(
316
362
  createSecretKeyOption("The sender's secret key", !db, sk => aliasedSecretKeyParser(sk, db)).conflicts('account'),
317
363
  )
364
+ .addOption(createAuthwitnessOption('Authorization witness to use for the simulation', !db, db))
318
365
  .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
319
- .addOption(createProfileOption())
320
- .action(async (functionName, _options, command) => {
321
- const { simulate } = await import('./simulate.js');
322
- const options = command.optsWithGlobals();
323
- const {
324
- args,
325
- contractArtifact: artifactPathPromise,
326
- contractAddress,
327
- from: parsedFromAddress,
328
- rpcUrl,
329
- secretKey,
330
- profile,
331
- } = options;
332
-
333
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
334
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
335
- const wallet = await getWalletWithScopes(account, db);
336
- const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
337
- await simulate(wallet, functionName, args, artifactPath, contractAddress, profile, log);
338
- });
366
+ .addOption(createVerboseOption());
367
+
368
+ addOptions(simulateCommand, CLIFeeArgs.getOptions()).action(async (functionName, _options, command) => {
369
+ const { simulate } = await import('./simulate.js');
370
+ const options = command.optsWithGlobals();
371
+ const {
372
+ args,
373
+ contractArtifact: artifactPathPromise,
374
+ contractAddress,
375
+ from: parsedFromAddress,
376
+ verbose,
377
+ authWitness,
378
+ } = options;
379
+
380
+ const { wallet, node } = walletAndNodeWrapper;
381
+
382
+ const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
383
+ const authWitnesses = cleanupAuthWitnesses(authWitness);
384
+ await simulate(
385
+ wallet,
386
+ node,
387
+ parsedFromAddress,
388
+ functionName,
389
+ args,
390
+ artifactPath,
391
+ contractAddress,
392
+ CLIFeeArgs.parse(options, log, db),
393
+ authWitnesses,
394
+ verbose,
395
+ log,
396
+ );
397
+ });
398
+
399
+ const profileCommand = program
400
+ .command('profile')
401
+ .description('Profiles a private function by counting the unconditional operations in its execution steps')
402
+ .argument('<functionName>', 'Name of function to simulate')
403
+ .addOption(createArgsOption(false, db))
404
+ .addOption(createContractAddressOption(db))
405
+ .addOption(createArtifactOption(db))
406
+ .addOption(createDebugExecutionStepsDirOption())
407
+ .addOption(createAuthwitnessOption('Authorization witness to use for the simulation', !db, db))
408
+ .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db));
409
+
410
+ addOptions(profileCommand, CLIFeeArgs.getOptions()).action(async (functionName, _options, command) => {
411
+ const { profile } = await import('./profile.js');
412
+ const options = command.optsWithGlobals();
413
+ const {
414
+ args,
415
+ contractArtifact: artifactPathPromise,
416
+ contractAddress,
417
+ from: parsedFromAddress,
418
+ debugExecutionStepsDir,
419
+ authWitness,
420
+ } = options;
421
+
422
+ const { wallet, node } = walletAndNodeWrapper;
423
+
424
+ const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
425
+ const authWitnesses = cleanupAuthWitnesses(authWitness);
426
+ await profile(
427
+ wallet,
428
+ node,
429
+ parsedFromAddress,
430
+ functionName,
431
+ args,
432
+ artifactPath,
433
+ contractAddress,
434
+ debugExecutionStepsDir,
435
+ CLIFeeArgs.parse(options, log, db),
436
+ authWitnesses,
437
+ log,
438
+ );
439
+ });
339
440
 
340
441
  program
341
442
  .command('bridge-fee-juice')
@@ -357,12 +458,11 @@ export function injectCommands(
357
458
  )
358
459
  .option('--mint', 'Mint the tokens on L1', false)
359
460
  .option('--l1-private-key <string>', 'The private key to the eth account bridging', PRIVATE_KEY)
360
- .addOption(pxeOption)
361
461
  .addOption(l1ChainIdOption)
362
462
  .option('--json', 'Output the claim in JSON format')
363
463
  // `options.wait` is default true. Passing `--no-wait` will set it to false.
364
464
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
365
- .option('--no-wait', 'Wait for the brigded funds to be available in L2, polling every 60 seconds')
465
+ .option('--no-wait', 'Wait for the bridged funds to be available in L2, polling every 60 seconds')
366
466
  .addOption(
367
467
  new Option('--interval <number>', 'The polling interval in seconds for the bridged funds')
368
468
  .default('60')
@@ -370,13 +470,12 @@ export function injectCommands(
370
470
  )
371
471
  .action(async (amount, recipient, options) => {
372
472
  const { bridgeL1FeeJuice } = await import('./bridge_fee_juice.js');
373
- const { rpcUrl, l1ChainId, l1RpcUrls, l1PrivateKey, mnemonic, mint, json, wait, interval: intervalS } = options;
374
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
473
+ const { l1ChainId, l1RpcUrls, l1PrivateKey, mnemonic, mint, json, wait, interval: intervalS } = options;
375
474
 
376
475
  const [secret, messageLeafIndex] = await bridgeL1FeeJuice(
377
476
  amount,
378
477
  recipient,
379
- client,
478
+ walletAndNodeWrapper.node,
380
479
  l1RpcUrls,
381
480
  l1ChainId,
382
481
  l1PrivateKey,
@@ -402,13 +501,9 @@ export function injectCommands(
402
501
  .argument('<caller>', 'Account to be authorized to perform the action', address =>
403
502
  aliasedAddressParser('accounts', address, db),
404
503
  )
405
- .addOption(pxeOption)
406
504
  .addOption(createArgsOption(false, db))
407
505
  .addOption(createContractAddressOption(db))
408
506
  .addOption(createArtifactOption(db))
409
- .addOption(
410
- createSecretKeyOption("The sender's secret key", !db, sk => aliasedSecretKeyParser(sk, db)).conflicts('account'),
411
- )
412
507
  .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
413
508
  .addOption(
414
509
  createAliasOption('Alias for the authorization witness. Used for easy reference in subsequent commands.', !db),
@@ -416,21 +511,20 @@ export function injectCommands(
416
511
  .action(async (functionName, caller, _options, command) => {
417
512
  const { createAuthwit } = await import('./create_authwit.js');
418
513
  const options = command.optsWithGlobals();
419
- const {
514
+ const { args, contractArtifact: artifactPathPromise, contractAddress, from: parsedFromAddress, alias } = options;
515
+
516
+ const wallet = walletAndNodeWrapper.wallet;
517
+ const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
518
+ const witness = await createAuthwit(
519
+ wallet,
520
+ parsedFromAddress,
521
+ functionName,
522
+ caller,
420
523
  args,
421
- contractArtifact: artifactPathPromise,
524
+ artifactPath,
422
525
  contractAddress,
423
- from: parsedFromAddress,
424
- rpcUrl,
425
- secretKey,
426
- alias,
427
- } = options;
428
-
429
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
430
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
431
- const wallet = await getWalletWithScopes(account, db);
432
- const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
433
- const witness = await createAuthwit(wallet, functionName, caller, args, artifactPath, contractAddress, log);
526
+ log,
527
+ );
434
528
 
435
529
  if (db) {
436
530
  await db.storeAuthwitness(witness, log, alias);
@@ -446,67 +540,25 @@ export function injectCommands(
446
540
  .argument('<caller>', 'Account to be authorized to perform the action', address =>
447
541
  aliasedAddressParser('accounts', address, db),
448
542
  )
449
- .addOption(pxeOption)
450
543
  .addOption(createArgsOption(false, db))
451
544
  .addOption(createContractAddressOption(db))
452
545
  .addOption(createArtifactOption(db))
453
- .addOption(
454
- createSecretKeyOption("The sender's secret key", !db, sk => aliasedSecretKeyParser(sk, db)).conflicts('account'),
455
- )
456
546
  .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
457
547
  .action(async (functionName, caller, _options, command) => {
458
548
  const { authorizeAction } = await import('./authorize_action.js');
459
549
  const options = command.optsWithGlobals();
460
- const {
461
- args,
462
- contractArtifact: artifactPathPromise,
463
- contractAddress,
464
- from: parsedFromAddress,
465
- rpcUrl,
466
- secretKey,
467
- } = options;
468
-
469
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
470
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
471
- const wallet = await getWalletWithScopes(account, db);
472
- const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
473
- await authorizeAction(wallet, functionName, caller, args, artifactPath, contractAddress, log);
474
- });
550
+ const { args, contractArtifact: artifactPathPromise, contractAddress, from: parsedFromAddress } = options;
475
551
 
476
- program
477
- .command('add-authwit')
478
- .description(
479
- 'Adds an authorization witness to the provided account, granting PXE access to the notes of the authorizer so that it can be verified',
480
- )
481
- .argument('<authwit>', 'Authorization witness to add to the account', witness => aliasedAuthWitParser(witness, db))
482
- .argument('<authorizer>', 'Account that provides the authorization to perform the action', address =>
483
- aliasedAddressParser('accounts', address, db),
484
- )
485
- .addOption(pxeOption)
486
- .addOption(
487
- createSecretKeyOption("The sender's secret key", !db, sk => aliasedSecretKeyParser(sk, db)).conflicts('account'),
488
- )
489
- .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
490
- .addOption(
491
- createAliasOption('Alias for the authorization witness. Used for easy reference in subsequent commands.', !db),
492
- )
493
- .action(async (authwit, authorizer, _options, command) => {
494
- const { addAuthwit } = await import('./add_authwit.js');
495
- const options = command.optsWithGlobals();
496
- const { from: parsedFromAddress, rpcUrl, secretKey } = options;
552
+ const wallet = walletAndNodeWrapper.wallet;
497
553
 
498
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
499
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
500
- const wallet = await getWalletWithScopes(account, db);
501
- await addAuthwit(wallet, authwit, authorizer, log);
502
- await addScopeToWallet(wallet, authorizer, db);
554
+ const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
555
+ await authorizeAction(wallet, parsedFromAddress, functionName, caller, args, artifactPath, contractAddress, log);
503
556
  });
504
557
 
505
558
  program
506
559
  .command('get-tx')
507
560
  .description('Gets the status of the recent txs, or a detailed view if a specific transaction hash is provided')
508
561
  .argument('[txHash]', 'A transaction hash to get the receipt for.', txHash => aliasedTxHashParser(txHash, db))
509
- .addOption(pxeOption)
510
562
  .option('-p, --page <number>', 'The page number to display', value => integerArgParser(value, '--page', 1), 1)
511
563
  .option(
512
564
  '-s, --page-size <number>',
@@ -516,12 +568,14 @@ export function injectCommands(
516
568
  )
517
569
  .action(async (txHash, options) => {
518
570
  const { checkTx } = await import('./check_tx.js');
519
- const { rpcUrl, pageSize } = options;
571
+ const { pageSize } = options;
520
572
  let { page } = options;
521
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
573
+
574
+ const wallet = walletAndNodeWrapper.wallet;
575
+ const node = walletAndNodeWrapper.node;
522
576
 
523
577
  if (txHash) {
524
- await checkTx(client, txHash, false, log);
578
+ await checkTx(wallet, node, txHash, false, log);
525
579
  } else if (db) {
526
580
  const aliases = await db.listAliases('transactions');
527
581
  const totalPages = Math.ceil(aliases.length / pageSize);
@@ -530,17 +584,16 @@ export function injectCommands(
530
584
  aliases.slice(page * pageSize, pageSize * (1 + page)).map(async ({ key, value }) => ({
531
585
  alias: key,
532
586
  txHash: value,
533
- cancellable: (await db.retrieveTxData(TxHash.fromString(value))).cancellable,
534
- status: await checkTx(client, TxHash.fromString(value), true, log),
587
+ status: await checkTx(wallet, node, TxHash.fromString(value), true, log),
535
588
  })),
536
589
  );
537
590
  log(`Recent transactions:`);
538
591
  log('');
539
592
  log(`${'Alias'.padEnd(32, ' ')} | ${'TxHash'.padEnd(64, ' ')} | ${'Cancellable'.padEnd(12, ' ')} | Status`);
540
- log(''.padEnd(32 + 64 + 12 + 20, '-'));
541
- for (const { alias, txHash, status, cancellable } of dataRows) {
542
- log(`${alias.padEnd(32, ' ')} | ${txHash} | ${cancellable.toString()?.padEnd(12, ' ')} | ${status}`);
543
- log(''.padEnd(32 + 64 + 12 + 20, '-'));
593
+ log(''.padEnd(32 + 64 + 20, '-'));
594
+ for (const { alias, txHash, status } of dataRows) {
595
+ log(`${alias.padEnd(32, ' ')} | ${txHash} | ${status}`);
596
+ log(''.padEnd(32 + 64 + 20, '-'));
544
597
  }
545
598
  log(`Displaying ${Math.min(pageSize, aliases.length)} rows, page ${page + 1}/${totalPages}`);
546
599
  } else {
@@ -548,42 +601,6 @@ export function injectCommands(
548
601
  }
549
602
  });
550
603
 
551
- program
552
- .command('cancel-tx')
553
- .description('Cancels a pending tx by reusing its nonce with a higher fee and an empty payload')
554
- .argument('<txHash>', 'A transaction hash to cancel.', txHash => aliasedTxHashParser(txHash, db))
555
- .addOption(pxeOption)
556
- .addOption(
557
- createSecretKeyOption("The sender's secret key", !db, sk => aliasedSecretKeyParser(sk, db)).conflicts('account'),
558
- )
559
- .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
560
- .addOption(FeeOpts.paymentMethodOption().default('method=fee_juice'))
561
- .option(
562
- '-i --increased-fees <da=1,l2=1>',
563
- 'The amounts by which the fees are increased',
564
- value => parseGasFees(value),
565
- new GasFees(1, 1),
566
- )
567
- .option('--max-fees-per-gas <da=100,l2=100>', 'Maximum fees per gas unit for DA and L2 computation.', value =>
568
- parseGasFees(value),
569
- )
570
- .action(async (txHash, options) => {
571
- const { cancelTx } = await import('./cancel_tx.js');
572
- const { from: parsedFromAddress, rpcUrl, secretKey, payment, increasedFees, maxFeesPerGas } = options;
573
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
574
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
575
- const wallet = await getWalletWithScopes(account, db);
576
-
577
- const txData = await db?.retrieveTxData(txHash);
578
- if (!txData) {
579
- throw new Error('Transaction data not found in the database, cannot reuse nonce');
580
- }
581
-
582
- const paymentMethod = await parsePaymentMethod(payment, false, log, db)(wallet);
583
-
584
- await cancelTx(wallet, txData, paymentMethod, increasedFees, maxFeesPerGas, log);
585
- });
586
-
587
604
  program
588
605
  .command('register-sender')
589
606
  .description(
@@ -592,15 +609,12 @@ export function injectCommands(
592
609
  .argument('[address]', 'The address of the sender to register', address =>
593
610
  aliasedAddressParser('accounts', address, db),
594
611
  )
595
- .addOption(pxeOption)
596
- .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
597
612
  .addOption(createAliasOption('Alias for the sender. Used for easy reference in subsequent commands.', !db))
598
613
  .action(async (address, options) => {
599
614
  const { registerSender } = await import('./register_sender.js');
600
- const { from: parsedFromAddress, rpcUrl, secretKey, alias } = options;
601
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
602
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
603
- const wallet = await getWalletWithScopes(account, db);
615
+ const { alias } = options;
616
+
617
+ const wallet = walletAndNodeWrapper.wallet;
604
618
 
605
619
  await registerSender(wallet, address, log);
606
620
 
@@ -616,21 +630,43 @@ export function injectCommands(
616
630
  aliasedAddressParser('accounts', address, db),
617
631
  )
618
632
  .argument('[artifact]', ARTIFACT_DESCRIPTION, artifactPathParser)
633
+ .option('--init <string>', 'The contract initializer function to call', 'constructor')
634
+ .option(
635
+ '-k, --public-key <string>',
636
+ 'Optional encryption public key for this address. Set this value only if this contract is expected to receive private notes, which will be encrypted using this public key.',
637
+ parsePublicKey,
638
+ )
639
+ .option(
640
+ '-s, --salt <hex string>',
641
+ 'Optional deployment salt as a hex string for generating the deployment address.',
642
+ parseFieldFromHexString,
643
+ )
644
+ .option('--deployer <string>', 'The address of the account that deployed the contract', address =>
645
+ aliasedAddressParser('accounts', address, db),
646
+ )
619
647
  .addOption(createArgsOption(true, db))
620
- .addOption(pxeOption)
621
- .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
622
648
  .addOption(createAliasOption('Alias for the contact. Used for easy reference in subsequent commands.', !db))
623
649
  .action(async (address, artifactPathPromise, _options, command) => {
624
650
  const { registerContract } = await import('./register_contract.js');
625
- const { from: parsedFromAddress, rpcUrl, nodeUrl, secretKey, alias } = command.optsWithGlobals();
626
- const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
627
- const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl);
628
- const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
629
- const wallet = await getWalletWithScopes(account, db);
651
+ const { alias, init, publicKey, salt, deployer, args } = command.optsWithGlobals();
652
+
653
+ const wallet = walletAndNodeWrapper.wallet;
654
+ const node = walletAndNodeWrapper.node;
630
655
 
631
656
  const artifactPath = await artifactPathPromise;
632
657
 
633
- const instance = await registerContract(wallet, node, address, artifactPath, log);
658
+ const instance = await registerContract(
659
+ wallet,
660
+ node,
661
+ address,
662
+ artifactPath,
663
+ log,
664
+ init,
665
+ publicKey,
666
+ args,
667
+ salt,
668
+ deployer,
669
+ );
634
670
 
635
671
  if (db && alias) {
636
672
  await db.storeContract(instance.address, artifactPath, log, alias);