From 0ef49ed3f716e57f4bcd9a3f95d9c48dbce488d3 Mon Sep 17 00:00:00 2001 From: edouardparis Date: Tue, 5 Dec 2023 18:17:26 +0100 Subject: [PATCH 1/2] gui: grey out unrelated hws --- gui/src/app/view/hw.rs | 50 ++++++++++++++++++----- gui/src/hw.rs | 84 +++++++++++++++++++++++++++++++------- gui/ui/src/component/hw.rs | 28 +++++++++++++ 3 files changed, 137 insertions(+), 25 deletions(-) diff --git a/gui/src/app/view/hw.rs b/gui/src/app/view/hw.rs index de1eafd3..a44e0ca4 100644 --- a/gui/src/app/view/hw.rs +++ b/gui/src/app/view/hw.rs @@ -2,7 +2,10 @@ use iced::Length; use liana_ui::{component::hw, theme, widget::*}; -use crate::{app::view::message::*, hw::HardwareWallet}; +use crate::{ + app::view::message::*, + hw::{HardwareWallet, UnsupportedReason}, +}; pub fn hw_list_view( i: usize, @@ -40,9 +43,18 @@ pub fn hw_list_view( hw::supported_hardware_wallet(kind, version.as_ref(), fingerprint, alias.as_ref()) } } - HardwareWallet::Unsupported { version, kind, .. } => { - hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()) - } + HardwareWallet::Unsupported { + version, + kind, + reason, + .. + } => match reason { + UnsupportedReason::NotPartOfWallet(fg) => { + hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg) + } + + _ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()), + }, HardwareWallet::Locked { kind, pairing_code, .. } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), @@ -90,9 +102,18 @@ pub fn hw_list_view_for_registration( hw::supported_hardware_wallet(kind, version.as_ref(), fingerprint, alias.as_ref()) } } - HardwareWallet::Unsupported { version, kind, .. } => { - hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()) - } + HardwareWallet::Unsupported { + version, + kind, + reason, + .. + } => match reason { + UnsupportedReason::NotPartOfWallet(fg) => { + hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg) + } + + _ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()), + }, HardwareWallet::Locked { kind, pairing_code, .. } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), @@ -127,9 +148,18 @@ pub fn hw_list_view_verify_address( hw::supported_hardware_wallet(kind, version.as_ref(), fingerprint, alias.as_ref()) } } - HardwareWallet::Unsupported { version, kind, .. } => { - hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()) - } + HardwareWallet::Unsupported { + version, + kind, + reason, + .. + } => match reason { + UnsupportedReason::NotPartOfWallet(fg) => { + hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg) + } + + _ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()), + }, HardwareWallet::Locked { kind, pairing_code, .. } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), diff --git a/gui/src/hw.rs b/gui/src/hw.rs index 90d753a0..8592dcda 100644 --- a/gui/src/hw.rs +++ b/gui/src/hw.rs @@ -14,6 +14,15 @@ use liana::miniscript::bitcoin::{bip32::Fingerprint, hashes::hex::FromHex, Netwo use serde::{Deserialize, Serialize}; use tracing::{debug, warn}; +#[derive(Debug, Clone)] +pub enum UnsupportedReason { + Version { + minimal_supported_version: &'static str, + }, + Method(&'static str), + NotPartOfWallet(Fingerprint), +} + // Todo drop the Clone, to remove the Mutex on HardwareWallet::Locked #[derive(Debug, Clone)] pub enum HardwareWallet { @@ -21,7 +30,7 @@ pub enum HardwareWallet { id: String, kind: DeviceKind, version: Option, - message: String, + reason: UnsupportedReason, }, Locked { id: String, @@ -225,21 +234,35 @@ impl HardwareWallets { BitBox02::from(paired_bb).with_network(network); let fingerprint = bitbox2.get_master_fingerprint().await?; let mut registered = false; - if let Some(wallet) = wallet { + if let Some(wallet) = &wallet { let desc = wallet.main_descriptor.to_string(); bitbox2 = bitbox2.with_policy(&desc)?; registered = bitbox2.is_policy_registered(&desc).await?; } - Ok(HardwareWallet::Supported { - id: id.clone(), - kind: DeviceKind::BitBox02, - fingerprint, - device: bitbox2.into(), - version: None, - registered: Some(registered), - alias: None, - }) + if wallet + .map(|w| w.descriptor_keys().contains(&fingerprint)) + == Some(true) + { + Ok(HardwareWallet::Supported { + id: id.clone(), + kind: DeviceKind::BitBox02, + fingerprint, + device: bitbox2.into(), + version: None, + registered: Some(registered), + alias: None, + }) + } else { + Ok(HardwareWallet::Unsupported { + id: id.clone(), + kind: DeviceKind::BitBox02, + version: None, + reason: UnsupportedReason::NotPartOfWallet( + fingerprint, + ), + }) + } }, |res| HardwareWalletMessage::Unlocked(id_cloned, res), )); @@ -417,7 +440,9 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) { id, kind: device.device_kind(), version, - message: "Minimal supported app version is 2.1.0".to_string(), + reason: UnsupportedReason::Version { + minimal_supported_version: "2.1.0", + }, }); } } @@ -426,7 +451,9 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) { id, kind: device.device_kind(), version: None, - message: "Minimal supported app version is 2.1.0".to_string(), + reason: UnsupportedReason::Version { + minimal_supported_version: "2.1.0", + }, }); } } @@ -516,7 +543,9 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) { id, kind: device.device_kind(), version, - message: "Minimal supported app version is 2.1.0".to_string(), + reason: UnsupportedReason::Version { + minimal_supported_version: "2.1.0", + }, }); } } @@ -525,7 +554,9 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) { id, kind: device.device_kind(), version: None, - message: "Minimal supported app version is 2.1.0".to_string(), + reason: UnsupportedReason::Version { + minimal_supported_version: "2.1.0", + }, }); } }, @@ -536,6 +567,29 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) { } } + if let Some(wallet) = &state.wallet { + let wallet_keys = wallet.descriptor_keys(); + for hw in &mut hws { + if let HardwareWallet::Supported { + fingerprint, + id, + kind, + version, + .. + } = &hw + { + if !wallet_keys.contains(fingerprint) { + *hw = HardwareWallet::Unsupported { + id: id.clone(), + kind: *kind, + version: version.clone(), + reason: UnsupportedReason::NotPartOfWallet(*fingerprint), + }; + } + } + } + } + state.connected_supported_hws = still .iter() .chain(hws.iter().filter_map(|hw| match hw { diff --git a/gui/ui/src/component/hw.rs b/gui/ui/src/component/hw.rs index c393e049..aad400ad 100644 --- a/gui/ui/src/component/hw.rs +++ b/gui/ui/src/component/hw.rs @@ -87,6 +87,34 @@ pub fn unregistered_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Displa .padding(10) } +pub fn unrelated_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( + kind: K, + version: Option, + fingerprint: F, +) -> Container<'a, T> { + container( + tooltip::Tooltip::new( + container( + column(vec![ + text::p1_regular(format!("#{}", fingerprint)).into(), + Row::new() + .spacing(5) + .push(text::caption(kind.to_string())) + .push_maybe(version.map(|v| text::caption(v.to_string()))) + .into(), + ]) + .width(Length::Fill), + ) + .width(Length::Fill) + .padding(10), + "The signing device is not part of the wallet setup", + tooltip::Position::Bottom, + ) + .style(theme::Container::Card(theme::Card::Simple)), + ) + .width(Length::Fill) +} + pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( kind: K, version: Option, From 3372e2f1e0be711dac71becf57541e48309e93e4 Mon Sep 17 00:00:00 2001 From: edouardparis Date: Tue, 5 Dec 2023 18:30:20 +0100 Subject: [PATCH 2/2] gui: grey out hws with addr verif unimplemented --- gui/src/app/view/hw.rs | 62 +++++++++++++++++++++++++++----------- gui/ui/src/component/hw.rs | 31 ++++++++++++++++++- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/gui/src/app/view/hw.rs b/gui/src/app/view/hw.rs index a44e0ca4..05cacf60 100644 --- a/gui/src/app/view/hw.rs +++ b/gui/src/app/view/hw.rs @@ -6,6 +6,7 @@ use crate::{ app::view::message::*, hw::{HardwareWallet, UnsupportedReason}, }; +use async_hwi::DeviceKind; pub fn hw_list_view( i: usize, @@ -52,7 +53,6 @@ pub fn hw_list_view( UnsupportedReason::NotPartOfWallet(fg) => { hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg) } - _ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()), }, HardwareWallet::Locked { @@ -111,7 +111,6 @@ pub fn hw_list_view_for_registration( UnsupportedReason::NotPartOfWallet(fg) => { hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg) } - _ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()), }, HardwareWallet::Locked { @@ -134,7 +133,7 @@ pub fn hw_list_view_verify_address( hw: &HardwareWallet, chosen: bool, ) -> Element { - let mut bttn = Button::new(match hw { + let (content, selectable) = match hw { HardwareWallet::Supported { kind, version, @@ -143,9 +142,32 @@ pub fn hw_list_view_verify_address( .. } => { if chosen { - hw::processing_hardware_wallet(kind, version.as_ref(), fingerprint, alias.as_ref()) + ( + hw::processing_hardware_wallet( + kind, + version.as_ref(), + fingerprint, + alias.as_ref(), + ), + false, + ) } else { - hw::supported_hardware_wallet(kind, version.as_ref(), fingerprint, alias.as_ref()) + match kind { + DeviceKind::Specter | DeviceKind::SpecterSimulator => { + (hw::unimplemented_method_hardware_wallet( + &kind.to_string(), + version.as_ref(), + fingerprint, + "Liana cannot request the device to display the address. \n The verification must be done manually with the device control." + ), false) + } + _ => (hw::supported_hardware_wallet( + kind, + version.as_ref(), + fingerprint, + alias.as_ref(), + ), true), + } } } HardwareWallet::Unsupported { @@ -153,20 +175,26 @@ pub fn hw_list_view_verify_address( kind, reason, .. - } => match reason { - UnsupportedReason::NotPartOfWallet(fg) => { - hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg) - } - - _ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()), - }, + } => ( + match reason { + UnsupportedReason::NotPartOfWallet(fg) => { + hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg) + } + _ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()), + }, + false, + ), HardwareWallet::Locked { kind, pairing_code, .. - } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), - }) - .style(theme::Button::Border) - .width(Length::Fill); - if !chosen && hw.is_supported() { + } => ( + hw::locked_hardware_wallet(kind, pairing_code.as_ref()), + false, + ), + }; + let mut bttn = Button::new(content) + .style(theme::Button::Border) + .width(Length::Fill); + if selectable && hw.is_supported() { bttn = bttn.on_press(Message::SelectHardwareWallet(i)); } Container::new(bttn) diff --git a/gui/ui/src/component/hw.rs b/gui/ui/src/component/hw.rs index aad400ad..848935e5 100644 --- a/gui/ui/src/component/hw.rs +++ b/gui/ui/src/component/hw.rs @@ -87,6 +87,35 @@ pub fn unregistered_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Displa .padding(10) } +pub fn unimplemented_method_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( + kind: K, + version: Option, + fingerprint: F, + message: &'static str, +) -> Container<'a, T> { + container( + tooltip::Tooltip::new( + container( + column(vec![ + text::p1_regular(format!("#{}", fingerprint)).into(), + Row::new() + .spacing(5) + .push(text::caption(kind.to_string())) + .push_maybe(version.map(|v| text::caption(v.to_string()))) + .into(), + ]) + .width(Length::Fill), + ) + .width(Length::Fill) + .padding(10), + message, + tooltip::Position::Bottom, + ) + .style(theme::Container::Card(theme::Card::Simple)), + ) + .width(Length::Fill) +} + pub fn unrelated_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( kind: K, version: Option, @@ -107,7 +136,7 @@ pub fn unrelated_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( ) .width(Length::Fill) .padding(10), - "The signing device is not part of the wallet setup", + "This signer does not have a key in this wallet.", tooltip::Position::Bottom, ) .style(theme::Container::Card(theme::Card::Simple)),