@aztec/cli-wallet 0.77.0-testnet-ignition.30 → 0.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dest/bin/index.js CHANGED
@@ -4,6 +4,7 @@ import { createConsoleLogger, createLogger } from '@aztec/foundation/log';
4
4
  import { openStoreAt } from '@aztec/kv-store/lmdb-v2';
5
5
  import { Argument, Command, Option } from 'commander';
6
6
  import { mkdirSync, readFileSync } from 'fs';
7
+ import { homedir } from 'os';
7
8
  import { dirname, join, resolve } from 'path';
8
9
  import { injectCommands } from '../cmds/index.js';
9
10
  import { Aliases, WalletDB } from '../storage/wallet_db.js';
@@ -11,7 +12,7 @@ import { createAliasOption } from '../utils/options/index.js';
11
12
  import { PXEWrapper } from '../utils/pxe_wrapper.js';
12
13
  const userLog = createConsoleLogger();
13
14
  const debugLogger = createLogger('wallet');
14
- const { WALLET_DATA_DIRECTORY = '~/.aztec/wallet', PXE_PROVER = 'none' } = process.env;
15
+ const { WALLET_DATA_DIRECTORY = join(homedir(), '.aztec/wallet'), PXE_PROVER = 'none' } = process.env;
15
16
  function injectInternalCommands(program, log, db) {
16
17
  program.command('alias').description('Aliases information for easy reference.').addArgument(new Argument('<type>', 'Type of alias to create').choices(Aliases)).argument('<key>', 'Key to alias.').argument('<value>', 'Value to assign to the alias.').action(async (type, key, value)=>{
17
18
  value = db.tryRetrieveAlias(value) || value;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cmds/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAI3D,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AAGjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAsBxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,KAAK,EACV,WAAW,EAAE,MAAM,EACnB,EAAE,CAAC,EAAE,QAAQ,EACb,UAAU,CAAC,EAAE,UAAU,WAskBxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cmds/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAI3D,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AAGjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAsBxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,KAAK,EACV,WAAW,EAAE,MAAM,EACnB,EAAE,CAAC,EAAE,QAAQ,EACb,UAAU,CAAC,EAAE,UAAU,WA6kBxB"}
@@ -7,7 +7,7 @@ import { createAztecNodeClient } from '@aztec/stdlib/interfaces/client';
7
7
  import { Option } from 'commander';
8
8
  import inquirer from 'inquirer';
9
9
  import { addScopeToWallet, createOrRetrieveAccount, getWalletWithScopes } from '../utils/accounts.js';
10
- import { FeeOpts } from '../utils/options/fees.js';
10
+ import { FeeOpts, FeeOptsWithFeePayer } from '../utils/options/fees.js';
11
11
  import { ARTIFACT_DESCRIPTION, aliasedAddressParser, aliasedAuthWitParser, aliasedSecretKeyParser, aliasedTxHashParser, artifactPathFromPromiseOrAlias, artifactPathParser, createAccountOption, createAliasOption, createArgsOption, createArtifactOption, createContractAddressOption, createProfileOption, createTypeOption, integerArgParser, parseGasFees, parsePaymentMethod } from '../utils/options/index.js';
12
12
  export function injectCommands(program, log, debugLogger, db, pxeWrapper) {
13
13
  program.command('import-test-accounts').description('Import test accounts from pxe.').addOption(pxeOption).option('--json', 'Emit output as json').action(async (options)=>{
@@ -22,7 +22,7 @@ export function injectCommands(program, log, debugLogger, db, pxeWrapper) {
22
22
  const createAccountCommand = program.command('create-account').description('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).').summary('Creates an aztec account that can be used for sending transactions.').option('--skip-initialization', 'Skip initializing the account contract. Useful for publicly deploying an existing account.').option('--public-deploy', 'Publicly deploys the account and registers the class if needed.').option('-p, --public-key <string>', 'Public key that identifies a private signing key stored outside of the wallet. Used for ECDSA SSH accounts over the secp256r1 curve.').addOption(pxeOption).addOption(createSecretKeyOption('Secret key for account. Uses random by default.', false, (sk)=>aliasedSecretKeyParser(sk, db)).conflicts('public-key')).addOption(createAliasOption('Alias for the account. Used for easy reference in subsequent commands.', !db)).addOption(createTypeOption(true)).option('--register-only', 'Just register the account on the PXE. Do not deploy or initialize the account contract.').option('--json', 'Emit output as json')// `options.wait` is default true. Passing `--no-wait` will set it to false.
23
23
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
24
24
  .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction');
25
- addOptions(createAccountCommand, FeeOpts.getOptions()).action(async (_options, command)=>{
25
+ addOptions(createAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command)=>{
26
26
  const { createAccount } = await import('./create_account.js');
27
27
  const options = command.optsWithGlobals();
28
28
  const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, rpcUrl, alias, json } = options;
@@ -40,7 +40,7 @@ export function injectCommands(program, log, debugLogger, db, pxeWrapper) {
40
40
  publicKey = answers.identity.split(' ')[1];
41
41
  }
42
42
  const client = pxeWrapper?.getPXE() ?? await createCompatibleClient(rpcUrl, debugLogger);
43
- const accountCreationResult = await createAccount(client, type, secretKey, publicKey, alias, registerOnly, skipInitialization, publicDeploy, wait, await FeeOpts.fromCli(options, client, log, db), json, debugLogger, log);
43
+ const accountCreationResult = await createAccount(client, type, secretKey, publicKey, alias, registerOnly, skipInitialization, publicDeploy, wait, await FeeOptsWithFeePayer.fromCli(options, client, log, db), json, debugLogger, log);
44
44
  if (db) {
45
45
  const { address, alias, secretKey, salt } = accountCreationResult;
46
46
  await db.storeAccount(address, {
@@ -55,13 +55,13 @@ export function injectCommands(program, log, debugLogger, db, pxeWrapper) {
55
55
  const deployAccountCommand = program.command('deploy-account').description('Deploys an already registered aztec account that can be used for sending transactions.').addOption(createAccountOption('Alias or address of the account to deploy', !db, db)).addOption(pxeOption).option('--json', 'Emit output as json')// `options.wait` is default true. Passing `--no-wait` will set it to false.
56
56
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
57
57
  .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction');
58
- addOptions(deployAccountCommand, FeeOpts.getOptions()).action(async (_options, command)=>{
58
+ addOptions(deployAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command)=>{
59
59
  const { deployAccount } = await import('./deploy_account.js');
60
60
  const options = command.optsWithGlobals();
61
61
  const { rpcUrl, wait, from: parsedFromAddress, json } = options;
62
62
  const client = pxeWrapper?.getPXE() ?? await createCompatibleClient(rpcUrl, debugLogger);
63
63
  const account = await createOrRetrieveAccount(client, parsedFromAddress, db);
64
- await deployAccount(account, wait, await FeeOpts.fromCli(options, client, log, db), json, debugLogger, log);
64
+ await deployAccount(account, wait, await FeeOptsWithFeePayer.fromCli(options, client, log, db), json, debugLogger, log);
65
65
  });
66
66
  const deployCommand = program.command('deploy').description('Deploys a compiled Aztec.nr contract to Aztec.').argument('[artifact]', ARTIFACT_DESCRIPTION, artifactPathParser).option('--init <string>', 'The contract initializer function to call', 'constructor').option('--no-init', 'Leave the contract uninitialized').option('-k, --public-key <string>', '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.', parsePublicKey).option('-s, --salt <hex string>', 'Optional deployment salt as a hex string for generating the deployment address.', parseFieldFromHexString).option('--universal', 'Do not mix the sender address into the deployment.').addOption(pxeOption).addOption(createArgsOption(true, db)).addOption(createSecretKeyOption("The sender's secret key", !db, (sk)=>aliasedSecretKeyParser(sk, db)).conflicts('account')).addOption(createAccountOption('Alias or address of the account to deploy from', !db, db)).addOption(createAliasOption('Alias for the contract. Used for easy reference subsequent commands.', !db)).option('--json', 'Emit output as json')// `options.wait` is default true. Passing `--no-wait` will set it to false.
67
67
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
@@ -192,7 +192,7 @@ export function injectCommands(program, log, debugLogger, db, pxeWrapper) {
192
192
  if (!txData) {
193
193
  throw new Error('Transaction data not found in the database, cannot reuse nonce');
194
194
  }
195
- const paymentMethod = await parsePaymentMethod(payment, log, db)(wallet);
195
+ const paymentMethod = await parsePaymentMethod(payment, false, log, db)(wallet);
196
196
  await cancelTx(wallet, txData, paymentMethod, increasedFees, maxFeesPerGas, log);
197
197
  });
198
198
  program.command('register-sender').description("Registers a sender's address in the wallet, so the note synching process will look for notes sent by them").argument('[address]', 'The address of the sender to register', (address)=>aliasedAddressParser('accounts', address, db)).addOption(pxeOption).addOption(createAccountOption('Alias or address of the account to simulate from', !db, db)).addOption(createAliasOption('Alias for the sender. Used for easy reference in subsequent commands.', !db)).action(async (address, options)=>{
@@ -31,6 +31,11 @@ export declare class FeeOpts implements IFeeOpts {
31
31
  static getOptions(): Option[];
32
32
  static fromCli(args: CliFeeArgs, pxe: PXE, log: LogFn, db?: WalletDB): Promise<FeeOpts>;
33
33
  }
34
- export declare function parsePaymentMethod(payment: string, log: LogFn, db?: WalletDB): (sender: AccountWallet) => Promise<FeePaymentMethod>;
34
+ export declare class FeeOptsWithFeePayer extends FeeOpts {
35
+ static paymentMethodOption(): Option;
36
+ static getOptions(): Option[];
37
+ static fromCli(args: CliFeeArgs, pxe: PXE, log: LogFn, db?: WalletDB): Promise<FeeOptsWithFeePayer>;
38
+ }
39
+ export declare function parsePaymentMethod(payment: string, allowCustomFeePayer: boolean, log: LogFn, db?: WalletDB): (sender: AccountWallet) => Promise<FeePaymentMethod>;
35
40
  export declare function parseGasFees(gasFees: string): GasFees;
36
41
  //# sourceMappingURL=fees.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fees.d.ts","sourceRoot":"","sources":["../../../src/utils/options/fees.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAEzB,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACR,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAO,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAI3D,MAAM,MAAM,UAAU,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9D,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC3E;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,QAAQ,EACjB,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,mBAAmB,CAAC,EAClE,GAAG,EAAE,KAAK,QAIX;AAYD,qBAAa,OAAQ,YAAW,QAAQ;IAE7B,YAAY,EAAE,OAAO;IACrB,WAAW,EAAE,WAAW;IAC/B,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;gBAPZ,YAAY,EAAE,OAAO,EACrB,WAAW,EAAE,WAAW,EACvB,oBAAoB,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC,EAC1E,eAAe,EAAE,CACvB,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,gBAAgB,KAC5B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,EAC/B,WAAW,EAAE,OAAO;IAGxB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAU7D,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAa/E,MAAM,CAAC,mBAAmB;IAO1B,MAAM,CAAC,UAAU;WAcJ,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,QAAQ;CAkC3E;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,KAAK,EACV,EAAE,CAAC,EAAE,QAAQ,GACZ,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAuEtD;AAsBD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAerD"}
1
+ {"version":3,"file":"fees.d.ts","sourceRoot":"","sources":["../../../src/utils/options/fees.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAEzB,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACR,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAO,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAI3D,MAAM,MAAM,UAAU,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9D,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC3E;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,QAAQ,EACjB,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,mBAAmB,CAAC,EAClE,GAAG,EAAE,KAAK,QAIX;AAuGD,qBAAa,OAAQ,YAAW,QAAQ;IAE7B,YAAY,EAAE,OAAO;IACrB,WAAW,EAAE,WAAW;IAC/B,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;gBAPZ,YAAY,EAAE,OAAO,EACrB,WAAW,EAAE,WAAW,EACvB,oBAAoB,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC,EAC1E,eAAe,EAAE,CACvB,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,gBAAgB,KAC5B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,EAC/B,WAAW,EAAE,OAAO;IAGxB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAU7D,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAa/E,MAAM,CAAC,mBAAmB;IAI1B,MAAM,CAAC,UAAU;WAIJ,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,QAAQ;CAsB3E;AAED,qBAAa,mBAAoB,SAAQ,OAAO;WAC9B,mBAAmB;WAInB,UAAU;WAIJ,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,QAAQ;CA2BpF;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,OAAO,EAC5B,GAAG,EAAE,KAAK,EACV,EAAE,CAAC,EAAE,QAAQ,GACZ,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAwEtD;AAsBD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAerD"}
@@ -18,6 +18,85 @@ function getEstimatedCost(estimate, maxFeesPerGas) {
18
18
  maxFeesPerGas
19
19
  }).getFeeLimit().toBigInt();
20
20
  }
21
+ async function parseGasSettings(args, pxe) {
22
+ const gasLimits = args.gasLimits ? parseGasLimits(args.gasLimits) : {};
23
+ const maxFeesPerGas = args.maxFeesPerGas ? parseGasFees(args.maxFeesPerGas) : await pxe.getCurrentBaseFees();
24
+ const maxPriorityFeesPerGas = args.maxPriorityFeesPerGas ? parseGasFees(args.maxPriorityFeesPerGas) : undefined;
25
+ return GasSettings.default({
26
+ ...gasLimits,
27
+ maxFeesPerGas,
28
+ maxPriorityFeesPerGas
29
+ });
30
+ }
31
+ function printOptionParams(params) {
32
+ const paramsWithDescription = Object.keys(params).filter((name)=>params[name].description);
33
+ const maxParamWidth = paramsWithDescription.reduce((v, name)=>Math.max(v, name.length), 0);
34
+ const indent = (size)=>''.padEnd(size, ' ');
35
+ const descriptionList = paramsWithDescription.map((name)=>[
36
+ `${indent(5)}${name}${indent(maxParamWidth - name.length)} ${params[name].description}`,
37
+ params[name].default ? `Default: ${params[name].default}` : ''
38
+ ].join(' '));
39
+ return descriptionList.length ? `\n Parameters:\n${descriptionList.join('\n')}` : '';
40
+ }
41
+ function getFeePaymentMethodParams(allowCustomFeePayer) {
42
+ const feePayer = allowCustomFeePayer ? {
43
+ type: 'address',
44
+ description: 'The account paying the fee.'
45
+ } : undefined;
46
+ return {
47
+ method: {
48
+ type: 'name',
49
+ description: 'Valid values: "fee_juice", "fpc-public", "fpc-private".',
50
+ default: 'fee_juice'
51
+ },
52
+ ...feePayer ? {
53
+ feePayer
54
+ } : {},
55
+ asset: {
56
+ type: 'address',
57
+ description: 'The asset used for fee payment. Not required for the "fee_juice" method.'
58
+ },
59
+ fpc: {
60
+ type: 'address',
61
+ description: 'The FPC contract that pays in fee juice. Not required for the "fee_juice" method.'
62
+ },
63
+ claim: {
64
+ type: 'boolean',
65
+ description: 'Whether to use a previously stored claim to bridge fee juice.'
66
+ },
67
+ claimSecret: {
68
+ type: 'string',
69
+ description: 'The secret to claim fee juice on L1.'
70
+ },
71
+ claimAmount: {
72
+ type: 'bigint',
73
+ description: 'The amount of fee juice to be claimed.'
74
+ },
75
+ messageLeafIndex: {
76
+ type: 'bigint',
77
+ description: 'The index of the claim in the l1toL2Message tree.'
78
+ },
79
+ feeRecipient: {
80
+ type: 'string',
81
+ description: 'Recipient of the fee.'
82
+ }
83
+ };
84
+ }
85
+ function getPaymentMethodOption(allowCustomFeePayer) {
86
+ const params = getFeePaymentMethodParams(allowCustomFeePayer);
87
+ const paramList = Object.keys(params).map((name)=>`${name}=${params[name].type}`);
88
+ return new Option(`--payment <${paramList.join(',')}>`, `Fee payment method and arguments.${printOptionParams(params)}`);
89
+ }
90
+ function getFeeOptions(allowCustomFeePayer) {
91
+ return [
92
+ getPaymentMethodOption(allowCustomFeePayer),
93
+ new Option('--gas-limits <da=100,l2=100,teardownDA=10,teardownL2=10>', 'Gas limits for the tx.'),
94
+ new Option('--max-fees-per-gas <da=100,l2=100>', 'Maximum fees per gas unit for DA and L2 computation.'),
95
+ new Option('--max-priority-fees-per-gas <da=0,l2=0>', 'Maximum priority fees per gas unit for DA and L2 computation.'),
96
+ new Option('--no-estimate-gas', 'Whether to automatically estimate gas limits for the tx.'),
97
+ new Option('--estimate-gas-only', 'Only report gas estimation for the tx, do not send it.')
98
+ ];
99
+ }
21
100
  export class FeeOpts {
22
101
  estimateOnly;
23
102
  gasSettings;
@@ -53,28 +132,35 @@ export class FeeOpts {
53
132
  };
54
133
  }
55
134
  static paymentMethodOption() {
56
- return new Option('--payment <method=name,feePayer=string,asset=address,fpc=address,claimSecret=string,claimAmount=string,feeRecipient=string>', 'Fee payment method and arguments. Valid methods are: fee_juice, fpc-public, fpc-private.');
135
+ return getPaymentMethodOption(false);
57
136
  }
58
137
  static getOptions() {
59
- return [
60
- new Option('--gas-limits <da=100,l2=100,teardownDA=10,teardownL2=10>', 'Gas limits for the tx.'),
61
- FeeOpts.paymentMethodOption(),
62
- new Option('--max-fees-per-gas <da=100,l2=100>', 'Maximum fees per gas unit for DA and L2 computation.'),
63
- new Option('--max-priority-fees-per-gas <da=0,l2=0>', 'Maximum priority fees per gas unit for DA and L2 computation.'),
64
- new Option('--no-estimate-gas', 'Whether to automatically estimate gas limits for the tx.'),
65
- new Option('--estimate-gas-only', 'Only report gas estimation for the tx, do not send it.')
66
- ];
138
+ return getFeeOptions(false);
139
+ }
140
+ static async fromCli(args, pxe, log, db) {
141
+ const estimateOnly = args.estimateGasOnly;
142
+ const gasSettings = await parseGasSettings(args, pxe);
143
+ const defaultPaymentMethod = async (sender)=>{
144
+ const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
145
+ return new FeeJuicePaymentMethod(sender.getAddress());
146
+ };
147
+ const getDeployWallet = ()=>{
148
+ // Returns undefined. The sender's wallet will be used by default.
149
+ return Promise.resolve(undefined);
150
+ };
151
+ return new FeeOpts(estimateOnly, gasSettings, args.payment ? parsePaymentMethod(args.payment, false, log, db) : defaultPaymentMethod, getDeployWallet, !!args.estimateGas);
152
+ }
153
+ }
154
+ export class FeeOptsWithFeePayer extends FeeOpts {
155
+ static paymentMethodOption() {
156
+ return getPaymentMethodOption(true);
157
+ }
158
+ static getOptions() {
159
+ return getFeeOptions(true);
67
160
  }
68
161
  static async fromCli(args, pxe, log, db) {
69
162
  const estimateOnly = args.estimateGasOnly;
70
- const gasLimits = args.gasLimits ? parseGasLimits(args.gasLimits) : {};
71
- const maxFeesPerGas = args.maxFeesPerGas ? parseGasFees(args.maxFeesPerGas) : await pxe.getCurrentBaseFees();
72
- const maxPriorityFeesPerGas = args.maxPriorityFeesPerGas ? parseGasFees(args.maxPriorityFeesPerGas) : undefined;
73
- const gasSettings = GasSettings.default({
74
- ...gasLimits,
75
- maxFeesPerGas,
76
- maxPriorityFeesPerGas
77
- });
163
+ const gasSettings = await parseGasSettings(args, pxe);
78
164
  const defaultPaymentMethod = async (sender)=>{
79
165
  const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
80
166
  return new FeeJuicePaymentMethod(sender.getAddress());
@@ -88,10 +174,10 @@ export class FeeOpts {
88
174
  }
89
175
  return undefined;
90
176
  };
91
- return new FeeOpts(estimateOnly, gasSettings, args.payment ? parsePaymentMethod(args.payment, log, db) : defaultPaymentMethod, getDeployWallet, !!args.estimateGas);
177
+ return new FeeOptsWithFeePayer(estimateOnly, gasSettings, args.payment ? parsePaymentMethod(args.payment, true, log, db) : defaultPaymentMethod, getDeployWallet, !!args.estimateGas);
92
178
  }
93
179
  }
94
- export function parsePaymentMethod(payment, log, db) {
180
+ export function parsePaymentMethod(payment, allowCustomFeePayer, log, db) {
95
181
  const parsed = payment.split(',').reduce((acc, item)=>{
96
182
  const [dimension, value] = item.split('=');
97
183
  acc[dimension] = value ?? 1;
@@ -131,7 +217,7 @@ export function parsePaymentMethod(payment, log, db) {
131
217
  } else {
132
218
  log(`Using Fee Juice for fee payment`);
133
219
  const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
134
- const feePayer = parsed.feePayer ? aliasedAddressParser('accounts', parsed.feePayer, db) : sender.getAddress();
220
+ const feePayer = parsed.feePayer && allowCustomFeePayer ? aliasedAddressParser('accounts', parsed.feePayer, db) : sender.getAddress();
135
221
  return new FeeJuicePaymentMethod(feePayer);
136
222
  }
137
223
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/cli-wallet",
3
- "version": "0.77.0-testnet-ignition.30",
3
+ "version": "0.77.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/cmds/index.js",
@@ -65,15 +65,15 @@
65
65
  ]
66
66
  },
67
67
  "dependencies": {
68
- "@aztec/accounts": "0.77.0-testnet-ignition.30",
69
- "@aztec/aztec.js": "0.77.0-testnet-ignition.30",
70
- "@aztec/cli": "0.77.0-testnet-ignition.30",
71
- "@aztec/ethereum": "0.77.0-testnet-ignition.30",
72
- "@aztec/foundation": "0.77.0-testnet-ignition.30",
73
- "@aztec/kv-store": "0.77.0-testnet-ignition.30",
74
- "@aztec/noir-contracts.js": "0.77.0-testnet-ignition.30",
75
- "@aztec/pxe": "0.77.0-testnet-ignition.30",
76
- "@aztec/stdlib": "0.77.0-testnet-ignition.30",
68
+ "@aztec/accounts": "0.77.0",
69
+ "@aztec/aztec.js": "0.77.0",
70
+ "@aztec/cli": "0.77.0",
71
+ "@aztec/ethereum": "0.77.0",
72
+ "@aztec/foundation": "0.77.0",
73
+ "@aztec/kv-store": "0.77.0",
74
+ "@aztec/noir-contracts.js": "0.77.0",
75
+ "@aztec/pxe": "0.77.0",
76
+ "@aztec/stdlib": "0.77.0",
77
77
  "commander": "^12.1.0",
78
78
  "inquirer": "^10.1.8",
79
79
  "source-map-support": "^0.5.21",
package/src/bin/index.ts CHANGED
@@ -5,6 +5,7 @@ import { openStoreAt } from '@aztec/kv-store/lmdb-v2';
5
5
 
6
6
  import { Argument, Command, Option } from 'commander';
7
7
  import { mkdirSync, readFileSync } from 'fs';
8
+ import { homedir } from 'os';
8
9
  import { dirname, join, resolve } from 'path';
9
10
 
10
11
  import { injectCommands } from '../cmds/index.js';
@@ -15,7 +16,7 @@ import { PXEWrapper } from '../utils/pxe_wrapper.js';
15
16
  const userLog = createConsoleLogger();
16
17
  const debugLogger = createLogger('wallet');
17
18
 
18
- const { WALLET_DATA_DIRECTORY = '~/.aztec/wallet', PXE_PROVER = 'none' } = process.env;
19
+ const { WALLET_DATA_DIRECTORY = join(homedir(), '.aztec/wallet'), PXE_PROVER = 'none' } = process.env;
19
20
 
20
21
  function injectInternalCommands(program: Command, log: LogFn, db: WalletDB) {
21
22
  program
package/src/cmds/index.ts CHANGED
@@ -22,7 +22,7 @@ import inquirer from 'inquirer';
22
22
 
23
23
  import type { WalletDB } from '../storage/wallet_db.js';
24
24
  import { type AccountType, addScopeToWallet, createOrRetrieveAccount, getWalletWithScopes } from '../utils/accounts.js';
25
- import { FeeOpts } from '../utils/options/fees.js';
25
+ import { FeeOpts, FeeOptsWithFeePayer } from '../utils/options/fees.js';
26
26
  import {
27
27
  ARTIFACT_DESCRIPTION,
28
28
  aliasedAddressParser,
@@ -100,7 +100,7 @@ export function injectCommands(
100
100
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
101
101
  .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction');
102
102
 
103
- addOptions(createAccountCommand, FeeOpts.getOptions()).action(async (_options, command) => {
103
+ addOptions(createAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
104
104
  const { createAccount } = await import('./create_account.js');
105
105
  const options = command.optsWithGlobals();
106
106
  const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, rpcUrl, alias, json } = options;
@@ -129,7 +129,7 @@ export function injectCommands(
129
129
  skipInitialization,
130
130
  publicDeploy,
131
131
  wait,
132
- await FeeOpts.fromCli(options, client, log, db),
132
+ await FeeOptsWithFeePayer.fromCli(options, client, log, db),
133
133
  json,
134
134
  debugLogger,
135
135
  log,
@@ -150,7 +150,7 @@ export function injectCommands(
150
150
  // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
151
151
  .option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction');
152
152
 
153
- addOptions(deployAccountCommand, FeeOpts.getOptions()).action(async (_options, command) => {
153
+ addOptions(deployAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
154
154
  const { deployAccount } = await import('./deploy_account.js');
155
155
  const options = command.optsWithGlobals();
156
156
  const { rpcUrl, wait, from: parsedFromAddress, json } = options;
@@ -158,7 +158,14 @@ export function injectCommands(
158
158
  const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
159
159
  const account = await createOrRetrieveAccount(client, parsedFromAddress, db);
160
160
 
161
- await deployAccount(account, wait, await FeeOpts.fromCli(options, client, log, db), json, debugLogger, log);
161
+ await deployAccount(
162
+ account,
163
+ wait,
164
+ await FeeOptsWithFeePayer.fromCli(options, client, log, db),
165
+ json,
166
+ debugLogger,
167
+ log,
168
+ );
162
169
  });
163
170
 
164
171
  const deployCommand = program
@@ -572,7 +579,7 @@ export function injectCommands(
572
579
  throw new Error('Transaction data not found in the database, cannot reuse nonce');
573
580
  }
574
581
 
575
- const paymentMethod = await parsePaymentMethod(payment, log, db)(wallet);
582
+ const paymentMethod = await parsePaymentMethod(payment, false, log, db)(wallet);
576
583
 
577
584
  await cancelTx(wallet, txData, paymentMethod, increasedFees, maxFeesPerGas, log);
578
585
  });
@@ -52,6 +52,97 @@ function getEstimatedCost(estimate: Pick<GasSettings, 'gasLimits' | 'teardownGas
52
52
  .toBigInt();
53
53
  }
54
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
+ }
65
+
66
+ type OptionParams = {
67
+ [key: string]: { type: string; description?: string; default?: string };
68
+ };
69
+
70
+ function printOptionParams(params: OptionParams) {
71
+ const paramsWithDescription = Object.keys(params).filter(name => params[name].description);
72
+ const maxParamWidth = paramsWithDescription.reduce((v, name) => Math.max(v, name.length), 0);
73
+ const indent = (size: number) => ''.padEnd(size, ' ');
74
+ const descriptionList = paramsWithDescription.map(name =>
75
+ [
76
+ `${indent(5)}${name}${indent(maxParamWidth - name.length)} ${params[name].description}`,
77
+ params[name].default ? `Default: ${params[name].default}` : '',
78
+ ].join(' '),
79
+ );
80
+ return descriptionList.length ? `\n Parameters:\n${descriptionList.join('\n')}` : '';
81
+ }
82
+
83
+ function getFeePaymentMethodParams(allowCustomFeePayer: boolean): OptionParams {
84
+ const feePayer = allowCustomFeePayer ? { type: 'address', description: 'The account paying the fee.' } : undefined;
85
+ return {
86
+ method: {
87
+ type: 'name',
88
+ description: 'Valid values: "fee_juice", "fpc-public", "fpc-private".',
89
+ default: 'fee_juice',
90
+ },
91
+ ...(feePayer ? { feePayer } : {}),
92
+ asset: {
93
+ type: 'address',
94
+ description: 'The asset used for fee payment. Not required for the "fee_juice" method.',
95
+ },
96
+ fpc: {
97
+ type: 'address',
98
+ description: 'The FPC contract that pays in fee juice. Not required for the "fee_juice" method.',
99
+ },
100
+ claim: {
101
+ type: 'boolean',
102
+ description: 'Whether to use a previously stored claim to bridge fee juice.',
103
+ },
104
+ claimSecret: {
105
+ type: 'string',
106
+ description: 'The secret to claim fee juice on L1.',
107
+ },
108
+ claimAmount: {
109
+ type: 'bigint',
110
+ description: 'The amount of fee juice to be claimed.',
111
+ },
112
+ messageLeafIndex: {
113
+ type: 'bigint',
114
+ description: 'The index of the claim in the l1toL2Message tree.',
115
+ },
116
+ feeRecipient: {
117
+ type: 'string',
118
+ description: 'Recipient of the fee.',
119
+ },
120
+ };
121
+ }
122
+
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
+ );
130
+ }
131
+
132
+ function getFeeOptions(allowCustomFeePayer: boolean) {
133
+ return [
134
+ getPaymentMethodOption(allowCustomFeePayer),
135
+ new Option('--gas-limits <da=100,l2=100,teardownDA=10,teardownL2=10>', 'Gas limits for the tx.'),
136
+ new Option('--max-fees-per-gas <da=100,l2=100>', 'Maximum fees per gas unit for DA and L2 computation.'),
137
+ new Option(
138
+ '--max-priority-fees-per-gas <da=0,l2=0>',
139
+ 'Maximum priority fees per gas unit for DA and L2 computation.',
140
+ ),
141
+ new Option('--no-estimate-gas', 'Whether to automatically estimate gas limits for the tx.'),
142
+ new Option('--estimate-gas-only', 'Only report gas estimation for the tx, do not send it.'),
143
+ ];
144
+ }
145
+
55
146
  export class FeeOpts implements IFeeOpts {
56
147
  constructor(
57
148
  public estimateOnly: boolean,
@@ -88,36 +179,49 @@ export class FeeOpts implements IFeeOpts {
88
179
  }
89
180
 
90
181
  static paymentMethodOption() {
91
- return new Option(
92
- '--payment <method=name,feePayer=string,asset=address,fpc=address,claimSecret=string,claimAmount=string,feeRecipient=string>',
93
- 'Fee payment method and arguments. Valid methods are: fee_juice, fpc-public, fpc-private.',
94
- );
182
+ return getPaymentMethodOption(false);
95
183
  }
96
184
 
97
185
  static getOptions() {
98
- return [
99
- new Option('--gas-limits <da=100,l2=100,teardownDA=10,teardownL2=10>', 'Gas limits for the tx.'),
100
- FeeOpts.paymentMethodOption(),
101
- new Option('--max-fees-per-gas <da=100,l2=100>', 'Maximum fees per gas unit for DA and L2 computation.'),
102
- new Option(
103
- '--max-priority-fees-per-gas <da=0,l2=0>',
104
- 'Maximum priority fees per gas unit for DA and L2 computation.',
105
- ),
106
- new Option('--no-estimate-gas', 'Whether to automatically estimate gas limits for the tx.'),
107
- new Option('--estimate-gas-only', 'Only report gas estimation for the tx, do not send it.'),
108
- ];
186
+ return getFeeOptions(false);
109
187
  }
110
188
 
111
189
  static async fromCli(args: CliFeeArgs, pxe: PXE, log: LogFn, db?: WalletDB) {
112
190
  const estimateOnly = args.estimateGasOnly;
113
- const gasLimits = args.gasLimits ? parseGasLimits(args.gasLimits) : {};
114
- const maxFeesPerGas = args.maxFeesPerGas ? parseGasFees(args.maxFeesPerGas) : await pxe.getCurrentBaseFees();
115
- const maxPriorityFeesPerGas = args.maxPriorityFeesPerGas ? parseGasFees(args.maxPriorityFeesPerGas) : undefined;
116
- const gasSettings = GasSettings.default({
117
- ...gasLimits,
118
- maxFeesPerGas,
119
- maxPriorityFeesPerGas,
120
- });
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);
121
225
 
122
226
  const defaultPaymentMethod = async (sender: AccountWallet) => {
123
227
  const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
@@ -134,10 +238,10 @@ export class FeeOpts implements IFeeOpts {
134
238
  return undefined;
135
239
  };
136
240
 
137
- return new FeeOpts(
241
+ return new FeeOptsWithFeePayer(
138
242
  estimateOnly,
139
243
  gasSettings,
140
- args.payment ? parsePaymentMethod(args.payment, log, db) : defaultPaymentMethod,
244
+ args.payment ? parsePaymentMethod(args.payment, true, log, db) : defaultPaymentMethod,
141
245
  getDeployWallet,
142
246
  !!args.estimateGas,
143
247
  );
@@ -146,6 +250,7 @@ export class FeeOpts implements IFeeOpts {
146
250
 
147
251
  export function parsePaymentMethod(
148
252
  payment: string,
253
+ allowCustomFeePayer: boolean,
149
254
  log: LogFn,
150
255
  db?: WalletDB,
151
256
  ): (sender: AccountWallet) => Promise<FeePaymentMethod> {
@@ -195,9 +300,10 @@ export function parsePaymentMethod(
195
300
  } else {
196
301
  log(`Using Fee Juice for fee payment`);
197
302
  const { FeeJuicePaymentMethod } = await import('@aztec/aztec.js/fee');
198
- const feePayer = parsed.feePayer
199
- ? aliasedAddressParser('accounts', parsed.feePayer, db)
200
- : sender.getAddress();
303
+ const feePayer =
304
+ parsed.feePayer && allowCustomFeePayer
305
+ ? aliasedAddressParser('accounts', parsed.feePayer, db)
306
+ : sender.getAddress();
201
307
  return new FeeJuicePaymentMethod(feePayer);
202
308
  }
203
309
  }