From a4cc127cbce5b1ac8ec55e61e7e83d57f00ec42b Mon Sep 17 00:00:00 2001 From: sneak Date: Mon, 5 Oct 2026 04:05:20 +0000 Subject: [PATCH] feat: a "Max" button on the Send screen (closes #198) Max fills in a token's balance, cut down to the 18 decimal places the confirmation screen accepts, or for ETH the exact balance minus the fee reserve the confirmation screen's balance check gates on. An ETH fee estimate that finishes after the Send screen was left, or its address, holding, recipient or amount changed, fills nothing in. The confirmation screen works a max ETH amount out again from its own fee estimate and signs it with that estimate's fee fields, so a fee that rose before signing cannot push amount plus fee above the balance. validateTransfer() still gates every send, the check that ETH covers a token send's fee included. Where there is nothing to fill in, a flash message says why. Model: opus-5-5 --- README.md | 20 +- TODO.md | 14 + docs/README.md | 4 +- src/popup/index.html | 20 +- src/popup/views/confirmTx.js | 77 +++-- src/popup/views/send.js | 116 +++++++- src/shared/txValidation.js | 37 ++- tests/sendMax.test.js | 530 +++++++++++++++++++++++++++++++++++ tests/txValidation.test.js | 68 +++++ 9 files changed, 851 insertions(+), 35 deletions(-) create mode 100644 tests/sendMax.test.js diff --git a/README.md b/README.md index 6b1c28b..1d19c85 100644 --- a/README.md +++ b/README.md @@ -1467,6 +1467,17 @@ view would leave a wallet one click from deletion. - Amount input with current balance display, which reads `Current balance: unknown (SYMBOL)` for a token whose scale is unknown, as ConfirmTx's balance line does (see Unknown token scale) + - "Max" button beside the amount input, always in place. It fills in a + token's balance, cut down to the 18 decimal places ConfirmTx accepts for a + token that has more, or for ETH the exact balance minus the network fee + reserve that ConfirmTx's balance check gates on, never the rounded balance + shown above it. The ETH fee is estimated for the recipient entered, so it + asks for a recipient first; an estimate that finishes after the screen was + left or the address, holding or recipient changed fills nothing in. Where + there is nothing to fill in, a flash message says why: the balance does + not cover the fee, the fee could not be estimated, or the token's balance + is unknown or zero. Typing in the amount makes it an ordinary amount; + changing what to send clears an amount Max filled in - "Review" button, disabled until the recipient validates - **Transitions**: - "Review" (valid inputs, ENS resolved) → **ConfirmTx** @@ -1483,7 +1494,14 @@ view would leave a wallet one click from deletion. - Token contract: full address + etherscan link (ERC-20 only) - From: blockie + color dot + full address + etherscan link + wallet title - To: blockie + color dot + full address + etherscan link + ENS name - - Amount: value + symbol (USD in parentheses) + - Amount: value + symbol (USD in parentheses). An ETH amount Send's "Max" + filled in is worked out again from this screen's own fee estimate when it + arrives, as the balance minus the reserve, and the transaction is signed + with that estimate's fee fields, so a fee fetched again at signing cannot + exceed what the amount leaves behind. The address keeps whatever part of + the reserve the transaction does not use. If the balance no longer covers + the fee, the amount is left as it was and the amount-plus-fee error below + blocks the send - Your balance: value + symbol (USD in parentheses), or `unknown (SYMBOL)` for a token whose scale is unknown - Network fee: "Estimating..." then two lines, or "Unable to estimate", diff --git a/TODO.md b/TODO.md index e34755e..e354a4a 100644 --- a/TODO.md +++ b/TODO.md @@ -45,6 +45,20 @@ but the review is broader than any of them. # Completed Steps +- 2026-10-05: The Send screen has a "Max" button + ([#198](https://git.eeqj.de/sneak/AutistMask/issues/198)). Emptying an ETH + address took guessing an amount and being refused by the confirmation screen's + balance check. Max fills in a token's whole balance, cut to the 18 decimal + places the confirmation screen accepts, or for ETH the exact balance minus the + fee reserve that check gates on, never the four-decimal balance shown; a fee + estimate that finishes after the Send screen was left, or its address, holding + or recipient changed, fills nothing in. The confirmation screen works a max + ETH amount out again from its own fee estimate and signs it with that + estimate's fee fields: fetched again at signing, a fee that had risen since + would leave amount plus fee above the balance, and the node would refuse the + send. A token's maximum is still refused when ETH cannot pay the fee. Where + there is nothing to fill in, a flash message says why. + - 2026-10-05: A token scale of zero decimals is tested ([#325](https://git.eeqj.de/sneak/AutistMask/issues/325)). `resolveTokenDecimals()` already used a scale of 0 from the bundled list or diff --git a/docs/README.md b/docs/README.md index 032fca3..6e4cf94 100644 --- a/docs/README.md +++ b/docs/README.md @@ -240,7 +240,9 @@ screen. Tokens can also be added from Settings, under "Tracked Tokens". 2. Select what to send (ETH, or any ERC-20 token with a balance on this address that survives the spam filters). 3. Enter the recipient address or ENS name (e.g. `vitalik.eth`). -4. Enter the amount. +4. Enter the amount, or click "Max" to fill it in: a token's balance, cut to 18 + decimal places, or your ETH balance minus the amount reserved for the network + fee. 5. Click "Review" to see the confirmation screen. The confirmation screen shows: diff --git a/src/popup/index.html b/src/popup/index.html index 83635ee..d318b67 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -551,12 +551,20 @@ class="text-xs text-muted" > - +
+ + +