From a6ec3453dd98239d56c3917e00ee85a6eaa18472 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 14 Oct 2025 19:52:46 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../ui/notifications/NotificationsFactory.kt | 18 +++- .../feeSelector/utils/FeeCalculationUtils.kt | 3 +- .../v2/send/confirm/model/SendConfirmModel.kt | 1 + .../notifications/model/NotificationsModel.kt | 90 ++++++++++--------- .../model/YieldSupplyNotificationsModel.kt | 1 + 5 files changed, 69 insertions(+), 44 deletions(-) diff --git a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt index 87e98e25c4..4afee30930 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt @@ -44,10 +44,12 @@ object NotificationsFactory { } } + @Suppress("LongParameterList") fun MutableList.addFeeUnreachableNotification( tokenStatus: CryptoCurrencyStatus, coinStatus: CryptoCurrencyStatus, feeError: GetFeeError?, + dustValue: BigDecimal?, onReload: () -> Unit, onClick: (currency: CryptoCurrency) -> Unit, ) { @@ -70,7 +72,16 @@ object NotificationsFactory { ) is GetFeeError.BlockchainErrors.SuiOneCoinRequired -> add(NotificationUM.Sui.NotEnoughCoinForTokenTransaction) - is GetFeeError.DataError, + is GetFeeError.DataError -> when (feeError.cause) { + BlockchainSdkError.TransactionDustChangeError -> add( + NotificationUM.Error.MinimumAmountError( + amount = dustValue.format { crypto(tokenStatus.currency) }, + ), + ) + else -> add( + NotificationUM.Warning.NetworkFeeUnreachable(onReload), + ) + } is GetFeeError.UnknownError, -> add( NotificationUM.Warning.NetworkFeeUnreachable(onReload), @@ -358,6 +369,11 @@ object NotificationsFactory { is BlockchainSdkError.Solana.DestinationRentExemption -> addRentExemptionDestinationNotification( rentExemptionAmount = validationError.rentAmount, ) + is BlockchainSdkError.TransactionDustChangeError -> add( + NotificationUM.Error.MinimumAmountError( + amount = dustValue.format { crypto(cryptoCurrency) }, + ), + ) null, -> minAdaValue?.let { add( diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/utils/FeeCalculationUtils.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/utils/FeeCalculationUtils.kt index 3c251c609b..3d2db932dc 100644 --- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/utils/FeeCalculationUtils.kt +++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/utils/FeeCalculationUtils.kt @@ -21,9 +21,10 @@ object FeeCalculationUtils { isAmountSubtractAvailable: Boolean, cryptoCurrencyStatus: CryptoCurrencyStatus, amountValue: BigDecimal, - feeValue: BigDecimal, + feeValue: BigDecimal?, reduceAmountBy: BigDecimal, ): BigDecimal { + if (feeValue == null || feeValue.isZero()) return amountValue val balance = cryptoCurrencyStatus.value.amount ?: return amountValue val isFeeCoverage = checkFeeCoverage( isSubtractAvailable = isAmountSubtractAvailable, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt index 414a66531b..647af4a902 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt @@ -161,6 +161,7 @@ internal class SendConfirmModel @Inject constructor( fun updateState(state: SendUM) { _uiState.value = state + onFeeReload() updateConfirmNotifications() } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/notifications/model/NotificationsModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/notifications/model/NotificationsModel.kt index 73649cccf8..23e1fec6c3 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/notifications/model/NotificationsModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/notifications/model/NotificationsModel.kt @@ -120,46 +120,8 @@ internal class NotificationsModel @Inject constructor( buildNotifications() } - private suspend fun buildNotifications() { - val notifications = buildList { - addFeeUnreachableNotification( - tokenStatus = cryptoCurrencyStatus, - coinStatus = feeCryptoCurrencyStatus, - feeError = notificationData.feeError, - onReload = params.callback::onFeeReload, - onClick = ::showTokenDetails, - ) - addDomainNotifications() - } - - notificationsUpdateTrigger.callbackHasError(notifications.any { it is NotificationUM.Error }) - - _uiState.value = notifications.toImmutableList() - } - - private fun showTokenDetails(currency: CryptoCurrency) { - appRouter.pop { isSuccess -> - if (isSuccess) { - appRouter.push( - AppRoute.CurrencyDetails( - userWalletId = userWalletId, - currency = currency, - ), - ) - } - } - } - - private suspend fun MutableList.addDomainNotifications() = with(notificationData) { - val balance = cryptoCurrencyStatus.value.amount ?: return - val feeValue = fee?.amount?.value ?: return - val isFeeCoverage = checkFeeCoverage( - isSubtractAvailable = isAmountSubtractAvailable, - balance = balance, - amountValue = amountValue, - feeValue = feeValue, - reduceAmountBy = reduceAmountBy, - ) + private suspend fun buildNotifications() = with(notificationData) { + val feeValue = fee?.amount?.value val sendingAmount = checkAndCalculateSubtractedAmount( isAmountSubtractAvailable = isAmountSubtractAvailable, cryptoCurrencyStatus = cryptoCurrencyStatus, @@ -180,6 +142,50 @@ internal class NotificationsModel @Inject constructor( feeCurrencyBalanceAfterTransaction = feeCurrencyBalanceAfterTransaction, ) + val notifications = buildList { + addFeeUnreachableNotification( + tokenStatus = cryptoCurrencyStatus, + coinStatus = feeCryptoCurrencyStatus, + feeError = notificationData.feeError, + dustValue = currencyCheck.dustValue, + onReload = params.callback::onFeeReload, + onClick = ::showTokenDetails, + ) + addDomainNotifications(currencyCheck = currencyCheck, sendingAmount = sendingAmount) + } + + notificationsUpdateTrigger.callbackHasError(notifications.any { it is NotificationUM.Error }) + + _uiState.value = notifications.toImmutableList() + } + + private fun showTokenDetails(currency: CryptoCurrency) { + appRouter.pop { isSuccess -> + if (isSuccess) { + appRouter.push( + AppRoute.CurrencyDetails( + userWalletId = userWalletId, + currency = currency, + ), + ) + } + } + } + + private suspend fun MutableList.addDomainNotifications( + currencyCheck: CryptoCurrencyCheck, + sendingAmount: BigDecimal, + ) = with(notificationData) { + val balance = cryptoCurrencyStatus.value.amount ?: return + val feeValue = fee?.amount?.value ?: return + val isFeeCoverage = checkFeeCoverage( + isSubtractAvailable = isAmountSubtractAvailable, + balance = balance, + amountValue = amountValue, + feeValue = feeValue, + reduceAmountBy = reduceAmountBy, + ) + addErrorNotifications( sendingAmount = sendingAmount, feeValue = feeValue, @@ -198,10 +204,10 @@ internal class NotificationsModel @Inject constructor( addInfoNotifications() } - private fun getFeeCurrencyBalanceAfterTx(sendingAmount: BigDecimal, feeValue: BigDecimal): BigDecimal? { + private fun getFeeCurrencyBalanceAfterTx(sendingAmount: BigDecimal, feeValue: BigDecimal?): BigDecimal? { val sendingCurrencyBalance = cryptoCurrencyStatus.value as? CryptoCurrencyStatus.Loaded val feeCurrencyBalance = feeCryptoCurrencyStatus.value as? CryptoCurrencyStatus.Loaded - if (feeCryptoCurrencyStatus.value !is CryptoCurrencyStatus.Loaded) return null + if (feeCryptoCurrencyStatus.value !is CryptoCurrencyStatus.Loaded || feeValue == null) return null return when { feeCryptoCurrencyStatus == cryptoCurrencyStatus -> sendingCurrencyBalance?.let { it.amount - sendingAmount - feeValue diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/notifications/model/YieldSupplyNotificationsModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/notifications/model/YieldSupplyNotificationsModel.kt index be0223b21d..464eaaec8b 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/notifications/model/YieldSupplyNotificationsModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/notifications/model/YieldSupplyNotificationsModel.kt @@ -68,6 +68,7 @@ internal class YieldSupplyNotificationsModel @Inject constructor( coinStatus = feeCryptoCurrencyStatus, feeError = data.feeError, onClick = ::openTokenDetails, + dustValue = null, onReload = params.callback::onFeeReload, ) }