Skip to content

Commit

Permalink
Cli api adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyera Eulberg committed Feb 6, 2020
1 parent 3fad635 commit 1122a60
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 52 deletions.
16 changes: 9 additions & 7 deletions clap-utils/src/input_parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,16 @@ pub fn amount_of(matches: &ArgMatches<'_>, name: &str, unit: &str) -> Option<u64
}
}

pub fn derivation_from_str(derivation_str: &str) -> DerivationPath {
let derivation_str = derivation_str.replace("'", "");
let mut parts = derivation_str.split('/');
let account = parts.next().unwrap().parse::<u16>().unwrap();
let change = parts.next().map(|change| change.parse::<u16>().unwrap());
DerivationPath { account, change }
}

pub fn derivation_of(matches: &ArgMatches<'_>, name: &str) -> Option<DerivationPath> {
matches.value_of(name).map(|derivation_str| {
let derivation_str = derivation_str.replace("'", "");
let mut parts = derivation_str.split('/');
let account = parts.next().unwrap().parse::<u16>().unwrap();
let change = parts.next().map(|change| change.parse::<u16>().unwrap());
DerivationPath { account, change }
})
matches.value_of(name).map(|derivation_str| derivation_from_str(derivation_str))
}

#[cfg(test)]
Expand Down
4 changes: 3 additions & 1 deletion cli-config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ lazy_static! {
pub struct Config {
pub url: String,
pub keypair_path: String,
pub derivation_path: String,
}

impl Config {
pub fn new(url: &str, keypair_path: &str) -> Self {
pub fn new(url: &str, keypair_path: &str, derivation_path: &str) -> Self {
Self {
url: url.to_string(),
keypair_path: keypair_path.to_string(),
derivation_path: derivation_path.to_string(),
}
}

Expand Down
15 changes: 10 additions & 5 deletions cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,19 +432,24 @@ impl CliConfig {
keypair_path.to_str().unwrap().to_string()
}

pub fn default_derivation_path() -> String {
"0".to_string()
}

pub fn default_json_rpc_url() -> String {
"http://127.0.0.1:8899".to_string()
}

pub(crate) fn pubkey(&self) -> Result<Pubkey, Box<dyn std::error::Error>> {
if let Some(path) = &self.keypair_path {
if path.starts_with("usb://") {
let (remote_wallet_info, mut derivation_path) =
RemoteWalletInfo::parse_path(path.to_string())?;
if let Some(derivation) = &self.derivation_path {
let remote_wallet_info = RemoteWalletInfo::parse_path(path.to_string())?;
let derivation_path = if let Some(derivation) = &self.derivation_path {
let derivation = derivation.clone();
derivation_path = derivation;
}
derivation
} else {
DerivationPath::default()
};
let ledger = get_ledger_from_info(remote_wallet_info)?;
return Ok(ledger.get_pubkey(derivation_path)?);
}
Expand Down
37 changes: 29 additions & 8 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use clap::{crate_description, crate_name, AppSettings, Arg, ArgGroup, ArgMatches
use console::style;

use solana_clap_utils::{
input_parsers::derivation_of,
input_parsers::{derivation_of, derivation_from_str},
input_validators::{is_derivation, is_url},
keypair::{
self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG,
Expand All @@ -26,27 +26,37 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
let config = Config::load(config_file).unwrap_or_default();
if let Some(field) = subcommand_matches.value_of("specific_setting") {
let (field_name, value, default_value) = match field {
"url" => ("RPC Url", config.url, CliConfig::default_json_rpc_url()),
"url" => ("RPC URL", config.url, CliConfig::default_json_rpc_url()),
"keypair" => (
"Key Path",
"Keypair Path",
config.keypair_path,
CliConfig::default_keypair_path(),
),
"derivation-path" => (
"Derivation Path",
config.derivation_path,
CliConfig::default_derivation_path(),
),
_ => unreachable!(),
};
println_name_value_or(&format!("{}:", field_name), &value, &default_value);
} else {
println_name_value("Config File:", config_file);
println_name_value_or(
"RPC Url:",
"RPC URL:",
&config.url,
&CliConfig::default_json_rpc_url(),
);
println_name_value_or(
"Key Path:",
"Keypair Path:",
&config.keypair_path,
&CliConfig::default_keypair_path(),
);
println_name_value_or(
"Derivation Path:",
&config.derivation_path,
&CliConfig::default_derivation_path(),
);
}
} else {
println!(
Expand All @@ -65,10 +75,14 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
if let Some(keypair) = subcommand_matches.value_of("keypair") {
config.keypair_path = keypair.to_string();
}
if let Some(derivation_path) = subcommand_matches.value_of("derivation_path") {
config.derivation_path = derivation_path.to_string();
}
config.save(config_file)?;
println_name_value("Config File:", config_file);
println_name_value("RPC URL:", &config.url);
println_name_value("Keypair Path:", &config.keypair_path);
println_name_value("Derivation Path:", &config.derivation_path);
} else {
println!(
"{} Either provide the `--config` arg or ensure home directory exists to use the default config location",
Expand Down Expand Up @@ -145,13 +159,19 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<CliConfig, Box<dyn error::
let default = CliConfig::default();
(default.keypair, None)
};
let derivation_path =
derivation_of(matches, "derivation_path").or(if config.derivation_path != "" {
Some(derivation_from_str(&config.derivation_path))
} else {
None
});

Ok(CliConfig {
command,
json_rpc_url,
keypair,
keypair_path,
derivation_path: derivation_of(matches, "derivation_path"),
derivation_path,
rpc_client: None,
verbose: matches.is_present("verbose"),
})
Expand Down Expand Up @@ -201,6 +221,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'")
Expand Down Expand Up @@ -240,7 +261,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.index(1)
.value_name("CONFIG_FIELD")
.takes_value(true)
.possible_values(&["url", "keypair"])
.possible_values(&["url", "keypair", "derivation-path"])
.help("Return a specific config setting"),
),
)
Expand All @@ -249,7 +270,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.about("Set a config setting")
.group(
ArgGroup::with_name("config_settings")
.args(&["json_rpc_url", "keypair"])
.args(&["json_rpc_url", "keypair", "derivation_path"])
.multiple(true)
.required(true),
),
Expand Down
7 changes: 2 additions & 5 deletions keygen/src/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,8 @@ fn get_pubkey_from_matches(
keypair_from_seed_phrase("pubkey recovery", skip_validation, false)
.map(|keypair| keypair.pubkey())
} else if keypair.starts_with("usb://") {
let (remote_wallet_info, mut derivation_path) =
RemoteWalletInfo::parse_path(keypair.to_string())?;
if let Some(derivation) = derivation_of(matches, "derivation_path") {
derivation_path = derivation;
}
let remote_wallet_info = RemoteWalletInfo::parse_path(keypair.to_string())?;
let derivation_path = derivation_of(matches, "derivation_path").unwrap_or_default();
let ledger = get_ledger_from_info(remote_wallet_info)?;
Ok(ledger.get_pubkey(derivation_path)?)
} else {
Expand Down
35 changes: 9 additions & 26 deletions remote-wallet/src/remote_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ pub struct RemoteWalletInfo {
}

impl RemoteWalletInfo {
pub fn parse_path(mut path: String) -> Result<(Self, DerivationPath), RemoteWalletError> {
pub fn parse_path(mut path: String) -> Result<Self, RemoteWalletError> {
if is_remote_wallet_path(&path).is_ok() {
let path = path.split_off(6);
let mut parts = path.split('/');
Expand All @@ -197,18 +197,7 @@ impl RemoteWalletInfo {
.next()
.and_then(|pubkey_str| Pubkey::from_str(pubkey_str).ok())
.unwrap_or_default();
let derivation_path = parts
.next()
.map(|account| {
let account = account.parse::<u16>().unwrap();
let change = parts.next().and_then(|change| change.parse::<u16>().ok());
DerivationPath { account, change }
})
.unwrap_or(DerivationPath {
account: 0,
change: None,
});
Ok((wallet_info, derivation_path))
Ok(wallet_info)
} else {
Err(RemoteWalletError::InvalidPath(path))
}
Expand Down Expand Up @@ -314,19 +303,13 @@ mod tests {
fn test_parse_path() {
let pubkey = Pubkey::new_rand();
assert_eq!(
RemoteWalletInfo::parse_path(format!("usb://ledger/nano-s/{:?}/1/2", pubkey)).unwrap(),
(
RemoteWalletInfo {
model: "nano-s".to_string(),
manufacturer: "ledger".to_string(),
serial: "".to_string(),
pubkey,
},
DerivationPath {
account: 1,
change: Some(2),
}
)
RemoteWalletInfo::parse_path(format!("usb://ledger/nano-s/{:?}", pubkey)).unwrap(),
RemoteWalletInfo {
model: "nano-s".to_string(),
manufacturer: "ledger".to_string(),
serial: "".to_string(),
pubkey,
}
)
}

Expand Down

0 comments on commit 1122a60

Please sign in to comment.