Merge #848: Grey out harware wallets when unrelated or do not support method
3372e2f1e0be711dac71becf57541e48309e93e4 gui: grey out hws with addr verif unimplemented (edouardparis)
0ef49ed3f716e57f4bcd9a3f95d9c48dbce488d3 gui: grey out unrelated hws (edouardparis)
Pull request description:
close #830
ACKs for top commit:
jp1ac4:
ACK 3372e2f1e0.
Tree-SHA512: 8c8cf17b05d3920dfd32e558c3ee27b94c4b9f65e931734cfc62cb8479e986d60882796bbc48b0c5f0061cda689a3b837b6d6bb159738139fa7f30684fa956a2
This commit is contained in:
commit
6151c57af4
@ -2,7 +2,11 @@ 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},
|
||||
};
|
||||
use async_hwi::DeviceKind;
|
||||
|
||||
pub fn hw_list_view(
|
||||
i: usize,
|
||||
@ -40,9 +44,17 @@ 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,17 @@ 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()),
|
||||
@ -113,7 +133,7 @@ pub fn hw_list_view_verify_address(
|
||||
hw: &HardwareWallet,
|
||||
chosen: bool,
|
||||
) -> Element<Message> {
|
||||
let mut bttn = Button::new(match hw {
|
||||
let (content, selectable) = match hw {
|
||||
HardwareWallet::Supported {
|
||||
kind,
|
||||
version,
|
||||
@ -122,21 +142,59 @@ 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 { 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()),
|
||||
},
|
||||
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)
|
||||
|
||||
@ -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<Version>,
|
||||
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 {
|
||||
|
||||
@ -87,6 +87,63 @@ 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<V>,
|
||||
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<V>,
|
||||
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),
|
||||
"This signer does not have a key in this wallet.",
|
||||
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<V>,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user