Skip to content

Commit f669d54

Browse files
authored
Merge pull request #379 from synonymdev/fix/suggested-fee-calc-boost
Minimal fee checks on RBF
2 parents 82d56cd + c8fbcae commit f669d54

File tree

6 files changed

+33
-14
lines changed

6 files changed

+33
-14
lines changed

app/src/main/java/to/bitkit/repositories/LightningRepo.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ import kotlin.time.Duration
6262
import kotlin.time.Duration.Companion.minutes
6363
import kotlin.time.Duration.Companion.seconds
6464

65-
private const val SYNC_TIMEOUT_MS = 15_000L
65+
private const val SYNC_TIMEOUT_MS = 20_000L
6666

6767
@Singleton
6868
class LightningRepo @Inject constructor(

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ fun HomeScreen(
151151
drawerState = drawerState,
152152
latestActivities = latestActivities,
153153
onRefresh = {
154+
activityListViewModel.fetchLatestActivities()
154155
walletViewModel.onPullToRefresh()
155156
homeViewModel.refreshWidgets()
156157
activityListViewModel.syncLdkNodePayments()

app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityDetailScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ fun ActivityDetailScreen(
155155
title = context.getString(R.string.wallet__boost_success_title),
156156
description = context.getString(R.string.wallet__boost_success_msg)
157157
)
158+
listViewModel.fetchLatestActivities()
158159
onCloseClick()
159160
},
160161
onFailure = {

app/src/main/java/to/bitkit/ui/sheets/BoostTransactionSheet.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ fun BoostTransactionSheet(
6969
val haptic = LocalHapticFeedback.current
7070

7171
// Setup activity when component is first created
72-
LaunchedEffect(item) {
72+
LaunchedEffect(Unit) {
7373
viewModel.setupActivity(item)
7474
}
7575

app/src/main/java/to/bitkit/ui/sheets/BoostTransactionViewModel.kt

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,16 @@ class BoostTransactionViewModel @Inject constructor(
4343
private companion object {
4444
const val TAG = "BoostTransactionViewModel"
4545
const val MAX_FEE_PERCENTAGE = 0.5
46-
const val MIN_FEE_RATE = 1UL
4746
const val MAX_FEE_RATE = 100UL
4847
const val FEE_RATE_STEP = 1UL
48+
const val RBF_MIN_INCREASE = 2UL
4949
}
5050

5151
// State variables
5252
private var totalFeeSatsRecommended: ULong = 0U
5353
private var maxTotalFee: ULong = 0U
5454
private var feeRateRecommended: ULong = 0U
55+
private var minFeeRate: ULong = 2U
5556
private var activity: Activity.Onchain? = null
5657

5758
fun setupActivity(activity: Activity.Onchain) {
@@ -71,7 +72,6 @@ class BoostTransactionViewModel @Inject constructor(
7172
private fun initializeFeeEstimates() {
7273
viewModelScope.launch {
7374
try {
74-
val speed = TransactionSpeed.Fast
7575
val activityContent = activity?.v1 ?: run {
7676
handleError("Activity value is null")
7777
return@launch
@@ -85,7 +85,12 @@ class BoostTransactionViewModel @Inject constructor(
8585

8686
// Get recommended fee estimates
8787
val feeRateResult = when (activityContent.txType) {
88-
PaymentType.SENT -> lightningRepo.getFeeRateForSpeed(speed = speed)
88+
PaymentType.SENT -> {
89+
// For RBF, use at least the original fee rate + 2 sat/vbyte, with a minimum of 2 sat/vbyte
90+
minFeeRate = (activityContent.feeRate + RBF_MIN_INCREASE)
91+
lightningRepo.getFeeRateForSpeed(speed = TransactionSpeed.Fast)
92+
}
93+
8994
PaymentType.RECEIVED -> lightningRepo.calculateCpfpFeeRate(activityContent.txId)
9095
}
9196

@@ -96,18 +101,29 @@ class BoostTransactionViewModel @Inject constructor(
96101
val totalFeeResult = lightningRepo.calculateTotalFee(
97102
amountSats = activityContent.value,
98103
utxosToSpend = sortedUtxos,
99-
speed = TransactionSpeed.Custom(feeRateResult.getOrDefault(0u).toUInt()),
104+
speed = TransactionSpeed.Custom(
105+
feeRateResult
106+
.getOrDefault(minFeeRate)
107+
.coerceAtLeast(minFeeRate)
108+
.toUInt()
109+
),
100110
)
101111

102112
when {
103113
totalFeeResult.isSuccess && feeRateResult.isSuccess -> {
104114
totalFeeSatsRecommended = totalFeeResult.getOrThrow()
105-
feeRateRecommended = feeRateResult.getOrThrow()
115+
feeRateRecommended = feeRateResult
116+
.getOrDefault(minFeeRate)
117+
.coerceAtLeast(minFeeRate)
106118

107119
updateUiStateWithFeeData(
108120
totalFee = totalFeeSatsRecommended,
109121
feeRate = feeRateRecommended
110122
)
123+
124+
if (_uiState.value.totalFeeSats >= maxTotalFee) {
125+
setBoostTransactionEffect(BoostTransactionEffects.OnMaxFee)
126+
}
111127
}
112128

113129
else -> {
@@ -124,7 +140,7 @@ class BoostTransactionViewModel @Inject constructor(
124140
private fun updateUiStateWithFeeData(totalFee: ULong, feeRate: ULong) {
125141
val currentFee = activity?.v1?.fee ?: 0u
126142
val isIncreaseEnabled = totalFee < maxTotalFee && feeRate < MAX_FEE_RATE
127-
val isDecreaseEnabled = totalFee > currentFee && feeRate > MIN_FEE_RATE
143+
val isDecreaseEnabled = totalFee > currentFee && feeRate > minFeeRate
128144

129145
_uiState.update {
130146
it.copy(
@@ -220,7 +236,7 @@ class BoostTransactionViewModel @Inject constructor(
220236
val newFeeRate = if (increase) {
221237
(currentFeeRate + FEE_RATE_STEP).coerceAtMost(MAX_FEE_RATE)
222238
} else {
223-
(currentFeeRate - FEE_RATE_STEP).coerceAtLeast(MIN_FEE_RATE)
239+
(currentFeeRate - FEE_RATE_STEP).coerceAtLeast(minFeeRate)
224240
}
225241

226242
if (newFeeRate == currentFeeRate) {
@@ -315,6 +331,7 @@ class BoostTransactionViewModel @Inject constructor(
315331
v1 = currentActivity.copy(
316332
isBoosted = true,
317333
feeRate = _uiState.value.feeRate,
334+
fee = _uiState.value.totalFeeSats,
318335
updatedAt = nowTimestamp().toEpochMilli().toULong()
319336
)
320337
)

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class ActivityListViewModel @Inject constructor(
9292
observeDateRange()
9393
observeSelectedTags()
9494

95-
syncState()
95+
fetchLatestActivities()
9696
}
9797

9898
@OptIn(FlowPreview::class)
@@ -129,7 +129,7 @@ class ActivityListViewModel @Inject constructor(
129129
}
130130
}
131131

132-
private fun syncState() {
132+
fun fetchLatestActivities() {
133133
viewModelScope.launch(bgDispatcher) {
134134
try {
135135
// Fetch latest activities for the home screen
@@ -221,22 +221,22 @@ class ActivityListViewModel @Inject constructor(
221221
fun syncLdkNodePayments() {
222222
viewModelScope.launch {
223223
activityRepo.syncActivities().onSuccess {
224-
syncState()
224+
fetchLatestActivities()
225225
}
226226
}
227227
}
228228

229229
fun generateRandomTestData(count: Int) {
230230
viewModelScope.launch(bgDispatcher) {
231231
coreService.activity.generateRandomTestData(count)
232-
syncState()
232+
fetchLatestActivities()
233233
}
234234
}
235235

236236
fun removeAllActivities() {
237237
viewModelScope.launch(bgDispatcher) {
238238
coreService.activity.removeAll()
239-
syncState()
239+
fetchLatestActivities()
240240
}
241241
}
242242
}

0 commit comments

Comments
 (0)