Adds a "Max" button beside the Send screen's amount input, for #198.
ETH: fills in the exact stored balance minus the fee reserve (gasLimit * maxFeePerGas) that validateTransfer() gates on, via maxEthAmount() in src/shared/txValidation.js. The fee depends on the recipient, so Max asks for one first. An estimate that finishes after the Send screen was left or opened again, or after the address, holding, recipient or amount changed, fills nothing in.
The confirmation screen works a max ETH amount out again from each fee estimate it gets, a reopen included.
Token: fills in the whole stored balance, cut down (never up) to 18 decimal places for a token that has more, the most the confirmation screen accepts. maxTokenAmount() does the cut; validateTransfer() now uses it for the cut it already made. The check that ETH covers the fee is unchanged.
Nothing to fill in (fee not covered or not estimable, token balance unknown or zero): a flash message, field untouched.
The button is always in place, so nothing moves.
Not obvious from the diff:
A max ETH send is signed with the fee fields of the estimate its amount came from. Otherwise ethers fetches fees again at signing, and any rise meanwhile puts amount plus fee over the balance and the node refuses it. Other sends still pin nothing.
The address keeps the unused part of the reserve, so a max send does not leave exactly zero.
Judgement call: pinning the fee fields goes beyond the issue's text; without it a max send fails whenever the fee rises before signing.
Model: opus-5-5
Adds a "Max" button beside the Send screen's amount input, for https://git.eeqj.de/sneak/AutistMask/issues/198.
- ETH: fills in the exact stored balance minus the fee reserve (`gasLimit * maxFeePerGas`) that `validateTransfer()` gates on, via `maxEthAmount()` in `src/shared/txValidation.js`. The fee depends on the recipient, so Max asks for one first. An estimate that finishes after the Send screen was left or opened again, or after the address, holding, recipient or amount changed, fills nothing in.
- The confirmation screen works a max ETH amount out again from each fee estimate it gets, a reopen included.
- Token: fills in the whole stored balance, cut down (never up) to 18 decimal places for a token that has more, the most the confirmation screen accepts. `maxTokenAmount()` does the cut; `validateTransfer()` now uses it for the cut it already made. The check that ETH covers the fee is unchanged.
- Nothing to fill in (fee not covered or not estimable, token balance unknown or zero): a flash message, field untouched.
- The button is always in place, so nothing moves.
Not obvious from the diff:
- A max ETH send is signed with the fee fields of the estimate its amount came from. Otherwise ethers fetches fees again at signing, and any rise meanwhile puts amount plus fee over the balance and the node refuses it. Other sends still pin nothing.
- The address keeps the unused part of the reserve, so a max send does not leave exactly zero.
Judgement call: pinning the fee fields goes beyond the issue's text; without it a max send fails whenever the fee rises before signing.
Model: opus-5-5
clawbot
self-assigned this 2026-10-05 06:08:12 +02:00
src/popup/views/send.js lines 287-290: a Max fee estimate still running when the user leaves the Send screen and opens it again, for the same or another address, still lands. It fills the new screen's empty amount field with the first address's maximum and marks it as a Max amount, and the confirmation screen then turns it into the whole ETH balance, less the fee reserve, of whichever address is now selected, which the user never asked for on that screen. The check before filling compares only the amount text and the token. Acceptable: drop the result unless the address and the recipient are still the ones the estimate was made for (opening Send clears the recipient), with a test that fails without the fix.
README.md lines 1470-1471: says Max fills in "the most the selected holding can send: a token's whole balance". For a token with more than 18 decimal places it fills in a balance the confirmation screen then refuses ("Please enter a valid amount to send."). The PR body lists this as a known limit; the README does not. Acceptable: either fill such a balance cut to the 18 places the confirmation screen accepts, or state the limit in this README entry.
Judgement call: signing a max ETH send with the fee fields of the estimate shown on the confirmation screen is safe to keep; it applies only to a max ETH send and still goes through the fee ceiling.
Model: opus-5-5
FAIL
1. `src/popup/views/send.js` lines 287-290: a Max fee estimate still running when the user leaves the Send screen and opens it again, for the same or another address, still lands. It fills the new screen's empty amount field with the first address's maximum and marks it as a Max amount, and the confirmation screen then turns it into the whole ETH balance, less the fee reserve, of whichever address is now selected, which the user never asked for on that screen. The check before filling compares only the amount text and the token. Acceptable: drop the result unless the address and the recipient are still the ones the estimate was made for (opening Send clears the recipient), with a test that fails without the fix.
2. `README.md` lines 1470-1471: says Max fills in "the most the selected holding can send: a token's whole balance". For a token with more than 18 decimal places it fills in a balance the confirmation screen then refuses ("Please enter a valid amount to send."). The PR body lists this as a known limit; the README does not. Acceptable: either fill such a balance cut to the 18 places the confirmation screen accepts, or state the limit in this README entry.
Judgement call: signing a max ETH send with the fee fields of the estimate shown on the confirmation screen is safe to keep; it applies only to a max ETH send and still goes through the fee ceiling.
Model: opus-5-5
The result is dropped unless the Send screen is still shown, has not been opened again since, and the address, holding, recipient and amount are unchanged. Tests cover reopening for the same and for another address, leaving, and a changed recipient.
Cut, not documented as a limit: Max fills a token balance cut down to 18 decimal places, using the same cut validateTransfer() already made, and the README.md entry says so. A test covers a 24-decimal token.
Model: opus-5-5
Rework for https://git.eeqj.de/sneak/AutistMask/pulls/452#issuecomment-126273, head `b60eec9`:
1. The result is dropped unless the Send screen is still shown, has not been opened again since, and the address, holding, recipient and amount are unchanged. Tests cover reopening for the same and for another address, leaving, and a changed recipient.
2. Cut, not documented as a limit: Max fills a token balance cut down to 18 decimal places, using the same cut `validateTransfer()` already made, and the `README.md` entry says so. A test covers a 24-decimal token.
Model: opus-5-5
src/popup/views/send.js lines 307 and 309: no test covers the checks that drop a late Max estimate when the holding was changed (line 307) or an amount was typed (line 309) while the fee was being estimated. Removing either check leaves the suite passing. Both can happen on the Send screen, through the holding dropdown and the amount field, and without line 307 an ETH maximum lands in a token's amount field marked as a Max amount. Acceptable: two tests in tests/sendMax.test.js, one changing the holding and one typing an amount while the estimate is held, each failing without its check.
docs/README.md lines 243-244: says Max fills in "your ETH balance minus the network fee". The same page defines the network fee as what the transfer is expected to cost, and the larger reserve as what the balance check gates on. Max subtracts the reserve, so the unused part of it stays on the address. The line also promises "a token's whole balance", which a token with more than 18 decimal places does not get. Acceptable: wording that promises no more than Max fills in, e.g. the ETH balance minus the amount reserved for the network fee, and a token's balance cut to 18 decimal places.
Model: opus-5-5
FAIL
1. `src/popup/views/send.js` lines 307 and 309: no test covers the checks that drop a late Max estimate when the holding was changed (line 307) or an amount was typed (line 309) while the fee was being estimated. Removing either check leaves the suite passing. Both can happen on the Send screen, through the holding dropdown and the amount field, and without line 307 an ETH maximum lands in a token's amount field marked as a Max amount. Acceptable: two tests in `tests/sendMax.test.js`, one changing the holding and one typing an amount while the estimate is held, each failing without its check.
2. `docs/README.md` lines 243-244: says Max fills in "your ETH balance minus the network fee". The same page defines the network fee as what the transfer is expected to cost, and the larger reserve as what the balance check gates on. Max subtracts the reserve, so the unused part of it stays on the address. The line also promises "a token's whole balance", which a token with more than 18 decimal places does not get. Acceptable: wording that promises no more than Max fills in, e.g. the ETH balance minus the amount reserved for the network fee, and a token's balance cut to 18 decimal places.
Model: opus-5-5
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
Added both tests to tests/sendMax.test.js: the holding changed through the dropdown, and an amount typed, while the estimate is held. Each fails with its check removed from src/popup/views/send.js; the code is unchanged.
docs/README.md now says Max fills in a token's balance cut to 18 decimal places, or the ETH balance minus the amount reserved for the network fee. README.md no longer says "the most the selected holding can send" or "whole balance".
Model: opus-5-5
Rework for https://git.eeqj.de/sneak/AutistMask/pulls/452#issuecomment-126291, head `a4cc127`:
1. Added both tests to `tests/sendMax.test.js`: the holding changed through the dropdown, and an amount typed, while the estimate is held. Each fails with its check removed from `src/popup/views/send.js`; the code is unchanged.
2. `docs/README.md` now says Max fills in a token's balance cut to 18 decimal places, or the ETH balance minus the amount reserved for the network fee. `README.md` no longer says "the most the selected holding can send" or "whole balance".
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds a "Max" button beside the Send screen's amount input, for #198.
gasLimit * maxFeePerGas) thatvalidateTransfer()gates on, viamaxEthAmount()insrc/shared/txValidation.js. The fee depends on the recipient, so Max asks for one first. An estimate that finishes after the Send screen was left or opened again, or after the address, holding, recipient or amount changed, fills nothing in.maxTokenAmount()does the cut;validateTransfer()now uses it for the cut it already made. The check that ETH covers the fee is unchanged.Not obvious from the diff:
Judgement call: pinning the fee fields goes beyond the issue's text; without it a max send fails whenever the fee rises before signing.
Model: opus-5-5
FAIL
src/popup/views/send.jslines 287-290: a Max fee estimate still running when the user leaves the Send screen and opens it again, for the same or another address, still lands. It fills the new screen's empty amount field with the first address's maximum and marks it as a Max amount, and the confirmation screen then turns it into the whole ETH balance, less the fee reserve, of whichever address is now selected, which the user never asked for on that screen. The check before filling compares only the amount text and the token. Acceptable: drop the result unless the address and the recipient are still the ones the estimate was made for (opening Send clears the recipient), with a test that fails without the fix.README.mdlines 1470-1471: says Max fills in "the most the selected holding can send: a token's whole balance". For a token with more than 18 decimal places it fills in a balance the confirmation screen then refuses ("Please enter a valid amount to send."). The PR body lists this as a known limit; the README does not. Acceptable: either fill such a balance cut to the 18 places the confirmation screen accepts, or state the limit in this README entry.Judgement call: signing a max ETH send with the fee fields of the estimate shown on the confirmation screen is safe to keep; it applies only to a max ETH send and still goes through the fee ceiling.
Model: opus-5-5
a0f1e98323tob60eec9197Rework for #452 (comment), head
b60eec9:validateTransfer()already made, and theREADME.mdentry says so. A test covers a 24-decimal token.Model: opus-5-5
FAIL
src/popup/views/send.jslines 307 and 309: no test covers the checks that drop a late Max estimate when the holding was changed (line 307) or an amount was typed (line 309) while the fee was being estimated. Removing either check leaves the suite passing. Both can happen on the Send screen, through the holding dropdown and the amount field, and without line 307 an ETH maximum lands in a token's amount field marked as a Max amount. Acceptable: two tests intests/sendMax.test.js, one changing the holding and one typing an amount while the estimate is held, each failing without its check.docs/README.mdlines 243-244: says Max fills in "your ETH balance minus the network fee". The same page defines the network fee as what the transfer is expected to cost, and the larger reserve as what the balance check gates on. Max subtracts the reserve, so the unused part of it stays on the address. The line also promises "a token's whole balance", which a token with more than 18 decimal places does not get. Acceptable: wording that promises no more than Max fills in, e.g. the ETH balance minus the amount reserved for the network fee, and a token's balance cut to 18 decimal places.Model: opus-5-5
b60eec9197toa4cc127cbcRework for #452 (comment), head
a4cc127:tests/sendMax.test.js: the holding changed through the dropdown, and an amount typed, while the estimate is held. Each fails with its check removed fromsrc/popup/views/send.js; the code is unchanged.docs/README.mdnow says Max fills in a token's balance cut to 18 decimal places, or the ETH balance minus the amount reserved for the network fee.README.mdno longer says "the most the selected holding can send" or "whole balance".Model: opus-5-5
PASS
Model: opus-5-5