gui: integrate restore backup to settings

This commit is contained in:
pythcoiner 2025-03-12 03:35:15 +01:00
parent d0d7007e83
commit 2fe297879b
No known key found for this signature in database
GPG Key ID: C1048AEEDF303B88
6 changed files with 63 additions and 29 deletions

View File

@ -7,6 +7,7 @@ use lianad::config::ConfigError;
use crate::{
app::{settings::SettingsError, wallet::WalletError},
daemon::DaemonError,
export,
};
#[derive(Debug)]
@ -18,6 +19,7 @@ pub enum Error {
HardwareWallet(async_hwi::Error),
Desc(LianaDescError),
Spend(SpendCreationError),
ImportExport(export::Error),
}
impl std::fmt::Display for Error {
@ -58,6 +60,7 @@ impl std::fmt::Display for Error {
Self::Unexpected(e) => write!(f, "Unexpected error: {}", e),
Self::HardwareWallet(e) => write!(f, "error: {}\nPlease check if the device is still connected and unlocked with the correct firmware open for the current network and no other application is accessing the device.", e),
Self::Desc(e) => write!(f, "Liana descriptor error: {}", e),
Self::ImportExport(e) => write!(f, "{e:?}"),
}
}
}

View File

@ -127,6 +127,11 @@ impl ExportModal {
}
// TODO: forward Descriptor
}
Progress::UpdateAliases(map) => {
return Task::perform(async {}, move |_| {
ImportExportMessage::UpdateAliases(map.clone()).into()
});
}
},
ImportExportMessage::TimedOut => {
self.stop(ImportExportState::TimedOut);
@ -173,6 +178,7 @@ impl ExportModal {
}
}
}
ImportExportMessage::UpdateAliases(_) => { /* unexpected */ }
}
Task::none()
}

View File

@ -10,7 +10,7 @@ use iced::Task;
use liana_ui::{component::form, widget::Element};
use bitcoind::BitcoindSettingsState;
use wallet::WalletSettingsState;
use wallet::{app_backup, WalletSettingsState};
use crate::{
app::{
@ -22,9 +22,8 @@ use crate::{
wallet::Wallet,
Config,
},
backup::Backup,
daemon::{Daemon, DaemonBackend},
export::{ImportExportMessage, ImportExportType},
export::{self, ImportExportMessage, ImportExportType},
};
use super::export::ExportModal;
@ -224,6 +223,14 @@ impl State for ImportExportSettingsState {
self.modal = None;
}
Message::View(view::Message::ImportExport(m)) => {
if let ImportExportMessage::UpdateAliases(aliases) = m {
let mut wallet = (*self.wallet).clone();
wallet.keys_aliases = aliases;
let wallet = Arc::new(wallet);
return Task::perform(async {}, move |_| {
Message::WalletUpdated(Ok(wallet.clone()))
});
}
if let Some(modal) = self.modal.as_mut() {
return modal.update(m);
};
@ -262,29 +269,32 @@ impl State for ImportExportSettingsState {
let wallet = self.wallet.clone();
let daemon = daemon.clone();
return Task::perform(
async move {
let backup =
Backup::from_app(datadir, network, config, wallet, daemon).await;
let backup = backup.unwrap();
serde_json::to_string_pretty(&backup).unwrap()
// TODO: do not unwrap, return an error message instead
},
async move { app_backup(datadir, network, config, wallet, daemon).await },
|s| {
Message::View(view::Message::Settings(
view::SettingsMessage::ExportBackup(Ok(s)),
view::SettingsMessage::ExportBackup(s),
))
},
);
}
}
Message::View(view::Message::Settings(view::SettingsMessage::ExportBackup(Ok(
backup,
)))) => {
Message::View(view::Message::Settings(view::SettingsMessage::ExportBackup(backup))) => {
let backup = match backup {
Ok(b) => b,
Err(e) => {
self.warning = Some(Error::ImportExport(export::Error::Backup(e)));
return Task::none();
}
};
let modal = ExportModal::new(Some(daemon), ImportExportType::ExportBackup(backup));
launch!(self, modal, true);
}
Message::View(view::Message::Settings(view::SettingsMessage::ImportWallet)) => {
// TODO:
if self.modal.is_none() {
let modal =
ExportModal::new(Some(daemon), ImportExportType::ImportBackup(None, None));
launch!(self, modal, false);
}
}
_ => {}
}

View File

@ -26,9 +26,9 @@ use crate::{
wallet::Wallet,
Config,
},
backup::Backup,
backup::{self, Backup},
daemon::{Daemon, DaemonBackend},
export::{ImportExportMessage, ImportExportType},
export::{self, ImportExportMessage, ImportExportType},
hw::{HardwareWallet, HardwareWalletConfig, HardwareWallets},
};
@ -231,16 +231,10 @@ impl State for WalletSettingsState {
let wallet = self.wallet.clone();
let daemon = daemon.clone();
Task::perform(
async move {
let backup =
Backup::from_app(datadir, network, config, wallet, daemon).await;
let backup = backup.unwrap();
serde_json::to_string_pretty(&backup).unwrap()
// TODO: do not unwrap, return an error message instead
},
async move { app_backup(datadir, network, config, wallet, daemon).await },
|s| {
Message::View(view::Message::Settings(
view::SettingsMessage::ExportBackup(Ok(s)),
view::SettingsMessage::ExportBackup(s),
))
},
)
@ -248,10 +242,15 @@ impl State for WalletSettingsState {
Task::none()
}
}
Message::View(view::Message::Settings(view::SettingsMessage::ExportBackup(Ok(
backup,
)))) => {
Message::View(view::Message::Settings(view::SettingsMessage::ExportBackup(backup))) => {
if self.modal.is_none() {
let backup = match backup {
Ok(b) => b,
Err(e) => {
self.warning = Some(Error::ImportExport(export::Error::Backup(e)));
return Task::none();
}
};
let modal =
ExportModal::new(Some(daemon), ImportExportType::ExportBackup(backup));
let launch = modal.launch(true);
@ -512,3 +511,14 @@ async fn update_keys_aliases(
Ok(Arc::new(wallet))
}
pub async fn app_backup(
datadir: PathBuf,
network: Network,
config: Arc<Config>,
wallet: Arc<Wallet>,
daemon: Arc<dyn Daemon + Sync + Send>,
) -> Result<String, backup::Error> {
let backup = Backup::from_app(datadir, network, config, wallet, daemon).await?;
serde_json::to_string_pretty(&backup).map_err(|_| backup::Error::Json)
}

View File

@ -49,6 +49,7 @@ impl From<&Error> for WarningMessage {
Error::HardwareWallet(_) => WarningMessage("Hardware wallet error".to_string()),
Error::Desc(e) => WarningMessage(format!("Descriptor analysis error: '{}'.", e)),
Error::Spend(e) => WarningMessage(format!("Spend creation error: '{}'.", e)),
Error::ImportExport(e) => WarningMessage(format!("{e:?}")),
}
}
}

View File

@ -11,6 +11,7 @@ use std::{
time,
};
use async_hwi::bitbox::api::btc::Fingerprint;
use chrono::{DateTime, Duration, Utc};
use liana::{
descriptors::LianaDescriptor,
@ -32,7 +33,7 @@ use crate::{
settings::{KeySetting, Settings},
view,
},
backup::Backup,
backup::{self, Backup},
daemon::{
model::{HistoryTransaction, Labelled},
Daemon, DaemonBackend, DaemonError,
@ -115,6 +116,7 @@ pub enum ImportExportMessage {
Close,
Overwrite,
Ignore,
UpdateAliases(HashMap<Fingerprint, String>),
}
impl From<ImportExportMessage> for view::Message {
@ -151,6 +153,7 @@ pub enum Error {
ParseDescriptor,
Bip329Export(String),
BackupImport(String),
Backup(backup::Error),
}
#[derive(Debug, Clone)]
@ -240,6 +243,7 @@ pub enum Progress {
Descriptor(LianaDescriptor),
LabelsConflict(SyncSender<bool>),
KeyAliasesConflict(SyncSender<bool>),
UpdateAliases(HashMap<Fingerprint, String>),
}
pub struct Export {