From 626cc1368495f7779968fd9e99434a294cc90f32 Mon Sep 17 00:00:00 2001 From: Jonathan Tzeng Date: Thu, 27 Aug 2026 18:49:05 -0700 Subject: [PATCH] Make MAX and multi-recipient send exclusive MAX spends the entire spendable balance, which only has a coherent meaning for a single recipient. The send scene now hides the MAX button whenever the send has more than one spend target, and withholds the "Add another address" row while a MAX amount is set, so the two can no longer be combined into a transaction that always fails with insufficient funds. --- CHANGELOG.md | 1 + src/components/scenes/SendScene2.tsx | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aac7bd2e16a..c072c1203af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - fixed: Show the QR scanner scam warning after the camera permission is granted, instead of behind the OS permission prompt where it flashed away, and show only the Settings recovery guidance when camera access is denied. - fixed: Password reminder no longer stops reappearing after unlocking Account Settings - fixed: Show the password recovery reminder at every balance milestone, including for funds that arrived while the app was closed or before the exchange rates loaded. +- fixed: Hide the send scene's MAX button once a send has more than one recipient, and hide "Add another address" once MAX has been applied, so the two can no longer combine into an insufficient-funds transaction. ## 4.51.0 (staging) diff --git a/src/components/scenes/SendScene2.tsx b/src/components/scenes/SendScene2.tsx index c1632fd810f..eb87b4e2b0a 100644 --- a/src/components/scenes/SendScene2.tsx +++ b/src/components/scenes/SendScene2.tsx @@ -631,6 +631,11 @@ const SendComponent: React.FC = props => { const handleFlipInputModal = (index: number, spendTarget: EdgeSpendTarget) => (): void => { const { noChangeMiningFee } = getSpecialCurrencyInfo(pluginId) + // A max spend only has a defined meaning for a single recipient: it + // consumes the entire spendable balance. Once the send has more than one + // target there is nothing left over for the others, so the button is + // hidden rather than allowed to produce an insufficient-funds spend. + const isMultipleTargets = spendInfo.spendTargets.length > 1 Airship.show(bridge => ( = props => { startNativeAmount={spendTarget.nativeAmount} feeTokenId={null} forceField={fieldChanged} + hideMaxButton={isMultipleTargets} onAmountsChanged={handleAmountsChanged(spendTarget)} onMaxSet={() => { setMaxSpendSetter(index) @@ -764,7 +770,11 @@ const SendComponent: React.FC = props => { hiddenFeaturesMap.address === true || hiddenFeaturesMap.amount === true || lockTilesMap.address === true || - lockTilesMap.amount === true + lockTilesMap.amount === true || + // The existing target already claims the whole spendable balance, so a + // second recipient could only ever be funded by shrinking it. Withhold + // the entry point instead of silently discarding the max amount. + maxSpendSetter >= 0 ) { return null }