diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index a70e9f4958..929ea8ae82 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -352,11 +352,26 @@ internal class SwapInteractorImpl @Inject constructor( ) } - private suspend fun manageWarnings(fromTokenStatus: CryptoCurrencyStatus, amount: SwapAmount): List { + private suspend fun manageWarnings( + fromTokenStatus: CryptoCurrencyStatus, + amount: SwapAmount, + feeState: TxFeeState, + ): List { val fromToken = fromTokenStatus.currency val userWalletId = getSelectedWallet()?.walletId ?: return emptyList() - val existentialDeposit = repository.getExistentialDeposit(userWalletId, fromToken.network) val warnings = mutableListOf() + manageExistentialDepositWarning(warnings, userWalletId, amount, fromToken) + manageDustWarning(warnings, feeState, userWalletId, fromTokenStatus, amount) + return warnings + } + + private suspend fun manageExistentialDepositWarning( + warnings: MutableList, + userWalletId: UserWalletId, + amount: SwapAmount, + fromToken: CryptoCurrency, + ) { + val existentialDeposit = repository.getExistentialDeposit(userWalletId, fromToken.network) if (existentialDeposit != null) { val nativeBalance = userWalletManager.getNativeTokenBalance( fromToken.network.backendId, @@ -366,15 +381,33 @@ internal class SwapInteractorImpl @Inject constructor( warnings.add(Warning.ExistentialDepositWarning(existentialDeposit)) } } - val dust = repository.getDustValue(userWalletId, fromToken.network) + } + + private suspend fun manageDustWarning( + warnings: MutableList, + feeState: TxFeeState, + userWalletId: UserWalletId, + fromTokenStatus: CryptoCurrencyStatus, + amount: SwapAmount, + ) { + val fee = when (feeState) { + TxFeeState.Empty -> BigDecimal.ZERO + is TxFeeState.MultipleFeeState -> feeState.priorityFee.feeValue + is TxFeeState.SingleFeeState -> feeState.fee.feeValue + } + val dust = repository.getDustValue(userWalletId, fromTokenStatus.currency.network) val balance = fromTokenStatus.value.amount ?: BigDecimal.ZERO - if (dust != null && !balance.isNullOrZero()) { - val isLowerThenDust = amount.value < dust || balance - amount.value < dust - if (isLowerThenDust) { + if (dust != null && + !balance.isNullOrZero() && + amount.value < balance + ) { + val change = balance - (amount.value + fee) + val isChangeLowerThanDust = change < dust && change != BigDecimal.ZERO + val isShowWarning = amount.value + fee < dust || isChangeLowerThanDust + if (isShowWarning) { warnings.add(Warning.MinAmountWarning(dust)) } } - return warnings } override suspend fun onSwap( @@ -803,7 +836,7 @@ internal class SwapInteractorImpl @Inject constructor( txFeeState = txFee, exchangeProviderType = exchangeProviderType, ).copy( - warnings = manageWarnings(fromToken, amount), + warnings = manageWarnings(fromToken, amount, txFee), ) when (exchangeProviderType) { @@ -968,7 +1001,7 @@ internal class SwapInteractorImpl @Inject constructor( ) swapState.copy( permissionState = PermissionDataState.Empty, - warnings = manageWarnings(fromToken, amount), + warnings = manageWarnings(fromToken, amount, txFeeState), preparedSwapConfigState = PreparedSwapConfigState( isAllowedToSpend = true, isBalanceEnough = isBalanceIncludeFeeEnough, diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index 9e80fad2e7..6572e025e2 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -254,7 +254,7 @@ internal class StateBuilder( ), fee = feeState, swapButton = SwapButton( - enabled = getSwapButtonEnabled(quoteModel.preparedSwapConfigState), + enabled = getSwapButtonEnabled(quoteModel), onClick = actions.onSwapClick, ), changeCardsButtonState = if (isReverseSwapPossible) { @@ -425,8 +425,12 @@ internal class StateBuilder( } } - private fun getSwapButtonEnabled(preparedSwapConfigState: PreparedSwapConfigState): Boolean { + private fun getSwapButtonEnabled(quoteModel: SwapState.QuotesLoadedState): Boolean { + val preparedSwapConfigState = quoteModel.preparedSwapConfigState + // check has has outgoing transaction if (preparedSwapConfigState.hasOutgoingTransaction) return false + // check has MinAmountWarning warning + if (quoteModel.warnings.filterIsInstance().isNotEmpty()) return false return when (preparedSwapConfigState.includeFeeInAmount) { IncludeFeeInAmount.BalanceNotEnough -> false IncludeFeeInAmount.Excluded ->