Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 107 additions & 3 deletions keep-desktop/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ use crate::screen::shares::{ShareEntry, ShareListScreen};
use crate::screen::signing_audit::{AuditDisplayEntry, ChainStatus, SigningAuditScreen};
use crate::screen::unlock::UnlockScreen;
use crate::screen::wallet::{
DescriptorProgress, SetupPhase, SetupState, TierConfig, WalletEntry, WalletScreen,
AnnounceState, DescriptorProgress, SetupPhase, SetupState, TierConfig, WalletEntry,
WalletScreen,
};
use crate::screen::Screen;
use crate::theme;
use crate::tray::{TrayEvent, TrayState};
use keep_frost_net::{MAX_XPUB_LABEL_LENGTH, MAX_XPUB_LENGTH};

static PENDING_NOSTRCONNECT: OnceLock<Mutex<Option<NostrConnectRequest>>> = OnceLock::new();

Expand Down Expand Up @@ -157,6 +159,7 @@ pub struct App {
pub(crate) pin_mismatch_confirm: bool,
pub(crate) bunker_cert_pin_failed: bool,
pub(crate) active_coordinations: HashMap<[u8; 32], ActiveCoordination>,
pub(crate) peer_xpubs: HashMap<u16, Vec<keep_frost_net::AnnouncedXpub>>,
import_return_to_nsec: bool,
cached_share_count: usize,
cached_nsec_count: usize,
Expand Down Expand Up @@ -567,6 +570,7 @@ impl App {
tray_last_bunker: false,
scanner_rx: None,
active_coordinations: HashMap::new(),
peer_xpubs: HashMap::new(),
import_return_to_nsec: false,
cached_share_count: 0,
cached_nsec_count: 0,
Expand Down Expand Up @@ -709,7 +713,14 @@ impl App {
| Message::WalletBeginCoordination
| Message::WalletCancelSetup
| Message::WalletSessionStarted(..)
| Message::WalletDescriptorProgress(..) => self.handle_wallet_message(message),
| Message::WalletDescriptorProgress(..)
| Message::WalletStartAnnounce
| Message::WalletAnnounceXpubChanged(..)
| Message::WalletAnnounceFingerprintChanged(..)
| Message::WalletAnnounceLabelChanged(..)
| Message::WalletCancelAnnounce
| Message::WalletSubmitAnnounce
| Message::WalletAnnounceResult(..) => self.handle_wallet_message(message),

Message::RelayUrlChanged(..)
| Message::ConnectPasswordChanged(..)
Expand Down Expand Up @@ -951,7 +962,9 @@ impl App {
Message::WalletsLoaded(result) => {
match result {
Ok(entries) => {
self.screen = Screen::Wallet(WalletScreen::new(entries));
let mut ws = WalletScreen::new(entries);
ws.peer_xpubs = self.peer_xpubs.clone();
self.screen = Screen::Wallet(ws);
}
Err(e) => {
self.set_toast(e, ToastKind::Error);
Expand Down Expand Up @@ -1420,6 +1433,95 @@ impl App {
}
Task::none()
}
Message::WalletStartAnnounce => {
if let Screen::Wallet(s) = &mut self.screen {
s.announce = Some(AnnounceState {
xpub: String::new(),
fingerprint: String::new(),
label: String::new(),
error: None,
submitting: false,
});
}
Task::none()
}
Message::WalletAnnounceXpubChanged(v) => {
if let Some(a) = self.announce_state_mut() {
a.xpub = v.chars().take(MAX_XPUB_LENGTH).collect();
}
Task::none()
}
Message::WalletAnnounceFingerprintChanged(v) => {
if let Some(a) = self.announce_state_mut() {
a.fingerprint = v
.chars()
.filter(|c| c.is_ascii_hexdigit())
.take(8)
.collect();
}
Task::none()
}
Message::WalletAnnounceLabelChanged(v) => {
if let Some(a) = self.announce_state_mut() {
a.label = v.chars().take(MAX_XPUB_LABEL_LENGTH).collect();
}
Task::none()
}
Message::WalletCancelAnnounce => {
if let Screen::Wallet(s) = &mut self.screen {
s.announce = None;
}
Task::none()
}
Message::WalletSubmitAnnounce => {
let Some(a) = self.announce_state_mut() else {
return Task::none();
};
a.submitting = true;
a.error = None;
let xpub = a.xpub.trim().to_string();
let fingerprint = a.fingerprint.trim().to_string();
let label = a.label.trim().to_string();

let Some(node) = self.get_frost_node() else {
if let Some(a) = self.announce_state_mut() {
a.error = Some("Relay not connected".into());
a.submitting = false;
}
return Task::none();
};

let announced = keep_frost_net::AnnouncedXpub {
xpub,
fingerprint,
label: if label.is_empty() { None } else { Some(label) },
};

Task::perform(
async move {
node.announce_xpubs(vec![announced])
.await
.map_err(|e| format!("{e}"))
},
Message::WalletAnnounceResult,
)
}
Message::WalletAnnounceResult(result) => {
match result {
Ok(()) => {
if let Screen::Wallet(s) = &mut self.screen {
s.announce = None;
}
}
Err(e) => {
if let Some(a) = self.announce_state_mut() {
a.error = Some(e);
a.submitting = false;
}
}
}
Task::none()
}
_ => Task::none(),
}
}
Expand Down Expand Up @@ -1779,6 +1881,7 @@ impl App {
let clear_clipboard = self.clipboard_clear_at.take().is_some();
self.active_share_hex = None;
self.active_coordinations.clear();
self.peer_xpubs.clear();
self.identities.clear();
self.cached_share_count = 0;
self.cached_nsec_count = 0;
Expand Down Expand Up @@ -3372,6 +3475,7 @@ impl App {
tray_last_bunker: false,
scanner_rx: None,
active_coordinations: HashMap::new(),
peer_xpubs: HashMap::new(),
import_return_to_nsec: false,
cached_share_count: 0,
cached_nsec_count: 0,
Expand Down
22 changes: 22 additions & 0 deletions keep-desktop/src/frost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,16 @@ impl App {
self.frost_node.lock().ok()?.clone()
}

pub(crate) fn announce_state_mut(
&mut self,
) -> Option<&mut crate::screen::wallet::AnnounceState> {
if let Screen::Wallet(ws) = &mut self.screen {
ws.announce.as_mut()
} else {
None
}
}

pub(crate) fn update_wallet_setup(
&mut self,
session_id: &[u8; 32],
Expand Down Expand Up @@ -819,6 +829,18 @@ impl App {
count = recovery_xpubs.len(),
"Received recovery xpub announcement"
);
let entry = self.peer_xpubs.entry(share_index).or_default();
for xpub in recovery_xpubs {
if let Some(existing) = entry.iter_mut().find(|x| x.xpub == xpub.xpub) {
existing.fingerprint = xpub.fingerprint;
existing.label = xpub.label;
} else if entry.len() < keep_frost_net::MAX_RECOVERY_XPUBS {
entry.push(xpub);
}
}
if let Screen::Wallet(ws) = &mut self.screen {
ws.peer_xpubs = self.peer_xpubs.clone();
}
}
FrostNodeMsg::HealthCheckComplete {
responsive,
Expand Down
21 changes: 21 additions & 0 deletions keep-desktop/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ pub enum Message {
WalletCancelSetup,
WalletSessionStarted(Result<([u8; 32], [u8; 32], String, usize), String>),
WalletDescriptorProgress(DescriptorProgress, Option<[u8; 32]>),
WalletStartAnnounce,
WalletAnnounceXpubChanged(String),
WalletAnnounceFingerprintChanged(String),
WalletAnnounceLabelChanged(String),
WalletCancelAnnounce,
WalletSubmitAnnounce,
WalletAnnounceResult(Result<(), String>),
// Relay / FROST
RelayUrlChanged(String),
ConnectPasswordChanged(Zeroizing<String>),
Expand Down Expand Up @@ -527,6 +534,20 @@ impl fmt::Debug for Message {
.field(&r.as_ref().map(|_| "ok").map_err(|e| e.as_str()))
.finish(),
Self::WalletDescriptorProgress(..) => f.write_str("WalletDescriptorProgress"),
Self::WalletStartAnnounce => f.write_str("WalletStartAnnounce"),
Self::WalletAnnounceXpubChanged(_) => f.write_str("WalletAnnounceXpubChanged(***)"),
Self::WalletAnnounceFingerprintChanged(_) => {
f.write_str("WalletAnnounceFingerprintChanged(<redacted>)")
}
Self::WalletAnnounceLabelChanged(_) => {
f.write_str("WalletAnnounceLabelChanged(<redacted>)")
}
Self::WalletCancelAnnounce => f.write_str("WalletCancelAnnounce"),
Self::WalletSubmitAnnounce => f.write_str("WalletSubmitAnnounce"),
Self::WalletAnnounceResult(r) => f
.debug_tuple("WalletAnnounceResult")
.field(&r.as_ref().map(|_| "ok").map_err(|e| e.as_str()))
.finish(),
Self::RelayUrlChanged(u) => f.debug_tuple("RelayUrlChanged").field(u).finish(),
Self::ConnectPasswordChanged(_) => f.write_str("ConnectPasswordChanged(***)"),
Self::AddRelay => f.write_str("AddRelay"),
Expand Down
Loading