mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
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:
parent
4191b15410
commit
cd9a539288
11 changed files with 53 additions and 12 deletions
|
@ -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 WALLET_LOG_FILE_NAME: &'static str = "grin-wallet.log";
|
||||||
const GRIN_HOME: &'static str = ".grin";
|
const GRIN_HOME: &'static str = ".grin";
|
||||||
const GRIN_CHAIN_DIR: &'static str = "chain_data";
|
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";
|
const API_SECRET_FILE_NAME: &'static str = ".api_secret";
|
||||||
|
|
||||||
fn get_grin_path(chain_type: &global::ChainTypes) -> Result<PathBuf, ConfigError> {
|
fn get_grin_path(chain_type: &global::ChainTypes) -> Result<PathBuf, ConfigError> {
|
||||||
|
|
|
@ -36,5 +36,5 @@ mod comments;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod types;
|
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};
|
pub use crate::types::{ConfigError, ConfigMembers, GlobalConfig, GlobalWalletConfig};
|
||||||
|
|
|
@ -272,7 +272,7 @@ impl LocalServerContainer {
|
||||||
self.wallet_config.owner_api_include_foreign = Some(self.config.owner_api_include_foreign);
|
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 _ = 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);
|
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 {
|
pub fn get_wallet_seed(config: &WalletConfig) -> wallet::WalletSeed {
|
||||||
let _ = fs::create_dir_all(config.clone().data_file_dir);
|
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 =
|
let wallet_seed =
|
||||||
wallet::WalletSeed::from_file(config, "").expect("Failed to read wallet seed file.");
|
wallet::WalletSeed::from_file(config, "").expect("Failed to read wallet seed file.");
|
||||||
wallet_seed
|
wallet_seed
|
||||||
|
|
|
@ -879,7 +879,7 @@ pub fn create_wallet(
|
||||||
) -> Arc<Mutex<dyn WalletInst<HTTPNodeClient, keychain::ExtKeychain>>> {
|
) -> Arc<Mutex<dyn WalletInst<HTTPNodeClient, keychain::ExtKeychain>>> {
|
||||||
let mut wallet_config = WalletConfig::default();
|
let mut wallet_config = WalletConfig::default();
|
||||||
wallet_config.data_file_dir = String::from(dir);
|
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> =
|
let mut wallet: LMDBBackend<HTTPNodeClient, keychain::ExtKeychain> =
|
||||||
LMDBBackend::new(wallet_config.clone(), "", client_n).unwrap_or_else(|e| {
|
LMDBBackend::new(wallet_config.clone(), "", client_n).unwrap_or_else(|e| {
|
||||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
/// Grin configuration file output command
|
/// Grin configuration file output command
|
||||||
use crate::config::{GlobalConfig, GlobalWalletConfig};
|
use crate::config::{GlobalConfig, GlobalWalletConfig, GRIN_WALLET_DIR};
|
||||||
use crate::core::global;
|
use crate::core::global;
|
||||||
use std::env;
|
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();
|
let mut config_file_name = current_dir.clone();
|
||||||
config_file_name.push(file_name);
|
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!(
|
panic!(
|
||||||
"{} already exists in the target directory. Please remove it first",
|
"{} already exists in the target directory. Please remove it first",
|
||||||
file_name
|
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(¤t_dir);
|
default_config.update_paths(¤t_dir);
|
||||||
default_config
|
default_config
|
||||||
.write_to_file(config_file_name.to_str().unwrap())
|
.write_to_file(config_file_name.to_str().unwrap())
|
||||||
|
|
|
@ -22,7 +22,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
pub fn _init_wallet_seed(wallet_config: WalletConfig, password: &str) {
|
pub fn _init_wallet_seed(wallet_config: WalletConfig, password: &str) {
|
||||||
if let Err(_) = WalletSeed::from_file(&wallet_config, password) {
|
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.");
|
.expect("Failed to create wallet seed file.");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,15 +233,28 @@ pub fn parse_init_args(
|
||||||
false => 32,
|
false => 32,
|
||||||
true => 16,
|
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() {
|
let password = match g_args.password.clone() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => prompt_password_confirm(),
|
None => prompt_password_confirm(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(command::InitArgs {
|
Ok(command::InitArgs {
|
||||||
list_length: list_length,
|
list_length: list_length,
|
||||||
password: password,
|
password: password,
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
|
recovery_phrase: recovery_phrase,
|
||||||
|
restore: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,11 @@ subcommands:
|
||||||
short: s
|
short: s
|
||||||
long: short_wordlist
|
long: short_wordlist
|
||||||
takes_value: false
|
takes_value: false
|
||||||
|
- recover:
|
||||||
|
help: Initialize new wallet using a recovery phrase
|
||||||
|
short: r
|
||||||
|
long: recover
|
||||||
|
takes_value: false
|
||||||
- recover:
|
- recover:
|
||||||
about: Recover a wallet.seed file from a recovery phrase (default) or displays a recovery phrase for an existing seed file
|
about: Recover a wallet.seed file from a recovery phrase (default) or displays a recovery phrase for an existing seed file
|
||||||
args:
|
args:
|
||||||
|
|
|
@ -51,10 +51,17 @@ pub struct InitArgs {
|
||||||
pub list_length: usize,
|
pub list_length: usize,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
pub config: WalletConfig,
|
pub config: WalletConfig,
|
||||||
|
pub recovery_phrase: Option<String>,
|
||||||
|
pub restore: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(g_args: &GlobalArgs, args: InitArgs) -> Result<(), Error> {
|
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");
|
info!("Wallet seed file created");
|
||||||
let client_n = HTTPNodeClient::new(
|
let client_n = HTTPNodeClient::new(
|
||||||
&args.config.check_node_api_http_addr,
|
&args.config.check_node_api_http_addr,
|
||||||
|
|
|
@ -160,7 +160,7 @@ where
|
||||||
{
|
{
|
||||||
let mut wallet_config = WalletConfig::default();
|
let mut wallet_config = WalletConfig::default();
|
||||||
wallet_config.data_file_dir = String::from(dir);
|
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)
|
let mut wallet = LMDBBackend::new(wallet_config.clone(), "", n_client)
|
||||||
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config));
|
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config));
|
||||||
wallet.open_with_credentials().unwrap_or_else(|e| {
|
wallet.open_with_credentials().unwrap_or_else(|e| {
|
||||||
|
|
|
@ -216,6 +216,7 @@ impl WalletSeed {
|
||||||
pub fn init_file(
|
pub fn init_file(
|
||||||
wallet_config: &WalletConfig,
|
wallet_config: &WalletConfig,
|
||||||
seed_length: usize,
|
seed_length: usize,
|
||||||
|
recovery_phrase: Option<String>,
|
||||||
password: &str,
|
password: &str,
|
||||||
) -> Result<WalletSeed, Error> {
|
) -> Result<WalletSeed, Error> {
|
||||||
// create directory if it doesn't exist
|
// create directory if it doesn't exist
|
||||||
|
@ -229,7 +230,11 @@ impl WalletSeed {
|
||||||
warn!("Generating wallet seed file at: {}", seed_file_path);
|
warn!("Generating wallet seed file at: {}", seed_file_path);
|
||||||
let _ = WalletSeed::seed_file_exists(wallet_config)?;
|
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 = EncryptedWalletSeed::from_seed(&seed, password)?;
|
||||||
let enc_seed_json = serde_json::to_string_pretty(&enc_seed).context(ErrorKind::Format)?;
|
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)?;
|
let mut file = File::create(seed_file_path).context(ErrorKind::IO)?;
|
||||||
|
|
Loading…
Reference in a new issue