CLI: dynamic signing reboot (#8384)
* Add keypair_util_from_path helper * Cli: impl config.keypair as a trait object * SDK: Add Debug and PartialEq for dyn Signer * ClapUtils: Arg parsing from pubkey+signers to Presigner * Impl Signers for &dyn Signer collections * CLI: Add helper for getting signers from args * CLI: Replace SigningAuthority with Signer trait-objs * CLI: Drop disused signers command field * CLI: Drop redundant tests * Add clap validator that handles all current signer types * clap_utils: Factor Presigner resolution to helper * SDK: `From` for boxing Signer implementors to trait objects * SDK: Derive `Clone` for `Presigner` * Remove panic * Cli: dedup signers in transfer for remote-wallet ergonomics * Update docs vis-a-vis ASK changes * Cli: update transaction types to use new dynamic-signer methods * CLI: Fix tests No. 1 what to do about write_keypair outstanding * Work around `CliConfig`'s signer not necessarily being a `Keypair` * CLI: Fix tests No. 2 * Remove unused arg * Remove unused methods * Move offline arg constants upstream * Make cli signing fallible Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>
This commit is contained in:
@@ -4,17 +4,13 @@ use console::style;
|
||||
use solana_clap_utils::{
|
||||
input_parsers::derivation_of,
|
||||
input_validators::{is_derivation, is_url},
|
||||
keypair::{
|
||||
self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG,
|
||||
SKIP_SEED_PHRASE_VALIDATION_ARG,
|
||||
},
|
||||
keypair::{keypair_util_from_path, SKIP_SEED_PHRASE_VALIDATION_ARG},
|
||||
};
|
||||
use solana_cli::{
|
||||
cli::{app, parse_command, process_command, CliCommandInfo, CliConfig, CliError},
|
||||
display::{println_name_value, println_name_value_or},
|
||||
};
|
||||
use solana_cli_config::config::{Config, CONFIG_FILE};
|
||||
use solana_sdk::signature::read_keypair_file;
|
||||
|
||||
use std::error;
|
||||
|
||||
@@ -105,42 +101,24 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<CliConfig, Box<dyn error::
|
||||
} = parse_command(&matches)?;
|
||||
|
||||
let (keypair, keypair_path) = if require_keypair {
|
||||
let KeypairWithSource { keypair, source } = keypair_input(&matches, "keypair")?;
|
||||
match source {
|
||||
keypair::Source::Path => (
|
||||
keypair,
|
||||
Some(matches.value_of("keypair").unwrap().to_string()),
|
||||
),
|
||||
keypair::Source::SeedPhrase => (keypair, None),
|
||||
keypair::Source::Generated => {
|
||||
let keypair_path = if config.keypair_path != "" {
|
||||
config.keypair_path
|
||||
} else {
|
||||
let default_keypair_path = CliConfig::default_keypair_path();
|
||||
if !std::path::Path::new(&default_keypair_path).exists() {
|
||||
return Err(CliError::KeypairFileNotFound(format!(
|
||||
"Generate a new keypair at {} with `solana-keygen new`",
|
||||
default_keypair_path
|
||||
))
|
||||
.into());
|
||||
}
|
||||
let path = if matches.is_present("keypair") {
|
||||
matches.value_of("keypair").unwrap().to_string()
|
||||
} else if config.keypair_path != "" {
|
||||
config.keypair_path
|
||||
} else {
|
||||
let default_keypair_path = CliConfig::default_keypair_path();
|
||||
if !std::path::Path::new(&default_keypair_path).exists() {
|
||||
return Err(CliError::KeypairFileNotFound(format!(
|
||||
"Generate a new keypair at {} with `solana-keygen new`",
|
||||
default_keypair_path
|
||||
};
|
||||
|
||||
let keypair = if keypair_path.starts_with("usb://") {
|
||||
keypair
|
||||
} else {
|
||||
read_keypair_file(&keypair_path).or_else(|err| {
|
||||
Err(CliError::BadParameter(format!(
|
||||
"{}: Unable to open keypair file: {}",
|
||||
err, keypair_path
|
||||
)))
|
||||
})?
|
||||
};
|
||||
|
||||
(keypair, Some(keypair_path))
|
||||
))
|
||||
.into());
|
||||
}
|
||||
}
|
||||
default_keypair_path
|
||||
};
|
||||
|
||||
let keypair = keypair_util_from_path(matches, &path, "keypair")?;
|
||||
(keypair, Some(path))
|
||||
} else {
|
||||
let default = CliConfig::default();
|
||||
(default.keypair, None)
|
||||
@@ -201,6 +179,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||
Arg::with_name("derivation_path")
|
||||
.long("derivation-path")
|
||||
.value_name("ACCOUNT or ACCOUNT/CHANGE")
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.validator(is_derivation)
|
||||
.help("Derivation path to use: m/44'/501'/ACCOUNT'/CHANGE'; default key is device base pubkey: m/44'/501'/0'")
|
||||
@@ -212,15 +191,6 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||
.global(true)
|
||||
.help("Show extra information header"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ASK_SEED_PHRASE_ARG.name)
|
||||
.long(ASK_SEED_PHRASE_ARG.long)
|
||||
.value_name("KEYPAIR NAME")
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.possible_values(&["keypair"])
|
||||
.help(ASK_SEED_PHRASE_ARG.help),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(SKIP_SEED_PHRASE_VALIDATION_ARG.name)
|
||||
.long(SKIP_SEED_PHRASE_VALIDATION_ARG.long)
|
||||
|
Reference in New Issue
Block a user