From 986a982d8e7148b51bf20e4913502bfa1ce1ffe6 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Mon, 7 Apr 2025 06:36:21 +0200 Subject: [PATCH 1/6] export: add export xpub feature --- liana-gui/src/app/state/export.rs | 2 ++ liana-gui/src/export.rs | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/liana-gui/src/app/state/export.rs b/liana-gui/src/app/state/export.rs index 18396330..77eae207 100644 --- a/liana-gui/src/app/state/export.rs +++ b/liana-gui/src/app/state/export.rs @@ -43,6 +43,7 @@ impl ExportModal { match self.import_export_type { ImportExportType::Transactions => "Export Transactions", ImportExportType::ExportPsbt(_) => "Export PSBT", + ImportExportType::ExportXpub(_) => "Export Xpub", ImportExportType::ExportBackup(_) => "Export Backup", ImportExportType::Descriptor(_) => "Export Descriptor", ImportExportType::ExportProcessBackup(..) | ImportExportType::ExportLabels => { @@ -62,6 +63,7 @@ impl ExportModal { format!("liana-txs-{date}.csv") } ImportExportType::ExportPsbt(_) => "psbt.psbt".into(), + ImportExportType::ExportXpub(_) => "liana.pub".into(), ImportExportType::Descriptor(descriptor) => { let checksum = descriptor .to_string() diff --git a/liana-gui/src/export.rs b/liana-gui/src/export.rs index 0848a7d1..fafc0262 100644 --- a/liana-gui/src/export.rs +++ b/liana-gui/src/export.rs @@ -144,6 +144,7 @@ impl Display for Error { pub enum ImportExportType { Transactions, ExportPsbt(String), + ExportXpub(String), ExportBackup(String), ExportProcessBackup(PathBuf, Network, Arc, Arc), ImportBackup( @@ -165,6 +166,7 @@ impl ImportExportType { | ImportExportType::ExportBackup(_) | ImportExportType::Descriptor(_) | ImportExportType::ExportProcessBackup(..) + | ImportExportType::ExportXpub(_) | ImportExportType::ExportLabels => "Export successful!", ImportExportType::ImportBackup(_, _) | ImportExportType::ImportPsbt @@ -284,6 +286,7 @@ impl Export { ImportExportType::ImportPsbt => import_psbt(&sender, path).await, ImportExportType::ImportDescriptor => import_descriptor(&sender, path).await, ImportExportType::ExportBackup(str) => export_string(&sender, path, str).await, + ImportExportType::ExportXpub(xpub_str) => export_string(&sender, path, xpub_str).await, ImportExportType::ExportProcessBackup(datadir, network, config, wallet) => { app_backup_export( datadir, @@ -556,10 +559,10 @@ pub async fn export_descriptor( pub async fn export_string( sender: &UnboundedSender, path: PathBuf, - psbt: String, + str: String, ) -> Result<(), Error> { let mut file = open_file_write(&path).await?; - file.write_all(psbt.as_bytes())?; + file.write_all(str.as_bytes())?; send_progress!(sender, Progress(100.0)); send_progress!(sender, Ended); Ok(()) From d7e388707b3368e12b73b578524b8e0c667ddb92 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Mon, 7 Apr 2025 06:37:14 +0200 Subject: [PATCH 2/6] installer: integrate export xpub feature --- liana-gui/src/installer/message.rs | 1 + liana-gui/src/installer/step/share_xpubs.rs | 41 +++++++++++++++++++-- liana-gui/src/installer/view/mod.rs | 8 ++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/liana-gui/src/installer/message.rs b/liana-gui/src/installer/message.rs index efe5dc2f..e0ff8ddd 100644 --- a/liana-gui/src/installer/message.rs +++ b/liana-gui/src/installer/message.rs @@ -56,6 +56,7 @@ pub enum Message { AllKeysRedeemed, BackupWallet, ExportWallet(Result), + ExportXpub(String), ImportExport(ImportExportMessage), ImportBackup, WalletFromBackup((HashMap, Backup)), diff --git a/liana-gui/src/installer/step/share_xpubs.rs b/liana-gui/src/installer/step/share_xpubs.rs index 39db3fb7..1befe594 100644 --- a/liana-gui/src/installer/step/share_xpubs.rs +++ b/liana-gui/src/installer/step/share_xpubs.rs @@ -9,6 +9,8 @@ use liana::miniscript::bitcoin::{ use liana_ui::widget::Element; use crate::{ + app::state::export::ExportModal, + export::{ImportExportMessage, ImportExportType}, hw::{HardwareWallet, HardwareWallets}, installer::{ message::Message, @@ -70,6 +72,7 @@ pub struct ShareXpubs { network: Network, hw_xpubs: Vec, xpubs_signer: SignerXpubs, + modal: Option, } impl ShareXpubs { @@ -78,6 +81,7 @@ impl ShareXpubs { network, hw_xpubs: Vec::new(), xpubs_signer: SignerXpubs::new(signer), + modal: None, } } } @@ -102,6 +106,24 @@ impl Step for ShareXpubs { } } } + Message::ExportXpub(xpub_str) => { + if self.modal.is_none() { + let modal = ExportModal::new(None, ImportExportType::ExportXpub(xpub_str)); + let launch = modal.launch(true); + self.modal = Some(modal); + return launch; + } + } + Message::ImportExport(ImportExportMessage::Close) => { + if self.modal.is_some() { + self.modal = None; + } + } + Message::ImportExport(msg) => { + if let Some(modal) = self.modal.as_mut() { + return modal.update(msg); + } + } Message::UseHotSigner => { self.xpubs_signer.select(self.network); } @@ -150,7 +172,14 @@ impl Step for ShareXpubs { } fn subscription(&self, hws: &HardwareWallets) -> Subscription { - hws.refresh().map(Message::HardwareWallets) + let hw = hws.refresh().map(Message::HardwareWallets); + if let Some(modal) = self.modal.as_ref() { + if let Some(sub) = modal.subscription() { + let export = sub.map(|m| Message::ImportExport(ImportExportMessage::Progress(m))); + return Subscription::batch(vec![hw, export]); + } + } + hw } fn apply(&mut self, ctx: &mut Context) -> bool { @@ -166,7 +195,7 @@ impl Step for ShareXpubs { _progress: (usize, usize), email: Option<&'a str>, ) -> Element { - view::share_xpubs( + let content = view::share_xpubs( email, hws.list .iter() @@ -190,7 +219,13 @@ impl Step for ShareXpubs { }) .collect(), self.xpubs_signer.view(), - ) + ); + + if let Some(modal) = &self.modal { + modal.view(content) + } else { + content + } } } diff --git a/liana-gui/src/installer/view/mod.rs b/liana-gui/src/installer/view/mod.rs index b91f19fd..d11d8478 100644 --- a/liana-gui/src/installer/view/mod.rs +++ b/liana-gui/src/installer/view/mod.rs @@ -446,8 +446,8 @@ pub fn signer_xpubs<'a>( ) .push( Container::new( - button::secondary(Some(icon::clipboard_icon()), "Copy") - .on_press(Message::Clibpboard(xpub.clone())) + button::primary(Some(icon::backup_icon()), "Export") + .on_press(Message::ExportXpub(xpub.clone())) .width(Length::Shrink), ) .padding(10), @@ -539,8 +539,8 @@ pub fn hardware_wallet_xpubs<'a>( ) .push( Container::new( - button::secondary(Some(icon::clipboard_icon()), "Copy") - .on_press(Message::Clibpboard(xpub.clone())) + button::primary(Some(icon::backup_icon()), "Export") + .on_press(Message::ExportXpub(xpub.clone())) .width(Length::Shrink), ) .padding(10), From 98bacb9f4c88ad63c537b7819a437e4e17bdd0b5 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Mon, 7 Apr 2025 09:55:27 +0200 Subject: [PATCH 3/6] export: add import xpub feature --- liana-gui/src/app/state/export.rs | 12 ++++++++- liana-gui/src/export.rs | 43 ++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/liana-gui/src/app/state/export.rs b/liana-gui/src/app/state/export.rs index 77eae207..046d8c2f 100644 --- a/liana-gui/src/app/state/export.rs +++ b/liana-gui/src/app/state/export.rs @@ -44,6 +44,7 @@ impl ExportModal { ImportExportType::Transactions => "Export Transactions", ImportExportType::ExportPsbt(_) => "Export PSBT", ImportExportType::ExportXpub(_) => "Export Xpub", + ImportExportType::ImportXpub(_) => "Import Xpub", ImportExportType::ExportBackup(_) => "Export Backup", ImportExportType::Descriptor(_) => "Export Descriptor", ImportExportType::ExportProcessBackup(..) | ImportExportType::ExportLabels => { @@ -63,7 +64,7 @@ impl ExportModal { format!("liana-txs-{date}.csv") } ImportExportType::ExportPsbt(_) => "psbt.psbt".into(), - ImportExportType::ExportXpub(_) => "liana.pub".into(), + ImportExportType::ExportXpub(_) | ImportExportType::ImportXpub(_) => "liana.pub".into(), ImportExportType::Descriptor(descriptor) => { let checksum = descriptor .to_string() @@ -129,6 +130,14 @@ impl ExportModal { } // TODO: forward PSBT } + Progress::Xpub(xpub_str) => { + if matches!(self.import_export_type, ImportExportType::ExportXpub(_)) { + self.state = ImportExportState::Ended; + } + return Task::perform(async {}, move |_| { + ImportExportMessage::Xpub(xpub_str.clone()).into() + }); + } Progress::Descriptor(_) => { if self.import_export_type == ImportExportType::ImportDescriptor { self.state = ImportExportState::Ended; @@ -216,6 +225,7 @@ impl ExportModal { } } ImportExportMessage::UpdateAliases(_) => { /* unexpected */ } + ImportExportMessage::Xpub(_) => { /* unexpected */ } } Task::none() } diff --git a/liana-gui/src/export.rs b/liana-gui/src/export.rs index fafc0262..54008e4c 100644 --- a/liana-gui/src/export.rs +++ b/liana-gui/src/export.rs @@ -15,7 +15,10 @@ use async_hwi::bitbox::api::btc::Fingerprint; use chrono::{DateTime, Duration, Utc}; use liana::{ descriptors::LianaDescriptor, - miniscript::bitcoin::{Amount, Network, Psbt, Txid}, + miniscript::{ + bitcoin::{Amount, Network, Psbt, Txid}, + DescriptorPublicKey, + }, }; use lianad::{ bip329::{error::ExportError, Labels}, @@ -80,6 +83,7 @@ pub enum ImportExportMessage { Overwrite, Ignore, UpdateAliases(HashMap), + Xpub(String), } impl From for view::Message { @@ -117,6 +121,8 @@ pub enum Error { Bip329Export(String), BackupImport(String), Backup(backup::Error), + ParseXpub, + XpubNetwork, } impl Display for Error { @@ -136,6 +142,8 @@ impl Display for Error { Error::Bip329Export(e) => write!(f, "Bip329Export: {e}"), Error::BackupImport(e) => write!(f, "BackupImport: {e}"), Error::Backup(e) => write!(f, "Backup: {e}"), + Error::ParseXpub => write!(f, "Fail to parse Xpub from file"), + Error::XpubNetwork => write!(f, "Xpub is for another network"), } } } @@ -155,6 +163,7 @@ pub enum ImportExportType { Descriptor(LianaDescriptor), ExportLabels, ImportPsbt, + ImportXpub(Network), ImportDescriptor, } @@ -170,6 +179,7 @@ impl ImportExportType { | ImportExportType::ExportLabels => "Export successful!", ImportExportType::ImportBackup(_, _) | ImportExportType::ImportPsbt + | ImportExportType::ImportXpub(_) | ImportExportType::WalletFromBackup | ImportExportType::ImportDescriptor => "Import successful", } @@ -231,6 +241,7 @@ pub enum Progress { None, Psbt(Psbt), Descriptor(LianaDescriptor), + Xpub(String), LabelsConflict(Sender), KeyAliasesConflict(Sender), UpdateAliases(HashMap), @@ -284,6 +295,7 @@ impl Export { } ImportExportType::ExportLabels => export_labels(&sender, daemon, path).await, ImportExportType::ImportPsbt => import_psbt(&sender, path).await, + ImportExportType::ImportXpub(network) => import_xpub(&sender, path, network).await, ImportExportType::ImportDescriptor => import_descriptor(&sender, path).await, ImportExportType::ExportBackup(str) => export_string(&sender, path, str).await, ImportExportType::ExportXpub(xpub_str) => export_string(&sender, path, xpub_str).await, @@ -596,6 +608,35 @@ pub async fn import_descriptor( Ok(()) } +pub async fn import_xpub( + sender: &UnboundedSender, + path: PathBuf, + network: Network, +) -> Result<(), Error> { + let mut file = File::open(path)?; + + let mut xpub_str = String::new(); + file.read_to_string(&mut xpub_str)?; + + if let Ok(DescriptorPublicKey::XPub(key)) = DescriptorPublicKey::from_str(&xpub_str) { + let valid = if network == Network::Bitcoin { + key.xkey.network == Network::Bitcoin.into() + } else { + key.xkey.network == Network::Testnet.into() + }; + if valid { + send_progress!(sender, Progress(100.0)); + send_progress!(sender, Xpub(xpub_str)); + } else { + return Err(Error::XpubNetwork); + } + } else { + return Err(Error::ParseXpub); + } + + Ok(()) +} + /// Import a backup in an already existing wallet: /// - Load backup from file /// - check if networks matches From 541c63419b1a39d0159ca87492360037e2119fbb Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Mon, 7 Apr 2025 09:56:15 +0200 Subject: [PATCH 4/6] installer: integrate import xpub feature --- liana-gui/src/installer/message.rs | 1 + .../installer/step/descriptor/editor/key.rs | 52 +++++++++++++++++-- liana-gui/src/installer/view/editor/mod.rs | 21 ++++++-- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/liana-gui/src/installer/message.rs b/liana-gui/src/installer/message.rs index e0ff8ddd..b00fdc52 100644 --- a/liana-gui/src/installer/message.rs +++ b/liana-gui/src/installer/message.rs @@ -180,6 +180,7 @@ pub enum ImportKeyModal { TokenEdited(String), ConfirmToken, SelectKey(usize), + ImportXpub(Network), } #[derive(Debug, Clone)] diff --git a/liana-gui/src/installer/step/descriptor/editor/key.rs b/liana-gui/src/installer/step/descriptor/editor/key.rs index 0cb3efed..98234742 100644 --- a/liana-gui/src/installer/step/descriptor/editor/key.rs +++ b/liana-gui/src/installer/step/descriptor/editor/key.rs @@ -14,6 +14,8 @@ use liana::miniscript::{ use liana_ui::{component::form, widget::Element}; +use crate::app::state::export::ExportModal; +use crate::export::{ImportExportMessage, ImportExportType}; use crate::{ app::settings::ProviderKey, hw::{HardwareWallet, HardwareWallets}, @@ -86,6 +88,7 @@ pub struct EditXpubModal { hot_signer: Arc>, hot_signer_fingerprint: Fingerprint, chosen_signer: Option, + modal: Option, } impl EditXpubModal { @@ -135,6 +138,7 @@ impl EditXpubModal { hot_signer_fingerprint, hot_signer, duplicate_master_fg: false, + modal: None, } } @@ -243,6 +247,28 @@ impl super::DescriptorEditModal for EditXpubModal { .unwrap_or_default(); self.form_name.valid = true; } + Message::ImportExport(import_msg) => match import_msg { + ImportExportMessage::Close => { + if self.modal.is_some() { + self.modal = None; + } + } + ImportExportMessage::Xpub(xpub_str) => { + if self.modal.is_some() { + self.modal = None; + return Task::perform(async move { xpub_str }, |xpub_str| { + Message::DefineDescriptor(message::DefineDescriptor::KeyModal( + message::ImportKeyModal::XPubEdited(xpub_str), + )) + }); + } + } + m => { + if let Some(modal) = self.modal.as_mut() { + return modal.update(m); + } + } + }, Message::DefineDescriptor(message::DefineDescriptor::KeyModal(msg)) => match msg { message::ImportKeyModal::FetchedKey(res) => { self.processing = false; @@ -323,6 +349,14 @@ impl super::DescriptorEditModal for EditXpubModal { self.form_token.valid = s.is_empty() || self.form_token_warning.is_none(); self.form_token.value = s; } + message::ImportKeyModal::ImportXpub(network) => { + if self.modal.is_none() { + let modal = ExportModal::new(None, ImportExportType::ImportXpub(network)); + let launch = modal.launch(false); + self.modal = Some(modal); + return launch; + } + } message::ImportKeyModal::XPubEdited(s) => { self.chosen_signer = None; if let Ok(DescriptorPublicKey::XPub(key)) = DescriptorPublicKey::from_str(&s) { @@ -416,7 +450,14 @@ impl super::DescriptorEditModal for EditXpubModal { } fn subscription(&self, hws: &HardwareWallets) -> Subscription { - hws.refresh().map(Message::HardwareWallets) + let hw = hws.refresh().map(Message::HardwareWallets); + if let Some(modal) = self.modal.as_ref() { + if let Some(sub) = modal.subscription() { + let import = sub.map(|m| Message::ImportExport(ImportExportMessage::Progress(m))); + return Subscription::batch(vec![hw, import]); + } + } + hw } fn view<'a>(&'a self, hws: &'a HardwareWallets) -> Element<'a, Message> { @@ -436,7 +477,7 @@ impl super::DescriptorEditModal for EditXpubModal { }) .collect(); let chosen_signer = self.chosen_signer.as_ref().map(|s| s.fingerprint); - view::editor::edit_key_modal( + let content = view::editor::edit_key_modal( "Set your key", self.network, self.path_kind, @@ -512,7 +553,12 @@ impl super::DescriptorEditModal for EditXpubModal { self.form_token_warning.as_ref(), self.form_key_source_kind.as_ref(), self.duplicate_master_fg, - ) + ); + if let Some(modal) = &self.modal { + modal.view(content) + } else { + content + } } } diff --git a/liana-gui/src/installer/view/editor/mod.rs b/liana-gui/src/installer/view/editor/mod.rs index 6e432406..caeb8d67 100644 --- a/liana-gui/src/installer/view/editor/mod.rs +++ b/liana-gui/src/installer/view/editor/mod.rs @@ -352,6 +352,7 @@ pub fn edit_key_modal<'a>( form_key_source_kind: Option<&KeySourceKind>, duplicate_master_fg: bool, ) -> Element<'a, Message> { + let xpub_valid = form_xpub.valid && !form_xpub.value.is_empty(); let content = Column::new() .padding(25) .push_maybe(error.map(|e| card::error("Failed to import xpub", e.to_string()))) @@ -392,8 +393,22 @@ pub fn edit_key_modal<'a>( .push( Row::new() .align_y(Alignment::Center) - .push(p1_regular("Enter an extended public key:").width(Length::Fill)) - .push(image::success_mark_icon().width(Length::Fixed(50.0))) + .push(p1_regular("Enter/import an extended public key:").width(Length::Fill)) + .push_maybe(if !xpub_valid{ + Some( + button::primary(Some(icon::restore_icon()), "Import") + .on_press( + Message::DefineDescriptor( + message::DefineDescriptor::KeyModal( + message::ImportKeyModal::ImportXpub(network),),) + )) + } else { None } + ) + .push_maybe( + if xpub_valid { + Some(image::success_mark_icon().width(Length::Fixed(50.0))) + } else {None} + ) ) .push( Row::new() @@ -422,7 +437,7 @@ pub fn edit_key_modal<'a>( .align_y(Alignment::Center) .spacing(10) .push(icon::import_icon()) - .push(p1_regular("Enter an extended public key")) + .push(p1_regular("Enter/import an extended public key")) ) .padding(20) .width(Length::Fill) From 8dd16fb586b4edc87d602b0a1d6ad396fe5340b3 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Mon, 7 Apr 2025 12:40:25 +0200 Subject: [PATCH 5/6] export: trim string read from files --- liana-gui/src/export.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/liana-gui/src/export.rs b/liana-gui/src/export.rs index 54008e4c..d86cc1d4 100644 --- a/liana-gui/src/export.rs +++ b/liana-gui/src/export.rs @@ -585,6 +585,7 @@ pub async fn import_psbt(sender: &UnboundedSender, path: PathBuf) -> R let mut psbt_str = String::new(); file.read_to_string(&mut psbt_str)?; + psbt_str = psbt_str.trim().to_string(); let psbt = Psbt::from_str(&psbt_str).map_err(|_| Error::ParsePsbt)?; @@ -601,7 +602,9 @@ pub async fn import_descriptor( let mut descr_str = String::new(); file.read_to_string(&mut descr_str)?; - let descriptor = LianaDescriptor::from_str(&descr_str).map_err(|_| Error::ParseDescriptor)?; + let descr_str = descr_str.trim(); + + let descriptor = LianaDescriptor::from_str(descr_str).map_err(|_| Error::ParseDescriptor)?; send_progress!(sender, Progress(100.0)); send_progress!(sender, Descriptor(descriptor)); @@ -617,6 +620,7 @@ pub async fn import_xpub( let mut xpub_str = String::new(); file.read_to_string(&mut xpub_str)?; + let xpub_str = xpub_str.trim().to_string(); if let Ok(DescriptorPublicKey::XPub(key)) = DescriptorPublicKey::from_str(&xpub_str) { let valid = if network == Network::Bitcoin { @@ -667,6 +671,7 @@ pub async fn import_backup( let mut backup_str = String::new(); file.read_to_string(&mut backup_str)?; + backup_str = backup_str.trim().to_string(); let backup: Result = serde_json::from_str(&backup_str); let backup = match backup { @@ -971,6 +976,7 @@ pub async fn wallet_from_backup( let mut backup_str = String::new(); file.read_to_string(&mut backup_str)?; + backup_str = backup_str.trim().to_string(); let backup: Result = serde_json::from_str(&backup_str); let backup = match backup { From 0b2ebd3aaad945afdf8b4dea4931179626663b89 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Mon, 14 Apr 2025 16:37:09 +0200 Subject: [PATCH 6/6] export: typo 'Fail to' => 'Failed to' --- liana-gui/src/app/view/warning.rs | 2 +- liana-gui/src/export.rs | 26 +++++++++++++------------- liana-gui/src/main.rs | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/liana-gui/src/app/view/warning.rs b/liana-gui/src/app/view/warning.rs index 1f371481..56ccb056 100644 --- a/liana-gui/src/app/view/warning.rs +++ b/liana-gui/src/app/view/warning.rs @@ -50,7 +50,7 @@ impl From<&Error> for WarningMessage { Error::Desc(e) => WarningMessage(format!("Descriptor analysis error: '{}'.", e)), Error::Spend(e) => WarningMessage(format!("Spend creation error: '{}'.", e)), Error::ImportExport(e) => WarningMessage(format!("{e}")), - Error::RestoreBackup(e) => WarningMessage(format!("Fail to restore backup: {e}")), + Error::RestoreBackup(e) => WarningMessage(format!("Failed to restore backup: {e}")), } } } diff --git a/liana-gui/src/export.rs b/liana-gui/src/export.rs index d86cc1d4..df1361b6 100644 --- a/liana-gui/src/export.rs +++ b/liana-gui/src/export.rs @@ -142,7 +142,7 @@ impl Display for Error { Error::Bip329Export(e) => write!(f, "Bip329Export: {e}"), Error::BackupImport(e) => write!(f, "BackupImport: {e}"), Error::Backup(e) => write!(f, "Backup: {e}"), - Error::ParseXpub => write!(f, "Fail to parse Xpub from file"), + Error::ParseXpub => write!(f, "Failed to parse Xpub from file"), Error::XpubNetwork => write!(f, "Xpub is for another network"), } } @@ -736,7 +736,7 @@ pub async fn import_backup( let db_labels = match daemon.get_labels_bip329(0, u32::MAX).await { Ok(l) => l, Err(_) => { - return Err(Error::BackupImport("Fail to dump DB labels".into())); + return Err(Error::BackupImport("Failed to dump DB labels".into())); } }; @@ -759,7 +759,7 @@ pub async fn import_backup( write_labels = match ack_receiver.recv().await { Some(b) => b, None => { - return Err(Error::BackupImport("Fail to receive labels ACK".into())); + return Err(Error::BackupImport("Failed to receive labels ACK".into())); } } } @@ -773,11 +773,11 @@ pub async fn import_backup( Some(c) => match &c.data_dir { Some(dd) => dd, None => { - return Err(Error::BackupImport("Fail to get Daemon config".into())); + return Err(Error::BackupImport("Failed to get Daemon config".into())); } }, None => { - return Err(Error::BackupImport("Fail to get Daemon config".into())); + return Err(Error::BackupImport("Failed to get Daemon config".into())); } }; @@ -787,7 +787,7 @@ pub async fn import_backup( let settings = match Settings::from_file(datadir.to_path_buf(), network) { Ok(s) => s, Err(_) => { - return Err(Error::BackupImport("Fail to get App Settings".into())); + return Err(Error::BackupImport("Failed to get App Settings".into())); } }; @@ -825,7 +825,7 @@ pub async fn import_backup( write_aliases = match ack_receiver.recv().await { Some(a) => a, None => { - return Err(Error::BackupImport("Fail to receive aliases ACK".into())); + return Err(Error::BackupImport("Failed to receive aliases ACK".into())); } }; } @@ -846,7 +846,7 @@ pub async fn import_backup( if daemon.update_deriv_indexes(receive, change).await.is_err() { return Err(Error::BackupImport( - "Fail to update derivation indexes".into(), + "Failed to update derivation indexes".into(), )); } @@ -858,7 +858,7 @@ pub async fn import_backup( psbts.push(p); } Err(_) => { - return Err(Error::BackupImport("Fail to parse PSBT".into())); + return Err(Error::BackupImport("Failed to parse PSBT".into())); } } } @@ -866,7 +866,7 @@ pub async fn import_backup( // import PSBTs for psbt in psbts { if daemon.update_spend_tx(&psbt).await.is_err() { - return Err(Error::BackupImport("Fail to store PSBT".into())); + return Err(Error::BackupImport("Failed to store PSBT".into())); } } @@ -883,7 +883,7 @@ pub async fn import_backup( }) .collect(); if daemon.update_labels(&labels).await.is_err() { - return Err(Error::BackupImport("Fail to import labels".into())); + return Err(Error::BackupImport("Failed to import labels".into())); } } @@ -904,7 +904,7 @@ pub async fn import_backup( settings.wallets.get_mut(0).expect("already checked").keys = settings_aliases.clone().into_values().collect(); if settings.to_file(datadir.to_path_buf(), network).is_err() { - return Err(Error::BackupImport("Fail to import keys aliases".into())); + return Err(Error::BackupImport("Failed to import keys aliases".into())); } else { // Update wallet state send_progress!(sender, UpdateAliases(settings_aliases)); @@ -1137,7 +1137,7 @@ pub async fn import_backup_at_launch( // import PSBTs for psbt in psbts { if let Err(e) = daemon.update_spend_tx(&psbt).await { - tracing::error!("Fail to restore PSBT: {e}") + tracing::error!("Failed to restore PSBT: {e}") } } diff --git a/liana-gui/src/main.rs b/liana-gui/src/main.rs index d98decfe..a9c97e0b 100644 --- a/liana-gui/src/main.rs +++ b/liana-gui/src/main.rs @@ -405,7 +405,7 @@ impl GUI { command.map(|msg| Message::Run(Box::new(msg))) } loader::Message::App(Err(e), _) => { - tracing::error!("Fail to import backup: {e}"); + tracing::error!("Failed to import backup: {e}"); Task::none() }