From 03476de35abd779de95595f538b081d2c945285f Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Thu, 13 Mar 2025 06:29:27 +0100 Subject: [PATCH] gui: call import_backup_at_launch --- liana-gui/src/backup.rs | 10 +++--- liana-gui/src/export.rs | 4 +-- liana-gui/src/installer/context.rs | 3 ++ liana-gui/src/installer/mod.rs | 2 +- liana-gui/src/loader.rs | 30 ++++++++++++++-- liana-gui/src/main.rs | 56 +++++++++++++++++++++++------- 6 files changed, 82 insertions(+), 23 deletions(-) diff --git a/liana-gui/src/backup.rs b/liana-gui/src/backup.rs index c11150cd..d66d9c9d 100644 --- a/liana-gui/src/backup.rs +++ b/liana-gui/src/backup.rs @@ -43,7 +43,7 @@ fn now() -> u64 { .as_secs() } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct Backup { #[serde(default, skip_serializing_if = "Option::is_none")] pub name: Option, @@ -371,7 +371,7 @@ async fn get_transactions( Ok(vec) } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Account { #[serde(default, skip_serializing_if = "Option::is_none")] pub name: Option, @@ -450,7 +450,7 @@ impl Account { } } -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] pub struct Key { pub key: Fingerprint, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -463,7 +463,7 @@ pub struct Key { pub metadata: Value, } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] pub enum KeyRole { /// Key to be used in normal spending condition Main, @@ -475,7 +475,7 @@ pub enum KeyRole { Cosigning, } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] pub enum KeyType { /// Main user Internal, diff --git a/liana-gui/src/export.rs b/liana-gui/src/export.rs index 7a38f78f..c50b5bdd 100644 --- a/liana-gui/src/export.rs +++ b/liana-gui/src/export.rs @@ -947,8 +947,8 @@ pub async fn import_backup( if let Some(ks) = KeySetting::from_backup( v.alias.clone().unwrap_or("".into()), *k, - v.role.clone(), - v.key_type.clone(), + v.role, + v.key_type, v.metadata.clone(), ) { settings_aliases.insert(*k, ks); diff --git a/liana-gui/src/installer/context.rs b/liana-gui/src/installer/context.rs index c1071ff1..025349bc 100644 --- a/liana-gui/src/installer/context.rs +++ b/liana-gui/src/installer/context.rs @@ -5,6 +5,7 @@ use std::time::Duration; use crate::{ app::settings::KeySetting, + backup::Backup, lianalite::client::backend::{BackendClient, BackendWalletClient}, node::bitcoind::{Bitcoind, InternalBitcoindConfig}, signer::Signer, @@ -69,6 +70,7 @@ pub struct Context { pub internal_bitcoind_config: Option, pub internal_bitcoind: Option, pub remote_backend: RemoteBackend, + pub backup: Option, } impl Context { @@ -95,6 +97,7 @@ impl Context { internal_bitcoind_config: None, internal_bitcoind: None, remote_backend, + backup: None, } } } diff --git a/liana-gui/src/installer/mod.rs b/liana-gui/src/installer/mod.rs index 4c0a6144..2eee9ed2 100644 --- a/liana-gui/src/installer/mod.rs +++ b/liana-gui/src/installer/mod.rs @@ -66,7 +66,7 @@ pub struct Installer { signer: Arc>, /// Context is data passed through each step. - context: Context, + pub context: Context, } impl Installer { diff --git a/liana-gui/src/loader.rs b/liana-gui/src/loader.rs index 72f0a1c9..e785f721 100644 --- a/liana-gui/src/loader.rs +++ b/liana-gui/src/loader.rs @@ -23,6 +23,9 @@ use lianad::{ StartupError, }; +use crate::app; +use crate::backup::Backup; +use crate::export::RestoreBackupError; use crate::{ app::{ cache::Cache, @@ -56,7 +59,7 @@ pub struct Loader { pub daemon_started: bool, pub internal_bitcoind: Option, pub waiting_daemon_bitcoind: bool, - + pub backup: Option, step: Step, } @@ -83,6 +86,20 @@ pub enum Message { Cache, Arc, Option, + Option, + ), + Error, + >, + ), + App( + Result< + ( + Cache, + Arc, + app::Config, + Arc, + PathBuf, + Option, ), Error, >, @@ -100,6 +117,7 @@ impl Loader { gui_config: GUIConfig, network: bitcoin::Network, internal_bitcoind: Option, + backup: Option, ) -> (Self, Task) { let path = gui_config .daemon_rpc_path @@ -114,6 +132,7 @@ impl Loader { daemon_started: false, internal_bitcoind, waiting_daemon_bitcoind: false, + backup, }, Task::perform(connect(path), Message::Loaded), ) @@ -134,6 +153,7 @@ impl Loader { self.datadir_path.clone(), self.network, self.internal_bitcoind.clone(), + self.backup.clone(), ), Message::Synced, ); @@ -232,6 +252,7 @@ impl Loader { self.datadir_path.clone(), self.network, self.internal_bitcoind.clone(), + self.backup.clone(), ), Message::Synced, ); @@ -290,6 +311,7 @@ impl Loader { self.gui_config.clone(), self.network, self.internal_bitcoind.clone(), + self.backup.clone(), ); *self = loader; cmd @@ -391,12 +413,14 @@ pub async fn load_application( datadir_path: PathBuf, network: bitcoin::Network, internal_bitcoind: Option, + backup: Option, ) -> Result< ( Arc, Cache, Arc, Option, + Option, ), Error, > { @@ -421,7 +445,7 @@ pub async fn load_application( ..Default::default() }; - Ok((Arc::new(wallet), cache, daemon, internal_bitcoind)) + Ok((Arc::new(wallet), cache, daemon, internal_bitcoind, backup)) } #[derive(Clone, Debug)] @@ -582,6 +606,7 @@ pub enum Error { Daemon(DaemonError), Bitcoind(StartInternalBitcoindError), BitcoindLogs(std::io::Error), + RestoreBackup(RestoreBackupError), } impl std::fmt::Display for Error { @@ -592,6 +617,7 @@ impl std::fmt::Display for Error { Self::Daemon(e) => write!(f, "Liana daemon error: {}", e), Self::Bitcoind(e) => write!(f, "Bitcoind error: {}", e), Self::BitcoindLogs(e) => write!(f, "Bitcoind logs error: {}", e), + Self::RestoreBackup(e) => write!(f, "Restore backup: {e}"), } } } diff --git a/liana-gui/src/main.rs b/liana-gui/src/main.rs index e256be2c..476d3ca6 100644 --- a/liana-gui/src/main.rs +++ b/liana-gui/src/main.rs @@ -24,11 +24,12 @@ use lianad::config::Config as DaemonConfig; use liana_gui::{ app::{self, cache::Cache, config::default_datadir, wallet::Wallet, App}, datadir, + export::import_backup_at_launch, hw::HardwareWalletConfig, installer::{self, Installer}, launcher::{self, Launcher}, lianalite::{ - client::{backend::api, backend::BackendWalletClient}, + client::backend::{api, BackendWalletClient}, login, }, loader::{self, Loader}, @@ -162,7 +163,7 @@ impl GUI { network, log_level.unwrap_or_else(|| cfg.log_level().unwrap_or(LevelFilter::INFO)), ); - let (loader, command) = Loader::new(datadir_path, cfg, network, None); + let (loader, command) = Loader::new(datadir_path, cfg, network, None, None); cmds.push(command.map(|msg| Message::Load(Box::new(msg)))); State::Loader(Box::new(loader)) } @@ -242,12 +243,13 @@ impl GUI { self.state = State::Login(Box::new(login)); command.map(|msg| Message::Login(Box::new(msg))) } else { - let (loader, command) = Loader::new(datadir_path, cfg, network, None); + let (loader, command) = + Loader::new(datadir_path, cfg, network, None, None); self.state = State::Loader(Box::new(loader)); command.map(|msg| Message::Load(Box::new(msg))) } } else { - let (loader, command) = Loader::new(datadir_path, cfg, network, None); + let (loader, command) = Loader::new(datadir_path, cfg, network, None, None); self.state = State::Loader(Box::new(loader)); command.map(|msg| Message::Load(Box::new(msg))) } @@ -334,6 +336,7 @@ impl GUI { cfg, daemon_cfg.bitcoin_config.network, internal_bitcoind, + i.context.backup.take(), ); self.state = State::Loader(Box::new(loader)); command.map(|msg| Message::Load(Box::new(msg))) @@ -353,18 +356,45 @@ impl GUI { self.state = State::Launcher(Box::new(launcher)); command.map(|msg| Message::Launch(Box::new(msg))) } - loader::Message::Synced(Ok((wallet, cache, daemon, bitcoind))) => { - let (app, command) = App::new( - cache, - wallet, - loader.gui_config.clone(), - daemon, - loader.datadir_path.clone(), - bitcoind, - ); + loader::Message::Synced(Ok((wallet, cache, daemon, bitcoind, backup))) => { + if let Some(backup) = backup { + let config = loader.gui_config.clone(); + let datadir = loader.datadir_path.clone(); + Task::perform( + async move { + import_backup_at_launch( + cache, wallet, config, daemon, datadir, bitcoind, backup, + ) + .await + }, + |r| { + let r = r.map_err(loader::Error::RestoreBackup); + Message::Load(Box::new(loader::Message::App(r))) + }, + ) + } else { + let (app, command) = App::new( + cache, + wallet, + loader.gui_config.clone(), + daemon, + loader.datadir_path.clone(), + bitcoind, + ); + self.state = State::App(app); + command.map(|msg| Message::Run(Box::new(msg))) + } + } + loader::Message::App(Ok((cache, wallet, config, daemon, datadir, bitcoind))) => { + let (app, command) = App::new(cache, wallet, config, daemon, datadir, bitcoind); self.state = State::App(app); command.map(|msg| Message::Run(Box::new(msg))) } + loader::Message::App(Err(e)) => { + tracing::error!("Fail to import backup: {e}"); + Task::none() + } + _ => loader.update(*msg).map(|msg| Message::Load(Box::new(msg))), }, (State::App(i), Message::Run(msg)) => {