diff --git a/Cargo.lock b/Cargo.lock index 67856084369e0c..8f9590d17cf498 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3698,7 +3698,7 @@ dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-hardware-wallet 0.24.0", + "solana-remote-wallet 0.24.0", "solana-sdk 0.24.0", "tiny-bip39 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3975,20 +3975,6 @@ dependencies = [ "solana-sdk 0.24.0", ] -[[package]] -name = "solana-hardware-wallet" -version = "0.24.0" -dependencies = [ - "base32 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hidapi 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rusb 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 0.24.0", - "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "solana-install" version = "0.24.0" @@ -4334,6 +4320,20 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "solana-remote-wallet" +version = "0.24.0" +dependencies = [ + "base32 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hidapi 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rusb 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 0.24.0", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "solana-runtime" version = "0.24.0" diff --git a/clap-utils/Cargo.toml b/clap-utils/Cargo.toml index e75d7a8c188927..ea3d4234311209 100644 --- a/clap-utils/Cargo.toml +++ b/clap-utils/Cargo.toml @@ -12,6 +12,7 @@ edition = "2018" clap = "2.33.0" rpassword = "4.0" semver = "0.9.0" +solana-remote-wallet = { path = "../remote-wallet", version = "0.24.0" } solana-sdk = { path = "../sdk", version = "0.24.0" } tiny-bip39 = "0.7.0" url = "2.1.0" diff --git a/clap-utils/src/input_parsers.rs b/clap-utils/src/input_parsers.rs index cf12d5c7ec019c..08c3e119acbbe4 100644 --- a/clap-utils/src/input_parsers.rs +++ b/clap-utils/src/input_parsers.rs @@ -1,6 +1,7 @@ use crate::keypair::{keypair_from_seed_phrase, ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG}; use chrono::DateTime; use clap::ArgMatches; +use solana_remote_wallet::remote_wallet::DerivationPath; use solana_sdk::{ clock::UnixTimestamp, native_token::sol_to_lamports, @@ -100,6 +101,16 @@ pub fn amount_of(matches: &ArgMatches<'_>, name: &str, unit: &str) -> Option, name: &str) -> Option { + 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::().unwrap(); + let change = parts.next().map(|change| change.parse::().unwrap()); + DerivationPath { account, change } + }) +} + #[cfg(test)] mod tests { use super::*; @@ -277,4 +288,40 @@ mod tests { .get_matches_from(vec!["test", "--single", "1.5", "--unit", "lamports"]); assert_eq!(amount_of(&matches, "single", "unit"), None); } + + #[test] + fn test_derivation_of() { + let matches = app() + .clone() + .get_matches_from(vec!["test", "--single", "2/3"]); + assert_eq!( + derivation_of(&matches, "single"), + Some(DerivationPath { + account: 2, + change: Some(3) + }) + ); + assert_eq!(derivation_of(&matches, "another"), None); + let matches = app() + .clone() + .get_matches_from(vec!["test", "--single", "2"]); + assert_eq!( + derivation_of(&matches, "single"), + Some(DerivationPath { + account: 2, + change: None + }) + ); + assert_eq!(derivation_of(&matches, "another"), None); + let matches = app() + .clone() + .get_matches_from(vec!["test", "--single", "2'/3'"]); + assert_eq!( + derivation_of(&matches, "single"), + Some(DerivationPath { + account: 2, + change: Some(3) + }) + ); + } } diff --git a/clap-utils/src/input_validators.rs b/clap-utils/src/input_validators.rs index 948765b2dda403..2b49c4f42975ee 100644 --- a/clap-utils/src/input_validators.rs +++ b/clap-utils/src/input_validators.rs @@ -1,8 +1,10 @@ use crate::keypair::ASK_KEYWORD; use chrono::DateTime; -use solana_sdk::hash::Hash; -use solana_sdk::pubkey::Pubkey; -use solana_sdk::signature::{read_keypair_file, Signature}; +use solana_sdk::{ + hash::Hash, + pubkey::Pubkey, + signature::{read_keypair_file, Signature}, +}; use std::str::FromStr; // Return an error if a pubkey cannot be parsed. @@ -141,3 +143,47 @@ pub fn is_rfc3339_datetime(value: String) -> Result<(), String> { .map(|_| ()) .map_err(|e| format!("{:?}", e)) } + +pub fn is_derivation(value: String) -> Result<(), String> { + let value = value.replace("'", ""); + let mut parts = value.split('/'); + let account = parts.next().unwrap(); + account + .parse::() + .map_err(|e| { + format!( + "Unable to parse derivation, provided: {}, err: {:?}", + account, e + ) + }) + .and_then(|_| { + if let Some(change) = parts.next() { + change.parse::().map_err(|e| { + format!( + "Unable to parse derivation, provided: {}, err: {:?}", + change, e + ) + }) + } else { + Ok(0) + } + }) + .map(|_| ()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_derivation() { + assert_eq!(is_derivation("2".to_string()), Ok(())); + assert_eq!(is_derivation("0".to_string()), Ok(())); + assert_eq!(is_derivation("0/2".to_string()), Ok(())); + assert_eq!(is_derivation("0'/2'".to_string()), Ok(())); + assert!(is_derivation("a".to_string()).is_err()); + assert!(is_derivation("65537".to_string()).is_err()); + assert!(is_derivation("a/b".to_string()).is_err()); + assert!(is_derivation("0/65537".to_string()).is_err()); + } +}