diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index c29a7a5b33..fd8e2c1288 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -386,6 +386,18 @@ class DefaultWalletManagersFacade( return if (manager is ExistentialDepositProvider) manager.getExistentialDeposit() else null } + @Deprecated("Will be removed in future") + override suspend fun getDustValue(userWalletId: UserWalletId, network: Network): BigDecimal? { + val blockchain = Blockchain.fromId(network.id.value) + val manager = getOrCreateWalletManager( + userWalletId = userWalletId, + blockchain = blockchain, + derivationPath = network.derivationPath.value, + ) + + return if (manager is ExistentialDepositProvider) manager.dustValue else null + } + @Deprecated("Will be removed in future") override suspend fun getReserveAmount(userWalletId: UserWalletId, network: Network): BigDecimal? { val manager = getOrCreateWalletManager( diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt index d8647329a8..818989d9c9 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt @@ -145,6 +145,9 @@ interface WalletManagersFacade { @Deprecated("Will be removed in future") suspend fun getExistentialDeposit(userWalletId: UserWalletId, network: Network): BigDecimal? + @Deprecated("Will be removed in future") + suspend fun getDustValue(userWalletId: UserWalletId, network: Network): BigDecimal? + /** * Returns reserve amount which is required to create an account * diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt index fa5e911138..45ee2c0517 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt @@ -315,6 +315,10 @@ internal class DefaultSwapRepository @Inject constructor( return walletManagersFacade.getExistentialDeposit(userWalletId, network) } + override suspend fun getDustValue(userWalletId: UserWalletId, network: Network): BigDecimal? { + return walletManagersFacade.getDustValue(userWalletId, network) + } + private fun parseTxDetails(txDetailsJson: String): TxDetails? { return try { txDetailsMoshiAdapter.fromJson(txDetailsJson) diff --git a/features/swap/domain/api/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt b/features/swap/domain/api/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt index 31ab424e2b..727d622c7d 100644 --- a/features/swap/domain/api/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt +++ b/features/swap/domain/api/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt @@ -76,4 +76,6 @@ interface SwapRepository { fun getNativeTokenForNetwork(networkId: String): CryptoCurrency suspend fun getExistentialDeposit(userWalletId: UserWalletId, network: Network): BigDecimal? + + suspend fun getDustValue(userWalletId: UserWalletId, network: Network): BigDecimal? } \ No newline at end of file diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/Warning.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/Warning.kt index b52f4c5586..d7f7790479 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/Warning.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/Warning.kt @@ -5,4 +5,6 @@ import java.math.BigDecimal sealed class Warning { data class ExistentialDepositWarning(val existentialDeposit: BigDecimal) : Warning() + + data class MinAmountWarning(val dustValue: BigDecimal) : Warning() } \ No newline at end of file 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 2ae0505504..b4d1266899 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 @@ -31,6 +31,7 @@ import com.tangem.lib.crypto.UserWalletManager import com.tangem.lib.crypto.models.* import com.tangem.lib.crypto.models.transactions.SendTxResult import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.isNullOrZero import com.tangem.utils.toFiatString import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.firstOrNull @@ -351,7 +352,8 @@ internal class SwapInteractorImpl @Inject constructor( ) } - private suspend fun manageWarnings(fromToken: CryptoCurrency, amount: SwapAmount): List { + private suspend fun manageWarnings(fromTokenStatus: CryptoCurrencyStatus, amount: SwapAmount): List { + val fromToken = fromTokenStatus.currency val userWalletId = getSelectedWallet()?.walletId ?: return emptyList() val existentialDeposit = repository.getExistentialDeposit(userWalletId, fromToken.network) val warnings = mutableListOf() @@ -364,6 +366,12 @@ internal class SwapInteractorImpl @Inject constructor( warnings.add(Warning.ExistentialDepositWarning(existentialDeposit)) } } + val dust = repository.getDustValue(userWalletId, fromToken.network) + val balance = fromTokenStatus.value.amount ?: BigDecimal.ZERO + val isLowerThenDust = amount.value < dust || balance - amount.value < dust + if (dust != null && !balance.isNullOrZero() && isLowerThenDust) { + warnings.add(Warning.MinAmountWarning(dust)) + } return warnings } @@ -793,7 +801,7 @@ internal class SwapInteractorImpl @Inject constructor( txFeeState = txFee, exchangeProviderType = exchangeProviderType, ).copy( - warnings = manageWarnings(fromToken.currency, amount), + warnings = manageWarnings(fromToken, amount), ) when (exchangeProviderType) { @@ -958,7 +966,7 @@ internal class SwapInteractorImpl @Inject constructor( ) swapState.copy( permissionState = PermissionDataState.Empty, - warnings = manageWarnings(fromToken.currency, amount), + warnings = manageWarnings(fromToken, amount), preparedSwapConfigState = PreparedSwapConfigState( isAllowedToSpend = true, isBalanceEnough = isBalanceIncludeFeeEnough, diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt index 38c34d868f..6d9915fa88 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt @@ -116,7 +116,7 @@ sealed interface SwapWarning { * @property priceImpact in format = 10 (means 10%) */ data class HighPriceImpact(val priceImpact: Int, val notificationConfig: NotificationConfig) : SwapWarning - data class TooSmallAmountWarning(val notificationConfig: NotificationConfig) : SwapWarning + data class GeneralError(val notificationConfig: NotificationConfig) : SwapWarning data class UnableToCoverFeeWarning(val notificationConfig: NotificationConfig) : SwapWarning data class GeneralWarning(val notificationConfig: NotificationConfig) : SwapWarning data class GeneralInformational(val notificationConfig: NotificationConfig) : SwapWarning 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 f6aa83db47..9e80fad2e7 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 @@ -384,6 +384,23 @@ internal class StateBuilder( ), ) } + is Warning.MinAmountWarning -> { + warnings.add( + SwapWarning.GeneralError( + NotificationConfig( + title = resourceReference(R.string.send_notification_invalid_amount_title), + subtitle = resourceReference( + R.string.send_notification_invalid_minimum_amount_text, + wrappedList( + it.dustValue.toPlainString(), + it.dustValue.toPlainString(), + ), + ), + iconResId = R.drawable.ic_alert_circle_24, + ), + ), + ) + } } } } @@ -523,7 +540,7 @@ internal class StateBuilder( private fun getWarningForError(dataError: DataError, fromToken: CryptoCurrency): SwapWarning { return when (dataError) { - is DataError.ExchangeTooSmallAmountError -> SwapWarning.TooSmallAmountWarning( + is DataError.ExchangeTooSmallAmountError -> SwapWarning.GeneralError( notificationConfig = NotificationConfig( title = resourceReference( id = R.string.warning_express_too_minimal_amount_title, diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt index 277c67246d..0badf967fd 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt @@ -356,7 +356,7 @@ private fun SwapWarnings(warnings: List) { config = warning.notificationConfig, ) } - is SwapWarning.TooSmallAmountWarning -> { + is SwapWarning.GeneralError -> { Notification( config = warning.notificationConfig, iconTint = TangemTheme.colors.icon.warning,