From f05f8b9c191721de87bff3cdfcd4ff759d4a5838 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 17:36:12 -0700 Subject: [PATCH 01/11] update dependency to `clap-v3` and `solana-clap-v3-utils` --- Cargo.lock | 4 ++-- token/cli/Cargo.toml | 4 ++-- token/cli/src/bench.rs | 2 +- token/cli/src/config.rs | 2 +- token/cli/src/main.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be8f16d15ba..f25a593ccc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7053,14 +7053,14 @@ name = "spl-token-cli" version = "3.1.0" dependencies = [ "assert_cmd", - "clap 2.34.0", + "clap 3.2.25", "console", "serde", "serde_derive", "serde_json", "serial_test", "solana-account-decoder", - "solana-clap-utils", + "solana-clap-v3-utils", "solana-cli-config", "solana-cli-output", "solana-client", diff --git a/token/cli/Cargo.toml b/token/cli/Cargo.toml index 46b247b624f..22fed5fac9c 100644 --- a/token/cli/Cargo.toml +++ b/token/cli/Cargo.toml @@ -12,13 +12,13 @@ version = "3.1.0" walkdir = "2" [dependencies] -clap = "2.33.3" +clap = "3.2.23" console = "0.15.7" serde = "1.0.188" serde_derive = "1.0.103" serde_json = "1.0.105" solana-account-decoder = "=1.16.3" -solana-clap-utils = "=1.16.3" +solana-clap-v3-utils = "=1.16.3" solana-cli-config = "=1.16.3" solana-cli-output = "=1.16.3" solana-client = "=1.16.3" diff --git a/token/cli/src/bench.rs b/token/cli/src/bench.rs index 9c0a83839c8..bd0bc85df21 100644 --- a/token/cli/src/bench.rs +++ b/token/cli/src/bench.rs @@ -2,7 +2,7 @@ use { crate::{config::Config, owner_address_arg, CommandResult, Error}, clap::{value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand}, - solana_clap_utils::{ + solana_clap_v3_utils::{ input_parsers::pubkey_of_signer, input_validators::{is_amount, is_parsable, is_valid_pubkey}, }, diff --git a/token/cli/src/config.rs b/token/cli/src/config.rs index e76b0f71b55..353626e2220 100644 --- a/token/cli/src/config.rs +++ b/token/cli/src/config.rs @@ -1,6 +1,6 @@ use crate::{signers_of, Error, MULTISIG_SIGNER_ARG}; use clap::ArgMatches; -use solana_clap_utils::{ +use solana_clap_v3_utils::{ input_parsers::{pubkey_of_signer, value_of}, input_validators::normalize_to_url_if_moniker, keypair::{signer_from_path, signer_from_path_with_config, SignerFromPathConfig}, diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 9edcc7c468d..d47e54dd01a 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -8,7 +8,7 @@ use solana_account_decoder::{ parse_token::{get_token_account_mint, parse_token, TokenAccountType, UiAccountState}, UiAccountData, }; -use solana_clap_utils::{ +use solana_clap_v3_utils::{ fee_payer::fee_payer_arg, input_parsers::{pubkey_of_signer, pubkeys_of_multiple_signers, value_of}, input_validators::{ From 70ecd77c83bf594767369a0d32bb9db78cd9ad54 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 17:38:04 -0700 Subject: [PATCH 02/11] remove extra lifetime parameters from `Arg` --- token/cli/src/bench.rs | 4 ++-- token/cli/src/config.rs | 12 ++++++------ token/cli/src/main.rs | 40 ++++++++++++++++++++-------------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/token/cli/src/bench.rs b/token/cli/src/bench.rs index bd0bc85df21..c0745bf504a 100644 --- a/token/cli/src/bench.rs +++ b/token/cli/src/bench.rs @@ -28,7 +28,7 @@ pub(crate) trait BenchSubCommand { fn bench_subcommand(self) -> Self; } -impl BenchSubCommand for App<'_, '_> { +impl BenchSubCommand for App<'_> { fn bench_subcommand(self) -> Self { self.subcommand( SubCommand::with_name("bench") @@ -166,7 +166,7 @@ impl BenchSubCommand for App<'_, '_> { } pub(crate) async fn bench_process_command( - matches: &ArgMatches<'_>, + matches: &ArgMatches, config: &Config<'_>, mut signers: Vec>, wallet_manager: &mut Option>, diff --git a/token/cli/src/config.rs b/token/cli/src/config.rs index 353626e2220..f6c085d1f47 100644 --- a/token/cli/src/config.rs +++ b/token/cli/src/config.rs @@ -49,7 +49,7 @@ pub(crate) struct Config<'a> { impl<'a> Config<'a> { pub(crate) async fn new( - matches: &ArgMatches<'_>, + matches: &ArgMatches, wallet_manager: &mut Option>, bulk_signers: &mut Vec>, multisigner_ids: &'a mut Vec, @@ -100,7 +100,7 @@ impl<'a> Config<'a> { } fn extract_multisig_signers( - matches: &ArgMatches<'_>, + matches: &ArgMatches, wallet_manager: &mut Option>, bulk_signers: &mut Vec>, multisigner_ids: &'a mut Vec, @@ -120,7 +120,7 @@ impl<'a> Config<'a> { } pub(crate) async fn new_with_clients_and_ws_url( - matches: &ArgMatches<'_>, + matches: &ArgMatches, wallet_manager: &mut Option>, bulk_signers: &mut Vec>, multisigner_ids: &'a mut Vec, @@ -303,7 +303,7 @@ impl<'a> Config<'a> { // return the associated token address for the default address. pub(crate) async fn associated_token_address_or_override( &self, - arg_matches: &ArgMatches<'_>, + arg_matches: &ArgMatches, override_name: &str, wallet_manager: &mut Option>, ) -> Result { @@ -322,7 +322,7 @@ impl<'a> Config<'a> { // return the associated token address for the default address. pub(crate) async fn associated_token_address_for_token_or_override( &self, - arg_matches: &ArgMatches<'_>, + arg_matches: &ArgMatches, override_name: &str, wallet_manager: &mut Option>, token: Option, @@ -353,7 +353,7 @@ impl<'a> Config<'a> { // Checks if an explicit address was provided, otherwise return the default address if there is one pub(crate) fn pubkey_or_default( &self, - arg_matches: &ArgMatches<'_>, + arg_matches: &ArgMatches, address_name: &str, wallet_manager: &mut Option>, ) -> Result { diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index d47e54dd01a..1be0a1d5df8 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -206,7 +206,7 @@ where } } -pub fn owner_address_arg<'a, 'b>() -> Arg<'a, 'b> { +pub fn owner_address_arg<'a>() -> Arg<'a> { Arg::with_name(OWNER_ADDRESS_ARG.name) .long(OWNER_ADDRESS_ARG.long) .takes_value(true) @@ -215,7 +215,7 @@ pub fn owner_address_arg<'a, 'b>() -> Arg<'a, 'b> { .help(OWNER_ADDRESS_ARG.help) } -pub fn owner_keypair_arg_with_value_name<'a, 'b>(value_name: &'static str) -> Arg<'a, 'b> { +pub fn owner_keypair_arg_with_value_name<'a>(value_name: &'static str) -> Arg<'a> { Arg::with_name(OWNER_KEYPAIR_ARG.name) .long(OWNER_KEYPAIR_ARG.long) .takes_value(true) @@ -224,11 +224,11 @@ pub fn owner_keypair_arg_with_value_name<'a, 'b>(value_name: &'static str) -> Ar .help(OWNER_KEYPAIR_ARG.help) } -pub fn owner_keypair_arg<'a, 'b>() -> Arg<'a, 'b> { +pub fn owner_keypair_arg<'a>() -> Arg<'a> { owner_keypair_arg_with_value_name("OWNER_KEYPAIR") } -pub fn mint_address_arg<'a, 'b>() -> Arg<'a, 'b> { +pub fn mint_address_arg<'a>() -> Arg<'a> { Arg::with_name(MINT_ADDRESS_ARG.name) .long(MINT_ADDRESS_ARG.long) .takes_value(true) @@ -241,7 +241,7 @@ fn is_mint_decimals(string: String) -> Result<(), String> { is_parsable::(string) } -pub fn mint_decimals_arg<'a, 'b>() -> Arg<'a, 'b> { +pub fn mint_decimals_arg<'a>() -> Arg<'a> { Arg::with_name(MINT_DECIMALS_ARG.name) .long(MINT_DECIMALS_ARG.long) .takes_value(true) @@ -254,14 +254,14 @@ pub trait MintArgs { fn mint_args(self) -> Self; } -impl MintArgs for App<'_, '_> { +impl MintArgs for App<'_> { fn mint_args(self) -> Self { self.arg(mint_address_arg().requires(MINT_DECIMALS_ARG.name)) .arg(mint_decimals_arg().requires(MINT_ADDRESS_ARG.name)) } } -pub fn delegate_address_arg<'a, 'b>() -> Arg<'a, 'b> { +pub fn delegate_address_arg<'a>() -> Arg<'a> { Arg::with_name(DELEGATE_ADDRESS_ARG.name) .long(DELEGATE_ADDRESS_ARG.long) .takes_value(true) @@ -270,7 +270,7 @@ pub fn delegate_address_arg<'a, 'b>() -> Arg<'a, 'b> { .help(DELEGATE_ADDRESS_ARG.help) } -pub fn multisig_signer_arg<'a, 'b>() -> Arg<'a, 'b> { +pub fn multisig_signer_arg<'a>() -> Arg<'a> { Arg::with_name(MULTISIG_SIGNER_ARG.name) .long(MULTISIG_SIGNER_ARG.long) .validator(is_valid_signer) @@ -332,7 +332,7 @@ fn new_throwaway_signer() -> (Arc, Pubkey) { } fn get_signer( - matches: &ArgMatches<'_>, + matches: &ArgMatches, keypair_name: &str, wallet_manager: &mut Option>, ) -> Option<(Arc, Pubkey)> { @@ -386,7 +386,7 @@ async fn check_wallet_balance( type SignersOf = Vec<(Arc, Pubkey)>; pub fn signers_of( - matches: &ArgMatches<'_>, + matches: &ArgMatches, name: &str, wallet_manager: &mut Option>, ) -> Result, Box> { @@ -2700,40 +2700,40 @@ async fn command_withdraw_withheld_tokens( struct SignOnlyNeedsFullMintSpec {} impl offline::ArgsConfig for SignOnlyNeedsFullMintSpec { - fn sign_only_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn sign_only_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[MINT_ADDRESS_ARG.name, MINT_DECIMALS_ARG.name]) } - fn signer_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn signer_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[MINT_ADDRESS_ARG.name, MINT_DECIMALS_ARG.name]) } } struct SignOnlyNeedsMintDecimals {} impl offline::ArgsConfig for SignOnlyNeedsMintDecimals { - fn sign_only_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn sign_only_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[MINT_DECIMALS_ARG.name]) } - fn signer_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn signer_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[MINT_DECIMALS_ARG.name]) } } struct SignOnlyNeedsMintAddress {} impl offline::ArgsConfig for SignOnlyNeedsMintAddress { - fn sign_only_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn sign_only_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[MINT_ADDRESS_ARG.name]) } - fn signer_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn signer_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[MINT_ADDRESS_ARG.name]) } } struct SignOnlyNeedsDelegateAddress {} impl offline::ArgsConfig for SignOnlyNeedsDelegateAddress { - fn sign_only_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn sign_only_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[DELEGATE_ADDRESS_ARG.name]) } - fn signer_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { + fn signer_arg<'a>(&self, arg: Arg<'a>) -> Arg<'a> { arg.requires_all(&[DELEGATE_ADDRESS_ARG.name]) } } @@ -2756,7 +2756,7 @@ fn app<'a, 'b>( default_decimals: &'a str, minimum_signers_help: &'b str, multisig_member_help: &'b str, -) -> App<'a, 'b> { +) -> App<'a> { App::new(crate_name!()) .about(crate_description!()) .version(crate_version!()) @@ -4247,7 +4247,7 @@ async fn main() -> Result<(), Error> { async fn process_command<'a>( sub_command: &CommandName, - sub_matches: &ArgMatches<'_>, + sub_matches: &ArgMatches, config: &Config<'a>, mut wallet_manager: Option>, mut bulk_signers: Vec>, From 65ce0b1f393796cb092d7979dfb9825ddc000844 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 17:39:01 -0700 Subject: [PATCH 03/11] update input to `short` arg to be type `char` instead of `str` --- token/cli/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 1be0a1d5df8..1db8631bf7f 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -2763,7 +2763,7 @@ fn app<'a, 'b>( .setting(AppSettings::SubcommandRequiredElseHelp) .arg( Arg::with_name("config_file") - .short("C") + .short('C') .long("config") .value_name("PATH") .takes_value(true) @@ -2772,7 +2772,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("verbose") - .short("v") + .short('v') .long("verbose") .takes_value(false) .global(true) @@ -2789,7 +2789,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("program_id") - .short("p") + .short('p') .long("program-id") .value_name("ADDRESS") .takes_value(true) @@ -2799,7 +2799,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("json_rpc_url") - .short("u") + .short('u') .long("url") .value_name("URL_OR_MONIKER") .takes_value(true) From be02b43ab57c5fb54a21e6bf583bd9d129dc6e14 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 17:42:01 -0700 Subject: [PATCH 04/11] update argument to `min_values` and `max_values` to be type `usize` instead of `u64` --- token/cli/src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 1db8631bf7f..81bc6269f4b 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -277,8 +277,8 @@ pub fn multisig_signer_arg<'a>() -> Arg<'a> { .value_name("MULTISIG_SIGNER") .takes_value(true) .multiple(true) - .min_values(0u64) - .max_values(MAX_SIGNERS as u64) + .min_values(0_usize) + .max_values(MAX_SIGNERS as usize) .help(MULTISIG_SIGNER_ARG.help) } @@ -3186,8 +3186,8 @@ fn app<'a, 'b>( .takes_value(true) .index(2) .required(true) - .min_values(MIN_SIGNERS as u64) - .max_values(MAX_SIGNERS as u64) + .min_values(MIN_SIGNERS as usize) + .max_values(MAX_SIGNERS as usize) .help(multisig_member_help), ) .arg( @@ -3380,7 +3380,7 @@ fn app<'a, 'b>( .value_name("PUBKEY:ROLE") .takes_value(true) .multiple(true) - .min_values(0u64) + .min_values(0_usize) .help("Additional pubkey(s) required for a transfer hook and their \ role, in the format \":\". The role must be \ \"readonly\", \"writable\". \"readonly-signer\", or \"writable-signer\".\ @@ -4121,7 +4121,7 @@ fn app<'a, 'b>( .value_name("ACCOUNT_ADDRESS") .takes_value(true) .multiple(true) - .min_values(0u64) + .min_values(0_usize) .help("The token accounts to withdraw from") ) .arg( From 307228a994ac643cb9719ed2324ed6415f634f04 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 17:42:51 -0700 Subject: [PATCH 05/11] update for ui change to `subcommand()` --- token/cli/src/bench.rs | 11 ++++++----- token/cli/src/main.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/token/cli/src/bench.rs b/token/cli/src/bench.rs index c0745bf504a..8d7d42860b3 100644 --- a/token/cli/src/bench.rs +++ b/token/cli/src/bench.rs @@ -173,8 +173,9 @@ pub(crate) async fn bench_process_command( ) -> CommandResult { assert!(!config.sign_only); - match matches.subcommand() { - ("create-accounts", Some(arg_matches)) => { + let subcommand = matches.subcommand().unwrap(); + match subcommand { + ("create-accounts", arg_matches) => { let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); @@ -186,7 +187,7 @@ pub(crate) async fn bench_process_command( command_create_accounts(config, signers, &token, n, &owner).await?; } - ("close-accounts", Some(arg_matches)) => { + ("close-accounts", arg_matches) => { let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); @@ -197,7 +198,7 @@ pub(crate) async fn bench_process_command( command_close_accounts(config, signers, &token, n, &owner).await?; } - ("deposit-into", Some(arg_matches)) => { + ("deposit-into", arg_matches) => { let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); @@ -212,7 +213,7 @@ pub(crate) async fn bench_process_command( ) .await?; } - ("withdraw-from", Some(arg_matches)) => { + ("withdraw-from", arg_matches) => { let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 81bc6269f4b..fc768474e99 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -4225,9 +4225,9 @@ async fn main() -> Result<(), Error> { let mut wallet_manager = None; let mut bulk_signers: Vec> = Vec::new(); - let (sub_command, sub_matches) = app_matches.subcommand(); + let (sub_command, sub_matches) = app_matches.subcommand().unwrap(); let sub_command = CommandName::from_str(sub_command).unwrap(); - let matches = sub_matches.unwrap(); + let matches = sub_matches; let mut multisigner_ids = Vec::new(); let config = Config::new( @@ -5392,9 +5392,9 @@ mod tests { &multisig_member_help, ) .get_matches_from(args); - let (sub_command, sub_matches) = app_matches.subcommand(); + let (sub_command, sub_matches) = app_matches.subcommand().unwrap(); let sub_command = CommandName::from_str(sub_command).unwrap(); - let matches = sub_matches.unwrap(); + let matches = sub_matches; let wallet_manager = None; let bulk_signers: Vec> = vec![Arc::new(clone_keypair(payer))]; @@ -5412,9 +5412,9 @@ mod tests { &multisig_member_help, ) .get_matches_from(args); - let (sub_command, sub_matches) = app_matches.subcommand(); + let (sub_command, sub_matches) = app_matches.subcommand().unwrap(); let sub_command = CommandName::from_str(sub_command).unwrap(); - let matches = sub_matches.unwrap(); + let matches = sub_matches; let mut wallet_manager = None; let mut bulk_signers: Vec> = Vec::new(); From 5edcfde08802a174e14783845285f2595dbb772c Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 17:53:01 -0700 Subject: [PATCH 06/11] resolve lifetime mismatch for inputs to `validator(...)` --- token/cli/src/bench.rs | 16 ++-- token/cli/src/main.rs | 176 ++++++++++++++++++++--------------------- 2 files changed, 96 insertions(+), 96 deletions(-) diff --git a/token/cli/src/bench.rs b/token/cli/src/bench.rs index 8d7d42860b3..c805b88fdc2 100644 --- a/token/cli/src/bench.rs +++ b/token/cli/src/bench.rs @@ -40,7 +40,7 @@ impl BenchSubCommand for App<'_> { .about("Create multiple token accounts for benchmarking") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ADDRESS") .takes_value(true) .index(1) @@ -63,7 +63,7 @@ impl BenchSubCommand for App<'_> { .about("Close multiple token accounts used for benchmarking") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ADDRESS") .takes_value(true) .index(1) @@ -86,7 +86,7 @@ impl BenchSubCommand for App<'_> { .about("Deposit tokens into multiple accounts") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ADDRESS") .takes_value(true) .index(1) @@ -104,7 +104,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("amount") - .validator(is_amount) + .validator(|s| is_amount(s)) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(3) @@ -114,7 +114,7 @@ impl BenchSubCommand for App<'_> { .arg( Arg::with_name("from") .long("from") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("SOURCE_TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .help("The source token account address [default: associated token account for --owner]") @@ -126,7 +126,7 @@ impl BenchSubCommand for App<'_> { .about("Withdraw tokens from multiple accounts") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ADDRESS") .takes_value(true) .index(1) @@ -144,7 +144,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("amount") - .validator(is_amount) + .validator(|s| is_amount(s)) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(3) @@ -154,7 +154,7 @@ impl BenchSubCommand for App<'_> { .arg( Arg::with_name("to") .long("to") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("RECIPIENT_TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .help("The recipient token account address [default: associated token account for --owner]") diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index fc768474e99..a8c6b3f3d69 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -211,7 +211,7 @@ pub fn owner_address_arg<'a>() -> Arg<'a> { .long(OWNER_ADDRESS_ARG.long) .takes_value(true) .value_name("OWNER_ADDRESS") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .help(OWNER_ADDRESS_ARG.help) } @@ -220,7 +220,7 @@ pub fn owner_keypair_arg_with_value_name<'a>(value_name: &'static str) -> Arg<'a .long(OWNER_KEYPAIR_ARG.long) .takes_value(true) .value_name(value_name) - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .help(OWNER_KEYPAIR_ARG.help) } @@ -233,11 +233,11 @@ pub fn mint_address_arg<'a>() -> Arg<'a> { .long(MINT_ADDRESS_ARG.long) .takes_value(true) .value_name("MINT_ADDRESS") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .help(MINT_ADDRESS_ARG.help) } -fn is_mint_decimals(string: String) -> Result<(), String> { +fn is_mint_decimals(string: &str) -> Result<(), String> { is_parsable::(string) } @@ -266,14 +266,14 @@ pub fn delegate_address_arg<'a>() -> Arg<'a> { .long(DELEGATE_ADDRESS_ARG.long) .takes_value(true) .value_name("DELEGATE_ADDRESS") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .help(DELEGATE_ADDRESS_ARG.help) } pub fn multisig_signer_arg<'a>() -> Arg<'a> { Arg::with_name(MULTISIG_SIGNER_ARG.name) .long(MULTISIG_SIGNER_ARG.long) - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .value_name("MULTISIG_SIGNER") .takes_value(true) .multiple(true) @@ -282,7 +282,7 @@ pub fn multisig_signer_arg<'a>() -> Arg<'a> { .help(MULTISIG_SIGNER_ARG.help) } -fn is_multisig_minimum_signers(string: String) -> Result<(), String> { +fn is_multisig_minimum_signers(string: &str) -> Result<(), String> { let v = u8::from_str(&string).map_err(|e| e.to_string())? as usize; if v < MIN_SIGNERS { Err(format!("must be at least {}", MIN_SIGNERS)) @@ -2794,7 +2794,7 @@ fn app<'a, 'b>( .value_name("ADDRESS") .takes_value(true) .global(true) - .validator(is_valid_token_program_id) + .validator(|s| is_valid_token_program_id(s)) .help("SPL Token program id"), ) .arg( @@ -2804,7 +2804,7 @@ fn app<'a, 'b>( .value_name("URL_OR_MONIKER") .takes_value(true) .global(true) - .validator(is_url_or_moniker) + .validator(|s| is_url_or_moniker(s)) .help( "URL for Solana's JSON RPC or moniker (or their first letter): \ [mainnet-beta, testnet, devnet, localhost] \ @@ -2825,7 +2825,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("token_keypair") .value_name("TOKEN_KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .index(1) .help( @@ -2839,7 +2839,7 @@ fn app<'a, 'b>( .long("mint-authority") .alias("owner") .value_name("ADDRESS") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .takes_value(true) .help( "Specify the mint authority address. \ @@ -2949,7 +2949,7 @@ fn app<'a, 'b>( Arg::with_name("transfer_hook") .long("transfer-hook") .value_name("TRANSFER_HOOK_PROGRAM_ID") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .takes_value(true) .help("Enable the mint authority to set the transfer hook program for this mint"), ) @@ -2968,7 +2968,7 @@ fn app<'a, 'b>( .about("Set the interest rate for an interest-bearing token") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .required(true) @@ -2984,7 +2984,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("rate_authority") .long("rate-authority") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .value_name("SIGNER") .takes_value(true) .help( @@ -2998,7 +2998,7 @@ fn app<'a, 'b>( .about("Set the transfer hook program id for a token") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .required(true) @@ -3007,7 +3007,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("new_program_id") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("NEW_PROGRAM_ID") .takes_value(true) .required_unless("disable") @@ -3024,7 +3024,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("program_authority") .long("program-authority") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .value_name("SIGNER") .takes_value(true) .help("Specify the authority keypair. Defaults to the client keypair address.") @@ -3035,7 +3035,7 @@ fn app<'a, 'b>( .about("Initialize metadata extension on a token mint") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .required(true) @@ -3068,7 +3068,7 @@ fn app<'a, 'b>( .long("mint-authority") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the mint authority keypair. \ @@ -3080,7 +3080,7 @@ fn app<'a, 'b>( Arg::with_name("update_authority") .long("update-authority") .value_name("ADDRESS") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .takes_value(true) .help( "Specify the update authority address. \ @@ -3093,7 +3093,7 @@ fn app<'a, 'b>( .about("Update metadata on a token mint that has the extension") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .required(true) @@ -3126,7 +3126,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("authority") .long("authority") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .value_name("SIGNER") .takes_value(true) .help("Specify the metadata update authority keypair. Defaults to the client keypair.") @@ -3137,7 +3137,7 @@ fn app<'a, 'b>( .about("Create a new token account") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3147,7 +3147,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("account_keypair") .value_name("ACCOUNT_KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .index(2) .help( @@ -3182,7 +3182,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("multisig_member") .value_name("MULTISIG_MEMBER_PUBKEY") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .takes_value(true) .index(2) .required(true) @@ -3194,7 +3194,7 @@ fn app<'a, 'b>( Arg::with_name("address_keypair") .long("address-keypair") .value_name("ADDRESS_KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the address keypair. \ @@ -3209,7 +3209,7 @@ fn app<'a, 'b>( .about("Authorize a new signing keypair to a token or token account") .arg( Arg::with_name("address") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ADDRESS") .takes_value(true) .index(1) @@ -3235,7 +3235,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("new_authority") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("AUTHORITY_ADDRESS") .takes_value(true) .index(3) @@ -3247,7 +3247,7 @@ fn app<'a, 'b>( .long("authority") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the current authority keypair. \ @@ -3276,7 +3276,7 @@ fn app<'a, 'b>( .about("Transfer tokens between accounts") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3285,7 +3285,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("amount") - .validator(is_amount_or_all) + .validator(|s| is_amount_or_all(s)) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -3294,7 +3294,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("recipient") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("RECIPIENT_WALLET_ADDRESS or RECIPIENT_TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(3) @@ -3305,7 +3305,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("from") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("SENDER_TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .long("from") @@ -3368,7 +3368,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("expected_fee") .long("expected-fee") - .validator(is_amount) + .validator(|s| is_amount(s)) .value_name("TOKEN_AMOUNT") .takes_value(true) .help("Expected fee amount collected during the transfer"), @@ -3376,7 +3376,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("transfer_hook_account") .long("transfer-hook-account") - .validator(validate_transfer_hook_account) + .validator(|s| validate_transfer_hook_account(s)) .value_name("PUBKEY:ROLE") .takes_value(true) .multiple(true) @@ -3397,7 +3397,7 @@ fn app<'a, 'b>( .about("Burn tokens from an account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3406,7 +3406,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("amount") - .validator(is_amount) + .validator(|s| is_amount(s)) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -3431,7 +3431,7 @@ fn app<'a, 'b>( .about("Mint new tokens") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3440,7 +3440,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("amount") - .validator(is_amount) + .validator(|s| is_amount(s)) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -3449,7 +3449,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("recipient") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("RECIPIENT_TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .conflicts_with("recipient_owner") @@ -3460,7 +3460,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("recipient_owner") .long("recipient-owner") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("RECIPIENT_WALLET_ADDRESS") .takes_value(true) .conflicts_with("recipient") @@ -3471,7 +3471,7 @@ fn app<'a, 'b>( .long("mint-authority") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the mint authority keypair. \ @@ -3490,7 +3490,7 @@ fn app<'a, 'b>( .about("Freeze a token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3502,7 +3502,7 @@ fn app<'a, 'b>( .long("freeze-authority") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the freeze authority keypair. \ @@ -3520,7 +3520,7 @@ fn app<'a, 'b>( .about("Thaw a token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3532,7 +3532,7 @@ fn app<'a, 'b>( .long("freeze-authority") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the freeze authority keypair. \ @@ -3550,7 +3550,7 @@ fn app<'a, 'b>( .about("Wrap native SOL in a SOL token account") .arg( Arg::with_name("amount") - .validator(is_amount) + .validator(|s| is_amount(s)) .value_name("AMOUNT") .takes_value(true) .index(1) @@ -3561,7 +3561,7 @@ fn app<'a, 'b>( Arg::with_name("wallet_keypair") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the keypair for the wallet which will have its native SOL wrapped. \ @@ -3592,7 +3592,7 @@ fn app<'a, 'b>( .about("Unwrap a SOL token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3603,7 +3603,7 @@ fn app<'a, 'b>( Arg::with_name("wallet_keypair") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the keypair for the wallet which owns the wrapped SOL. \ @@ -3622,7 +3622,7 @@ fn app<'a, 'b>( .about("Approve a delegate for a token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3631,7 +3631,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("amount") - .validator(is_amount) + .validator(|s| is_amount(s)) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -3640,7 +3640,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("delegate") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("DELEGATE_TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(3) @@ -3660,7 +3660,7 @@ fn app<'a, 'b>( .about("Revoke a delegate's authority") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3679,7 +3679,7 @@ fn app<'a, 'b>( .about("Close a token account") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3690,7 +3690,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("recipient") .long("recipient") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("REFUND_ACCOUNT_ADDRESS") .takes_value(true) .help("The address of the account to receive remaining SOL [default: --owner]"), @@ -3700,7 +3700,7 @@ fn app<'a, 'b>( .long("close-authority") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the token's close authority if it has one, \ @@ -3712,7 +3712,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("address") .long("address") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .conflicts_with("token") @@ -3728,7 +3728,7 @@ fn app<'a, 'b>( .about("Close a token mint") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3738,7 +3738,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("recipient") .long("recipient") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("REFUND_ACCOUNT_ADDRESS") .takes_value(true) .help("The address of the account to receive remaining SOL [default: --owner]"), @@ -3747,7 +3747,7 @@ fn app<'a, 'b>( Arg::with_name("close_authority") .long("close-authority") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the token's close authority. \ @@ -3765,7 +3765,7 @@ fn app<'a, 'b>( .about("Get token account balance") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3775,7 +3775,7 @@ fn app<'a, 'b>( .arg(owner_address_arg().conflicts_with("address")) .arg( Arg::with_name("address") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .long("address") @@ -3789,7 +3789,7 @@ fn app<'a, 'b>( .about("Get token supply") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3802,7 +3802,7 @@ fn app<'a, 'b>( .about("List all token accounts by owner") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3843,7 +3843,7 @@ fn app<'a, 'b>( .about("Get wallet address") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .long("token") @@ -3864,7 +3864,7 @@ fn app<'a, 'b>( .setting(AppSettings::Hidden) .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -3883,7 +3883,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("address") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .long("address") @@ -3897,7 +3897,7 @@ fn app<'a, 'b>( .setting(AppSettings::Hidden) .arg( Arg::with_name("address") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("MULTISIG_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3910,7 +3910,7 @@ fn app<'a, 'b>( .about("Query details of an SPL Token mint, account, or multisig by address") .arg( Arg::with_name("address") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ADDRESS") .takes_value(true) .index(1) @@ -3942,7 +3942,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("address") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .long("address") @@ -3955,7 +3955,7 @@ fn app<'a, 'b>( .about("Enable required transfer memos for token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3973,7 +3973,7 @@ fn app<'a, 'b>( .about("Disable required transfer memos for token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -3991,7 +3991,7 @@ fn app<'a, 'b>( .about("Enable CPI Guard for token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -4009,7 +4009,7 @@ fn app<'a, 'b>( .about("Disable CPI Guard for token account") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -4027,7 +4027,7 @@ fn app<'a, 'b>( .about("Updates default account state for the mint. Requires the default account state extension.") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -4047,7 +4047,7 @@ fn app<'a, 'b>( Arg::with_name("freeze_authority") .long("freeze-authority") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the token's freeze authority. \ @@ -4065,7 +4065,7 @@ fn app<'a, 'b>( .about("Updates metadata pointer address for the mint. Requires the metadata pointer extension.") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) @@ -4075,7 +4075,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("metadata_address") .index(2) - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("METADATA_ADDRESS") .takes_value(true) .required_unless("disable") @@ -4092,7 +4092,7 @@ fn app<'a, 'b>( Arg::with_name("authority") .long("authority") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the token's metadata-pointer authority. \ @@ -4108,7 +4108,7 @@ fn app<'a, 'b>( .about("Withdraw withheld transfer fee tokens from mint and / or account(s)") .arg( Arg::with_name("account") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) @@ -4117,7 +4117,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("source") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("ACCOUNT_ADDRESS") .takes_value(true) .multiple(true) @@ -4135,7 +4135,7 @@ fn app<'a, 'b>( .long("withdraw-withheld-authority") .alias("owner") .value_name("KEYPAIR") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .takes_value(true) .help( "Specify the withdraw withheld authority keypair. \ @@ -4151,7 +4151,7 @@ fn app<'a, 'b>( .about("Set the transfer fee for a token with a configured transfer fee") .arg( Arg::with_name("token") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .required(true) @@ -4167,7 +4167,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("maximum_fee") .value_name("TOKEN_AMOUNT") - .validator(is_amount) + .validator(|s| is_amount(s)) .takes_value(true) .required(true) .help("The new maximum transfer fee in UI amount"), @@ -4175,7 +4175,7 @@ fn app<'a, 'b>( .arg( Arg::with_name("transfer_fee_authority") .long("transfer-fee-authority") - .validator(is_valid_signer) + .validator(|s| is_valid_signer(s)) .value_name("SIGNER") .takes_value(true) .help( @@ -4191,7 +4191,7 @@ fn app<'a, 'b>( .about("Withdraw lamports from a Token Program owned account") .arg( Arg::with_name("from") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("SOURCE_ACCOUNT_ADDRESS") .takes_value(true) .required(true) @@ -4199,7 +4199,7 @@ fn app<'a, 'b>( ) .arg( Arg::with_name("recipient") - .validator(is_valid_pubkey) + .validator(|s| is_valid_pubkey(s)) .value_name("REFUND_ACCOUNT_ADDRESS") .takes_value(true) .required(true) From 73e528ed39edc178b918e290848e8d1b33b316b0 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 17:53:22 -0700 Subject: [PATCH 07/11] remove extra lifetime parameters from `App` --- token/cli/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index a8c6b3f3d69..d4f8859d4ab 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -2752,10 +2752,10 @@ fn multisig_member_help_string() -> String { ) } -fn app<'a, 'b>( +fn app<'a>( default_decimals: &'a str, - minimum_signers_help: &'b str, - multisig_member_help: &'b str, + minimum_signers_help: &'a str, + multisig_member_help: &'a str, ) -> App<'a> { App::new(crate_name!()) .about(crate_description!()) From 5f8cf144c45b09a81a88e5de12acf4d85d06e0eb Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 4 Sep 2023 18:11:08 -0700 Subject: [PATCH 08/11] clippy --- token/cli/src/main.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index d4f8859d4ab..09bc9b7116b 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -278,12 +278,12 @@ pub fn multisig_signer_arg<'a>() -> Arg<'a> { .takes_value(true) .multiple(true) .min_values(0_usize) - .max_values(MAX_SIGNERS as usize) + .max_values(MAX_SIGNERS) .help(MULTISIG_SIGNER_ARG.help) } fn is_multisig_minimum_signers(string: &str) -> Result<(), String> { - let v = u8::from_str(&string).map_err(|e| e.to_string())? as usize; + let v = u8::from_str(string).map_err(|e| e.to_string())? as usize; if v < MIN_SIGNERS { Err(format!("must be at least {}", MIN_SIGNERS)) } else if v > MAX_SIGNERS { @@ -2784,7 +2784,7 @@ fn app<'a>( .value_name("FORMAT") .global(true) .takes_value(true) - .possible_values(&["json", "json-compact"]) + .possible_values(["json", "json-compact"]) .help("Return information in specified output format"), ) .arg( @@ -2905,7 +2905,7 @@ fn app<'a>( .long("default-account-state") .requires("enable_freeze") .takes_value(true) - .possible_values(&["initialized", "frozen"]) + .possible_values(["initialized", "frozen"]) .help("Specify that accounts have a default state. \ Note: specifying \"initialized\" adds an extension, which gives \ the option of specifying default frozen accounts in the future. \ @@ -2936,7 +2936,7 @@ fn app<'a>( .long("enable-confidential-transfers") .value_names(&["APPROVE-POLICY"]) .takes_value(true) - .possible_values(&["auto", "manual"]) + .possible_values(["auto", "manual"]) .help( "Enable accounts to make confidential transfers. If \"auto\" \ is selected, then accounts are automatically approved to make \ @@ -3186,8 +3186,8 @@ fn app<'a>( .takes_value(true) .index(2) .required(true) - .min_values(MIN_SIGNERS as usize) - .max_values(MAX_SIGNERS as usize) + .min_values(MIN_SIGNERS) + .max_values(MAX_SIGNERS) .help(multisig_member_help), ) .arg( @@ -3220,7 +3220,7 @@ fn app<'a>( Arg::with_name("authority_type") .value_name("AUTHORITY_TYPE") .takes_value(true) - .possible_values(&[ + .possible_values([ "mint", "freeze", "owner", "close", "close-mint", "transfer-fee-config", "withheld-withdraw", "interest-rate", "permanent-delegate", "confidential-transfer-mint", @@ -4038,7 +4038,7 @@ fn app<'a>( Arg::with_name("state") .value_name("STATE") .takes_value(true) - .possible_values(&["initialized", "frozen"]) + .possible_values(["initialized", "frozen"]) .index(2) .required(true) .help("The new default account state."), @@ -4517,7 +4517,7 @@ async fn process_command<'a>( let no_recipient_is_ata_owner = arg_matches.is_present("no_recipient_is_ata_owner") || !recipient_is_ata_owner; if recipient_is_ata_owner { - println_display(config, format!("recipient-is-ata-owner is now the default behavior. The option has been deprecated and will be removed in a future release.")); + println_display(config, "recipient-is-ata-owner is now the default behavior. The option has been deprecated and will be removed in a future release.".to_string()); } let use_unchecked_instruction = arg_matches.is_present("use_unchecked_instruction"); let expected_fee = value_of::(arg_matches, "expected_fee"); From 365266176af1a5935d55041cb28426f38f5d8466 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Tue, 5 Sep 2023 17:15:21 -0700 Subject: [PATCH 09/11] add missing indices for arguments --- token/cli/src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 09bc9b7116b..8abcce33562 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -3563,6 +3563,7 @@ fn app<'a>( .value_name("KEYPAIR") .validator(|s| is_valid_signer(s)) .takes_value(true) + .index(2) .help( "Specify the keypair for the wallet which will have its native SOL wrapped. \ This wallet will be assigned as the owner of the wrapped SOL token account. \ @@ -3605,6 +3606,7 @@ fn app<'a>( .value_name("KEYPAIR") .validator(|s| is_valid_signer(s)) .takes_value(true) + .index(2) .help( "Specify the keypair for the wallet which owns the wrapped SOL. \ This wallet will receive the unwrapped SOL. \ @@ -4120,6 +4122,7 @@ fn app<'a>( .validator(|s| is_valid_pubkey(s)) .value_name("ACCOUNT_ADDRESS") .takes_value(true) + .index(2) .multiple(true) .min_values(0_usize) .help("The token accounts to withdraw from") From 574112413b373e5eac7e7f71ea93ce96bb2c02f9 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 6 Sep 2023 17:32:39 -0700 Subject: [PATCH 10/11] add custom `is_present` and `value_of` --- token/cli/src/config.rs | 44 +++++++++++------------- token/cli/src/input_parsers.rs | 61 ++++++++++++++++++++++++++++++++++ token/cli/src/main.rs | 53 +++++++++++++++-------------- 3 files changed, 109 insertions(+), 49 deletions(-) create mode 100644 token/cli/src/input_parsers.rs diff --git a/token/cli/src/config.rs b/token/cli/src/config.rs index f6c085d1f47..c0e677c1e7a 100644 --- a/token/cli/src/config.rs +++ b/token/cli/src/config.rs @@ -1,7 +1,6 @@ -use crate::{signers_of, Error, MULTISIG_SIGNER_ARG}; +use crate::{is_present, pubkey_of_signer, signers_of, value_of, Error, MULTISIG_SIGNER_ARG}; use clap::ArgMatches; use solana_clap_v3_utils::{ - input_parsers::{pubkey_of_signer, value_of}, input_validators::normalize_to_url_if_moniker, keypair::{signer_from_path, signer_from_path_with_config, SignerFromPathConfig}, nonce::{NONCE_ARG, NONCE_AUTHORITY_ARG}, @@ -74,7 +73,7 @@ impl<'a> Config<'a> { json_rpc_url, CommitmentConfig::confirmed(), )); - let sign_only = matches.is_present(SIGN_ONLY_ARG.name); + let sign_only = is_present(matches, SIGN_ONLY_ARG.name); let program_client: Arc> = if sign_only { let blockhash = value_of(matches, BLOCKHASH_ARG.name).unwrap_or_default(); Arc::new(ProgramOfflineClient::new( @@ -148,8 +147,8 @@ impl<'a> Config<'a> { let default_keypair = cli_config.keypair_path.clone(); let default_signer: Option> = { - if let Some(owner_path) = matches.value_of("owner") { - signer_from_path_with_config(matches, owner_path, "owner", wallet_manager, &config) + if let Some(owner_path) = value_of::(matches, "owner") { + signer_from_path_with_config(matches, &owner_path, "owner", wallet_manager, &config) .ok() } else { signer_from_path_with_config( @@ -172,11 +171,10 @@ impl<'a> Config<'a> { } .map(Arc::from); - let fee_payer: Option> = matches - .value_of("fee_payer") + let fee_payer: Option> = value_of::(matches, "fee_payer") .map(|path| { Arc::from( - signer_from_path(matches, path, "fee_payer", wallet_manager).unwrap_or_else( + signer_from_path(matches, &path, "fee_payer", wallet_manager).unwrap_or_else( |e| { eprintln!("error: {}", e); exit(1); @@ -186,10 +184,9 @@ impl<'a> Config<'a> { }) .or_else(|| default_signer.clone()); - let verbose = matches.is_present("verbose"); - let output_format = matches - .value_of("output_format") - .map(|value| match value { + let verbose = is_present(matches, "verbose"); + let output_format = value_of::(matches, "output_format") + .map(|value| match value.as_str() { "json" => OutputFormat::Json, "json-compact" => OutputFormat::JsonCompact, _ => unreachable!(), @@ -208,9 +205,8 @@ impl<'a> Config<'a> { let nonce_authority = if nonce_account.is_some() { let (nonce_authority, _) = signer_from_path( matches, - matches - .value_of(NONCE_AUTHORITY_ARG.name) - .unwrap_or(&cli_config.keypair_path), + &value_of::(matches, NONCE_AUTHORITY_ARG.name) + .unwrap_or(cli_config.keypair_path), NONCE_AUTHORITY_ARG.name, wallet_manager, ) @@ -229,17 +225,17 @@ impl<'a> Config<'a> { None }; - let sign_only = matches.is_present(SIGN_ONLY_ARG.name); - let dump_transaction_message = matches.is_present(DUMP_TRANSACTION_MESSAGE.name); + let sign_only = is_present(matches, SIGN_ONLY_ARG.name); + let dump_transaction_message = is_present(matches, DUMP_TRANSACTION_MESSAGE.name); let default_program_id = spl_token::id(); let (program_id, restrict_to_program_id) = - if let Some(program_id) = value_of(matches, "program_id") { + if let Some(program_id) = value_of::(matches, "program_id") { (program_id, true) } else if !sign_only { - if let Some(address) = value_of(matches, "token") - .or_else(|| value_of(matches, "account")) - .or_else(|| value_of(matches, "address")) + if let Some(address) = value_of::(matches, "token") + .or_else(|| value_of::(matches, "account")) + .or_else(|| value_of::(matches, "address")) { ( rpc_client @@ -256,7 +252,7 @@ impl<'a> Config<'a> { (default_program_id, false) }; - let nonce_blockhash = value_of(matches, BLOCKHASH_ARG.name); + let nonce_blockhash = value_of::(matches, BLOCKHASH_ARG.name); Self { default_signer, rpc_client, @@ -380,10 +376,10 @@ impl<'a> Config<'a> { }; let mut load_authority = move || -> Result, Error> { if authority_name != "owner" { - if let Some(keypair_path) = arg_matches.value_of(authority_name) { + if let Some(keypair_path) = value_of::(arg_matches, authority_name) { return signer_from_path_with_config( arg_matches, - keypair_path, + &keypair_path, authority_name, wallet_manager, &config, diff --git a/token/cli/src/input_parsers.rs b/token/cli/src/input_parsers.rs new file mode 100644 index 00000000000..65efef0dd31 --- /dev/null +++ b/token/cli/src/input_parsers.rs @@ -0,0 +1,61 @@ +//! The beahvior of `ArgMatches::is_present` and `ArgMatches::value_of` differ in `clap_v2` and +//! `clap_v3`. This submodule contains adaptation of these functions to preserve their v2 behavior in +//! v3. + +use clap::ArgMatches; +use solana_clap_v3_utils::keypair::pubkey_from_path; +use solana_remote_wallet::remote_wallet::RemoteWalletManager; +use solana_sdk::pubkey::Pubkey; +use std::sync::Arc; + +/// Adaptation of `ArgMatches::is_present` that has the same behavior in `clap_v3` as in `clap_v2`. +/// +/// The function `ArgMatches::is_present` behaves differently in clap v2 and clap v3: +/// - In v2, `index_of` returns `true` on success and `false` on all other cases. +/// - In v3, `index_of` returns `true` on success, `false` if the queried argument id +/// is valid but the argument was not provided, and panics if the input argument id does not +/// exist. +/// This adaptation behaves as in `clap_v2`. +pub(crate) fn is_present(matches: &ArgMatches, name: &str) -> bool { + matches.try_contains_id(name).unwrap_or(false) +} + +/// Adaptation of `ArgMatches::value_of` that has the same behavior in `clap_v3` as in `clap_v2`. +/// +/// The function `ArgMatches::value_of` behaves differently in clap v2 and clap v3: +/// - In v2, `value_of` returns `Some(...)` on success and `None` on all other cases. +/// - In v3, `value_of` returns `Some(...)` on success, `None` if the queried argument id +/// is valid but the argument was not provided, and panics if the input argument id does not +/// exist. +/// This adaptation behaves as in `clap_v2`. +pub(crate) fn value_of(matches: &ArgMatches, name: &str) -> Option +where + T: std::str::FromStr, + ::Err: std::fmt::Debug, +{ + let maybe_value = matches.try_get_one::(name).unwrap_or(None); + if let Some(value) = maybe_value { + value.parse::().ok() + } else { + None + } +} + +/// Adaptation of `solana_clap_v3_utils::input_parsers::pubkey_of_signer` that has the same +/// behavior as `solana_clap_utils::input_parsers::pubkey_of_signer`. +pub(crate) fn pubkey_of_signer( + matches: &ArgMatches, + name: &str, + wallet_manager: &mut Option>, +) -> Result, Box> { + if let Some(location) = matches.try_get_one::(name).ok().flatten() { + Ok(Some(pubkey_from_path( + matches, + location, + name, + wallet_manager, + )?)) + } else { + Ok(None) + } +} diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 8abcce33562..2287e8d8ab0 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -10,7 +10,7 @@ use solana_account_decoder::{ }; use solana_clap_v3_utils::{ fee_payer::fee_payer_arg, - input_parsers::{pubkey_of_signer, pubkeys_of_multiple_signers, value_of}, + input_parsers::pubkeys_of_multiple_signers, input_validators::{ is_amount, is_amount_or_all, is_parsable, is_pubkey, is_url_or_moniker, is_valid_pubkey, is_valid_signer, @@ -74,6 +74,9 @@ use sort::{sort_and_parse_token_accounts, AccountFilter}; mod bench; use bench::*; +mod input_parsers; +use input_parsers::{is_present, pubkey_of_signer, value_of}; + pub const OWNER_ADDRESS_ARG: ArgConstant<'static> = ArgConstant { name: "owner", long: "owner", @@ -4310,10 +4313,10 @@ async fn process_command<'a>( decimals, token, mint_authority, - arg_matches.is_present("enable_freeze"), - arg_matches.is_present("enable_close"), - arg_matches.is_present("enable_non_transferable"), - arg_matches.is_present("enable_permanent_delegate"), + is_present(arg_matches, "enable_freeze"), + is_present(arg_matches, "enable_close"), + is_present(arg_matches, "enable_non_transferable"), + is_present(arg_matches, "enable_permanent_delegate"), memo, metadata_address, rate_bps, @@ -4321,7 +4324,7 @@ async fn process_command<'a>( transfer_fee, confidential_transfer_auto_approve, transfer_hook_program_id, - arg_matches.is_present("enable_metadata"), + is_present(arg_matches, "enable_metadata"), bulk_signers, ) .await @@ -4426,7 +4429,7 @@ async fn process_command<'a>( token, owner, account, - arg_matches.is_present("immutable"), + is_present(arg_matches, "immutable"), bulk_signers, ) .await @@ -4480,7 +4483,7 @@ async fn process_command<'a>( let new_authority = pubkey_of_signer(arg_matches, "new_authority", &mut wallet_manager).unwrap(); - let force_authorize = arg_matches.is_present("force"); + let force_authorize = is_present(arg_matches, "force"); command_authorize( config, address, @@ -4512,17 +4515,17 @@ async fn process_command<'a>( } let mint_decimals = value_of::(arg_matches, MINT_DECIMALS_ARG.name); - let fund_recipient = arg_matches.is_present("fund_recipient"); + let fund_recipient = is_present(arg_matches, "fund_recipient"); let allow_unfunded_recipient = arg_matches.is_present("allow_empty_recipient") - || arg_matches.is_present("allow_unfunded_recipient"); + || is_present(arg_matches, "allow_unfunded_recipient"); - let recipient_is_ata_owner = arg_matches.is_present("recipient_is_ata_owner"); + let recipient_is_ata_owner = is_present(arg_matches, "recipient_is_ata_owner"); let no_recipient_is_ata_owner = - arg_matches.is_present("no_recipient_is_ata_owner") || !recipient_is_ata_owner; + is_present(arg_matches, "no_recipient_is_ata_owner") || !recipient_is_ata_owner; if recipient_is_ata_owner { println_display(config, "recipient-is-ata-owner is now the default behavior. The option has been deprecated and will be removed in a future release.".to_string()); } - let use_unchecked_instruction = arg_matches.is_present("use_unchecked_instruction"); + let use_unchecked_instruction = is_present(arg_matches, "use_unchecked_instruction"); let expected_fee = value_of::(arg_matches, "expected_fee"); let memo = value_t!(arg_matches, "memo", String).ok(); let transfer_hook_accounts = arg_matches.values_of("transfer_hook_account").map(|v| { @@ -4546,8 +4549,8 @@ async fn process_command<'a>( expected_fee, memo, bulk_signers, - arg_matches.is_present("no_wait"), - arg_matches.is_present("allow_non_system_account_recipient"), + is_present(arg_matches, "no_wait"), + is_present(arg_matches, "allow_non_system_account_recipient"), transfer_hook_accounts, ) .await @@ -4567,7 +4570,7 @@ async fn process_command<'a>( let mint_address = pubkey_of_signer(arg_matches, MINT_ADDRESS_ARG.name, &mut wallet_manager).unwrap(); let mint_decimals = value_of::(arg_matches, MINT_DECIMALS_ARG.name); - let use_unchecked_instruction = arg_matches.is_present("use_unchecked_instruction"); + let use_unchecked_instruction = is_present(arg_matches, "use_unchecked_instruction"); let memo = value_t!(arg_matches, "memo", String).ok(); command_burn( config, @@ -4612,7 +4615,7 @@ async fn process_command<'a>( )? }; config.check_account(&recipient, Some(token)).await?; - let use_unchecked_instruction = arg_matches.is_present("use_unchecked_instruction"); + let use_unchecked_instruction = is_present(arg_matches, "use_unchecked_instruction"); let memo = value_t!(arg_matches, "memo", String).ok(); command_mint( config, @@ -4671,7 +4674,7 @@ async fn process_command<'a>( } (CommandName::Wrap, arg_matches) => { let amount = value_t_or_exit!(arg_matches, "amount", f64); - let account = if arg_matches.is_present("create_aux_account") { + let account = if is_present(arg_matches, "create_aux_account") { let (signer, account) = new_throwaway_signer(); bulk_signers.push(signer); Some(account) @@ -4689,7 +4692,7 @@ async fn process_command<'a>( amount, wallet_address, account, - arg_matches.is_present("immutable"), + is_present(arg_matches, "immutable"), bulk_signers, ) .await @@ -4719,7 +4722,7 @@ async fn process_command<'a>( let mint_address = pubkey_of_signer(arg_matches, MINT_ADDRESS_ARG.name, &mut wallet_manager).unwrap(); let mint_decimals = value_of::(arg_matches, MINT_DECIMALS_ARG.name); - let use_unchecked_instruction = arg_matches.is_present("use_unchecked_instruction"); + let use_unchecked_instruction = is_present(arg_matches, "use_unchecked_instruction"); command_approve( config, account, @@ -4798,9 +4801,9 @@ async fn process_command<'a>( (CommandName::Accounts, arg_matches) => { let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager).unwrap(); let owner = config.pubkey_or_default(arg_matches, "owner", &mut wallet_manager)?; - let filter = if arg_matches.is_present("delegated") { + let filter = if is_present(arg_matches, "delegated") { AccountFilter::Delegated - } else if arg_matches.is_present("externally_closeable") { + } else if is_present(arg_matches, "externally_closeable") { AccountFilter::ExternallyCloseable } else { AccountFilter::All @@ -4811,7 +4814,7 @@ async fn process_command<'a>( token, owner, filter, - arg_matches.is_present("addresses_only"), + is_present(arg_matches, "addresses_only"), ) .await } @@ -4850,7 +4853,7 @@ async fn process_command<'a>( } let close_empty_associated_accounts = - arg_matches.is_present("close_empty_associated_accounts"); + is_present(arg_matches, "close_empty_associated_accounts"); let (owner_signer, owner_address) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); @@ -4983,7 +4986,7 @@ async fn process_command<'a>( pubkey_of_signer(arg_matches, "account", &mut wallet_manager) .unwrap() .unwrap(); - let include_mint = arg_matches.is_present("include_mint"); + let include_mint = is_present(arg_matches, "include_mint"); let source_accounts = arg_matches .values_of("source") .unwrap_or_default() From d8192ee31549578dc382c20870c5c7f51645ebf9 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 6 Sep 2023 17:35:09 -0700 Subject: [PATCH 11/11] make owner address argument in `account-info` command to be non-positional --- token/cli/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 2287e8d8ab0..1c6824cf819 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -3880,7 +3880,6 @@ fn app<'a>( ) .arg( owner_address_arg() - .index(2) .conflicts_with("address") .help("Owner of the associated account for the specified token. \ To query a specific account, use the `--address` parameter instead. \