wallet settings: edit fingerprint aliases
This commit is contained in:
parent
ae8df0dd4c
commit
f5394bf889
@ -13,15 +13,18 @@ use crate::{
|
||||
},
|
||||
daemon::Daemon,
|
||||
hw::{list_hardware_wallets, HardwareWallet, HardwareWalletConfig},
|
||||
ui::component::modal,
|
||||
ui::component::{form, modal},
|
||||
};
|
||||
|
||||
pub struct WalletSettingsState {
|
||||
data_dir: PathBuf,
|
||||
warning: Option<Error>,
|
||||
descriptor: String,
|
||||
keys_aliases: Vec<(Fingerprint, form::Value<String>)>,
|
||||
wallet: Arc<Wallet>,
|
||||
modal: Option<RegisterWalletModal>,
|
||||
processing: bool,
|
||||
updated: bool,
|
||||
}
|
||||
|
||||
impl WalletSettingsState {
|
||||
@ -29,17 +32,52 @@ impl WalletSettingsState {
|
||||
WalletSettingsState {
|
||||
data_dir,
|
||||
descriptor: wallet.main_descriptor.to_string(),
|
||||
keys_aliases: Self::keys_aliases(&wallet),
|
||||
wallet,
|
||||
warning: None,
|
||||
modal: None,
|
||||
processing: false,
|
||||
updated: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn keys_aliases(wallet: &Wallet) -> Vec<(Fingerprint, form::Value<String>)> {
|
||||
let mut keys_aliases: Vec<(Fingerprint, form::Value<String>)> = wallet
|
||||
.keys_aliases
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|(fg, name)| {
|
||||
(
|
||||
fg,
|
||||
form::Value {
|
||||
value: name,
|
||||
valid: true,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
for fingerprint in wallet.descriptor_keys().into_iter() {
|
||||
if wallet.keys_aliases.get(&fingerprint).is_none() {
|
||||
keys_aliases.push((fingerprint, form::Value::default()));
|
||||
}
|
||||
}
|
||||
|
||||
keys_aliases.sort_by(|(fg1, _), (fg2, _)| fg1.cmp(fg2));
|
||||
keys_aliases
|
||||
}
|
||||
}
|
||||
|
||||
impl State for WalletSettingsState {
|
||||
fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> {
|
||||
let content =
|
||||
view::settings::wallet_settings(cache, self.warning.as_ref(), &self.descriptor);
|
||||
let content = view::settings::wallet_settings(
|
||||
cache,
|
||||
self.warning.as_ref(),
|
||||
&self.descriptor,
|
||||
&self.keys_aliases,
|
||||
self.processing,
|
||||
self.updated,
|
||||
);
|
||||
if let Some(m) = &self.modal {
|
||||
modal::Modal::new(content, m.view())
|
||||
.on_blur(Some(view::Message::Close))
|
||||
@ -56,18 +94,60 @@ impl State for WalletSettingsState {
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
match message {
|
||||
Message::Updated(res) => match res {
|
||||
Ok(()) => {
|
||||
self.processing = false;
|
||||
self.updated = true;
|
||||
Command::perform(async {}, |_| Message::LoadWallet)
|
||||
}
|
||||
Err(e) => {
|
||||
self.processing = false;
|
||||
self.warning = Some(e);
|
||||
Command::none()
|
||||
}
|
||||
},
|
||||
Message::WalletLoaded(res) => {
|
||||
match res {
|
||||
Ok(wallet) => {
|
||||
if let Some(modal) = &mut self.modal {
|
||||
modal.wallet = wallet.clone();
|
||||
}
|
||||
self.keys_aliases = Self::keys_aliases(&wallet);
|
||||
self.wallet = wallet;
|
||||
}
|
||||
Err(e) => self.warning = Some(e),
|
||||
};
|
||||
Command::none()
|
||||
}
|
||||
Message::View(view::Message::Settings(
|
||||
view::SettingsMessage::FingerprintAliasEdited(fg, value),
|
||||
)) => {
|
||||
if let Some((_, name)) = self
|
||||
.keys_aliases
|
||||
.iter_mut()
|
||||
.find(|(fingerprint, _)| fg == *fingerprint)
|
||||
{
|
||||
name.value = value;
|
||||
}
|
||||
Command::none()
|
||||
}
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::Save)) => {
|
||||
self.modal = None;
|
||||
self.processing = true;
|
||||
self.updated = false;
|
||||
Command::perform(
|
||||
update_keys_aliases(
|
||||
self.data_dir.clone(),
|
||||
cache.network,
|
||||
self.wallet.clone(),
|
||||
self.keys_aliases
|
||||
.iter()
|
||||
.map(|(fg, name)| (*fg, name.value.to_owned()))
|
||||
.collect(),
|
||||
),
|
||||
Message::Updated,
|
||||
)
|
||||
}
|
||||
Message::View(view::Message::Close) => {
|
||||
self.modal = None;
|
||||
Command::none()
|
||||
@ -249,6 +329,33 @@ async fn register_wallet(
|
||||
Ok(fingerprint)
|
||||
}
|
||||
|
||||
async fn update_keys_aliases(
|
||||
data_dir: PathBuf,
|
||||
network: Network,
|
||||
wallet: Arc<Wallet>,
|
||||
keys_aliases: Vec<(Fingerprint, String)>,
|
||||
) -> Result<(), Error> {
|
||||
let mut settings = settings::Settings::from_file(data_dir.clone(), network)?;
|
||||
let checksum = wallet.descriptor_checksum();
|
||||
if let Some(wallet_setting) = settings
|
||||
.wallets
|
||||
.iter_mut()
|
||||
.find(|w| w.descriptor_checksum == checksum)
|
||||
{
|
||||
wallet_setting.keys = keys_aliases
|
||||
.into_iter()
|
||||
.map(|(master_fingerprint, name)| settings::KeySetting {
|
||||
master_fingerprint,
|
||||
name,
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
settings.to_file(data_dir, network)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn list_hws(wallet: Arc<Wallet>) -> Vec<HardwareWallet> {
|
||||
list_hardware_wallets(
|
||||
&wallet.hardware_wallets,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::app::menu::Menu;
|
||||
use liana::miniscript::bitcoin::util::bip32::Fingerprint;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
@ -53,6 +54,8 @@ pub enum SettingsMessage {
|
||||
EditWalletSettings,
|
||||
AboutSection,
|
||||
RegisterWallet,
|
||||
FingerprintAliasEdited(Fingerprint, String),
|
||||
Save,
|
||||
Edit(usize, SettingsEditMessage),
|
||||
}
|
||||
|
||||
|
||||
@ -523,6 +523,9 @@ pub fn wallet_settings<'a>(
|
||||
cache: &'a Cache,
|
||||
warning: Option<&Error>,
|
||||
descriptor: &'a str,
|
||||
keys_aliases: &[(Fingerprint, form::Value<String>)],
|
||||
processing: bool,
|
||||
updated: bool,
|
||||
) -> Element<'a, Message> {
|
||||
dashboard(
|
||||
&Menu::Settings,
|
||||
@ -548,7 +551,7 @@ pub fn wallet_settings<'a>(
|
||||
)
|
||||
.push(card::simple(
|
||||
Column::new()
|
||||
.push(text("Wallet descriptor:").small().bold())
|
||||
.push(text("Wallet descriptor:").bold())
|
||||
.push(text(descriptor.to_owned()).small())
|
||||
.push(
|
||||
Row::new()
|
||||
@ -567,6 +570,54 @@ pub fn wallet_settings<'a>(
|
||||
),
|
||||
)
|
||||
.spacing(10),
|
||||
))
|
||||
.push(card::simple(
|
||||
Column::new()
|
||||
.push(text("Fingerprint aliases:").bold())
|
||||
.push(keys_aliases.iter().fold(
|
||||
Column::new().spacing(10),
|
||||
|col, (fingerprint, name)| {
|
||||
let fg = *fingerprint;
|
||||
col.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(text(fg.to_string()).bold().width(Length::Units(100)))
|
||||
.push(
|
||||
form::Form::new("Alias", name, move |msg| {
|
||||
Message::Settings(
|
||||
SettingsMessage::FingerprintAliasEdited(fg, msg),
|
||||
)
|
||||
})
|
||||
.warning("Please enter correct alias")
|
||||
.size(20)
|
||||
.padding(10),
|
||||
),
|
||||
)
|
||||
},
|
||||
))
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push_maybe(if updated {
|
||||
Some(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::SUCCESS))
|
||||
.push(text("Updated").style(color::SUCCESS)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.push(if !processing {
|
||||
button::primary(None, "Update")
|
||||
.on_press(Message::Settings(SettingsMessage::Save))
|
||||
} else {
|
||||
button::primary(None, "Updating")
|
||||
}),
|
||||
)
|
||||
.spacing(10),
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user