From 9dc55e59ec7923d48bdf908b93c33f164a483201 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Fri, 8 Nov 2024 10:52:55 +0900 Subject: [PATCH] [token-cli] Remove `is_amount_or_all`, `is_amount`, and `is_parsable` validators (#7448) * parse instead of validate for `decimals` * replace `is_amount_or_all` with parser * replace `is_amount` with parser * repalce `is_parsable` with parser * remove unnecessary imports --- token/cli/src/bench.rs | 30 ++-- token/cli/src/clap_app.rs | 60 ++++--- token/cli/src/command.rs | 323 ++++++++++++++++++++------------------ token/cli/src/config.rs | 10 +- 4 files changed, 222 insertions(+), 201 deletions(-) diff --git a/token/cli/src/bench.rs b/token/cli/src/bench.rs index db58f5db97f..209591cefdd 100644 --- a/token/cli/src/bench.rs +++ b/token/cli/src/bench.rs @@ -1,8 +1,8 @@ /// The `bench` subcommand use { crate::{clap_app::Error, command::CommandResult, config::Config}, - clap::{value_t_or_exit, ArgMatches}, - solana_clap_v3_utils::input_parsers::pubkey_of_signer, + clap::ArgMatches, + solana_clap_v3_utils::input_parsers::{pubkey_of_signer, Amount}, solana_client::{ nonblocking::rpc_client::RpcClient, rpc_client::RpcClient as BlockingRpcClient, tpu_client::TpuClient, tpu_client::TpuClientConfig, @@ -34,7 +34,7 @@ pub(crate) async fn bench_process_command( let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); - let n = value_t_or_exit!(arg_matches, "n", usize); + let n = *arg_matches.get_one::("n").unwrap(); let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", wallet_manager); @@ -46,7 +46,7 @@ pub(crate) async fn bench_process_command( let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); - let n = value_t_or_exit!(arg_matches, "n", usize); + let n = *arg_matches.get_one::("n").unwrap(); let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", wallet_manager); signers.push(owner_signer); @@ -57,8 +57,8 @@ pub(crate) async fn bench_process_command( let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); - let n = value_t_or_exit!(arg_matches, "n", usize); - let ui_amount = value_t_or_exit!(arg_matches, "amount", f64); + let n = *arg_matches.get_one::("n").unwrap(); + let ui_amount = *arg_matches.get_one::("amount").unwrap(); let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", wallet_manager); signers.push(owner_signer); @@ -72,8 +72,8 @@ pub(crate) async fn bench_process_command( let token = pubkey_of_signer(arg_matches, "token", wallet_manager) .unwrap() .unwrap(); - let n = value_t_or_exit!(arg_matches, "n", usize); - let ui_amount = value_t_or_exit!(arg_matches, "amount", f64); + let n = *arg_matches.get_one::("n").unwrap(); + let ui_amount = *arg_matches.get_one::("amount").unwrap(); let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", wallet_manager); signers.push(owner_signer); @@ -237,7 +237,7 @@ async fn command_deposit_into_or_withdraw_from( token: &Pubkey, n: usize, owner: &Pubkey, - ui_amount: f64, + ui_amount: Amount, from_or_to: Option, deposit_into: bool, ) -> Result<(), Error> { @@ -250,7 +250,17 @@ async fn command_deposit_into_or_withdraw_from( let from_or_to = from_or_to .unwrap_or_else(|| get_associated_token_address_with_program_id(owner, token, &program_id)); config.check_account(&from_or_to, Some(*token)).await?; - let amount = spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals); + let amount = match ui_amount { + Amount::Raw(ui_amount) => ui_amount, + Amount::Decimal(ui_amount) => spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals), + Amount::All => { + return Err( + "Use of ALL keyword currently not supported for the bench command" + .to_string() + .into(), + ); + } + }; let token_addresses_with_seed = get_token_addresses_with_seed(&program_id, token, owner, n); let mut messages = vec![]; diff --git a/token/cli/src/clap_app.rs b/token/cli/src/clap_app.rs index 83183d88aa5..e084b5b0efa 100644 --- a/token/cli/src/clap_app.rs +++ b/token/cli/src/clap_app.rs @@ -6,10 +6,8 @@ use { }, solana_clap_v3_utils::{ fee_payer::fee_payer_arg, - input_validators::{ - is_amount, is_amount_or_all, is_parsable, is_pubkey, is_url_or_moniker, - is_valid_pubkey, is_valid_signer, - }, + input_parsers::Amount, + input_validators::{is_pubkey, is_url_or_moniker, is_valid_pubkey, is_valid_signer}, memo::memo_arg, nonce::*, offline::{self, *}, @@ -306,16 +304,12 @@ pub fn mint_address_arg<'a>() -> Arg<'a> { .help(MINT_ADDRESS_ARG.help) } -fn is_mint_decimals(string: &str) -> Result<(), String> { - is_parsable::(string) -} - pub fn mint_decimals_arg<'a>() -> Arg<'a> { Arg::with_name(MINT_DECIMALS_ARG.name) .long(MINT_DECIMALS_ARG.long) .takes_value(true) .value_name("MINT_DECIMALS") - .validator(is_mint_decimals) + .value_parser(clap::value_parser!(u8)) .help(MINT_DECIMALS_ARG.help) } @@ -344,7 +338,7 @@ pub fn transfer_lamports_arg<'a>() -> Arg<'a> { .long(TRANSFER_LAMPORTS_ARG.long) .takes_value(true) .value_name("LAMPORTS") - .validator(|s| is_amount(s)) + .value_parser(clap::value_parser!(u64)) .help(TRANSFER_LAMPORTS_ARG.help) } @@ -477,7 +471,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("n") - .validator(is_parsable::) + .value_parser(clap::value_parser!(usize)) .value_name("N") .takes_value(true) .index(2) @@ -500,7 +494,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("n") - .validator(is_parsable::) + .value_parser(clap::value_parser!(usize)) .value_name("N") .takes_value(true) .index(2) @@ -523,7 +517,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("n") - .validator(is_parsable::) + .value_parser(clap::value_parser!(usize)) .value_name("N") .takes_value(true) .index(2) @@ -532,7 +526,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("amount") - .validator(|s| is_amount(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(3) @@ -563,7 +557,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("n") - .validator(is_parsable::) + .value_parser(clap::value_parser!(usize)) .value_name("N") .takes_value(true) .index(2) @@ -572,7 +566,7 @@ impl BenchSubCommand for App<'_> { ) .arg( Arg::with_name("amount") - .validator(|s| is_amount(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(3) @@ -676,7 +670,7 @@ pub fn app<'a>( .takes_value(true) .global(true) .value_name("COMPUTE-UNIT-LIMIT") - .validator(is_parsable::) + .value_parser(clap::value_parser!(u32)) .help(COMPUTE_UNIT_LIMIT_ARG.help) ) .arg( @@ -685,7 +679,7 @@ pub fn app<'a>( .takes_value(true) .global(true) .value_name("COMPUTE-UNIT-PRICE") - .validator(is_parsable::) + .value_parser(clap::value_parser!(u64)) .help(COMPUTE_UNIT_PRICE_ARG.help) ) .bench_subcommand() @@ -717,7 +711,7 @@ pub fn app<'a>( .arg( Arg::with_name("decimals") .long("decimals") - .validator(is_mint_decimals) + .value_parser(clap::value_parser!(u8)) .value_name("DECIMALS") .takes_value(true) .default_value(default_decimals) @@ -839,7 +833,7 @@ pub fn app<'a>( .number_of_values(1) .conflicts_with("transfer_fee") .requires("transfer_fee_basis_points") - .validator(|s| is_amount(s)) + .value_parser(Amount::parse) .help( "Add a UI amount maximum transfer fee to the mint. \ The mint authority can set and collect fees" @@ -1090,7 +1084,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("max_size") - .validator(|s| is_amount(s)) + .value_parser(clap::value_parser!(u64)) .value_name("MAX_SIZE") .takes_value(true) .required(true) @@ -1136,7 +1130,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("new_max_size") - .validator(|s| is_amount(s)) + .value_parser(clap::value_parser!(u64)) .value_name("NEW_MAX_SIZE") .takes_value(true) .required(true) @@ -1350,7 +1344,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("amount") - .validator(|s| is_amount_or_all(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -1434,8 +1428,8 @@ pub fn app<'a>( .arg( Arg::with_name("expected_fee") .long("expected-fee") - .validator(|s| is_amount(s)) - .value_name("TOKEN_AMOUNT") + .value_parser(Amount::parse) + .value_name("EXPECTED_FEE") .takes_value(true) .help("Expected fee amount collected during the transfer"), ) @@ -1480,7 +1474,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("amount") - .validator(|s| is_amount_or_all(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -1514,7 +1508,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("amount") - .validator(|s| is_amount(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -1624,7 +1618,7 @@ pub fn app<'a>( .about("Wrap native SOL in a SOL token account") .arg( Arg::with_name("amount") - .validator(|s| is_amount(s)) + .value_parser(Amount::parse) .value_name("AMOUNT") .takes_value(true) .index(1) @@ -1706,7 +1700,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("amount") - .validator(|s| is_amount(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -2337,8 +2331,8 @@ pub fn app<'a>( ) .arg( Arg::with_name("maximum_fee") - .value_name("TOKEN_AMOUNT") - .validator(|s| is_amount(s)) + .value_name("MAXIMUM_FEE") + .value_parser(Amount::parse) .takes_value(true) .required(true) .help("The new maximum transfer fee in UI amount"), @@ -2606,7 +2600,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("amount") - .validator(|s| is_amount_or_all(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) @@ -2643,7 +2637,7 @@ pub fn app<'a>( ) .arg( Arg::with_name("amount") - .validator(|s| is_amount_or_all(s)) + .value_parser(Amount::parse) .value_name("TOKEN_AMOUNT") .takes_value(true) .index(2) diff --git a/token/cli/src/command.rs b/token/cli/src/command.rs index e30eb7eb2ab..46cbffa9262 100644 --- a/token/cli/src/command.rs +++ b/token/cli/src/command.rs @@ -17,7 +17,7 @@ use { UiAccountData, }, solana_clap_v3_utils::{ - input_parsers::{pubkey_of_signer, pubkeys_of_multiple_signers}, + input_parsers::{pubkey_of_signer, pubkeys_of_multiple_signers, Amount}, keypair::signer_from_path, }, solana_cli_output::{ @@ -81,6 +81,21 @@ fn print_error_and_exit(e: E) -> T { exit(1) } +fn amount_to_raw_amount(amount: Amount, decimals: u8, all_amount: Option, name: &str) -> u64 { + match amount { + Amount::Raw(ui_amount) => ui_amount, + Amount::Decimal(ui_amount) => spl_token::ui_amount_to_amount(ui_amount, decimals), + Amount::All => { + if let Some(raw_amount) = all_amount { + raw_amount + } else { + eprintln!("ALL keyword is not allowed for {}", name); + exit(1) + } + } + } +} + type BulkSigners = Vec>; pub type CommandResult = Result; @@ -109,13 +124,6 @@ fn get_signer( }) } -fn parse_amount_or_all(matches: &ArgMatches) -> Option { - match matches.value_of("amount").unwrap() { - "ALL" => None, - amount => Some(amount.parse::().unwrap()), - } -} - async fn check_wallet_balance( config: &Config<'_>, wallet: &Pubkey, @@ -735,7 +743,7 @@ async fn command_set_transfer_fee( token_pubkey: Pubkey, transfer_fee_authority: Pubkey, transfer_fee_basis_points: u16, - maximum_fee: f64, + maximum_fee: Amount, mint_decimals: Option, bulk_signers: Vec>, ) -> CommandResult { @@ -777,16 +785,19 @@ async fn command_set_transfer_fee( mint_decimals.unwrap() }; + let token = token_client_from_config(config, &token_pubkey, Some(decimals))?; + let maximum_fee = amount_to_raw_amount(maximum_fee, decimals, None, "MAXIMUM_FEE"); + println_display( config, format!( "Setting transfer fee for {} to {} bps, {} maximum", - token_pubkey, transfer_fee_basis_points, maximum_fee + token_pubkey, + transfer_fee_basis_points, + spl_token::amount_to_ui_amount(maximum_fee, decimals) ), ); - let token = token_client_from_config(config, &token_pubkey, Some(decimals))?; - let maximum_fee = spl_token::ui_amount_to_amount(maximum_fee, decimals); let res = token .set_transfer_fee( &transfer_fee_authority, @@ -1200,7 +1211,7 @@ async fn command_authorize( async fn command_transfer( config: &Config<'_>, token_pubkey: Pubkey, - ui_amount: Option, + ui_amount: Amount, recipient: Pubkey, sender: Option, sender_owner: Pubkey, @@ -1209,7 +1220,7 @@ async fn command_transfer( mint_decimals: Option, no_recipient_is_ata_owner: bool, use_unchecked_instruction: bool, - ui_fee: Option, + ui_fee: Option, memo: Option, bulk_signers: BulkSigners, no_wait: bool, @@ -1263,30 +1274,43 @@ async fn command_transfer( token.get_associated_token_address(&sender_owner) }; - // the amount the user wants to transfer, as a f64 - let maybe_transfer_balance = - ui_amount.map(|ui_amount| spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals)); + // the sender balance + let sender_balance = if config.sign_only { + None + } else { + Some(token.get_account_info(&sender).await?.base.amount) + }; - // the amount we will transfer, as a u64 - let transfer_balance = if !config.sign_only { - let sender_balance = token.get_account_info(&sender).await?.base.amount; - let transfer_balance = maybe_transfer_balance.unwrap_or(sender_balance); + // the amount the user wants to transfer, as a u64 + let transfer_balance = match ui_amount { + Amount::Raw(ui_amount) => ui_amount, + Amount::Decimal(ui_amount) => spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals), + Amount::All => { + if config.sign_only { + return Err("Use of ALL keyword to burn tokens requires online signing" + .to_string() + .into()); + } + sender_balance.unwrap() + } + }; - println_display( - config, - format!( - "{}Transfer {} tokens\n Sender: {}\n Recipient: {}", - if confidential_transfer_args.is_some() { - "Confidential " - } else { - "" - }, - spl_token::amount_to_ui_amount(transfer_balance, mint_info.decimals), - sender, - recipient - ), - ); + println_display( + config, + format!( + "{}Transfer {} tokens\n Sender: {}\n Recipient: {}", + if confidential_transfer_args.is_some() { + "Confidential " + } else { + "" + }, + spl_token::amount_to_ui_amount(transfer_balance, mint_info.decimals), + sender, + recipient + ), + ); + if let Some(sender_balance) = sender_balance { if transfer_balance > sender_balance && confidential_transfer_args.is_none() { return Err(format!( "Error: Sender has insufficient funds, current balance is {}", @@ -1297,14 +1321,10 @@ async fn command_transfer( ) .into()); } - - transfer_balance - } else { - maybe_transfer_balance.unwrap() - }; + } let maybe_fee = - ui_fee.map(|ui_amount| spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals)); + ui_fee.map(|v| amount_to_raw_amount(v, mint_info.decimals, None, "EXPECTED_FEE")); // determine whether recipient is a token account or an expected owner of one let recipient_is_token_account = if !config.sign_only { @@ -1716,7 +1736,7 @@ async fn command_burn( config: &Config<'_>, account: Pubkey, owner: Pubkey, - ui_amount: Option, + ui_amount: Amount, mint_address: Option, mint_decimals: Option, use_unchecked_instruction: bool, @@ -1733,15 +1753,17 @@ async fn command_burn( let token = token_client_from_config(config, &mint_info.address, decimals)?; - let amount = if let Some(ui_amount) = ui_amount { - spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals) - } else { - if config.sign_only { - return Err("Use of ALL keyword to burn tokens requires online signing" - .to_string() - .into()); + let amount = match ui_amount { + Amount::Raw(ui_amount) => ui_amount, + Amount::Decimal(ui_amount) => spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals), + Amount::All => { + if config.sign_only { + return Err("Use of ALL keyword to burn tokens requires online signing" + .to_string() + .into()); + } + token.get_account_info(&account).await?.base.amount } - token.get_account_info(&account).await?.base.amount }; println_display( @@ -1774,7 +1796,7 @@ async fn command_burn( async fn command_mint( config: &Config<'_>, token: Pubkey, - ui_amount: f64, + ui_amount: Amount, recipient: Pubkey, mint_info: MintInfo, mint_authority: Pubkey, @@ -1782,15 +1804,18 @@ async fn command_mint( memo: Option, bulk_signers: BulkSigners, ) -> CommandResult { + let amount = amount_to_raw_amount(ui_amount, mint_info.decimals, None, "TOKEN_AMOUNT"); + println_display( config, format!( "Minting {} tokens\n Token: {}\n Recipient: {}", - ui_amount, token, recipient + spl_token::amount_to_ui_amount(amount, mint_info.decimals), + token, + recipient ), ); - let amount = spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals); let decimals = if use_unchecked_instruction { None } else { @@ -1891,19 +1916,32 @@ async fn command_thaw( async fn command_wrap( config: &Config<'_>, - sol: f64, + amount: Amount, wallet_address: Pubkey, wrapped_sol_account: Option, immutable_owner: bool, bulk_signers: BulkSigners, ) -> CommandResult { - let lamports = sol_to_lamports(sol); + let lamports = match amount { + Amount::Raw(amount) => amount, + Amount::Decimal(amount) => sol_to_lamports(amount), + Amount::All => { + return Err("ALL keyword not supported for SOL amount".into()); + } + }; let token = native_token_client_from_config(config)?; let account = wrapped_sol_account.unwrap_or_else(|| token.get_associated_token_address(&wallet_address)); - println_display(config, format!("Wrapping {} SOL into {}", sol, account)); + println_display( + config, + format!( + "Wrapping {} SOL into {}", + lamports_to_sol(lamports), + account + ), + ); if !config.sign_only { if let Some(account_data) = config.program_client.get_account(account).await? { @@ -2007,30 +2045,32 @@ async fn command_approve( config: &Config<'_>, account: Pubkey, owner: Pubkey, - ui_amount: f64, + ui_amount: Amount, delegate: Pubkey, mint_address: Option, mint_decimals: Option, use_unchecked_instruction: bool, bulk_signers: BulkSigners, ) -> CommandResult { - println_display( - config, - format!( - "Approve {} tokens\n Account: {}\n Delegate: {}", - ui_amount, account, delegate - ), - ); - let mint_address = config.check_account(&account, mint_address).await?; let mint_info = config.get_mint_info(&mint_address, mint_decimals).await?; - let amount = spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals); + let amount = amount_to_raw_amount(ui_amount, mint_info.decimals, None, "TOKEN_AMOUNT"); let decimals = if use_unchecked_instruction { None } else { Some(mint_info.decimals) }; + println_display( + config, + format!( + "Approve {} tokens\n Account: {}\n Delegate: {}", + spl_token::amount_to_ui_amount(amount, mint_info.decimals), + account, + delegate + ), + ); + let token = token_client_from_config(config, &mint_info.address, decimals)?; let res = token .approve(&account, &delegate, &owner, amount, &bulk_signers) @@ -3231,7 +3271,7 @@ async fn command_deposit_withdraw_confidential_tokens( owner: Pubkey, maybe_account: Option, bulk_signers: BulkSigners, - ui_amount: Option, + ui_amount: Amount, mint_decimals: Option, instruction_type: ConfidentialInstructionType, elgamal_keypair: Option<&ElGamalKeypair>, @@ -3272,59 +3312,56 @@ async fn command_deposit_withdraw_confidential_tokens( let state_with_extension = StateWithExtensionsOwned::::unpack(account.data)?; let token = token_client_from_config(config, &state_with_extension.base.mint, None)?; - // the amount the user wants to deposit or withdraw, as an f64 - let maybe_amount = - ui_amount.map(|ui_amount| spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals)); - - // the amount we will deposit or withdraw, as a u64 - let amount = if !config.sign_only && instruction_type == ConfidentialInstructionType::Deposit { - let current_balance = state_with_extension.base.amount; - let deposit_amount = maybe_amount.unwrap_or(current_balance); - - println_display( - config, - format!( - "Depositing {} confidential tokens", - spl_token::amount_to_ui_amount(deposit_amount, mint_info.decimals), - ), - ); + // the amount the user wants to deposit or withdraw, as a u64 + let amount = match ui_amount { + Amount::Raw(ui_amount) => ui_amount, + Amount::Decimal(ui_amount) => spl_token::ui_amount_to_amount(ui_amount, mint_info.decimals), + Amount::All => { + if config.sign_only { + return Err("Use of ALL keyword to burn tokens requires online signing" + .to_string() + .into()); + } + if instruction_type == ConfidentialInstructionType::Withdraw { + return Err("ALL keyword is not currently supported for withdraw" + .to_string() + .into()); + } + state_with_extension.base.amount + } + }; - if deposit_amount > current_balance { - return Err(format!( - "Error: Insufficient funds, current balance is {}", - spl_token_2022::amount_to_ui_amount_string_trimmed( - current_balance, - mint_info.decimals + match instruction_type { + ConfidentialInstructionType::Deposit => { + println_display( + config, + format!( + "Depositing {} confidential tokens", + spl_token::amount_to_ui_amount(amount, mint_info.decimals), + ), + ); + let current_balance = state_with_extension.base.amount; + if amount > current_balance { + return Err(format!( + "Error: Insufficient funds, current balance is {}", + spl_token_2022::amount_to_ui_amount_string_trimmed( + current_balance, + mint_info.decimals + ) ) - ) - .into()); + .into()); + } } - - deposit_amount - } else if !config.sign_only && instruction_type == ConfidentialInstructionType::Withdraw { - // // TODO: expose account balance decryption in token - // let aes_key = aes_key.expect("AES key must be provided"); - // let current_balance = token - // .confidential_transfer_get_available_balance_with_key( - // &token_account_address, - // aes_key, - // ) - // .await?; - let withdraw_amount = - maybe_amount.expect("ALL keyword is not currently supported for withdraw"); - - println_display( - config, - format!( - "Withdrawing {} confidential tokens", - spl_token::amount_to_ui_amount(withdraw_amount, mint_info.decimals) - ), - ); - - withdraw_amount - } else { - maybe_amount.unwrap() - }; + ConfidentialInstructionType::Withdraw => { + println_display( + config, + format!( + "Withdrawing {} confidential tokens", + spl_token::amount_to_ui_amount(amount, mint_info.decimals) + ), + ); + } + } let res = match instruction_type { ConfidentialInstructionType::Deposit => { @@ -3510,7 +3547,7 @@ pub async fn process_command<'a>( .await } (CommandName::CreateToken, arg_matches) => { - let decimals = value_t_or_exit!(arg_matches, "decimals", u8); + let decimals = *arg_matches.get_one::("decimals").unwrap(); let mint_authority = config.pubkey_or_default(arg_matches, "mint_authority", &mut wallet_manager)?; let memo = value_t!(arg_matches, "memo", String).ok(); @@ -3535,11 +3572,8 @@ pub async fn process_command<'a>( let transfer_fee_basis_point = arg_matches.get_one::("transfer_fee_basis_points"); let transfer_fee_maximum_fee = arg_matches - .get_one::("transfer_fee_maximum_fee") - .map(|str| { - let v = str.parse::().unwrap(); // inputs are validated so this is safe - spl_token::ui_amount_to_amount(v, decimals) - }); + .get_one::("transfer_fee_maximum_fee") + .map(|v| amount_to_raw_amount(*v, decimals, None, "MAXIMUM_FEE")); let transfer_fee = transfer_fee_basis_point .map(|v| (*v, transfer_fee_maximum_fee.unwrap())) .or(transfer_fee); @@ -3665,8 +3699,8 @@ pub async fn process_command<'a>( }; let value = arg_matches.value_of("value").map(|v| v.to_string()); let transfer_lamports = arg_matches - .get_one(TRANSFER_LAMPORTS_ARG.name) - .map(|v: &String| v.parse::().unwrap()); + .get_one::(TRANSFER_LAMPORTS_ARG.name) + .copied(); let bulk_signers = vec![authority_signer]; command_update_metadata( @@ -3684,7 +3718,7 @@ pub async fn process_command<'a>( let token_pubkey = pubkey_of_signer(arg_matches, "token", &mut wallet_manager) .unwrap() .unwrap(); - let max_size = value_t_or_exit!(arg_matches, "max_size", u64); + let max_size = *arg_matches.get_one::("max_size").unwrap(); let (mint_authority_signer, mint_authority) = config.signer_or_default(arg_matches, "mint_authority", &mut wallet_manager); let update_authority = @@ -3705,7 +3739,7 @@ pub async fn process_command<'a>( let token_pubkey = pubkey_of_signer(arg_matches, "token", &mut wallet_manager) .unwrap() .unwrap(); - let new_max_size = value_t_or_exit!(arg_matches, "new_max_size", u64); + let new_max_size = *arg_matches.get_one::("new_max_size").unwrap(); let (update_authority_signer, update_authority) = config.signer_or_default(arg_matches, "update_authority", &mut wallet_manager); let bulk_signers = vec![update_authority_signer]; @@ -3824,7 +3858,7 @@ pub async fn process_command<'a>( let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager) .unwrap() .unwrap(); - let amount = parse_amount_or_all(arg_matches); + let amount = *arg_matches.get_one::("amount").unwrap(); let recipient = pubkey_of_signer(arg_matches, "recipient", &mut wallet_manager) .unwrap() .unwrap(); @@ -3859,9 +3893,7 @@ pub async fn process_command<'a>( push_signer_with_dedup(owner_signer, &mut bulk_signers); } - let mint_decimals = arg_matches - .get_one(MINT_DECIMALS_ARG.name) - .map(|v: &String| v.parse::().unwrap()); + let mint_decimals = arg_matches.get_one::(MINT_DECIMALS_ARG.name).copied(); let fund_recipient = arg_matches.is_present("fund_recipient"); let allow_unfunded_recipient = arg_matches.is_present("allow_empty_recipient") || arg_matches.is_present("allow_unfunded_recipient"); @@ -3873,9 +3905,7 @@ pub async fn process_command<'a>( 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 = arg_matches - .get_one::("expected_fee") - .map(|str| str.parse::().unwrap()); // unwrap safe since inputs are validated + let expected_fee = arg_matches.get_one::("expected_fee").copied(); let memo = value_t!(arg_matches, "memo", String).ok(); let transfer_hook_accounts = arg_matches.values_of("transfer_hook_account").map(|v| { v.into_iter() @@ -3916,7 +3946,7 @@ pub async fn process_command<'a>( push_signer_with_dedup(owner_signer, &mut bulk_signers); } - let amount = parse_amount_or_all(arg_matches); + let amount = *arg_matches.get_one::("amount").unwrap(); let mint_address = pubkey_of_signer(arg_matches, MINT_ADDRESS_ARG.name, &mut wallet_manager).unwrap(); let mint_decimals = arg_matches @@ -3947,10 +3977,8 @@ pub async fn process_command<'a>( let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager) .unwrap() .unwrap(); - let amount = value_t_or_exit!(arg_matches, "amount", f64); - let mint_decimals = arg_matches - .get_one(MINT_DECIMALS_ARG.name) - .map(|v: &String| v.parse::().unwrap()); + let amount = *arg_matches.get_one::("amount").unwrap(); + let mint_decimals = arg_matches.get_one::(MINT_DECIMALS_ARG.name).copied(); let mint_info = config.get_mint_info(&token, mint_decimals).await?; let recipient = if let Some(address) = pubkey_of_signer(arg_matches, "recipient", &mut wallet_manager).unwrap() @@ -4027,7 +4055,7 @@ pub async fn process_command<'a>( .await } (CommandName::Wrap, arg_matches) => { - let amount = value_t_or_exit!(arg_matches, "amount", f64); + let amount = *arg_matches.get_one::("amount").unwrap(); let account = if arg_matches.is_present("create_aux_account") { let (signer, account) = new_throwaway_signer(); bulk_signers.push(signer); @@ -4069,7 +4097,7 @@ pub async fn process_command<'a>( let account = pubkey_of_signer(arg_matches, "account", &mut wallet_manager) .unwrap() .unwrap(); - let amount = value_t_or_exit!(arg_matches, "amount", f64); + let amount = *arg_matches.get_one::("amount").unwrap(); let delegate = pubkey_of_signer(arg_matches, "delegate", &mut wallet_manager) .unwrap() .unwrap(); @@ -4411,12 +4439,10 @@ pub async fn process_command<'a>( .unwrap(); let transfer_fee_basis_points = value_t_or_exit!(arg_matches, "transfer_fee_basis_points", u16); - let maximum_fee = value_t_or_exit!(arg_matches, "maximum_fee", f64); + let maximum_fee = *arg_matches.get_one::("maximum_fee").unwrap(); let (transfer_fee_authority_signer, transfer_fee_authority_pubkey) = config .signer_or_default(arg_matches, "transfer_fee_authority", &mut wallet_manager); - let mint_decimals = arg_matches - .get_one(MINT_DECIMALS_ARG.name) - .map(|v: &String| v.parse::().unwrap()); + let mint_decimals = arg_matches.get_one::(MINT_DECIMALS_ARG.name).copied(); let bulk_signers = vec![transfer_fee_authority_signer]; command_set_transfer_fee( @@ -4556,15 +4582,12 @@ pub async fn process_command<'a>( let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager) .unwrap() .unwrap(); - let amount = parse_amount_or_all(arg_matches); + let amount = *arg_matches.get_one::("amount").unwrap(); let account = pubkey_of_signer(arg_matches, "address", &mut wallet_manager).unwrap(); let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - - let mint_decimals = arg_matches - .get_one(MINT_DECIMALS_ARG.name) - .map(|v: &String| v.parse::().unwrap()); + let mint_decimals = arg_matches.get_one::(MINT_DECIMALS_ARG.name).copied(); let (instruction_type, elgamal_keypair, aes_key) = match c { CommandName::DepositConfidentialTokens => { diff --git a/token/cli/src/config.rs b/token/cli/src/config.rs index adea54dbfb7..8469383498e 100644 --- a/token/cli/src/config.rs +++ b/token/cli/src/config.rs @@ -327,16 +327,10 @@ impl<'a> Config<'a> { .flatten() .copied(); - let compute_unit_price = matches - .try_get_one::(COMPUTE_UNIT_PRICE_ARG.name) - .ok() - .flatten() - .copied(); + let compute_unit_price = matches.get_one::(COMPUTE_UNIT_PRICE_ARG.name).copied(); let compute_unit_limit = matches - .try_get_one::(COMPUTE_UNIT_LIMIT_ARG.name) - .ok() - .flatten() + .get_one::(COMPUTE_UNIT_LIMIT_ARG.name) .copied() .map(ComputeUnitLimit::Static) .unwrap_or_else(|| {