spl-token-cli: support ATA in close, balance, and account-info (#1537)
* Use ATA by default in close command * Use ATA by default in balance/account-info queries * Add Aux tag and gc messaging to spl-token account-info * Recommend 'token' only if no args provided
This commit is contained in:
parent
19e1161be2
commit
f2de73da8e
|
@ -834,7 +834,17 @@ fn command_revoke(config: &Config, account: Pubkey, delegate: Option<Pubkey>) ->
|
||||||
Ok(Some((0, vec![instructions])))
|
Ok(Some((0, vec![instructions])))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_close(config: &Config, account: Pubkey, destination: Pubkey) -> CommandResult {
|
fn command_close(
|
||||||
|
config: &Config,
|
||||||
|
token: Option<Pubkey>,
|
||||||
|
recipient: Pubkey,
|
||||||
|
account: Option<Pubkey>,
|
||||||
|
) -> CommandResult {
|
||||||
|
let account = if let Some(account) = account {
|
||||||
|
account
|
||||||
|
} else {
|
||||||
|
get_associated_token_address(&config.owner, &token.unwrap())
|
||||||
|
};
|
||||||
if !config.sign_only {
|
if !config.sign_only {
|
||||||
let source_account = config
|
let source_account = config
|
||||||
.rpc_client
|
.rpc_client
|
||||||
|
@ -864,15 +874,27 @@ fn command_close(config: &Config, account: Pubkey, destination: Pubkey) -> Comma
|
||||||
let instructions = vec![close_account(
|
let instructions = vec![close_account(
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&account,
|
&account,
|
||||||
&destination,
|
&recipient,
|
||||||
&config.owner,
|
&config.owner,
|
||||||
&config.multisigner_pubkeys,
|
&config.multisigner_pubkeys,
|
||||||
)?];
|
)?];
|
||||||
Ok(Some((0, vec![instructions])))
|
Ok(Some((0, vec![instructions])))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_balance(config: &Config, address: Pubkey) -> CommandResult {
|
fn command_balance(
|
||||||
let balance = config.rpc_client.get_token_account_balance(&address)?;
|
config: &Config,
|
||||||
|
token: Option<Pubkey>,
|
||||||
|
address: Option<Pubkey>,
|
||||||
|
) -> CommandResult {
|
||||||
|
let address = if let Some(address) = address {
|
||||||
|
address
|
||||||
|
} else {
|
||||||
|
get_associated_token_address(&config.owner, &token.unwrap())
|
||||||
|
};
|
||||||
|
let balance = config
|
||||||
|
.rpc_client
|
||||||
|
.get_token_account_balance(&address)
|
||||||
|
.map_err(|_| format!("Could not find token account {}", address))?;
|
||||||
|
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("ui amount: {}", balance.real_number_string_trimmed());
|
println!("ui amount: {}", balance.real_number_string_trimmed());
|
||||||
|
@ -1027,10 +1049,35 @@ fn command_address(config: &Config, token: Option<Pubkey>) -> CommandResult {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_account_info(config: &Config, address: Pubkey) -> CommandResult {
|
fn command_account_info(
|
||||||
let account = config.rpc_client.get_token_account(&address)?.unwrap();
|
config: &Config,
|
||||||
|
token: Option<Pubkey>,
|
||||||
|
address: Option<Pubkey>,
|
||||||
|
) -> CommandResult {
|
||||||
|
let mut is_associated = false;
|
||||||
|
let address = if let Some(address) = address {
|
||||||
|
address
|
||||||
|
} else {
|
||||||
|
is_associated = true;
|
||||||
|
get_associated_token_address(&config.owner, &token.unwrap())
|
||||||
|
};
|
||||||
|
let account = config
|
||||||
|
.rpc_client
|
||||||
|
.get_token_account(&address)
|
||||||
|
.map_err(|_| format!("Could not find token account {}", address))?
|
||||||
|
.unwrap();
|
||||||
|
if !is_associated {
|
||||||
|
if let Ok(mint) = Pubkey::from_str(&account.mint) {
|
||||||
|
is_associated = get_associated_token_address(&config.owner, &mint) == address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let address_message = if is_associated {
|
||||||
|
address.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{} (Aux*)", address)
|
||||||
|
};
|
||||||
println!();
|
println!();
|
||||||
println_name_value("Address:", &address.to_string());
|
println_name_value("Address:", &address_message);
|
||||||
println_name_value(
|
println_name_value(
|
||||||
"Balance:",
|
"Balance:",
|
||||||
&account.token_amount.real_number_string_trimmed(),
|
&account.token_amount.real_number_string_trimmed(),
|
||||||
|
@ -1055,6 +1102,10 @@ fn command_account_info(config: &Config, address: Pubkey) -> CommandResult {
|
||||||
"Close authority:",
|
"Close authority:",
|
||||||
&account.close_authority.as_ref().unwrap_or(&String::new()),
|
&account.close_authority.as_ref().unwrap_or(&String::new()),
|
||||||
);
|
);
|
||||||
|
if !is_associated {
|
||||||
|
println!();
|
||||||
|
println!("* Please run `spl-token gc` to clean up Aux accounts");
|
||||||
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1703,22 +1754,32 @@ fn main() {
|
||||||
SubCommand::with_name("close")
|
SubCommand::with_name("close")
|
||||||
.about("Close a token account")
|
.about("Close a token account")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("account")
|
Arg::with_name("token")
|
||||||
.validator(is_valid_pubkey)
|
.validator(is_valid_pubkey)
|
||||||
.value_name("TOKEN_ACCOUNT_ADDRESS")
|
.value_name("TOKEN_ADDRESS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(1)
|
.index(1)
|
||||||
.required(true)
|
.required_unless("address")
|
||||||
.help("The address of the token account to close"),
|
.help("Token to close. To close a specific account, use the `--address` parameter instead"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("destination")
|
Arg::with_name("recipient")
|
||||||
|
.long("recipient")
|
||||||
.validator(is_valid_pubkey)
|
.validator(is_valid_pubkey)
|
||||||
.value_name("REFUND_ACCOUNT_ADDRESS")
|
.value_name("REFUND_ACCOUNT_ADDRESS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(2)
|
|
||||||
.help("The address of the account to receive remaining SOL [default: --owner]"),
|
.help("The address of the account to receive remaining SOL [default: --owner]"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("address")
|
||||||
|
.long("address")
|
||||||
|
.validator(is_valid_pubkey)
|
||||||
|
.value_name("TOKEN_ACCOUNT_ADDRESS")
|
||||||
|
.takes_value(true)
|
||||||
|
.conflicts_with("token")
|
||||||
|
.help("Specify the token account to close \
|
||||||
|
[default: owner's associated token account]"),
|
||||||
|
)
|
||||||
.arg(multisig_signer_arg())
|
.arg(multisig_signer_arg())
|
||||||
.nonce_args(true)
|
.nonce_args(true)
|
||||||
.offline_args(),
|
.offline_args(),
|
||||||
|
@ -1726,14 +1787,24 @@ fn main() {
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("balance")
|
SubCommand::with_name("balance")
|
||||||
.about("Get token account balance")
|
.about("Get token account balance")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("token")
|
||||||
|
.validator(is_valid_pubkey)
|
||||||
|
.value_name("TOKEN_ADDRESS")
|
||||||
|
.takes_value(true)
|
||||||
|
.index(1)
|
||||||
|
.required_unless("address")
|
||||||
|
.help("Token of associated account. To query a specific account, use the `--address` parameter instead"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("address")
|
Arg::with_name("address")
|
||||||
.validator(is_valid_pubkey)
|
.validator(is_valid_pubkey)
|
||||||
.value_name("TOKEN_ACCOUNT_ADDRESS")
|
.value_name("TOKEN_ACCOUNT_ADDRESS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(1)
|
.long("address")
|
||||||
.required(true)
|
.conflicts_with("token")
|
||||||
.help("The token account address"),
|
.help("Specify the token account to query \
|
||||||
|
[default: owner's associated token account]"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
|
@ -1777,14 +1848,23 @@ fn main() {
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("account-info")
|
SubCommand::with_name("account-info")
|
||||||
.about("Query details of an SPL Token account by address")
|
.about("Query details of an SPL Token account by address")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("token")
|
||||||
|
.validator(is_valid_pubkey)
|
||||||
|
.value_name("TOKEN_ADDRESS")
|
||||||
|
.takes_value(true)
|
||||||
|
.index(1)
|
||||||
|
.required_unless("address")
|
||||||
|
.help("Token of associated account. To query a specific account, use the `--address` parameter instead"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("address")
|
Arg::with_name("address")
|
||||||
.validator(is_valid_pubkey)
|
.validator(is_valid_pubkey)
|
||||||
.value_name("TOKEN_ACCOUNT_ADDRESS")
|
.value_name("TOKEN_ACCOUNT_ADDRESS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(1)
|
.long("address")
|
||||||
.required(true)
|
.conflicts_with("token")
|
||||||
.help("The address of the SPL Token account to query"),
|
.help("Specify the token account to query"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
|
@ -2146,19 +2226,17 @@ fn main() {
|
||||||
command_revoke(&config, account, delegate_address)
|
command_revoke(&config, account, delegate_address)
|
||||||
}
|
}
|
||||||
("close", Some(arg_matches)) => {
|
("close", Some(arg_matches)) => {
|
||||||
let account = pubkey_of_signer(arg_matches, "account", &mut wallet_manager)
|
let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager).unwrap();
|
||||||
.unwrap()
|
let recipient = pubkey_of_signer(arg_matches, "recipient", &mut wallet_manager)
|
||||||
.unwrap();
|
|
||||||
let destination = pubkey_of_signer(arg_matches, "destination", &mut wallet_manager)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap_or(config.owner);
|
.unwrap_or(config.owner);
|
||||||
command_close(&config, account, destination)
|
let account = pubkey_of_signer(arg_matches, "address", &mut wallet_manager).unwrap();
|
||||||
|
command_close(&config, token, recipient, account)
|
||||||
}
|
}
|
||||||
("balance", Some(arg_matches)) => {
|
("balance", Some(arg_matches)) => {
|
||||||
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager)
|
let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager).unwrap();
|
||||||
.unwrap()
|
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager).unwrap();
|
||||||
.unwrap();
|
command_balance(&config, token, address)
|
||||||
command_balance(&config, address)
|
|
||||||
}
|
}
|
||||||
("supply", Some(arg_matches)) => {
|
("supply", Some(arg_matches)) => {
|
||||||
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager)
|
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager)
|
||||||
|
@ -2175,10 +2253,9 @@ fn main() {
|
||||||
command_address(&config, token)
|
command_address(&config, token)
|
||||||
}
|
}
|
||||||
("account-info", Some(arg_matches)) => {
|
("account-info", Some(arg_matches)) => {
|
||||||
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager)
|
let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager).unwrap();
|
||||||
.unwrap()
|
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager).unwrap();
|
||||||
.unwrap();
|
command_account_info(&config, token, address)
|
||||||
command_account_info(&config, address)
|
|
||||||
}
|
}
|
||||||
("multisig-info", Some(arg_matches)) => {
|
("multisig-info", Some(arg_matches)) => {
|
||||||
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager)
|
let address = pubkey_of_signer(arg_matches, "address", &mut wallet_manager)
|
||||||
|
|
Loading…
Reference in New Issue