Wallet audit: warn about at-risk balance before removing a mint (1.2.39)
Audited the wallet surface (real money: Cashu proofs, Lightning, NWC).
Most of it is solid — the Cashu singleton init with browser-CORS mint
probing/auto-heal, the send/receive token flows, the Lightning receive
path (double-tap guard + redeemed-quote listener cleanup + actionable
CORS errors), and the melt-based send all check out and match the zap
path.
One real money-loss gap: removing a mint calls
mintRepository.deleteMint(), which drops that mint's proofs from the
device — so removing a mint you still hold sats in strands those funds.
There are two remove-mint dialogs and they disagreed:
• MintPrivacyManager already warned with the concrete at-risk balance.
• CashuWallet's dialog showed only a generic static "make sure you've
withdrawn funds" line — no balance, no escalation — so a user could
delete a mint holding sats with effectively no warning.
Brought CashuWallet up to (slightly past) parity: when the mint being
removed has a non-zero balance it now shows a loud red warning with the
exact sats at risk and relabels the button "Remove anyway"; empty mints
keep the mild yellow note. Deletion is still allowed (a permanently
offline mint must be removable even with a stuck balance) — it's now an
informed choice, not a silent one.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
parent
56e2b17990
commit
c6e74cc189
2 changed files with 24 additions and 8 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "skate-spots",
|
"name": "skate-spots",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.2.38",
|
"version": "1.2.39",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"homepage": "https://skate-spots.com",
|
"homepage": "https://skate-spots.com",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -663,12 +663,26 @@ export function CashuWallet() {
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Alert className="bg-yellow-950/30 border-yellow-500/30">
|
{mintToRemove && (balances[mintToRemove.url] || 0) > 0 ? (
|
||||||
<AlertCircle className="h-4 w-4 text-yellow-400" />
|
// Real balance at risk — removing deletes the local proofs and
|
||||||
<AlertDescription className="text-sm text-gray-300">
|
// strands these sats. Make the amount explicit and loud.
|
||||||
Make sure you have withdrawn all funds from this mint before removing it.
|
<Alert className="bg-red-950/40 border-red-500/50">
|
||||||
</AlertDescription>
|
<AlertCircle className="h-4 w-4 text-red-400" />
|
||||||
</Alert>
|
<AlertDescription className="text-sm text-gray-200">
|
||||||
|
<span className="font-bold text-red-400">Warning:</span> This mint still holds{' '}
|
||||||
|
<span className="font-bold">{(balances[mintToRemove.url] || 0).toLocaleString()} sats</span>.
|
||||||
|
Removing it deletes those funds from this device — withdraw or send them first,
|
||||||
|
or they'll be lost.
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
) : (
|
||||||
|
<Alert className="bg-yellow-950/30 border-yellow-500/30">
|
||||||
|
<AlertCircle className="h-4 w-4 text-yellow-400" />
|
||||||
|
<AlertDescription className="text-sm text-gray-300">
|
||||||
|
Make sure you have withdrawn all funds from this mint before removing it.
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
<div className="flex gap-3 justify-end">
|
<div className="flex gap-3 justify-end">
|
||||||
<Button variant="outline" onClick={() => setShowRemoveMintModal(false)}>
|
<Button variant="outline" onClick={() => setShowRemoveMintModal(false)}>
|
||||||
Cancel
|
Cancel
|
||||||
|
|
@ -677,7 +691,9 @@ export function CashuWallet() {
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
onClick={handleConfirmRemoveMint}
|
onClick={handleConfirmRemoveMint}
|
||||||
>
|
>
|
||||||
Remove Mint
|
{mintToRemove && (balances[mintToRemove.url] || 0) > 0
|
||||||
|
? 'Remove anyway'
|
||||||
|
: 'Remove Mint'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue