From 408395bf05c2bb8a129a19392afa356798d98a87 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 8 Oct 2026 16:45:45 -0700 Subject: Max in fiat sends every sat: the figure a Max fill wrote is remembered with its exact sats, so the cent-rounded amount no longer parses back a few sats short and strands them. Anything typed parses as typed Co-Authored-By: Claude Opus 5.5 --- src/app.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/app.js') diff --git a/src/app.js b/src/app.js index 122ccfe..ec7ef53 100644 --- a/src/app.js +++ b/src/app.js @@ -1154,11 +1154,22 @@ function toggleUnit() { // A sats figure as the amount field types it in the current unit — what a // Max button or a fixed-amount invoice fills in. Fiat is floored to the // cent so a filled-in maximum never parses back to more than was offered. +// The figure it filled is remembered with its exact sats: a fiat maximum +// rounded to the cent would otherwise parse back a few sats short and leave +// them behind. Typing anything else parses as typed. +let lastFill = null; function amountField(sat) { - if (unit === 'sats') return String(sat); + let s; const r = unit === 'fiat' && rateNow(); - if (r) return (Math.floor((sat / 1e8) * r * 100) / 100).toFixed(2); - return (sat / 1e8).toFixed(8); + if (unit === 'sats') s = String(sat); + else if (r) s = (Math.floor((sat / 1e8) * r * 100) / 100).toFixed(2); + else s = (sat / 1e8).toFixed(8); + lastFill = { s, unit, sat }; + return s; +} +function parseField(v, u = unit) { + if (lastFill && lastFill.unit === u && String(v).trim() === lastFill.s) return lastFill.sat; + return parseAmount(v, u, rateNow()); } const unitLabel = () => (unit === 'sats' ? 'sats' : unit === 'fiat' ? getCurrency() : 'BTC'); @@ -5583,7 +5594,7 @@ function reviewSend() { recipients = s.recipients.map((r, i) => { const addr = r.address.trim(); if (!addr) throw new Error(t('enterAddrForN', { n: i + 1 })); - const sats = parseAmount(r.amount, unit, rateNow()); + const sats = parseField(r.amount); if (!sats || sats <= 0) throw new Error(t('enterValidAmtForN', { n: i + 1 })); return { address: addr, amount: sats }; }); @@ -5963,7 +5974,7 @@ const ctx = { openSettingsPage: (page) => { clearFeatureNav(); ui.screen = 'wallet'; ui.tab = 'settings'; ui.settingsPage = page; render(); try { window.scrollTo(0, 0); } catch {} }, fmtAmount, unitLabel, unitTag, getUnit: () => unit, toggleUnit, download, amountField, // in fiat the typed figure is money, so it needs today's price to become sats - parseAmount: (v, u) => parseAmount(v, u, rateNow()), + parseAmount: parseField, worthLine, openImage: (src) => { ui.lightbox = src; render(); }, // What woke this run, if anything did, and how to say we're finished. -- cgit v1.2.3