diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt index bf4385fd78..709bd1f9bc 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt @@ -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, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeCustomFieldConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeCustomFieldConverter.kt index 16a8666b36..23571ac345 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeCustomFieldConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeCustomFieldConverter.kt @@ -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 + } + }, + ) } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/custom/KaspaCustomFeeConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/custom/KaspaCustomFeeConverter.kt index a85d1bb97e..769bd3ee75 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/custom/KaspaCustomFeeConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/custom/KaspaCustomFeeConverter.kt @@ -95,6 +95,40 @@ internal class KaspaCustomFeeConverter( }.toImmutableList() } + fun tryAutoFixValue( + minimumFee: Fee.Kaspa, + customValues: ImmutableList, + ): ImmutableList { + 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 } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index 14b94f1d08..cdd155d645 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -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() },