2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
crate::{
|
2022-08-18 14:12:53 -07:00
|
|
|
address_lookup_table::*, clap_app::*, cluster_query::*, feature::*, inflation::*, nonce::*,
|
|
|
|
program::*, spend_utils::*, stake::*, validator_info::*, vote::*, wallet::*,
|
2021-12-03 09:00:31 -08:00
|
|
|
},
|
|
|
|
clap::{crate_description, crate_name, value_t_or_exit, ArgMatches, Shell},
|
|
|
|
log::*,
|
|
|
|
num_traits::FromPrimitive,
|
|
|
|
serde_json::{self, Value},
|
2022-04-11 11:56:51 -07:00
|
|
|
solana_clap_utils::{self, input_parsers::*, keypair::*},
|
|
|
|
solana_cli_config::ConfigInput,
|
2021-12-03 09:00:31 -08:00
|
|
|
solana_cli_output::{
|
|
|
|
display::println_name_value, CliSignature, CliValidatorsSortOrder, OutputFormat,
|
|
|
|
},
|
|
|
|
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
2022-08-24 09:47:02 -07:00
|
|
|
solana_rpc_client::rpc_client::RpcClient,
|
|
|
|
solana_rpc_client_api::{
|
|
|
|
client_error::{Error as ClientError, Result as ClientResult},
|
|
|
|
config::{RpcLargestAccountsFilter, RpcSendTransactionConfig, RpcTransactionLogsFilter},
|
|
|
|
},
|
|
|
|
solana_rpc_client_nonce_utils::blockhash_query::BlockhashQuery,
|
2021-12-03 09:00:31 -08:00
|
|
|
solana_sdk::{
|
|
|
|
clock::{Epoch, Slot},
|
|
|
|
commitment_config::CommitmentConfig,
|
|
|
|
decode_error::DecodeError,
|
|
|
|
hash::Hash,
|
|
|
|
instruction::InstructionError,
|
2022-10-17 08:19:12 -07:00
|
|
|
offchain_message::OffchainMessage,
|
2021-12-03 09:00:31 -08:00
|
|
|
pubkey::Pubkey,
|
|
|
|
signature::{Signature, Signer, SignerError},
|
|
|
|
stake::{instruction::LockupArgs, state::Lockup},
|
2022-03-16 20:43:04 -07:00
|
|
|
transaction::{TransactionError, VersionedTransaction},
|
2021-12-03 09:00:31 -08:00
|
|
|
},
|
2023-02-01 18:10:06 -08:00
|
|
|
solana_tpu_client::tpu_client::DEFAULT_TPU_ENABLE_UDP,
|
2021-12-03 09:00:31 -08:00
|
|
|
solana_vote_program::vote_state::VoteAuthorize,
|
|
|
|
std::{collections::HashMap, error, io::stdout, str::FromStr, sync::Arc, time::Duration},
|
|
|
|
thiserror::Error,
|
2019-09-09 18:17:32 -07:00
|
|
|
};
|
2018-09-14 01:58:39 -07:00
|
|
|
|
2020-07-23 08:21:59 -07:00
|
|
|
pub const DEFAULT_RPC_TIMEOUT_SECONDS: &str = "30";
|
2021-06-29 18:08:45 -07:00
|
|
|
pub const DEFAULT_CONFIRM_TX_TIMEOUT_SECONDS: &str = "5";
|
2021-07-15 15:45:03 -07:00
|
|
|
const CHECKED: bool = true;
|
2018-10-22 21:21:33 -07:00
|
|
|
|
2018-09-14 01:59:09 -07:00
|
|
|
#[derive(Debug, PartialEq)]
|
2019-05-09 19:31:42 -07:00
|
|
|
#[allow(clippy::large_enum_variant)]
|
2019-10-04 15:13:21 -07:00
|
|
|
pub enum CliCommand {
|
2019-10-04 19:54:09 -07:00
|
|
|
// Cluster Query Commands
|
2019-11-13 14:58:14 -08:00
|
|
|
Catchup {
|
2021-01-04 17:10:27 -08:00
|
|
|
node_pubkey: Option<Pubkey>,
|
2020-03-04 11:44:13 -08:00
|
|
|
node_json_rpc_url: Option<String>,
|
2020-04-02 11:05:29 -07:00
|
|
|
follow: bool,
|
2021-01-04 17:10:27 -08:00
|
|
|
our_localhost_port: Option<u16>,
|
|
|
|
log: bool,
|
2019-11-13 14:58:14 -08:00
|
|
|
},
|
2020-05-05 08:42:03 -07:00
|
|
|
ClusterDate,
|
2019-10-04 19:54:09 -07:00
|
|
|
ClusterVersion,
|
2020-09-23 13:36:34 -07:00
|
|
|
Feature(FeatureCliCommand),
|
2020-09-30 20:17:29 -07:00
|
|
|
Inflation(InflationCliCommand),
|
2021-02-25 22:48:33 -08:00
|
|
|
Fees {
|
|
|
|
blockhash: Option<Hash>,
|
|
|
|
},
|
2020-09-06 10:54:01 -07:00
|
|
|
FirstAvailableBlock,
|
2020-09-06 11:10:19 -07:00
|
|
|
GetBlock {
|
2020-10-09 12:55:35 -07:00
|
|
|
slot: Option<Slot>,
|
2020-09-06 11:10:19 -07:00
|
|
|
},
|
2019-11-25 23:40:36 -08:00
|
|
|
GetBlockTime {
|
2020-05-05 08:42:03 -07:00
|
|
|
slot: Option<Slot>,
|
2019-11-25 23:40:36 -08:00
|
|
|
},
|
2020-06-17 11:18:48 -07:00
|
|
|
GetEpoch,
|
|
|
|
GetEpochInfo,
|
2019-11-08 20:56:57 -08:00
|
|
|
GetGenesisHash,
|
2020-06-17 11:18:48 -07:00
|
|
|
GetSlot,
|
2020-07-22 08:36:12 -07:00
|
|
|
GetBlockHeight,
|
2020-06-17 11:18:48 -07:00
|
|
|
GetTransactionCount,
|
2020-05-12 20:05:05 -07:00
|
|
|
LargestAccounts {
|
|
|
|
filter: Option<RpcLargestAccountsFilter>,
|
|
|
|
},
|
2020-12-28 10:38:15 -08:00
|
|
|
LeaderSchedule {
|
|
|
|
epoch: Option<Epoch>,
|
|
|
|
},
|
2020-02-29 08:39:07 -08:00
|
|
|
LiveSlots,
|
2020-11-20 13:52:58 -08:00
|
|
|
Logs {
|
|
|
|
filter: RpcTransactionLogsFilter,
|
|
|
|
},
|
2019-10-04 14:18:19 -07:00
|
|
|
Ping {
|
|
|
|
interval: Duration,
|
|
|
|
count: Option<u64>,
|
|
|
|
timeout: Duration,
|
2020-12-07 04:10:50 -08:00
|
|
|
blockhash: Option<Hash>,
|
|
|
|
print_timestamp: bool,
|
2022-05-15 21:06:33 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-08-29 20:45:53 -07:00
|
|
|
},
|
2021-01-20 22:24:26 -08:00
|
|
|
Rent {
|
|
|
|
data_length: usize,
|
|
|
|
use_lamports_unit: bool,
|
|
|
|
},
|
2019-12-18 10:38:54 -08:00
|
|
|
ShowBlockProduction {
|
|
|
|
epoch: Option<Epoch>,
|
|
|
|
slot_limit: Option<u64>,
|
|
|
|
},
|
2019-11-15 12:15:34 -08:00
|
|
|
ShowGossip,
|
2020-01-17 11:10:52 -08:00
|
|
|
ShowStakes {
|
|
|
|
use_lamports_unit: bool,
|
|
|
|
vote_account_pubkeys: Option<Vec<Pubkey>>,
|
2022-06-17 12:52:23 -07:00
|
|
|
withdraw_authority: Option<Pubkey>,
|
2020-01-17 11:10:52 -08:00
|
|
|
},
|
2019-10-06 21:47:24 -07:00
|
|
|
ShowValidators {
|
|
|
|
use_lamports_unit: bool,
|
2021-04-19 10:24:07 -07:00
|
|
|
sort_order: CliValidatorsSortOrder,
|
|
|
|
reverse_sort: bool,
|
2021-04-19 13:35:59 -07:00
|
|
|
number_validators: bool,
|
2021-07-12 23:10:10 -07:00
|
|
|
keep_unstaked_delinquents: bool,
|
|
|
|
delinquent_slot_distance: Option<Slot>,
|
2019-10-06 21:47:24 -07:00
|
|
|
},
|
2020-06-17 11:18:48 -07:00
|
|
|
Supply {
|
|
|
|
print_accounts: bool,
|
|
|
|
},
|
|
|
|
TotalSupply,
|
2020-04-20 22:01:09 -07:00
|
|
|
TransactionHistory {
|
|
|
|
address: Pubkey,
|
2020-08-05 11:30:21 -07:00
|
|
|
before: Option<Signature>,
|
2020-08-15 09:42:17 -07:00
|
|
|
until: Option<Signature>,
|
2020-07-28 20:46:23 -07:00
|
|
|
limit: usize,
|
2020-09-04 22:26:02 -07:00
|
|
|
show_transactions: bool,
|
2020-04-20 22:01:09 -07:00
|
|
|
},
|
2020-11-12 13:48:34 -08:00
|
|
|
WaitForMaxStake {
|
|
|
|
max_stake_percent: f32,
|
|
|
|
},
|
2019-12-10 00:24:44 -08:00
|
|
|
// Nonce commands
|
2019-12-19 16:13:01 -08:00
|
|
|
AuthorizeNonceAccount {
|
|
|
|
nonce_account: Pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2019-12-19 16:13:01 -08:00
|
|
|
new_authority: Pubkey,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-12-19 16:13:01 -08:00
|
|
|
},
|
2019-12-10 00:24:44 -08:00
|
|
|
CreateNonceAccount {
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_account: SignerIndex,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed: Option<String>,
|
2020-01-02 17:05:08 -08:00
|
|
|
nonce_authority: Option<Pubkey>,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-12-10 00:24:44 -08:00
|
|
|
},
|
|
|
|
GetNonce(Pubkey),
|
2019-12-17 06:34:21 -08:00
|
|
|
NewNonce {
|
|
|
|
nonce_account: Pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-12-17 06:34:21 -08:00
|
|
|
},
|
2019-12-10 00:24:44 -08:00
|
|
|
ShowNonceAccount {
|
|
|
|
nonce_account_pubkey: Pubkey,
|
|
|
|
use_lamports_unit: bool,
|
|
|
|
},
|
|
|
|
WithdrawFromNonceAccount {
|
2019-12-17 06:34:21 -08:00
|
|
|
nonce_account: Pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2019-12-10 00:24:44 -08:00
|
|
|
destination_account_pubkey: Pubkey,
|
|
|
|
lamports: u64,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-12-10 00:24:44 -08:00
|
|
|
},
|
2022-06-09 17:04:29 -07:00
|
|
|
UpgradeNonceAccount {
|
|
|
|
nonce_account: Pubkey,
|
|
|
|
memo: Option<String>,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2022-06-09 17:04:29 -07:00
|
|
|
},
|
2019-10-04 14:18:19 -07:00
|
|
|
// Program Deployment
|
2022-10-21 00:29:37 -07:00
|
|
|
Deploy,
|
2020-12-21 13:02:53 -08:00
|
|
|
Program(ProgramCliCommand),
|
2019-10-04 14:18:19 -07:00
|
|
|
// Stake Commands
|
2019-10-21 16:08:09 -07:00
|
|
|
CreateStakeAccount {
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_account: SignerIndex,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed: Option<String>,
|
2019-10-21 16:08:09 -07:00
|
|
|
staker: Option<Pubkey>,
|
|
|
|
withdrawer: Option<Pubkey>,
|
2021-07-15 15:45:03 -07:00
|
|
|
withdrawer_signer: Option<SignerIndex>,
|
2019-10-21 16:08:09 -07:00
|
|
|
lockup: Lockup,
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount,
|
2020-02-12 22:00:28 -08:00
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-02-12 22:00:28 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
|
|
|
from: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-10-21 16:08:09 -07:00
|
|
|
},
|
2019-11-25 21:09:57 -08:00
|
|
|
DeactivateStake {
|
|
|
|
stake_account_pubkey: Pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority: SignerIndex,
|
2019-11-25 21:09:57 -08:00
|
|
|
sign_only: bool,
|
2022-03-25 09:11:51 -07:00
|
|
|
deactivate_delinquent: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
2019-12-27 12:35:49 -08:00
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2021-04-21 11:05:05 -07:00
|
|
|
seed: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-11-25 21:09:57 -08:00
|
|
|
},
|
|
|
|
DelegateStake {
|
|
|
|
stake_account_pubkey: Pubkey,
|
|
|
|
vote_account_pubkey: Pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority: SignerIndex,
|
2019-11-25 21:09:57 -08:00
|
|
|
force: bool,
|
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
2019-12-27 12:35:49 -08:00
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-06-29 10:03:44 -07:00
|
|
|
redelegation_stake_account_pubkey: Option<Pubkey>,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-11-25 21:09:57 -08:00
|
|
|
},
|
2020-02-02 21:20:28 -08:00
|
|
|
SplitStake {
|
|
|
|
stake_account_pubkey: Pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority: SignerIndex,
|
2020-02-02 21:20:28 -08:00
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-02-02 21:20:28 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
split_stake_account: SignerIndex,
|
2020-02-02 21:20:28 -08:00
|
|
|
seed: Option<String>,
|
|
|
|
lamports: u64,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-02-02 21:20:28 -08:00
|
|
|
},
|
2020-06-10 21:02:04 -07:00
|
|
|
MergeStake {
|
|
|
|
stake_account_pubkey: Pubkey,
|
|
|
|
source_stake_account_pubkey: Pubkey,
|
|
|
|
stake_authority: SignerIndex,
|
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-06-10 21:02:04 -07:00
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-06-10 21:02:04 -07:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-06-10 21:02:04 -07:00
|
|
|
},
|
2019-10-25 09:20:08 -07:00
|
|
|
ShowStakeHistory {
|
|
|
|
use_lamports_unit: bool,
|
2021-04-20 01:30:19 -07:00
|
|
|
limit_results: usize,
|
2019-10-25 09:20:08 -07:00
|
|
|
},
|
2019-10-04 14:18:19 -07:00
|
|
|
ShowStakeAccount {
|
2019-09-10 12:36:59 -07:00
|
|
|
pubkey: Pubkey,
|
|
|
|
use_lamports_unit: bool,
|
2021-04-08 09:57:33 -07:00
|
|
|
with_rewards: Option<usize>,
|
2019-09-10 12:36:59 -07:00
|
|
|
},
|
2020-01-15 13:32:06 -08:00
|
|
|
StakeAuthorize {
|
|
|
|
stake_account_pubkey: Pubkey,
|
2021-07-15 15:45:03 -07:00
|
|
|
new_authorizations: Vec<StakeAuthorizationIndexed>,
|
2020-01-17 09:30:56 -08:00
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
2020-01-17 09:30:56 -08:00
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
2021-01-26 09:44:44 -08:00
|
|
|
custodian: Option<SignerIndex>,
|
2021-05-17 09:54:33 -07:00
|
|
|
no_wait: bool,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-01-15 13:32:06 -08:00
|
|
|
},
|
2020-02-12 15:36:29 -08:00
|
|
|
StakeSetLockup {
|
|
|
|
stake_account_pubkey: Pubkey,
|
2020-03-02 12:28:43 -08:00
|
|
|
lockup: LockupArgs,
|
2020-02-24 16:03:30 -08:00
|
|
|
custodian: SignerIndex,
|
2021-07-15 15:45:03 -07:00
|
|
|
new_custodian_signer: Option<SignerIndex>,
|
2020-02-12 15:36:29 -08:00
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-02-12 15:36:29 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-02-12 15:36:29 -08:00
|
|
|
},
|
2020-01-15 13:32:06 -08:00
|
|
|
WithdrawStake {
|
|
|
|
stake_account_pubkey: Pubkey,
|
|
|
|
destination_account_pubkey: Pubkey,
|
2021-04-26 08:33:56 -07:00
|
|
|
amount: SpendAmount,
|
2020-02-24 16:03:30 -08:00
|
|
|
withdraw_authority: SignerIndex,
|
2020-04-22 15:00:18 -07:00
|
|
|
custodian: Option<SignerIndex>,
|
2020-02-12 22:00:28 -08:00
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2020-02-12 22:00:28 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2021-04-21 11:05:05 -07:00
|
|
|
seed: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-01-15 13:32:06 -08:00
|
|
|
},
|
2019-10-04 14:18:19 -07:00
|
|
|
// Validator Info Commands
|
|
|
|
GetValidatorInfo(Option<Pubkey>),
|
2019-10-21 16:08:09 -07:00
|
|
|
SetValidatorInfo {
|
|
|
|
validator_info: Value,
|
|
|
|
force_keybase: bool,
|
|
|
|
info_pubkey: Option<Pubkey>,
|
|
|
|
},
|
2019-10-04 14:18:19 -07:00
|
|
|
// Vote Commands
|
2019-10-21 16:08:09 -07:00
|
|
|
CreateVoteAccount {
|
2020-07-13 20:27:41 -07:00
|
|
|
vote_account: SignerIndex,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed: Option<String>,
|
2020-03-19 01:58:52 -07:00
|
|
|
identity_account: SignerIndex,
|
2019-10-21 16:08:09 -07:00
|
|
|
authorized_voter: Option<Pubkey>,
|
2021-09-02 17:22:33 -07:00
|
|
|
authorized_withdrawer: Pubkey,
|
2019-10-21 16:08:09 -07:00
|
|
|
commission: u8,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: bool,
|
|
|
|
dump_transaction_message: bool,
|
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-10-21 16:08:09 -07:00
|
|
|
},
|
2019-09-26 10:26:47 -07:00
|
|
|
ShowVoteAccount {
|
|
|
|
pubkey: Pubkey,
|
|
|
|
use_lamports_unit: bool,
|
2021-04-08 09:57:33 -07:00
|
|
|
with_rewards: Option<usize>,
|
2019-09-26 10:26:47 -07:00
|
|
|
},
|
2020-03-13 13:30:04 -07:00
|
|
|
WithdrawFromVoteAccount {
|
|
|
|
vote_account_pubkey: Pubkey,
|
|
|
|
destination_account_pubkey: Pubkey,
|
|
|
|
withdraw_authority: SignerIndex,
|
2020-06-15 14:36:47 -07:00
|
|
|
withdraw_amount: SpendAmount,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: bool,
|
|
|
|
dump_transaction_message: bool,
|
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-03-13 13:30:04 -07:00
|
|
|
},
|
2021-09-13 08:13:59 -07:00
|
|
|
CloseVoteAccount {
|
|
|
|
vote_account_pubkey: Pubkey,
|
|
|
|
destination_account_pubkey: Pubkey,
|
|
|
|
withdraw_authority: SignerIndex,
|
|
|
|
memo: Option<String>,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2021-09-13 08:13:59 -07:00
|
|
|
},
|
2019-12-12 15:04:03 -08:00
|
|
|
VoteAuthorize {
|
|
|
|
vote_account_pubkey: Pubkey,
|
|
|
|
new_authorized_pubkey: Pubkey,
|
|
|
|
vote_authorize: VoteAuthorize,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: bool,
|
|
|
|
dump_transaction_message: bool,
|
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: SignerIndex,
|
2021-07-15 15:45:03 -07:00
|
|
|
authorized: SignerIndex,
|
|
|
|
new_authorized: Option<SignerIndex>,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-12-12 15:04:03 -08:00
|
|
|
},
|
|
|
|
VoteUpdateValidator {
|
|
|
|
vote_account_pubkey: Pubkey,
|
2020-03-19 01:58:52 -07:00
|
|
|
new_identity_account: SignerIndex,
|
2020-07-13 20:49:59 -07:00
|
|
|
withdraw_authority: SignerIndex,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: bool,
|
|
|
|
dump_transaction_message: bool,
|
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2019-12-12 15:04:03 -08:00
|
|
|
},
|
2020-06-09 21:15:46 -07:00
|
|
|
VoteUpdateCommission {
|
|
|
|
vote_account_pubkey: Pubkey,
|
|
|
|
commission: u8,
|
2020-07-13 19:30:49 -07:00
|
|
|
withdraw_authority: SignerIndex,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: bool,
|
|
|
|
dump_transaction_message: bool,
|
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: SignerIndex,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-06-09 21:15:46 -07:00
|
|
|
},
|
2019-10-04 14:18:19 -07:00
|
|
|
// Wallet Commands
|
|
|
|
Address,
|
|
|
|
Airdrop {
|
2020-02-16 10:41:00 -08:00
|
|
|
pubkey: Option<Pubkey>,
|
2019-10-04 14:18:19 -07:00
|
|
|
lamports: u64,
|
|
|
|
},
|
|
|
|
Balance {
|
2019-10-21 16:08:09 -07:00
|
|
|
pubkey: Option<Pubkey>,
|
2019-09-26 10:26:47 -07:00
|
|
|
use_lamports_unit: bool,
|
|
|
|
},
|
2019-10-04 14:18:19 -07:00
|
|
|
Confirm(Signature),
|
2021-07-28 23:19:34 -07:00
|
|
|
CreateAddressWithSeed {
|
|
|
|
from_pubkey: Option<Pubkey>,
|
|
|
|
seed: String,
|
|
|
|
program_id: Pubkey,
|
|
|
|
},
|
2022-03-16 20:43:04 -07:00
|
|
|
DecodeTransaction(VersionedTransaction),
|
2020-03-14 20:48:41 -07:00
|
|
|
ResolveSigner(Option<String>),
|
2019-10-04 19:54:09 -07:00
|
|
|
ShowAccount {
|
|
|
|
pubkey: Pubkey,
|
|
|
|
output_file: Option<String>,
|
|
|
|
use_lamports_unit: bool,
|
|
|
|
},
|
2020-02-07 11:16:35 -08:00
|
|
|
Transfer {
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount,
|
2020-02-07 11:16:35 -08:00
|
|
|
to: Pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
from: SignerIndex,
|
2020-02-07 11:16:35 -08:00
|
|
|
sign_only: bool,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: bool,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: bool,
|
2020-04-08 22:46:19 -07:00
|
|
|
no_wait: bool,
|
2020-02-07 11:16:35 -08:00
|
|
|
blockhash_query: BlockhashQuery,
|
|
|
|
nonce_account: Option<Pubkey>,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: SignerIndex,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: Option<String>,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: SignerIndex,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed: Option<String>,
|
|
|
|
derived_address_program_id: Option<Pubkey>,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: Option<u64>,
|
2020-02-07 11:16:35 -08:00
|
|
|
},
|
2022-07-21 05:23:18 -07:00
|
|
|
StakeMinimumDelegation {
|
|
|
|
use_lamports_unit: bool,
|
|
|
|
},
|
2022-08-18 14:12:53 -07:00
|
|
|
// Address lookup table commands
|
|
|
|
AddressLookupTable(AddressLookupTableCliCommand),
|
2022-10-17 08:19:12 -07:00
|
|
|
SignOffchainMessage {
|
|
|
|
message: OffchainMessage,
|
|
|
|
},
|
|
|
|
VerifyOffchainSignature {
|
|
|
|
signer_pubkey: Option<Pubkey>,
|
|
|
|
signature: Signature,
|
|
|
|
message: OffchainMessage,
|
|
|
|
},
|
2018-09-14 01:58:39 -07:00
|
|
|
}
|
|
|
|
|
2019-10-21 16:08:09 -07:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct CliCommandInfo {
|
|
|
|
pub command: CliCommand,
|
2020-02-24 16:03:30 -08:00
|
|
|
pub signers: CliSigners,
|
2019-10-21 16:08:09 -07:00
|
|
|
}
|
|
|
|
|
2020-05-14 11:24:14 -07:00
|
|
|
#[derive(Debug, Error)]
|
2019-10-04 15:13:21 -07:00
|
|
|
pub enum CliError {
|
2021-03-02 11:13:41 -08:00
|
|
|
#[error("Bad parameter: {0}")]
|
2018-09-14 01:58:39 -07:00
|
|
|
BadParameter(String),
|
2020-05-14 11:24:14 -07:00
|
|
|
#[error(transparent)]
|
|
|
|
ClientError(#[from] ClientError),
|
2021-03-02 11:13:41 -08:00
|
|
|
#[error("Command not recognized: {0}")]
|
2019-08-09 14:52:06 -07:00
|
|
|
CommandNotRecognized(String),
|
2021-03-02 11:13:41 -08:00
|
|
|
#[error("Account {1} has insufficient funds for fee ({0} SOL)")]
|
|
|
|
InsufficientFundsForFee(f64, Pubkey),
|
|
|
|
#[error("Account {1} has insufficient funds for spend ({0} SOL)")]
|
|
|
|
InsufficientFundsForSpend(f64, Pubkey),
|
|
|
|
#[error("Account {2} has insufficient funds for spend ({0} SOL) + fee ({1} SOL)")]
|
|
|
|
InsufficientFundsForSpendAndFee(f64, f64, Pubkey),
|
2020-03-12 23:20:49 -07:00
|
|
|
#[error(transparent)]
|
2022-08-24 09:47:02 -07:00
|
|
|
InvalidNonce(solana_rpc_client_nonce_utils::Error),
|
2021-03-02 11:13:41 -08:00
|
|
|
#[error("Dynamic program error: {0}")]
|
2018-10-22 21:21:33 -07:00
|
|
|
DynamicProgramError(String),
|
2021-03-02 11:13:41 -08:00
|
|
|
#[error("RPC request error: {0}")]
|
2018-09-20 22:27:06 -07:00
|
|
|
RpcRequestError(String),
|
2021-03-02 11:13:41 -08:00
|
|
|
#[error("Keypair file not found: {0}")]
|
2019-09-12 18:37:29 -07:00
|
|
|
KeypairFileNotFound(String),
|
2022-10-17 08:19:12 -07:00
|
|
|
#[error("Invalid signature")]
|
|
|
|
InvalidSignature,
|
2018-09-14 01:58:39 -07:00
|
|
|
}
|
|
|
|
|
2020-02-21 13:55:53 -08:00
|
|
|
impl From<Box<dyn error::Error>> for CliError {
|
|
|
|
fn from(error: Box<dyn error::Error>) -> Self {
|
2020-03-12 23:20:49 -07:00
|
|
|
CliError::DynamicProgramError(error.to_string())
|
2020-02-21 13:55:53 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-24 09:47:02 -07:00
|
|
|
impl From<solana_rpc_client_nonce_utils::Error> for CliError {
|
|
|
|
fn from(error: solana_rpc_client_nonce_utils::Error) -> Self {
|
2020-03-10 12:00:15 -07:00
|
|
|
match error {
|
2022-08-24 09:47:02 -07:00
|
|
|
solana_rpc_client_nonce_utils::Error::Client(client_error) => {
|
|
|
|
Self::RpcRequestError(client_error)
|
|
|
|
}
|
2020-03-10 12:00:15 -07:00
|
|
|
_ => Self::InvalidNonce(error),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-24 16:03:30 -08:00
|
|
|
pub struct CliConfig<'a> {
|
2019-10-04 15:13:21 -07:00
|
|
|
pub command: CliCommand,
|
2019-05-06 07:38:26 -07:00
|
|
|
pub json_rpc_url: String,
|
2020-02-29 08:39:07 -08:00
|
|
|
pub websocket_url: String,
|
2020-02-24 16:03:30 -08:00
|
|
|
pub keypair_path: String,
|
2022-04-11 11:56:51 -07:00
|
|
|
pub commitment: CommitmentConfig,
|
|
|
|
pub signers: Vec<&'a dyn Signer>,
|
2021-04-22 18:35:12 -07:00
|
|
|
pub rpc_client: Option<Arc<RpcClient>>,
|
2020-07-23 08:21:59 -07:00
|
|
|
pub rpc_timeout: Duration,
|
2019-12-19 14:37:47 -08:00
|
|
|
pub verbose: bool,
|
2020-04-14 12:10:25 -07:00
|
|
|
pub output_format: OutputFormat,
|
2020-06-17 11:18:48 -07:00
|
|
|
pub send_transaction_config: RpcSendTransactionConfig,
|
2021-06-29 18:08:45 -07:00
|
|
|
pub confirm_transaction_initial_timeout: Duration,
|
2020-06-17 23:09:33 -07:00
|
|
|
pub address_labels: HashMap<String, String>,
|
2022-08-25 09:26:12 -07:00
|
|
|
pub use_quic: bool,
|
2018-09-14 01:58:39 -07:00
|
|
|
}
|
|
|
|
|
2020-02-24 16:03:30 -08:00
|
|
|
impl CliConfig<'_> {
|
2020-02-21 13:55:53 -08:00
|
|
|
pub(crate) fn pubkey(&self) -> Result<Pubkey, SignerError> {
|
2020-02-24 16:03:30 -08:00
|
|
|
if !self.signers.is_empty() {
|
|
|
|
self.signers[0].try_pubkey()
|
|
|
|
} else {
|
2020-04-01 11:13:31 -07:00
|
|
|
Err(SignerError::Custom(
|
2020-02-24 16:03:30 -08:00
|
|
|
"Default keypair must be set if pubkey arg not provided".to_string(),
|
|
|
|
))
|
|
|
|
}
|
2020-02-07 10:26:56 -08:00
|
|
|
}
|
2020-06-17 11:18:48 -07:00
|
|
|
|
|
|
|
pub fn recent_for_tests() -> Self {
|
2020-12-13 17:26:34 -08:00
|
|
|
Self {
|
2021-01-26 11:23:07 -08:00
|
|
|
commitment: CommitmentConfig::processed(),
|
2020-12-13 17:26:34 -08:00
|
|
|
send_transaction_config: RpcSendTransactionConfig {
|
|
|
|
skip_preflight: true,
|
2021-01-26 11:23:07 -08:00
|
|
|
preflight_commitment: Some(CommitmentConfig::processed().commitment),
|
2020-12-13 17:26:34 -08:00
|
|
|
..RpcSendTransactionConfig::default()
|
|
|
|
},
|
|
|
|
..Self::default()
|
|
|
|
}
|
2020-06-17 11:18:48 -07:00
|
|
|
}
|
2019-11-23 08:55:43 -08:00
|
|
|
}
|
2019-09-05 10:14:23 -07:00
|
|
|
|
2020-02-24 16:03:30 -08:00
|
|
|
impl Default for CliConfig<'_> {
|
|
|
|
fn default() -> CliConfig<'static> {
|
2019-10-04 15:13:21 -07:00
|
|
|
CliConfig {
|
|
|
|
command: CliCommand::Balance {
|
2019-10-21 16:08:09 -07:00
|
|
|
pubkey: Some(Pubkey::default()),
|
2019-09-10 12:36:59 -07:00
|
|
|
use_lamports_unit: false,
|
|
|
|
},
|
2022-04-11 11:56:51 -07:00
|
|
|
json_rpc_url: ConfigInput::default().json_rpc_url,
|
|
|
|
websocket_url: ConfigInput::default().websocket_url,
|
|
|
|
keypair_path: ConfigInput::default().keypair_path,
|
|
|
|
commitment: ConfigInput::default().commitment,
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: Vec::new(),
|
2019-01-13 23:10:03 -08:00
|
|
|
rpc_client: None,
|
2020-07-23 08:21:59 -07:00
|
|
|
rpc_timeout: Duration::from_secs(u64::from_str(DEFAULT_RPC_TIMEOUT_SECONDS).unwrap()),
|
2019-12-19 14:37:47 -08:00
|
|
|
verbose: false,
|
2020-04-14 12:10:25 -07:00
|
|
|
output_format: OutputFormat::Display,
|
2020-06-17 11:18:48 -07:00
|
|
|
send_transaction_config: RpcSendTransactionConfig::default(),
|
2021-06-29 18:08:45 -07:00
|
|
|
confirm_transaction_initial_timeout: Duration::from_secs(
|
|
|
|
u64::from_str(DEFAULT_CONFIRM_TX_TIMEOUT_SECONDS).unwrap(),
|
|
|
|
),
|
2020-06-17 23:09:33 -07:00
|
|
|
address_labels: HashMap::new(),
|
2022-09-07 13:19:14 -07:00
|
|
|
use_quic: !DEFAULT_TPU_ENABLE_UDP,
|
2018-09-14 01:58:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-24 16:03:30 -08:00
|
|
|
pub fn parse_command(
|
|
|
|
matches: &ArgMatches<'_>,
|
2020-09-21 20:53:15 -07:00
|
|
|
default_signer: &DefaultSigner,
|
2020-04-18 11:54:21 -07:00
|
|
|
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
2020-02-24 16:03:30 -08:00
|
|
|
) -> Result<CliCommandInfo, Box<dyn error::Error>> {
|
2018-09-14 01:58:39 -07:00
|
|
|
let response = match matches.subcommand() {
|
2021-07-28 23:19:34 -07:00
|
|
|
// Autocompletion Command
|
|
|
|
("completion", Some(matches)) => {
|
|
|
|
let shell_choice = match matches.value_of("shell") {
|
|
|
|
Some("bash") => Shell::Bash,
|
|
|
|
Some("fish") => Shell::Fish,
|
|
|
|
Some("zsh") => Shell::Zsh,
|
|
|
|
Some("powershell") => Shell::PowerShell,
|
|
|
|
Some("elvish") => Shell::Elvish,
|
|
|
|
// This is safe, since we assign default_value and possible_values
|
|
|
|
// are restricted
|
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
|
|
|
get_clap_app(
|
|
|
|
crate_name!(),
|
|
|
|
crate_description!(),
|
|
|
|
solana_version::version!(),
|
|
|
|
)
|
|
|
|
.gen_completions_to("solana", shell_choice, &mut stdout());
|
|
|
|
std::process::exit(0);
|
|
|
|
}
|
2019-10-04 19:54:09 -07:00
|
|
|
// Cluster Query Commands
|
2021-07-28 23:19:34 -07:00
|
|
|
("block", Some(matches)) => parse_get_block(matches),
|
|
|
|
("block-height", Some(matches)) => parse_get_block_height(matches),
|
|
|
|
("block-production", Some(matches)) => parse_show_block_production(matches),
|
|
|
|
("block-time", Some(matches)) => parse_get_block_time(matches),
|
2020-03-16 15:17:13 -07:00
|
|
|
("catchup", Some(matches)) => parse_catchup(matches, wallet_manager),
|
2020-05-05 08:42:03 -07:00
|
|
|
("cluster-date", Some(_matches)) => Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::ClusterDate,
|
|
|
|
signers: vec![],
|
|
|
|
}),
|
2019-10-21 16:08:09 -07:00
|
|
|
("cluster-version", Some(_matches)) => Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::ClusterVersion,
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-10-21 16:08:09 -07:00
|
|
|
}),
|
2021-07-28 23:19:34 -07:00
|
|
|
("epoch", Some(matches)) => parse_get_epoch(matches),
|
|
|
|
("epoch-info", Some(matches)) => parse_get_epoch_info(matches),
|
2020-09-24 13:30:38 -07:00
|
|
|
("feature", Some(matches)) => {
|
|
|
|
parse_feature_subcommand(matches, default_signer, wallet_manager)
|
|
|
|
}
|
2021-02-25 22:48:33 -08:00
|
|
|
("fees", Some(matches)) => {
|
|
|
|
let blockhash = value_of::<Hash>(matches, "blockhash");
|
|
|
|
Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::Fees { blockhash },
|
|
|
|
signers: vec![],
|
|
|
|
})
|
|
|
|
}
|
2020-09-06 10:54:01 -07:00
|
|
|
("first-available-block", Some(_matches)) => Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::FirstAvailableBlock,
|
|
|
|
signers: vec![],
|
|
|
|
}),
|
2020-01-20 22:06:47 -08:00
|
|
|
("genesis-hash", Some(_matches)) => Ok(CliCommandInfo {
|
2019-11-08 20:56:57 -08:00
|
|
|
command: CliCommand::GetGenesisHash,
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-10-21 16:08:09 -07:00
|
|
|
}),
|
2021-07-28 23:19:34 -07:00
|
|
|
("gossip", Some(_matches)) => Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::ShowGossip,
|
|
|
|
signers: vec![],
|
|
|
|
}),
|
2020-09-30 20:17:29 -07:00
|
|
|
("inflation", Some(matches)) => {
|
|
|
|
parse_inflation_subcommand(matches, default_signer, wallet_manager)
|
|
|
|
}
|
2020-05-12 20:05:05 -07:00
|
|
|
("largest-accounts", Some(matches)) => parse_largest_accounts(matches),
|
2020-12-28 10:38:15 -08:00
|
|
|
("leader-schedule", Some(matches)) => parse_leader_schedule(matches),
|
2020-02-29 08:39:07 -08:00
|
|
|
("live-slots", Some(_matches)) => Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::LiveSlots,
|
|
|
|
signers: vec![],
|
|
|
|
}),
|
2020-11-20 13:52:58 -08:00
|
|
|
("logs", Some(matches)) => parse_logs(matches, wallet_manager),
|
2021-07-28 23:19:34 -07:00
|
|
|
("ping", Some(matches)) => parse_cluster_ping(matches, default_signer, wallet_manager),
|
|
|
|
("rent", Some(matches)) => {
|
|
|
|
let data_length = value_of::<RentLengthValue>(matches, "data_length")
|
|
|
|
.unwrap()
|
|
|
|
.length();
|
|
|
|
let use_lamports_unit = matches.is_present("lamports");
|
|
|
|
Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::Rent {
|
|
|
|
data_length,
|
|
|
|
use_lamports_unit,
|
|
|
|
},
|
|
|
|
signers: vec![],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
("slot", Some(matches)) => parse_get_slot(matches),
|
2020-03-16 15:17:13 -07:00
|
|
|
("stakes", Some(matches)) => parse_show_stakes(matches, wallet_manager),
|
2021-07-28 23:19:34 -07:00
|
|
|
("supply", Some(matches)) => parse_supply(matches),
|
|
|
|
("total-supply", Some(matches)) => parse_total_supply(matches),
|
|
|
|
("transaction-count", Some(matches)) => parse_get_transaction_count(matches),
|
2020-04-20 22:01:09 -07:00
|
|
|
("transaction-history", Some(matches)) => {
|
|
|
|
parse_transaction_history(matches, wallet_manager)
|
|
|
|
}
|
2021-07-28 23:19:34 -07:00
|
|
|
("validators", Some(matches)) => parse_show_validators(matches),
|
2019-12-10 00:24:44 -08:00
|
|
|
// Nonce Commands
|
2020-02-24 16:03:30 -08:00
|
|
|
("authorize-nonce-account", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_authorize_nonce_account(matches, default_signer, wallet_manager)
|
2020-02-24 16:03:30 -08:00
|
|
|
}
|
|
|
|
("create-nonce-account", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_nonce_create_account(matches, default_signer, wallet_manager)
|
2020-02-24 16:03:30 -08:00
|
|
|
}
|
2020-03-16 15:17:13 -07:00
|
|
|
("nonce", Some(matches)) => parse_get_nonce(matches, wallet_manager),
|
2020-09-21 20:53:15 -07:00
|
|
|
("new-nonce", Some(matches)) => parse_new_nonce(matches, default_signer, wallet_manager),
|
2020-03-16 15:17:13 -07:00
|
|
|
("nonce-account", Some(matches)) => parse_show_nonce_account(matches, wallet_manager),
|
2019-12-10 00:24:44 -08:00
|
|
|
("withdraw-from-nonce-account", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_withdraw_from_nonce_account(matches, default_signer, wallet_manager)
|
2019-12-10 00:24:44 -08:00
|
|
|
}
|
2022-06-09 17:04:29 -07:00
|
|
|
("upgrade-nonce-account", Some(matches)) => parse_upgrade_nonce_account(matches),
|
2019-10-04 19:54:09 -07:00
|
|
|
// Program Deployment
|
2022-10-21 00:29:37 -07:00
|
|
|
("deploy", Some(_matches)) => clap::Error::with_description(
|
|
|
|
"`solana deploy` has been replaced with `solana program deploy`",
|
|
|
|
clap::ErrorKind::UnrecognizedSubcommand,
|
|
|
|
)
|
|
|
|
.exit(),
|
2020-12-21 13:02:53 -08:00
|
|
|
("program", Some(matches)) => {
|
|
|
|
parse_program_subcommand(matches, default_signer, wallet_manager)
|
2020-12-14 15:35:10 -08:00
|
|
|
}
|
2022-08-18 14:12:53 -07:00
|
|
|
("address-lookup-table", Some(matches)) => {
|
|
|
|
parse_address_lookup_table_subcommand(matches, default_signer, wallet_manager)
|
|
|
|
}
|
2020-11-12 13:48:34 -08:00
|
|
|
("wait-for-max-stake", Some(matches)) => {
|
|
|
|
let max_stake_percent = value_t_or_exit!(matches, "max_percent", f32);
|
|
|
|
Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::WaitForMaxStake { max_stake_percent },
|
|
|
|
signers: vec![],
|
|
|
|
})
|
|
|
|
}
|
2019-10-04 19:54:09 -07:00
|
|
|
// Stake Commands
|
2020-02-24 16:03:30 -08:00
|
|
|
("create-stake-account", Some(matches)) => {
|
2021-07-15 15:45:03 -07:00
|
|
|
parse_create_stake_account(matches, default_signer, wallet_manager, !CHECKED)
|
|
|
|
}
|
|
|
|
("create-stake-account-checked", Some(matches)) => {
|
|
|
|
parse_create_stake_account(matches, default_signer, wallet_manager, CHECKED)
|
2020-02-24 16:03:30 -08:00
|
|
|
}
|
|
|
|
("delegate-stake", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_stake_delegate_stake(matches, default_signer, wallet_manager)
|
2020-02-24 16:03:30 -08:00
|
|
|
}
|
2022-06-29 10:03:44 -07:00
|
|
|
("redelegate-stake", Some(matches)) => {
|
|
|
|
parse_stake_delegate_stake(matches, default_signer, wallet_manager)
|
|
|
|
}
|
2020-02-24 16:03:30 -08:00
|
|
|
("withdraw-stake", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_stake_withdraw_stake(matches, default_signer, wallet_manager)
|
2019-10-04 19:54:09 -07:00
|
|
|
}
|
2020-02-24 16:03:30 -08:00
|
|
|
("deactivate-stake", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_stake_deactivate_stake(matches, default_signer, wallet_manager)
|
2020-02-24 16:03:30 -08:00
|
|
|
}
|
|
|
|
("split-stake", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_split_stake(matches, default_signer, wallet_manager)
|
2020-02-24 16:03:30 -08:00
|
|
|
}
|
2020-06-10 21:02:04 -07:00
|
|
|
("merge-stake", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_merge_stake(matches, default_signer, wallet_manager)
|
2020-06-10 21:02:04 -07:00
|
|
|
}
|
2020-03-21 18:56:17 -07:00
|
|
|
("stake-authorize", Some(matches)) => {
|
2021-07-15 15:45:03 -07:00
|
|
|
parse_stake_authorize(matches, default_signer, wallet_manager, !CHECKED)
|
|
|
|
}
|
|
|
|
("stake-authorize-checked", Some(matches)) => {
|
|
|
|
parse_stake_authorize(matches, default_signer, wallet_manager, CHECKED)
|
2020-03-21 18:56:17 -07:00
|
|
|
}
|
2020-02-24 16:03:30 -08:00
|
|
|
("stake-set-lockup", Some(matches)) => {
|
2021-07-15 15:45:03 -07:00
|
|
|
parse_stake_set_lockup(matches, default_signer, wallet_manager, !CHECKED)
|
|
|
|
}
|
|
|
|
("stake-set-lockup-checked", Some(matches)) => {
|
|
|
|
parse_stake_set_lockup(matches, default_signer, wallet_manager, CHECKED)
|
2019-10-04 19:54:09 -07:00
|
|
|
}
|
2020-03-16 15:17:13 -07:00
|
|
|
("stake-account", Some(matches)) => parse_show_stake_account(matches, wallet_manager),
|
2020-01-26 20:00:57 -08:00
|
|
|
("stake-history", Some(matches)) => parse_show_stake_history(matches),
|
2022-07-21 05:23:18 -07:00
|
|
|
("stake-minimum-delegation", Some(matches)) => parse_stake_minimum_delegation(matches),
|
2019-10-04 19:54:09 -07:00
|
|
|
// Validator Info Commands
|
|
|
|
("validator-info", Some(matches)) => match matches.subcommand() {
|
2020-02-24 16:03:30 -08:00
|
|
|
("publish", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_validator_info_command(matches, default_signer, wallet_manager)
|
2020-02-24 16:03:30 -08:00
|
|
|
}
|
2019-10-04 19:54:09 -07:00
|
|
|
("get", Some(matches)) => parse_get_validator_info_command(matches),
|
|
|
|
_ => unreachable!(),
|
|
|
|
},
|
|
|
|
// Vote Commands
|
2020-02-24 16:03:30 -08:00
|
|
|
("create-vote-account", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_create_vote_account(matches, default_signer, wallet_manager)
|
2019-10-04 19:54:09 -07:00
|
|
|
}
|
2020-02-24 16:03:30 -08:00
|
|
|
("vote-update-validator", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_vote_update_validator(matches, default_signer, wallet_manager)
|
2019-10-04 19:54:09 -07:00
|
|
|
}
|
2020-06-09 21:15:46 -07:00
|
|
|
("vote-update-commission", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_vote_update_commission(matches, default_signer, wallet_manager)
|
2020-06-09 21:15:46 -07:00
|
|
|
}
|
2020-02-24 16:03:30 -08:00
|
|
|
("vote-authorize-voter", Some(matches)) => parse_vote_authorize(
|
|
|
|
matches,
|
2020-09-21 20:53:15 -07:00
|
|
|
default_signer,
|
2020-02-24 16:03:30 -08:00
|
|
|
wallet_manager,
|
|
|
|
VoteAuthorize::Voter,
|
2021-07-15 15:45:03 -07:00
|
|
|
!CHECKED,
|
2020-02-24 16:03:30 -08:00
|
|
|
),
|
|
|
|
("vote-authorize-withdrawer", Some(matches)) => parse_vote_authorize(
|
|
|
|
matches,
|
2020-09-21 20:53:15 -07:00
|
|
|
default_signer,
|
2020-02-24 16:03:30 -08:00
|
|
|
wallet_manager,
|
|
|
|
VoteAuthorize::Withdrawer,
|
2021-07-15 15:45:03 -07:00
|
|
|
!CHECKED,
|
|
|
|
),
|
|
|
|
("vote-authorize-voter-checked", Some(matches)) => parse_vote_authorize(
|
|
|
|
matches,
|
|
|
|
default_signer,
|
|
|
|
wallet_manager,
|
|
|
|
VoteAuthorize::Voter,
|
|
|
|
CHECKED,
|
|
|
|
),
|
|
|
|
("vote-authorize-withdrawer-checked", Some(matches)) => parse_vote_authorize(
|
|
|
|
matches,
|
|
|
|
default_signer,
|
|
|
|
wallet_manager,
|
|
|
|
VoteAuthorize::Withdrawer,
|
|
|
|
CHECKED,
|
2020-02-24 16:03:30 -08:00
|
|
|
),
|
2020-03-16 15:17:13 -07:00
|
|
|
("vote-account", Some(matches)) => parse_vote_get_account_command(matches, wallet_manager),
|
2020-03-13 13:30:04 -07:00
|
|
|
("withdraw-from-vote-account", Some(matches)) => {
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_withdraw_from_vote_account(matches, default_signer, wallet_manager)
|
2020-03-13 13:30:04 -07:00
|
|
|
}
|
2021-09-13 08:13:59 -07:00
|
|
|
("close-vote-account", Some(matches)) => {
|
|
|
|
parse_close_vote_account(matches, default_signer, wallet_manager)
|
|
|
|
}
|
2019-10-04 19:54:09 -07:00
|
|
|
// Wallet Commands
|
2021-07-28 23:19:34 -07:00
|
|
|
("account", Some(matches)) => parse_account(matches, wallet_manager),
|
2020-02-26 14:24:44 -08:00
|
|
|
("address", Some(matches)) => Ok(CliCommandInfo {
|
2019-10-21 16:08:09 -07:00
|
|
|
command: CliCommand::Address,
|
2020-09-21 20:53:15 -07:00
|
|
|
signers: vec![default_signer.signer_from_path(matches, wallet_manager)?],
|
2019-10-21 16:08:09 -07:00
|
|
|
}),
|
2021-07-28 23:19:34 -07:00
|
|
|
("airdrop", Some(matches)) => parse_airdrop(matches, default_signer, wallet_manager),
|
|
|
|
("balance", Some(matches)) => parse_balance(matches, default_signer, wallet_manager),
|
2019-10-21 16:08:09 -07:00
|
|
|
("confirm", Some(matches)) => match matches.value_of("signature").unwrap().parse() {
|
|
|
|
Ok(signature) => Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::Confirm(signature),
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-10-21 16:08:09 -07:00
|
|
|
}),
|
2020-04-20 10:00:20 -07:00
|
|
|
_ => Err(CliError::BadParameter("Invalid signature".to_string())),
|
2019-10-21 16:08:09 -07:00
|
|
|
},
|
2021-07-28 23:19:34 -07:00
|
|
|
("create-address-with-seed", Some(matches)) => {
|
|
|
|
parse_create_address_with_seed(matches, default_signer, wallet_manager)
|
2019-08-12 21:33:13 -07:00
|
|
|
}
|
2021-07-28 23:19:34 -07:00
|
|
|
("decode-transaction", Some(matches)) => parse_decode_transaction(matches),
|
2020-03-14 20:48:41 -07:00
|
|
|
("resolve-signer", Some(matches)) => {
|
|
|
|
let signer_path = resolve_signer(matches, "signer", wallet_manager)?;
|
|
|
|
Ok(CliCommandInfo {
|
|
|
|
command: CliCommand::ResolveSigner(signer_path),
|
|
|
|
signers: vec![],
|
|
|
|
})
|
|
|
|
}
|
2021-07-28 23:19:34 -07:00
|
|
|
("transfer", Some(matches)) => parse_transfer(matches, default_signer, wallet_manager),
|
2022-10-17 08:19:12 -07:00
|
|
|
("sign-offchain-message", Some(matches)) => {
|
|
|
|
parse_sign_offchain_message(matches, default_signer, wallet_manager)
|
|
|
|
}
|
|
|
|
("verify-offchain-signature", Some(matches)) => {
|
|
|
|
parse_verify_offchain_signature(matches, default_signer, wallet_manager)
|
|
|
|
}
|
2019-12-10 00:24:44 -08:00
|
|
|
//
|
2018-09-14 01:58:39 -07:00
|
|
|
("", None) => {
|
2018-09-24 09:23:16 -07:00
|
|
|
eprintln!("{}", matches.usage());
|
2019-10-04 15:13:21 -07:00
|
|
|
Err(CliError::CommandNotRecognized(
|
2018-09-14 01:58:39 -07:00
|
|
|
"no subcommand given".to_string(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}?;
|
|
|
|
Ok(response)
|
|
|
|
}
|
|
|
|
|
2019-10-08 22:34:26 -07:00
|
|
|
pub type ProcessResult = Result<String, Box<dyn std::error::Error>>;
|
2019-02-09 13:15:44 -08:00
|
|
|
|
2019-10-04 15:13:21 -07:00
|
|
|
pub fn process_command(config: &CliConfig) -> ProcessResult {
|
2021-01-20 08:48:10 -08:00
|
|
|
if config.verbose && config.output_format == OutputFormat::DisplayVerbose {
|
2020-02-05 10:14:44 -08:00
|
|
|
println_name_value("RPC URL:", &config.json_rpc_url);
|
2020-02-24 16:03:30 -08:00
|
|
|
println_name_value("Default Signer Path:", &config.keypair_path);
|
|
|
|
if config.keypair_path.starts_with("usb://") {
|
2021-01-21 22:58:34 -08:00
|
|
|
let pubkey = config
|
|
|
|
.pubkey()
|
2022-12-06 06:30:06 -08:00
|
|
|
.map(|pubkey| format!("{pubkey:?}"))
|
2021-01-21 22:58:34 -08:00
|
|
|
.unwrap_or_else(|_| "Unavailable".to_string());
|
|
|
|
println_name_value("Pubkey:", &pubkey);
|
2019-11-24 16:34:18 -08:00
|
|
|
}
|
2021-01-20 08:48:10 -08:00
|
|
|
println_name_value("Commitment:", &config.commitment.commitment.to_string());
|
2018-11-09 14:42:11 -08:00
|
|
|
}
|
|
|
|
|
2019-01-13 23:10:03 -08:00
|
|
|
let rpc_client = if config.rpc_client.is_none() {
|
2021-06-29 18:08:45 -07:00
|
|
|
Arc::new(RpcClient::new_with_timeouts_and_commitment(
|
2021-01-19 14:33:03 -08:00
|
|
|
config.json_rpc_url.to_string(),
|
|
|
|
config.rpc_timeout,
|
|
|
|
config.commitment,
|
2021-06-29 18:08:45 -07:00
|
|
|
config.confirm_transaction_initial_timeout,
|
2021-04-22 18:35:12 -07:00
|
|
|
))
|
2019-01-13 23:10:03 -08:00
|
|
|
} else {
|
|
|
|
// Primarily for testing
|
2021-04-22 18:35:12 -07:00
|
|
|
config.rpc_client.as_ref().unwrap().clone()
|
2019-01-13 23:10:03 -08:00
|
|
|
};
|
2018-11-09 14:36:08 -08:00
|
|
|
|
2019-05-09 19:31:42 -07:00
|
|
|
match &config.command {
|
2019-10-04 19:54:09 -07:00
|
|
|
// Cluster Query Commands
|
2019-12-19 14:37:47 -08:00
|
|
|
// Get address of this client
|
2020-02-07 10:26:56 -08:00
|
|
|
CliCommand::Address => Ok(format!("{}", config.pubkey()?)),
|
2019-10-04 19:54:09 -07:00
|
|
|
// Return software version of solana-cli and cluster entrypoint node
|
2020-03-04 11:44:13 -08:00
|
|
|
CliCommand::Catchup {
|
|
|
|
node_pubkey,
|
|
|
|
node_json_rpc_url,
|
2020-04-02 11:05:29 -07:00
|
|
|
follow,
|
2021-01-04 17:10:27 -08:00
|
|
|
our_localhost_port,
|
|
|
|
log,
|
|
|
|
} => process_catchup(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
*node_pubkey,
|
|
|
|
node_json_rpc_url.clone(),
|
|
|
|
*follow,
|
|
|
|
*our_localhost_port,
|
|
|
|
*log,
|
|
|
|
),
|
2020-05-05 08:42:03 -07:00
|
|
|
CliCommand::ClusterDate => process_cluster_date(&rpc_client, config),
|
2020-09-21 20:20:51 -07:00
|
|
|
CliCommand::ClusterVersion => process_cluster_version(&rpc_client, config),
|
2019-12-14 04:38:24 -08:00
|
|
|
CliCommand::CreateAddressWithSeed {
|
|
|
|
from_pubkey,
|
|
|
|
seed,
|
|
|
|
program_id,
|
2021-06-18 06:34:46 -07:00
|
|
|
} => process_create_address_with_seed(config, from_pubkey.as_ref(), seed, program_id),
|
2021-02-25 22:48:33 -08:00
|
|
|
CliCommand::Fees { ref blockhash } => process_fees(&rpc_client, config, blockhash.as_ref()),
|
2020-09-23 13:36:34 -07:00
|
|
|
CliCommand::Feature(feature_subcommand) => {
|
|
|
|
process_feature_subcommand(&rpc_client, config, feature_subcommand)
|
|
|
|
}
|
2020-09-06 10:54:01 -07:00
|
|
|
CliCommand::FirstAvailableBlock => process_first_available_block(&rpc_client),
|
2020-09-06 11:10:19 -07:00
|
|
|
CliCommand::GetBlock { slot } => process_get_block(&rpc_client, config, *slot),
|
2020-05-05 08:42:03 -07:00
|
|
|
CliCommand::GetBlockTime { slot } => process_get_block_time(&rpc_client, config, *slot),
|
2020-06-17 11:18:48 -07:00
|
|
|
CliCommand::GetEpoch => process_get_epoch(&rpc_client, config),
|
|
|
|
CliCommand::GetEpochInfo => process_get_epoch_info(&rpc_client, config),
|
2019-11-08 20:56:57 -08:00
|
|
|
CliCommand::GetGenesisHash => process_get_genesis_hash(&rpc_client),
|
2020-06-17 11:18:48 -07:00
|
|
|
CliCommand::GetSlot => process_get_slot(&rpc_client, config),
|
2020-07-22 08:36:12 -07:00
|
|
|
CliCommand::GetBlockHeight => process_get_block_height(&rpc_client, config),
|
2020-06-17 11:18:48 -07:00
|
|
|
CliCommand::LargestAccounts { filter } => {
|
|
|
|
process_largest_accounts(&rpc_client, config, filter.clone())
|
2019-11-24 16:34:18 -08:00
|
|
|
}
|
2020-06-17 11:18:48 -07:00
|
|
|
CliCommand::GetTransactionCount => process_get_transaction_count(&rpc_client, config),
|
2020-09-30 20:17:29 -07:00
|
|
|
CliCommand::Inflation(inflation_subcommand) => {
|
|
|
|
process_inflation_subcommand(&rpc_client, config, inflation_subcommand)
|
|
|
|
}
|
2021-01-09 16:02:22 -08:00
|
|
|
CliCommand::LeaderSchedule { epoch } => {
|
|
|
|
process_leader_schedule(&rpc_client, config, *epoch)
|
|
|
|
}
|
2021-06-18 06:34:46 -07:00
|
|
|
CliCommand::LiveSlots => process_live_slots(config),
|
|
|
|
CliCommand::Logs { filter } => process_logs(config, filter),
|
2019-10-04 19:54:09 -07:00
|
|
|
CliCommand::Ping {
|
|
|
|
interval,
|
|
|
|
count,
|
|
|
|
timeout,
|
2020-12-07 04:10:50 -08:00
|
|
|
blockhash,
|
|
|
|
print_timestamp,
|
2022-05-15 21:06:33 -07:00
|
|
|
compute_unit_price,
|
2020-12-07 04:10:50 -08:00
|
|
|
} => process_ping(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
interval,
|
|
|
|
count,
|
|
|
|
timeout,
|
|
|
|
blockhash,
|
|
|
|
*print_timestamp,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-12-07 04:10:50 -08:00
|
|
|
),
|
2021-01-20 22:24:26 -08:00
|
|
|
CliCommand::Rent {
|
|
|
|
data_length,
|
|
|
|
use_lamports_unit,
|
|
|
|
} => process_calculate_rent(&rpc_client, config, *data_length, *use_lamports_unit),
|
2019-12-18 10:38:54 -08:00
|
|
|
CliCommand::ShowBlockProduction { epoch, slot_limit } => {
|
2019-12-20 08:38:08 -08:00
|
|
|
process_show_block_production(&rpc_client, config, *epoch, *slot_limit)
|
2019-12-18 10:38:54 -08:00
|
|
|
}
|
2020-06-17 23:09:33 -07:00
|
|
|
CliCommand::ShowGossip => process_show_gossip(&rpc_client, config),
|
2020-01-17 11:10:52 -08:00
|
|
|
CliCommand::ShowStakes {
|
|
|
|
use_lamports_unit,
|
|
|
|
vote_account_pubkeys,
|
2022-06-17 12:52:23 -07:00
|
|
|
withdraw_authority,
|
2020-01-17 11:10:52 -08:00
|
|
|
} => process_show_stakes(
|
|
|
|
&rpc_client,
|
2020-04-14 12:10:25 -07:00
|
|
|
config,
|
2020-01-17 11:10:52 -08:00
|
|
|
*use_lamports_unit,
|
|
|
|
vote_account_pubkeys.as_deref(),
|
2022-06-17 12:52:23 -07:00
|
|
|
withdraw_authority.as_ref(),
|
2020-01-17 11:10:52 -08:00
|
|
|
),
|
2020-11-12 13:48:34 -08:00
|
|
|
CliCommand::WaitForMaxStake { max_stake_percent } => {
|
|
|
|
process_wait_for_max_stake(&rpc_client, config, *max_stake_percent)
|
|
|
|
}
|
2021-04-19 10:24:07 -07:00
|
|
|
CliCommand::ShowValidators {
|
|
|
|
use_lamports_unit,
|
|
|
|
sort_order,
|
|
|
|
reverse_sort,
|
2021-04-19 13:35:59 -07:00
|
|
|
number_validators,
|
2021-07-12 23:10:10 -07:00
|
|
|
keep_unstaked_delinquents,
|
|
|
|
delinquent_slot_distance,
|
2021-04-19 10:24:07 -07:00
|
|
|
} => process_show_validators(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
*use_lamports_unit,
|
|
|
|
*sort_order,
|
|
|
|
*reverse_sort,
|
2021-04-19 13:35:59 -07:00
|
|
|
*number_validators,
|
2021-07-12 23:10:10 -07:00
|
|
|
*keep_unstaked_delinquents,
|
|
|
|
*delinquent_slot_distance,
|
2021-04-19 10:24:07 -07:00
|
|
|
),
|
2020-06-17 11:18:48 -07:00
|
|
|
CliCommand::Supply { print_accounts } => {
|
|
|
|
process_supply(&rpc_client, config, *print_accounts)
|
|
|
|
}
|
|
|
|
CliCommand::TotalSupply => process_total_supply(&rpc_client, config),
|
2020-04-20 22:01:09 -07:00
|
|
|
CliCommand::TransactionHistory {
|
|
|
|
address,
|
2020-08-05 11:30:21 -07:00
|
|
|
before,
|
2020-08-15 09:42:17 -07:00
|
|
|
until,
|
2020-07-28 20:46:23 -07:00
|
|
|
limit,
|
2020-09-04 22:26:02 -07:00
|
|
|
show_transactions,
|
|
|
|
} => process_transaction_history(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
address,
|
|
|
|
*before,
|
|
|
|
*until,
|
|
|
|
*limit,
|
|
|
|
*show_transactions,
|
|
|
|
),
|
2019-06-07 13:11:56 -07:00
|
|
|
|
2019-12-10 00:24:44 -08:00
|
|
|
// Nonce Commands
|
|
|
|
|
2019-12-19 16:13:01 -08:00
|
|
|
// Assign authority to nonce account
|
|
|
|
CliCommand::AuthorizeNonceAccount {
|
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2019-12-19 16:13:01 -08:00
|
|
|
new_authority,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-12-19 16:13:01 -08:00
|
|
|
} => process_authorize_nonce_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2019-12-19 16:13:01 -08:00
|
|
|
new_authority,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-12-19 16:13:01 -08:00
|
|
|
),
|
2019-12-10 00:24:44 -08:00
|
|
|
// Create nonce account
|
|
|
|
CliCommand::CreateNonceAccount {
|
|
|
|
nonce_account,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed,
|
2019-12-17 06:34:21 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-05-14 11:24:14 -07:00
|
|
|
amount,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-12-17 06:34:21 -08:00
|
|
|
} => process_create_nonce_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_account,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed.clone(),
|
2020-01-02 17:05:08 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-05-14 11:24:14 -07:00
|
|
|
*amount,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-12-17 06:34:21 -08:00
|
|
|
),
|
2019-12-10 00:24:44 -08:00
|
|
|
// Get the current nonce
|
|
|
|
CliCommand::GetNonce(nonce_account_pubkey) => {
|
2021-06-18 06:34:46 -07:00
|
|
|
process_get_nonce(&rpc_client, config, nonce_account_pubkey)
|
2019-12-10 00:24:44 -08:00
|
|
|
}
|
|
|
|
// Get a new nonce
|
2019-12-17 06:34:21 -08:00
|
|
|
CliCommand::NewNonce {
|
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2021-04-05 13:53:50 -07:00
|
|
|
} => process_new_nonce(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
nonce_account,
|
|
|
|
*nonce_authority,
|
|
|
|
memo.as_ref(),
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2021-04-05 13:53:50 -07:00
|
|
|
),
|
2019-12-10 00:24:44 -08:00
|
|
|
// Show the contents of a nonce account
|
|
|
|
CliCommand::ShowNonceAccount {
|
|
|
|
nonce_account_pubkey,
|
|
|
|
use_lamports_unit,
|
2020-04-14 12:10:25 -07:00
|
|
|
} => process_show_nonce_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
nonce_account_pubkey,
|
2020-04-14 12:10:25 -07:00
|
|
|
*use_lamports_unit,
|
|
|
|
),
|
2019-12-10 00:24:44 -08:00
|
|
|
// Withdraw lamports from a nonce account
|
|
|
|
CliCommand::WithdrawFromNonceAccount {
|
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2019-12-10 00:24:44 -08:00
|
|
|
destination_account_pubkey,
|
|
|
|
lamports,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-12-10 00:24:44 -08:00
|
|
|
} => process_withdraw_from_nonce_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-06-18 06:34:46 -07:00
|
|
|
destination_account_pubkey,
|
2019-12-10 00:24:44 -08:00
|
|
|
*lamports,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-12-10 00:24:44 -08:00
|
|
|
),
|
2022-06-09 17:04:29 -07:00
|
|
|
// Upgrade nonce account out of blockhash domain.
|
|
|
|
CliCommand::UpgradeNonceAccount {
|
|
|
|
nonce_account,
|
|
|
|
memo,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
|
|
|
} => process_upgrade_nonce_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
*nonce_account,
|
|
|
|
memo.as_ref(),
|
|
|
|
compute_unit_price.as_ref(),
|
|
|
|
),
|
2019-12-10 00:24:44 -08:00
|
|
|
|
2019-10-04 19:54:09 -07:00
|
|
|
// Program Deployment
|
2022-10-21 00:29:37 -07:00
|
|
|
CliCommand::Deploy => {
|
|
|
|
// This command is not supported any longer
|
|
|
|
// Error message is printed on the previous stage
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
2019-08-29 20:45:53 -07:00
|
|
|
|
2019-10-04 19:54:09 -07:00
|
|
|
// Deploy a custom program to the chain
|
2020-12-21 13:02:53 -08:00
|
|
|
CliCommand::Program(program_subcommand) => {
|
2021-04-22 18:35:12 -07:00
|
|
|
process_program_subcommand(rpc_client, config, program_subcommand)
|
2020-12-21 13:02:53 -08:00
|
|
|
}
|
2020-12-14 15:35:10 -08:00
|
|
|
|
2019-10-04 19:54:09 -07:00
|
|
|
// Stake Commands
|
2019-07-26 09:34:12 -07:00
|
|
|
|
2019-10-04 19:54:09 -07:00
|
|
|
// Create stake account
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommand::CreateStakeAccount {
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_account,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed,
|
2019-10-21 16:08:09 -07:00
|
|
|
staker,
|
|
|
|
withdrawer,
|
2021-07-15 15:45:03 -07:00
|
|
|
withdrawer_signer,
|
2019-10-21 16:08:09 -07:00
|
|
|
lockup,
|
2020-05-14 11:24:14 -07:00
|
|
|
amount,
|
2020-02-12 22:00:28 -08:00
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-02-12 22:00:28 -08:00
|
|
|
blockhash_query,
|
|
|
|
ref nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
|
|
|
from,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-10-21 16:08:09 -07:00
|
|
|
} => process_create_stake_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2020-02-24 16:03:30 -08:00
|
|
|
*stake_account,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed,
|
2019-10-21 16:08:09 -07:00
|
|
|
staker,
|
|
|
|
withdrawer,
|
2021-07-15 15:45:03 -07:00
|
|
|
*withdrawer_signer,
|
2019-10-21 16:08:09 -07:00
|
|
|
lockup,
|
2020-05-14 11:24:14 -07:00
|
|
|
*amount,
|
2020-02-12 22:00:28 -08:00
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-02-12 22:00:28 -08:00
|
|
|
blockhash_query,
|
|
|
|
nonce_account.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
|
|
|
*from,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-10-21 16:08:09 -07:00
|
|
|
),
|
2019-11-25 21:09:57 -08:00
|
|
|
CliCommand::DeactivateStake {
|
|
|
|
stake_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority,
|
2019-11-25 21:09:57 -08:00
|
|
|
sign_only,
|
2022-03-25 09:11:51 -07:00
|
|
|
deactivate_delinquent,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query,
|
2019-12-27 12:35:49 -08:00
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2021-04-21 11:05:05 -07:00
|
|
|
seed,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-11-25 21:09:57 -08:00
|
|
|
} => process_deactivate_stake_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
*stake_authority,
|
2019-11-25 21:09:57 -08:00
|
|
|
*sign_only,
|
2022-03-25 09:11:51 -07:00
|
|
|
*deactivate_delinquent,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query,
|
2019-12-27 12:35:49 -08:00
|
|
|
*nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-04-21 11:05:05 -07:00
|
|
|
seed.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-11-25 21:09:57 -08:00
|
|
|
),
|
|
|
|
CliCommand::DelegateStake {
|
|
|
|
stake_account_pubkey,
|
|
|
|
vote_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority,
|
2019-11-25 21:09:57 -08:00
|
|
|
force,
|
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query,
|
2019-12-27 12:35:49 -08:00
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
2022-06-29 10:03:44 -07:00
|
|
|
redelegation_stake_account_pubkey,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-11-25 21:09:57 -08:00
|
|
|
} => process_delegate_stake(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
|
|
|
vote_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
*stake_authority,
|
2019-11-25 21:09:57 -08:00
|
|
|
*force,
|
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query,
|
2019-12-27 12:35:49 -08:00
|
|
|
*nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
2022-06-29 10:03:44 -07:00
|
|
|
redelegation_stake_account_pubkey.as_ref(),
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-11-25 21:09:57 -08:00
|
|
|
),
|
2020-02-02 21:20:28 -08:00
|
|
|
CliCommand::SplitStake {
|
|
|
|
stake_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority,
|
2020-02-02 21:20:28 -08:00
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-02-02 21:20:28 -08:00
|
|
|
blockhash_query,
|
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-02-02 21:20:28 -08:00
|
|
|
split_stake_account,
|
|
|
|
seed,
|
|
|
|
lamports,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-02-02 21:20:28 -08:00
|
|
|
} => process_split_stake(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
*stake_authority,
|
2020-02-02 21:20:28 -08:00
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-02-02 21:20:28 -08:00
|
|
|
blockhash_query,
|
|
|
|
*nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*split_stake_account,
|
2020-02-02 21:20:28 -08:00
|
|
|
seed,
|
|
|
|
*lamports,
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-02-02 21:20:28 -08:00
|
|
|
),
|
2020-06-10 21:02:04 -07:00
|
|
|
CliCommand::MergeStake {
|
|
|
|
stake_account_pubkey,
|
|
|
|
source_stake_account_pubkey,
|
|
|
|
stake_authority,
|
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-06-10 21:02:04 -07:00
|
|
|
blockhash_query,
|
|
|
|
nonce_account,
|
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-06-10 21:02:04 -07:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-06-10 21:02:04 -07:00
|
|
|
} => process_merge_stake(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
|
|
|
source_stake_account_pubkey,
|
2020-06-10 21:02:04 -07:00
|
|
|
*stake_authority,
|
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-06-10 21:02:04 -07:00
|
|
|
blockhash_query,
|
|
|
|
*nonce_account,
|
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-06-10 21:02:04 -07:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-06-10 21:02:04 -07:00
|
|
|
),
|
2019-10-04 19:54:09 -07:00
|
|
|
CliCommand::ShowStakeAccount {
|
|
|
|
pubkey: stake_account_pubkey,
|
|
|
|
use_lamports_unit,
|
2021-04-08 09:57:33 -07:00
|
|
|
with_rewards,
|
2019-10-04 19:54:09 -07:00
|
|
|
} => process_show_stake_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
2019-10-04 19:54:09 -07:00
|
|
|
*use_lamports_unit,
|
2021-04-08 09:57:33 -07:00
|
|
|
*with_rewards,
|
2019-10-04 19:54:09 -07:00
|
|
|
),
|
2021-04-20 01:30:19 -07:00
|
|
|
CliCommand::ShowStakeHistory {
|
|
|
|
use_lamports_unit,
|
|
|
|
limit_results,
|
|
|
|
} => process_show_stake_history(&rpc_client, config, *use_lamports_unit, *limit_results),
|
2020-01-15 13:32:06 -08:00
|
|
|
CliCommand::StakeAuthorize {
|
2019-09-29 21:18:15 -07:00
|
|
|
stake_account_pubkey,
|
2020-03-21 18:56:17 -07:00
|
|
|
ref new_authorizations,
|
2020-01-17 09:30:56 -08:00
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query,
|
2020-01-17 09:30:56 -08:00
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
2021-01-26 09:44:44 -08:00
|
|
|
custodian,
|
2021-05-17 09:54:33 -07:00
|
|
|
no_wait,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-01-15 13:32:06 -08:00
|
|
|
} => process_stake_authorize(
|
2019-08-01 21:08:24 -07:00
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
2020-03-21 18:56:17 -07:00
|
|
|
new_authorizations,
|
2021-01-26 09:44:44 -08:00
|
|
|
*custodian,
|
2020-01-17 09:30:56 -08:00
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query,
|
2020-01-17 09:30:56 -08:00
|
|
|
*nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
2021-05-17 09:54:33 -07:00
|
|
|
*no_wait,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-08-01 21:08:24 -07:00
|
|
|
),
|
2020-02-12 15:36:29 -08:00
|
|
|
CliCommand::StakeSetLockup {
|
|
|
|
stake_account_pubkey,
|
2021-07-15 15:45:03 -07:00
|
|
|
lockup,
|
2020-02-24 16:03:30 -08:00
|
|
|
custodian,
|
2021-07-15 15:45:03 -07:00
|
|
|
new_custodian_signer,
|
2020-02-12 15:36:29 -08:00
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-02-12 15:36:29 -08:00
|
|
|
blockhash_query,
|
|
|
|
nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-02-12 15:36:29 -08:00
|
|
|
} => process_stake_set_lockup(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
2021-07-15 15:45:03 -07:00
|
|
|
lockup,
|
|
|
|
*new_custodian_signer,
|
2020-02-24 16:03:30 -08:00
|
|
|
*custodian,
|
2020-02-12 15:36:29 -08:00
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-02-12 15:36:29 -08:00
|
|
|
blockhash_query,
|
|
|
|
*nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-02-12 15:36:29 -08:00
|
|
|
),
|
2020-01-15 13:32:06 -08:00
|
|
|
CliCommand::WithdrawStake {
|
|
|
|
stake_account_pubkey,
|
|
|
|
destination_account_pubkey,
|
2021-04-26 08:33:56 -07:00
|
|
|
amount,
|
2020-02-24 16:03:30 -08:00
|
|
|
withdraw_authority,
|
2020-04-22 15:00:18 -07:00
|
|
|
custodian,
|
2020-02-12 22:00:28 -08:00
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2020-02-12 22:00:28 -08:00
|
|
|
blockhash_query,
|
|
|
|
ref nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2021-04-21 11:05:05 -07:00
|
|
|
seed,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-01-15 13:32:06 -08:00
|
|
|
} => process_withdraw_stake(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
stake_account_pubkey,
|
|
|
|
destination_account_pubkey,
|
2021-04-26 08:33:56 -07:00
|
|
|
*amount,
|
2020-02-24 16:03:30 -08:00
|
|
|
*withdraw_authority,
|
2020-04-22 15:00:18 -07:00
|
|
|
*custodian,
|
2020-02-12 22:00:28 -08:00
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2020-02-12 22:00:28 -08:00
|
|
|
blockhash_query,
|
|
|
|
nonce_account.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-04-21 11:05:05 -07:00
|
|
|
seed.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-01-15 13:32:06 -08:00
|
|
|
),
|
2022-07-21 05:23:18 -07:00
|
|
|
CliCommand::StakeMinimumDelegation { use_lamports_unit } => {
|
|
|
|
process_stake_minimum_delegation(&rpc_client, config, *use_lamports_unit)
|
|
|
|
}
|
2019-06-21 22:28:34 -07:00
|
|
|
|
2019-10-04 19:54:09 -07:00
|
|
|
// Validator Info Commands
|
|
|
|
|
|
|
|
// Return all or single validator info
|
|
|
|
CliCommand::GetValidatorInfo(info_pubkey) => {
|
2020-04-14 12:10:25 -07:00
|
|
|
process_get_validator_info(&rpc_client, config, *info_pubkey)
|
2019-10-04 19:54:09 -07:00
|
|
|
}
|
|
|
|
// Publish validator info
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommand::SetValidatorInfo {
|
|
|
|
validator_info,
|
|
|
|
force_keybase,
|
|
|
|
info_pubkey,
|
|
|
|
} => process_set_validator_info(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
validator_info,
|
2019-10-21 16:08:09 -07:00
|
|
|
*force_keybase,
|
|
|
|
*info_pubkey,
|
|
|
|
),
|
2018-10-22 21:21:33 -07:00
|
|
|
|
2019-10-04 19:54:09 -07:00
|
|
|
// Vote Commands
|
|
|
|
|
|
|
|
// Create vote account
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommand::CreateVoteAccount {
|
2020-07-13 20:27:41 -07:00
|
|
|
vote_account,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed,
|
2020-03-19 01:58:52 -07:00
|
|
|
identity_account,
|
2019-10-21 16:08:09 -07:00
|
|
|
authorized_voter,
|
|
|
|
authorized_withdrawer,
|
|
|
|
commission,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only,
|
|
|
|
dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
ref nonce_account,
|
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-10-21 16:08:09 -07:00
|
|
|
} => process_create_vote_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2020-07-13 20:27:41 -07:00
|
|
|
*vote_account,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed,
|
2020-03-19 01:58:52 -07:00
|
|
|
*identity_account,
|
2019-10-21 16:08:09 -07:00
|
|
|
authorized_voter,
|
2021-09-02 17:22:33 -07:00
|
|
|
*authorized_withdrawer,
|
2019-10-21 16:08:09 -07:00
|
|
|
*commission,
|
2021-12-06 14:54:50 -08:00
|
|
|
*sign_only,
|
|
|
|
*dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
nonce_account.as_ref(),
|
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-12-06 14:54:50 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-10-21 16:08:09 -07:00
|
|
|
),
|
2019-10-04 19:54:09 -07:00
|
|
|
CliCommand::ShowVoteAccount {
|
|
|
|
pubkey: vote_account_pubkey,
|
|
|
|
use_lamports_unit,
|
2021-04-08 09:57:33 -07:00
|
|
|
with_rewards,
|
2019-10-04 19:54:09 -07:00
|
|
|
} => process_show_vote_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
vote_account_pubkey,
|
2019-10-04 19:54:09 -07:00
|
|
|
*use_lamports_unit,
|
2021-04-08 09:57:33 -07:00
|
|
|
*with_rewards,
|
2019-10-04 19:54:09 -07:00
|
|
|
),
|
2020-03-13 13:30:04 -07:00
|
|
|
CliCommand::WithdrawFromVoteAccount {
|
|
|
|
vote_account_pubkey,
|
|
|
|
withdraw_authority,
|
2020-06-15 14:36:47 -07:00
|
|
|
withdraw_amount,
|
2020-03-13 13:30:04 -07:00
|
|
|
destination_account_pubkey,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only,
|
|
|
|
dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
ref nonce_account,
|
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-03-13 13:30:04 -07:00
|
|
|
} => process_withdraw_from_vote_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
vote_account_pubkey,
|
|
|
|
*withdraw_authority,
|
2020-06-15 14:36:47 -07:00
|
|
|
*withdraw_amount,
|
2020-03-13 13:30:04 -07:00
|
|
|
destination_account_pubkey,
|
2021-12-06 14:54:50 -08:00
|
|
|
*sign_only,
|
|
|
|
*dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
nonce_account.as_ref(),
|
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-12-06 14:54:50 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-03-13 13:30:04 -07:00
|
|
|
),
|
2021-09-13 08:13:59 -07:00
|
|
|
CliCommand::CloseVoteAccount {
|
|
|
|
vote_account_pubkey,
|
|
|
|
withdraw_authority,
|
|
|
|
destination_account_pubkey,
|
|
|
|
memo,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2021-09-13 08:13:59 -07:00
|
|
|
} => process_close_vote_account(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
|
|
|
vote_account_pubkey,
|
|
|
|
*withdraw_authority,
|
|
|
|
destination_account_pubkey,
|
|
|
|
memo.as_ref(),
|
2021-12-06 14:54:50 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2021-09-13 08:13:59 -07:00
|
|
|
),
|
2019-12-12 15:04:03 -08:00
|
|
|
CliCommand::VoteAuthorize {
|
|
|
|
vote_account_pubkey,
|
|
|
|
new_authorized_pubkey,
|
|
|
|
vote_authorize,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only,
|
|
|
|
dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
nonce_account,
|
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer,
|
2021-07-15 15:45:03 -07:00
|
|
|
authorized,
|
|
|
|
new_authorized,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-12-12 15:04:03 -08:00
|
|
|
} => process_vote_authorize(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
vote_account_pubkey,
|
|
|
|
new_authorized_pubkey,
|
2019-12-12 15:04:03 -08:00
|
|
|
*vote_authorize,
|
2021-07-15 15:45:03 -07:00
|
|
|
*authorized,
|
|
|
|
*new_authorized,
|
2021-12-06 14:54:50 -08:00
|
|
|
*sign_only,
|
|
|
|
*dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
*nonce_account,
|
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-12-06 14:54:50 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-12-12 15:04:03 -08:00
|
|
|
),
|
|
|
|
CliCommand::VoteUpdateValidator {
|
|
|
|
vote_account_pubkey,
|
2020-03-19 01:58:52 -07:00
|
|
|
new_identity_account,
|
2020-07-13 20:49:59 -07:00
|
|
|
withdraw_authority,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only,
|
|
|
|
dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
nonce_account,
|
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2019-12-12 15:04:03 -08:00
|
|
|
} => process_vote_update_validator(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
vote_account_pubkey,
|
2020-03-19 01:58:52 -07:00
|
|
|
*new_identity_account,
|
2020-07-13 20:49:59 -07:00
|
|
|
*withdraw_authority,
|
2021-12-06 14:54:50 -08:00
|
|
|
*sign_only,
|
|
|
|
*dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
*nonce_account,
|
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-12-06 14:54:50 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2019-12-12 15:04:03 -08:00
|
|
|
),
|
2020-06-09 21:15:46 -07:00
|
|
|
CliCommand::VoteUpdateCommission {
|
|
|
|
vote_account_pubkey,
|
|
|
|
commission,
|
2020-07-13 19:30:49 -07:00
|
|
|
withdraw_authority,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only,
|
|
|
|
dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
nonce_account,
|
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-07-13 19:30:49 -07:00
|
|
|
} => process_vote_update_commission(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2021-06-18 06:34:46 -07:00
|
|
|
vote_account_pubkey,
|
2020-07-13 19:30:49 -07:00
|
|
|
*commission,
|
|
|
|
*withdraw_authority,
|
2021-12-06 14:54:50 -08:00
|
|
|
*sign_only,
|
|
|
|
*dump_transaction_message,
|
|
|
|
blockhash_query,
|
|
|
|
*nonce_account,
|
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2021-12-06 14:54:50 -08:00
|
|
|
*fee_payer,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-07-13 19:30:49 -07:00
|
|
|
),
|
2019-10-04 19:54:09 -07:00
|
|
|
|
|
|
|
// Wallet Commands
|
|
|
|
|
2019-12-16 13:05:17 -08:00
|
|
|
// Request an airdrop from Solana Faucet;
|
2021-04-14 23:25:23 -07:00
|
|
|
CliCommand::Airdrop { pubkey, lamports } => {
|
|
|
|
process_airdrop(&rpc_client, config, pubkey, *lamports)
|
2019-10-04 19:54:09 -07:00
|
|
|
}
|
|
|
|
// Check client balance
|
|
|
|
CliCommand::Balance {
|
|
|
|
pubkey,
|
|
|
|
use_lamports_unit,
|
2021-06-18 06:34:46 -07:00
|
|
|
} => process_balance(&rpc_client, config, pubkey, *use_lamports_unit),
|
2019-10-04 19:54:09 -07:00
|
|
|
// Confirm the last client transaction by signature
|
2020-04-15 20:51:05 -07:00
|
|
|
CliCommand::Confirm(signature) => process_confirm(&rpc_client, config, signature),
|
2021-02-25 13:15:52 -08:00
|
|
|
CliCommand::DecodeTransaction(transaction) => {
|
|
|
|
process_decode_transaction(config, transaction)
|
|
|
|
}
|
2020-03-14 20:48:41 -07:00
|
|
|
CliCommand::ResolveSigner(path) => {
|
|
|
|
if let Some(path) = path {
|
|
|
|
Ok(path.to_string())
|
|
|
|
} else {
|
|
|
|
Ok("Signer is valid".to_string())
|
|
|
|
}
|
|
|
|
}
|
2019-10-04 19:54:09 -07:00
|
|
|
CliCommand::ShowAccount {
|
|
|
|
pubkey,
|
|
|
|
output_file,
|
|
|
|
use_lamports_unit,
|
2021-06-18 06:34:58 -07:00
|
|
|
} => process_show_account(&rpc_client, config, pubkey, output_file, *use_lamports_unit),
|
2020-02-07 11:16:35 -08:00
|
|
|
CliCommand::Transfer {
|
2020-05-14 11:24:14 -07:00
|
|
|
amount,
|
2020-02-07 11:16:35 -08:00
|
|
|
to,
|
2020-02-24 16:03:30 -08:00
|
|
|
from,
|
2020-02-07 11:16:35 -08:00
|
|
|
sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient,
|
2020-04-08 22:46:19 -07:00
|
|
|
no_wait,
|
2020-02-07 11:16:35 -08:00
|
|
|
ref blockhash_query,
|
|
|
|
ref nonce_account,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed,
|
|
|
|
ref derived_address_program_id,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price,
|
2020-02-07 11:16:35 -08:00
|
|
|
} => process_transfer(
|
|
|
|
&rpc_client,
|
|
|
|
config,
|
2020-05-14 11:24:14 -07:00
|
|
|
*amount,
|
2020-02-07 11:16:35 -08:00
|
|
|
to,
|
2020-02-24 16:03:30 -08:00
|
|
|
*from,
|
2020-02-07 11:16:35 -08:00
|
|
|
*sign_only,
|
2021-03-12 18:37:39 -08:00
|
|
|
*dump_transaction_message,
|
2021-03-22 11:10:44 -07:00
|
|
|
*allow_unfunded_recipient,
|
2020-04-08 22:46:19 -07:00
|
|
|
*no_wait,
|
2020-02-07 11:16:35 -08:00
|
|
|
blockhash_query,
|
|
|
|
nonce_account.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*nonce_authority,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo.as_ref(),
|
2020-02-24 16:03:30 -08:00
|
|
|
*fee_payer,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed.clone(),
|
|
|
|
derived_address_program_id.as_ref(),
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price.as_ref(),
|
2020-02-07 11:16:35 -08:00
|
|
|
),
|
2022-08-18 14:12:53 -07:00
|
|
|
// Address Lookup Table Commands
|
|
|
|
CliCommand::AddressLookupTable(subcommand) => {
|
|
|
|
process_address_lookup_table_subcommand(rpc_client, config, subcommand)
|
|
|
|
}
|
2022-10-17 08:19:12 -07:00
|
|
|
CliCommand::SignOffchainMessage { message } => {
|
|
|
|
process_sign_offchain_message(config, message)
|
|
|
|
}
|
|
|
|
CliCommand::VerifyOffchainSignature {
|
|
|
|
signer_pubkey,
|
|
|
|
signature,
|
|
|
|
message,
|
|
|
|
} => process_verify_offchain_signature(config, signer_pubkey, signature, message),
|
2018-09-14 01:58:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-13 23:10:03 -08:00
|
|
|
pub fn request_and_confirm_airdrop(
|
2018-12-10 11:20:55 -08:00
|
|
|
rpc_client: &RpcClient,
|
2021-04-14 23:25:23 -07:00
|
|
|
config: &CliConfig,
|
2019-03-14 19:18:28 -07:00
|
|
|
to_pubkey: &Pubkey,
|
2019-03-05 17:22:46 -08:00
|
|
|
lamports: u64,
|
2021-04-06 00:01:05 -07:00
|
|
|
) -> ClientResult<Signature> {
|
2021-08-13 09:08:20 -07:00
|
|
|
let recent_blockhash = rpc_client.get_latest_blockhash()?;
|
2021-04-14 23:25:23 -07:00
|
|
|
let signature =
|
|
|
|
rpc_client.request_airdrop_with_blockhash(to_pubkey, lamports, &recent_blockhash)?;
|
|
|
|
rpc_client.confirm_transaction_with_spinner(
|
|
|
|
&signature,
|
|
|
|
&recent_blockhash,
|
|
|
|
config.commitment,
|
|
|
|
)?;
|
|
|
|
Ok(signature)
|
2018-10-22 21:21:33 -07:00
|
|
|
}
|
|
|
|
|
2021-06-01 16:25:53 -07:00
|
|
|
fn common_error_adapter<E>(ix_error: &InstructionError) -> Option<E>
|
|
|
|
where
|
|
|
|
E: 'static + std::error::Error + DecodeError<E> + FromPrimitive,
|
|
|
|
{
|
|
|
|
if let InstructionError::Custom(code) = ix_error {
|
|
|
|
E::decode_custom_error_to_enum(*code)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 21:21:48 -07:00
|
|
|
pub fn log_instruction_custom_error<E>(
|
|
|
|
result: ClientResult<Signature>,
|
|
|
|
config: &CliConfig,
|
|
|
|
) -> ProcessResult
|
2019-04-25 10:29:44 -07:00
|
|
|
where
|
|
|
|
E: 'static + std::error::Error + DecodeError<E> + FromPrimitive,
|
2021-06-01 16:25:53 -07:00
|
|
|
{
|
|
|
|
log_instruction_custom_error_ex::<E, _>(result, config, common_error_adapter)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn log_instruction_custom_error_ex<E, F>(
|
|
|
|
result: ClientResult<Signature>,
|
|
|
|
config: &CliConfig,
|
|
|
|
error_adapter: F,
|
|
|
|
) -> ProcessResult
|
|
|
|
where
|
|
|
|
E: 'static + std::error::Error + DecodeError<E> + FromPrimitive,
|
|
|
|
F: Fn(&InstructionError) -> Option<E>,
|
2019-04-25 10:29:44 -07:00
|
|
|
{
|
2019-10-02 18:33:01 -07:00
|
|
|
match result {
|
|
|
|
Err(err) => {
|
2021-06-01 16:25:53 -07:00
|
|
|
let maybe_tx_err = err.get_transaction_error();
|
|
|
|
if let Some(TransactionError::InstructionError(_, ix_error)) = maybe_tx_err {
|
|
|
|
if let Some(specific_error) = error_adapter(&ix_error) {
|
2019-10-02 18:33:01 -07:00
|
|
|
return Err(specific_error.into());
|
|
|
|
}
|
2019-04-25 10:29:44 -07:00
|
|
|
}
|
2019-10-02 18:33:01 -07:00
|
|
|
Err(err.into())
|
2019-04-25 10:29:44 -07:00
|
|
|
}
|
2020-05-06 21:21:48 -07:00
|
|
|
Ok(sig) => {
|
|
|
|
let signature = CliSignature {
|
|
|
|
signature: sig.clone().to_string(),
|
|
|
|
};
|
|
|
|
Ok(config.output_format.formatted_string(&signature))
|
|
|
|
}
|
2019-04-25 10:29:44 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-14 01:58:39 -07:00
|
|
|
#[cfg(test)]
|
2018-09-14 01:59:09 -07:00
|
|
|
mod tests {
|
2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
super::*,
|
2022-10-21 00:29:37 -07:00
|
|
|
serde_json::json,
|
2022-08-23 22:34:35 -07:00
|
|
|
solana_rpc_client::mock_sender_for_cli::SIGNATURE,
|
2022-08-24 09:47:02 -07:00
|
|
|
solana_rpc_client_api::{
|
|
|
|
request::RpcRequest,
|
|
|
|
response::{Response, RpcResponseContext},
|
|
|
|
},
|
|
|
|
solana_rpc_client_nonce_utils::blockhash_query,
|
2021-12-03 09:00:31 -08:00
|
|
|
solana_sdk::{
|
|
|
|
pubkey::Pubkey,
|
|
|
|
signature::{
|
|
|
|
keypair_from_seed, read_keypair_file, write_keypair_file, Keypair, Presigner,
|
|
|
|
},
|
|
|
|
stake, system_program,
|
|
|
|
transaction::TransactionError,
|
|
|
|
},
|
|
|
|
solana_transaction_status::TransactionConfirmationStatus,
|
2019-09-18 09:29:57 -07:00
|
|
|
};
|
2018-09-14 01:59:09 -07:00
|
|
|
|
2019-09-29 21:18:15 -07:00
|
|
|
fn make_tmp_path(name: &str) -> String {
|
|
|
|
let out_dir = std::env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string());
|
|
|
|
let keypair = Keypair::new();
|
|
|
|
|
|
|
|
let path = format!("{}/tmp/{}-{}", out_dir, name, keypair.pubkey());
|
|
|
|
|
|
|
|
// whack any possible collision
|
|
|
|
let _ignored = std::fs::remove_dir_all(&path);
|
|
|
|
// whack any possible collision
|
|
|
|
let _ignored = std::fs::remove_file(&path);
|
|
|
|
|
|
|
|
path
|
|
|
|
}
|
|
|
|
|
2020-02-24 16:03:30 -08:00
|
|
|
#[test]
|
|
|
|
fn test_generate_unique_signers() {
|
|
|
|
let matches = ArgMatches::default();
|
|
|
|
|
|
|
|
let default_keypair = Keypair::new();
|
|
|
|
let default_keypair_file = make_tmp_path("keypair_file");
|
|
|
|
write_keypair_file(&default_keypair, &default_keypair_file).unwrap();
|
|
|
|
|
2021-05-28 00:42:55 -07:00
|
|
|
let default_signer = DefaultSigner::new("keypair", &default_keypair_file);
|
2020-09-21 20:53:15 -07:00
|
|
|
|
|
|
|
let signer_info = default_signer
|
|
|
|
.generate_unique_signers(vec![], &matches, &mut None)
|
|
|
|
.unwrap();
|
2020-02-24 16:03:30 -08:00
|
|
|
assert_eq!(signer_info.signers.len(), 0);
|
|
|
|
|
2020-09-21 20:53:15 -07:00
|
|
|
let signer_info = default_signer
|
|
|
|
.generate_unique_signers(vec![None, None], &matches, &mut None)
|
|
|
|
.unwrap();
|
2020-02-24 16:03:30 -08:00
|
|
|
assert_eq!(signer_info.signers.len(), 1);
|
|
|
|
assert_eq!(signer_info.index_of(None), Some(0));
|
2020-10-19 12:23:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
signer_info.index_of(Some(solana_sdk::pubkey::new_rand())),
|
|
|
|
None
|
|
|
|
);
|
2020-02-24 16:03:30 -08:00
|
|
|
|
|
|
|
let keypair0 = keypair_from_seed(&[1u8; 32]).unwrap();
|
|
|
|
let keypair0_pubkey = keypair0.pubkey();
|
|
|
|
let keypair0_clone = keypair_from_seed(&[1u8; 32]).unwrap();
|
|
|
|
let keypair0_clone_pubkey = keypair0.pubkey();
|
|
|
|
let signers = vec![None, Some(keypair0.into()), Some(keypair0_clone.into())];
|
2020-09-21 20:53:15 -07:00
|
|
|
let signer_info = default_signer
|
|
|
|
.generate_unique_signers(signers, &matches, &mut None)
|
|
|
|
.unwrap();
|
2020-02-24 16:03:30 -08:00
|
|
|
assert_eq!(signer_info.signers.len(), 2);
|
|
|
|
assert_eq!(signer_info.index_of(None), Some(0));
|
|
|
|
assert_eq!(signer_info.index_of(Some(keypair0_pubkey)), Some(1));
|
|
|
|
assert_eq!(signer_info.index_of(Some(keypair0_clone_pubkey)), Some(1));
|
|
|
|
|
|
|
|
let keypair0 = keypair_from_seed(&[1u8; 32]).unwrap();
|
|
|
|
let keypair0_pubkey = keypair0.pubkey();
|
|
|
|
let keypair0_clone = keypair_from_seed(&[1u8; 32]).unwrap();
|
|
|
|
let signers = vec![Some(keypair0.into()), Some(keypair0_clone.into())];
|
2020-09-21 20:53:15 -07:00
|
|
|
let signer_info = default_signer
|
|
|
|
.generate_unique_signers(signers, &matches, &mut None)
|
|
|
|
.unwrap();
|
2020-02-24 16:03:30 -08:00
|
|
|
assert_eq!(signer_info.signers.len(), 1);
|
|
|
|
assert_eq!(signer_info.index_of(Some(keypair0_pubkey)), Some(0));
|
|
|
|
|
|
|
|
// Signers with the same pubkey are not distinct
|
|
|
|
let keypair0 = keypair_from_seed(&[2u8; 32]).unwrap();
|
|
|
|
let keypair0_pubkey = keypair0.pubkey();
|
|
|
|
let keypair1 = keypair_from_seed(&[3u8; 32]).unwrap();
|
|
|
|
let keypair1_pubkey = keypair1.pubkey();
|
|
|
|
let message = vec![0, 1, 2, 3];
|
|
|
|
let presigner0 = Presigner::new(&keypair0.pubkey(), &keypair0.sign_message(&message));
|
|
|
|
let presigner0_pubkey = presigner0.pubkey();
|
|
|
|
let presigner1 = Presigner::new(&keypair1.pubkey(), &keypair1.sign_message(&message));
|
|
|
|
let presigner1_pubkey = presigner1.pubkey();
|
|
|
|
let signers = vec![
|
|
|
|
Some(keypair0.into()),
|
|
|
|
Some(presigner0.into()),
|
|
|
|
Some(presigner1.into()),
|
|
|
|
Some(keypair1.into()),
|
|
|
|
];
|
2020-09-21 20:53:15 -07:00
|
|
|
let signer_info = default_signer
|
|
|
|
.generate_unique_signers(signers, &matches, &mut None)
|
|
|
|
.unwrap();
|
2020-02-24 16:03:30 -08:00
|
|
|
assert_eq!(signer_info.signers.len(), 2);
|
|
|
|
assert_eq!(signer_info.index_of(Some(keypair0_pubkey)), Some(0));
|
|
|
|
assert_eq!(signer_info.index_of(Some(keypair1_pubkey)), Some(1));
|
|
|
|
assert_eq!(signer_info.index_of(Some(presigner0_pubkey)), Some(0));
|
|
|
|
assert_eq!(signer_info.index_of(Some(presigner1_pubkey)), Some(1));
|
|
|
|
}
|
|
|
|
|
2018-09-14 01:59:09 -07:00
|
|
|
#[test]
|
2020-05-15 09:35:43 -07:00
|
|
|
#[allow(clippy::cognitive_complexity)]
|
2019-10-04 15:13:21 -07:00
|
|
|
fn test_cli_parse_command() {
|
2021-07-28 08:43:32 -07:00
|
|
|
let test_commands = get_clap_app("test", "desc", "version");
|
2019-05-09 19:31:42 -07:00
|
|
|
|
2020-10-19 12:12:08 -07:00
|
|
|
let pubkey = solana_sdk::pubkey::new_rand();
|
2022-12-06 06:30:06 -08:00
|
|
|
let pubkey_string = format!("{pubkey}");
|
2018-09-14 01:59:09 -07:00
|
|
|
|
2020-09-21 20:53:15 -07:00
|
|
|
let default_keypair = Keypair::new();
|
|
|
|
let keypair_file = make_tmp_path("keypair_file");
|
|
|
|
write_keypair_file(&default_keypair, &keypair_file).unwrap();
|
|
|
|
let keypair = read_keypair_file(&keypair_file).unwrap();
|
2021-05-28 00:42:55 -07:00
|
|
|
let default_signer = DefaultSigner::new("", &keypair_file);
|
2018-09-19 12:44:16 -07:00
|
|
|
// Test Airdrop Subcommand
|
2020-02-16 10:41:00 -08:00
|
|
|
let test_airdrop =
|
|
|
|
test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "airdrop", "50", &pubkey_string]);
|
2018-09-14 01:59:09 -07:00
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_airdrop, &default_signer, &mut None).unwrap(),
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Airdrop {
|
2020-02-16 10:41:00 -08:00
|
|
|
pubkey: Some(pubkey),
|
2020-02-15 11:53:52 -08:00
|
|
|
lamports: 50_000_000_000,
|
2019-10-21 16:08:09 -07:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-08-29 20:45:53 -07:00
|
|
|
}
|
2018-09-14 01:59:09 -07:00
|
|
|
);
|
|
|
|
|
2019-08-08 17:10:09 -07:00
|
|
|
// Test Balance Subcommand, incl pubkey and keypair-file inputs
|
|
|
|
let test_balance = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"balance",
|
|
|
|
&keypair.pubkey().to_string(),
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_balance, &default_signer, &mut None).unwrap(),
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Balance {
|
|
|
|
pubkey: Some(keypair.pubkey()),
|
2020-05-11 16:07:40 -07:00
|
|
|
use_lamports_unit: false,
|
2019-10-21 16:08:09 -07:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-09-10 12:36:59 -07:00
|
|
|
}
|
2019-08-08 17:10:09 -07:00
|
|
|
);
|
2019-09-10 12:36:59 -07:00
|
|
|
let test_balance = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"balance",
|
|
|
|
&keypair_file,
|
|
|
|
"--lamports",
|
|
|
|
]);
|
2019-08-08 17:10:09 -07:00
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_balance, &default_signer, &mut None).unwrap(),
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Balance {
|
|
|
|
pubkey: Some(keypair.pubkey()),
|
2020-05-11 16:07:40 -07:00
|
|
|
use_lamports_unit: true,
|
2019-10-21 16:08:09 -07:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-10-21 16:08:09 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
let test_balance =
|
|
|
|
test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "balance", "--lamports"]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_balance, &default_signer, &mut None).unwrap(),
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Balance {
|
|
|
|
pubkey: None,
|
2020-05-11 16:07:40 -07:00
|
|
|
use_lamports_unit: true,
|
2019-10-21 16:08:09 -07:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
|
2019-09-10 12:36:59 -07:00
|
|
|
}
|
2019-08-08 17:10:09 -07:00
|
|
|
);
|
|
|
|
|
2018-09-19 12:44:16 -07:00
|
|
|
// Test Confirm Subcommand
|
2020-05-15 09:35:43 -07:00
|
|
|
let signature = Signature::new(&[1; 64]);
|
2022-12-06 06:30:06 -08:00
|
|
|
let signature_string = format!("{signature:?}");
|
2018-09-14 01:59:09 -07:00
|
|
|
let test_confirm =
|
|
|
|
test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "confirm", &signature_string]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_confirm, &default_signer, &mut None).unwrap(),
|
2019-10-21 16:08:09 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Confirm(signature),
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-10-21 16:08:09 -07:00
|
|
|
}
|
2018-09-14 01:59:09 -07:00
|
|
|
);
|
2018-09-19 12:44:16 -07:00
|
|
|
let test_bad_signature = test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "confirm", "deadbeef"]);
|
2020-09-21 20:53:15 -07:00
|
|
|
assert!(parse_command(&test_bad_signature, &default_signer, &mut None).is_err());
|
2018-09-19 12:44:16 -07:00
|
|
|
|
2019-12-14 04:38:24 -08:00
|
|
|
// Test CreateAddressWithSeed
|
2020-10-19 12:12:08 -07:00
|
|
|
let from_pubkey = Some(solana_sdk::pubkey::new_rand());
|
2019-12-14 04:38:24 -08:00
|
|
|
let from_str = from_pubkey.unwrap().to_string();
|
|
|
|
for (name, program_id) in &[
|
2021-06-15 09:04:00 -07:00
|
|
|
("STAKE", stake::program::id()),
|
2019-12-14 04:38:24 -08:00
|
|
|
("VOTE", solana_vote_program::id()),
|
2020-03-19 09:36:53 -07:00
|
|
|
("NONCE", system_program::id()),
|
2019-12-14 04:38:24 -08:00
|
|
|
] {
|
|
|
|
let test_create_address_with_seed = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"create-address-with-seed",
|
|
|
|
"seed",
|
|
|
|
name,
|
|
|
|
"--from",
|
|
|
|
&from_str,
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_create_address_with_seed, &default_signer, &mut None).unwrap(),
|
2019-12-14 04:38:24 -08:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::CreateAddressWithSeed {
|
|
|
|
from_pubkey,
|
|
|
|
seed: "seed".to_string(),
|
|
|
|
program_id: *program_id
|
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![],
|
2019-12-14 04:38:24 -08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
let test_create_address_with_seed = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"create-address-with-seed",
|
|
|
|
"seed",
|
|
|
|
"STAKE",
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_create_address_with_seed, &default_signer, &mut None).unwrap(),
|
2019-12-14 04:38:24 -08:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::CreateAddressWithSeed {
|
|
|
|
from_pubkey: None,
|
|
|
|
seed: "seed".to_string(),
|
2021-06-15 09:04:00 -07:00
|
|
|
program_id: stake::program::id(),
|
2019-12-14 04:38:24 -08:00
|
|
|
},
|
2020-03-08 23:02:24 -07:00
|
|
|
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
|
2019-12-14 04:38:24 -08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2021-04-14 22:19:01 -07:00
|
|
|
// Test ResolveSigner Subcommand, SignerSource::Filepath
|
2020-03-14 20:48:41 -07:00
|
|
|
let test_resolve_signer =
|
|
|
|
test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "resolve-signer", &keypair_file]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_resolve_signer, &default_signer, &mut None).unwrap(),
|
2020-03-14 20:48:41 -07:00
|
|
|
CliCommandInfo {
|
2022-10-17 08:19:12 -07:00
|
|
|
command: CliCommand::ResolveSigner(Some(keypair_file.clone())),
|
2020-03-14 20:48:41 -07:00
|
|
|
signers: vec![],
|
|
|
|
}
|
|
|
|
);
|
2021-04-14 22:19:01 -07:00
|
|
|
// Test ResolveSigner Subcommand, SignerSource::Pubkey (Presigner)
|
2020-03-14 20:48:41 -07:00
|
|
|
let test_resolve_signer =
|
|
|
|
test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "resolve-signer", &pubkey_string]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_resolve_signer, &default_signer, &mut None).unwrap(),
|
2020-03-14 20:48:41 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::ResolveSigner(Some(pubkey.to_string())),
|
|
|
|
signers: vec![],
|
|
|
|
}
|
|
|
|
);
|
2022-10-17 08:19:12 -07:00
|
|
|
|
|
|
|
// Test SignOffchainMessage
|
|
|
|
let test_sign_offchain = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"sign-offchain-message",
|
|
|
|
"Test Message",
|
|
|
|
]);
|
|
|
|
let message = OffchainMessage::new(0, b"Test Message").unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
parse_command(&test_sign_offchain, &default_signer, &mut None).unwrap(),
|
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::SignOffchainMessage {
|
|
|
|
message: message.clone()
|
|
|
|
},
|
|
|
|
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
// Test VerifyOffchainSignature
|
|
|
|
let signature = keypair.sign_message(&message.serialize().unwrap());
|
|
|
|
let test_verify_offchain = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"verify-offchain-signature",
|
|
|
|
"Test Message",
|
|
|
|
&signature.to_string(),
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
|
|
|
parse_command(&test_verify_offchain, &default_signer, &mut None).unwrap(),
|
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::VerifyOffchainSignature {
|
|
|
|
signer_pubkey: None,
|
|
|
|
signature,
|
|
|
|
message
|
|
|
|
},
|
|
|
|
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
|
|
|
|
}
|
|
|
|
);
|
2018-09-14 01:59:09 -07:00
|
|
|
}
|
2019-01-13 23:10:03 -08:00
|
|
|
|
2018-09-14 01:59:09 -07:00
|
|
|
#[test]
|
2020-05-15 09:35:43 -07:00
|
|
|
#[allow(clippy::cognitive_complexity)]
|
2019-10-04 15:13:21 -07:00
|
|
|
fn test_cli_process_command() {
|
2019-01-13 23:10:03 -08:00
|
|
|
// Success cases
|
2020-12-13 17:26:34 -08:00
|
|
|
let mut config = CliConfig {
|
2021-04-22 18:35:12 -07:00
|
|
|
rpc_client: Some(Arc::new(RpcClient::new_mock("succeeds".to_string()))),
|
2020-12-13 17:26:34 -08:00
|
|
|
json_rpc_url: "http://127.0.0.1:8899".to_string(),
|
|
|
|
..CliConfig::default()
|
|
|
|
};
|
2018-11-12 12:48:59 -08:00
|
|
|
|
2019-01-13 23:10:03 -08:00
|
|
|
let keypair = Keypair::new();
|
|
|
|
let pubkey = keypair.pubkey().to_string();
|
2020-02-24 16:03:30 -08:00
|
|
|
config.signers = vec![&keypair];
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Address;
|
2019-01-13 23:10:03 -08:00
|
|
|
assert_eq!(process_command(&config).unwrap(), pubkey);
|
2018-09-14 01:59:09 -07:00
|
|
|
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Balance {
|
2019-10-21 16:08:09 -07:00
|
|
|
pubkey: None,
|
2019-09-10 12:36:59 -07:00
|
|
|
use_lamports_unit: true,
|
|
|
|
};
|
2019-03-20 09:44:16 -07:00
|
|
|
assert_eq!(process_command(&config).unwrap(), "50 lamports");
|
2018-09-14 01:59:09 -07:00
|
|
|
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Balance {
|
2019-10-21 16:08:09 -07:00
|
|
|
pubkey: None,
|
2019-09-10 12:36:59 -07:00
|
|
|
use_lamports_unit: false,
|
|
|
|
};
|
2019-10-29 19:03:48 -07:00
|
|
|
assert_eq!(process_command(&config).unwrap(), "0.00000005 SOL");
|
2019-09-10 12:36:59 -07:00
|
|
|
|
2019-01-13 23:10:03 -08:00
|
|
|
let good_signature = Signature::new(&bs58::decode(SIGNATURE).into_vec().unwrap());
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Confirm(good_signature);
|
2021-01-20 17:32:48 -08:00
|
|
|
assert_eq!(
|
|
|
|
process_command(&config).unwrap(),
|
|
|
|
format!("{:?}", TransactionConfirmationStatus::Finalized)
|
|
|
|
);
|
2018-09-14 01:59:09 -07:00
|
|
|
|
2019-11-06 06:47:34 -08:00
|
|
|
let bob_keypair = Keypair::new();
|
|
|
|
let bob_pubkey = bob_keypair.pubkey();
|
2020-03-19 01:58:52 -07:00
|
|
|
let identity_keypair = Keypair::new();
|
2019-10-21 16:08:09 -07:00
|
|
|
config.command = CliCommand::CreateVoteAccount {
|
2020-07-13 20:27:41 -07:00
|
|
|
vote_account: 1,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed: None,
|
2020-03-19 01:58:52 -07:00
|
|
|
identity_account: 2,
|
2019-10-21 16:08:09 -07:00
|
|
|
authorized_voter: Some(bob_pubkey),
|
2021-09-02 17:22:33 -07:00
|
|
|
authorized_withdrawer: bob_pubkey,
|
2019-10-21 16:08:09 -07:00
|
|
|
commission: 0,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: false,
|
|
|
|
dump_transaction_message: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-10-21 16:08:09 -07:00
|
|
|
};
|
2020-03-19 01:58:52 -07:00
|
|
|
config.signers = vec![&keypair, &bob_keypair, &identity_keypair];
|
2020-04-06 18:27:37 -07:00
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
2019-05-09 19:31:42 -07:00
|
|
|
|
2021-09-15 12:59:05 -07:00
|
|
|
let vote_account_info_response = json!(Response {
|
2022-05-11 21:17:21 -07:00
|
|
|
context: RpcResponseContext {
|
|
|
|
slot: 1,
|
|
|
|
api_version: None
|
|
|
|
},
|
2021-09-15 12:59:05 -07:00
|
|
|
value: json!({
|
|
|
|
"data": ["KLUv/QBYNQIAtAIBAAAAbnoc3Smwt4/ROvTFWY/v9O8qlxZuPKby5Pv8zYBQW/EFAAEAAB8ACQD6gx92zAiAAecDP4B2XeEBSIx7MQeung==", "base64+zstd"],
|
|
|
|
"lamports": 42,
|
|
|
|
"owner": "Vote111111111111111111111111111111111111111",
|
|
|
|
"executable": false,
|
|
|
|
"rentEpoch": 1,
|
|
|
|
}),
|
|
|
|
});
|
|
|
|
let mut mocks = HashMap::new();
|
|
|
|
mocks.insert(RpcRequest::GetAccountInfo, vote_account_info_response);
|
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
let mut vote_config = CliConfig {
|
|
|
|
rpc_client: Some(Arc::new(rpc_client)),
|
|
|
|
json_rpc_url: "http://127.0.0.1:8899".to_string(),
|
|
|
|
..CliConfig::default()
|
|
|
|
};
|
|
|
|
let current_authority = keypair_from_seed(&[5; 32]).unwrap();
|
2020-10-19 12:12:08 -07:00
|
|
|
let new_authorized_pubkey = solana_sdk::pubkey::new_rand();
|
2021-09-15 12:59:05 -07:00
|
|
|
vote_config.signers = vec![¤t_authority];
|
|
|
|
vote_config.command = CliCommand::VoteAuthorize {
|
2019-12-12 15:04:03 -08:00
|
|
|
vote_account_pubkey: bob_pubkey,
|
|
|
|
new_authorized_pubkey,
|
2021-09-15 12:59:05 -07:00
|
|
|
vote_authorize: VoteAuthorize::Withdrawer,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: false,
|
|
|
|
dump_transaction_message: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: 0,
|
2021-07-15 15:45:03 -07:00
|
|
|
authorized: 0,
|
|
|
|
new_authorized: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-12-12 15:04:03 -08:00
|
|
|
};
|
2021-09-15 12:59:05 -07:00
|
|
|
let result = process_command(&vote_config);
|
2020-04-06 18:27:37 -07:00
|
|
|
assert!(result.is_ok());
|
2019-12-12 15:04:03 -08:00
|
|
|
|
2020-03-19 01:58:52 -07:00
|
|
|
let new_identity_keypair = Keypair::new();
|
|
|
|
config.signers = vec![&keypair, &bob_keypair, &new_identity_keypair];
|
2019-12-12 15:04:03 -08:00
|
|
|
config.command = CliCommand::VoteUpdateValidator {
|
|
|
|
vote_account_pubkey: bob_pubkey,
|
2020-03-19 01:58:52 -07:00
|
|
|
new_identity_account: 2,
|
2020-07-13 20:49:59 -07:00
|
|
|
withdraw_authority: 1,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: false,
|
|
|
|
dump_transaction_message: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-12-12 15:04:03 -08:00
|
|
|
};
|
2020-04-06 18:27:37 -07:00
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
2019-05-09 19:31:42 -07:00
|
|
|
|
2019-11-06 06:47:34 -08:00
|
|
|
let bob_keypair = Keypair::new();
|
|
|
|
let bob_pubkey = bob_keypair.pubkey();
|
2020-10-19 12:12:08 -07:00
|
|
|
let custodian = solana_sdk::pubkey::new_rand();
|
2019-10-21 16:08:09 -07:00
|
|
|
config.command = CliCommand::CreateStakeAccount {
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_account: 1,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed: None,
|
2019-10-21 16:08:09 -07:00
|
|
|
staker: None,
|
|
|
|
withdrawer: None,
|
2021-07-15 15:45:03 -07:00
|
|
|
withdrawer_signer: None,
|
2019-11-25 15:11:55 -08:00
|
|
|
lockup: Lockup {
|
|
|
|
epoch: 0,
|
2019-12-19 14:37:47 -08:00
|
|
|
unix_timestamp: 0,
|
2019-11-25 15:11:55 -08:00
|
|
|
custodian,
|
|
|
|
},
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount::Some(30),
|
2020-02-12 22:00:28 -08:00
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2020-03-11 11:14:15 -07:00
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
2020-02-12 22:00:28 -08:00
|
|
|
nonce_account: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
|
|
|
from: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-10-21 16:08:09 -07:00
|
|
|
};
|
2020-02-24 16:03:30 -08:00
|
|
|
config.signers = vec![&keypair, &bob_keypair];
|
2020-04-06 18:27:37 -07:00
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
2019-03-06 20:29:08 -08:00
|
|
|
|
2020-10-19 12:12:08 -07:00
|
|
|
let stake_account_pubkey = solana_sdk::pubkey::new_rand();
|
|
|
|
let to_pubkey = solana_sdk::pubkey::new_rand();
|
2020-01-15 13:32:06 -08:00
|
|
|
config.command = CliCommand::WithdrawStake {
|
2020-06-10 21:02:04 -07:00
|
|
|
stake_account_pubkey,
|
2020-01-15 13:32:06 -08:00
|
|
|
destination_account_pubkey: to_pubkey,
|
2021-04-26 08:33:56 -07:00
|
|
|
amount: SpendAmount::All,
|
2020-02-24 16:03:30 -08:00
|
|
|
withdraw_authority: 0,
|
2020-04-22 15:00:18 -07:00
|
|
|
custodian: None,
|
2020-02-12 22:00:28 -08:00
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2020-03-11 11:14:15 -07:00
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
2020-02-12 22:00:28 -08:00
|
|
|
nonce_account: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-04-21 11:05:05 -07:00
|
|
|
seed: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-01-15 13:32:06 -08:00
|
|
|
};
|
2020-02-24 16:03:30 -08:00
|
|
|
config.signers = vec![&keypair];
|
2020-04-06 18:27:37 -07:00
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
2019-06-21 22:28:34 -07:00
|
|
|
|
2020-10-19 12:12:08 -07:00
|
|
|
let stake_account_pubkey = solana_sdk::pubkey::new_rand();
|
2019-11-25 21:09:57 -08:00
|
|
|
config.command = CliCommand::DeactivateStake {
|
2020-06-10 21:02:04 -07:00
|
|
|
stake_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority: 0,
|
2019-11-25 21:09:57 -08:00
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2022-03-25 09:11:51 -07:00
|
|
|
deactivate_delinquent: false,
|
2020-01-30 08:21:32 -08:00
|
|
|
blockhash_query: BlockhashQuery::default(),
|
2019-12-27 12:35:49 -08:00
|
|
|
nonce_account: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-04-21 11:05:05 -07:00
|
|
|
seed: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-11-25 21:09:57 -08:00
|
|
|
};
|
2020-04-06 18:27:37 -07:00
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
2020-02-02 21:20:28 -08:00
|
|
|
|
2020-10-19 12:12:08 -07:00
|
|
|
let stake_account_pubkey = solana_sdk::pubkey::new_rand();
|
2020-02-02 21:20:28 -08:00
|
|
|
let split_stake_account = Keypair::new();
|
|
|
|
config.command = CliCommand::SplitStake {
|
2020-06-10 21:02:04 -07:00
|
|
|
stake_account_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
stake_authority: 0,
|
2020-02-02 21:20:28 -08:00
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2020-02-02 21:20:28 -08:00
|
|
|
blockhash_query: BlockhashQuery::default(),
|
|
|
|
nonce_account: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
split_stake_account: 1,
|
2020-02-02 21:20:28 -08:00
|
|
|
seed: None,
|
2020-05-14 11:24:14 -07:00
|
|
|
lamports: 30,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-02-02 21:20:28 -08:00
|
|
|
};
|
2020-02-24 16:03:30 -08:00
|
|
|
config.signers = vec![&keypair, &split_stake_account];
|
2020-04-06 18:27:37 -07:00
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
2019-06-21 23:45:03 -07:00
|
|
|
|
2020-10-19 12:12:08 -07:00
|
|
|
let stake_account_pubkey = solana_sdk::pubkey::new_rand();
|
|
|
|
let source_stake_account_pubkey = solana_sdk::pubkey::new_rand();
|
2020-06-10 21:02:04 -07:00
|
|
|
let merge_stake_account = Keypair::new();
|
|
|
|
config.command = CliCommand::MergeStake {
|
|
|
|
stake_account_pubkey,
|
|
|
|
source_stake_account_pubkey,
|
|
|
|
stake_authority: 1,
|
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2020-06-10 21:02:04 -07:00
|
|
|
blockhash_query: BlockhashQuery::default(),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-06-10 21:02:04 -07:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-06-10 21:02:04 -07:00
|
|
|
};
|
|
|
|
config.signers = vec![&keypair, &merge_stake_account];
|
|
|
|
let result = process_command(&config);
|
2021-04-26 08:33:56 -07:00
|
|
|
assert!(result.is_ok());
|
2020-06-10 21:02:04 -07:00
|
|
|
|
2020-06-17 11:18:48 -07:00
|
|
|
config.command = CliCommand::GetSlot;
|
2019-08-05 13:17:03 -07:00
|
|
|
assert_eq!(process_command(&config).unwrap(), "0");
|
|
|
|
|
2020-06-17 11:18:48 -07:00
|
|
|
config.command = CliCommand::GetTransactionCount;
|
2019-01-13 23:10:03 -08:00
|
|
|
assert_eq!(process_command(&config).unwrap(), "1234");
|
|
|
|
|
2020-03-08 23:02:24 -07:00
|
|
|
// CreateAddressWithSeed
|
2020-10-19 12:12:08 -07:00
|
|
|
let from_pubkey = solana_sdk::pubkey::new_rand();
|
2020-03-08 23:02:24 -07:00
|
|
|
config.signers = vec![];
|
|
|
|
config.command = CliCommand::CreateAddressWithSeed {
|
|
|
|
from_pubkey: Some(from_pubkey),
|
|
|
|
seed: "seed".to_string(),
|
2021-06-15 09:04:00 -07:00
|
|
|
program_id: stake::program::id(),
|
2020-03-08 23:02:24 -07:00
|
|
|
};
|
|
|
|
let address = process_command(&config);
|
|
|
|
let expected_address =
|
2021-06-15 09:04:00 -07:00
|
|
|
Pubkey::create_with_seed(&from_pubkey, "seed", &stake::program::id()).unwrap();
|
2020-03-08 23:02:24 -07:00
|
|
|
assert_eq!(address.unwrap(), expected_address.to_string());
|
|
|
|
|
2019-01-13 23:10:03 -08:00
|
|
|
// Need airdrop cases
|
2020-10-19 12:12:08 -07:00
|
|
|
let to = solana_sdk::pubkey::new_rand();
|
2020-03-08 23:02:24 -07:00
|
|
|
config.signers = vec![&keypair];
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Airdrop {
|
2020-02-16 10:41:00 -08:00
|
|
|
pubkey: Some(to),
|
2019-08-29 20:45:53 -07:00
|
|
|
lamports: 50,
|
|
|
|
};
|
2019-08-16 15:23:59 -07:00
|
|
|
assert!(process_command(&config).is_ok());
|
2018-11-14 18:57:34 -08:00
|
|
|
|
2019-04-05 19:56:17 -07:00
|
|
|
// sig_not_found case
|
2021-04-22 18:35:12 -07:00
|
|
|
config.rpc_client = Some(Arc::new(RpcClient::new_mock("sig_not_found".to_string())));
|
2019-03-17 00:40:45 -07:00
|
|
|
let missing_signature = Signature::new(&bs58::decode("5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW").into_vec().unwrap());
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Confirm(missing_signature);
|
2019-03-17 00:40:45 -07:00
|
|
|
assert_eq!(process_command(&config).unwrap(), "Not found");
|
|
|
|
|
2019-04-05 19:56:17 -07:00
|
|
|
// Tx error case
|
2021-04-22 18:35:12 -07:00
|
|
|
config.rpc_client = Some(Arc::new(RpcClient::new_mock("account_in_use".to_string())));
|
2019-04-05 19:56:17 -07:00
|
|
|
let any_signature = Signature::new(&bs58::decode(SIGNATURE).into_vec().unwrap());
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Confirm(any_signature);
|
2019-04-05 19:56:17 -07:00
|
|
|
assert_eq!(
|
|
|
|
process_command(&config).unwrap(),
|
2020-04-16 20:02:02 -07:00
|
|
|
format!("Transaction failed: {}", TransactionError::AccountInUse)
|
2019-04-05 19:56:17 -07:00
|
|
|
);
|
|
|
|
|
2019-03-17 00:40:45 -07:00
|
|
|
// Failure cases
|
2021-04-22 18:35:12 -07:00
|
|
|
config.rpc_client = Some(Arc::new(RpcClient::new_mock("fails".to_string())));
|
2019-01-13 23:10:03 -08:00
|
|
|
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Airdrop {
|
2020-02-16 10:41:00 -08:00
|
|
|
pubkey: None,
|
2019-08-29 20:45:53 -07:00
|
|
|
lamports: 50,
|
|
|
|
};
|
2019-01-13 23:10:03 -08:00
|
|
|
assert!(process_command(&config).is_err());
|
2018-09-25 11:45:25 -07:00
|
|
|
|
2019-10-04 15:13:21 -07:00
|
|
|
config.command = CliCommand::Balance {
|
2019-10-21 16:08:09 -07:00
|
|
|
pubkey: None,
|
2019-09-10 12:36:59 -07:00
|
|
|
use_lamports_unit: false,
|
|
|
|
};
|
2019-01-13 23:10:03 -08:00
|
|
|
assert!(process_command(&config).is_err());
|
|
|
|
|
2019-11-06 06:47:34 -08:00
|
|
|
let bob_keypair = Keypair::new();
|
2020-03-19 01:58:52 -07:00
|
|
|
let identity_keypair = Keypair::new();
|
2019-10-21 16:08:09 -07:00
|
|
|
config.command = CliCommand::CreateVoteAccount {
|
2020-07-13 20:27:41 -07:00
|
|
|
vote_account: 1,
|
2020-01-09 15:22:48 -08:00
|
|
|
seed: None,
|
2020-03-19 01:58:52 -07:00
|
|
|
identity_account: 2,
|
2019-10-21 16:08:09 -07:00
|
|
|
authorized_voter: Some(bob_pubkey),
|
2021-09-02 17:22:33 -07:00
|
|
|
authorized_withdrawer: bob_pubkey,
|
2019-10-21 16:08:09 -07:00
|
|
|
commission: 0,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: false,
|
|
|
|
dump_transaction_message: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-10-21 16:08:09 -07:00
|
|
|
};
|
2020-03-19 01:58:52 -07:00
|
|
|
config.signers = vec![&keypair, &bob_keypair, &identity_keypair];
|
2019-03-06 20:29:08 -08:00
|
|
|
assert!(process_command(&config).is_err());
|
|
|
|
|
2019-12-12 15:04:03 -08:00
|
|
|
config.command = CliCommand::VoteAuthorize {
|
|
|
|
vote_account_pubkey: bob_pubkey,
|
|
|
|
new_authorized_pubkey: bob_pubkey,
|
|
|
|
vote_authorize: VoteAuthorize::Voter,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: false,
|
|
|
|
dump_transaction_message: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: 0,
|
2021-07-15 15:45:03 -07:00
|
|
|
authorized: 0,
|
|
|
|
new_authorized: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-12-12 15:04:03 -08:00
|
|
|
};
|
|
|
|
assert!(process_command(&config).is_err());
|
|
|
|
|
|
|
|
config.command = CliCommand::VoteUpdateValidator {
|
|
|
|
vote_account_pubkey: bob_pubkey,
|
2020-03-19 01:58:52 -07:00
|
|
|
new_identity_account: 1,
|
2020-07-13 20:49:59 -07:00
|
|
|
withdraw_authority: 1,
|
2021-12-06 14:54:50 -08:00
|
|
|
sign_only: false,
|
|
|
|
dump_transaction_message: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-12-06 14:54:50 -08:00
|
|
|
fee_payer: 0,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2019-12-12 15:04:03 -08:00
|
|
|
};
|
2019-03-06 20:29:08 -08:00
|
|
|
assert!(process_command(&config).is_err());
|
|
|
|
|
2020-06-17 11:18:48 -07:00
|
|
|
config.command = CliCommand::GetSlot;
|
2019-08-05 13:17:03 -07:00
|
|
|
assert!(process_command(&config).is_err());
|
|
|
|
|
2020-06-17 11:18:48 -07:00
|
|
|
config.command = CliCommand::GetTransactionCount;
|
2019-01-13 23:10:03 -08:00
|
|
|
assert!(process_command(&config).is_err());
|
2022-10-17 08:19:12 -07:00
|
|
|
|
|
|
|
let message = OffchainMessage::new(0, b"Test Message").unwrap();
|
|
|
|
config.command = CliCommand::SignOffchainMessage {
|
|
|
|
message: message.clone(),
|
|
|
|
};
|
|
|
|
config.signers = vec![&keypair];
|
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
|
|
|
|
|
|
|
config.command = CliCommand::VerifyOffchainSignature {
|
|
|
|
signer_pubkey: None,
|
|
|
|
signature: result.unwrap().parse().unwrap(),
|
|
|
|
message,
|
|
|
|
};
|
|
|
|
config.signers = vec![&keypair];
|
|
|
|
let result = process_command(&config);
|
|
|
|
assert!(result.is_ok());
|
2018-09-14 01:59:09 -07:00
|
|
|
}
|
2019-01-17 08:49:16 -08:00
|
|
|
|
2020-02-07 11:16:35 -08:00
|
|
|
#[test]
|
|
|
|
fn test_parse_transfer_subcommand() {
|
2021-07-28 08:43:32 -07:00
|
|
|
let test_commands = get_clap_app("test", "desc", "version");
|
2020-02-07 11:16:35 -08:00
|
|
|
|
2020-02-24 16:03:30 -08:00
|
|
|
let default_keypair = Keypair::new();
|
|
|
|
let default_keypair_file = make_tmp_path("keypair_file");
|
|
|
|
write_keypair_file(&default_keypair, &default_keypair_file).unwrap();
|
2021-05-28 00:42:55 -07:00
|
|
|
let default_signer = DefaultSigner::new("", &default_keypair_file);
|
2020-02-24 16:03:30 -08:00
|
|
|
|
2020-02-15 11:53:52 -08:00
|
|
|
//Test Transfer Subcommand, SOL
|
2020-02-07 11:16:35 -08:00
|
|
|
let from_keypair = keypair_from_seed(&[0u8; 32]).unwrap();
|
|
|
|
let from_pubkey = from_keypair.pubkey();
|
|
|
|
let from_string = from_pubkey.to_string();
|
|
|
|
let to_keypair = keypair_from_seed(&[1u8; 32]).unwrap();
|
|
|
|
let to_pubkey = to_keypair.pubkey();
|
|
|
|
let to_string = to_pubkey.to_string();
|
|
|
|
let test_transfer = test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "transfer", &to_string, "42"]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_transfer, &default_signer, &mut None).unwrap(),
|
2020-02-07 11:16:35 -08:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Transfer {
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount::Some(42_000_000_000),
|
|
|
|
to: to_pubkey,
|
|
|
|
from: 0,
|
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: false,
|
2020-05-14 11:24:14 -07:00
|
|
|
no_wait: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-05-14 11:24:14 -07:00
|
|
|
fee_payer: 0,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed: None,
|
|
|
|
derived_address_program_id: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-05-14 11:24:14 -07:00
|
|
|
},
|
|
|
|
signers: vec![read_keypair_file(&default_keypair_file).unwrap().into()],
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
// Test Transfer ALL
|
|
|
|
let test_transfer = test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["test", "transfer", &to_string, "ALL"]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_transfer, &default_signer, &mut None).unwrap(),
|
2020-05-14 11:24:14 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Transfer {
|
|
|
|
amount: SpendAmount::All,
|
2020-02-07 11:16:35 -08:00
|
|
|
to: to_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
from: 0,
|
2020-02-07 11:16:35 -08:00
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: false,
|
2020-04-08 22:46:19 -07:00
|
|
|
no_wait: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-04-08 22:46:19 -07:00
|
|
|
fee_payer: 0,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed: None,
|
|
|
|
derived_address_program_id: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-04-08 22:46:19 -07:00
|
|
|
},
|
|
|
|
signers: vec![read_keypair_file(&default_keypair_file).unwrap().into()],
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2021-03-22 11:10:44 -07:00
|
|
|
// Test Transfer no-wait and --allow-unfunded-recipient
|
2020-04-08 22:46:19 -07:00
|
|
|
let test_transfer = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"transfer",
|
|
|
|
"--no-wait",
|
2021-03-22 11:10:44 -07:00
|
|
|
"--allow-unfunded-recipient",
|
2020-04-08 22:46:19 -07:00
|
|
|
&to_string,
|
|
|
|
"42",
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_transfer, &default_signer, &mut None).unwrap(),
|
2020-04-08 22:46:19 -07:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Transfer {
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount::Some(42_000_000_000),
|
2020-04-08 22:46:19 -07:00
|
|
|
to: to_pubkey,
|
|
|
|
from: 0,
|
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: true,
|
2020-04-08 22:46:19 -07:00
|
|
|
no_wait: true,
|
2020-03-11 11:14:15 -07:00
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
2020-02-07 11:16:35 -08:00
|
|
|
nonce_account: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed: None,
|
|
|
|
derived_address_program_id: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-02-07 11:16:35 -08:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![read_keypair_file(&default_keypair_file).unwrap().into()],
|
2020-02-07 11:16:35 -08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
//Test Transfer Subcommand, offline sign
|
|
|
|
let blockhash = Hash::new(&[1u8; 32]);
|
|
|
|
let blockhash_string = blockhash.to_string();
|
|
|
|
let test_transfer = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"transfer",
|
|
|
|
&to_string,
|
|
|
|
"42",
|
|
|
|
"--blockhash",
|
|
|
|
&blockhash_string,
|
|
|
|
"--sign-only",
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_transfer, &default_signer, &mut None).unwrap(),
|
2020-02-07 11:16:35 -08:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Transfer {
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount::Some(42_000_000_000),
|
2020-02-07 11:16:35 -08:00
|
|
|
to: to_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
from: 0,
|
2020-02-07 11:16:35 -08:00
|
|
|
sign_only: true,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: false,
|
2020-04-08 22:46:19 -07:00
|
|
|
no_wait: false,
|
2020-03-11 11:14:15 -07:00
|
|
|
blockhash_query: BlockhashQuery::None(blockhash),
|
2020-02-07 11:16:35 -08:00
|
|
|
nonce_account: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed: None,
|
|
|
|
derived_address_program_id: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-02-07 11:16:35 -08:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![read_keypair_file(&default_keypair_file).unwrap().into()],
|
2020-02-07 11:16:35 -08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
//Test Transfer Subcommand, submit offline `from`
|
|
|
|
let from_sig = from_keypair.sign_message(&[0u8]);
|
2022-12-06 06:30:06 -08:00
|
|
|
let from_signer = format!("{from_pubkey}={from_sig}");
|
2020-02-07 11:16:35 -08:00
|
|
|
let test_transfer = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"transfer",
|
|
|
|
&to_string,
|
|
|
|
"42",
|
|
|
|
"--from",
|
|
|
|
&from_string,
|
|
|
|
"--fee-payer",
|
|
|
|
&from_string,
|
|
|
|
"--signer",
|
|
|
|
&from_signer,
|
|
|
|
"--blockhash",
|
|
|
|
&blockhash_string,
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_transfer, &default_signer, &mut None).unwrap(),
|
2020-02-07 11:16:35 -08:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Transfer {
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount::Some(42_000_000_000),
|
2020-02-07 11:16:35 -08:00
|
|
|
to: to_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
from: 0,
|
2020-02-07 11:16:35 -08:00
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: false,
|
2020-04-08 22:46:19 -07:00
|
|
|
no_wait: false,
|
2020-03-11 11:14:15 -07:00
|
|
|
blockhash_query: BlockhashQuery::FeeCalculator(
|
|
|
|
blockhash_query::Source::Cluster,
|
|
|
|
blockhash
|
|
|
|
),
|
2020-02-07 11:16:35 -08:00
|
|
|
nonce_account: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed: None,
|
|
|
|
derived_address_program_id: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-02-07 11:16:35 -08:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![Presigner::new(&from_pubkey, &from_sig).into()],
|
2020-02-07 11:16:35 -08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
//Test Transfer Subcommand, with nonce
|
2023-01-21 10:06:27 -08:00
|
|
|
let nonce_address = Pubkey::from([1u8; 32]);
|
2020-02-07 11:16:35 -08:00
|
|
|
let nonce_address_string = nonce_address.to_string();
|
|
|
|
let nonce_authority = keypair_from_seed(&[2u8; 32]).unwrap();
|
|
|
|
let nonce_authority_file = make_tmp_path("nonce_authority_file");
|
|
|
|
write_keypair_file(&nonce_authority, &nonce_authority_file).unwrap();
|
|
|
|
let test_transfer = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"transfer",
|
|
|
|
&to_string,
|
|
|
|
"42",
|
|
|
|
"--blockhash",
|
|
|
|
&blockhash_string,
|
|
|
|
"--nonce",
|
|
|
|
&nonce_address_string,
|
|
|
|
"--nonce-authority",
|
|
|
|
&nonce_authority_file,
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
2020-09-21 20:53:15 -07:00
|
|
|
parse_command(&test_transfer, &default_signer, &mut None).unwrap(),
|
2020-02-07 11:16:35 -08:00
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Transfer {
|
2020-05-14 11:24:14 -07:00
|
|
|
amount: SpendAmount::Some(42_000_000_000),
|
2020-02-07 11:16:35 -08:00
|
|
|
to: to_pubkey,
|
2020-02-24 16:03:30 -08:00
|
|
|
from: 0,
|
2020-02-07 11:16:35 -08:00
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: false,
|
2020-04-08 22:46:19 -07:00
|
|
|
no_wait: false,
|
2020-03-11 11:14:15 -07:00
|
|
|
blockhash_query: BlockhashQuery::FeeCalculator(
|
|
|
|
blockhash_query::Source::NonceAccount(nonce_address),
|
|
|
|
blockhash
|
|
|
|
),
|
2020-05-15 09:35:43 -07:00
|
|
|
nonce_account: Some(nonce_address),
|
2020-02-24 16:03:30 -08:00
|
|
|
nonce_authority: 1,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2020-02-24 16:03:30 -08:00
|
|
|
fee_payer: 0,
|
2021-02-17 23:08:12 -08:00
|
|
|
derived_address_seed: None,
|
|
|
|
derived_address_program_id: None,
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2020-02-07 11:16:35 -08:00
|
|
|
},
|
2020-02-24 16:03:30 -08:00
|
|
|
signers: vec![
|
|
|
|
read_keypair_file(&default_keypair_file).unwrap().into(),
|
|
|
|
read_keypair_file(&nonce_authority_file).unwrap().into()
|
|
|
|
],
|
2020-02-07 11:16:35 -08:00
|
|
|
}
|
|
|
|
);
|
2021-02-17 23:08:12 -08:00
|
|
|
|
|
|
|
//Test Transfer Subcommand, with seed
|
|
|
|
let derived_address_seed = "seed".to_string();
|
|
|
|
let derived_address_program_id = "STAKE";
|
|
|
|
let test_transfer = test_commands.clone().get_matches_from(vec![
|
|
|
|
"test",
|
|
|
|
"transfer",
|
|
|
|
&to_string,
|
|
|
|
"42",
|
|
|
|
"--derived-address-seed",
|
|
|
|
&derived_address_seed,
|
|
|
|
"--derived-address-program-id",
|
|
|
|
derived_address_program_id,
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
|
|
|
parse_command(&test_transfer, &default_signer, &mut None).unwrap(),
|
|
|
|
CliCommandInfo {
|
|
|
|
command: CliCommand::Transfer {
|
|
|
|
amount: SpendAmount::Some(42_000_000_000),
|
|
|
|
to: to_pubkey,
|
|
|
|
from: 0,
|
|
|
|
sign_only: false,
|
2021-03-12 18:37:39 -08:00
|
|
|
dump_transaction_message: false,
|
2021-03-22 11:10:44 -07:00
|
|
|
allow_unfunded_recipient: false,
|
2021-02-17 23:08:12 -08:00
|
|
|
no_wait: false,
|
|
|
|
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
nonce_account: None,
|
|
|
|
nonce_authority: 0,
|
2021-04-05 13:53:50 -07:00
|
|
|
memo: None,
|
2021-02-17 23:08:12 -08:00
|
|
|
fee_payer: 0,
|
|
|
|
derived_address_seed: Some(derived_address_seed),
|
2021-06-15 09:04:00 -07:00
|
|
|
derived_address_program_id: Some(stake::program::id()),
|
2022-08-02 20:23:05 -07:00
|
|
|
compute_unit_price: None,
|
2021-02-17 23:08:12 -08:00
|
|
|
},
|
|
|
|
signers: vec![read_keypair_file(&default_keypair_file).unwrap().into(),],
|
|
|
|
}
|
|
|
|
);
|
2020-02-07 11:16:35 -08:00
|
|
|
}
|
2018-09-14 01:59:09 -07:00
|
|
|
}
|