diff --git a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt index d546442104..0a79dbba45 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt @@ -73,6 +73,11 @@ sealed class NotificationUM(val config: NotificationConfig) { ), ) + data object TonStakingExtraFeeError : Error( + title = resourceReference(R.string.staking_notification_ton_extra_reserve_title), + subtitle = resourceReference(R.string.staking_notification_ton_extra_reserve_is_required), + ) + data class TokenExceedsBalance( val networkIconId: Int, val currencyName: String, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt index da6dc0fcff..edd38e289e 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/BalanceItemConverter.kt @@ -17,7 +17,6 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.staking.impl.R import com.tangem.features.staking.impl.presentation.state.BalanceState import com.tangem.lib.crypto.BlockchainUtils -import com.tangem.lib.crypto.BlockchainUtils.isTon import com.tangem.utils.Provider import com.tangem.utils.converter.Converter import com.tangem.utils.extensions.orZero @@ -66,7 +65,7 @@ internal class BalanceItemConverter( ), rawCurrencyId = value.rawCurrencyId, pendingActions = value.pendingActions.toPersistentList(), - isClickable = value.isClickable(), + isClickable = value.type.isClickable() && !value.isPending, isPending = value.isPending, ) } @@ -84,14 +83,6 @@ internal class BalanceItemConverter( } } - private fun BalanceItem.isClickable(): Boolean { - val networkId = cryptoCurrencyStatus.currency.network.id.value - return when { - isTon(networkId) -> pendingActions.any { it.type == StakingActionType.WITHDRAW } - else -> this.type.isClickable() && !this.isPending - } - } - private fun BalanceType.getTitle(validatorName: String?) = when (this) { BalanceType.PREPARING, BalanceType.STAKED, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt index f301a048e9..4774ef7850 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt @@ -11,6 +11,7 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addRentExemptionN import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountErrorNotification import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification import com.tangem.core.ui.extensions.networkIconResId +import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.staking.model.stakekit.StakingError @@ -22,6 +23,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning import com.tangem.domain.transaction.error.GetFeeError +import com.tangem.features.staking.impl.R import com.tangem.features.staking.impl.presentation.state.FeeState import com.tangem.features.staking.impl.presentation.state.StakingNotification import com.tangem.features.staking.impl.presentation.state.StakingStates @@ -29,6 +31,7 @@ import com.tangem.features.staking.impl.presentation.state.StakingUiState import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalculateSubtractedAmount import com.tangem.features.staking.impl.presentation.state.utils.checkFeeCoverage import com.tangem.lib.crypto.BlockchainUtils +import com.tangem.lib.crypto.BlockchainUtils.isTon import com.tangem.utils.Provider import com.tangem.utils.extensions.orZero import com.tangem.utils.transformer.Transformer @@ -175,6 +178,9 @@ internal class AddStakingNotificationsTransformer( cryptoCurrencyStatus = cryptoCurrencyStatus, onClick = prevState.clickIntents::openTokenDetails, ) + addTonUnstakeNotification( + actionType = prevState.actionType, + ) addExceedsBalanceNotification( cryptoCurrencyWarning = currencyWarning, cryptoCurrencyStatus = cryptoCurrencyStatus, @@ -246,7 +252,7 @@ internal class AddStakingNotificationsTransformer( cryptoCurrencyStatus: CryptoCurrencyStatus, onClick: (CryptoCurrency) -> Unit, ) { - val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO + val balance = cryptoCurrencyStatus.value.amount.orZero() if (!isSubtractionAvailable) return val showNotification = sendingAmount + feeAmount > balance @@ -269,4 +275,25 @@ internal class AddStakingNotificationsTransformer( add(notification) } } + + private fun MutableList.addTonUnstakeNotification(actionType: StakingActionCommonType) { + val amount = cryptoCurrencyStatusProvider().value.amount.orZero() + val cryptoCurrencyNetworkIdValue = cryptoCurrencyStatusProvider().currency.network.id.value + + if (isTon(cryptoCurrencyNetworkIdValue) && actionType !is StakingActionCommonType.Enter) { + val notification = if (amount < TON_BALANCE_EXTRA_FEE_THRESHOLD) { + NotificationUM.Error.TonStakingExtraFeeError + } else { + StakingNotification.Info.Ordinary( + title = resourceReference(R.string.staking_notification_ton_extra_reserve_title), + text = resourceReference(R.string.staking_notification_ton_extra_reserve_info), + ) + } + add(notification) + } + } + + private companion object { + val TON_BALANCE_EXTRA_FEE_THRESHOLD = BigDecimal(0.2) + } } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt index dbf10dc2b0..2fe83cd25c 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt @@ -11,11 +11,13 @@ import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.staking.model.stakekit.action.StakingActionType import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.staking.impl.R +import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState import com.tangem.features.staking.impl.presentation.state.StakingNotification import com.tangem.features.staking.impl.presentation.state.StakingStates import com.tangem.features.staking.impl.presentation.state.StakingUiState import com.tangem.lib.crypto.BlockchainUtils.isCardano import com.tangem.lib.crypto.BlockchainUtils.isCosmos +import com.tangem.lib.crypto.BlockchainUtils.isTon import com.tangem.lib.crypto.BlockchainUtils.isTron import com.tangem.utils.Provider import com.tangem.utils.extensions.isZero @@ -46,7 +48,7 @@ internal class StakingInfoNotificationsFactory( when (prevState.actionType) { is StakingActionCommonType.Enter -> addEnterInfoNotifications(sendingAmount, feeValue) - is StakingActionCommonType.Exit -> addExitInfoNotifications() + is StakingActionCommonType.Exit -> addExitInfoNotifications(prevState) is StakingActionCommonType.Pending -> { addCardanoRestakeMinimumAmountNotification(feeValue) addPendingInfoNotifications(prevState) @@ -54,13 +56,15 @@ internal class StakingInfoNotificationsFactory( } } - private fun MutableList.addExitInfoNotifications() { + private fun MutableList.addExitInfoNotifications(prevState: StakingUiState) { val cooldownPeriodDays = yield.metadata.cooldownPeriod?.days + + val cryptoCurrencyNetworkIdValue = cryptoCurrencyStatusProvider().currency.network.id.value if (cooldownPeriodDays != null) { add( StakingNotification.Info.Unstake( cooldownPeriodDays = cooldownPeriodDays, - subtitleRes = if (isCosmos(cryptoCurrencyStatusProvider().currency.network.id.value)) { + subtitleRes = if (isCosmos(cryptoCurrencyNetworkIdValue)) { R.string.staking_notification_unstake_cosmos_text } else { R.string.staking_notification_unstake_text @@ -68,6 +72,19 @@ internal class StakingInfoNotificationsFactory( ), ) } + + val initialInfoState = prevState.initialInfoState as? StakingStates.InitialInfoState.Data + val stakingBalances = (initialInfoState?.yieldBalance as? InnerYieldBalanceState.Data)?.balances + val activeStakesCount = stakingBalances.orEmpty().filter { it.type == BalanceType.STAKED }.size + + if (isTon(cryptoCurrencyNetworkIdValue) && activeStakesCount > 1) { + add( + StakingNotification.Info.Ordinary( + title = resourceReference(R.string.staking_notification_ton_have_to_unstake_all_title), + text = resourceReference(R.string.staking_notification_ton_have_to_unstake_all_text), + ), + ) + } } private fun MutableList.addEnterInfoNotifications(