17
17
UiAccountData ,
18
18
} ,
19
19
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 } ,
21
21
keypair:: signer_from_path,
22
22
} ,
23
23
solana_cli_output:: {
@@ -109,13 +109,6 @@ fn get_signer(
109
109
} )
110
110
}
111
111
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
-
119
112
async fn check_wallet_balance (
120
113
config : & Config < ' _ > ,
121
114
wallet : & Pubkey ,
@@ -1200,7 +1193,7 @@ async fn command_authorize(
1200
1193
async fn command_transfer (
1201
1194
config : & Config < ' _ > ,
1202
1195
token_pubkey : Pubkey ,
1203
- ui_amount : Option < f64 > ,
1196
+ ui_amount : Amount ,
1204
1197
recipient : Pubkey ,
1205
1198
sender : Option < Pubkey > ,
1206
1199
sender_owner : Pubkey ,
@@ -1263,30 +1256,43 @@ async fn command_transfer(
1263
1256
token. get_associated_token_address ( & sender_owner)
1264
1257
} ;
1265
1258
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
+ } ;
1269
1265
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
+ } ;
1274
1279
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
+ ) ;
1289
1294
1295
+ if let Some ( sender_balance) = sender_balance {
1290
1296
if transfer_balance > sender_balance && confidential_transfer_args. is_none ( ) {
1291
1297
return Err ( format ! (
1292
1298
"Error: Sender has insufficient funds, current balance is {}" ,
@@ -1297,11 +1303,7 @@ async fn command_transfer(
1297
1303
)
1298
1304
. into ( ) ) ;
1299
1305
}
1300
-
1301
- transfer_balance
1302
- } else {
1303
- maybe_transfer_balance. unwrap ( )
1304
- } ;
1306
+ }
1305
1307
1306
1308
let maybe_fee =
1307
1309
ui_fee. map ( |ui_amount| spl_token:: ui_amount_to_amount ( ui_amount, mint_info. decimals ) ) ;
@@ -1716,7 +1718,7 @@ async fn command_burn(
1716
1718
config : & Config < ' _ > ,
1717
1719
account : Pubkey ,
1718
1720
owner : Pubkey ,
1719
- ui_amount : Option < f64 > ,
1721
+ ui_amount : Amount ,
1720
1722
mint_address : Option < Pubkey > ,
1721
1723
mint_decimals : Option < u8 > ,
1722
1724
use_unchecked_instruction : bool ,
@@ -1733,15 +1735,17 @@ async fn command_burn(
1733
1735
1734
1736
let token = token_client_from_config ( config, & mint_info. address , decimals) ?;
1735
1737
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
1743
1748
}
1744
- token. get_account_info ( & account) . await ?. base . amount
1745
1749
} ;
1746
1750
1747
1751
println_display (
@@ -3231,7 +3235,7 @@ async fn command_deposit_withdraw_confidential_tokens(
3231
3235
owner : Pubkey ,
3232
3236
maybe_account : Option < Pubkey > ,
3233
3237
bulk_signers : BulkSigners ,
3234
- ui_amount : Option < f64 > ,
3238
+ ui_amount : Amount ,
3235
3239
mint_decimals : Option < u8 > ,
3236
3240
instruction_type : ConfidentialInstructionType ,
3237
3241
elgamal_keypair : Option < & ElGamalKeypair > ,
@@ -3272,59 +3276,56 @@ async fn command_deposit_withdraw_confidential_tokens(
3272
3276
let state_with_extension = StateWithExtensionsOwned :: < Account > :: unpack ( account. data ) ?;
3273
3277
let token = token_client_from_config ( config, & state_with_extension. base . mint , None ) ?;
3274
3278
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
+ } ;
3291
3297
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
+ )
3298
3315
)
3299
- )
3300
- . into ( ) ) ;
3316
+ . into ( ) ) ;
3317
+ }
3301
3318
}
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
+ }
3328
3329
3329
3330
let res = match instruction_type {
3330
3331
ConfidentialInstructionType :: Deposit => {
@@ -3824,7 +3825,7 @@ pub async fn process_command<'a>(
3824
3825
let token = pubkey_of_signer ( arg_matches, "token" , & mut wallet_manager)
3825
3826
. unwrap ( )
3826
3827
. unwrap ( ) ;
3827
- let amount = parse_amount_or_all ( arg_matches) ;
3828
+ let amount = * arg_matches. get_one :: < Amount > ( "amount" ) . unwrap ( ) ;
3828
3829
let recipient = pubkey_of_signer ( arg_matches, "recipient" , & mut wallet_manager)
3829
3830
. unwrap ( )
3830
3831
. unwrap ( ) ;
@@ -3914,7 +3915,7 @@ pub async fn process_command<'a>(
3914
3915
push_signer_with_dedup ( owner_signer, & mut bulk_signers) ;
3915
3916
}
3916
3917
3917
- let amount = parse_amount_or_all ( arg_matches) ;
3918
+ let amount = * arg_matches. get_one :: < Amount > ( "amount" ) . unwrap ( ) ;
3918
3919
let mint_address =
3919
3920
pubkey_of_signer ( arg_matches, MINT_ADDRESS_ARG . name , & mut wallet_manager) . unwrap ( ) ;
3920
3921
let mint_decimals = arg_matches
@@ -4550,7 +4551,7 @@ pub async fn process_command<'a>(
4550
4551
let token = pubkey_of_signer ( arg_matches, "token" , & mut wallet_manager)
4551
4552
. unwrap ( )
4552
4553
. unwrap ( ) ;
4553
- let amount = parse_amount_or_all ( arg_matches) ;
4554
+ let amount = * arg_matches. get_one :: < Amount > ( "amount" ) . unwrap ( ) ;
4554
4555
let account = pubkey_of_signer ( arg_matches, "address" , & mut wallet_manager) . unwrap ( ) ;
4555
4556
4556
4557
let ( owner_signer, owner) =
0 commit comments