goblin: bounce an approved pay request that races the wallet lock
WalletTask::NostrPayRequest ran nostr_pay/nostr_receive with no lock check, so an Approve tapped just before locking could spend or receive seconds later while the wallet was locked. Guard the task entry: when locked, the request is left Pending in the store (still approvable after unlock) and fail_send() flips the send phase to FAILED, which the activity card already consumes — the spinner clears and the reason line explains the bounce. Adds goblin.lock.approve_locked to all 10 locales. (cherry picked from commit ee47343259f12314932976c193739a2e0e96521d)
This commit is contained in:
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "Zahlungen kommen auch im gesperrten Zustand weiter an. Gib dein Passwort ein, um zu entsperren und dein Guthaben zu nutzen."
|
||||
unlock: "Entsperren"
|
||||
close_wallet: "Wallet schließen"
|
||||
approve_locked: "Die Wallet wurde gesperrt, bevor dies bezahlt werden konnte. Es ist weiter ausstehend — genehmige es erneut."
|
||||
trusted_sites:
|
||||
title: "Vertrauenswürdige Seiten"
|
||||
intro: "Seiten, denen du in dieser Sitzung vertraut hast, können risikoarme Aktionen ohne Nachfrage signieren. Bei Geld wird immer gefragt. Beende jede Sitzung hier."
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "Payments keep arriving while locked. Enter your password to unlock and use your funds."
|
||||
unlock: "Unlock"
|
||||
close_wallet: "Close wallet"
|
||||
approve_locked: "The wallet was locked before this could be paid. It's still pending — approve it again."
|
||||
trusted_sites:
|
||||
title: "Trusted Sites"
|
||||
intro: "Sites you trusted this session can sign low-risk actions without asking. Money always asks. End any session here."
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "Los pagos siguen llegando mientras está bloqueada. Ingresa tu contraseña para desbloquear y usar tus fondos."
|
||||
unlock: "Desbloquear"
|
||||
close_wallet: "Cerrar billetera"
|
||||
approve_locked: "La billetera se bloqueó antes de que esto pudiera pagarse. Sigue pendiente — apruébalo de nuevo."
|
||||
trusted_sites:
|
||||
title: "Sitios de confianza"
|
||||
intro: "Los sitios en los que confiaste esta sesión pueden firmar acciones de bajo riesgo sin preguntar. El dinero siempre pregunta. Termina cualquier sesión aquí."
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "Les paiements continuent d'arriver pendant le verrouillage. Saisissez votre mot de passe pour déverrouiller et utiliser vos fonds."
|
||||
unlock: "Déverrouiller"
|
||||
close_wallet: "Fermer le portefeuille"
|
||||
approve_locked: "Le portefeuille a été verrouillé avant que ce paiement puisse être effectué. Il est toujours en attente — approuvez-le à nouveau."
|
||||
trusted_sites:
|
||||
title: "Sites de confiance"
|
||||
intro: "Les sites auxquels vous avez fait confiance cette session peuvent signer des actions à faible risque sans demander. L'argent demande toujours. Terminez toute session ici."
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "ロック中も支払いは届き続けます。パスワードを入力してロックを解除し、残高を使えるようにします。"
|
||||
unlock: "ロック解除"
|
||||
close_wallet: "ウォレットを閉じる"
|
||||
approve_locked: "支払いが完了する前にウォレットがロックされました。リクエストは保留中のままです — もう一度承認してください。"
|
||||
trusted_sites:
|
||||
title: "信頼済みサイト"
|
||||
intro: "このセッションで信頼したサイトは、リスクの低い操作を確認なしで署名できます。お金が動く操作は必ず確認します。ここでいつでもセッションを終了できます。"
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "잠긴 동안에도 결제는 계속 도착합니다. 비밀번호를 입력해 잠금을 풀고 자금을 사용하세요."
|
||||
unlock: "잠금 해제"
|
||||
close_wallet: "지갑 닫기"
|
||||
approve_locked: "결제가 완료되기 전에 지갑이 잠겼습니다. 요청은 아직 대기 중입니다 — 다시 승인하세요."
|
||||
trusted_sites:
|
||||
title: "신뢰하는 사이트"
|
||||
intro: "이번 세션에 신뢰한 사이트는 확인 없이 위험도가 낮은 작업에 서명할 수 있습니다. 돈이 오갈 때는 항상 확인합니다. 여기에서 언제든 세션을 종료할 수 있습니다."
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "Платежи продолжают поступать, пока кошелёк заблокирован. Введите пароль, чтобы разблокировать и распоряжаться средствами."
|
||||
unlock: "Разблокировать"
|
||||
close_wallet: "Закрыть кошелёк"
|
||||
approve_locked: "Кошелёк был заблокирован до того, как платёж прошёл. Запрос всё ещё ожидает — подтвердите его снова."
|
||||
trusted_sites:
|
||||
title: "Доверенные сайты"
|
||||
intro: "Сайты, которым вы доверились в этой сессии, могут подписывать действия с низким риском без запроса. Деньги всегда запрашивают подтверждение. Завершите любую сессию здесь."
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "Kilitliyken ödemeler gelmeye devam eder. Kilidi açıp bakiyeni kullanmak için parolanı gir."
|
||||
unlock: "Kilidi aç"
|
||||
close_wallet: "Cüzdanı kapat"
|
||||
approve_locked: "Ödeme yapılamadan cüzdan kilitlendi. İstek hâlâ beklemede — yeniden onayla."
|
||||
trusted_sites:
|
||||
title: "Güvenilen Siteler"
|
||||
intro: "Bu oturumda güvendiğiniz siteler, düşük riskli eylemleri sormadan imzalayabilir. Para her zaman sorar. Herhangi bir oturumu buradan sonlandırın."
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "锁定期间付款仍会到账。输入密码即可解锁并使用资金。"
|
||||
unlock: "解锁"
|
||||
close_wallet: "关闭钱包"
|
||||
approve_locked: "付款完成前钱包已被锁定。请求仍在等待中——请重新批准。"
|
||||
trusted_sites:
|
||||
title: "受信任网站"
|
||||
intro: "本次会话中你信任的网站可在不询问的情况下签署低风险操作。资金操作始终询问。可在此结束任意会话。"
|
||||
|
||||
@@ -775,6 +775,7 @@ goblin:
|
||||
subtitle: "鎖定期間付款仍會到帳。輸入密碼即可解鎖並使用資金。"
|
||||
unlock: "解鎖"
|
||||
close_wallet: "關閉錢包"
|
||||
approve_locked: "付款完成前錢包已被鎖定。請求仍在等待中——請重新批准。"
|
||||
trusted_sites:
|
||||
title: "受信任網站"
|
||||
intro: "本次會話中你信任的網站可在不詢問的情況下籤署低風險操作。資金操作始終詢問。可在此結束任意會話。"
|
||||
|
||||
@@ -3542,6 +3542,16 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
error!("nostr pay: request is not pending");
|
||||
return;
|
||||
}
|
||||
// Money-path lock guard: an Approve tapped just before (or racing) a
|
||||
// lock must not spend or receive while locked. Bounce it the way the
|
||||
// ingest gate defers — the request stays Pending in the store (still
|
||||
// approvable after unlock) and the FAILED phase un-greys the card and
|
||||
// surfaces why, instead of half-executing a seed operation.
|
||||
if w.is_locked() {
|
||||
info!("nostr pay: wallet locked, bouncing request back to pending");
|
||||
service.fail_send(t!("goblin.lock.approve_locked"));
|
||||
return;
|
||||
}
|
||||
// Drive the approve button's busy/failed state so it doesn't stay
|
||||
// greyed forever if the pay can't go through.
|
||||
service.set_send_phase(crate::nostr::send_phase::WORKING);
|
||||
|
||||
Reference in New Issue
Block a user