Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit ec9961c

Browse files
committed
spl-token-cli: Add 'account-info' subcommand
1 parent 7903e62 commit ec9961c

File tree

3 files changed

+134
-25
lines changed

3 files changed

+134
-25
lines changed

Cargo.lock

Lines changed: 53 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

token/cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ serde_json = "1.0.57"
1515
solana-account-decoder = { version = "=1.3.13" }
1616
solana-clap-utils = { version = "=1.3.13"}
1717
solana-cli-config = { version = "=1.3.13" }
18+
solana-cli-output = { version = "=1.3.13" }
1819
solana-client = { version = "=1.3.13" }
1920
solana-logger = { version = "=1.3.13" }
2021
solana-sdk = { version = "=1.3.13" }

token/cli/src/main.rs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ use clap::{
44
};
55
use console::Emoji;
66
use solana_account_decoder::{
7-
parse_token::{TokenAccountType, UiAccountState},
7+
parse_token::{TokenAccountType, UiAccountState, UiTokenAmount},
88
UiAccountData,
99
};
1010
use solana_clap_utils::{
1111
input_parsers::pubkey_of,
1212
input_validators::{is_amount, is_keypair, is_pubkey_or_keypair, is_url},
1313
keypair::signer_from_path,
1414
};
15+
use solana_cli_output::display::println_name_value;
1516
use solana_client::{rpc_client::RpcClient, rpc_request::TokenAccountsFilter};
1617
use solana_sdk::{
1718
commitment_config::CommitmentConfig,
@@ -546,6 +547,67 @@ fn command_accounts(config: &Config, token: Option<Pubkey>) -> CommandResult {
546547
Ok(None)
547548
}
548549

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+
549611
fn main() {
550612
let default_decimals = &format!("{}", native_mint::DECIMALS);
551613
let matches = App::new(crate_name!())
@@ -864,6 +926,19 @@ fn main() {
864926
.help("The address of the token account to unwrap"),
865927
),
866928
)
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+
)
867942
.get_matches();
868943

869944
let mut wallet_manager = None;
@@ -1010,6 +1085,10 @@ fn main() {
10101085
let token = pubkey_of(arg_matches, "token");
10111086
command_accounts(&config, token)
10121087
}
1088+
("account-info", Some(arg_matches)) => {
1089+
let address = pubkey_of(arg_matches, "address").unwrap();
1090+
command_account(&config, address)
1091+
}
10131092
_ => unreachable!(),
10141093
}
10151094
.and_then(|transaction| {

0 commit comments

Comments
 (0)