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

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 (115) hide show
  1. package/README.md +30 -0
  2. package/dest/bin/index.d.ts +2 -1
  3. package/dest/bin/index.js +58 -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 +11 -5
  7. package/dest/cmds/bridge_fee_juice.d.ts +4 -4
  8. package/dest/cmds/bridge_fee_juice.d.ts.map +1 -1
  9. package/dest/cmds/bridge_fee_juice.js +10 -8
  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 +174 -6
  13. package/dest/cmds/create_account.d.ts +10 -7
  14. package/dest/cmds/create_account.d.ts.map +1 -1
  15. package/dest/cmds/create_account.js +74 -38
  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 +8 -4
  20. package/dest/cmds/deploy.d.ts.map +1 -1
  21. package/dest/cmds/deploy.js +108 -59
  22. package/dest/cmds/deploy_account.d.ts +7 -8
  23. package/dest/cmds/deploy_account.d.ts.map +1 -1
  24. package/dest/cmds/deploy_account.js +70 -36
  25. package/dest/cmds/get_fee_juice_balance.d.ts +5 -0
  26. package/dest/cmds/get_fee_juice_balance.d.ts.map +1 -0
  27. package/dest/cmds/get_fee_juice_balance.js +27 -0
  28. package/dest/cmds/import_test_accounts.d.ts +3 -3
  29. package/dest/cmds/import_test_accounts.d.ts.map +1 -1
  30. package/dest/cmds/import_test_accounts.js +6 -9
  31. package/dest/cmds/index.d.ts +3 -3
  32. package/dest/cmds/index.d.ts.map +1 -1
  33. package/dest/cmds/index.js +99 -115
  34. package/dest/cmds/profile.d.ts +8 -0
  35. package/dest/cmds/profile.d.ts.map +1 -0
  36. package/dest/cmds/profile.js +28 -0
  37. package/dest/cmds/register_contract.d.ts +7 -3
  38. package/dest/cmds/register_contract.d.ts.map +1 -1
  39. package/dest/cmds/register_contract.js +20 -7
  40. package/dest/cmds/register_sender.d.ts +4 -3
  41. package/dest/cmds/register_sender.d.ts.map +1 -1
  42. package/dest/cmds/send.d.ts +9 -9
  43. package/dest/cmds/send.d.ts.map +1 -1
  44. package/dest/cmds/send.js +54 -27
  45. package/dest/cmds/simulate.d.ts +7 -3
  46. package/dest/cmds/simulate.d.ts.map +1 -1
  47. package/dest/cmds/simulate.js +26 -20
  48. package/dest/storage/wallet_db.d.ts +12 -19
  49. package/dest/storage/wallet_db.d.ts.map +1 -1
  50. package/dest/storage/wallet_db.js +63 -55
  51. package/dest/utils/authorizations.d.ts +6 -0
  52. package/dest/utils/authorizations.d.ts.map +1 -0
  53. package/dest/utils/authorizations.js +28 -0
  54. package/dest/utils/cli_wallet_and_node_wrapper.d.ts +12 -0
  55. package/dest/utils/cli_wallet_and_node_wrapper.d.ts.map +1 -0
  56. package/dest/utils/cli_wallet_and_node_wrapper.js +25 -0
  57. package/dest/utils/constants.d.ts +4 -0
  58. package/dest/utils/constants.d.ts.map +1 -0
  59. package/dest/utils/constants.js +7 -0
  60. package/dest/utils/ecdsa.d.ts +1 -3
  61. package/dest/utils/ecdsa.d.ts.map +1 -1
  62. package/dest/utils/options/fees.d.ts +23 -28
  63. package/dest/utils/options/fees.d.ts.map +1 -1
  64. package/dest/utils/options/fees.js +112 -148
  65. package/dest/utils/options/index.d.ts +1 -1
  66. package/dest/utils/options/options.d.ts +9 -5
  67. package/dest/utils/options/options.d.ts.map +1 -1
  68. package/dest/utils/options/options.js +26 -14
  69. package/dest/utils/profiling.d.ts +5 -0
  70. package/dest/utils/profiling.d.ts.map +1 -0
  71. package/dest/utils/profiling.js +68 -0
  72. package/dest/utils/wallet.d.ts +44 -0
  73. package/dest/utils/wallet.d.ts.map +1 -0
  74. package/dest/utils/wallet.js +263 -0
  75. package/package.json +31 -23
  76. package/src/bin/index.ts +63 -33
  77. package/src/cmds/authorize_action.ts +16 -5
  78. package/src/cmds/bridge_fee_juice.ts +16 -12
  79. package/src/cmds/check_tx.ts +212 -5
  80. package/src/cmds/create_account.ts +89 -45
  81. package/src/cmds/create_authwit.ts +9 -5
  82. package/src/cmds/deploy.ts +115 -71
  83. package/src/cmds/deploy_account.ts +84 -36
  84. package/src/cmds/get_fee_juice_balance.ts +37 -0
  85. package/src/cmds/import_test_accounts.ts +7 -11
  86. package/src/cmds/index.ts +312 -222
  87. package/src/cmds/profile.ts +48 -0
  88. package/src/cmds/register_contract.ts +28 -5
  89. package/src/cmds/register_sender.ts +3 -2
  90. package/src/cmds/send.ts +59 -25
  91. package/src/cmds/simulate.ts +37 -24
  92. package/src/storage/wallet_db.ts +67 -68
  93. package/src/utils/authorizations.ts +51 -0
  94. package/src/utils/cli_wallet_and_node_wrapper.ts +35 -0
  95. package/src/utils/constants.ts +4 -0
  96. package/src/utils/options/fees.ts +169 -210
  97. package/src/utils/options/options.ts +41 -19
  98. package/src/utils/profiling.ts +172 -0
  99. package/src/utils/wallet.ts +330 -0
  100. package/dest/cmds/add_authwit.d.ts +0 -4
  101. package/dest/cmds/add_authwit.d.ts.map +0 -1
  102. package/dest/cmds/add_authwit.js +0 -4
  103. package/dest/cmds/cancel_tx.d.ts +0 -11
  104. package/dest/cmds/cancel_tx.d.ts.map +0 -1
  105. package/dest/cmds/cancel_tx.js +0 -38
  106. package/dest/utils/accounts.d.ts +0 -11
  107. package/dest/utils/accounts.d.ts.map +0 -1
  108. package/dest/utils/accounts.js +0 -87
  109. package/dest/utils/pxe_wrapper.d.ts +0 -10
  110. package/dest/utils/pxe_wrapper.d.ts.map +0 -1
  111. package/dest/utils/pxe_wrapper.js +0 -21
  112. package/src/cmds/add_authwit.ts +0 -13
  113. package/src/cmds/cancel_tx.ts +0 -62
  114. package/src/utils/accounts.ts +0 -102
  115. 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';
9
- import { Fr } from '@aztec/foundation/fields';
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';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
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
- import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
8
+ import { Gas, GasFees, GasSettings, ManaUsageEstimate } 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 { MIN_FEE_PADDING } from '../constants.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,68 @@ 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
+ estimateOnly?: boolean,
119
+ ): (wallet: Wallet, from: AztecAddress, gasSettings: GasSettings) => Promise<FeePaymentMethod | undefined> {
120
+ const parsed = payment.split(',').reduce(
121
+ (acc, item) => {
122
+ const [dimension, value] = item.split('=');
123
+ acc[dimension] = value ?? 1;
124
+ return acc;
125
+ },
126
+ {} as Record<string, string>,
127
+ );
262
128
 
263
- const getFpcOpts = (parsed: Record<string, string>, db?: WalletDB) => {
129
+ const getFpc = () => {
264
130
  if (!parsed.fpc) {
265
131
  throw new Error('Missing "fpc" in payment option');
266
132
  }
133
+ return aliasedAddressParser('contracts', parsed.fpc, db);
134
+ };
135
+
136
+ const getAsset = () => {
267
137
  if (!parsed.asset) {
268
138
  throw new Error('Missing "asset" in payment option');
269
139
  }
270
-
271
- const fpc = aliasedAddressParser('contracts', parsed.fpc, db);
272
-
273
- return [AztecAddress.fromString(parsed.asset), fpc];
140
+ return AztecAddress.fromString(parsed.asset);
274
141
  };
275
142
 
276
- return async (sender: AccountWallet) => {
143
+ return async (wallet: Wallet, from: AztecAddress, gasSettings: GasSettings) => {
277
144
  switch (parsed.method) {
278
145
  case 'fee_juice': {
279
146
  if (parsed.claim || (parsed.claimSecret && parsed.claimAmount && parsed.messageLeafIndex)) {
@@ -283,41 +150,50 @@ export function parsePaymentMethod(
283
150
  amount: claimAmount,
284
151
  secret: claimSecret,
285
152
  leafIndex: messageLeafIndex,
286
- } = await db.popBridgedFeeJuice(sender.getAddress(), log));
153
+ } = estimateOnly ? await db.peekBridgedFeeJuice(from, log) : await db.popBridgedFeeJuice(from, log));
287
154
  } else {
288
155
  ({ claimAmount, claimSecret, messageLeafIndex } = parsed);
289
156
  }
290
157
  log(`Using Fee Juice for fee payments with claim for ${claimAmount} tokens`);
291
158
  const { FeeJuicePaymentMethodWithClaim } = await import('@aztec/aztec.js/fee');
292
- return new FeeJuicePaymentMethodWithClaim(sender, {
159
+ return new FeeJuicePaymentMethodWithClaim(from, {
293
160
  claimAmount: (typeof claimAmount === 'string'
294
- ? Fr.fromHexString(claimAmount)
161
+ ? Fr.fromString(claimAmount)
295
162
  : new Fr(claimAmount)
296
163
  ).toBigInt(),
297
- claimSecret: Fr.fromHexString(claimSecret),
164
+ claimSecret: typeof claimSecret === 'string' ? Fr.fromString(claimSecret) : claimSecret,
298
165
  messageLeafIndex: BigInt(messageLeafIndex),
299
166
  });
300
167
  } 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);
168
+ log(`Using Fee Juice for fee payment with the balance of account ${from}`);
169
+ return;
308
170
  }
309
171
  }
310
172
  case 'fpc-public': {
311
- const [asset, fpc] = getFpcOpts(parsed, db);
173
+ const fpc = getFpc();
174
+ const asset = getAsset();
175
+ log(
176
+ `WARNING: fpc-public is deprecated and will not work on mainnet alpha. Use fee_juice or fpc-sponsored instead.`,
177
+ );
312
178
  log(`Using public fee payment with asset ${asset} via paymaster ${fpc}`);
313
179
  const { PublicFeePaymentMethod } = await import('@aztec/aztec.js/fee');
314
- return new PublicFeePaymentMethod(fpc, sender);
180
+ return new PublicFeePaymentMethod(fpc, from, wallet, gasSettings);
315
181
  }
316
182
  case 'fpc-private': {
317
- const [asset, fpc] = getFpcOpts(parsed, db);
183
+ const fpc = getFpc();
184
+ const asset = getAsset();
185
+ log(
186
+ `WARNING: fpc-private is deprecated and will not work on mainnet alpha. Use fee_juice or fpc-sponsored instead.`,
187
+ );
318
188
  log(`Using private fee payment with asset ${asset} via paymaster ${fpc}`);
319
189
  const { PrivateFeePaymentMethod } = await import('@aztec/aztec.js/fee');
320
- return new PrivateFeePaymentMethod(fpc, sender);
190
+ return new PrivateFeePaymentMethod(fpc, from, wallet, gasSettings);
191
+ }
192
+ case 'fpc-sponsored': {
193
+ const sponsor = getFpc();
194
+ log(`Using sponsored fee payment with sponsor ${sponsor}`);
195
+ const { SponsoredFeePaymentMethod } = await import('@aztec/aztec.js/fee/testing');
196
+ return new SponsoredFeePaymentMethod(sponsor);
321
197
  }
322
198
  case undefined:
323
199
  throw new Error('Missing "method" in payment option');
@@ -328,11 +204,14 @@ export function parsePaymentMethod(
328
204
  }
329
205
 
330
206
  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>);
207
+ const parsed = gasLimits.split(',').reduce(
208
+ (acc, limit) => {
209
+ const [dimension, value] = limit.split('=');
210
+ acc[dimension] = parseInt(value, 10);
211
+ return acc;
212
+ },
213
+ {} as Record<string, number>,
214
+ );
336
215
 
337
216
  const expected = ['da', 'l2', 'teardownDA', 'teardownL2'];
338
217
  for (const dimension of expected) {
@@ -348,11 +227,14 @@ function parseGasLimits(gasLimits: string): { gasLimits: Gas; teardownGasLimits:
348
227
  }
349
228
 
350
229
  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>);
230
+ const parsed = gasFees.split(',').reduce(
231
+ (acc, fee) => {
232
+ const [dimension, value] = fee.split('=');
233
+ acc[dimension] = parseInt(value, 10);
234
+ return acc;
235
+ },
236
+ {} as Record<string, number>,
237
+ );
356
238
 
357
239
  const expected = ['da', 'l2'];
358
240
  for (const dimension of expected) {
@@ -363,3 +245,80 @@ export function parseGasFees(gasFees: string): GasFees {
363
245
 
364
246
  return new GasFees(parsed.da, parsed.l2);
365
247
  }
248
+ export class CLIFeeArgs {
249
+ constructor(
250
+ public estimateOnly: boolean,
251
+ private paymentMethod: (
252
+ wallet: Wallet,
253
+ feePayer: AztecAddress,
254
+ gasSettings: GasSettings,
255
+ ) => Promise<FeePaymentMethod | undefined>,
256
+ private gasSettings: Partial<FieldsOf<GasSettings>>,
257
+ ) {}
258
+
259
+ async toUserFeeOptions(node: AztecNode, wallet: Wallet, from: AztecAddress): Promise<ParsedFeeOptions> {
260
+ const minFees = await this.getMinFees(node);
261
+ const maxFeesPerGas = minFees.mul(1 + MIN_FEE_PADDING);
262
+ const gasSettings = GasSettings.fallback({ ...this.gasSettings, maxFeesPerGas });
263
+ const paymentMethod = await this.paymentMethod(wallet, from, gasSettings);
264
+ return {
265
+ paymentMethod,
266
+ gasSettings,
267
+ };
268
+ }
269
+
270
+ /**
271
+ * Returns the worst-case min fee across predicted future slots.
272
+ * Falls back to getCurrentMinFees if the node doesn't support getPredictedMinFees.
273
+ */
274
+ private async getMinFees(node: AztecNode): Promise<GasFees> {
275
+ try {
276
+ const predicted = await node.getPredictedMinFees(ManaUsageEstimate.Limit);
277
+ if (predicted.length === 0) {
278
+ return node.getCurrentMinFees();
279
+ }
280
+ return predicted.reduce((worst, fees) => (fees.feePerL2Gas > worst.feePerL2Gas ? fees : worst));
281
+ } catch (err: any) {
282
+ // Fallback for old nodes that don't support getPredictedMinFees.
283
+ // Only fall back on method-not-found errors (JSON-RPC code -32601); rethrow others.
284
+ if (err?.cause?.code === -32601 || err?.message?.includes('Method not found')) {
285
+ return node.getCurrentMinFees();
286
+ }
287
+ throw err;
288
+ }
289
+ }
290
+
291
+ static parse(args: RawCliFeeArgs, log: LogFn, db?: WalletDB): CLIFeeArgs {
292
+ const estimateOnly = !!args.estimateGasOnly;
293
+ return new CLIFeeArgs(
294
+ estimateOnly,
295
+ parsePaymentMethod(args.payment ?? 'method=fee_juice', log, db, estimateOnly),
296
+ parseGasSettings(args),
297
+ );
298
+ }
299
+
300
+ static getOptions() {
301
+ return getFeeOptions();
302
+ }
303
+ }
304
+
305
+ // Printing
306
+
307
+ export function printGasEstimates(
308
+ feeOpts: FeeOptions,
309
+ gasEstimates: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>,
310
+ log: LogFn,
311
+ ) {
312
+ log(`Estimated gas usage: ${formatGasEstimate(gasEstimates)}`);
313
+ log(`Maximum total tx fee: ${getEstimatedCost(gasEstimates, feeOpts.gasSettings.maxFeesPerGas)}`);
314
+ }
315
+
316
+ function formatGasEstimate(estimate: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>) {
317
+ return `da=${estimate.gasLimits.daGas},l2=${estimate.gasLimits.l2Gas},teardownDA=${estimate.teardownGasLimits.daGas},teardownL2=${estimate.teardownGasLimits.l2Gas}`;
318
+ }
319
+
320
+ function getEstimatedCost(estimate: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>, maxFeesPerGas: GasFees) {
321
+ return GasSettings.fallback({ ...estimate, maxFeesPerGas })
322
+ .getFeeLimit()
323
+ .toBigInt();
324
+ }
@@ -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 '../constants.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
+ }