Updated on 2026-08-14

This commit is contained in:
Tangem 2024-12-12 02:39:36 +05:00
parent 1ec13d5e04
commit b2b3114759
4 changed files with 91 additions and 3 deletions

View file

@ -166,6 +166,31 @@ internal class FeeStateFactory(
)
}
fun tryAutoFixCustomFeeValue(): SendUiState {
val state = currentStateProvider()
val isEditState = stateRouterProvider().isEditState
val feeState = state.getFeeState(isEditState) ?: return state
val feeSelectorState = feeState.feeSelectorState as? FeeSelectorState.Content ?: return state
return when (feeSelectorState.selectedFee) {
FeeType.Slow,
FeeType.Market,
FeeType.Fast,
-> state
FeeType.Custom -> {
val updatedFeeSelectorState = customFeeFieldConverter.tryAutoFixValue(feeSelectorState)
val fee = feeConverter.convert(updatedFeeSelectorState)
return state.copyWrapped(
isEditState = isEditState,
feeState = feeState.copy(
feeSelectorState = updatedFeeSelectorState,
fee = fee,
),
)
}
}
}
private fun isPrimaryButtonEnabled(
feeState: SendStates.FeeState,
notifications: ImmutableList<NotificationUM>,

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.impl.presentation.state.fee
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.StateRouter
@ -78,4 +79,19 @@ internal class SendFeeCustomFieldConverter(
else -> feeSelectorState.customValues
},
)
fun tryAutoFixValue(feeSelectorState: FeeSelectorState.Content) = feeSelectorState.copy(
customValues = when (feeSelectorState.fees) {
is TransactionFee.Choosable -> feeSelectorState.fees.minimum
is TransactionFee.Single -> feeSelectorState.fees.normal
}.let {
when (it) {
is Fee.Kaspa -> kaspaCustomFeeConverter.tryAutoFixValue(
minimumFee = it,
customValues = feeSelectorState.customValues,
)
else -> feeSelectorState.customValues
}
},
)
}

View file

@ -95,6 +95,40 @@ internal class KaspaCustomFeeConverter(
}.toImmutableList()
}
fun tryAutoFixValue(
minimumFee: Fee.Kaspa,
customValues: ImmutableList<SendTextField.CustomFee>,
): ImmutableList<SendTextField.CustomFee> {
val mutableCustomValues = customValues.toMutableList()
val minimumFeeAmountValue = minimumFee.amount.value
return mutableCustomValues.apply {
// check that there is reveal transaction info (= krc-20 token transfer)
// return without changes otherwise
if (minimumFee.revealTransactionFee != null && minimumFeeAmountValue != null) {
getOrNull(FEE_AMOUNT_INDEX)?.let {
val valueDecimal = it.value.parseToBigDecimal(it.decimals)
// krc-20 transaction will be failed if custom fee value is less than minimum,
// so we set value to minimum in this case
if (valueDecimal < minimumFee.amount.value) {
val fixedValue = minimumFeeAmountValue.parseBigDecimal(it.decimals)
set(
FEE_AMOUNT_INDEX,
it.copy(
value = fixedValue,
label = getFiatReference(
rate = feeCryptoCurrencyStatusProvider()?.value?.fiatRate,
value = valueDecimal,
appCurrency = appCurrencyProvider(),
),
),
)
}
}
}
}.toImmutableList()
}
private companion object {
private const val FEE_AMOUNT_INDEX = 0
}

View file

@ -513,13 +513,12 @@ internal class SendViewModel @Inject constructor(
when (currentState.type) {
SendUiStateType.Fee,
SendUiStateType.EditFee,
-> if (onFeeNext()) return
-> if (onFeeNextIntercept(isFromEdit)) return
SendUiStateType.Amount,
SendUiStateType.EditAmount,
-> loadFee()
else -> Unit
}
stateRouter.onNextClick()
}
@ -580,9 +579,23 @@ internal class SendViewModel @Inject constructor(
override fun onTokenDetailsClick(currency: CryptoCurrency) = innerRouter.openTokenDetails(userWalletId, currency)
private fun onFeeNext(): Boolean {
private fun onFeeNextIntercept(isFromEdit: Boolean): Boolean {
val feeState = uiState.value.getFeeState(stateRouter.isEditState)
val feeSelectorState = feeState?.feeSelectorState as? FeeSelectorState.Content ?: return false
if (isFromEdit) {
// in some cases, if it's possible to fix incorrect fee automatically,
// do it, update current state and go let continue the flow
val fixedState = feeStateFactory.tryAutoFixCustomFeeValue()
if (fixedState.editFeeState != feeState) {
uiState.value = fixedState
val currentState = stateRouter.currentState.value
uiState.value = stateFactory.syncEditStates(isFromEdit = isFromEdit)
sendScreenAnalyticSender.send(currentState.type, uiState.value)
return false
}
}
if (checkIfFeeTooLow(feeSelectorState)) {
uiState.value = eventStateFactory.getFeeTooLowAlert(
onConsume = { uiState.value = eventStateFactory.onConsumeEventState() },