mirror of
https://code.gri.mw/GUI/grim.git
synced 2026-07-20 05:38:55 +00:00
Build 78: honest transport labels, request decline/cancel, NIP-05 on requests, full localization
Settings now says "Manual transaction" and the privacy row reads "Messages & lookups" opening a new Network privacy page that tells the truth: messages, names, price and avatars ride the Nym mixnet; the grin node connects directly. README and lander updated to match. Requests are messages, payments are final: declining a request now sends the requester a void control message (NIP-17), a requester can cancel a request they sent (cancels the local invoice and notifies the payer), and incoming requests resolve the sender's verified @username instead of a bare npub. The Requested amount on the success screen is centered. New NostrDecline/NostrCancel tasks and a goblin-action control message carry it, bound to the stored counterparty. Localization: every Goblin-screen string moved to t!() keys (370 keys) and translated into de/fr/ru/tr/zh-CN, guarded by a key/placeholder drift test. System-locale auto-detect now matches region locales like zh-CN.
This commit is contained in:
@@ -450,4 +450,12 @@ pub enum WalletTask {
|
||||
/// Republish our kind-0 profile (e.g. after toggling the incoming-requests
|
||||
/// preference) so the change propagates to relays immediately.
|
||||
NostrRepublishProfile,
|
||||
/// Decline an incoming payment request: mark it declined and send the
|
||||
/// requester a void control message so their side clears too.
|
||||
/// * request id (rumor event id hex)
|
||||
NostrDeclineRequest(String),
|
||||
/// Cancel a request WE sent: cancel the local invoice tx and send the payer a
|
||||
/// void control message so the pending card disappears on their side.
|
||||
/// * slate id (uuid string)
|
||||
NostrCancelOutgoing(String),
|
||||
}
|
||||
|
||||
@@ -2364,6 +2364,59 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
service.republish_identity().await;
|
||||
}
|
||||
}
|
||||
WalletTask::NostrDeclineRequest(rumor_id) => {
|
||||
let Some(service) = w.nostr_service() else {
|
||||
return;
|
||||
};
|
||||
let Some(mut request) = service.store.request(rumor_id) else {
|
||||
error!("nostr decline: request not found");
|
||||
return;
|
||||
};
|
||||
// Mark declined locally (idempotent) so the card stays gone, then tell
|
||||
// the requester. Requests are messages; payments are final.
|
||||
request.status = crate::nostr::RequestStatus::Declined;
|
||||
service.store.save_request(&request);
|
||||
if let Err(e) = service
|
||||
.send_control_dm(&request.npub, &request.slate_id, &[])
|
||||
.await
|
||||
{
|
||||
error!("nostr decline: control dispatch failed: {e}");
|
||||
}
|
||||
}
|
||||
WalletTask::NostrCancelOutgoing(slate_id) => {
|
||||
let Some(service) = w.nostr_service() else {
|
||||
return;
|
||||
};
|
||||
let Some(meta) = service.store.tx_meta(slate_id) else {
|
||||
error!("nostr cancel: no metadata for slate {slate_id}");
|
||||
return;
|
||||
};
|
||||
if meta.direction != crate::nostr::NostrTxDirection::RequestedByUs {
|
||||
error!("nostr cancel: slate {slate_id} is not an outgoing request");
|
||||
return;
|
||||
}
|
||||
// Cancel the underlying grin invoice tx (an issued invoice locks no
|
||||
// outputs, but cancelling keeps the wallet ledger tidy).
|
||||
if let Some(tx_id) = w.get_data().and_then(|d| d.txs).and_then(|txs| {
|
||||
txs.iter()
|
||||
.find(|t| {
|
||||
t.data.tx_slate_id.map(|u| u.to_string()).as_deref()
|
||||
== Some(slate_id.as_str())
|
||||
})
|
||||
.map(|t| t.data.id)
|
||||
}) {
|
||||
if let Err(e) = w.cancel(tx_id) {
|
||||
error!("nostr cancel: wallet cancel failed: {e}");
|
||||
}
|
||||
}
|
||||
service
|
||||
.store
|
||||
.update_tx_status(slate_id, crate::nostr::NostrSendStatus::Cancelled);
|
||||
if let Err(e) = service.send_control_dm(&meta.npub, slate_id, &[]).await {
|
||||
error!("nostr cancel: control dispatch failed: {e}");
|
||||
}
|
||||
sync_wallet_data(&w, false);
|
||||
}
|
||||
WalletTask::NostrResend(id) => {
|
||||
let Some(service) = w.nostr_service() else {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user