Move CLI nonce args to clap-utils
This commit is contained in:
committed by
Trent Nelson
parent
011b674d41
commit
3fb8428636
@ -27,4 +27,5 @@ pub mod commitment;
|
|||||||
pub mod input_parsers;
|
pub mod input_parsers;
|
||||||
pub mod input_validators;
|
pub mod input_validators;
|
||||||
pub mod keypair;
|
pub mod keypair;
|
||||||
|
pub mod nonce;
|
||||||
pub mod offline;
|
pub mod offline;
|
||||||
|
47
clap-utils/src/nonce.rs
Normal file
47
clap-utils/src/nonce.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use crate::{input_validators::*, offline::BLOCKHASH_ARG, ArgConstant};
|
||||||
|
use clap::{App, Arg};
|
||||||
|
|
||||||
|
pub const NONCE_ARG: ArgConstant<'static> = ArgConstant {
|
||||||
|
name: "nonce",
|
||||||
|
long: "nonce",
|
||||||
|
help: "Provide the nonce account to use when creating a nonced \n\
|
||||||
|
transaction. Nonced transactions are useful when a transaction \n\
|
||||||
|
requires a lengthy signing process. Learn more about nonced \n\
|
||||||
|
transactions at https://docs.solana.com/offline-signing/durable-nonce",
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const NONCE_AUTHORITY_ARG: ArgConstant<'static> = ArgConstant {
|
||||||
|
name: "nonce_authority",
|
||||||
|
long: "nonce-authority",
|
||||||
|
help: "Provide the nonce authority keypair to use when signing a nonced transaction",
|
||||||
|
};
|
||||||
|
|
||||||
|
fn nonce_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
|
Arg::with_name(NONCE_ARG.name)
|
||||||
|
.long(NONCE_ARG.long)
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("PUBKEY")
|
||||||
|
.requires(BLOCKHASH_ARG.name)
|
||||||
|
.validator(is_valid_pubkey)
|
||||||
|
.help(NONCE_ARG.help)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nonce_authority_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
|
Arg::with_name(NONCE_AUTHORITY_ARG.name)
|
||||||
|
.long(NONCE_AUTHORITY_ARG.long)
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("KEYPAIR")
|
||||||
|
.validator(is_valid_signer)
|
||||||
|
.help(NONCE_AUTHORITY_ARG.help)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait NonceArgs {
|
||||||
|
fn nonce_args(self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NonceArgs for App<'_, '_> {
|
||||||
|
fn nonce_args(self) -> Self {
|
||||||
|
self.arg(nonce_arg())
|
||||||
|
.arg(nonce_authority_arg().requires(NONCE_ARG.name))
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ use crate::{
|
|||||||
cli_output::{CliAccount, CliSignOnlyData, CliSignature, OutputFormat},
|
cli_output::{CliAccount, CliSignOnlyData, CliSignature, OutputFormat},
|
||||||
cluster_query::*,
|
cluster_query::*,
|
||||||
display::{new_spinner_progress_bar, println_name_value, println_transaction},
|
display::{new_spinner_progress_bar, println_name_value, println_transaction},
|
||||||
nonce::{self, *},
|
nonce::*,
|
||||||
offline::{blockhash_query::BlockhashQuery, *},
|
offline::{blockhash_query::BlockhashQuery, *},
|
||||||
spend_utils::*,
|
spend_utils::*,
|
||||||
stake::*,
|
stake::*,
|
||||||
@ -16,8 +16,8 @@ use num_traits::FromPrimitive;
|
|||||||
use serde_json::{self, json, Value};
|
use serde_json::{self, json, Value};
|
||||||
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
||||||
use solana_clap_utils::{
|
use solana_clap_utils::{
|
||||||
commitment::commitment_arg_with_default, input_parsers::*, input_validators::*,
|
self, commitment::commitment_arg_with_default, input_parsers::*, input_validators::*,
|
||||||
keypair::signer_from_path, offline::SIGN_ONLY_ARG, ArgConstant,
|
keypair::signer_from_path, nonce::*, offline::SIGN_ONLY_ARG, ArgConstant,
|
||||||
};
|
};
|
||||||
use solana_client::{
|
use solana_client::{
|
||||||
client_error::{ClientError, ClientErrorKind, Result as ClientResult},
|
client_error::{ClientError, ClientErrorKind, Result as ClientResult},
|
||||||
@ -135,10 +135,6 @@ pub fn fee_payer_arg<'a, 'b>() -> Arg<'a, 'b> {
|
|||||||
.help(FEE_PAYER_ARG.help)
|
.help(FEE_PAYER_ARG.help)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nonce_authority_arg<'a, 'b>() -> Arg<'a, 'b> {
|
|
||||||
nonce::nonce_authority_arg().requires(NONCE_ARG.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum CliCommand {
|
pub enum CliCommand {
|
||||||
@ -2278,8 +2274,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
|||||||
.help("The amount to send, in SOL; accepts keyword ALL"),
|
.help("The amount to send, in SOL; accepts keyword ALL"),
|
||||||
)
|
)
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg()),
|
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("resolve-signer")
|
SubCommand::with_name("resolve-signer")
|
||||||
@ -2326,8 +2321,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
|||||||
.help("Return signature immediately after submitting the transaction, instead of waiting for confirmations"),
|
.help("Return signature immediately after submitting the transaction, instead of waiting for confirmations"),
|
||||||
)
|
)
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg()),
|
.arg(fee_payer_arg()),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
|
@ -8,9 +8,7 @@ use crate::{
|
|||||||
spend_utils::{resolve_spend_tx_and_check_account_balance, SpendAmount},
|
spend_utils::{resolve_spend_tx_and_check_account_balance, SpendAmount},
|
||||||
};
|
};
|
||||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||||
use solana_clap_utils::{
|
use solana_clap_utils::{input_parsers::*, input_validators::*, nonce::*};
|
||||||
input_parsers::*, input_validators::*, offline::BLOCKHASH_ARG, ArgConstant,
|
|
||||||
};
|
|
||||||
use solana_client::{nonce_utils::*, rpc_client::RpcClient};
|
use solana_client::{nonce_utils::*, rpc_client::RpcClient};
|
||||||
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
@ -28,44 +26,10 @@ use solana_sdk::{
|
|||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub const NONCE_ARG: ArgConstant<'static> = ArgConstant {
|
|
||||||
name: "nonce",
|
|
||||||
long: "nonce",
|
|
||||||
help: "Provide the nonce account to use when creating a nonced \n\
|
|
||||||
transaction. Nonced transactions are useful when a transaction \n\
|
|
||||||
requires a lengthy signing process. Learn more about nonced \n\
|
|
||||||
transactions at https://docs.solana.com/offline-signing/durable-nonce",
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const NONCE_AUTHORITY_ARG: ArgConstant<'static> = ArgConstant {
|
|
||||||
name: "nonce_authority",
|
|
||||||
long: "nonce-authority",
|
|
||||||
help: "Provide the nonce authority keypair to use when signing a nonced transaction",
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait NonceSubCommands {
|
pub trait NonceSubCommands {
|
||||||
fn nonce_subcommands(self) -> Self;
|
fn nonce_subcommands(self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nonce_arg<'a, 'b>() -> Arg<'a, 'b> {
|
|
||||||
Arg::with_name(NONCE_ARG.name)
|
|
||||||
.long(NONCE_ARG.long)
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("PUBKEY")
|
|
||||||
.requires(BLOCKHASH_ARG.name)
|
|
||||||
.validator(is_valid_pubkey)
|
|
||||||
.help(NONCE_ARG.help)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nonce_authority_arg<'a, 'b>() -> Arg<'a, 'b> {
|
|
||||||
Arg::with_name(NONCE_AUTHORITY_ARG.name)
|
|
||||||
.long(NONCE_AUTHORITY_ARG.long)
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("KEYPAIR")
|
|
||||||
.validator(is_valid_signer)
|
|
||||||
.help(NONCE_AUTHORITY_ARG.help)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NonceSubCommands for App<'_, '_> {
|
impl NonceSubCommands for App<'_, '_> {
|
||||||
fn nonce_subcommands(self) -> Self {
|
fn nonce_subcommands(self) -> Self {
|
||||||
self.subcommand(
|
self.subcommand(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use solana_clap_utils::nonce::*;
|
||||||
use solana_client::nonce_utils;
|
use solana_client::nonce_utils;
|
||||||
use solana_sdk::commitment_config::CommitmentConfig;
|
use solana_sdk::commitment_config::CommitmentConfig;
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ impl BlockhashQuery {
|
|||||||
pub fn new_from_matches(matches: &ArgMatches<'_>) -> Self {
|
pub fn new_from_matches(matches: &ArgMatches<'_>) -> Self {
|
||||||
let blockhash = value_of(matches, BLOCKHASH_ARG.name);
|
let blockhash = value_of(matches, BLOCKHASH_ARG.name);
|
||||||
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
|
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
|
||||||
let nonce_account = pubkey_of(matches, nonce::NONCE_ARG.name);
|
let nonce_account = pubkey_of(matches, NONCE_ARG.name);
|
||||||
BlockhashQuery::new(blockhash, sign_only, nonce_account)
|
BlockhashQuery::new(blockhash, sign_only, nonce_account)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ impl Default for BlockhashQuery {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{nonce::nonce_arg, offline::blockhash_query::BlockhashQuery};
|
use crate::offline::blockhash_query::BlockhashQuery;
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use serde_json::{self, json, Value};
|
use serde_json::{self, json, Value};
|
||||||
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
||||||
@ -172,9 +173,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_blockhash_query_new_from_matches_ok() {
|
fn test_blockhash_query_new_from_matches_ok() {
|
||||||
let test_commands = App::new("blockhash_query_test")
|
let test_commands = App::new("blockhash_query_test").nonce_args().offline_args();
|
||||||
.arg(nonce_arg())
|
|
||||||
.offline_args();
|
|
||||||
let blockhash = hash(&[1u8]);
|
let blockhash = hash(&[1u8]);
|
||||||
let blockhash_string = blockhash.to_string();
|
let blockhash_string = blockhash.to_string();
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
pub mod blockhash_query;
|
pub mod blockhash_query;
|
||||||
|
|
||||||
use crate::nonce;
|
|
||||||
use clap::{App, Arg, ArgMatches};
|
use clap::{App, Arg, ArgMatches};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use solana_clap_utils::{
|
use solana_clap_utils::{
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
checks::{check_account_for_fee_with_commitment, check_unique_pubkeys},
|
checks::{check_account_for_fee_with_commitment, check_unique_pubkeys},
|
||||||
cli::{
|
cli::{
|
||||||
fee_payer_arg, generate_unique_signers, log_instruction_custom_error, nonce_authority_arg,
|
fee_payer_arg, generate_unique_signers, log_instruction_custom_error, return_signers,
|
||||||
return_signers, CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult,
|
CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult, SignerIndex, FEE_PAYER_ARG,
|
||||||
SignerIndex, FEE_PAYER_ARG,
|
|
||||||
},
|
},
|
||||||
cli_output::{CliStakeHistory, CliStakeHistoryEntry, CliStakeState, CliStakeType},
|
cli_output::{CliStakeHistory, CliStakeHistoryEntry, CliStakeState, CliStakeType},
|
||||||
nonce::{check_nonce_account, nonce_arg, NONCE_ARG, NONCE_AUTHORITY_ARG},
|
nonce::check_nonce_account,
|
||||||
offline::{blockhash_query::BlockhashQuery, *},
|
offline::{blockhash_query::BlockhashQuery, *},
|
||||||
spend_utils::{resolve_spend_tx_and_check_account_balances, SpendAmount},
|
spend_utils::{resolve_spend_tx_and_check_account_balances, SpendAmount},
|
||||||
};
|
};
|
||||||
use clap::{App, Arg, ArgGroup, ArgMatches, SubCommand};
|
use clap::{App, Arg, ArgGroup, ArgMatches, SubCommand};
|
||||||
use solana_clap_utils::{input_parsers::*, input_validators::*, offline::*, ArgConstant};
|
use solana_clap_utils::{input_parsers::*, input_validators::*, nonce::*, offline::*, ArgConstant};
|
||||||
use solana_client::{
|
use solana_client::{
|
||||||
nonce_utils, rpc_client::RpcClient, rpc_request::DELINQUENT_VALIDATOR_SLOT_DISTANCE,
|
nonce_utils, rpc_client::RpcClient, rpc_request::DELINQUENT_VALIDATOR_SLOT_DISTANCE,
|
||||||
};
|
};
|
||||||
@ -146,8 +145,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
.help("Source account of funds [default: cli config keypair]"),
|
.help("Source account of funds [default: cli config keypair]"),
|
||||||
)
|
)
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -176,8 +174,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
)
|
)
|
||||||
.arg(stake_authority_arg())
|
.arg(stake_authority_arg())
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -207,8 +204,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
.arg(stake_authority_arg())
|
.arg(stake_authority_arg())
|
||||||
.arg(withdraw_authority_arg())
|
.arg(withdraw_authority_arg())
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -223,8 +219,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
)
|
)
|
||||||
.arg(stake_authority_arg())
|
.arg(stake_authority_arg())
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -264,8 +259,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
)
|
)
|
||||||
.arg(stake_authority_arg())
|
.arg(stake_authority_arg())
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -287,8 +281,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
)
|
)
|
||||||
.arg(stake_authority_arg())
|
.arg(stake_authority_arg())
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -319,8 +312,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
)
|
)
|
||||||
.arg(withdraw_authority_arg())
|
.arg(withdraw_authority_arg())
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("custodian")
|
Arg::with_name("custodian")
|
||||||
@ -375,8 +367,7 @@ impl StakeSubCommands for App<'_, '_> {
|
|||||||
.help("Keypair of the existing custodian [default: cli config pubkey]")
|
.help("Keypair of the existing custodian [default: cli config pubkey]")
|
||||||
)
|
)
|
||||||
.offline_args()
|
.offline_args()
|
||||||
.arg(nonce_arg())
|
.nonce_args()
|
||||||
.arg(nonce_authority_arg())
|
|
||||||
.arg(fee_payer_arg())
|
.arg(fee_payer_arg())
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
|
Reference in New Issue
Block a user