1717 UiAccountData ,
1818 } ,
1919 solana_clap_v3_utils:: {
20- input_parsers:: { pubkey_of_signer, pubkeys_of_multiple_signers} ,
20+ input_parsers:: { pubkey_of_signer, pubkeys_of_multiple_signers, Amount } ,
2121 keypair:: signer_from_path,
2222 } ,
2323 solana_cli_output:: {
@@ -109,13 +109,6 @@ fn get_signer(
109109 } )
110110}
111111
112- fn parse_amount_or_all ( matches : & ArgMatches ) -> Option < f64 > {
113- match matches. value_of ( "amount" ) . unwrap ( ) {
114- "ALL" => None ,
115- amount => Some ( amount. parse :: < f64 > ( ) . unwrap ( ) ) ,
116- }
117- }
118-
119112async fn check_wallet_balance (
120113 config : & Config < ' _ > ,
121114 wallet : & Pubkey ,
@@ -1200,7 +1193,7 @@ async fn command_authorize(
12001193async fn command_transfer (
12011194 config : & Config < ' _ > ,
12021195 token_pubkey : Pubkey ,
1203- ui_amount : Option < f64 > ,
1196+ ui_amount : Amount ,
12041197 recipient : Pubkey ,
12051198 sender : Option < Pubkey > ,
12061199 sender_owner : Pubkey ,
@@ -1263,30 +1256,43 @@ async fn command_transfer(
12631256 token. get_associated_token_address ( & sender_owner)
12641257 } ;
12651258
1266- // the amount the user wants to transfer, as a f64
1267- let maybe_transfer_balance =
1268- ui_amount. map ( |ui_amount| spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals ) ) ;
1259+ // the sender balance
1260+ let sender_balance = if config. sign_only {
1261+ None
1262+ } else {
1263+ Some ( token. get_account_info ( & sender) . await ?. base . amount )
1264+ } ;
12691265
1270- // the amount we will transfer, as a u64
1271- let transfer_balance = if !config. sign_only {
1272- let sender_balance = token. get_account_info ( & sender) . await ?. base . amount ;
1273- let transfer_balance = maybe_transfer_balance. unwrap_or ( sender_balance) ;
1266+ // the amount the user wants to transfer, as a u64
1267+ let transfer_balance = match ui_amount {
1268+ Amount :: Raw ( ui_amount) => ui_amount,
1269+ Amount :: Decimal ( ui_amount) => spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals ) ,
1270+ Amount :: All => {
1271+ if config. sign_only {
1272+ return Err ( "Use of ALL keyword to burn tokens requires online signing"
1273+ . to_string ( )
1274+ . into ( ) ) ;
1275+ }
1276+ sender_balance. unwrap ( )
1277+ }
1278+ } ;
12741279
1275- println_display (
1276- config,
1277- format ! (
1278- "{}Transfer {} tokens\n Sender: {}\n Recipient: {}" ,
1279- if confidential_transfer_args. is_some( ) {
1280- "Confidential "
1281- } else {
1282- ""
1283- } ,
1284- spl_token:: amount_to_ui_amount( transfer_balance, mint_info. decimals) ,
1285- sender,
1286- recipient
1287- ) ,
1288- ) ;
1280+ println_display (
1281+ config,
1282+ format ! (
1283+ "{}Transfer {} tokens\n Sender: {}\n Recipient: {}" ,
1284+ if confidential_transfer_args. is_some( ) {
1285+ "Confidential "
1286+ } else {
1287+ ""
1288+ } ,
1289+ spl_token:: amount_to_ui_amount( transfer_balance, mint_info. decimals) ,
1290+ sender,
1291+ recipient
1292+ ) ,
1293+ ) ;
12891294
1295+ if let Some ( sender_balance) = sender_balance {
12901296 if transfer_balance > sender_balance && confidential_transfer_args. is_none ( ) {
12911297 return Err ( format ! (
12921298 "Error: Sender has insufficient funds, current balance is {}" ,
@@ -1297,11 +1303,7 @@ async fn command_transfer(
12971303 )
12981304 . into ( ) ) ;
12991305 }
1300-
1301- transfer_balance
1302- } else {
1303- maybe_transfer_balance. unwrap ( )
1304- } ;
1306+ }
13051307
13061308 let maybe_fee =
13071309 ui_fee. map ( |ui_amount| spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals ) ) ;
@@ -1716,7 +1718,7 @@ async fn command_burn(
17161718 config : & Config < ' _ > ,
17171719 account : Pubkey ,
17181720 owner : Pubkey ,
1719- ui_amount : Option < f64 > ,
1721+ ui_amount : Amount ,
17201722 mint_address : Option < Pubkey > ,
17211723 mint_decimals : Option < u8 > ,
17221724 use_unchecked_instruction : bool ,
@@ -1733,15 +1735,17 @@ async fn command_burn(
17331735
17341736 let token = token_client_from_config ( config, & mint_info. address , decimals) ?;
17351737
1736- let amount = if let Some ( ui_amount) = ui_amount {
1737- spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals )
1738- } else {
1739- if config. sign_only {
1740- return Err ( "Use of ALL keyword to burn tokens requires online signing"
1741- . to_string ( )
1742- . into ( ) ) ;
1738+ let amount = match ui_amount {
1739+ Amount :: Raw ( ui_amount) => ui_amount,
1740+ Amount :: Decimal ( ui_amount) => spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals ) ,
1741+ Amount :: All => {
1742+ if config. sign_only {
1743+ return Err ( "Use of ALL keyword to burn tokens requires online signing"
1744+ . to_string ( )
1745+ . into ( ) ) ;
1746+ }
1747+ token. get_account_info ( & account) . await ?. base . amount
17431748 }
1744- token. get_account_info ( & account) . await ?. base . amount
17451749 } ;
17461750
17471751 println_display (
@@ -3231,7 +3235,7 @@ async fn command_deposit_withdraw_confidential_tokens(
32313235 owner : Pubkey ,
32323236 maybe_account : Option < Pubkey > ,
32333237 bulk_signers : BulkSigners ,
3234- ui_amount : Option < f64 > ,
3238+ ui_amount : Amount ,
32353239 mint_decimals : Option < u8 > ,
32363240 instruction_type : ConfidentialInstructionType ,
32373241 elgamal_keypair : Option < & ElGamalKeypair > ,
@@ -3272,59 +3276,56 @@ async fn command_deposit_withdraw_confidential_tokens(
32723276 let state_with_extension = StateWithExtensionsOwned :: < Account > :: unpack ( account. data ) ?;
32733277 let token = token_client_from_config ( config, & state_with_extension. base . mint , None ) ?;
32743278
3275- // the amount the user wants to deposit or withdraw, as an f64
3276- let maybe_amount =
3277- ui_amount. map ( |ui_amount| spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals ) ) ;
3278-
3279- // the amount we will deposit or withdraw, as a u64
3280- let amount = if !config. sign_only && instruction_type == ConfidentialInstructionType :: Deposit {
3281- let current_balance = state_with_extension. base . amount ;
3282- let deposit_amount = maybe_amount. unwrap_or ( current_balance) ;
3283-
3284- println_display (
3285- config,
3286- format ! (
3287- "Depositing {} confidential tokens" ,
3288- spl_token:: amount_to_ui_amount( deposit_amount, mint_info. decimals) ,
3289- ) ,
3290- ) ;
3279+ // the amount the user wants to deposit or withdraw, as a u64
3280+ let amount = match ui_amount {
3281+ Amount :: Raw ( ui_amount) => ui_amount,
3282+ Amount :: Decimal ( ui_amount) => spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals ) ,
3283+ Amount :: All => {
3284+ if config. sign_only {
3285+ return Err ( "Use of ALL keyword to burn tokens requires online signing"
3286+ . to_string ( )
3287+ . into ( ) ) ;
3288+ }
3289+ if instruction_type == ConfidentialInstructionType :: Withdraw {
3290+ return Err ( "ALL keyword is not currently supported for withdraw"
3291+ . to_string ( )
3292+ . into ( ) ) ;
3293+ }
3294+ state_with_extension. base . amount
3295+ }
3296+ } ;
32913297
3292- if deposit_amount > current_balance {
3293- return Err ( format ! (
3294- "Error: Insufficient funds, current balance is {}" ,
3295- spl_token_2022:: amount_to_ui_amount_string_trimmed(
3296- current_balance,
3297- mint_info. decimals
3298+ match instruction_type {
3299+ ConfidentialInstructionType :: Deposit => {
3300+ println_display (
3301+ config,
3302+ format ! (
3303+ "Depositing {} confidential tokens" ,
3304+ spl_token:: amount_to_ui_amount( amount, mint_info. decimals) ,
3305+ ) ,
3306+ ) ;
3307+ let current_balance = state_with_extension. base . amount ;
3308+ if amount > current_balance {
3309+ return Err ( format ! (
3310+ "Error: Insufficient funds, current balance is {}" ,
3311+ spl_token_2022:: amount_to_ui_amount_string_trimmed(
3312+ current_balance,
3313+ mint_info. decimals
3314+ )
32983315 )
3299- )
3300- . into ( ) ) ;
3316+ . into ( ) ) ;
3317+ }
33013318 }
3302-
3303- deposit_amount
3304- } else if !config. sign_only && instruction_type == ConfidentialInstructionType :: Withdraw {
3305- // // TODO: expose account balance decryption in token
3306- // let aes_key = aes_key.expect("AES key must be provided");
3307- // let current_balance = token
3308- // .confidential_transfer_get_available_balance_with_key(
3309- // &token_account_address,
3310- // aes_key,
3311- // )
3312- // .await?;
3313- let withdraw_amount =
3314- maybe_amount. expect ( "ALL keyword is not currently supported for withdraw" ) ;
3315-
3316- println_display (
3317- config,
3318- format ! (
3319- "Withdrawing {} confidential tokens" ,
3320- spl_token:: amount_to_ui_amount( withdraw_amount, mint_info. decimals)
3321- ) ,
3322- ) ;
3323-
3324- withdraw_amount
3325- } else {
3326- maybe_amount. unwrap ( )
3327- } ;
3319+ ConfidentialInstructionType :: Withdraw => {
3320+ println_display (
3321+ config,
3322+ format ! (
3323+ "Withdrawing {} confidential tokens" ,
3324+ spl_token:: amount_to_ui_amount( amount, mint_info. decimals)
3325+ ) ,
3326+ ) ;
3327+ }
3328+ }
33283329
33293330 let res = match instruction_type {
33303331 ConfidentialInstructionType :: Deposit => {
@@ -3824,7 +3825,7 @@ pub async fn process_command<'a>(
38243825 let token = pubkey_of_signer ( arg_matches, "token" , & mut wallet_manager)
38253826 . unwrap ( )
38263827 . unwrap ( ) ;
3827- let amount = parse_amount_or_all ( arg_matches) ;
3828+ let amount = * arg_matches. get_one :: < Amount > ( "amount" ) . unwrap ( ) ;
38283829 let recipient = pubkey_of_signer ( arg_matches, "recipient" , & mut wallet_manager)
38293830 . unwrap ( )
38303831 . unwrap ( ) ;
@@ -3914,7 +3915,7 @@ pub async fn process_command<'a>(
39143915 push_signer_with_dedup ( owner_signer, & mut bulk_signers) ;
39153916 }
39163917
3917- let amount = parse_amount_or_all ( arg_matches) ;
3918+ let amount = * arg_matches. get_one :: < Amount > ( "amount" ) . unwrap ( ) ;
39183919 let mint_address =
39193920 pubkey_of_signer ( arg_matches, MINT_ADDRESS_ARG . name , & mut wallet_manager) . unwrap ( ) ;
39203921 let mint_decimals = arg_matches
@@ -4550,7 +4551,7 @@ pub async fn process_command<'a>(
45504551 let token = pubkey_of_signer ( arg_matches, "token" , & mut wallet_manager)
45514552 . unwrap ( )
45524553 . unwrap ( ) ;
4553- let amount = parse_amount_or_all ( arg_matches) ;
4554+ let amount = * arg_matches. get_one :: < Amount > ( "amount" ) . unwrap ( ) ;
45544555 let account = pubkey_of_signer ( arg_matches, "address" , & mut wallet_manager) . unwrap ( ) ;
45554556
45564557 let ( owner_signer, owner) =
0 commit comments