Skip to content

Commit 0248536

Browse files
authored
Merge branch 'master' into feat/nav3
2 parents 9e96420 + f4c26b0 commit 0248536

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

app/src/main/java/to/bitkit/models/BalanceState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable
66
data class BalanceState(
77
val totalOnchainSats: ULong = 0uL,
88
val totalLightningSats: ULong = 0uL,
9-
val maxSendLightningSats: ULong = 0uL,
9+
val maxSendLightningSats: ULong = 0uL, // Without account routing fees
1010
val maxSendOnchainSats: ULong = 0uL,
1111
val balanceInTransferToSavings: ULong = 0uL,
1212
val balanceInTransferToSpending: ULong = 0uL,

app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import to.bitkit.models.BalanceState
3333
import to.bitkit.models.BitcoinDisplayUnit
3434
import to.bitkit.models.NodeLifecycleState
3535
import to.bitkit.models.Toast
36+
import to.bitkit.models.safe
3637
import to.bitkit.repositories.CurrencyState
3738
import to.bitkit.ui.LocalBalances
3839
import to.bitkit.ui.LocalCurrencies
@@ -91,6 +92,12 @@ fun SendAmountScreen(
9192
currentOnEvent(SendEvent.AmountChange(amountInputUiState.sats.toULong()))
9293
}
9394

95+
LaunchedEffect(uiState.decodedInvoice, uiState.payMethod) {
96+
if (uiState.payMethod == SendMethod.LIGHTNING && uiState.decodedInvoice != null) {
97+
currentOnEvent(SendEvent.EstimateMaxRoutingFee)
98+
}
99+
}
100+
94101
SendAmountContent(
95102
walletUiState = walletUiState,
96103
uiState = uiState,
@@ -190,7 +197,11 @@ private fun SendAmountNodeRunning(
190197
val availableAmount = when {
191198
isLnurlWithdraw -> uiState.lnurl.data.maxWithdrawableSat().toLong()
192199
uiState.payMethod == SendMethod.ONCHAIN -> balances.maxSendOnchainSats.toLong()
193-
else -> balances.maxSendLightningSats.toLong()
200+
else -> {
201+
val maxLightning = balances.maxSendLightningSats
202+
val routingFee = uiState.estimatedRoutingFee
203+
(maxLightning.safe() - routingFee.safe()).toLong()
204+
}
194205
}
195206

196207
Column(

app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import to.bitkit.models.NewTransactionSheetType
7878
import to.bitkit.models.Suggestion
7979
import to.bitkit.models.Toast
8080
import to.bitkit.models.TransactionSpeed
81+
import to.bitkit.models.safe
8182
import to.bitkit.models.toActivityFilter
8283
import to.bitkit.models.toTxType
8384
import to.bitkit.repositories.ActivityRepo
@@ -484,6 +485,10 @@ class AppViewModel @Inject constructor(
484485
SendEvent.SwipeToPay -> onSwipeToPay()
485486
is SendEvent.ConfirmAmountWarning -> onConfirmAmountWarning(it.warning)
486487
SendEvent.DismissAmountWarning -> onDismissAmountWarning()
488+
SendEvent.EstimateMaxRoutingFee -> viewModelScope.launch {
489+
estimateMaxAmountRoutingFee()
490+
}
491+
487492
SendEvent.PayConfirmed -> onConfirmPay()
488493
SendEvent.ClearPayConfirmation -> _sendUiState.update { s -> s.copy(shouldConfirmPay = false) }
489494
SendEvent.BackToAmount -> setSendEffect(SendEffect.PopBack(Routes.Send.Amount()))
@@ -1018,9 +1023,12 @@ class AppViewModel @Inject constructor(
10181023
if (_sendUiState.value.showSanityWarningDialog != null) return
10191024

10201025
val settings = settingsStore.data.first()
1021-
1026+
val balanceToCheck = when (_sendUiState.value.payMethod) {
1027+
SendMethod.ONCHAIN -> walletRepo.balanceState.value.maxSendOnchainSats
1028+
SendMethod.LIGHTNING -> walletRepo.balanceState.value.maxSendLightningSats
1029+
}
10221030
if (
1023-
amountSats > BigDecimal.valueOf(walletRepo.balanceState.value.totalSats.toLong())
1031+
amountSats > BigDecimal.valueOf(balanceToCheck.toLong())
10241032
.times(BigDecimal(MAX_BALANCE_FRACTION)).toLong().toUInt() &&
10251033
SanityWarning.OVER_HALF_BALANCE !in _sendUiState.value.confirmedWarnings
10261034
) {
@@ -1432,6 +1440,37 @@ class AppViewModel @Inject constructor(
14321440
}
14331441
}
14341442

1443+
private suspend fun estimateMaxAmountRoutingFee() {
1444+
val currentState = _sendUiState.value
1445+
if (currentState.payMethod != SendMethod.LIGHTNING) return
1446+
1447+
val decodedInvoice = currentState.decodedInvoice ?: return
1448+
val bolt11 = decodedInvoice.bolt11
1449+
1450+
val maxSendLightning = walletRepo.balanceState.value.maxSendLightningSats
1451+
if (maxSendLightning == 0uL) {
1452+
_sendUiState.update { it.copy(estimatedRoutingFee = 0uL) }
1453+
return
1454+
}
1455+
1456+
val buffer = 2uL
1457+
val amountToEstimate = maxSendLightning.safe() - buffer.safe()
1458+
1459+
val feeResult = lightningRepo.estimateRoutingFeesForAmount(
1460+
bolt11 = bolt11,
1461+
amountSats = amountToEstimate
1462+
)
1463+
1464+
feeResult.onSuccess { fee ->
1465+
_sendUiState.update {
1466+
it.copy(estimatedRoutingFee = fee + buffer)
1467+
}
1468+
}.onFailure { e ->
1469+
Logger.error("Failed to estimate routing fee for max amount", e, context = TAG)
1470+
_sendUiState.update { it.copy(estimatedRoutingFee = 0uL) }
1471+
}
1472+
}
1473+
14351474
private suspend fun getFeeEstimate(speed: TransactionSpeed? = null): Long {
14361475
val currentState = _sendUiState.value
14371476
return lightningRepo.calculateTotalFee(
@@ -1750,6 +1789,7 @@ data class SendUiState(
17501789
val feeRates: FeeRates? = null,
17511790
val fee: SendFee? = null,
17521791
val fees: Map<FeeRate, Long> = emptyMap(),
1792+
val estimatedRoutingFee: ULong = 0uL,
17531793
)
17541794

17551795
enum class SanityWarning(@StringRes val message: Int, val testTag: String) {
@@ -1810,6 +1850,7 @@ sealed interface SendEvent {
18101850
data object SpeedAndFee : SendEvent
18111851
data object PaymentMethodSwitch : SendEvent
18121852
data class ConfirmAmountWarning(val warning: SanityWarning) : SendEvent
1853+
data object EstimateMaxRoutingFee : SendEvent
18131854
data object DismissAmountWarning : SendEvent
18141855
data object PayConfirmed : SendEvent
18151856
data object ClearPayConfirmation : SendEvent

0 commit comments

Comments
 (0)