From b80b931a48f1bff752a25fde117d57d42a09ea07 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 15 Jun 2026 07:31:07 -0300 Subject: [PATCH 1/5] fix: set currentMaxAllowedToSend on max exceeded --- .../ui/screens/transfer/SpendingAmountScreen.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt index 7a9fe15e9..3438f2f6a 100644 --- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt @@ -92,11 +92,14 @@ fun SpendingAmountScreen( LaunchedEffect(Unit) { amountInputViewModel.effect.collect { when (it) { - AmountInputEffect.MaxExceeded -> toast( - context.getString(R.string.lightning__spending_amount__error_max__title), - context.getString(R.string.lightning__spending_amount__error_max__description) - .replace("{amount}", currentMaxAllowedToSend.formatToModernDisplay()), - ) + AmountInputEffect.MaxExceeded -> { + amountInputViewModel.setSats(currentMaxAllowedToSend, currencies) + toast( + context.getString(R.string.lightning__spending_amount__error_max__title), + context.getString(R.string.lightning__spending_amount__error_max__description) + .replace("{amount}", currentMaxAllowedToSend.formatToModernDisplay()), + ) + } } } } From f495670474ab509b28b35477fa6cd4f12d4fbaf1 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 15 Jun 2026 07:37:06 -0300 Subject: [PATCH 2/5] chore: add changelog fragment Co-Authored-By: Claude Opus 4.8 (1M context) --- changelog.d/next/1013.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/next/1013.fixed.md diff --git a/changelog.d/next/1013.fixed.md b/changelog.d/next/1013.fixed.md new file mode 100644 index 000000000..a18e5fbe3 --- /dev/null +++ b/changelog.d/next/1013.fixed.md @@ -0,0 +1 @@ +Transfer to Spending now fills in the maximum transferable amount when you enter a value above the limit, instead of only showing an error. From a9369789e4aec41420081fb2aac1455dd6568db0 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 15 Jun 2026 07:41:17 -0300 Subject: [PATCH 3/5] fix: set currentMaxAllowedToSend on max exceeded in spending advanced screen --- .../screens/transfer/SpendingAdvancedScreen.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt index ba779be63..36afb9690 100644 --- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt @@ -112,13 +112,16 @@ fun SpendingAdvancedScreen( LaunchedEffect(Unit) { amountInputViewModel.effect.collect { when (it) { - AmountInputEffect.MaxExceeded -> app.toast( - type = Toast.ToastType.WARNING, - title = context.getString(R.string.lightning__spending_advanced__error_max__title), - description = context.getString(R.string.lightning__spending_advanced__error_max__description) - .replace("{amount}", currentMaxLspBalance.formatToModernDisplay()), - visibilityTime = Toast.VISIBILITY_TIME_SHORT, - ) + AmountInputEffect.MaxExceeded -> { + amountInputViewModel.setSats(currentMaxLspBalance.toLong(), currencies) + app.toast( + type = Toast.ToastType.WARNING, + title = context.getString(R.string.lightning__spending_advanced__error_max__title), + description = context.getString(R.string.lightning__spending_advanced__error_max__description) + .replace("{amount}", currentMaxLspBalance.formatToModernDisplay()), + visibilityTime = Toast.VISIBILITY_TIME_SHORT, + ) + } } } } From cd7f0b7c8b3c5d3fcd598842b1a592e854d11c04 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 15 Jun 2026 07:59:05 -0300 Subject: [PATCH 4/5] fix: stop max/quarter buttons reloading limits --- .../screens/transfer/SpendingAmountScreen.kt | 18 ++---------------- .../to/bitkit/viewmodels/TransferViewModel.kt | 7 ++++--- .../bitkit/viewmodels/TransferViewModelTest.kt | 2 ++ 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt index 3438f2f6a..e257bbc6d 100644 --- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt @@ -55,7 +55,6 @@ import to.bitkit.viewmodels.TransferEffect import to.bitkit.viewmodels.TransferToSpendingUiState import to.bitkit.viewmodels.TransferViewModel import to.bitkit.viewmodels.previewAmountInputViewModel -import kotlin.math.min @Suppress("ViewModelForwarding") @Composable @@ -112,23 +111,10 @@ fun SpendingAmountScreen( currencies = currencies, onBackClick = onBackClick, onClickQuarter = { - val quarter = uiState.balanceAfterFeeQuarter() - val max = uiState.maxAllowedToSend - if (quarter > max) { - toast( - context.getString(R.string.lightning__spending_amount__error_max__title), - context.getString(R.string.lightning__spending_amount__error_max__description) - .replace("{amount}", max.formatToModernDisplay()), - ) - } - val cappedQuarter = min(quarter, max) - viewModel.updateLimits(cappedQuarter) - amountInputViewModel.setSats(cappedQuarter, currencies) + amountInputViewModel.setSats(uiState.quarterAmount, currencies) }, onClickMaxAmount = { - val newAmountSats = uiState.maxAllowedToSend - viewModel.updateLimits(newAmountSats) - amountInputViewModel.setSats(newAmountSats, currencies) + amountInputViewModel.setSats(uiState.maxAllowedToSend, currencies) }, onConfirmAmount = { viewModel.onConfirmAmount(amountUiState.sats) }, ) diff --git a/app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt index 6e03c7514..202ac4ee9 100644 --- a/app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt @@ -405,12 +405,14 @@ class TransferViewModel @Inject constructor( liquidity.maxClientBalanceSat.toLong(), maxClientBalance.toLong() ) + val quarterAmount = min((maxSend.toDouble() * 0.25).roundToLong(), maxSend) _spendingUiState.update { it.copy( maxAllowedToSend = maxSend, isLoading = false, balanceAfterFee = maxSend, + quarterAmount = quarterAmount, ) } }.onFailure { @@ -650,12 +652,11 @@ data class TransferToSpendingUiState( val isAdvanced: Boolean = false, val maxAllowedToSend: Long = 0, val balanceAfterFee: Long = 0, + val quarterAmount: Long = 0, val isLoading: Boolean = false, val receivingAmount: Long = 0, val feeEstimate: Long? = null, -) { - fun balanceAfterFeeQuarter() = (balanceAfterFee.toDouble() * 0.25).roundToLong() -} +) data class TransferValues( val defaultLspBalance: ULong = 0u, diff --git a/app/src/test/java/to/bitkit/viewmodels/TransferViewModelTest.kt b/app/src/test/java/to/bitkit/viewmodels/TransferViewModelTest.kt index 2f45eefa3..e4472bdab 100644 --- a/app/src/test/java/to/bitkit/viewmodels/TransferViewModelTest.kt +++ b/app/src/test/java/to/bitkit/viewmodels/TransferViewModelTest.kt @@ -27,6 +27,7 @@ import to.bitkit.repositories.LightningState import to.bitkit.repositories.TransferRepo import to.bitkit.repositories.WalletRepo import to.bitkit.test.BaseUnitTest +import kotlin.math.roundToLong import kotlin.test.assertEquals import kotlin.time.Clock import kotlin.time.ExperimentalTime @@ -89,6 +90,7 @@ class TransferViewModelTest : BaseUnitTest() { val state = sut.spendingUiState.value assertEquals(OPTION_MAX_CLIENT_BALANCE.toLong(), state.maxAllowedToSend) assertEquals(OPTION_MAX_CLIENT_BALANCE.toLong(), state.balanceAfterFee) + assertEquals((OPTION_MAX_CLIENT_BALANCE.toDouble() * 0.25).roundToLong(), state.quarterAmount) // The order fee must be estimated against the clamped client balance, not the full balance. verify(blocktankRepo).estimateOrderFee(eq(LSP_MAX_CLIENT_BALANCE), any(), any()) From fcfd2f662332e559d79204b5c052d9c6ae2765a3 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 15 Jun 2026 08:04:01 -0300 Subject: [PATCH 5/5] fix: stale currencies --- .../to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt | 3 ++- .../java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt index 36afb9690..06a48a341 100644 --- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt @@ -75,6 +75,7 @@ fun SpendingAdvancedScreen( val transferValues by viewModel.transferValues.collectAsStateWithLifecycle() val currentMaxLspBalance by rememberUpdatedState(transferValues.maxLspBalance) + val currentCurrencies by rememberUpdatedState(currencies) LaunchedEffect(order.clientBalanceSat) { viewModel.updateTransferValues(order.clientBalanceSat) @@ -113,7 +114,7 @@ fun SpendingAdvancedScreen( amountInputViewModel.effect.collect { when (it) { AmountInputEffect.MaxExceeded -> { - amountInputViewModel.setSats(currentMaxLspBalance.toLong(), currencies) + amountInputViewModel.setSats(currentMaxLspBalance.toLong(), currentCurrencies) app.toast( type = Toast.ToastType.WARNING, title = context.getString(R.string.lightning__spending_advanced__error_max__title), diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt index e257bbc6d..36ea358a0 100644 --- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt @@ -73,6 +73,7 @@ fun SpendingAmountScreen( val amountUiState by amountInputViewModel.uiState.collectAsStateWithLifecycle() val context = LocalContext.current val currentMaxAllowedToSend by rememberUpdatedState(uiState.maxAllowedToSend) + val currentCurrencies by rememberUpdatedState(currencies) LaunchedEffect(isOffline) { viewModel.updateLimits() @@ -92,7 +93,7 @@ fun SpendingAmountScreen( amountInputViewModel.effect.collect { when (it) { AmountInputEffect.MaxExceeded -> { - amountInputViewModel.setSats(currentMaxAllowedToSend, currencies) + amountInputViewModel.setSats(currentMaxAllowedToSend, currentCurrencies) toast( context.getString(R.string.lightning__spending_amount__error_max__title), context.getString(R.string.lightning__spending_amount__error_max__description)