@@ -4,14 +4,15 @@ use clap::{
4
4
} ;
5
5
use console:: Emoji ;
6
6
use solana_account_decoder:: {
7
- parse_token:: { TokenAccountType , UiAccountState } ,
7
+ parse_token:: { TokenAccountType , UiAccountState , UiTokenAmount } ,
8
8
UiAccountData ,
9
9
} ;
10
10
use solana_clap_utils:: {
11
11
input_parsers:: pubkey_of,
12
12
input_validators:: { is_amount, is_keypair, is_pubkey_or_keypair, is_url} ,
13
13
keypair:: signer_from_path,
14
14
} ;
15
+ use solana_cli_output:: display:: println_name_value;
15
16
use solana_client:: { rpc_client:: RpcClient , rpc_request:: TokenAccountsFilter } ;
16
17
use solana_sdk:: {
17
18
commitment_config:: CommitmentConfig ,
@@ -546,6 +547,67 @@ fn command_accounts(config: &Config, token: Option<Pubkey>) -> CommandResult {
546
547
Ok ( None )
547
548
}
548
549
550
+ fn stringify_ui_token_amount ( amount : & UiTokenAmount ) -> String {
551
+ let decimals = amount. decimals as usize ;
552
+ if decimals > 0 {
553
+ let amount = u64:: from_str ( & amount. amount ) . unwrap ( ) ;
554
+
555
+ // Left-pad zeros to decimals + 1, so we at least have an integer zero
556
+ let mut s = format ! ( "{:01$}" , amount, decimals + 1 ) ;
557
+
558
+ // Add the decimal point (Sorry, "," locales!)
559
+ s. insert ( s. len ( ) - decimals, '.' ) ;
560
+ s
561
+ } else {
562
+ amount. amount . clone ( )
563
+ }
564
+ }
565
+
566
+ fn stringify_ui_token_amount_trimmed ( amount : & UiTokenAmount ) -> String {
567
+ let s = stringify_ui_token_amount ( amount) ;
568
+ let zeros_trimmed = s. trim_end_matches ( '0' ) ;
569
+ let decimal_trimmed = zeros_trimmed. trim_end_matches ( '.' ) ;
570
+ decimal_trimmed. to_string ( )
571
+ }
572
+
573
+ fn command_account ( config : & Config , address : Pubkey ) -> CommandResult {
574
+ let account = config
575
+ . rpc_client
576
+ . get_token_account_with_commitment ( & address, config. commitment_config ) ?
577
+ . value
578
+ . unwrap ( ) ;
579
+ println ! ( ) ;
580
+ println_name_value ( "Address:" , & address. to_string ( ) ) ;
581
+ println_name_value (
582
+ "Balance:" ,
583
+ & stringify_ui_token_amount_trimmed ( & account. token_amount ) ,
584
+ ) ;
585
+ let mint = format ! (
586
+ "{}{}" ,
587
+ account. mint,
588
+ if account. is_native { " (native)" } else { "" }
589
+ ) ;
590
+ println_name_value ( "Mint:" , & mint) ;
591
+ println_name_value ( "Owner:" , & account. owner ) ;
592
+ println_name_value ( "State:" , & format ! ( "{:?}" , account. state) ) ;
593
+ if let Some ( delegate) = & account. delegate {
594
+ println ! ( "Delegation:" ) ;
595
+ println_name_value ( " Delegate:" , delegate) ;
596
+ let allowance = account. delegated_amount . as_ref ( ) . unwrap ( ) ;
597
+ println_name_value (
598
+ " Allowance:" ,
599
+ & stringify_ui_token_amount_trimmed ( & allowance) ,
600
+ ) ;
601
+ } else {
602
+ println_name_value ( "Delegation:" , "" ) ;
603
+ }
604
+ println_name_value (
605
+ "Close authority:" ,
606
+ & account. close_authority . as_ref ( ) . unwrap_or ( & String :: new ( ) ) ,
607
+ ) ;
608
+ Ok ( None )
609
+ }
610
+
549
611
fn main ( ) {
550
612
let default_decimals = & format ! ( "{}" , native_mint:: DECIMALS ) ;
551
613
let matches = App :: new ( crate_name ! ( ) )
@@ -864,6 +926,19 @@ fn main() {
864
926
. help ( "The address of the token account to unwrap" ) ,
865
927
) ,
866
928
)
929
+ . subcommand (
930
+ SubCommand :: with_name ( "account-info" )
931
+ . about ( "Query details of an SPL Token account by address" )
932
+ . arg (
933
+ Arg :: with_name ( "address" )
934
+ . validator ( is_pubkey_or_keypair)
935
+ . value_name ( "TOKEN_ACCOUNT_ADDRESS" )
936
+ . takes_value ( true )
937
+ . index ( 1 )
938
+ . required ( true )
939
+ . help ( "The address of the SPL Token account to query" ) ,
940
+ ) ,
941
+ )
867
942
. get_matches ( ) ;
868
943
869
944
let mut wallet_manager = None ;
@@ -1010,6 +1085,10 @@ fn main() {
1010
1085
let token = pubkey_of ( arg_matches, "token" ) ;
1011
1086
command_accounts ( & config, token)
1012
1087
}
1088
+ ( "account-info" , Some ( arg_matches) ) => {
1089
+ let address = pubkey_of ( arg_matches, "address" ) . unwrap ( ) ;
1090
+ command_account ( & config, address)
1091
+ }
1013
1092
_ => unreachable ! ( ) ,
1014
1093
}
1015
1094
. and_then ( |transaction| {
0 commit comments