diff --git a/Cargo.lock b/Cargo.lock index c1d9ef2..d112ce2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2193,8 +2193,8 @@ dependencies = [ [[package]] name = "grin_wallet_api" -version = "5.3.1" -source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.1#1f8824d0bca49e4f3723d4c98dd68d2f3e4ceee7" +version = "5.3.2" +source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.2#a58c44b930161533701d97141535115428526403" dependencies = [ "base64 0.12.3", "chrono", @@ -2217,8 +2217,8 @@ dependencies = [ [[package]] name = "grin_wallet_config" -version = "5.3.1" -source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.1#1f8824d0bca49e4f3723d4c98dd68d2f3e4ceee7" +version = "5.3.2" +source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.2#a58c44b930161533701d97141535115428526403" dependencies = [ "dirs", "grin_wallet_util", @@ -2231,8 +2231,8 @@ dependencies = [ [[package]] name = "grin_wallet_controller" -version = "5.3.1" -source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.1#1f8824d0bca49e4f3723d4c98dd68d2f3e4ceee7" +version = "5.3.2" +source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.2#a58c44b930161533701d97141535115428526403" dependencies = [ "chrono", "colored", @@ -2266,8 +2266,8 @@ dependencies = [ [[package]] name = "grin_wallet_impls" -version = "5.3.1" -source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.1#1f8824d0bca49e4f3723d4c98dd68d2f3e4ceee7" +version = "5.3.2" +source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.2#a58c44b930161533701d97141535115428526403" dependencies = [ "base64 0.12.3", "blake2-rfc", @@ -2301,8 +2301,8 @@ dependencies = [ [[package]] name = "grin_wallet_libwallet" -version = "5.3.1" -source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.1#1f8824d0bca49e4f3723d4c98dd68d2f3e4ceee7" +version = "5.3.2" +source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.2#a58c44b930161533701d97141535115428526403" dependencies = [ "base64 0.12.3", "bch", @@ -2361,8 +2361,8 @@ dependencies = [ [[package]] name = "grin_wallet_util" -version = "5.3.1" -source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.1#1f8824d0bca49e4f3723d4c98dd68d2f3e4ceee7" +version = "5.3.2" +source = "git+https://github.com/mwcproject/mwc-wallet?tag=5.3.2#a58c44b930161533701d97141535115428526403" dependencies = [ "data-encoding", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index dcbc851..6b8310b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,12 +42,12 @@ grin_util = { git = "https://github.com/mwcproject/mwc-node", tag = "5.3.2" } grin_api = { git = "https://github.com/mwcproject/mwc-node", tag = "5.3.2" } grin_store = { git = "https://github.com/mwcproject/mwc-node", tag = "5.3.2" } grin_p2p = { git = "https://github.com/mwcproject/mwc-node", tag = "5.3.2" } -grin_wallet_impls = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.1" } -grin_wallet_libwallet = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.1" } -grin_wallet_api = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.1" } -grin_wallet_controller = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.1" } -grin_wallet_config = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.1" } -grin_wallet_util = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.1" } +grin_wallet_impls = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.2" } +grin_wallet_libwallet = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.2" } +grin_wallet_api = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.2" } +grin_wallet_controller = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.2" } +grin_wallet_config = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.2" } +grin_wallet_util = { git = "https://github.com/mwcproject/mwc-wallet", tag = "5.3.2" } # For bleeding edge #grin_core = { git = "https://github.com/mwcproject/mwc-node", branch = "master" } diff --git a/src/cli/parser.rs b/src/cli/parser.rs index d11553b..cc7d457 100644 --- a/src/cli/parser.rs +++ b/src/cli/parser.rs @@ -75,9 +75,12 @@ impl<'a, 'b> Parser { .min_values(0) ) .arg( - Arg::from_usage("[short] -s, --short 'short seed mnemonic'") + Arg::from_usage("[short] -s, --short 'short seed mnemonic, 12 seed words'") .takes_value(false) ) + .arg( + Arg::from_usage("[seed_length] -l, --seed_length= 'seed mnemonic length, one of 12, 15, 18, 21, 24'") + ) ) .subcommand( SubCommand::with_name("unlock") @@ -347,10 +350,6 @@ impl<'a, 'b> Parser { Arg::from_usage("[passphrase] -p, --passphrase= 'the passphrase to use'") .min_values(0) ) - .arg( - Arg::from_usage("[short] -s, --short 'short seed mnemonic'") - .takes_value(false) - ) ) .subcommand( SubCommand::with_name("recover") @@ -362,10 +361,6 @@ impl<'a, 'b> Parser { .arg( Arg::from_usage("[words] -m, --mnemonic=... 'the seed mnemonic'") ) - .arg( - Arg::from_usage("[short] -s, --short 'short seed mnemonic'") - .takes_value(false) - ) .arg( Arg::from_usage("[display] -d, --display= 'display the current mnemonic'") ) diff --git a/src/common/error.rs b/src/common/error.rs index 6e507ce..20da9d2 100644 --- a/src/common/error.rs +++ b/src/common/error.rs @@ -2,6 +2,8 @@ use std::env::VarError; #[derive(Clone, Eq, PartialEq, Debug, thiserror::Error)] pub enum Error { + #[error("Wallet seed length must be a number between 12 and 24, divisible by 3. Requested {0} wordrs.")] + WalletSeedIncorrectLength(usize), #[error("could not open wallet seed!")] WalletSeedCouldNotBeOpened, #[error("transaction doesn't have a proof!")] diff --git a/src/main.rs b/src/main.rs index b5fa61c..f8b0b0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -573,12 +573,12 @@ fn main() { SubCommand::with_name("init") .about("initializes the wallet") .arg(Arg::from_usage("[short] -s --short 'short seed mnemonic'")) + .arg(Arg::from_usage("[seed_length] -l, --seed_length= 'seed mnemonic length, one of 12, 15, 18, 21, 24'")) ) .subcommand( SubCommand::with_name("recover") .about("recover wallet from mnemonic or displays the current mnemonic") .arg(Arg::from_usage("[words] -m, --mnemonic=... 'the seed mnemonic'")) - .arg(Arg::from_usage("[short] -s, --short 'short seed mnemonic'")) ) .subcommand(SubCommand::with_name("state").about("print wallet initialization state and exit")) .get_matches(); @@ -675,13 +675,14 @@ fn main() { println!(); println!("Set an optional password to secure your wallet with. Leave blank for no password."); println!(); - let mut short_seed = ""; + let mut seed_length = "24"; if let Some(init) = matches.subcommand_matches("init") { + seed_length = init.value_of("seed_length").unwrap_or("24"); if init.is_present("short") { - short_seed = "-s " + seed_length = "12"; } }; - let cmd = format!("init {}-p {}", short_seed, &passphrase); + let cmd = format!("init --seed_length {} -p {}", seed_length, &passphrase); if let Err(err) = do_command( &cmd, &mut config, @@ -701,19 +702,13 @@ fn main() { print!("Mnemonic: "); io::stdout().flush().unwrap(); let mut mnemonic = String::new(); - let mut short_seed = ""; if let Some(recover) = matches.subcommand_matches("recover") { if recover.is_present("words") { - mnemonic = matches - .subcommand_matches("recover") - .unwrap() + mnemonic = recover .value_of("words") .unwrap() .to_string(); } - if recover.is_present("short") { - short_seed = "-s " - } } else { if io::stdin().read_line(&mut mnemonic).unwrap() == 0 { println!("{}: invalid mnemonic", "ERROR".bright_red()); @@ -726,7 +721,7 @@ fn main() { println!("Set an optional password to secure your wallet with. Leave blank for no password."); println!(); // TODO: refactor this - let cmd = format!("recover {}-m {} -p {}", short_seed, mnemonic, &passphrase); + let cmd = format!("recover -m {} -p {}", mnemonic, &passphrase); if let Err(err) = do_command( &cmd, &mut config, @@ -1109,9 +1104,16 @@ fn do_command( let passphrase = grin_util::ZeroingString::from(passphrase); - let short_seed = args.is_present("short"); + let mut seed_length = args.value_of("seed_length") + .unwrap_or("24") + .parse::() + .map_err(|_| Error::ArgumentError("Expected integer 'seed_length' value".to_string()))?; - let seed = wallet.lock().init(config, passphrase.clone(), true, short_seed)?; + if args.is_present("short") { + seed_length = 12; + } + + let seed = wallet.lock().init(config, passphrase.clone(), true, seed_length)?; println!( "{}", @@ -1124,7 +1126,7 @@ fn do_command( { let mut wallet_inst = wallet.lock(); - wallet_inst.complete(seed, config, "default", passphrase, true, short_seed)?; + wallet_inst.complete(seed, config, "default", passphrase, true, seed_length)?; wallet_inst.update_tip_as_last_scanned()?; } show_address(config, wallet, false)?; @@ -2195,12 +2197,20 @@ fn do_command( println!("restoring... please wait as this could take a few minutes to complete."); let passphrase = ZeroingString::from(passphrase.as_str()); - let short_seed = args.is_present("short"); + + let mut seed_length = args.value_of("seed_length") + .unwrap_or("24") + .parse::() + .map_err(|_| Error::ArgumentError("Expected integer 'seed_length' value".to_string()))?; + + if args.is_present("short") { + seed_length = 12; + } { let mut w = wallet.lock(); - let seed = w.init(config, passphrase.clone(), false, short_seed)?; - w.complete(seed, config, "default", passphrase.clone(), true, short_seed)?; + let seed = w.init(config, passphrase.clone(), false, seed_length)?; + w.complete(seed, config, "default", passphrase.clone(), true, seed_length)?; w.restore_state()?; w.update_tip_as_last_scanned()?; } @@ -2230,30 +2240,24 @@ fn do_command( if getenv("MWC_MNEMONIC")?.is_some() { let envvar = env::var("MWC_MNEMONIC")?; let words: Vec<&str> = envvar.split(" ").collect(); - let short_seed = match words.len() { - 16 => true, - _ => false - }; + let seed_words = words.len(); { println!("Recovering with environment variable words: {:?}", words); let mut w = wallet.lock(); w.restore_seed(config, &words, passphrase.clone())?; - let seed = w.init(config, passphrase.clone(), false, short_seed)?; - w.complete(seed, config, "default", passphrase.clone(), true, short_seed)?; + let seed = w.init(config, passphrase.clone(), false, seed_words)?; + w.complete(seed, config, "default", passphrase.clone(), true, seed_words)?; w.restore_state()?; } } else { let words: Vec<&str> = words.collect(); - let short_seed = match words.len() { - 16 => true, - _ => false - }; + let seed_words = words.len(); { println!("Recovering with commandline specified words: {:?}", words); let mut w = wallet.lock(); w.restore_seed(config, &words, passphrase.clone())?; - let seed = w.init(config, passphrase.clone(), false, short_seed)?; - w.complete(seed, config, "default", passphrase.clone(), true, short_seed)?; + let seed = w.init(config, passphrase.clone(), false, seed_words)?; + w.complete(seed, config, "default", passphrase.clone(), true, seed_words)?; w.restore_state()?; } } diff --git a/src/wallet/wallet.rs b/src/wallet/wallet.rs index c022ccf..c746b20 100644 --- a/src/wallet/wallet.rs +++ b/src/wallet/wallet.rs @@ -176,9 +176,9 @@ impl Wallet { account: &str, passphrase: grin_util::ZeroingString, create_new: bool, - short_seed: bool + seed_words_num: usize, ) -> Result { - let seed = self.init_seed(&config, passphrase.clone(), create_new, true, Some(seed), short_seed)?; + let seed = self.init_seed(&config, passphrase.clone(), create_new, true, Some(seed), seed_words_num)?; //self.init_backend(&wallet_config, &config, passphrase)?; self.unlock(config, account, passphrase)?; Ok(seed) @@ -189,9 +189,9 @@ impl Wallet { config: &Wallet713Config, passphrase: grin_util::ZeroingString, create_new: bool, - short_seed: bool + seed_words_num: usize ) -> Result { - let seed = self.init_seed(&config, passphrase, create_new, false, None, short_seed)?; + let seed = self.init_seed(&config, passphrase, create_new, false, None, seed_words_num)?; Ok(seed) } @@ -870,14 +870,14 @@ impl Wallet { create_new: bool, create_file: bool, seed: Option, - short_seed: bool + seed_words_num: usize ) -> Result { let data_file_dir = config.get_data_path_str()?; let result = WalletSeed::from_file(&data_file_dir, passphrase.clone()); - let seed_lenght = match short_seed { - true => 16, - false => 32 - }; + if seed_words_num < 12 || seed_words_num>24 || seed_words_num % 3 !=0 { + return Err(Error::WalletSeedIncorrectLength(seed_words_num)); + } + let seed_lenght = seed_words_num * 4 / 3; let seed = match result { Ok(seed) => seed, Err(_) => {