diff --git a/liana-gui/src/app/state/export.rs b/liana-gui/src/app/state/export.rs index 1e2fadac..46cc9c69 100644 --- a/liana-gui/src/app/state/export.rs +++ b/liana-gui/src/app/state/export.rs @@ -83,7 +83,7 @@ impl ExportModal { } ImportExportType::ImportPsbt(_) => "Import PSBT", ImportExportType::ImportDescriptor => "Import Descriptor", - ImportExportType::ImportBackup(..) => "Restore Backup", + ImportExportType::ImportBackup { .. } => "Restore Backup", ImportExportType::WalletFromBackup => "Import existing wallet from backup", } } @@ -111,7 +111,7 @@ impl ExportModal { ImportExportType::ExportBackup(_) | ImportExportType::ExportProcessBackup(..) => { format!("liana-backup-{date}.json") } - ImportExportType::WalletFromBackup | ImportExportType::ImportBackup(_, _) => { + ImportExportType::WalletFromBackup | ImportExportType::ImportBackup { .. } => { "liana-backup.json".to_string() } } @@ -140,15 +140,33 @@ impl ExportModal { } Progress::Finished | Progress::Ended => self.state = ImportExportState::Ended, Progress::KeyAliasesConflict(ref sender) => { - if let ImportExportType::ImportBackup(_, None) = &self.import_export_type { - self.import_export_type = - ImportExportType::ImportBackup(None, Some(sender.clone())); + if let ImportExportType::ImportBackup { + network_dir, + wallet, + .. + } = &self.import_export_type + { + self.import_export_type = ImportExportType::ImportBackup { + network_dir: network_dir.clone(), + wallet: wallet.clone(), + overwrite_labels: None, + overwrite_aliases: Some(sender.clone()), + }; } } Progress::LabelsConflict(ref sender) => { - if let ImportExportType::ImportBackup(None, _) = &self.import_export_type { - self.import_export_type = - ImportExportType::ImportBackup(Some(sender.clone()), None); + if let ImportExportType::ImportBackup { + network_dir, + wallet, + .. + } = &self.import_export_type + { + self.import_export_type = ImportExportType::ImportBackup { + network_dir: network_dir.clone(), + wallet: wallet.clone(), + overwrite_labels: Some(sender.clone()), + overwrite_aliases: None, + }; } } Progress::Error(e) => { @@ -164,7 +182,7 @@ impl ExportModal { }); } Progress::Descriptor(_) => { - if self.import_export_type == ImportExportType::ImportDescriptor { + if matches!(self.import_export_type, ImportExportType::ImportDescriptor) { self.state = ImportExportState::Ended; } } @@ -192,10 +210,13 @@ impl ExportModal { } ImportExportMessage::Close | ImportExportMessage::Open => { /* unreachable */ } ImportExportMessage::Overwrite => { - if let ImportExportType::ImportBackup(labels, aliases) = - &mut self.import_export_type + if let ImportExportType::ImportBackup { + overwrite_labels, + overwrite_aliases, + .. + } = &mut self.import_export_type { - if let Some(sender) = labels.take() { + if let Some(sender) = overwrite_labels.take() { return Task::perform( async move { if sender.send(true).await.is_err() { @@ -206,7 +227,7 @@ impl ExportModal { }, |_| ImportExportMessage::Ignore.into(), ); - } else if let Some(sender) = aliases.take() { + } else if let Some(sender) = overwrite_aliases.take() { return Task::perform( async move { if sender.send(true).await.is_err() { @@ -221,10 +242,13 @@ impl ExportModal { } } ImportExportMessage::Ignore => { - if let ImportExportType::ImportBackup(labels, aliases) = - &mut self.import_export_type + if let ImportExportType::ImportBackup { + overwrite_labels, + overwrite_aliases, + .. + } = &mut self.import_export_type { - if let Some(sender) = labels.take() { + if let Some(sender) = overwrite_labels.take() { return Task::perform( async move { if sender.send(false).await.is_err() { @@ -235,7 +259,7 @@ impl ExportModal { }, |_| ImportExportMessage::Ignore.into(), ); - } else if let Some(sender) = aliases.take() { + } else if let Some(sender) = overwrite_aliases.take() { return Task::perform( async move { if sender.send(false).await.is_err() { diff --git a/liana-gui/src/app/state/settings/mod.rs b/liana-gui/src/app/state/settings/mod.rs index b5eb1aea..14cb6747 100644 --- a/liana-gui/src/app/state/settings/mod.rs +++ b/liana-gui/src/app/state/settings/mod.rs @@ -269,8 +269,15 @@ impl State for ImportExportSettingsState { } Message::View(view::Message::Settings(view::SettingsMessage::ImportWallet)) => { if self.modal.is_none() { - let modal = - ExportModal::new(Some(daemon), ImportExportType::ImportBackup(None, None)); + let modal = ExportModal::new( + Some(daemon), + ImportExportType::ImportBackup { + network_dir: cache.datadir_path.network_directory(cache.network), + wallet: self.wallet.clone(), + overwrite_labels: None, + overwrite_aliases: None, + }, + ); launch!(self, modal, false); } } diff --git a/liana-gui/src/app/state/settings/wallet.rs b/liana-gui/src/app/state/settings/wallet.rs index b69191e8..9aa39743 100644 --- a/liana-gui/src/app/state/settings/wallet.rs +++ b/liana-gui/src/app/state/settings/wallet.rs @@ -289,8 +289,15 @@ impl State for WalletSettingsState { } Message::View(view::Message::Settings(view::SettingsMessage::ImportWallet)) => { if self.modal.is_none() { - let modal = - ExportModal::new(Some(daemon), ImportExportType::ImportBackup(None, None)); + let modal = ExportModal::new( + Some(daemon), + ImportExportType::ImportBackup { + network_dir: cache.datadir_path.network_directory(cache.network), + wallet: self.wallet.clone(), + overwrite_labels: None, + overwrite_aliases: None, + }, + ); let launch = modal.launch(false); self.modal = Modal::ImportExport(modal); launch diff --git a/liana-gui/src/app/view/export.rs b/liana-gui/src/app/view/export.rs index 5498d2be..0eb8eea5 100644 --- a/liana-gui/src/app/view/export.rs +++ b/liana-gui/src/app/view/export.rs @@ -86,7 +86,11 @@ pub fn export_modal<'a, Message: From + Clone + 'static>( )), ); let (msg, button) = match import_export_type { - ImportExportType::ImportBackup(labels, aliases) => match (labels, aliases) { + ImportExportType::ImportBackup { + overwrite_labels, + overwrite_aliases, + .. + } => match (overwrite_labels, overwrite_aliases) { (Some(_), _) => labels_btn, (_, Some(_)) => aliases_btn, diff --git a/liana-gui/src/export.rs b/liana-gui/src/export.rs index 46c59505..cf2253e0 100644 --- a/liana-gui/src/export.rs +++ b/liana-gui/src/export.rs @@ -165,10 +165,12 @@ pub enum ImportExportType { ExportXpub(String), ExportBackup(String), ExportProcessBackup(LianaDirectory, Network, Arc, Arc), - ImportBackup( - Option>, /*overwrite_labels*/ - Option>, /*overwrite_aliases*/ - ), + ImportBackup { + network_dir: NetworkDirectory, + wallet: Arc, + overwrite_labels: Option>, + overwrite_aliases: Option>, + }, WalletFromBackup, Descriptor(LianaDescriptor), ExportLabels, @@ -187,7 +189,7 @@ impl ImportExportType { | ImportExportType::ExportProcessBackup(..) | ImportExportType::ExportXpub(_) | ImportExportType::ExportLabels => "Export successful!", - ImportExportType::ImportBackup(_, _) + ImportExportType::ImportBackup { .. } | ImportExportType::ImportPsbt(_) | ImportExportType::ImportXpub(_) | ImportExportType::WalletFromBackup @@ -196,20 +198,6 @@ impl ImportExportType { } } -impl PartialEq for ImportExportType { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Self::ExportPsbt(l0), Self::ExportPsbt(r0)) => l0 == r0, - (Self::ExportBackup(l0), Self::ExportBackup(r0)) => l0 == r0, - (Self::ImportBackup(l0, l1), Self::ImportBackup(r0, r1)) => { - l0.is_some() == r0.is_some() && l1.is_some() == r1.is_some() - } - (Self::Descriptor(l0), Self::Descriptor(r0)) => l0 == r0, - _ => core::mem::discriminant(self) == core::mem::discriminant(other), - } - } -} - impl From for Error { fn from(value: JoinError) -> Self { Error::JoinError(format!("{:?}", value)) @@ -321,7 +309,11 @@ impl Export { ) .await } - ImportExportType::ImportBackup(..) => import_backup(&sender, path, daemon).await, + ImportExportType::ImportBackup { + network_dir, + wallet, + .. + } => import_backup(&network_dir, wallet, &sender, path, daemon).await, ImportExportType::WalletFromBackup => wallet_from_backup(&sender, path).await, } { if let Err(e) = sender.send(Progress::Error(e)) { @@ -694,6 +686,8 @@ pub async fn import_xpub( /// - import labels if no conflict or user ACK /// - update aliases if no conflict or user ACK pub async fn import_backup( + network_dir: &NetworkDirectory, + wallet: Arc, sender: &UnboundedSender, path: PathBuf, daemon: Option>, @@ -810,32 +804,16 @@ pub async fn import_backup( Vec::new() }; - let lianad_datadir = daemon - .config() - .and_then(|c| c.data_directory()) - .ok_or(Error::BackupImport("Failed to get Daemon config".into()))?; - - let descriptor_checksum = descriptor - .to_string() - .split_once('#') - .map(|(_, checksum)| checksum) - .unwrap() - .to_string(); - // check if key aliases can be imported w/o conflict let mut write_aliases = true; let settings = if !account.keys.is_empty() { - // TODO: change lianad_datadir is common to gui datadir only for legacy wallet before - // multiple wallet - let network_dir = NetworkDirectory::new(lianad_datadir.path().to_path_buf()); - let wallet_settings = match WalletSettings::from_file(&network_dir, |w| { - w.descriptor_checksum == descriptor_checksum - }) { - Ok(Some(s)) => s, - _ => { - return Err(Error::BackupImport("Failed to get App Settings".into())); - } - }; + let wallet_settings = + match WalletSettings::from_file(network_dir, |w| w.wallet_id() == wallet.id()) { + Ok(Some(s)) => s, + _ => { + return Err(Error::BackupImport("Failed to get App Settings".into())); + } + }; let settings_aliases: HashMap<_, _> = wallet_settings .keys @@ -937,19 +915,16 @@ pub async fn import_backup( } } - if let Err(e) = update_settings_file( - &NetworkDirectory::new(lianad_datadir.path().to_path_buf()), - |mut settings| { - if let Some(wallet) = settings - .wallets - .iter_mut() - .find(|w| w.descriptor_checksum == descriptor_checksum) - { - wallet.keys = settings_aliases.clone().into_values().collect(); - } - settings - }, - ) + if let Err(e) = update_settings_file(network_dir, |mut settings| { + if let Some(wallet) = settings + .wallets + .iter_mut() + .find(|w| w.wallet_id() == wallet.id()) + { + wallet.keys = settings_aliases.clone().into_values().collect(); + } + settings + }) .await { return Err(Error::BackupImport(format!(