Merge #1623: gui(installer): show manually entered xpub in modal until saved

b9f19360ca81654da38cb00da1e6f69b2bc82a0c gui(installer): show manually entered xpub in modal until saved (Michael Mallan)

Pull request description:

  This fixes a regression introduced as part of the key-from-token work for cosigner and Safety Net keys.

  The manually entered xpub should continue to be displayed until the "Apply" button has been clicked and the changes saved.

  The `chosen_key_source_kind` field has been renamed to `form_key_source_kind` as it is only used to determine which of the xpub and token forms should be displayed. Its value is now only set to `Some` when the form for entering an xpub or token should be displayed. This change allows to distinguish between a manual xpub that has just been entered in the form and one that was previously entered and has been chosen from the list of existing keys.

ACKs for top commit:
  edouardparis:
    ACK b9f19360ca81654da38cb00da1e6f69b2bc82a0c

Tree-SHA512: 0e246a0113038c93f4ad0ece42a4bf1a414772f4cf1ad123dafe84d453d5249b81f485d3937c5373a0442f9dd2bf19f46cb55231dfae06c18987023ba13568a1
This commit is contained in:
edouardparis 2025-03-31 14:47:06 +02:00
commit 46ad749b78
No known key found for this signature in database
GPG Key ID: E65F7A089C20DC8F
2 changed files with 17 additions and 16 deletions

View File

@ -75,6 +75,8 @@ pub struct EditXpubModal {
// store `form_token_warning` directly in `form_token`.
form_token: form::Value<String>,
form_token_warning: Option<String>,
/// The `KeySourceKind` corresponding to the required form for entering a new key.
form_key_source_kind: Option<KeySourceKind>,
other_path_keys: HashSet<Fingerprint>,
duplicate_master_fg: bool,
@ -84,7 +86,6 @@ pub struct EditXpubModal {
hot_signer: Arc<Mutex<Signer>>,
hot_signer_fingerprint: Fingerprint,
chosen_signer: Option<Key>,
chosen_key_source_kind: Option<KeySourceKind>,
}
impl EditXpubModal {
@ -124,12 +125,12 @@ impl EditXpubModal {
.unwrap_or_default(),
},
form_token_warning: None,
form_key_source_kind: None, // no form will be shown until user clicks on required option
keys,
keys_coordinate,
processing: false,
error: None,
network,
chosen_key_source_kind: key.as_ref().map(|k| k.source.kind()),
chosen_signer: key,
hot_signer_fingerprint,
hot_signer,
@ -163,7 +164,7 @@ impl super::DescriptorEditModal for EditXpubModal {
}) = hws.list.get(i)
{
self.processing = true;
self.chosen_key_source_kind = Some(KeySourceKind::Device);
self.form_key_source_kind = None;
let device_version = version.clone();
let fingerprint = *fingerprint;
let device_kind = *kind;
@ -211,7 +212,7 @@ impl super::DescriptorEditModal for EditXpubModal {
return self.load();
}
Message::UseHotSigner => {
self.chosen_key_source_kind = Some(KeySourceKind::HotSigner);
self.form_key_source_kind = None;
let fingerprint = self.hot_signer.lock().unwrap().fingerprint();
let derivation_path = default_derivation_path(self.network);
let key_str = format!(
@ -250,7 +251,7 @@ impl super::DescriptorEditModal for EditXpubModal {
// If it is a provider key that has just been fetched, do some additional sanity checks.
if let Some(key_kind) = key.source.provider_key_kind() {
// We don't need to check key's status as redeemed keys are not returned.
self.form_token_warning = if self.chosen_key_source_kind
self.form_token_warning = if self.form_key_source_kind
!= Some(KeySourceKind::Token(key_kind))
{
Some("Wrong kind of token".to_string())
@ -295,12 +296,12 @@ impl super::DescriptorEditModal for EditXpubModal {
}
message::ImportKeyModal::ManuallyImportXpub => {
self.chosen_signer = None;
self.chosen_key_source_kind = Some(KeySourceKind::Manual);
self.form_key_source_kind = Some(KeySourceKind::Manual);
self.form_xpub = form::Value::default();
}
message::ImportKeyModal::UseToken(kind) => {
self.chosen_signer = None;
self.chosen_key_source_kind = Some(KeySourceKind::Token(kind));
self.form_key_source_kind = Some(KeySourceKind::Token(kind));
self.form_token = form::Value::default();
}
message::ImportKeyModal::NameEdited(name) => {
@ -323,8 +324,8 @@ impl super::DescriptorEditModal for EditXpubModal {
self.form_token.value = s;
}
message::ImportKeyModal::XPubEdited(s) => {
self.chosen_signer = None;
if let Ok(DescriptorPublicKey::XPub(key)) = DescriptorPublicKey::from_str(&s) {
self.chosen_signer = None;
if !key.derivation_path.is_master() {
self.form_xpub.valid = false;
} else if let Some((fingerprint, _)) = key.origin {
@ -403,7 +404,7 @@ impl super::DescriptorEditModal for EditXpubModal {
message::ImportKeyModal::SelectKey(i) => {
if let Some(key) = self.keys.get(i) {
self.chosen_signer = Some(key.clone());
self.chosen_key_source_kind = Some(key.source.kind());
self.form_key_source_kind = None;
self.form_name.value.clone_from(&key.name);
self.form_name.valid = true;
}
@ -497,7 +498,6 @@ impl super::DescriptorEditModal for EditXpubModal {
.collect(),
self.error.as_ref(),
self.chosen_signer.as_ref().map(|s| s.fingerprint),
self.chosen_key_source_kind.as_ref(),
&self.hot_signer_fingerprint,
self.keys.iter().find_map(|k| {
if k.fingerprint == self.hot_signer_fingerprint {
@ -510,6 +510,7 @@ impl super::DescriptorEditModal for EditXpubModal {
&self.form_xpub,
&self.form_token,
self.form_token_warning.as_ref(),
self.form_key_source_kind.as_ref(),
self.duplicate_master_fg,
)
}

View File

@ -261,7 +261,7 @@ pub fn undefined_key<'a>(
fn maybe_key_from_token<'a>(
path_kind: PathKind,
chosen_key_source_kind: Option<&KeySourceKind>,
form_key_source_kind: Option<&KeySourceKind>,
has_chosen_signer: bool,
form_token: &form::Value<String>,
form_token_warning: Option<&'a String>,
@ -271,7 +271,7 @@ fn maybe_key_from_token<'a>(
None
} else {
Some(
match (chosen_key_source_kind, has_chosen_signer) {
match (form_key_source_kind, has_chosen_signer) {
(Some(KeySourceKind::Token(key_kind)), false) => card::simple(
Column::new()
.spacing(10)
@ -343,13 +343,13 @@ pub fn edit_key_modal<'a>(
provider_keys: Vec<Element<'a, Message>>,
error: Option<&Error>,
chosen_signer: Option<Fingerprint>,
chosen_key_source_kind: Option<&KeySourceKind>,
hot_signer_fingerprint: &Fingerprint,
signer_alias: Option<&'a String>,
form_name: &'a form::Value<String>,
form_xpub: &form::Value<String>,
form_token: &form::Value<String>,
form_token_warning: Option<&'a String>,
form_key_source_kind: Option<&KeySourceKind>,
duplicate_master_fg: bool,
) -> Element<'a, Message> {
let content = Column::new()
@ -386,7 +386,7 @@ pub fn edit_key_modal<'a>(
)
.push_maybe(if !path_kind.can_choose_key_source_kind(&KeySourceKind::Manual) {
None
} else if chosen_key_source_kind == Some(&KeySourceKind::Manual) && chosen_signer.is_none() {
} else if form_key_source_kind == Some(&KeySourceKind::Manual) {
Some(card::simple(Column::new()
.spacing(10)
.push(
@ -433,8 +433,8 @@ pub fn edit_key_modal<'a>(
))
}
)
.push_maybe(maybe_key_from_token(path_kind, chosen_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::api::KeyKind::SafetyNet))
.push_maybe(maybe_key_from_token(path_kind, chosen_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::api::KeyKind::Cosigner))
.push_maybe(maybe_key_from_token(path_kind, form_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::api::KeyKind::SafetyNet))
.push_maybe(maybe_key_from_token(path_kind, form_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::api::KeyKind::Cosigner))
.width(Length::Fill),
)
.push_maybe(