diff --git a/liana-gui/src/backup.rs b/liana-gui/src/backup.rs index fd436668..7f768e45 100644 --- a/liana-gui/src/backup.rs +++ b/liana-gui/src/backup.rs @@ -50,6 +50,8 @@ fn now() -> u64 { pub struct Backup { #[serde(default, skip_serializing_if = "Option::is_none")] pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub alias: Option, pub accounts: Vec, pub network: Network, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -132,6 +134,7 @@ impl Backup { Ok(Backup { name, + alias: None, accounts: vec![account], network: ctx.network, proprietary: serde_json::Map::new(), @@ -157,13 +160,15 @@ impl Backup { let keys = wallet.keys(); let network_dir = datadir.network_directory(network); + let mut wallet_alias = wallet.alias.clone(); if let Some(settings) = WalletSettings::from_file(&network_dir, |settings| wallet.id() == settings.wallet_id()) .map_err(|_| Error::SettingsFromFile)? { - if let Ok(settings) = serde_json::to_value(settings) { + if let Ok(settings) = serde_json::to_value(&settings) { proprietary.insert(SETTINGS_KEY.to_string(), settings); } + wallet_alias = settings.alias; }; if let Ok(config) = serde_json::to_value((*config).clone()) { @@ -245,6 +250,7 @@ impl Backup { Ok(Backup { name: Some(name), + alias: wallet_alias, accounts: vec![account], network, proprietary: serde_json::Map::new(), @@ -477,6 +483,7 @@ mod test { fn backup_serde() { let mut backup = Backup { name: None, + alias: None, accounts: Vec::new(), network: Network::Signet, date: Some(0), diff --git a/liana-gui/src/installer/mod.rs b/liana-gui/src/installer/mod.rs index 354f73c7..52cc69b3 100644 --- a/liana-gui/src/installer/mod.rs +++ b/liana-gui/src/installer/mod.rs @@ -316,11 +316,6 @@ impl Installer { .expect("There is always a step") .update(&mut self.hws, Message::Installed(wallet_id, Err(e))) } - Message::WalletFromBackup((ks, backup)) => { - self.context.keys = ks; - self.context.backup = Some(backup); - Task::none() - } _ => self .steps .get_mut(self.current) diff --git a/liana-gui/src/installer/step/descriptor/mod.rs b/liana-gui/src/installer/step/descriptor/mod.rs index a5ba04b1..223576a1 100644 --- a/liana-gui/src/installer/step/descriptor/mod.rs +++ b/liana-gui/src/installer/step/descriptor/mod.rs @@ -29,11 +29,12 @@ use crate::{ pub struct ImportDescriptor { network: Network, - imported_descriptor: form::Value, wrong_network: bool, error: Option, modal: Option, - imported_backup: bool, + imported_descriptor: form::Value, + imported_backup: Option, + imported_aliases: Option>, } impl ImportDescriptor { @@ -44,7 +45,8 @@ impl ImportDescriptor { wrong_network: false, error: None, modal: None, - imported_backup: false, + imported_backup: None, + imported_aliases: None, } } @@ -97,6 +99,12 @@ impl Step for ImportDescriptor { fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { match message { Message::DefineDescriptor(message::DefineDescriptor::ImportDescriptor(desc)) => { + // If user manually change the descriptor, then the imported backup + // becomes invalid; + if desc != self.imported_descriptor.value { + self.imported_backup = None; + self.imported_aliases = None; + } self.imported_descriptor.value = desc; self.check_descriptor(self.network); } @@ -104,21 +112,18 @@ impl Step for ImportDescriptor { self.modal = None; } Message::ImportBackup => { - if !self.imported_backup { - let modal = ExportModal::new(None, ImportExportType::WalletFromBackup); - let launch = modal.launch(false); - self.modal = Some(modal); - return launch; - } + self.imported_backup = None; + let modal = ExportModal::new(None, ImportExportType::WalletFromBackup); + let launch = modal.launch(false); + self.modal = Some(modal); + return launch; } Message::ImportExport(ImportExportMessage::Progress(Progress::WalletFromBackup(r))) => { let (descriptor, network, aliases, backup) = r; if self.network == network { - self.imported_backup = true; + self.imported_backup = Some(backup); self.imported_descriptor.value = descriptor.to_string(); - return Task::perform(async move { (aliases, backup) }, |(a, b)| { - Message::WalletFromBackup((a, b)) - }); + self.imported_aliases = Some(aliases); } else { self.error = Some("Backup network do not match the selected network!".into()); } @@ -141,10 +146,29 @@ impl Step for ImportDescriptor { // descriptor forms for import or creation cannot be both empty or filled. if let Some(desc) = self.check_descriptor(self.network) { ctx.descriptor = Some(desc); - true } else { - false + return false; } + + if let Some(backup) = &self.imported_backup { + ctx.backup = Some(backup.clone()); + } + + if let Some(aliases) = &self.imported_aliases { + ctx.keys = aliases.clone(); + } + + if let Some(wallet_alias) = self.imported_backup.as_ref().and_then(|b| b.alias.clone()) { + ctx.wallet_alias = wallet_alias; + } + true + } + + fn revert(&self, ctx: &mut Context) { + ctx.keys = HashMap::new(); + ctx.backup = None; + ctx.descriptor = None; + ctx.wallet_alias = String::new(); } fn view<'a>( @@ -157,7 +181,7 @@ impl Step for ImportDescriptor { progress, email, &self.imported_descriptor, - self.imported_backup, + self.imported_backup.is_some(), self.wrong_network, self.error.as_ref(), ); diff --git a/liana-gui/src/installer/step/wallet_alias.rs b/liana-gui/src/installer/step/wallet_alias.rs index f79f2494..9fbc4dec 100644 --- a/liana-gui/src/installer/step/wallet_alias.rs +++ b/liana-gui/src/installer/step/wallet_alias.rs @@ -1,5 +1,6 @@ use iced::Task; +use liana::miniscript::bitcoin::Network; use liana_ui::{component::form, widget::*}; use crate::{ @@ -15,9 +16,31 @@ pub struct WalletAlias { impl Step for WalletAlias { fn load_context(&mut self, ctx: &Context) { - if !ctx.wallet_alias.is_empty() { - self.wallet_alias.value = ctx.wallet_alias.clone(); - self.wallet_alias.valid = true; + match ( + ctx.wallet_alias.is_empty(), + self.wallet_alias.value.is_empty(), + ) { + // Alias from context is the first one to be set. + (false, _) => { + self.wallet_alias.value = ctx.wallet_alias.clone(); + self.wallet_alias.valid = true; + } + // No alias at all, we set a default value. + (true, true) => { + self.wallet_alias.value = format!( + "My Liana {} wallet", + match ctx.network { + Network::Bitcoin => "Bitcoin", + Network::Signet => "Signet", + Network::Testnet => "Testnet", + Network::Regtest => "Regtest", + _ => "", + } + ); + self.wallet_alias.valid = true; + } + // We keep the current value. + (true, false) => {} } }