Add jade hardware wallet
This commit is contained in:
parent
b7a72e064d
commit
6b0c93c5c3
124
gui/Cargo.lock
generated
124
gui/Cargo.lock
generated
@ -2,27 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "CoreFoundation-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mach 0.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "IOKit-sys"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a"
|
||||
dependencies = [
|
||||
"CoreFoundation-sys",
|
||||
"libc",
|
||||
"mach 0.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph"
|
||||
version = "0.2.20"
|
||||
@ -214,9 +193,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-hwi"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "912663643d018301fb5534949e8430515c7cdc9bf453bfefba2dc70dc854dd31"
|
||||
checksum = "647a2513ce55652719759c6416e98de94b19a349dc94e1be4924b0487f73ce9b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bitbox-api",
|
||||
@ -227,10 +206,17 @@ dependencies = [
|
||||
"ledger-apdu",
|
||||
"ledger-transport-hidapi",
|
||||
"ledger_bitcoin_client",
|
||||
"prost 0.12.2",
|
||||
"prost-derive 0.12.2",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_cbor",
|
||||
"serialport",
|
||||
"tokio",
|
||||
"tokio-serial",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1353,7 +1339,7 @@ checksum = "bdd2162b720141a91a054640662d3edce3d50a944a50ffca5313cd951abb35b4"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"flume",
|
||||
"half",
|
||||
"half 2.2.1",
|
||||
"lebe",
|
||||
"miniz_oxide",
|
||||
"rayon-core",
|
||||
@ -1853,6 +1839,12 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.2.1"
|
||||
@ -2132,7 +2124,7 @@ dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bytemuck",
|
||||
"cosmic-text",
|
||||
"half",
|
||||
"half 2.2.1",
|
||||
"iced_core",
|
||||
"iced_futures",
|
||||
"image",
|
||||
@ -2337,6 +2329,16 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-kit-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"mach2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.11"
|
||||
@ -2810,19 +2812,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mach"
|
||||
version = "0.1.2"
|
||||
name = "mach2"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mach"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
|
||||
checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -2957,7 +2950,7 @@ checksum = "20a4c60ca5c9c0e114b3bd66ff4aa5f9b2b175442be51ca6c4365d687a97a2ac"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mio",
|
||||
"nix 0.26.2",
|
||||
"nix",
|
||||
"serialport",
|
||||
"winapi",
|
||||
]
|
||||
@ -3033,17 +3026,6 @@ dependencies = [
|
||||
"jni-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.2"
|
||||
@ -4253,6 +4235,25 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_bytes"
|
||||
version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
|
||||
dependencies = [
|
||||
"half 1.8.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.186"
|
||||
@ -4289,18 +4290,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serialport"
|
||||
version = "4.2.0"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aab92efb5cf60ad310548bc3f16fa6b0d950019cb7ed8ff41968c3d03721cf12"
|
||||
checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828"
|
||||
dependencies = [
|
||||
"CoreFoundation-sys",
|
||||
"IOKit-sys",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.4.2",
|
||||
"cfg-if",
|
||||
"core-foundation-sys",
|
||||
"io-kit-sys",
|
||||
"libudev",
|
||||
"mach 0.3.2",
|
||||
"nix 0.24.3",
|
||||
"mach2",
|
||||
"nix",
|
||||
"regex",
|
||||
"scopeguard",
|
||||
"unescaper",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@ -4942,6 +4945,15 @@ version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "unescaper"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0adf6ad32eb5b3cadff915f7b770faaac8f7ff0476633aa29eb0d9584d889d34"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
|
||||
@ -15,7 +15,7 @@ path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
async-hwi = "0.0.16"
|
||||
async-hwi = "0.0.17"
|
||||
liana = { git = "https://github.com/wizardsardine/liana", branch = "master", default-features = false, features = ["nonblocking_shutdown"] }
|
||||
liana_ui = { path = "ui" }
|
||||
backtrace = "0.3"
|
||||
|
||||
@ -53,6 +53,9 @@ pub fn hw_list_view(
|
||||
UnsupportedReason::NotPartOfWallet(fg) => {
|
||||
hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg)
|
||||
}
|
||||
UnsupportedReason::WrongNetwork => {
|
||||
hw::wrong_network_hardware_wallet(&kind.to_string(), version.as_ref())
|
||||
}
|
||||
_ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()),
|
||||
},
|
||||
HardwareWallet::Locked {
|
||||
@ -111,6 +114,9 @@ pub fn hw_list_view_for_registration(
|
||||
UnsupportedReason::NotPartOfWallet(fg) => {
|
||||
hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg)
|
||||
}
|
||||
UnsupportedReason::WrongNetwork => {
|
||||
hw::wrong_network_hardware_wallet(&kind.to_string(), version.as_ref())
|
||||
}
|
||||
_ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()),
|
||||
},
|
||||
HardwareWallet::Locked {
|
||||
@ -180,6 +186,9 @@ pub fn hw_list_view_verify_address(
|
||||
UnsupportedReason::NotPartOfWallet(fg) => {
|
||||
hw::unrelated_hardware_wallet(&kind.to_string(), version.as_ref(), fg)
|
||||
}
|
||||
UnsupportedReason::WrongNetwork => {
|
||||
hw::wrong_network_hardware_wallet(&kind.to_string(), version.as_ref())
|
||||
}
|
||||
_ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()),
|
||||
},
|
||||
false,
|
||||
|
||||
245
gui/src/hw.rs
245
gui/src/hw.rs
@ -8,7 +8,9 @@ use std::{
|
||||
use crate::app::{settings, wallet::Wallet};
|
||||
use async_hwi::{
|
||||
bitbox::{api::runtime, BitBox02, PairingBitbox02},
|
||||
coldcard, ledger, specter, DeviceKind, Error as HWIError, Version, HWI,
|
||||
coldcard,
|
||||
jade::{self, Jade},
|
||||
ledger, specter, DeviceKind, Error as HWIError, Version, HWI,
|
||||
};
|
||||
use liana::miniscript::bitcoin::{bip32::Fingerprint, hashes::hex::FromHex, Network};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -21,6 +23,7 @@ pub enum UnsupportedReason {
|
||||
},
|
||||
Method(&'static str),
|
||||
NotPartOfWallet(Fingerprint),
|
||||
WrongNetwork,
|
||||
}
|
||||
|
||||
// Todo drop the Clone, to remove the Mutex on HardwareWallet::Locked
|
||||
@ -51,7 +54,8 @@ pub enum HardwareWallet {
|
||||
}
|
||||
|
||||
pub enum LockedDevice {
|
||||
BitBox02(PairingBitbox02<runtime::TokioRuntime>),
|
||||
BitBox02(Box<PairingBitbox02<runtime::TokioRuntime>>),
|
||||
Jade(Jade<jade::SerialTransport>),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for LockedDevice {
|
||||
@ -221,25 +225,47 @@ impl HardwareWallets {
|
||||
*alias = self.aliases.get(fingerprint).cloned();
|
||||
}
|
||||
HardwareWallet::Locked { device, id, .. } => {
|
||||
if let Some(LockedDevice::BitBox02(bb)) = device.lock().unwrap().take()
|
||||
{
|
||||
let id = id.to_string();
|
||||
let id_cloned = id.clone();
|
||||
let network = self.network;
|
||||
let wallet = self.wallet.clone();
|
||||
cmds.push(Command::perform(
|
||||
async move {
|
||||
let paired_bb = bb.wait_confirm().await?;
|
||||
let mut bitbox2 =
|
||||
BitBox02::from(paired_bb).with_network(network);
|
||||
let fingerprint = bitbox2.get_master_fingerprint().await?;
|
||||
let mut registered = false;
|
||||
if let Some(wallet) = &wallet {
|
||||
let desc = wallet.main_descriptor.to_string();
|
||||
bitbox2 = bitbox2.with_policy(&desc)?;
|
||||
registered =
|
||||
bitbox2.is_policy_registered(&desc).await?;
|
||||
if wallet.descriptor_keys().contains(&fingerprint) {
|
||||
match device.lock().unwrap().take() {
|
||||
None => {}
|
||||
Some(LockedDevice::BitBox02(bb)) => {
|
||||
let id = id.to_string();
|
||||
let id_cloned = id.clone();
|
||||
let network = self.network;
|
||||
let wallet = self.wallet.clone();
|
||||
cmds.push(Command::perform(
|
||||
async move {
|
||||
let paired_bb = bb.wait_confirm().await?;
|
||||
let mut bitbox2 =
|
||||
BitBox02::from(paired_bb).with_network(network);
|
||||
let fingerprint =
|
||||
bitbox2.get_master_fingerprint().await?;
|
||||
let mut registered = false;
|
||||
if let Some(wallet) = &wallet {
|
||||
let desc = wallet.main_descriptor.to_string();
|
||||
bitbox2 = bitbox2.with_policy(&desc)?;
|
||||
registered =
|
||||
bitbox2.is_policy_registered(&desc).await?;
|
||||
if wallet.descriptor_keys().contains(&fingerprint) {
|
||||
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,
|
||||
),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Ok(HardwareWallet::Supported {
|
||||
id: id.clone(),
|
||||
kind: DeviceKind::BitBox02,
|
||||
@ -249,30 +275,31 @@ impl HardwareWallets {
|
||||
registered: Some(registered),
|
||||
alias: None,
|
||||
})
|
||||
} else {
|
||||
Ok(HardwareWallet::Unsupported {
|
||||
id: id.clone(),
|
||||
kind: DeviceKind::BitBox02,
|
||||
version: None,
|
||||
reason: UnsupportedReason::NotPartOfWallet(
|
||||
fingerprint,
|
||||
),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Ok(HardwareWallet::Supported {
|
||||
id: id.clone(),
|
||||
kind: DeviceKind::BitBox02,
|
||||
fingerprint,
|
||||
device: bitbox2.into(),
|
||||
version: None,
|
||||
registered: Some(registered),
|
||||
alias: None,
|
||||
})
|
||||
}
|
||||
},
|
||||
|res| HardwareWalletMessage::Unlocked(id_cloned, res),
|
||||
));
|
||||
},
|
||||
|res| HardwareWalletMessage::Unlocked(id_cloned, res),
|
||||
));
|
||||
}
|
||||
Some(LockedDevice::Jade(device)) => {
|
||||
let id = id.clone();
|
||||
let id_cloned = id.clone();
|
||||
let network = self.network;
|
||||
let wallet = self.wallet.clone();
|
||||
cmds.push(Command::perform(
|
||||
async move {
|
||||
device.auth().await?;
|
||||
handle_jade_device(
|
||||
id,
|
||||
network,
|
||||
device,
|
||||
wallet.as_ref().map(|w| w.as_ref()),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
},
|
||||
|res| HardwareWalletMessage::Unlocked(id_cloned, res),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -286,8 +313,8 @@ impl HardwareWallets {
|
||||
}
|
||||
HardwareWalletMessage::Unlocked(id, res) => {
|
||||
match res {
|
||||
Err(_) => {
|
||||
warn!("Pairing failed with an external device");
|
||||
Err(e) => {
|
||||
warn!("Pairing failed with an external device {}", e);
|
||||
self.list.retain(|hw| hw.id() != &id);
|
||||
}
|
||||
Ok(hw) => {
|
||||
@ -317,6 +344,7 @@ impl HardwareWallets {
|
||||
iced::subscription::unfold(
|
||||
format!("refresh-{}", self.network),
|
||||
State {
|
||||
network: self.network,
|
||||
keys_aliases: self.aliases.clone(),
|
||||
wallet: self.wallet.clone(),
|
||||
connected_supported_hws: Vec::new(),
|
||||
@ -329,6 +357,7 @@ impl HardwareWallets {
|
||||
}
|
||||
|
||||
struct State {
|
||||
network: Network,
|
||||
keys_aliases: HashMap<Fingerprint, String>,
|
||||
wallet: Option<Arc<Wallet>>,
|
||||
connected_supported_hws: Vec<String>,
|
||||
@ -406,6 +435,38 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) {
|
||||
}
|
||||
Err(e) => warn!("Error while listing specter wallets: {}", e),
|
||||
}
|
||||
|
||||
match jade::SerialTransport::enumerate_potential_ports() {
|
||||
Ok(ports) => {
|
||||
for port in ports {
|
||||
let id = format!("jade-{}", port);
|
||||
if state.connected_supported_hws.contains(&id) {
|
||||
still.push(id);
|
||||
} else {
|
||||
let device =
|
||||
Jade::new(jade::SerialTransport::new(port)).with_network(state.network);
|
||||
match handle_jade_device(
|
||||
id,
|
||||
state.network,
|
||||
device,
|
||||
state.wallet.as_ref().map(|w| w.as_ref()),
|
||||
Some(&state.keys_aliases),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(hw) => {
|
||||
hws.push(hw);
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => warn!("Error while listing jade devices: {}", e),
|
||||
}
|
||||
|
||||
match ledger::LedgerSimulator::try_connect().await {
|
||||
Ok(mut device) => {
|
||||
let id = "ledger-simulator".to_string();
|
||||
@ -497,7 +558,9 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) {
|
||||
id,
|
||||
kind: DeviceKind::BitBox02,
|
||||
pairing_code: device.pairing_code().map(|s| s.replace('\n', " ")),
|
||||
device: Arc::new(Mutex::new(Some(LockedDevice::BitBox02(device)))),
|
||||
device: Arc::new(Mutex::new(Some(LockedDevice::BitBox02(Box::new(
|
||||
device,
|
||||
))))),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -648,6 +711,94 @@ async fn refresh(mut state: State) -> (HardwareWalletMessage, State) {
|
||||
)
|
||||
}
|
||||
|
||||
async fn handle_jade_device(
|
||||
id: String,
|
||||
network: Network,
|
||||
device: Jade<async_hwi::jade::SerialTransport>,
|
||||
wallet: Option<&Wallet>,
|
||||
keys_aliases: Option<&HashMap<Fingerprint, String>>,
|
||||
) -> Result<HardwareWallet, HWIError> {
|
||||
let info = device.get_info().await?;
|
||||
let version = async_hwi::parse_version(&info.jade_version).ok();
|
||||
// Jade may not be setup for the current network
|
||||
if (network == Network::Bitcoin
|
||||
&& info.jade_networks != jade::api::JadeNetworks::Main
|
||||
&& info.jade_networks != jade::api::JadeNetworks::All)
|
||||
|| (network != Network::Bitcoin && info.jade_networks == jade::api::JadeNetworks::Main)
|
||||
{
|
||||
Ok(HardwareWallet::Unsupported {
|
||||
id,
|
||||
kind: device.device_kind(),
|
||||
version,
|
||||
reason: UnsupportedReason::WrongNetwork,
|
||||
})
|
||||
} else {
|
||||
match info.jade_state {
|
||||
jade::api::JadeState::Locked
|
||||
| jade::api::JadeState::Temp
|
||||
| jade::api::JadeState::Uninit
|
||||
| jade::api::JadeState::Unsaved => Ok(HardwareWallet::Locked {
|
||||
id,
|
||||
kind: DeviceKind::Jade,
|
||||
pairing_code: None,
|
||||
device: Arc::new(Mutex::new(Some(LockedDevice::Jade(device)))),
|
||||
}),
|
||||
jade::api::JadeState::Ready => {
|
||||
let kind = device.device_kind();
|
||||
let version = device.get_version().await.ok();
|
||||
let fingerprint = match device.get_master_fingerprint().await {
|
||||
Err(HWIError::NetworkMismatch) => {
|
||||
return Ok(HardwareWallet::Unsupported {
|
||||
id: id.clone(),
|
||||
kind,
|
||||
version,
|
||||
reason: UnsupportedReason::WrongNetwork,
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
Ok(fingerprint) => fingerprint,
|
||||
};
|
||||
let alias = keys_aliases.and_then(|aliases| aliases.get(&fingerprint).cloned());
|
||||
if let Some(wallet) = &wallet {
|
||||
if wallet.descriptor_keys().contains(&fingerprint) {
|
||||
let desc = wallet.main_descriptor.to_string();
|
||||
let device = device.with_wallet(wallet.name.clone());
|
||||
let registered = device.is_wallet_registered(&wallet.name, &desc).await?;
|
||||
Ok(HardwareWallet::Supported {
|
||||
id: id.clone(),
|
||||
kind,
|
||||
fingerprint,
|
||||
device: Arc::new(device),
|
||||
version,
|
||||
registered: Some(registered),
|
||||
alias,
|
||||
})
|
||||
} else {
|
||||
Ok(HardwareWallet::Unsupported {
|
||||
id: id.clone(),
|
||||
kind,
|
||||
version,
|
||||
reason: UnsupportedReason::NotPartOfWallet(fingerprint),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Ok(HardwareWallet::Supported {
|
||||
id: id.clone(),
|
||||
kind,
|
||||
fingerprint,
|
||||
device: Arc::new(device),
|
||||
version,
|
||||
registered: Some(false),
|
||||
alias,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AsRefWrap<'a, T> {
|
||||
inner: &'a T,
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ use liana_ui::{
|
||||
|
||||
use crate::{
|
||||
bitcoind::{ConfigField, RpcAuthType, RpcAuthValues, StartInternalBitcoindError},
|
||||
hw::{is_compatible_with_tapminiscript, HardwareWallet},
|
||||
hw::{is_compatible_with_tapminiscript, HardwareWallet, UnsupportedReason},
|
||||
installer::{
|
||||
message::{self, Message},
|
||||
prompt,
|
||||
@ -614,9 +614,20 @@ pub fn hardware_wallet_xpubs<'a>(
|
||||
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)
|
||||
}
|
||||
UnsupportedReason::WrongNetwork => {
|
||||
hw::wrong_network_hardware_wallet(&kind.to_string(), version.as_ref())
|
||||
}
|
||||
_ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()),
|
||||
},
|
||||
HardwareWallet::Locked {
|
||||
kind, pairing_code, ..
|
||||
} => hw::locked_hardware_wallet(kind, pairing_code.as_ref()),
|
||||
@ -1745,9 +1756,20 @@ 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)
|
||||
}
|
||||
UnsupportedReason::WrongNetwork => {
|
||||
hw::wrong_network_hardware_wallet(&kind.to_string(), version.as_ref())
|
||||
}
|
||||
_ => hw::unsupported_hardware_wallet(&kind.to_string(), version.as_ref()),
|
||||
},
|
||||
HardwareWallet::Locked {
|
||||
kind, pairing_code, ..
|
||||
} => hw::locked_hardware_wallet(kind, pairing_code.as_ref()),
|
||||
|
||||
@ -14,7 +14,14 @@ pub fn locked_hardware_wallet<'a, T: 'a, K: Display>(
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text::p1_bold("Locked, check code:"))
|
||||
.push(text::p1_bold(format!(
|
||||
"Locked{}",
|
||||
if pairing_code.is_some() {
|
||||
", check code:"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
)))
|
||||
.push_maybe(pairing_code.map(|a| text::p1_bold(a)))
|
||||
.into(),
|
||||
Row::new()
|
||||
@ -277,6 +284,38 @@ pub fn registration_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn wrong_network_hardware_wallet<'a, T: 'a, K: Display, V: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text::p1_bold("Wrong network in the device settings"))
|
||||
.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)
|
||||
.into(),
|
||||
tooltip::Tooltip::new(
|
||||
icon::warning_icon(),
|
||||
"The wrong bitcoin application is open or the device was initialized with the wrong network",
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn unsupported_hardware_wallet<'a, T: 'a, K: Display, V: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user