Add 'recover' option to grin wallet init (#2330)

* Only update outputs with unconfirmed transactions outstanding

* add further check for Unspent output that have been spent to check_repair

* rename  to

* make updating all outputs optional API parameter. do full update before a wallet check, remove unspent->spent check from check process

* rustfmt

* typo

* add recover from phrase option to init

* rustfmt

* don't panic if recover is cancelled, grin-wallet.toml is created but wallet_data dir doesn't yet exits

* rustfmt
This commit is contained in:
Yeastplume 2019-01-10 12:06:12 +00:00 committed by GitHub
parent 4191b15410
commit cd9a539288
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 53 additions and 12 deletions

View file

@ -44,7 +44,8 @@ const SERVER_LOG_FILE_NAME: &'static str = "grin-server.log";
const WALLET_LOG_FILE_NAME: &'static str = "grin-wallet.log";
const GRIN_HOME: &'static str = ".grin";
const GRIN_CHAIN_DIR: &'static str = "chain_data";
const GRIN_WALLET_DIR: &'static str = "wallet_data";
/// Wallet data directory
pub const GRIN_WALLET_DIR: &'static str = "wallet_data";
const API_SECRET_FILE_NAME: &'static str = ".api_secret";
fn get_grin_path(chain_type: &global::ChainTypes) -> Result<PathBuf, ConfigError> {

View file

@ -36,5 +36,5 @@ mod comments;
pub mod config;
pub mod types;
pub use crate::config::{initial_setup_server, initial_setup_wallet};
pub use crate::config::{initial_setup_server, initial_setup_wallet, GRIN_WALLET_DIR};
pub use crate::types::{ConfigError, ConfigMembers, GlobalConfig, GlobalWalletConfig};

View file

@ -272,7 +272,7 @@ impl LocalServerContainer {
self.wallet_config.owner_api_include_foreign = Some(self.config.owner_api_include_foreign);
let _ = fs::create_dir_all(self.wallet_config.clone().data_file_dir);
let r = wallet::WalletSeed::init_file(&self.wallet_config, 32, "");
let r = wallet::WalletSeed::init_file(&self.wallet_config, 32, None, "");
let client_n = HTTPNodeClient::new(&self.wallet_config.check_node_api_http_addr, None);
@ -331,7 +331,7 @@ impl LocalServerContainer {
pub fn get_wallet_seed(config: &WalletConfig) -> wallet::WalletSeed {
let _ = fs::create_dir_all(config.clone().data_file_dir);
wallet::WalletSeed::init_file(config, 32, "").unwrap();
wallet::WalletSeed::init_file(config, 32, None, "").unwrap();
let wallet_seed =
wallet::WalletSeed::from_file(config, "").expect("Failed to read wallet seed file.");
wallet_seed

View file

@ -879,7 +879,7 @@ pub fn create_wallet(
) -> Arc<Mutex<dyn WalletInst<HTTPNodeClient, keychain::ExtKeychain>>> {
let mut wallet_config = WalletConfig::default();
wallet_config.data_file_dir = String::from(dir);
let _ = wallet::WalletSeed::init_file(&wallet_config, 32, "");
let _ = wallet::WalletSeed::init_file(&wallet_config, 32, None, "");
let mut wallet: LMDBBackend<HTTPNodeClient, keychain::ExtKeychain> =
LMDBBackend::new(wallet_config.clone(), "", client_n).unwrap_or_else(|e| {
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)

View file

@ -13,7 +13,7 @@
// limitations under the License.
/// Grin configuration file output command
use crate::config::{GlobalConfig, GlobalWalletConfig};
use crate::config::{GlobalConfig, GlobalWalletConfig, GRIN_WALLET_DIR};
use crate::core::global;
use std::env;
@ -52,12 +52,22 @@ pub fn config_command_wallet(chain_type: &global::ChainTypes, file_name: &str) {
});
let mut config_file_name = current_dir.clone();
config_file_name.push(file_name);
if config_file_name.exists() {
let mut data_dir_name = current_dir.clone();
data_dir_name.push(GRIN_WALLET_DIR);
if config_file_name.exists() && data_dir_name.exists() {
panic!(
"{} already exists in the target directory. Please remove it first",
file_name
);
}
// just leave as is if file exists but there's no data dir
if config_file_name.exists() {
return;
}
default_config.update_paths(&current_dir);
default_config
.write_to_file(config_file_name.to_str().unwrap())

View file

@ -22,7 +22,7 @@ use std::time::Duration;
pub fn _init_wallet_seed(wallet_config: WalletConfig, password: &str) {
if let Err(_) = WalletSeed::from_file(&wallet_config, password) {
WalletSeed::init_file(&wallet_config, 32, password)
WalletSeed::init_file(&wallet_config, 32, None, password)
.expect("Failed to create wallet seed file.");
};
}

View file

@ -233,15 +233,28 @@ pub fn parse_init_args(
false => 32,
true => 16,
};
println!("Please enter a password for your new wallet");
let recovery_phrase = match args.is_present("recover") {
true => Some(prompt_recovery_phrase()?),
false => None,
};
if recovery_phrase.is_some() {
println!("Please provide a new password for the recovered wallet");
} else {
println!("Please enter a password for your new wallet");
}
let password = match g_args.password.clone() {
Some(p) => p,
None => prompt_password_confirm(),
};
Ok(command::InitArgs {
list_length: list_length,
password: password,
config: config.clone(),
recovery_phrase: recovery_phrase,
restore: false,
})
}

View file

@ -284,6 +284,11 @@ subcommands:
short: s
long: short_wordlist
takes_value: false
- recover:
help: Initialize new wallet using a recovery phrase
short: r
long: recover
takes_value: false
- recover:
about: Recover a wallet.seed file from a recovery phrase (default) or displays a recovery phrase for an existing seed file
args:

View file

@ -51,10 +51,17 @@ pub struct InitArgs {
pub list_length: usize,
pub password: String,
pub config: WalletConfig,
pub recovery_phrase: Option<String>,
pub restore: bool,
}
pub fn init(g_args: &GlobalArgs, args: InitArgs) -> Result<(), Error> {
WalletSeed::init_file(&args.config, args.list_length, &args.password)?;
WalletSeed::init_file(
&args.config,
args.list_length,
args.recovery_phrase,
&args.password,
)?;
info!("Wallet seed file created");
let client_n = HTTPNodeClient::new(
&args.config.check_node_api_http_addr,

View file

@ -160,7 +160,7 @@ where
{
let mut wallet_config = WalletConfig::default();
wallet_config.data_file_dir = String::from(dir);
let _ = WalletSeed::init_file(&wallet_config, 32, "");
let _ = WalletSeed::init_file(&wallet_config, 32, None, "");
let mut wallet = LMDBBackend::new(wallet_config.clone(), "", n_client)
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config));
wallet.open_with_credentials().unwrap_or_else(|e| {

View file

@ -216,6 +216,7 @@ impl WalletSeed {
pub fn init_file(
wallet_config: &WalletConfig,
seed_length: usize,
recovery_phrase: Option<String>,
password: &str,
) -> Result<WalletSeed, Error> {
// create directory if it doesn't exist
@ -229,7 +230,11 @@ impl WalletSeed {
warn!("Generating wallet seed file at: {}", seed_file_path);
let _ = WalletSeed::seed_file_exists(wallet_config)?;
let seed = WalletSeed::init_new(seed_length);
let seed = match recovery_phrase {
Some(p) => WalletSeed::from_mnemonic(&p)?,
None => WalletSeed::init_new(seed_length),
};
let enc_seed = EncryptedWalletSeed::from_seed(&seed, password)?;
let enc_seed_json = serde_json::to_string_pretty(&enc_seed).context(ErrorKind::Format)?;
let mut file = File::create(seed_file_path).context(ErrorKind::IO)?;