diff --git a/clap-utils/src/lib.rs b/clap-utils/src/lib.rs index ab51ffa627..aeeaa98251 100644 --- a/clap-utils/src/lib.rs +++ b/clap-utils/src/lib.rs @@ -27,4 +27,5 @@ pub mod commitment; pub mod input_parsers; pub mod input_validators; pub mod keypair; +pub mod nonce; pub mod offline; diff --git a/clap-utils/src/nonce.rs b/clap-utils/src/nonce.rs new file mode 100644 index 0000000000..fd5ff2ef71 --- /dev/null +++ b/clap-utils/src/nonce.rs @@ -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)) + } +} diff --git a/cli/src/cli.rs b/cli/src/cli.rs index e5c6050675..c119f41f38 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -3,7 +3,7 @@ use crate::{ cli_output::{CliAccount, CliSignOnlyData, CliSignature, OutputFormat}, cluster_query::*, display::{new_spinner_progress_bar, println_name_value, println_transaction}, - nonce::{self, *}, + nonce::*, offline::{blockhash_query::BlockhashQuery, *}, spend_utils::*, stake::*, @@ -16,8 +16,8 @@ use num_traits::FromPrimitive; use serde_json::{self, json, Value}; use solana_account_decoder::{UiAccount, UiAccountEncoding}; use solana_clap_utils::{ - commitment::commitment_arg_with_default, input_parsers::*, input_validators::*, - keypair::signer_from_path, offline::SIGN_ONLY_ARG, ArgConstant, + self, commitment::commitment_arg_with_default, input_parsers::*, input_validators::*, + keypair::signer_from_path, nonce::*, offline::SIGN_ONLY_ARG, ArgConstant, }; use solana_client::{ 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) } -pub fn nonce_authority_arg<'a, 'b>() -> Arg<'a, 'b> { - nonce::nonce_authority_arg().requires(NONCE_ARG.name) -} - #[derive(Debug, PartialEq)] #[allow(clippy::large_enum_variant)] 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"), ) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()), + .nonce_args() ) .subcommand( 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"), ) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()), ) .subcommand( diff --git a/cli/src/nonce.rs b/cli/src/nonce.rs index 91687223a9..0c4eaaa9a8 100644 --- a/cli/src/nonce.rs +++ b/cli/src/nonce.rs @@ -8,9 +8,7 @@ use crate::{ spend_utils::{resolve_spend_tx_and_check_account_balance, SpendAmount}, }; use clap::{App, Arg, ArgMatches, SubCommand}; -use solana_clap_utils::{ - input_parsers::*, input_validators::*, offline::BLOCKHASH_ARG, ArgConstant, -}; +use solana_clap_utils::{input_parsers::*, input_validators::*, nonce::*}; use solana_client::{nonce_utils::*, rpc_client::RpcClient}; use solana_remote_wallet::remote_wallet::RemoteWalletManager; use solana_sdk::{ @@ -28,44 +26,10 @@ use solana_sdk::{ }; 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 { 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<'_, '_> { fn nonce_subcommands(self) -> Self { self.subcommand( diff --git a/cli/src/offline/blockhash_query.rs b/cli/src/offline/blockhash_query.rs index a24d5e7484..ec84802ab3 100644 --- a/cli/src/offline/blockhash_query.rs +++ b/cli/src/offline/blockhash_query.rs @@ -1,4 +1,5 @@ use super::*; +use solana_clap_utils::nonce::*; use solana_client::nonce_utils; use solana_sdk::commitment_config::CommitmentConfig; @@ -76,7 +77,7 @@ impl BlockhashQuery { pub fn new_from_matches(matches: &ArgMatches<'_>) -> Self { let blockhash = value_of(matches, BLOCKHASH_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) } @@ -109,7 +110,7 @@ impl Default for BlockhashQuery { #[cfg(test)] mod tests { use super::*; - use crate::{nonce::nonce_arg, offline::blockhash_query::BlockhashQuery}; + use crate::offline::blockhash_query::BlockhashQuery; use clap::App; use serde_json::{self, json, Value}; use solana_account_decoder::{UiAccount, UiAccountEncoding}; @@ -172,9 +173,7 @@ mod tests { #[test] fn test_blockhash_query_new_from_matches_ok() { - let test_commands = App::new("blockhash_query_test") - .arg(nonce_arg()) - .offline_args(); + let test_commands = App::new("blockhash_query_test").nonce_args().offline_args(); let blockhash = hash(&[1u8]); let blockhash_string = blockhash.to_string(); diff --git a/cli/src/offline/mod.rs b/cli/src/offline/mod.rs index 3cef004cdc..283f49edf3 100644 --- a/cli/src/offline/mod.rs +++ b/cli/src/offline/mod.rs @@ -1,6 +1,5 @@ pub mod blockhash_query; -use crate::nonce; use clap::{App, Arg, ArgMatches}; use serde_json::Value; use solana_clap_utils::{ diff --git a/cli/src/stake.rs b/cli/src/stake.rs index 57668eb544..eb1e514863 100644 --- a/cli/src/stake.rs +++ b/cli/src/stake.rs @@ -1,17 +1,16 @@ use crate::{ checks::{check_account_for_fee_with_commitment, check_unique_pubkeys}, cli::{ - fee_payer_arg, generate_unique_signers, log_instruction_custom_error, nonce_authority_arg, - return_signers, CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult, - SignerIndex, FEE_PAYER_ARG, + fee_payer_arg, generate_unique_signers, log_instruction_custom_error, return_signers, + CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult, SignerIndex, FEE_PAYER_ARG, }, 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, *}, spend_utils::{resolve_spend_tx_and_check_account_balances, SpendAmount}, }; 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::{ 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]"), ) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) ) .subcommand( @@ -176,8 +174,7 @@ impl StakeSubCommands for App<'_, '_> { ) .arg(stake_authority_arg()) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) ) .subcommand( @@ -207,8 +204,7 @@ impl StakeSubCommands for App<'_, '_> { .arg(stake_authority_arg()) .arg(withdraw_authority_arg()) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) ) .subcommand( @@ -223,8 +219,7 @@ impl StakeSubCommands for App<'_, '_> { ) .arg(stake_authority_arg()) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) ) .subcommand( @@ -264,8 +259,7 @@ impl StakeSubCommands for App<'_, '_> { ) .arg(stake_authority_arg()) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) ) .subcommand( @@ -287,8 +281,7 @@ impl StakeSubCommands for App<'_, '_> { ) .arg(stake_authority_arg()) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) ) .subcommand( @@ -319,8 +312,7 @@ impl StakeSubCommands for App<'_, '_> { ) .arg(withdraw_authority_arg()) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) .arg( Arg::with_name("custodian") @@ -375,8 +367,7 @@ impl StakeSubCommands for App<'_, '_> { .help("Keypair of the existing custodian [default: cli config pubkey]") ) .offline_args() - .arg(nonce_arg()) - .arg(nonce_authority_arg()) + .nonce_args() .arg(fee_payer_arg()) ) .subcommand(