From 541c63419b1a39d0159ca87492360037e2119fbb Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Mon, 7 Apr 2025 09:56:15 +0200 Subject: [PATCH] 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)