diff --git a/gui/src/installer/step/descriptor.rs b/gui/src/installer/step/descriptor.rs index 99a5581b..a9645003 100644 --- a/gui/src/installer/step/descriptor.rs +++ b/gui/src/installer/step/descriptor.rs @@ -6,10 +6,10 @@ use liana::{ descriptors::MultipathDescriptor, miniscript::{ bitcoin::{ - util::bip32::{DerivationPath, Fingerprint}, + util::bip32::{DerivationPath, ExtendedPubKey, Fingerprint}, Network, }, - descriptor::{DescriptorMultiXKey, DescriptorPublicKey, Wildcard}, + descriptor::DescriptorPublicKey, }, }; @@ -124,13 +124,13 @@ impl Step for DefineDescriptor { fn apply(&mut self, ctx: &mut Context) -> bool { ctx.bitcoin_config.network = self.network; // descriptor forms for import or creation cannot be both empty or filled. - let user_key = DescriptorPublicKey::from_str(&self.user_xpub.value); + let user_key = DescriptorPublicKey::from_str(&format!("{}/<0;1>/*", &self.user_xpub.value)); self.user_xpub.valid = user_key.is_ok(); if let Ok(key) = &user_key { self.user_xpub.valid = check_key_network(key, self.network); } - let heir_key = DescriptorPublicKey::from_str(&self.heir_xpub.value); + let heir_key = DescriptorPublicKey::from_str(&format!("{}/<0;1>/*", &self.heir_xpub.value)); self.heir_xpub.valid = heir_key.is_ok(); if let Ok(key) = &heir_key { self.heir_xpub.valid = check_key_network(key, self.network); @@ -297,30 +297,47 @@ impl GetHardwareWalletXpubModal { } } +pub struct XKey { + origin: Option<(Fingerprint, DerivationPath)>, + key: ExtendedPubKey, +} + +impl std::fmt::Display for XKey { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if let Some((ref master_id, ref master_deriv)) = self.origin { + std::fmt::Formatter::write_str(f, "[")?; + for byte in master_id.into_bytes().iter() { + write!(f, "{:02x}", byte)?; + } + for child in master_deriv { + write!(f, "/{}", child)?; + } + std::fmt::Formatter::write_str(f, "]")?; + } + self.key.fmt(f)?; + Ok(()) + } +} + async fn get_extended_pubkey( hw: std::sync::Arc, fingerprint: Fingerprint, network: Network, -) -> Result { +) -> Result { let derivation_path = DerivationPath::from_str(if network == Network::Bitcoin { LIANA_STANDARD_PATH } else { LIANA_TESTNET_STANDARD_PATH }) .unwrap(); - let xkey = hw + let key = hw .get_extended_pubkey(&derivation_path, false) .await .map_err(Error::from)?; - Ok(DescriptorPublicKey::MultiXPub(DescriptorMultiXKey { + Ok(XKey { origin: Some((fingerprint, derivation_path)), - derivation_paths: vec![ - DerivationPath::from_str("m/0").unwrap(), - DerivationPath::from_str("m/1").unwrap(), - ], - xkey, - wildcard: Wildcard::Unhardened, - })) + key, + }) } pub struct ImportDescriptor { diff --git a/gui/src/installer/view.rs b/gui/src/installer/view.rs index 806560c7..c208346e 100644 --- a/gui/src/installer/view.rs +++ b/gui/src/installer/view.rs @@ -148,6 +148,9 @@ pub fn define_descriptor<'a>( .push(text("Your public key:").bold()) .push( Row::new() + .push(button::border(Some(icon::chip_icon()), "Import").on_press( + Message::DefineDescriptor(message::DefineDescriptor::ImportUserHWXpub), + )) .push( form::Form::new("Xpub", user_xpub, |msg| { Message::DefineDescriptor(message::DefineDescriptor::UserXpubEdited(msg)) @@ -158,11 +161,9 @@ pub fn define_descriptor<'a>( "Please enter correct tpub" }) .size(20) - .padding(10), + .padding(12), ) - .push(button::primary(Some(icon::chip_icon()), "Import").on_press( - Message::DefineDescriptor(message::DefineDescriptor::ImportUserHWXpub), - )) + .push(Container::new(text("/<0;1>/*"))) .spacing(5) .align_items(Alignment::Center), ) @@ -172,6 +173,9 @@ pub fn define_descriptor<'a>( .push(text("Public key of the recovery key:").bold()) .push( Row::new() + .push(button::border(Some(icon::chip_icon()), "Import").on_press( + Message::DefineDescriptor(message::DefineDescriptor::ImportHeirHWXpub), + )) .push( form::Form::new("Xpub", heir_xpub, |msg| { Message::DefineDescriptor(message::DefineDescriptor::HeirXpubEdited(msg)) @@ -182,11 +186,9 @@ pub fn define_descriptor<'a>( "Please enter correct tpub" }) .size(20) - .padding(10), + .padding(12), ) - .push(button::primary(Some(icon::chip_icon()), "Import").on_press( - Message::DefineDescriptor(message::DefineDescriptor::ImportHeirHWXpub), - )) + .push(Container::new(text("/<0;1>/*"))) .spacing(5) .align_items(Alignment::Center), ) @@ -217,7 +219,7 @@ pub fn define_descriptor<'a>( .push(col_user_xpub) .push(col_sequence) .push(col_heir_xpub) - .spacing(20), + .spacing(25), ) .push( if user_xpub.value.is_empty()