installer: use appended path instead of account number for xpubs
This commit is contained in:
parent
6c969aeacd
commit
30ce2dea08
10
gui/Cargo.lock
generated
10
gui/Cargo.lock
generated
@ -133,9 +133,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-hwi"
|
||||
version = "0.0.9"
|
||||
version = "0.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85192c0f286ebcf3f154ea7220ac343a097aa327a0e748c001b685a0c7f05e4f"
|
||||
checksum = "22355924b351ed9bad0e8b400d0b039eb624259e80ad4afb978e04a35e81ea93"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.13.1",
|
||||
@ -1907,9 +1907,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ledger_bitcoin_client"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0a13c32d94c0313fa58f77f14f7aa425fddc6cd13aa375bde12f98740f0e6a"
|
||||
checksum = "53b3850bd03537874d58c09dcdd15cfab272b3e9d3381e57843b4f9e1c9ceae7"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bitcoin",
|
||||
@ -1919,7 +1919,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "liana"
|
||||
version = "1.0.0"
|
||||
source = "git+https://github.com/wizardsardine/liana?branch=master#ebea147c2fd6768a8fee9aea8255721e305d568d"
|
||||
source = "git+https://github.com/wizardsardine/liana?branch=master#6c969aeacdde28a84f0a04060b280343a1e22afe"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bip39",
|
||||
|
||||
@ -14,7 +14,7 @@ name = "liana-gui"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
async-hwi = "0.0.9"
|
||||
async-hwi = "0.0.10"
|
||||
liana = { git = "https://github.com/wizardsardine/liana", branch = "master", default-features = false }
|
||||
liana_ui = { path = "ui" }
|
||||
backtrace = "0.3"
|
||||
|
||||
@ -136,24 +136,28 @@ mod tests {
|
||||
amount: bitcoin::Amount::from_sat(1),
|
||||
block_height: Some(3),
|
||||
spend_info: None,
|
||||
is_immature: false,
|
||||
},
|
||||
Coin {
|
||||
outpoint: bitcoin::OutPoint { txid, vout: 3 },
|
||||
amount: bitcoin::Amount::from_sat(1),
|
||||
block_height: None,
|
||||
spend_info: None,
|
||||
is_immature: false,
|
||||
},
|
||||
Coin {
|
||||
outpoint: bitcoin::OutPoint { txid, vout: 0 },
|
||||
amount: bitcoin::Amount::from_sat(1),
|
||||
block_height: Some(2),
|
||||
spend_info: None,
|
||||
is_immature: false,
|
||||
},
|
||||
Coin {
|
||||
outpoint: bitcoin::OutPoint { txid, vout: 1 },
|
||||
amount: bitcoin::Amount::from_sat(1),
|
||||
block_height: Some(3),
|
||||
spend_info: None,
|
||||
is_immature: false,
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -197,7 +198,7 @@ impl From<RecoveryPanel> for Box<dyn State> {
|
||||
pub struct RecoveryPath {
|
||||
threshold: usize,
|
||||
sequence: u16,
|
||||
origins: Vec<(Fingerprint, DerivationPath)>,
|
||||
origins: Vec<(Fingerprint, HashSet<DerivationPath>)>,
|
||||
total_amount: Amount,
|
||||
number_of_coins: usize,
|
||||
}
|
||||
|
||||
@ -309,19 +309,19 @@ pub fn signatures<'a>(
|
||||
sigs.signed_pubkeys
|
||||
.keys()
|
||||
.fold(Row::new().spacing(5), |row, value| {
|
||||
row.push(if let Some(alias) = keys_aliases.get(&value.0) {
|
||||
row.push(if let Some(alias) = keys_aliases.get(value) {
|
||||
Container::new(
|
||||
tooltip::Tooltip::new(
|
||||
Container::new(text(alias))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
value.0.to_string(),
|
||||
value.to_string(),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(value.0.to_string()))
|
||||
Container::new(text(value.to_string()))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple))
|
||||
})
|
||||
@ -401,14 +401,14 @@ pub fn path_view<'a>(
|
||||
sigs: &'a PathSpendInfo,
|
||||
key_aliases: &'a HashMap<Fingerprint, String>,
|
||||
) -> Element<'a, Message> {
|
||||
let mut keys: Vec<(Fingerprint, DerivationPath)> =
|
||||
let mut keys: Vec<(Fingerprint, HashSet<DerivationPath>)> =
|
||||
path.thresh_origins().1.into_iter().collect();
|
||||
let missing_signatures = if sigs.sigs_count >= sigs.threshold {
|
||||
0
|
||||
} else {
|
||||
sigs.threshold - sigs.sigs_count
|
||||
};
|
||||
keys.sort();
|
||||
keys.sort_by_key(|a| a.0);
|
||||
scrollable(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
@ -439,7 +439,7 @@ pub fn path_view<'a>(
|
||||
None
|
||||
} else {
|
||||
Some(keys.iter().fold(Row::new().spacing(5), |row, value| {
|
||||
row.push_maybe(if !sigs.signed_pubkeys.contains_key(value) {
|
||||
row.push_maybe(if !sigs.signed_pubkeys.contains_key(&value.0) {
|
||||
Some(if let Some(alias) = key_aliases.get(&value.0) {
|
||||
Container::new(
|
||||
tooltip::Tooltip::new(
|
||||
@ -470,19 +470,19 @@ pub fn path_view<'a>(
|
||||
sigs.signed_pubkeys
|
||||
.keys()
|
||||
.fold(Row::new().spacing(5), |row, value| {
|
||||
row.push(if let Some(alias) = key_aliases.get(&value.0) {
|
||||
row.push(if let Some(alias) = key_aliases.get(value) {
|
||||
Container::new(
|
||||
tooltip::Tooltip::new(
|
||||
Container::new(text(alias))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
value.0.to_string(),
|
||||
value.to_string(),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(value.0.to_string()))
|
||||
Container::new(text(value.to_string()))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple))
|
||||
})
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use iced::{
|
||||
widget::{checkbox, tooltip, Space},
|
||||
@ -137,7 +137,7 @@ pub fn recovery<'a>(
|
||||
pub fn recovery_path_view<'a>(
|
||||
index: usize,
|
||||
threshold: usize,
|
||||
origins: &'a [(Fingerprint, DerivationPath)],
|
||||
origins: &'a [(Fingerprint, HashSet<DerivationPath>)],
|
||||
total_amount: Amount,
|
||||
number_of_coins: usize,
|
||||
key_aliases: &'a HashMap<Fingerprint, String>,
|
||||
|
||||
@ -106,12 +106,12 @@ impl SpendTx {
|
||||
|
||||
pub fn signers(&self) -> HashSet<Fingerprint> {
|
||||
let mut signers = HashSet::new();
|
||||
for (fg, _) in self.sigs.primary_path().signed_pubkeys.keys() {
|
||||
for fg in self.sigs.primary_path().signed_pubkeys.keys() {
|
||||
signers.insert(*fg);
|
||||
}
|
||||
|
||||
for path in self.sigs.recovery_paths().values() {
|
||||
for (fg, _) in path.signed_pubkeys.keys() {
|
||||
for fg in path.signed_pubkeys.keys() {
|
||||
signers.insert(*fg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,12 +230,10 @@ fn ledger_version_supported(version: Option<&Version>) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn list_unregistered_hardware_wallets(
|
||||
aliases: Option<&HashMap<Fingerprint, String>>,
|
||||
) -> Vec<HardwareWallet> {
|
||||
pub async fn list_unregistered_hardware_wallets() -> Vec<HardwareWallet> {
|
||||
let mut hws: Vec<HardwareWallet> = Vec::new();
|
||||
match specter::SpecterSimulator::try_connect().await {
|
||||
Ok(device) => match HardwareWallet::new(Arc::new(device), aliases).await {
|
||||
Ok(device) => match HardwareWallet::new(Arc::new(device), None).await {
|
||||
Ok(hw) => hws.push(hw),
|
||||
Err(e) => {
|
||||
debug!("{}", e);
|
||||
@ -249,7 +247,7 @@ pub async fn list_unregistered_hardware_wallets(
|
||||
match specter::Specter::enumerate().await {
|
||||
Ok(devices) => {
|
||||
for device in devices {
|
||||
match HardwareWallet::new(Arc::new(device), aliases).await {
|
||||
match HardwareWallet::new(Arc::new(device), None).await {
|
||||
Ok(hw) => hws.push(hw),
|
||||
Err(e) => {
|
||||
debug!("{}", e);
|
||||
@ -270,7 +268,7 @@ pub async fn list_unregistered_hardware_wallets(
|
||||
device: Arc::new(device),
|
||||
version,
|
||||
registered: None,
|
||||
alias: aliases.and_then(|aliases| aliases.get(&fingerprint).cloned()),
|
||||
alias: None,
|
||||
});
|
||||
} else {
|
||||
hws.push(HardwareWallet::Unsupported {
|
||||
@ -310,8 +308,7 @@ pub async fn list_unregistered_hardware_wallets(
|
||||
device: Arc::new(device),
|
||||
version,
|
||||
registered: None,
|
||||
alias: aliases
|
||||
.and_then(|aliases| aliases.get(&fingerprint).cloned()),
|
||||
alias: None,
|
||||
});
|
||||
} else {
|
||||
hws.push(HardwareWallet::Unsupported {
|
||||
|
||||
@ -78,6 +78,7 @@ pub enum ImportKeyModal {
|
||||
EditName,
|
||||
NameEdited(String),
|
||||
ConfirmXpub,
|
||||
SelectKey(usize),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@ use iced::widget::{
|
||||
};
|
||||
use iced::{alignment, Alignment, Length};
|
||||
|
||||
use async_hwi::DeviceKind;
|
||||
use std::{collections::HashSet, str::FromStr};
|
||||
|
||||
use liana::miniscript::bitcoin::{self, bip32::Fingerprint};
|
||||
@ -1139,12 +1140,10 @@ pub fn undefined_descriptor_key<'a>() -> Element<'a, message::DefineKey> {
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn defined_descriptor_key(
|
||||
name: &str,
|
||||
valid: bool,
|
||||
duplicate_key: bool,
|
||||
pub fn defined_descriptor_key<'a>(
|
||||
name: String,
|
||||
duplicate_name: bool,
|
||||
) -> Element<message::DefineKey> {
|
||||
) -> Element<'a, message::DefineKey> {
|
||||
let col = Column::new()
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
@ -1182,33 +1181,7 @@ pub fn defined_descriptor_key(
|
||||
)
|
||||
.push(Space::with_height(Length::Fixed(5.0)));
|
||||
|
||||
if !valid {
|
||||
Column::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(
|
||||
card::invalid(col)
|
||||
.padding(5)
|
||||
.height(Length::Fixed(150.0))
|
||||
.width(Length::Fixed(150.0)),
|
||||
)
|
||||
.push(
|
||||
text("Key is for a different network")
|
||||
.small()
|
||||
.style(color::RED),
|
||||
)
|
||||
.into()
|
||||
} else if duplicate_key {
|
||||
Column::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(
|
||||
card::invalid(col)
|
||||
.padding(5)
|
||||
.height(Length::Fixed(150.0))
|
||||
.width(Length::Fixed(150.0)),
|
||||
)
|
||||
.push(text("Duplicate key").small().style(color::RED))
|
||||
.into()
|
||||
} else if duplicate_name {
|
||||
if duplicate_name {
|
||||
Column::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(
|
||||
@ -1231,9 +1204,9 @@ pub fn defined_descriptor_key(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn edit_key_modal<'a>(
|
||||
network: bitcoin::Network,
|
||||
hws: &'a [HardwareWallet],
|
||||
hws: Vec<Element<'a, Message>>,
|
||||
keys: Vec<Element<'a, Message>>,
|
||||
error: Option<&Error>,
|
||||
processing: bool,
|
||||
chosen_signer: Option<Fingerprint>,
|
||||
hot_signer_fingerprint: &Fingerprint,
|
||||
signer_alias: Option<&'a String>,
|
||||
@ -1262,21 +1235,12 @@ pub fn edit_key_modal<'a>(
|
||||
),
|
||||
)
|
||||
.spacing(10)
|
||||
.push(hws.iter().enumerate().fold(
|
||||
Column::new().spacing(10),
|
||||
|col, (i, hw)| {
|
||||
col.push(hw_list_view(
|
||||
i,
|
||||
hw,
|
||||
hw.fingerprint() == chosen_signer,
|
||||
processing,
|
||||
!processing
|
||||
&& hw.fingerprint() == chosen_signer
|
||||
&& form_xpub.valid
|
||||
&& !form_xpub.value.is_empty(),
|
||||
))
|
||||
},
|
||||
))
|
||||
.push(
|
||||
Column::with_children(hws).spacing(10)
|
||||
)
|
||||
.push(
|
||||
Column::with_children(keys).spacing(10)
|
||||
)
|
||||
.push(
|
||||
Button::new(if Some(*hot_signer_fingerprint) == chosen_signer {
|
||||
hw::selected_hot_signer(hot_signer_fingerprint, signer_alias)
|
||||
@ -1312,7 +1276,6 @@ pub fn edit_key_modal<'a>(
|
||||
.padding(10),
|
||||
)
|
||||
.spacing(10)
|
||||
.push(Container::new(text("/<0;1>/*")).padding(5)),
|
||||
),
|
||||
)
|
||||
.push(
|
||||
@ -1475,7 +1438,7 @@ pub fn edit_sequence_modal<'a>(sequence: &form::Value<String>) -> Element<'a, Me
|
||||
.into()
|
||||
}
|
||||
|
||||
fn hw_list_view(
|
||||
pub fn hw_list_view(
|
||||
i: usize,
|
||||
hw: &HardwareWallet,
|
||||
chosen: bool,
|
||||
@ -1513,6 +1476,39 @@ fn hw_list_view(
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn key_list_view<'a>(
|
||||
i: usize,
|
||||
name: &'a str,
|
||||
fingerprint: &'a Fingerprint,
|
||||
kind: Option<&'a DeviceKind>,
|
||||
chosen: bool,
|
||||
) -> Element<'a, Message> {
|
||||
let bttn = Button::new(if chosen {
|
||||
hw::selected_hardware_wallet(
|
||||
kind.map(|k| k.to_string()).unwrap_or_else(String::new),
|
||||
None::<String>,
|
||||
fingerprint,
|
||||
Some(name),
|
||||
)
|
||||
} else {
|
||||
hw::supported_hardware_wallet(
|
||||
kind.map(|k| k.to_string()).unwrap_or_else(String::new),
|
||||
None::<String>,
|
||||
fingerprint,
|
||||
Some(name),
|
||||
)
|
||||
})
|
||||
.style(theme::Button::Border)
|
||||
.width(Length::Fill)
|
||||
.on_press(Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(message::ImportKeyModal::SelectKey(i)),
|
||||
));
|
||||
Container::new(bttn)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn backup_mnemonic<'a>(
|
||||
progress: (usize, usize),
|
||||
words: &'a [&'static str; 12],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user