diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 42f8e1d971..0c50c27bcd 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Account::switch` command to allow changing accounts quickly; - UX improvements (Ctrl+l, TAB completion/suggestions and more) during interactive account management; - `WalletCommand::SetPow` command; +- Check for existing stronghold on `restore`; ### Changed diff --git a/cli/src/command/wallet.rs b/cli/src/command/wallet.rs index 605baee51e..7d4c26f5a5 100644 --- a/cli/src/command/wallet.rs +++ b/cli/src/command/wallet.rs @@ -247,14 +247,22 @@ pub async fn node_info_command(storage_path: &Path) -> Result { pub async fn restore_command(storage_path: &Path, snapshot_path: &Path, backup_path: &Path) -> Result { check_file_exists(backup_path).await?; - let password = get_password("Stronghold password", false)?; - let secret_manager = SecretManager::Stronghold( - StrongholdSecretManager::builder() - .password(password.clone()) - .build(snapshot_path)?, - ); - let wallet = Wallet::builder() - .with_secret_manager(secret_manager) + let mut builder = Wallet::builder(); + if check_file_exists(snapshot_path).await.is_ok() { + println!( + "Detected a stronghold file at {}. Enter password to unlock:", + snapshot_path.to_str().unwrap() + ); + let password = get_password("Stronghold password", false)?; + let secret_manager = SecretManager::Stronghold( + StrongholdSecretManager::builder() + .password(password.clone()) + .build(snapshot_path)?, + ); + builder = builder.with_secret_manager(secret_manager); + } + + let wallet = builder // Will be overwritten by the backup's value. .with_client_options(ClientOptions::new().with_node(DEFAULT_NODE_URL)?) .with_storage_path(storage_path.to_str().expect("invalid unicode")) @@ -263,6 +271,7 @@ pub async fn restore_command(storage_path: &Path, snapshot_path: &Path, backup_p .finish() .await?; + let password = get_password("Stronghold backup password", false)?; wallet.restore_backup(backup_path.into(), password, None, None).await?; println_log_info!( diff --git a/sdk/src/client/stronghold/mod.rs b/sdk/src/client/stronghold/mod.rs index 7cd0552567..f91b41a3b7 100644 --- a/sdk/src/client/stronghold/mod.rs +++ b/sdk/src/client/stronghold/mod.rs @@ -182,6 +182,16 @@ impl StrongholdAdapterBuilder { /// [`password()`]: Self::password() /// [`timeout()`]: Self::timeout() pub fn build>(self, snapshot_path: P) -> Result { + if snapshot_path.as_ref().is_dir() { + // TODO: Add Error in 2.0 as its breaking. + // Issue #1197 + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Path is not a file: {:?}", snapshot_path.as_ref().to_path_buf()), + ) + .into()); + } + // In any case, Stronghold - as a necessary component - needs to be present at this point. let stronghold = self.stronghold.unwrap_or_default(); @@ -484,6 +494,16 @@ impl StrongholdAdapter { /// /// [`unload_stronghold_snapshot()`]: Self::unload_stronghold_snapshot() pub async fn write_stronghold_snapshot(&self, snapshot_path: Option<&Path>) -> Result<(), Error> { + if let Some(p) = snapshot_path { + if p.is_dir() { + // TODO: Add Error in 2.0 as its breaking. + // Issue #1197 + return Err( + std::io::Error::new(std::io::ErrorKind::Other, format!("Path is not a file: {:?}", p)).into(), + ); + } + } + // The key needs to be supplied first. let locked_key_provider = self.key_provider.lock().await; let key_provider = if let Some(key_provider) = &*locked_key_provider {