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

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 (107) hide show
  1. package/README.md +30 -0
  2. package/dest/bin/index.d.ts +1 -1
  3. package/dest/bin/index.js +57 -26
  4. package/dest/cmds/authorize_action.d.ts +4 -3
  5. package/dest/cmds/authorize_action.d.ts.map +1 -1
  6. package/dest/cmds/authorize_action.js +9 -5
  7. package/dest/cmds/bridge_fee_juice.d.ts +3 -3
  8. package/dest/cmds/bridge_fee_juice.d.ts.map +1 -1
  9. package/dest/cmds/bridge_fee_juice.js +8 -7
  10. package/dest/cmds/check_tx.d.ts +5 -3
  11. package/dest/cmds/check_tx.d.ts.map +1 -1
  12. package/dest/cmds/check_tx.js +144 -6
  13. package/dest/cmds/create_account.d.ts +7 -6
  14. package/dest/cmds/create_account.d.ts.map +1 -1
  15. package/dest/cmds/create_account.js +46 -27
  16. package/dest/cmds/create_authwit.d.ts +4 -3
  17. package/dest/cmds/create_authwit.d.ts.map +1 -1
  18. package/dest/cmds/create_authwit.js +6 -6
  19. package/dest/cmds/deploy.d.ts +7 -4
  20. package/dest/cmds/deploy.d.ts.map +1 -1
  21. package/dest/cmds/deploy.js +71 -54
  22. package/dest/cmds/deploy_account.d.ts +6 -8
  23. package/dest/cmds/deploy_account.d.ts.map +1 -1
  24. package/dest/cmds/deploy_account.js +46 -29
  25. package/dest/cmds/import_test_accounts.d.ts +3 -3
  26. package/dest/cmds/import_test_accounts.d.ts.map +1 -1
  27. package/dest/cmds/import_test_accounts.js +6 -9
  28. package/dest/cmds/index.d.ts +3 -3
  29. package/dest/cmds/index.d.ts.map +1 -1
  30. package/dest/cmds/index.js +83 -115
  31. package/dest/cmds/profile.d.ts +8 -0
  32. package/dest/cmds/profile.d.ts.map +1 -0
  33. package/dest/cmds/profile.js +28 -0
  34. package/dest/cmds/register_contract.d.ts +7 -3
  35. package/dest/cmds/register_contract.d.ts.map +1 -1
  36. package/dest/cmds/register_contract.js +20 -7
  37. package/dest/cmds/register_sender.d.ts +4 -3
  38. package/dest/cmds/register_sender.d.ts.map +1 -1
  39. package/dest/cmds/send.d.ts +8 -9
  40. package/dest/cmds/send.d.ts.map +1 -1
  41. package/dest/cmds/send.js +32 -21
  42. package/dest/cmds/simulate.d.ts +7 -3
  43. package/dest/cmds/simulate.d.ts.map +1 -1
  44. package/dest/cmds/simulate.js +26 -20
  45. package/dest/storage/wallet_db.d.ts +6 -18
  46. package/dest/storage/wallet_db.d.ts.map +1 -1
  47. package/dest/storage/wallet_db.js +2 -23
  48. package/dest/utils/authorizations.d.ts +6 -0
  49. package/dest/utils/authorizations.d.ts.map +1 -0
  50. package/dest/utils/authorizations.js +28 -0
  51. package/dest/utils/cli_wallet_and_node_wrapper.d.ts +12 -0
  52. package/dest/utils/cli_wallet_and_node_wrapper.d.ts.map +1 -0
  53. package/dest/utils/cli_wallet_and_node_wrapper.js +25 -0
  54. package/dest/utils/ecdsa.d.ts +1 -3
  55. package/dest/utils/ecdsa.d.ts.map +1 -1
  56. package/dest/utils/options/fees.d.ts +22 -28
  57. package/dest/utils/options/fees.d.ts.map +1 -1
  58. package/dest/utils/options/fees.js +85 -144
  59. package/dest/utils/options/index.d.ts +1 -1
  60. package/dest/utils/options/options.d.ts +9 -5
  61. package/dest/utils/options/options.d.ts.map +1 -1
  62. package/dest/utils/options/options.js +26 -14
  63. package/dest/utils/profiling.d.ts +5 -0
  64. package/dest/utils/profiling.d.ts.map +1 -0
  65. package/dest/utils/profiling.js +60 -0
  66. package/dest/utils/wallet.d.ts +36 -0
  67. package/dest/utils/wallet.d.ts.map +1 -0
  68. package/dest/utils/wallet.js +195 -0
  69. package/package.json +29 -22
  70. package/src/bin/index.ts +62 -33
  71. package/src/cmds/authorize_action.ts +16 -5
  72. package/src/cmds/bridge_fee_juice.ts +14 -11
  73. package/src/cmds/check_tx.ts +181 -5
  74. package/src/cmds/create_account.ts +55 -32
  75. package/src/cmds/create_authwit.ts +9 -5
  76. package/src/cmds/deploy.ts +79 -62
  77. package/src/cmds/deploy_account.ts +57 -28
  78. package/src/cmds/import_test_accounts.ts +7 -11
  79. package/src/cmds/index.ts +256 -220
  80. package/src/cmds/profile.ts +48 -0
  81. package/src/cmds/register_contract.ts +28 -5
  82. package/src/cmds/register_sender.ts +3 -2
  83. package/src/cmds/send.ts +32 -18
  84. package/src/cmds/simulate.ts +40 -24
  85. package/src/storage/wallet_db.ts +3 -31
  86. package/src/utils/authorizations.ts +51 -0
  87. package/src/utils/cli_wallet_and_node_wrapper.ts +35 -0
  88. package/src/utils/options/fees.ts +135 -206
  89. package/src/utils/options/options.ts +41 -19
  90. package/src/utils/profiling.ts +158 -0
  91. package/src/utils/wallet.ts +266 -0
  92. package/dest/cmds/add_authwit.d.ts +0 -4
  93. package/dest/cmds/add_authwit.d.ts.map +0 -1
  94. package/dest/cmds/add_authwit.js +0 -4
  95. package/dest/cmds/cancel_tx.d.ts +0 -11
  96. package/dest/cmds/cancel_tx.d.ts.map +0 -1
  97. package/dest/cmds/cancel_tx.js +0 -38
  98. package/dest/utils/accounts.d.ts +0 -11
  99. package/dest/utils/accounts.d.ts.map +0 -1
  100. package/dest/utils/accounts.js +0 -87
  101. package/dest/utils/pxe_wrapper.d.ts +0 -10
  102. package/dest/utils/pxe_wrapper.d.ts.map +0 -1
  103. package/dest/utils/pxe_wrapper.js +0 -21
  104. package/src/cmds/add_authwit.ts +0 -13
  105. package/src/cmds/cancel_tx.ts +0 -62
  106. package/src/utils/accounts.ts +0 -102
  107. package/src/utils/pxe_wrapper.ts +0 -26
@@ -1,67 +1,31 @@
1
- import {
2
- type AccountWallet,
3
- type DeployAccountOptions,
4
- FeeJuicePaymentMethod,
5
- type FeePaymentMethod,
6
- type PXE,
7
- type SendMethodOptions,
8
- } from '@aztec/aztec.js';
1
+ import type { FeePaymentMethod } from '@aztec/aztec.js/fee';
2
+ import type { AztecNode } from '@aztec/aztec.js/node';
3
+ import type { Wallet } from '@aztec/aztec.js/wallet';
9
4
  import { Fr } from '@aztec/foundation/fields';
10
5
  import type { LogFn } from '@aztec/foundation/log';
6
+ import type { FieldsOf } from '@aztec/foundation/types';
11
7
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
12
8
  import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
9
+ import type { FeeOptions } from '@aztec/wallet-sdk/base-wallet';
13
10
 
14
11
  import { Option } from 'commander';
15
12
 
16
13
  import type { WalletDB } from '../../storage/wallet_db.js';
17
- import { createOrRetrieveAccount } from '../accounts.js';
14
+ import { BASE_FEE_PADDING } from '../wallet.js';
18
15
  import { aliasedAddressParser } from './options.js';
19
16
 
20
- export type CliFeeArgs = {
17
+ export type RawCliFeeArgs = {
21
18
  estimateGasOnly: boolean;
22
19
  gasLimits?: string;
23
20
  payment?: string;
24
21
  maxFeesPerGas?: string;
25
22
  maxPriorityFeesPerGas?: string;
26
- estimateGas?: boolean;
27
23
  };
28
24
 
29
- export interface IFeeOpts {
30
- estimateOnly: boolean;
31
- gasSettings: GasSettings;
32
- toSendOpts(sender: AccountWallet): Promise<SendMethodOptions>;
33
- toDeployAccountOpts(sender: AccountWallet): Promise<DeployAccountOptions>;
34
- }
35
-
36
- export function printGasEstimates(
37
- feeOpts: IFeeOpts,
38
- gasEstimates: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>,
39
- log: LogFn,
40
- ) {
41
- log(`Estimated gas usage: ${formatGasEstimate(gasEstimates)}`);
42
- log(`Maximum total tx fee: ${getEstimatedCost(gasEstimates, feeOpts.gasSettings.maxFeesPerGas)}`);
43
- }
44
-
45
- function formatGasEstimate(estimate: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>) {
46
- return `da=${estimate.gasLimits.daGas},l2=${estimate.gasLimits.l2Gas},teardownDA=${estimate.teardownGasLimits.daGas},teardownL2=${estimate.teardownGasLimits.l2Gas}`;
47
- }
48
-
49
- function getEstimatedCost(estimate: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>, maxFeesPerGas: GasFees) {
50
- return GasSettings.default({ ...estimate, maxFeesPerGas })
51
- .getFeeLimit()
52
- .toBigInt();
53
- }
54
-
55
- async function parseGasSettings(args: CliFeeArgs, pxe: PXE) {
56
- const gasLimits = args.gasLimits ? parseGasLimits(args.gasLimits) : {};
57
- const maxFeesPerGas = args.maxFeesPerGas ? parseGasFees(args.maxFeesPerGas) : await pxe.getCurrentBaseFees();
58
- const maxPriorityFeesPerGas = args.maxPriorityFeesPerGas ? parseGasFees(args.maxPriorityFeesPerGas) : undefined;
59
- return GasSettings.default({
60
- ...gasLimits,
61
- maxFeesPerGas,
62
- maxPriorityFeesPerGas,
63
- });
64
- }
25
+ export type ParsedFeeOptions = {
26
+ paymentMethod?: FeePaymentMethod;
27
+ gasSettings?: Partial<FieldsOf<GasSettings>>;
28
+ };
65
29
 
66
30
  type OptionParams = {
67
31
  [key: string]: { type: string; description?: string; default?: string };
@@ -77,21 +41,23 @@ function printOptionParams(params: OptionParams) {
77
41
  params[name].default ? `Default: ${params[name].default}` : '',
78
42
  ].join(' '),
79
43
  );
80
- return descriptionList.length ? `\n Parameters:\n${descriptionList.join('\n')}` : '';
44
+ return descriptionList.length
45
+ ? `\n Parameters:\n${descriptionList.join('\n')}\nFormat: --payment ${Object.keys(params)
46
+ .slice(0, 3)
47
+ .map(name => `${name}=${params[name].type}`)} ${Object.keys(params).length > 3 ? '...' : ''}`
48
+ : '';
81
49
  }
82
50
 
83
- function getFeePaymentMethodParams(allowCustomFeePayer: boolean): OptionParams {
84
- const feePayer = allowCustomFeePayer ? { type: 'address', description: 'The account paying the fee.' } : undefined;
51
+ function getFeePaymentMethodParams(): OptionParams {
85
52
  return {
86
53
  method: {
87
54
  type: 'name',
88
- description: 'Valid values: "fee_juice", "fpc-public", "fpc-private".',
55
+ description: 'Valid values: "fee_juice", "fpc-public", "fpc-private", "fpc-sponsored"',
89
56
  default: 'fee_juice',
90
57
  },
91
- ...(feePayer ? { feePayer } : {}),
92
58
  asset: {
93
59
  type: 'address',
94
- description: 'The asset used for fee payment. Not required for the "fee_juice" method.',
60
+ description: 'The asset used for fee payment. Required for "fpc-public" and "fpc-private".',
95
61
  },
96
62
  fpc: {
97
63
  type: 'address',
@@ -113,167 +79,67 @@ function getFeePaymentMethodParams(allowCustomFeePayer: boolean): OptionParams {
113
79
  type: 'bigint',
114
80
  description: 'The index of the claim in the l1toL2Message tree.',
115
81
  },
116
- feeRecipient: {
117
- type: 'string',
118
- description: 'Recipient of the fee.',
119
- },
120
82
  };
121
83
  }
122
84
 
123
- function getPaymentMethodOption(allowCustomFeePayer: boolean) {
124
- const params = getFeePaymentMethodParams(allowCustomFeePayer);
125
- const paramList = Object.keys(params).map(name => `${name}=${params[name].type}`);
126
- return new Option(
127
- `--payment <${paramList.join(',')}>`,
128
- `Fee payment method and arguments.${printOptionParams(params)}`,
129
- );
85
+ export function getPaymentMethodOption() {
86
+ const params = getFeePaymentMethodParams();
87
+ return new Option(`--payment <options>`, `Fee payment method and arguments.${printOptionParams(params)}`);
130
88
  }
131
89
 
132
- function getFeeOptions(allowCustomFeePayer: boolean) {
90
+ function getFeeOptions() {
133
91
  return [
134
- getPaymentMethodOption(allowCustomFeePayer),
92
+ getPaymentMethodOption(),
135
93
  new Option('--gas-limits <da=100,l2=100,teardownDA=10,teardownL2=10>', 'Gas limits for the tx.'),
136
94
  new Option('--max-fees-per-gas <da=100,l2=100>', 'Maximum fees per gas unit for DA and L2 computation.'),
137
95
  new Option(
138
96
  '--max-priority-fees-per-gas <da=0,l2=0>',
139
97
  'Maximum priority fees per gas unit for DA and L2 computation.',
140
98
  ),
141
- new Option('--no-estimate-gas', 'Whether to automatically estimate gas limits for the tx.'),
142
99
  new Option('--estimate-gas-only', 'Only report gas estimation for the tx, do not send it.'),
143
100
  ];
144
101
  }
145
102
 
146
- export class FeeOpts implements IFeeOpts {
147
- constructor(
148
- public estimateOnly: boolean,
149
- public gasSettings: GasSettings,
150
- private paymentMethodFactory: (sender: AccountWallet) => Promise<FeePaymentMethod>,
151
- private getDeployWallet: (
152
- sender: AccountWallet,
153
- paymentMethod: FeePaymentMethod,
154
- ) => Promise<AccountWallet | undefined>,
155
- private estimateGas: boolean,
156
- ) {}
157
-
158
- async toSendOpts(sender: AccountWallet): Promise<SendMethodOptions> {
159
- return {
160
- fee: {
161
- estimateGas: this.estimateGas,
162
- gasSettings: this.gasSettings,
163
- paymentMethod: await this.paymentMethodFactory(sender),
164
- },
165
- };
166
- }
167
-
168
- async toDeployAccountOpts(sender: AccountWallet): Promise<DeployAccountOptions> {
169
- const paymentMethod = await this.paymentMethodFactory(sender);
170
- const deployWallet = await this.getDeployWallet(sender, paymentMethod);
171
- return {
172
- deployWallet,
173
- fee: {
174
- estimateGas: this.estimateGas,
175
- gasSettings: this.gasSettings,
176
- paymentMethod,
177
- },
178
- };
179
- }
180
-
181
- static paymentMethodOption() {
182
- return getPaymentMethodOption(false);
183
- }
184
-
185
- static getOptions() {
186
- return getFeeOptions(false);
187
- }
188
-
189
- static async fromCli(args: CliFeeArgs, pxe: PXE, log: LogFn, db?: WalletDB) {
190
- const estimateOnly = args.estimateGasOnly;
191
- const gasSettings = await parseGasSettings(args, pxe);
192
-
193
- const defaultPaymentMethod = async (sender: AccountWallet) => {
194
- const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
195
- return new FeeJuicePaymentMethod(sender.getAddress());
196
- };
197
-
198
- const getDeployWallet = () => {
199
- // Returns undefined. The sender's wallet will be used by default.
200
- return Promise.resolve(undefined);
201
- };
202
-
203
- return new FeeOpts(
204
- estimateOnly,
205
- gasSettings,
206
- args.payment ? parsePaymentMethod(args.payment, false, log, db) : defaultPaymentMethod,
207
- getDeployWallet,
208
- !!args.estimateGas,
209
- );
210
- }
211
- }
212
-
213
- export class FeeOptsWithFeePayer extends FeeOpts {
214
- static override paymentMethodOption() {
215
- return getPaymentMethodOption(true);
216
- }
217
-
218
- static override getOptions() {
219
- return getFeeOptions(true);
220
- }
221
-
222
- static override async fromCli(args: CliFeeArgs, pxe: PXE, log: LogFn, db?: WalletDB) {
223
- const estimateOnly = args.estimateGasOnly;
224
- const gasSettings = await parseGasSettings(args, pxe);
225
-
226
- const defaultPaymentMethod = async (sender: AccountWallet) => {
227
- const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
228
- return new FeeJuicePaymentMethod(sender.getAddress());
229
- };
230
-
231
- const getDeployWallet = async (sender: AccountWallet, paymentMethod: FeePaymentMethod) => {
232
- if (paymentMethod instanceof FeeJuicePaymentMethod) {
233
- const feePayer = await paymentMethod.getFeePayer();
234
- if (!sender.getAddress().equals(feePayer)) {
235
- return (await createOrRetrieveAccount(pxe, feePayer, db)).getWallet();
236
- }
237
- }
238
- return undefined;
239
- };
240
-
241
- return new FeeOptsWithFeePayer(
242
- estimateOnly,
243
- gasSettings,
244
- args.payment ? parsePaymentMethod(args.payment, true, log, db) : defaultPaymentMethod,
245
- getDeployWallet,
246
- !!args.estimateGas,
247
- );
248
- }
103
+ function parseGasSettings(args: RawCliFeeArgs): Partial<FieldsOf<GasSettings>> {
104
+ const gasLimits = args.gasLimits ? parseGasLimits(args.gasLimits) : {};
105
+ const maxFeesPerGas = args.maxFeesPerGas ? parseGasFees(args.maxFeesPerGas) : undefined;
106
+ const maxPriorityFeesPerGas = args.maxPriorityFeesPerGas ? parseGasFees(args.maxPriorityFeesPerGas) : undefined;
107
+ return {
108
+ ...gasLimits,
109
+ maxFeesPerGas,
110
+ maxPriorityFeesPerGas,
111
+ };
249
112
  }
250
113
 
251
114
  export function parsePaymentMethod(
252
115
  payment: string,
253
- allowCustomFeePayer: boolean,
254
116
  log: LogFn,
255
117
  db?: WalletDB,
256
- ): (sender: AccountWallet) => Promise<FeePaymentMethod> {
257
- const parsed = payment.split(',').reduce((acc, item) => {
258
- const [dimension, value] = item.split('=');
259
- acc[dimension] = value ?? 1;
260
- return acc;
261
- }, {} as Record<string, string>);
118
+ ): (wallet: Wallet, from: AztecAddress, gasSettings: GasSettings) => Promise<FeePaymentMethod | undefined> {
119
+ const parsed = payment.split(',').reduce(
120
+ (acc, item) => {
121
+ const [dimension, value] = item.split('=');
122
+ acc[dimension] = value ?? 1;
123
+ return acc;
124
+ },
125
+ {} as Record<string, string>,
126
+ );
262
127
 
263
- const getFpcOpts = (parsed: Record<string, string>, db?: WalletDB) => {
128
+ const getFpc = () => {
264
129
  if (!parsed.fpc) {
265
130
  throw new Error('Missing "fpc" in payment option');
266
131
  }
132
+ return aliasedAddressParser('contracts', parsed.fpc, db);
133
+ };
134
+
135
+ const getAsset = () => {
267
136
  if (!parsed.asset) {
268
137
  throw new Error('Missing "asset" in payment option');
269
138
  }
270
-
271
- const fpc = aliasedAddressParser('contracts', parsed.fpc, db);
272
-
273
- return [AztecAddress.fromString(parsed.asset), fpc];
139
+ return AztecAddress.fromString(parsed.asset);
274
140
  };
275
141
 
276
- return async (sender: AccountWallet) => {
142
+ return async (wallet: Wallet, from: AztecAddress, gasSettings: GasSettings) => {
277
143
  switch (parsed.method) {
278
144
  case 'fee_juice': {
279
145
  if (parsed.claim || (parsed.claimSecret && parsed.claimAmount && parsed.messageLeafIndex)) {
@@ -283,13 +149,13 @@ export function parsePaymentMethod(
283
149
  amount: claimAmount,
284
150
  secret: claimSecret,
285
151
  leafIndex: messageLeafIndex,
286
- } = await db.popBridgedFeeJuice(sender.getAddress(), log));
152
+ } = await db.popBridgedFeeJuice(from, log));
287
153
  } else {
288
154
  ({ claimAmount, claimSecret, messageLeafIndex } = parsed);
289
155
  }
290
156
  log(`Using Fee Juice for fee payments with claim for ${claimAmount} tokens`);
291
157
  const { FeeJuicePaymentMethodWithClaim } = await import('@aztec/aztec.js/fee');
292
- return new FeeJuicePaymentMethodWithClaim(sender, {
158
+ return new FeeJuicePaymentMethodWithClaim(from, {
293
159
  claimAmount: (typeof claimAmount === 'string'
294
160
  ? Fr.fromHexString(claimAmount)
295
161
  : new Fr(claimAmount)
@@ -298,26 +164,29 @@ export function parsePaymentMethod(
298
164
  messageLeafIndex: BigInt(messageLeafIndex),
299
165
  });
300
166
  } else {
301
- log(`Using Fee Juice for fee payment`);
302
- const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
303
- const feePayer =
304
- parsed.feePayer && allowCustomFeePayer
305
- ? aliasedAddressParser('accounts', parsed.feePayer, db)
306
- : sender.getAddress();
307
- return new FeeJuicePaymentMethod(feePayer);
167
+ log(`Using Fee Juice for fee payment with the balance of account ${from}`);
168
+ return;
308
169
  }
309
170
  }
310
171
  case 'fpc-public': {
311
- const [asset, fpc] = getFpcOpts(parsed, db);
172
+ const fpc = getFpc();
173
+ const asset = getAsset();
312
174
  log(`Using public fee payment with asset ${asset} via paymaster ${fpc}`);
313
175
  const { PublicFeePaymentMethod } = await import('@aztec/aztec.js/fee');
314
- return new PublicFeePaymentMethod(fpc, sender);
176
+ return new PublicFeePaymentMethod(fpc, from, wallet, gasSettings);
315
177
  }
316
178
  case 'fpc-private': {
317
- const [asset, fpc] = getFpcOpts(parsed, db);
179
+ const fpc = getFpc();
180
+ const asset = getAsset();
318
181
  log(`Using private fee payment with asset ${asset} via paymaster ${fpc}`);
319
182
  const { PrivateFeePaymentMethod } = await import('@aztec/aztec.js/fee');
320
- return new PrivateFeePaymentMethod(fpc, sender);
183
+ return new PrivateFeePaymentMethod(fpc, from, wallet, gasSettings);
184
+ }
185
+ case 'fpc-sponsored': {
186
+ const sponsor = getFpc();
187
+ log(`Using sponsored fee payment with sponsor ${sponsor}`);
188
+ const { SponsoredFeePaymentMethod } = await import('@aztec/aztec.js/fee/testing');
189
+ return new SponsoredFeePaymentMethod(sponsor);
321
190
  }
322
191
  case undefined:
323
192
  throw new Error('Missing "method" in payment option');
@@ -328,11 +197,14 @@ export function parsePaymentMethod(
328
197
  }
329
198
 
330
199
  function parseGasLimits(gasLimits: string): { gasLimits: Gas; teardownGasLimits: Gas } {
331
- const parsed = gasLimits.split(',').reduce((acc, limit) => {
332
- const [dimension, value] = limit.split('=');
333
- acc[dimension] = parseInt(value, 10);
334
- return acc;
335
- }, {} as Record<string, number>);
200
+ const parsed = gasLimits.split(',').reduce(
201
+ (acc, limit) => {
202
+ const [dimension, value] = limit.split('=');
203
+ acc[dimension] = parseInt(value, 10);
204
+ return acc;
205
+ },
206
+ {} as Record<string, number>,
207
+ );
336
208
 
337
209
  const expected = ['da', 'l2', 'teardownDA', 'teardownL2'];
338
210
  for (const dimension of expected) {
@@ -348,11 +220,14 @@ function parseGasLimits(gasLimits: string): { gasLimits: Gas; teardownGasLimits:
348
220
  }
349
221
 
350
222
  export function parseGasFees(gasFees: string): GasFees {
351
- const parsed = gasFees.split(',').reduce((acc, fee) => {
352
- const [dimension, value] = fee.split('=');
353
- acc[dimension] = parseInt(value, 10);
354
- return acc;
355
- }, {} as Record<string, number>);
223
+ const parsed = gasFees.split(',').reduce(
224
+ (acc, fee) => {
225
+ const [dimension, value] = fee.split('=');
226
+ acc[dimension] = parseInt(value, 10);
227
+ return acc;
228
+ },
229
+ {} as Record<string, number>,
230
+ );
356
231
 
357
232
  const expected = ['da', 'l2'];
358
233
  for (const dimension of expected) {
@@ -363,3 +238,57 @@ export function parseGasFees(gasFees: string): GasFees {
363
238
 
364
239
  return new GasFees(parsed.da, parsed.l2);
365
240
  }
241
+ export class CLIFeeArgs {
242
+ constructor(
243
+ public estimateOnly: boolean,
244
+ private paymentMethod: (
245
+ wallet: Wallet,
246
+ feePayer: AztecAddress,
247
+ gasSettings: GasSettings,
248
+ ) => Promise<FeePaymentMethod | undefined>,
249
+ private gasSettings: Partial<FieldsOf<GasSettings>>,
250
+ ) {}
251
+
252
+ async toUserFeeOptions(node: AztecNode, wallet: Wallet, from: AztecAddress): Promise<ParsedFeeOptions> {
253
+ const maxFeesPerGas = (await node.getCurrentBaseFees()).mul(1 + BASE_FEE_PADDING);
254
+ const gasSettings = GasSettings.default({ ...this.gasSettings, maxFeesPerGas });
255
+ const paymentMethod = await this.paymentMethod(wallet, from, gasSettings);
256
+ return {
257
+ paymentMethod,
258
+ gasSettings,
259
+ };
260
+ }
261
+
262
+ static parse(args: RawCliFeeArgs, log: LogFn, db?: WalletDB): CLIFeeArgs {
263
+ return new CLIFeeArgs(
264
+ !!args.estimateGasOnly,
265
+ parsePaymentMethod(args.payment ?? 'method=fee_juice', log, db),
266
+ parseGasSettings(args),
267
+ );
268
+ }
269
+
270
+ static getOptions() {
271
+ return getFeeOptions();
272
+ }
273
+ }
274
+
275
+ // Printing
276
+
277
+ export function printGasEstimates(
278
+ feeOpts: FeeOptions,
279
+ gasEstimates: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>,
280
+ log: LogFn,
281
+ ) {
282
+ log(`Estimated gas usage: ${formatGasEstimate(gasEstimates)}`);
283
+ log(`Maximum total tx fee: ${getEstimatedCost(gasEstimates, feeOpts.gasSettings.maxFeesPerGas)}`);
284
+ }
285
+
286
+ function formatGasEstimate(estimate: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>) {
287
+ return `da=${estimate.gasLimits.daGas},l2=${estimate.gasLimits.l2Gas},teardownDA=${estimate.teardownGasLimits.daGas},teardownL2=${estimate.teardownGasLimits.l2Gas}`;
288
+ }
289
+
290
+ function getEstimatedCost(estimate: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>, maxFeesPerGas: GasFees) {
291
+ return GasSettings.default({ ...estimate, maxFeesPerGas })
292
+ .getFeeLimit()
293
+ .toBigInt();
294
+ }
@@ -1,3 +1,4 @@
1
+ import { TxHash } from '@aztec/aztec.js/tx';
1
2
  import { parseAztecAddress, parseSecretKey, parseTxHash } from '@aztec/cli/utils';
2
3
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
3
4
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -6,7 +7,7 @@ import { Option } from 'commander';
6
7
  import { readdir, stat } from 'fs/promises';
7
8
 
8
9
  import type { AliasType, WalletDB } from '../../storage/wallet_db.js';
9
- import { AccountTypes } from '../accounts.js';
10
+ import { AccountTypes } from '../wallet.js';
10
11
 
11
12
  const TARGET_DIR = 'target';
12
13
 
@@ -29,24 +30,28 @@ export function integerArgParser(
29
30
  return parsed;
30
31
  }
31
32
 
32
- export function aliasedTxHashParser(txHash: string, db?: WalletDB) {
33
+ export function aliasedTxHashParser(txHash: string, db?: WalletDB): TxHash {
33
34
  try {
34
35
  return parseTxHash(txHash);
35
- } catch (err) {
36
+ } catch {
36
37
  const prefixed = txHash.includes(':') ? txHash : `transactions:${txHash}`;
37
38
  const rawTxHash = db ? db.tryRetrieveAlias(prefixed) : txHash;
38
39
  return parseTxHash(rawTxHash);
39
40
  }
40
41
  }
41
42
 
42
- export function aliasedAuthWitParser(witness: string, db?: WalletDB) {
43
- try {
44
- return AuthWitness.fromString(witness);
45
- } catch (err) {
46
- const prefixed = witness.includes(':') ? witness : `authwits:${witness}`;
47
- const rawAuthWitness = db ? db.tryRetrieveAlias(prefixed) : witness;
48
- return AuthWitness.fromString(rawAuthWitness);
49
- }
43
+ export function aliasedAuthWitParser(witnesses: string, db?: WalletDB) {
44
+ const parsedWitnesses = witnesses.split(',').map(witness => {
45
+ try {
46
+ return AuthWitness.fromString(witness);
47
+ } catch {
48
+ const prefixed = witness.includes(':') ? witness : `authwits:${witness}`;
49
+ const rawAuthWitness = db ? db.tryRetrieveAlias(prefixed) : witness;
50
+ return AuthWitness.fromString(rawAuthWitness);
51
+ }
52
+ });
53
+
54
+ return parsedWitnesses;
50
55
  }
51
56
 
52
57
  export function aliasedAddressParser(defaultPrefix: AliasType, address: string, db?: WalletDB) {
@@ -79,6 +84,12 @@ export function createAccountOption(description: string, hide: boolean, db?: Wal
79
84
  .argParser(address => aliasedAddressParser('accounts', address, db));
80
85
  }
81
86
 
87
+ export function createAuthwitnessOption(description: string, hide: boolean, db?: WalletDB) {
88
+ return new Option('-aw, --auth-witness <string,...>', description)
89
+ .hideHelp(hide)
90
+ .argParser(witness => aliasedAuthWitParser(witness, db));
91
+ }
92
+
82
93
  export function createTypeOption(mandatory: boolean) {
83
94
  return new Option('-t, --type <string>', 'Type of account to create')
84
95
  .choices(AccountTypes)
@@ -103,6 +114,20 @@ export function createContractAddressOption(db?: WalletDB) {
103
114
  .makeOptionMandatory(true);
104
115
  }
105
116
 
117
+ export function createDebugExecutionStepsDirOption() {
118
+ return new Option(
119
+ '--debug-execution-steps-dir <address>',
120
+ 'Directory to write execution step artifacts for bb profiling/debugging.',
121
+ ).makeOptionMandatory(false);
122
+ }
123
+
124
+ export function createVerboseOption() {
125
+ return new Option(
126
+ '-v, --verbose',
127
+ 'Provide timings on all executed operations (synching, simulating, proving)',
128
+ ).default(false);
129
+ }
130
+
106
131
  export function artifactPathParser(filePath: string, db?: WalletDB) {
107
132
  if (filePath.includes('@')) {
108
133
  const [pkg, contractName] = filePath.split('@');
@@ -140,18 +165,11 @@ export function createArtifactOption(db?: WalletDB) {
140
165
  .makeOptionMandatory(false);
141
166
  }
142
167
 
143
- export function createProfileOption() {
144
- return new Option(
145
- '-p, --profile',
146
- 'Run the real prover and get the gate count for each function in the transaction.',
147
- ).default(false);
148
- }
149
-
150
168
  async function contractArtifactFromWorkspace(pkg?: string, contractName?: string) {
151
169
  const cwd = process.cwd();
152
170
  try {
153
171
  await stat(`${cwd}/Nargo.toml`);
154
- } catch (e) {
172
+ } catch {
155
173
  throw new Error(
156
174
  'Invalid contract artifact argument provided. To use this option, command should be called from a nargo workspace',
157
175
  );
@@ -173,3 +191,7 @@ async function contractArtifactFromWorkspace(pkg?: string, contractName?: string
173
191
  }
174
192
  return `${cwd}/${TARGET_DIR}/${bestMatch[0]}`;
175
193
  }
194
+
195
+ export function cleanupAuthWitnesses(authWitnesses: AuthWitness[] | undefined): AuthWitness[] {
196
+ return authWitnesses?.filter(w => w !== undefined) ?? [];
197
+ }