Merge #421: Add alias to hotsigner component
997829bdfe30a950ca40412fc1d273c2f1ca7e43 fix unregistered hardware wallet view (edouard)
53d32085147fe6f8c0094c26008314eddfcc3bd0 Add alias to hot signer (edouard)
Pull request description:
When a hot signer is suggested to user and an alias was entered then the alias must be displayed with the "This computer" label as signer kind.
ACKs for top commit:
edouardparis:
Self-ACK 997829bdfe30a950ca40412fc1d273c2f1ca7e43
Tree-SHA512: 68cd8f6ca8bdbd439f6392fddf4f34f1d8a1a8b312003f219e20519dabff43b95af496051eef857fed132f80b3b49ee5cd3034361f0af7fdfe9ef666b2c16c2e
This commit is contained in:
commit
e55432d2d6
@ -379,6 +379,10 @@ impl Action for SignAction {
|
||||
self.error.as_ref(),
|
||||
&self.hws,
|
||||
self.wallet.signer.as_ref().map(|s| s.fingerprint()),
|
||||
self.wallet
|
||||
.signer
|
||||
.as_ref()
|
||||
.and_then(|signer| self.wallet.keys_aliases.get(&signer.fingerprint)),
|
||||
self.processing,
|
||||
self.chosen_hw,
|
||||
&self.signed,
|
||||
|
||||
@ -17,6 +17,7 @@ pub fn hw_list_view(
|
||||
version,
|
||||
fingerprint,
|
||||
alias,
|
||||
registered,
|
||||
..
|
||||
} => {
|
||||
if chosen && processing {
|
||||
@ -28,6 +29,13 @@ pub fn hw_list_view(
|
||||
fingerprint,
|
||||
alias.as_ref(),
|
||||
)
|
||||
} else if *registered == Some(false) {
|
||||
hw::unregistered_hardware_wallet(
|
||||
kind,
|
||||
version.as_ref(),
|
||||
fingerprint,
|
||||
alias.as_ref(),
|
||||
)
|
||||
} else {
|
||||
hw::supported_hardware_wallet(kind, version.as_ref(), fingerprint, alias.as_ref())
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ use liana_ui::{
|
||||
component::{
|
||||
badge, button, card,
|
||||
collapse::Collapse,
|
||||
form, separation,
|
||||
form, hw, separation,
|
||||
text::{text, Text},
|
||||
},
|
||||
icon, theme,
|
||||
@ -710,6 +710,7 @@ pub fn sign_action<'a>(
|
||||
warning: Option<&Error>,
|
||||
hws: &'a [HardwareWallet],
|
||||
signer: Option<Fingerprint>,
|
||||
signer_alias: Option<&'a String>,
|
||||
processing: bool,
|
||||
chosen_hw: Option<usize>,
|
||||
signed: &[Fingerprint],
|
||||
@ -746,35 +747,11 @@ pub fn sign_action<'a>(
|
||||
},
|
||||
))
|
||||
.push_maybe(signer.map(|fingerprint| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(
|
||||
Column::new()
|
||||
.width(Length::Fill)
|
||||
.push(text("This computer").bold())
|
||||
.push(
|
||||
text(format!("fingerprint: {}", fingerprint))
|
||||
.small(),
|
||||
)
|
||||
.spacing(5)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(if signed.contains(&fingerprint) {
|
||||
Some(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.spacing(5)
|
||||
.push(
|
||||
icon::circle_check_icon()
|
||||
.style(color::legacy::SUCCESS),
|
||||
)
|
||||
.push(text("Signed").style(color::legacy::SUCCESS)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}),
|
||||
)
|
||||
Button::new(if signed.contains(&fingerprint) {
|
||||
hw::sign_success_hot_signer(fingerprint, signer_alias)
|
||||
} else {
|
||||
hw::hot_signer(fingerprint, signer_alias)
|
||||
})
|
||||
.on_press(Message::Spend(SpendTxMessage::SelectHotSigner))
|
||||
.padding(10)
|
||||
.style(theme::Button::Secondary)
|
||||
|
||||
@ -725,11 +725,9 @@ pub struct EditXpubModal {
|
||||
form_xpub: form::Value<String>,
|
||||
edit_name: bool,
|
||||
|
||||
chosen_hw: Option<usize>,
|
||||
hws: Vec<HardwareWallet>,
|
||||
|
||||
signer: Arc<Signer>,
|
||||
chosen_signer: bool,
|
||||
hot_signer: Arc<Signer>,
|
||||
chosen_signer: Option<Fingerprint>,
|
||||
}
|
||||
|
||||
impl EditXpubModal {
|
||||
@ -742,7 +740,7 @@ impl EditXpubModal {
|
||||
network: Network,
|
||||
account_indexes: HashMap<Fingerprint, ChildNumber>,
|
||||
keys_aliases: HashMap<Fingerprint, String>,
|
||||
signer: Arc<Signer>,
|
||||
hot_signer: Arc<Signer>,
|
||||
) -> Self {
|
||||
Self {
|
||||
form_name: form::Value {
|
||||
@ -757,14 +755,13 @@ impl EditXpubModal {
|
||||
account_indexes,
|
||||
path_index,
|
||||
key_index,
|
||||
chosen_hw: None,
|
||||
processing: false,
|
||||
hws: Vec::new(),
|
||||
error: None,
|
||||
network,
|
||||
edit_name: false,
|
||||
chosen_signer: Some(signer.fingerprint()) == key.map(|k| k.master_fingerprint()),
|
||||
signer,
|
||||
chosen_signer: key.map(|k| k.master_fingerprint()),
|
||||
hot_signer,
|
||||
}
|
||||
}
|
||||
fn load(&self) -> Command<Message> {
|
||||
@ -790,7 +787,7 @@ impl DescriptorEditModal for EditXpubModal {
|
||||
..
|
||||
}) = self.hws.get(i)
|
||||
{
|
||||
self.chosen_hw = Some(i);
|
||||
self.chosen_signer = Some(*fingerprint);
|
||||
self.processing = true;
|
||||
// If another account n exists, the key is retrieved for the account n+1
|
||||
let account_index = self
|
||||
@ -815,10 +812,7 @@ impl DescriptorEditModal for EditXpubModal {
|
||||
Message::ConnectedHardwareWallets(hws) => {
|
||||
self.hws = hws;
|
||||
if let Ok(key) = DescriptorPublicKey::from_str(&self.form_xpub.value) {
|
||||
self.chosen_hw = self
|
||||
.hws
|
||||
.iter()
|
||||
.position(|hw| hw.fingerprint() == Some(key.master_fingerprint()));
|
||||
self.chosen_signer = Some(key.master_fingerprint());
|
||||
}
|
||||
}
|
||||
Message::Reload => {
|
||||
@ -826,10 +820,9 @@ impl DescriptorEditModal for EditXpubModal {
|
||||
return self.load();
|
||||
}
|
||||
Message::UseHotSigner => {
|
||||
self.chosen_hw = None;
|
||||
self.chosen_signer = true;
|
||||
let fingerprint = self.hot_signer.fingerprint();
|
||||
self.chosen_signer = Some(fingerprint);
|
||||
self.form_xpub.valid = true;
|
||||
let fingerprint = self.signer.fingerprint();
|
||||
if let Some(alias) = self.keys_aliases.get(&fingerprint) {
|
||||
self.form_name.valid = true;
|
||||
self.form_name.value = alias.clone();
|
||||
@ -848,7 +841,7 @@ impl DescriptorEditModal for EditXpubModal {
|
||||
"[{}{}]{}",
|
||||
fingerprint,
|
||||
derivation_path.to_string().trim_start_matches('m'),
|
||||
self.signer.get_extended_pubkey(&derivation_path)
|
||||
self.hot_signer.get_extended_pubkey(&derivation_path)
|
||||
);
|
||||
}
|
||||
Message::DefineDescriptor(message::DefineDescriptor::KeyModal(msg)) => match msg {
|
||||
@ -863,12 +856,12 @@ impl DescriptorEditModal for EditXpubModal {
|
||||
} else {
|
||||
self.edit_name = true;
|
||||
}
|
||||
self.chosen_signer = false;
|
||||
self.chosen_signer = None;
|
||||
self.form_xpub.valid = true;
|
||||
self.form_xpub.value = key.to_string();
|
||||
}
|
||||
Err(e) => {
|
||||
self.chosen_hw = None;
|
||||
self.chosen_signer = None;
|
||||
self.error = Some(e);
|
||||
}
|
||||
}
|
||||
@ -944,8 +937,9 @@ impl DescriptorEditModal for EditXpubModal {
|
||||
&self.hws,
|
||||
self.error.as_ref(),
|
||||
self.processing,
|
||||
self.chosen_hw,
|
||||
self.chosen_signer,
|
||||
&self.hot_signer,
|
||||
self.keys_aliases.get(&self.hot_signer.fingerprint),
|
||||
&self.form_xpub,
|
||||
&self.form_name,
|
||||
self.edit_name,
|
||||
|
||||
@ -5,7 +5,7 @@ use iced::{alignment, Alignment, Length};
|
||||
|
||||
use std::{collections::HashSet, str::FromStr};
|
||||
|
||||
use liana::miniscript::bitcoin;
|
||||
use liana::miniscript::bitcoin::{self, util::bip32::Fingerprint};
|
||||
use liana_ui::{
|
||||
color,
|
||||
component::{
|
||||
@ -25,6 +25,7 @@ use crate::{
|
||||
message::{self, Message},
|
||||
prompt, Error,
|
||||
},
|
||||
signer::Signer,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@ -1236,8 +1237,9 @@ pub fn edit_key_modal<'a>(
|
||||
hws: &'a [HardwareWallet],
|
||||
error: Option<&Error>,
|
||||
processing: bool,
|
||||
chosen_hw: Option<usize>,
|
||||
chosen_signer: bool,
|
||||
chosen_signer: Option<Fingerprint>,
|
||||
signer: &Signer,
|
||||
signer_alias: Option<&'a String>,
|
||||
form_xpub: &form::Value<String>,
|
||||
form_name: &'a form::Value<String>,
|
||||
edit_name: bool,
|
||||
@ -1269,37 +1271,21 @@ pub fn edit_key_modal<'a>(
|
||||
col.push(hw_list_view(
|
||||
i,
|
||||
hw,
|
||||
Some(i) == chosen_hw,
|
||||
hw.fingerprint() == chosen_signer,
|
||||
processing,
|
||||
!processing
|
||||
&& Some(i) == chosen_hw
|
||||
&& hw.fingerprint() == chosen_signer
|
||||
&& form_xpub.valid
|
||||
&& !form_xpub.value.is_empty(),
|
||||
))
|
||||
},
|
||||
))
|
||||
.push(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.padding(5)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.push(
|
||||
Column::new()
|
||||
.spacing(5)
|
||||
.push(text("This computer").bold())
|
||||
.push(
|
||||
text("Derive a key from a mnemonic stored on this computer").small(),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(if chosen_signer {
|
||||
Some(icon::circle_check_icon().style(color::legacy::SUCCESS))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.spacing(10),
|
||||
)
|
||||
Button::new(if Some(signer.fingerprint) == chosen_signer {
|
||||
hw::selected_hot_signer(signer.fingerprint, signer_alias)
|
||||
} else {
|
||||
hw::unselected_hot_signer(signer.fingerprint, signer_alias)
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.on_press(Message::UseHotSigner)
|
||||
.style(theme::Button::Secondary),
|
||||
@ -1315,7 +1301,9 @@ pub fn edit_key_modal<'a>(
|
||||
.push(
|
||||
form::Form::new("Extended public key", form_xpub, |msg| {
|
||||
Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(message::ImportKeyModal::XPubEdited(msg)),
|
||||
message::DefineDescriptor::KeyModal(
|
||||
message::ImportKeyModal::XPubEdited(msg),
|
||||
),
|
||||
)
|
||||
})
|
||||
.warning(if network == bitcoin::Network::Bitcoin {
|
||||
@ -1349,9 +1337,9 @@ pub fn edit_key_modal<'a>(
|
||||
.push(text(&form_name.value)),
|
||||
)
|
||||
.push(button::border(Some(icon::pencil_icon()), "Edit").on_press(
|
||||
Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(message::ImportKeyModal::EditName),
|
||||
)
|
||||
Message::DefineDescriptor(message::DefineDescriptor::KeyModal(
|
||||
message::ImportKeyModal::EditName,
|
||||
)),
|
||||
)),
|
||||
)
|
||||
} else if !form_xpub.value.is_empty() && form_xpub.valid {
|
||||
@ -1365,9 +1353,9 @@ pub fn edit_key_modal<'a>(
|
||||
)
|
||||
.push(
|
||||
form::Form::new("Alias", form_name, |msg| {
|
||||
Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(message::ImportKeyModal::NameEdited(msg)),
|
||||
)
|
||||
Message::DefineDescriptor(message::DefineDescriptor::KeyModal(
|
||||
message::ImportKeyModal::NameEdited(msg),
|
||||
))
|
||||
})
|
||||
.warning("Please enter correct alias")
|
||||
.size(20)
|
||||
@ -1381,11 +1369,11 @@ pub fn edit_key_modal<'a>(
|
||||
if form_xpub.valid && !form_xpub.value.is_empty() && !form_name.value.is_empty()
|
||||
{
|
||||
button::primary(None, "Apply")
|
||||
.on_press(
|
||||
Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(message::ImportKeyModal::ConfirmXpub),
|
||||
)
|
||||
)
|
||||
.on_press(Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(
|
||||
message::ImportKeyModal::ConfirmXpub,
|
||||
),
|
||||
))
|
||||
.width(Length::Units(200))
|
||||
} else {
|
||||
button::primary(None, "Apply").width(Length::Units(100))
|
||||
|
||||
@ -15,7 +15,7 @@ use liana::{
|
||||
pub struct Signer {
|
||||
curve: secp256k1::Secp256k1<secp256k1::SignOnly>,
|
||||
key: HotSigner,
|
||||
fingerprint: Fingerprint,
|
||||
pub fingerprint: Fingerprint,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Signer {
|
||||
|
||||
@ -235,3 +235,109 @@ pub fn unsupported_hardware_wallet<'a, T: 'a, K: Display, V: Display>(
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn sign_success_hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push_maybe(alias.map(|a| text(a).bold()))
|
||||
.push(text(format!("#{}", fingerprint)))
|
||||
.into(),
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text("This computer").small())
|
||||
.into(),
|
||||
])
|
||||
.width(Length::Fill)
|
||||
.into(),
|
||||
row(vec![
|
||||
icon::circle_check_icon()
|
||||
.style(color::legacy::SUCCESS)
|
||||
.into(),
|
||||
text("Signed").style(color::legacy::SUCCESS).into(),
|
||||
])
|
||||
.align_items(Alignment::Center)
|
||||
.spacing(5)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn selected_hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push_maybe(alias.map(|a| text(a).bold()))
|
||||
.push(text(format!("#{}", fingerprint)))
|
||||
.into(),
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text("This computer").small())
|
||||
.push(text("(A derived key from a mnemonic stored locally)").small())
|
||||
.into(),
|
||||
])
|
||||
.width(Length::Fill)
|
||||
.into(),
|
||||
icon::circle_check_icon()
|
||||
.style(color::legacy::SUCCESS)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn unselected_hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
) -> Container<'a, T> {
|
||||
Container::new(
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push_maybe(alias.map(|a| text(a).bold()))
|
||||
.push(text(format!("#{}", fingerprint)))
|
||||
.into(),
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text("This computer").small())
|
||||
.push(text("(A derived key from a mnemonic stored locally)").small())
|
||||
.into(),
|
||||
])
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
) -> Container<'a, T> {
|
||||
Container::new(
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push_maybe(alias.map(|a| text(a).bold()))
|
||||
.push(text(format!("#{}", fingerprint)))
|
||||
.into(),
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text("This computer").small())
|
||||
.into(),
|
||||
])
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user