Cli: enable flexible flexible signer paths for pubkey args (#8892)

automerge
This commit is contained in:
Tyera Eulberg 2020-03-16 16:17:13 -06:00 committed by GitHub
parent 7079559c2d
commit 6077458ad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 221 additions and 148 deletions

View File

@ -129,6 +129,22 @@ pub fn pubkey_of_signer(
}
}
pub fn pubkeys_of_multiple_signers(
matches: &ArgMatches<'_>,
name: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<Option<Vec<Pubkey>>, Box<dyn std::error::Error>> {
if let Some(pubkey_matches) = matches.values_of(name) {
let mut pubkeys: Vec<Pubkey> = vec![];
for signer in pubkey_matches {
pubkeys.push(pubkey_from_path(matches, signer, name, wallet_manager)?);
}
Ok(Some(pubkeys))
} else {
Ok(None)
}
}
pub fn resolve_signer(
matches: &ArgMatches<'_>,
name: &str,

View File

@ -46,18 +46,27 @@ pub fn is_pubkey_or_keypair(string: String) -> Result<(), String> {
is_pubkey(string.clone()).or_else(|_| is_keypair(string))
}
// Return an error if string cannot be parsed as pubkey or keypair file or keypair ask keyword
pub fn is_pubkey_or_keypair_or_ask_keyword(string: String) -> Result<(), String> {
is_pubkey(string.clone()).or_else(|_| is_keypair_or_ask_keyword(string))
}
pub fn is_valid_signer(string: String) -> Result<(), String> {
// Return an error if string cannot be parsed as a pubkey string, or a valid Signer that can
// produce a pubkey()
pub fn is_valid_pubkey(string: String) -> Result<(), String> {
match parse_keypair_path(&string) {
KeypairUrl::Filepath(path) => is_keypair(path),
_ => Ok(()),
}
}
// Return an error if string cannot be parsed as a valid Signer. This is an alias of
// `is_valid_pubkey`, and does accept pubkey strings, even though a Pubkey is not by itself
// sufficient to sign a transaction.
//
// In the current offline-signing implementation, a pubkey is the valid input for a signer field
// when paired with an offline `--signer` argument to provide a Presigner (pubkey + signature).
// Clap validators can't check multiple fields at once, so the verification that a `--signer` is
// also provided and correct happens in parsing, not in validation.
pub fn is_valid_signer(string: String) -> Result<(), String> {
is_valid_pubkey(string)
}
// Return an error if string cannot be parsed as pubkey=signature string
pub fn is_pubkey_sig(string: String) -> Result<(), String> {
let mut signer = string.split('=');

View File

@ -569,7 +569,7 @@ pub fn parse_command(
) -> Result<CliCommandInfo, Box<dyn error::Error>> {
let response = match matches.subcommand() {
// Cluster Query Commands
("catchup", Some(matches)) => parse_catchup(matches),
("catchup", Some(matches)) => parse_catchup(matches, wallet_manager),
("cluster-version", Some(_matches)) => Ok(CliCommandInfo {
command: CliCommand::ClusterVersion,
signers: vec![],
@ -604,7 +604,7 @@ pub fn parse_command(
command: CliCommand::ShowGossip,
signers: vec![],
}),
("stakes", Some(matches)) => parse_show_stakes(matches),
("stakes", Some(matches)) => parse_show_stakes(matches, wallet_manager),
("validators", Some(matches)) => parse_show_validators(matches),
// Nonce Commands
("authorize-nonce-account", Some(matches)) => {
@ -613,11 +613,11 @@ pub fn parse_command(
("create-nonce-account", Some(matches)) => {
parse_nonce_create_account(matches, default_signer_path, wallet_manager)
}
("nonce", Some(matches)) => parse_get_nonce(matches),
("nonce", Some(matches)) => parse_get_nonce(matches, wallet_manager),
("new-nonce", Some(matches)) => {
parse_new_nonce(matches, default_signer_path, wallet_manager)
}
("nonce-account", Some(matches)) => parse_show_nonce_account(matches),
("nonce-account", Some(matches)) => parse_show_nonce_account(matches, wallet_manager),
("withdraw-from-nonce-account", Some(matches)) => {
parse_withdraw_from_nonce_account(matches, default_signer_path, wallet_manager)
}
@ -662,7 +662,7 @@ pub fn parse_command(
("stake-set-lockup", Some(matches)) => {
parse_stake_set_lockup(matches, default_signer_path, wallet_manager)
}
("stake-account", Some(matches)) => parse_show_stake_account(matches),
("stake-account", Some(matches)) => parse_show_stake_account(matches, wallet_manager),
("stake-history", Some(matches)) => parse_show_stake_history(matches),
// Storage Commands
("create-archiver-storage-account", Some(matches)) => {
@ -674,7 +674,9 @@ pub fn parse_command(
("claim-storage-reward", Some(matches)) => {
parse_storage_claim_reward(matches, default_signer_path, wallet_manager)
}
("storage-account", Some(matches)) => parse_storage_get_account_command(matches),
("storage-account", Some(matches)) => {
parse_storage_get_account_command(matches, wallet_manager)
}
// Validator Info Commands
("validator-info", Some(matches)) => match matches.subcommand() {
("publish", Some(matches)) => {
@ -702,7 +704,7 @@ pub fn parse_command(
wallet_manager,
VoteAuthorize::Withdrawer,
),
("vote-account", Some(matches)) => parse_vote_get_account_command(matches),
("vote-account", Some(matches)) => parse_vote_get_account_command(matches, wallet_manager),
("withdraw-from-vote-account", Some(matches)) => {
parse_withdraw_from_vote_account(matches, default_signer_path, wallet_manager)
}
@ -738,7 +740,7 @@ pub fn parse_command(
} else {
None
};
let pubkey = pubkey_of(matches, "to");
let pubkey = pubkey_of_signer(matches, "to", wallet_manager)?;
let signers = if pubkey.is_some() {
vec![]
} else {
@ -761,7 +763,7 @@ pub fn parse_command(
})
}
("balance", Some(matches)) => {
let pubkey = pubkey_of(matches, "pubkey");
let pubkey = pubkey_of_signer(matches, "pubkey", wallet_manager)?;
let signers = if pubkey.is_some() {
vec![]
} else {
@ -802,7 +804,7 @@ pub fn parse_command(
},
("pay", Some(matches)) => {
let lamports = lamports_of_sol(matches, "amount").unwrap();
let to = pubkey_of(matches, "to").unwrap();
let to = pubkey_of_signer(matches, "to", wallet_manager)?.unwrap();
let timestamp = if matches.is_present("timestamp") {
// Parse input for serde_json
let date_string = if !matches.value_of("timestamp").unwrap().contains('Z') {
@ -819,7 +821,7 @@ pub fn parse_command(
let cancelable = matches.is_present("cancelable");
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
let nonce_account = pubkey_of(matches, NONCE_ARG.name);
let nonce_account = pubkey_of_signer(matches, NONCE_ARG.name, wallet_manager)?;
let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
@ -852,7 +854,8 @@ pub fn parse_command(
})
}
("account", Some(matches)) => {
let account_pubkey = pubkey_of(matches, "account_pubkey").unwrap();
let account_pubkey =
pubkey_of_signer(matches, "account_pubkey", wallet_manager)?.unwrap();
let output_file = matches.value_of("output_file");
let use_lamports_unit = matches.is_present("lamports");
Ok(CliCommandInfo {
@ -907,10 +910,10 @@ pub fn parse_command(
}
("transfer", Some(matches)) => {
let lamports = lamports_of_sol(matches, "amount").unwrap();
let to = pubkey_of(matches, "to").unwrap();
let to = pubkey_of_signer(matches, "to", wallet_manager)?.unwrap();
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
let nonce_account = pubkey_of(matches, NONCE_ARG.name);
let nonce_account = pubkey_of_signer(matches, NONCE_ARG.name, wallet_manager)?;
let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
let (fee_payer, fee_payer_pubkey) =
@ -2249,7 +2252,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
.index(2)
.value_name("PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The pubkey of airdrop recipient"),
),
)
@ -2261,7 +2264,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
.index(1)
.value_name("PUBKEY")
.takes_value(true)
.validator(is_valid_signer)
.validator(is_valid_pubkey)
.help("The public key of the balance to check"),
)
.arg(
@ -2324,7 +2327,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
.value_name("PUBKEY")
.takes_value(true)
.required(false)
.validator(is_valid_signer)
.validator(is_valid_pubkey)
.help("From (base) key, [default: cli config keypair]"),
),
)
@ -2349,7 +2352,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The pubkey of recipient"),
)
.arg(
@ -2467,7 +2470,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The pubkey of recipient"),
)
.arg(
@ -2502,7 +2505,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Account pubkey"),
)
.arg(

View File

@ -58,7 +58,7 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.index(1)
.takes_value(true)
.value_name("PUBKEY")
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.required(true)
.help("Identity pubkey of the validator"),
)
@ -224,7 +224,7 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.value_name("VOTE ACCOUNT PUBKEYS")
.takes_value(true)
.multiple(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Only show stake accounts delegated to the provided vote accounts"),
)
.arg(
@ -256,8 +256,11 @@ impl ClusterQuerySubCommands for App<'_, '_> {
}
}
pub fn parse_catchup(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let node_pubkey = pubkey_of(matches, "node_pubkey").unwrap();
pub fn parse_catchup(
matches: &ArgMatches<'_>,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let node_pubkey = pubkey_of_signer(matches, "node_pubkey", wallet_manager)?.unwrap();
let node_json_rpc_url = value_t!(matches, "node_json_rpc_url", String).ok();
Ok(CliCommandInfo {
command: CliCommand::Catchup {
@ -359,9 +362,13 @@ pub fn parse_get_transaction_count(matches: &ArgMatches<'_>) -> Result<CliComman
})
}
pub fn parse_show_stakes(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
pub fn parse_show_stakes(
matches: &ArgMatches<'_>,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let use_lamports_unit = matches.is_present("lamports");
let vote_account_pubkeys = pubkeys_of(matches, "vote_account_pubkeys");
let vote_account_pubkeys =
pubkeys_of_multiple_signers(matches, "vote_account_pubkeys", wallet_manager)?;
Ok(CliCommandInfo {
command: CliCommand::ShowStakes {

View File

@ -74,7 +74,7 @@ pub fn nonce_arg<'a, 'b>() -> Arg<'a, 'b> {
.takes_value(true)
.value_name("PUBKEY")
.requires(BLOCKHASH_ARG.name)
.validator(is_pubkey)
.validator(is_valid_pubkey)
.help(NONCE_ARG.help)
}
@ -98,7 +98,7 @@ impl NonceSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Address of the nonce account"),
)
.arg(
@ -107,7 +107,7 @@ impl NonceSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Account to be granted authority of the nonce account"),
)
.arg(
@ -125,10 +125,10 @@ impl NonceSubCommands for App<'_, '_> {
.arg(
Arg::with_name("nonce_account_keypair")
.index(1)
.value_name("PUBKEY")
.value_name("KEYPAIR")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_signer)
.help("Keypair of the nonce account to fund"),
)
.arg(
@ -145,7 +145,7 @@ impl NonceSubCommands for App<'_, '_> {
.long(NONCE_AUTHORITY_ARG.long)
.takes_value(true)
.value_name("PUBKEY")
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Assign noncing authority to another entity"),
),
)
@ -159,7 +159,7 @@ impl NonceSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Address of the nonce account to display"),
),
)
@ -167,12 +167,12 @@ impl NonceSubCommands for App<'_, '_> {
SubCommand::with_name("new-nonce")
.about("Generate a new nonce, rendering the existing nonce useless")
.arg(
Arg::with_name("nonce_account_keypair")
Arg::with_name("nonce_account_pubkey")
.index(1)
.value_name("KEYPAIR")
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Address of the nonce account"),
)
.arg(nonce_authority_arg()),
@ -187,7 +187,7 @@ impl NonceSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Address of the nonce account to display"),
)
.arg(
@ -201,12 +201,12 @@ impl NonceSubCommands for App<'_, '_> {
SubCommand::with_name("withdraw-from-nonce-account")
.about("Withdraw SOL from the nonce account")
.arg(
Arg::with_name("nonce_account_keypair")
Arg::with_name("nonce_account_pubkey")
.index(1)
.value_name("KEYPAIR")
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_valid_signer)
.validator(is_valid_pubkey)
.help("Nonce account to withdraw from"),
)
.arg(
@ -215,7 +215,7 @@ impl NonceSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The account to which the SOL should be transferred"),
)
.arg(
@ -279,8 +279,8 @@ pub fn parse_authorize_nonce_account(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let nonce_account = pubkey_of(matches, "nonce_account_pubkey").unwrap();
let new_authority = pubkey_of(matches, "new_authority").unwrap();
let nonce_account = pubkey_of_signer(matches, "nonce_account_pubkey", wallet_manager)?.unwrap();
let new_authority = pubkey_of_signer(matches, "new_authority", wallet_manager)?.unwrap();
let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
@ -311,7 +311,7 @@ pub fn parse_nonce_create_account(
signer_of(matches, "nonce_account_keypair", wallet_manager)?;
let seed = matches.value_of("seed").map(|s| s.to_string());
let lamports = lamports_of_sol(matches, "amount").unwrap();
let nonce_authority = pubkey_of(matches, NONCE_AUTHORITY_ARG.name);
let nonce_authority = pubkey_of_signer(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
let payer_provided = None;
let signer_info = generate_unique_signers(
@ -332,8 +332,12 @@ pub fn parse_nonce_create_account(
})
}
pub fn parse_get_nonce(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let nonce_account_pubkey = pubkey_of(matches, "nonce_account_pubkey").unwrap();
pub fn parse_get_nonce(
matches: &ArgMatches<'_>,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let nonce_account_pubkey =
pubkey_of_signer(matches, "nonce_account_pubkey", wallet_manager)?.unwrap();
Ok(CliCommandInfo {
command: CliCommand::GetNonce(nonce_account_pubkey),
@ -346,7 +350,7 @@ pub fn parse_new_nonce(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let nonce_account = pubkey_of(matches, "nonce_account_keypair").unwrap();
let nonce_account = pubkey_of_signer(matches, "nonce_account_pubkey", wallet_manager)?.unwrap();
let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
@ -367,8 +371,12 @@ pub fn parse_new_nonce(
})
}
pub fn parse_show_nonce_account(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let nonce_account_pubkey = pubkey_of(matches, "nonce_account_pubkey").unwrap();
pub fn parse_show_nonce_account(
matches: &ArgMatches<'_>,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let nonce_account_pubkey =
pubkey_of_signer(matches, "nonce_account_pubkey", wallet_manager)?.unwrap();
let use_lamports_unit = matches.is_present("lamports");
Ok(CliCommandInfo {
@ -385,8 +393,9 @@ pub fn parse_withdraw_from_nonce_account(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let nonce_account = pubkey_of(matches, "nonce_account_keypair").unwrap();
let destination_account_pubkey = pubkey_of(matches, "destination_account_pubkey").unwrap();
let nonce_account = pubkey_of_signer(matches, "nonce_account_pubkey", wallet_manager)?.unwrap();
let destination_account_pubkey =
pubkey_of_signer(matches, "destination_account_pubkey", wallet_manager)?.unwrap();
let lamports = lamports_of_sol(matches, "amount").unwrap();
let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;

View File

@ -93,7 +93,7 @@ impl StakeSubCommands for App<'_, '_> {
.long("custodian")
.value_name("PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Identity of the custodian (can withdraw before lockup expires)")
)
.arg(
@ -123,7 +123,7 @@ impl StakeSubCommands for App<'_, '_> {
.long(STAKE_AUTHORITY_ARG.long)
.value_name("PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help(STAKE_AUTHORITY_ARG.help)
)
.arg(
@ -131,7 +131,7 @@ impl StakeSubCommands for App<'_, '_> {
.long(WITHDRAW_AUTHORITY_ARG.long)
.value_name("PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help(WITHDRAW_AUTHORITY_ARG.help)
)
.arg(
@ -163,7 +163,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Stake account to delegate")
)
.arg(
@ -172,7 +172,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The vote account to which the stake will be delegated")
)
.arg(stake_authority_arg())
@ -190,7 +190,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Stake account in which to set the authorized staker")
)
.arg(
@ -199,7 +199,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("New authorized staker")
)
.arg(stake_authority_arg())
@ -217,7 +217,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Stake account in which to set the authorized withdrawer")
)
.arg(
@ -226,7 +226,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("New authorized withdrawer")
)
.arg(withdraw_authority_arg())
@ -244,6 +244,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_valid_pubkey)
.help("Stake account to be deactivated.")
)
.arg(stake_authority_arg())
@ -261,6 +262,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_valid_pubkey)
.help("Stake account to be split")
)
.arg(
@ -303,7 +305,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Stake account from which to withdraw")
)
.arg(
@ -312,7 +314,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The account to which the SOL should be transferred")
)
.arg(
@ -339,7 +341,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Stake account for which to set Lockup")
)
.arg(
@ -362,7 +364,7 @@ impl StakeSubCommands for App<'_, '_> {
.long("new-custodian")
.value_name("PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Identity of the new lockup custodian (can withdraw before lockup expires)")
)
.group(ArgGroup::with_name("lockup_details")
@ -391,7 +393,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Address of the stake account to display")
)
.arg(
@ -423,13 +425,13 @@ pub fn parse_stake_create_account(
let seed = matches.value_of("seed").map(|s| s.to_string());
let epoch = value_of(matches, "lockup_epoch").unwrap_or(0);
let unix_timestamp = unix_timestamp_from_rfc3339_datetime(matches, "lockup_date").unwrap_or(0);
let custodian = pubkey_of(matches, "custodian").unwrap_or_default();
let staker = pubkey_of(matches, STAKE_AUTHORITY_ARG.name);
let withdrawer = pubkey_of(matches, WITHDRAW_AUTHORITY_ARG.name);
let custodian = pubkey_of_signer(matches, "custodian", wallet_manager)?.unwrap_or_default();
let staker = pubkey_of_signer(matches, STAKE_AUTHORITY_ARG.name, wallet_manager)?;
let withdrawer = pubkey_of_signer(matches, WITHDRAW_AUTHORITY_ARG.name, wallet_manager)?;
let lamports = lamports_of_sol(matches, "amount").unwrap();
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
let nonce_account = pubkey_of(matches, NONCE_ARG.name);
let nonce_account = pubkey_of_signer(matches, NONCE_ARG.name, wallet_manager)?;
let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
let (fee_payer, fee_payer_pubkey) = signer_of(matches, FEE_PAYER_ARG.name, wallet_manager)?;
@ -472,8 +474,10 @@ pub fn parse_stake_delegate_stake(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let vote_account_pubkey =
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
let force = matches.is_present("force");
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
@ -513,8 +517,10 @@ pub fn parse_stake_authorize(
wallet_manager: Option<&Arc<RemoteWalletManager>>,
stake_authorize: StakeAuthorize,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let new_authorized_pubkey = pubkey_of(matches, "authorized_pubkey").unwrap();
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let new_authorized_pubkey =
pubkey_of_signer(matches, "authorized_pubkey", wallet_manager)?.unwrap();
let authority_flag = match stake_authorize {
StakeAuthorize::Staker => STAKE_AUTHORITY_ARG.name,
StakeAuthorize::Withdrawer => WITHDRAW_AUTHORITY_ARG.name,
@ -555,7 +561,8 @@ pub fn parse_split_stake(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let (split_stake_account, split_stake_account_pubkey) =
signer_of(matches, "split_stake_account", wallet_manager)?;
let lamports = lamports_of_sol(matches, "amount").unwrap();
@ -599,7 +606,8 @@ pub fn parse_stake_deactivate_stake(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
let nonce_account = pubkey_of(matches, NONCE_ARG.name);
@ -635,8 +643,10 @@ pub fn parse_stake_withdraw_stake(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let destination_account_pubkey = pubkey_of(matches, "destination_account_pubkey").unwrap();
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let destination_account_pubkey =
pubkey_of_signer(matches, "destination_account_pubkey", wallet_manager)?.unwrap();
let lamports = lamports_of_sol(matches, "amount").unwrap();
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
@ -675,10 +685,11 @@ pub fn parse_stake_set_lockup(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let epoch = value_of(matches, "lockup_epoch");
let unix_timestamp = unix_timestamp_from_rfc3339_datetime(matches, "lockup_date");
let new_custodian = pubkey_of(matches, "new_custodian");
let new_custodian = pubkey_of_signer(matches, "new_custodian", wallet_manager)?;
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
@ -715,8 +726,12 @@ pub fn parse_stake_set_lockup(
})
}
pub fn parse_show_stake_account(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
pub fn parse_show_stake_account(
matches: &ArgMatches<'_>,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let use_lamports_unit = matches.is_present("lamports");
Ok(CliCommandInfo {
command: CliCommand::ShowStakeAccount {

View File

@ -29,7 +29,7 @@ impl StorageSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair),
.validator(is_valid_pubkey),
)
.arg(
Arg::with_name("storage_account")
@ -49,7 +49,7 @@ impl StorageSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair),
.validator(is_valid_pubkey),
)
.arg(
Arg::with_name("storage_account")
@ -69,7 +69,7 @@ impl StorageSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The node account to credit the rewards to"),
)
.arg(
@ -78,7 +78,7 @@ impl StorageSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Storage account address to redeem credits for"),
),
)
@ -92,7 +92,7 @@ impl StorageSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Storage account pubkey"),
),
)
@ -104,7 +104,8 @@ pub fn parse_storage_create_archiver_account(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let account_owner = pubkey_of(matches, "storage_account_owner").unwrap();
let account_owner =
pubkey_of_signer(matches, "storage_account_owner", wallet_manager)?.unwrap();
let (storage_account, storage_account_pubkey) =
signer_of(matches, "storage_account", wallet_manager)?;
@ -131,7 +132,8 @@ pub fn parse_storage_create_validator_account(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let account_owner = pubkey_of(matches, "storage_account_owner").unwrap();
let account_owner =
pubkey_of_signer(matches, "storage_account_owner", wallet_manager)?.unwrap();
let (storage_account, storage_account_pubkey) =
signer_of(matches, "storage_account", wallet_manager)?;
@ -158,8 +160,10 @@ pub fn parse_storage_claim_reward(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let node_account_pubkey = pubkey_of(matches, "node_account_pubkey").unwrap();
let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap();
let node_account_pubkey =
pubkey_of_signer(matches, "node_account_pubkey", wallet_manager)?.unwrap();
let storage_account_pubkey =
pubkey_of_signer(matches, "storage_account_pubkey", wallet_manager)?.unwrap();
Ok(CliCommandInfo {
command: CliCommand::ClaimStorageReward {
node_account_pubkey,
@ -176,8 +180,10 @@ pub fn parse_storage_claim_reward(
pub fn parse_storage_get_account_command(
matches: &ArgMatches<'_>,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap();
let storage_account_pubkey =
pubkey_of_signer(matches, "storage_account_pubkey", wallet_manager)?.unwrap();
Ok(CliCommandInfo {
command: CliCommand::ShowStorageAccount(storage_account_pubkey),
signers: vec![],

View File

@ -45,7 +45,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Validator that will vote with this account"),
)
.arg(
@ -61,7 +61,7 @@ impl VoteSubCommands for App<'_, '_> {
.long("authorized-voter")
.value_name("PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Public key of the authorized voter [default: validator identity pubkey]"),
)
.arg(
@ -69,7 +69,7 @@ impl VoteSubCommands for App<'_, '_> {
.long("authorized-withdrawer")
.value_name("PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Public key of the authorized withdrawer [default: validator identity pubkey]"),
)
.arg(
@ -80,37 +80,6 @@ impl VoteSubCommands for App<'_, '_> {
.help("Seed for address generation; if specified, the resulting account will be at a derived address of the VOTE ACCOUNT pubkey")
),
)
.subcommand(
SubCommand::with_name("vote-update-validator")
.about("Update the vote account's validator identity")
.arg(
Arg::with_name("vote_account_pubkey")
.index(1)
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.help("Vote account to update"),
)
.arg(
Arg::with_name("new_identity_pubkey")
.index(2)
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.help("New validator that will vote with this account"),
)
.arg(
Arg::with_name("authorized_voter")
.index(3)
.value_name("KEYPAIR")
.takes_value(true)
.required(true)
.validator(is_valid_signer)
.help("Authorized voter keypair"),
)
)
.subcommand(
SubCommand::with_name("vote-authorize-voter")
.about("Authorize a new vote signing keypair for the given vote account")
@ -120,7 +89,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Vote account in which to set the authorized voter"),
)
.arg(
@ -129,7 +98,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("New vote signer to authorize"),
),
)
@ -142,7 +111,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Vote account in which to set the authorized withdrawer"),
)
.arg(
@ -151,10 +120,41 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("New withdrawer to authorize"),
),
)
.subcommand(
SubCommand::with_name("vote-update-validator")
.about("Update the vote account's validator identity")
.arg(
Arg::with_name("vote_account_pubkey")
.index(1)
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_valid_pubkey)
.help("Vote account to update"),
)
.arg(
Arg::with_name("new_identity_pubkey")
.index(2)
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_valid_pubkey)
.help("New validator that will vote with this account"),
)
.arg(
Arg::with_name("authorized_voter")
.index(3)
.value_name("KEYPAIR")
.takes_value(true)
.required(true)
.validator(is_valid_signer)
.help("Authorized voter keypair"),
)
)
.subcommand(
SubCommand::with_name("vote-account")
.about("Show the contents of a vote account")
@ -173,7 +173,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Vote account pubkey"),
)
.arg(
@ -192,7 +192,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("Vote account from which to withdraw"),
)
.arg(
@ -201,7 +201,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.validator(is_valid_pubkey)
.help("The account to which the SOL should be transferred"),
)
.arg(
@ -232,10 +232,10 @@ pub fn parse_create_vote_account(
) -> Result<CliCommandInfo, CliError> {
let (vote_account, _) = signer_of(matches, "vote_account", wallet_manager)?;
let seed = matches.value_of("seed").map(|s| s.to_string());
let identity_pubkey = pubkey_of(matches, "identity_pubkey").unwrap();
let identity_pubkey = pubkey_of_signer(matches, "identity_pubkey", wallet_manager)?.unwrap();
let commission = value_t_or_exit!(matches, "commission", u8);
let authorized_voter = pubkey_of(matches, "authorized_voter");
let authorized_withdrawer = pubkey_of(matches, "authorized_withdrawer");
let authorized_voter = pubkey_of_signer(matches, "authorized_voter", wallet_manager)?;
let authorized_withdrawer = pubkey_of_signer(matches, "authorized_withdrawer", wallet_manager)?;
let payer_provided = None;
let CliSignerInfo { signers } = generate_unique_signers(
@ -263,8 +263,10 @@ pub fn parse_vote_authorize(
wallet_manager: Option<&Arc<RemoteWalletManager>>,
vote_authorize: VoteAuthorize,
) -> Result<CliCommandInfo, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let new_authorized_pubkey = pubkey_of(matches, "new_authorized_pubkey").unwrap();
let vote_account_pubkey =
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
let new_authorized_pubkey =
pubkey_of_signer(matches, "new_authorized_pubkey", wallet_manager)?.unwrap();
let authorized_voter_provided = None;
let CliSignerInfo { signers } = generate_unique_signers(
@ -289,8 +291,10 @@ pub fn parse_vote_update_validator(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let new_identity_pubkey = pubkey_of(matches, "new_identity_pubkey").unwrap();
let vote_account_pubkey =
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
let new_identity_pubkey =
pubkey_of_signer(matches, "new_identity_pubkey", wallet_manager)?.unwrap();
let (authorized_voter, _) = signer_of(matches, "authorized_voter", wallet_manager)?;
let payer_provided = None;
@ -312,8 +316,10 @@ pub fn parse_vote_update_validator(
pub fn parse_vote_get_account_command(
matches: &ArgMatches<'_>,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let vote_account_pubkey =
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
let use_lamports_unit = matches.is_present("lamports");
let commitment_config = if matches.is_present("confirmed") {
CommitmentConfig::default()
@ -335,8 +341,10 @@ pub fn parse_withdraw_from_vote_account(
default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let destination_account_pubkey = pubkey_of(matches, "destination_account_pubkey").unwrap();
let vote_account_pubkey =
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
let destination_account_pubkey =
pubkey_of_signer(matches, "destination_account_pubkey", wallet_manager)?.unwrap();
let lamports = lamports_of_sol(matches, "amount").unwrap();
let (withdraw_authority, withdraw_authority_pubkey) =
signer_of(matches, "authorized_withdrawer", wallet_manager)?;