@@ -455,10 +455,17 @@ fn resolve_mint_info(
455
455
. rpc_client
456
456
. get_token_account ( & token_account) ?
457
457
. ok_or_else ( || format ! ( "Could not find token account {}" , token_account) ) ?;
458
- Ok ( (
459
- Pubkey :: from_str ( & source_account. mint ) ?,
460
- source_account. token_amount . decimals ,
461
- ) )
458
+ let source_mint = Pubkey :: from_str ( & source_account. mint ) ?;
459
+ if let Some ( mint) = mint_address {
460
+ if source_mint != mint {
461
+ return Err ( format ! (
462
+ "Source {:?} does not contain {:?} tokens" ,
463
+ token_account, mint
464
+ )
465
+ . into ( ) ) ;
466
+ }
467
+ }
468
+ Ok ( ( source_mint, source_account. token_amount . decimals ) )
462
469
} else {
463
470
Ok ( (
464
471
mint_address. unwrap_or_default ( ) ,
@@ -470,15 +477,20 @@ fn resolve_mint_info(
470
477
#[ allow( clippy:: too_many_arguments) ]
471
478
fn command_transfer (
472
479
config : & Config ,
473
- sender : Pubkey ,
480
+ token : Pubkey ,
474
481
ui_amount : Option < f64 > ,
475
482
recipient : Pubkey ,
483
+ sender : Option < Pubkey > ,
476
484
allow_unfunded_recipient : bool ,
477
485
fund_recipient : bool ,
478
- mint_address : Option < Pubkey > ,
479
486
mint_decimals : Option < u8 > ,
480
487
) -> CommandResult {
481
- let ( mint_pubkey, decimals) = resolve_mint_info ( config, & sender, mint_address, mint_decimals) ?;
488
+ let sender = if let Some ( sender) = sender {
489
+ sender
490
+ } else {
491
+ get_associated_token_address ( & config. owner , & token)
492
+ } ;
493
+ let ( mint_pubkey, decimals) = resolve_mint_info ( config, & sender, Some ( token) , mint_decimals) ?;
482
494
let sender_token_amount = config
483
495
. rpc_client
484
496
. get_token_account_balance ( & sender)
@@ -1399,13 +1411,13 @@ fn main() {
1399
1411
SubCommand :: with_name ( "transfer" )
1400
1412
. about ( "Transfer tokens between accounts" )
1401
1413
. arg (
1402
- Arg :: with_name ( "sender " )
1414
+ Arg :: with_name ( "token " )
1403
1415
. validator ( is_valid_pubkey)
1404
- . value_name ( "SENDER_TOKEN_ACCOUNT_ADDRESS " )
1416
+ . value_name ( "TOKEN_ADDRESS " )
1405
1417
. takes_value ( true )
1406
1418
. index ( 1 )
1407
1419
. required ( true )
1408
- . help ( "The token account address of the sender " ) ,
1420
+ . help ( "Token to transfer " ) ,
1409
1421
)
1410
1422
. arg (
1411
1423
Arg :: with_name ( "amount" )
@@ -1427,6 +1439,15 @@ fn main() {
1427
1439
Otherwise assume the recipient address is a user wallet and transfer to \
1428
1440
the associated token account")
1429
1441
)
1442
+ . arg (
1443
+ Arg :: with_name ( "from" )
1444
+ . validator ( is_valid_pubkey)
1445
+ . value_name ( "SENDER_TOKEN_ACCOUNT_ADDRESS" )
1446
+ . takes_value ( true )
1447
+ . long ( "from" )
1448
+ . help ( "Specify the sending token account \
1449
+ [default: owner's associated token account]")
1450
+ )
1430
1451
. arg (
1431
1452
Arg :: with_name ( "allow_unfunded_recipient" )
1432
1453
. long ( "allow-unfunded-recipient" )
@@ -1446,9 +1467,9 @@ fn main() {
1446
1467
. help ( "Create the associated token account for the recipient if doesn't already exist" )
1447
1468
)
1448
1469
. arg ( multisig_signer_arg ( ) )
1449
- . mint_args ( )
1470
+ . arg ( mint_decimals_arg ( ) )
1450
1471
. nonce_args ( true )
1451
- . offline_args_config ( & SignOnlyNeedsFullMintSpec { } ) ,
1472
+ . offline_args_config ( & SignOnlyNeedsMintDecimals { } ) ,
1452
1473
)
1453
1474
. subcommand (
1454
1475
SubCommand :: with_name ( "burn" )
@@ -1964,31 +1985,29 @@ fn main() {
1964
1985
)
1965
1986
}
1966
1987
( "transfer" , Some ( arg_matches) ) => {
1967
- let sender = pubkey_of_signer ( arg_matches, "sender " , & mut wallet_manager)
1988
+ let token = pubkey_of_signer ( arg_matches, "token " , & mut wallet_manager)
1968
1989
. unwrap ( )
1969
1990
. unwrap ( ) ;
1970
-
1971
1991
let amount = match matches. value_of ( "amount" ) . unwrap ( ) {
1972
1992
"ALL" => None ,
1973
1993
amount => Some ( amount. parse :: < f64 > ( ) . unwrap ( ) ) ,
1974
1994
} ;
1975
1995
let recipient = pubkey_of_signer ( arg_matches, "recipient" , & mut wallet_manager)
1976
1996
. unwrap ( )
1977
1997
. unwrap ( ) ;
1978
- let mint_address =
1979
- pubkey_of_signer ( arg_matches, MINT_ADDRESS_ARG . name , & mut wallet_manager) . unwrap ( ) ;
1998
+ let sender = pubkey_of_signer ( arg_matches, "from" , & mut wallet_manager) . unwrap ( ) ;
1980
1999
let mint_decimals = value_of :: < u8 > ( & arg_matches, MINT_DECIMALS_ARG . name ) ;
1981
2000
let fund_recipient = matches. is_present ( "fund_recipient" ) ;
1982
2001
let allow_unfunded_recipient = matches. is_present ( "allow_empty_recipient" )
1983
2002
|| matches. is_present ( "allow_unfunded_recipient" ) ;
1984
2003
command_transfer (
1985
2004
& config,
1986
- sender ,
2005
+ token ,
1987
2006
amount,
1988
2007
recipient,
2008
+ sender,
1989
2009
allow_unfunded_recipient,
1990
2010
fund_recipient,
1991
- mint_address,
1992
2011
mint_decimals,
1993
2012
)
1994
2013
}
0 commit comments