spl-token-cli: Consolidate TX construction/signing

This commit is contained in:
Trent Nelson 2020-09-25 18:47:01 -06:00 committed by mergify[bot]
parent e0fb75d134
commit 748ff6c7d8
1 changed files with 224 additions and 338 deletions

View File

@ -8,14 +8,15 @@ use solana_account_decoder::{
UiAccountData, UiAccountData,
}; };
use solana_clap_utils::{ use solana_clap_utils::{
input_parsers::pubkey_of_signer, input_parsers::{pubkey_of_signer, signer_of},
input_validators::{is_amount, is_url, is_valid_pubkey, is_valid_signer}, input_validators::{is_amount, is_url, is_valid_pubkey, is_valid_signer},
keypair::signer_from_path, keypair::DefaultSigner,
}; };
use solana_cli_output::display::println_name_value; use solana_cli_output::display::println_name_value;
use solana_client::{rpc_client::RpcClient, rpc_request::TokenAccountsFilter}; use solana_client::{rpc_client::RpcClient, rpc_request::TokenAccountsFilter};
use solana_sdk::{ use solana_sdk::{
commitment_config::CommitmentConfig, commitment_config::CommitmentConfig,
instruction::Instruction,
native_token::*, native_token::*,
program_pack::Pack, program_pack::Pack,
pubkey::Pubkey, pubkey::Pubkey,
@ -36,27 +37,27 @@ static WARNING: Emoji = Emoji("⚠️", "!");
struct Config { struct Config {
rpc_client: RpcClient, rpc_client: RpcClient,
verbose: bool, verbose: bool,
owner: Box<dyn Signer>, owner: Pubkey,
fee_payer: Box<dyn Signer>, fee_payer: Pubkey,
commitment_config: CommitmentConfig, commitment_config: CommitmentConfig,
default_signer: DefaultSigner,
} }
type Error = Box<dyn std::error::Error>; type Error = Box<dyn std::error::Error>;
type CommandResult = Result<Option<Transaction>, Error>; type CommandResult = Result<Option<(u64, Vec<Instruction>)>, Error>;
macro_rules! unique_signers { fn new_throwaway_signer() -> (Option<Box<dyn Signer>>, Option<Pubkey>) {
($vec:ident) => { let keypair = Keypair::new();
$vec.sort_by_key(|l| l.pubkey()); let pubkey = keypair.pubkey();
$vec.dedup(); (Some(Box::new(keypair) as Box<dyn Signer>), Some(pubkey))
};
} }
fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Error> { fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Error> {
let balance = config.rpc_client.get_balance(&config.fee_payer.pubkey())?; let balance = config.rpc_client.get_balance(&config.fee_payer)?;
if balance < required_balance { if balance < required_balance {
Err(format!( Err(format!(
"Fee payer, {}, has insufficient balance: {} required, {} available", "Fee payer, {}, has insufficient balance: {} required, {} available",
config.fee_payer.pubkey(), config.fee_payer,
lamports_to_sol(required_balance), lamports_to_sol(required_balance),
lamports_to_sol(balance) lamports_to_sol(balance)
) )
@ -67,11 +68,11 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(),
} }
fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> { fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> {
let balance = config.rpc_client.get_balance(&config.owner.pubkey())?; let balance = config.rpc_client.get_balance(&config.owner)?;
if balance < required_balance { if balance < required_balance {
Err(format!( Err(format!(
"Owner, {}, has insufficient balance: {} required, {} available", "Owner, {}, has insufficient balance: {} required, {} available",
config.owner.pubkey(), config.owner,
lamports_to_sol(required_balance), lamports_to_sol(required_balance),
lamports_to_sol(balance) lamports_to_sol(balance)
) )
@ -84,90 +85,57 @@ fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Err
fn command_create_token( fn command_create_token(
config: &Config, config: &Config,
decimals: u8, decimals: u8,
token: Box<dyn Signer>, token: Pubkey,
enable_freeze: bool, enable_freeze: bool,
) -> CommandResult { ) -> CommandResult {
println!("Creating token {}", token.pubkey()); println!("Creating token {}", token);
let minimum_balance_for_rent_exemption = config let minimum_balance_for_rent_exemption = config
.rpc_client .rpc_client
.get_minimum_balance_for_rent_exemption(Mint::LEN)?; .get_minimum_balance_for_rent_exemption(Mint::LEN)?;
let freeze_authority_pubkey = if enable_freeze { let freeze_authority_pubkey = if enable_freeze {
Some(config.owner.pubkey()) Some(config.owner)
} else { } else {
None None
}; };
let mut transaction = Transaction::new_with_payer( let instructions = vec![
&[
system_instruction::create_account( system_instruction::create_account(
&config.fee_payer.pubkey(), &config.fee_payer,
&token.pubkey(), &token,
minimum_balance_for_rent_exemption, minimum_balance_for_rent_exemption,
Mint::LEN as u64, Mint::LEN as u64,
&spl_token::id(), &spl_token::id(),
), ),
initialize_mint( initialize_mint(
&spl_token::id(), &spl_token::id(),
&token.pubkey(), &token,
&config.owner.pubkey(), &config.owner,
freeze_authority_pubkey.as_ref(), freeze_authority_pubkey.as_ref(),
decimals, decimals,
)?, )?,
], ];
Some(&config.fee_payer.pubkey()), Ok(Some((minimum_balance_for_rent_exemption, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(
config,
minimum_balance_for_rent_exemption + fee_calculator.calculate_fee(&transaction.message()),
)?;
let mut signers = vec![config.fee_payer.as_ref(), token.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_create_account( fn command_create_account(config: &Config, token: Pubkey, account: Pubkey) -> CommandResult {
config: &Config, println!("Creating account {}", account);
token: Pubkey,
account: Box<dyn Signer>,
) -> CommandResult {
println!("Creating account {}", account.pubkey());
let minimum_balance_for_rent_exemption = config let minimum_balance_for_rent_exemption = config
.rpc_client .rpc_client
.get_minimum_balance_for_rent_exemption(Account::LEN)?; .get_minimum_balance_for_rent_exemption(Account::LEN)?;
let mut transaction = Transaction::new_with_payer( let instructions = vec![
&[
system_instruction::create_account( system_instruction::create_account(
&config.fee_payer.pubkey(), &config.fee_payer,
&account.pubkey(), &account,
minimum_balance_for_rent_exemption, minimum_balance_for_rent_exemption,
Account::LEN as u64, Account::LEN as u64,
&spl_token::id(), &spl_token::id(),
), ),
initialize_account( initialize_account(&spl_token::id(), &account, &token, &config.owner)?,
&spl_token::id(), ];
&account.pubkey(), Ok(Some((minimum_balance_for_rent_exemption, instructions)))
&token,
&config.owner.pubkey(),
)?,
],
Some(&config.fee_payer.pubkey()),
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(
config,
minimum_balance_for_rent_exemption + fee_calculator.calculate_fee(&transaction.message()),
)?;
let mut signers = vec![config.fee_payer.as_ref(), account.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_authorize( fn command_authorize(
@ -186,31 +154,22 @@ fn command_authorize(
"Updating {}\n Current {}: {}\n New {}: {}", "Updating {}\n Current {}: {}\n New {}: {}",
account, account,
auth_str, auth_str,
config.owner.pubkey(), config.owner,
auth_str, auth_str,
new_owner new_owner
.map(|pubkey| pubkey.to_string()) .map(|pubkey| pubkey.to_string())
.unwrap_or_else(|| "disabled".to_string()) .unwrap_or_else(|| "disabled".to_string())
); );
let mut transaction = Transaction::new_with_payer( let instructions = vec![set_authority(
&[set_authority(
&spl_token::id(), &spl_token::id(),
&account, &account,
new_owner.as_ref(), new_owner.as_ref(),
authority_type, authority_type,
&config.owner.pubkey(), &config.owner,
&[], &[],
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_transfer( fn command_transfer(
@ -232,26 +191,17 @@ fn command_transfer(
let mint_pubkey = Pubkey::from_str(&source_account.mint)?; let mint_pubkey = Pubkey::from_str(&source_account.mint)?;
let amount = spl_token::ui_amount_to_amount(ui_amount, source_account.token_amount.decimals); let amount = spl_token::ui_amount_to_amount(ui_amount, source_account.token_amount.decimals);
let mut transaction = Transaction::new_with_payer( let instructions = vec![transfer_checked(
&[transfer_checked(
&spl_token::id(), &spl_token::id(),
&sender, &sender,
&mint_pubkey, &mint_pubkey,
&recipient, &recipient,
&config.owner.pubkey(), &config.owner,
&[], &[],
amount, amount,
source_account.token_amount.decimals, source_account.token_amount.decimals,
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommandResult { fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommandResult {
@ -265,25 +215,16 @@ fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommandResul
let mint_pubkey = Pubkey::from_str(&source_account.mint)?; let mint_pubkey = Pubkey::from_str(&source_account.mint)?;
let amount = spl_token::ui_amount_to_amount(ui_amount, source_account.token_amount.decimals); let amount = spl_token::ui_amount_to_amount(ui_amount, source_account.token_amount.decimals);
let mut transaction = Transaction::new_with_payer( let instructions = vec![burn_checked(
&[burn_checked(
&spl_token::id(), &spl_token::id(),
&source, &source,
&mint_pubkey, &mint_pubkey,
&config.owner.pubkey(), &config.owner,
&[], &[],
amount, amount,
source_account.token_amount.decimals, source_account.token_amount.decimals,
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_mint( fn command_mint(
@ -303,25 +244,16 @@ fn command_mint(
.value; .value;
let amount = spl_token::ui_amount_to_amount(ui_amount, recipient_token_balance.decimals); let amount = spl_token::ui_amount_to_amount(ui_amount, recipient_token_balance.decimals);
let mut transaction = Transaction::new_with_payer( let instructions = vec![mint_to_checked(
&[mint_to_checked(
&spl_token::id(), &spl_token::id(),
&token, &token,
&recipient, &recipient,
&config.owner.pubkey(), &config.owner,
&[], &[],
amount, amount,
recipient_token_balance.decimals, recipient_token_balance.decimals,
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_freeze(config: &Config, account: Pubkey) -> CommandResult { fn command_freeze(config: &Config, account: Pubkey) -> CommandResult {
@ -334,23 +266,14 @@ fn command_freeze(config: &Config, account: Pubkey) -> CommandResult {
println!("Freezing account: {}\n Token: {}", account, token); println!("Freezing account: {}\n Token: {}", account, token);
let mut transaction = Transaction::new_with_payer( let instructions = vec![freeze_account(
&[freeze_account(
&spl_token::id(), &spl_token::id(),
&account, &account,
&token, &token,
&config.owner.pubkey(), &config.owner,
&[], &[],
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_thaw(config: &Config, account: Pubkey) -> CommandResult { fn command_thaw(config: &Config, account: Pubkey) -> CommandResult {
@ -363,56 +286,37 @@ fn command_thaw(config: &Config, account: Pubkey) -> CommandResult {
println!("Freezing account: {}\n Token: {}", account, token); println!("Freezing account: {}\n Token: {}", account, token);
let mut transaction = Transaction::new_with_payer( let instructions = vec![thaw_account(
&[thaw_account(
&spl_token::id(), &spl_token::id(),
&account, &account,
&token, &token,
&config.owner.pubkey(), &config.owner,
&[], &[],
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_wrap(config: &Config, sol: f64) -> CommandResult { fn command_wrap(config: &Config, sol: f64, account: Pubkey) -> CommandResult {
let account = Keypair::new();
let lamports = sol_to_lamports(sol); let lamports = sol_to_lamports(sol);
println!("Wrapping {} SOL into {}", sol, account.pubkey()); println!("Wrapping {} SOL into {}", sol, account);
let mut transaction = Transaction::new_with_payer( let instructions = vec![
&[
system_instruction::create_account( system_instruction::create_account(
&config.owner.pubkey(), &config.owner,
&account.pubkey(), &account,
lamports, lamports,
Account::LEN as u64, Account::LEN as u64,
&spl_token::id(), &spl_token::id(),
), ),
initialize_account( initialize_account(
&spl_token::id(), &spl_token::id(),
&account.pubkey(), &account,
&native_mint::id(), &native_mint::id(),
&config.owner.pubkey(), &config.owner,
)?, )?,
], ];
Some(&config.fee_payer.pubkey()),
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_owner_balance(config, lamports)?; check_owner_balance(config, lamports)?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; Ok(Some((0, instructions)))
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref(), &account];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_unwrap(config: &Config, address: Pubkey) -> CommandResult { fn command_unwrap(config: &Config, address: Pubkey) -> CommandResult {
@ -425,26 +329,17 @@ fn command_unwrap(config: &Config, address: Pubkey) -> CommandResult {
.get_balance_with_commitment(&address, config.commitment_config)? .get_balance_with_commitment(&address, config.commitment_config)?
.value .value
), ),
config.owner.pubkey() &config.owner,
); );
let mut transaction = Transaction::new_with_payer( let instructions = vec![close_account(
&[close_account(
&spl_token::id(), &spl_token::id(),
&address, &address,
&config.owner.pubkey(), &config.owner,
&config.owner.pubkey(), &config.owner,
&[], &[],
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_approve( fn command_approve(
@ -466,26 +361,17 @@ fn command_approve(
let mint_pubkey = Pubkey::from_str(&source_account.mint)?; let mint_pubkey = Pubkey::from_str(&source_account.mint)?;
let amount = spl_token::ui_amount_to_amount(ui_amount, source_account.token_amount.decimals); let amount = spl_token::ui_amount_to_amount(ui_amount, source_account.token_amount.decimals);
let mut transaction = Transaction::new_with_payer( let instructions = vec![approve_checked(
&[approve_checked(
&spl_token::id(), &spl_token::id(),
&account, &account,
&mint_pubkey, &mint_pubkey,
&delegate, &delegate,
&config.owner.pubkey(), &config.owner,
&[], &[],
amount, amount,
source_account.token_amount.decimals, source_account.token_amount.decimals,
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_revoke(config: &Config, account: Pubkey) -> CommandResult { fn command_revoke(config: &Config, account: Pubkey) -> CommandResult {
@ -505,22 +391,8 @@ fn command_revoke(config: &Config, account: Pubkey) -> CommandResult {
return Err(format!("No delegate on account {}", account).into()); return Err(format!("No delegate on account {}", account).into());
} }
let mut transaction = Transaction::new_with_payer( let instructions = vec![revoke(&spl_token::id(), &account, &config.owner, &[])?];
&[revoke( Ok(Some((0, instructions)))
&spl_token::id(),
&account,
&config.owner.pubkey(),
&[],
)?],
Some(&config.fee_payer.pubkey()),
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_close(config: &Config, account: Pubkey, destination: Pubkey) -> CommandResult { fn command_close(config: &Config, account: Pubkey, destination: Pubkey) -> CommandResult {
@ -538,23 +410,14 @@ fn command_close(config: &Config, account: Pubkey, destination: Pubkey) -> Comma
.into()); .into());
} }
let mut transaction = Transaction::new_with_payer( let instructions = vec![close_account(
&[close_account(
&spl_token::id(), &spl_token::id(),
&account, &account,
&destination, &destination,
&config.owner.pubkey(), &config.owner,
&[], &[],
)?], )?];
Some(&config.fee_payer.pubkey()), Ok(Some((0, instructions)))
);
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
Ok(Some(transaction))
} }
fn command_balance(config: &Config, address: Pubkey) -> CommandResult { fn command_balance(config: &Config, address: Pubkey) -> CommandResult {
@ -587,7 +450,7 @@ fn command_accounts(config: &Config, token: Option<Pubkey>) -> CommandResult {
let accounts = config let accounts = config
.rpc_client .rpc_client
.get_token_accounts_by_owner_with_commitment( .get_token_accounts_by_owner_with_commitment(
&config.owner.pubkey(), &config.owner,
match token { match token {
Some(token) => TokenAccountsFilter::Mint(token), Some(token) => TokenAccountsFilter::Mint(token),
None => TokenAccountsFilter::ProgramId(spl_token::id()), None => TokenAccountsFilter::ProgramId(spl_token::id()),
@ -1116,6 +979,7 @@ fn main() {
.get_matches(); .get_matches();
let mut wallet_manager = None; let mut wallet_manager = None;
let mut bulk_signers: Vec<Option<Box<dyn Signer>>> = Vec::new();
let config = { let config = {
let cli_config = if let Some(config_file) = matches.value_of("config_file") { let cli_config = if let Some(config_file) = matches.value_of("config_file") {
@ -1128,30 +992,31 @@ fn main() {
.unwrap_or(&cli_config.json_rpc_url) .unwrap_or(&cli_config.json_rpc_url)
.to_string(); .to_string();
let owner = signer_from_path( let default_signer_arg_name = "owner".to_string();
&matches, let default_signer_path = matches
matches .value_of(&default_signer_arg_name)
.value_of("owner") .map(|s| s.to_string())
.unwrap_or(&cli_config.keypair_path), .unwrap_or(cli_config.keypair_path);
"owner", let default_signer = DefaultSigner {
&mut wallet_manager, path: default_signer_path,
) arg_name: default_signer_arg_name,
.unwrap_or_else(|e| { };
eprintln!("error: {}", e); let owner = default_signer
exit(1); .signer_from_path(&matches, &mut wallet_manager)
}); .unwrap_or_else(|e| {
let fee_payer = signer_from_path( eprintln!("error: {}", e);
&matches, exit(1);
matches })
.value_of("fee_payer") .pubkey();
.unwrap_or(&cli_config.keypair_path), bulk_signers.push(None);
"fee_payer", let (signer, fee_payer) = signer_of(&matches, "fee_payer", &mut wallet_manager)
&mut wallet_manager,
)
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
eprintln!("error: {}", e); eprintln!("error: {}", e);
exit(1); exit(1);
}); });
let fee_payer = fee_payer.unwrap_or(owner);
bulk_signers.push(signer);
let verbose = matches.is_present("verbose"); let verbose = matches.is_present("verbose");
Config { Config {
@ -1160,6 +1025,7 @@ fn main() {
owner, owner,
fee_payer, fee_payer,
commitment_config: CommitmentConfig::single_gossip(), commitment_config: CommitmentConfig::single_gossip(),
default_signer,
} }
}; };
@ -1168,20 +1034,16 @@ fn main() {
let _ = match matches.subcommand() { let _ = match matches.subcommand() {
("create-token", Some(arg_matches)) => { ("create-token", Some(arg_matches)) => {
let decimals = value_t_or_exit!(arg_matches, "decimals", u8); let decimals = value_t_or_exit!(arg_matches, "decimals", u8);
let token = if arg_matches.is_present("token_keypair") { let (signer, token) = if arg_matches.is_present("token_keypair") {
signer_from_path( signer_of(&arg_matches, "token_keypair", &mut wallet_manager).unwrap_or_else(|e| {
&matches,
&value_t_or_exit!(arg_matches, "token_keypair", String),
"token_keypair",
&mut wallet_manager,
)
.unwrap_or_else(|e| {
eprintln!("error: {}", e); eprintln!("error: {}", e);
exit(1); exit(1);
}) })
} else { } else {
Box::new(Keypair::new()) new_throwaway_signer()
}; };
let token = token.unwrap();
bulk_signers.push(signer);
command_create_token( command_create_token(
&config, &config,
@ -1194,20 +1056,18 @@ fn main() {
let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager) let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager)
.unwrap() .unwrap()
.unwrap(); .unwrap();
let account = if arg_matches.is_present("account_keypair") { let (signer, account) = if arg_matches.is_present("account_keypair") {
signer_from_path( signer_of(&arg_matches, "account_keypair", &mut wallet_manager).unwrap_or_else(
&matches, |e| {
&value_t_or_exit!(arg_matches, "account_keypair", String),
"account_keypair",
&mut wallet_manager,
)
.unwrap_or_else(|e| {
eprintln!("error: {}", e); eprintln!("error: {}", e);
exit(1); exit(1);
}) },
)
} else { } else {
Box::new(Keypair::new()) new_throwaway_signer()
}; };
let account = account.unwrap();
bulk_signers.push(signer);
command_create_account(&config, token, account) command_create_account(&config, token, account)
} }
@ -1268,7 +1128,10 @@ fn main() {
} }
("wrap", Some(arg_matches)) => { ("wrap", Some(arg_matches)) => {
let amount = value_t_or_exit!(arg_matches, "amount", f64); let amount = value_t_or_exit!(arg_matches, "amount", f64);
command_wrap(&config, amount) let (signer, account) = new_throwaway_signer();
let account = account.unwrap();
bulk_signers.push(signer);
command_wrap(&config, amount, account)
} }
("unwrap", Some(arg_matches)) => { ("unwrap", 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)
@ -1325,8 +1188,31 @@ fn main() {
} }
_ => unreachable!(), _ => unreachable!(),
} }
.and_then(|transaction| { .and_then(|transaction_info| {
if let Some(transaction) = transaction { if let Some((minimum_balance_for_rent_exemption, instructions)) = transaction_info {
let mut transaction =
Transaction::new_with_payer(&instructions, Some(&config.fee_payer));
let (recent_blockhash, fee_calculator) = config
.rpc_client
.get_recent_blockhash()
.unwrap_or_else(|e| {
eprintln!("error: {}", e);
exit(1);
});
check_fee_payer_balance(
&config,
minimum_balance_for_rent_exemption
+ fee_calculator.calculate_fee(&transaction.message()),
)?;
let signer_info = config
.default_signer
.generate_unique_signers(bulk_signers, &matches, &mut wallet_manager)
.unwrap_or_else(|e| {
eprintln!("error: {}", e);
exit(1);
});
transaction.sign(&signer_info.signers, recent_blockhash);
let signature = config let signature = config
.rpc_client .rpc_client
.send_and_confirm_transaction_with_spinner_and_commitment( .send_and_confirm_transaction_with_spinner_and_commitment(