Updated on 2026-08-14

This commit is contained in:
Tangem 2025-04-24 12:34:12 +03:00
parent 632b0dd663
commit 4a840b127f
4 changed files with 54 additions and 14 deletions

View file

@ -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,

View file

@ -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<NotificationUM>.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)
}
}

View file

@ -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<NotificationUM>.addExitInfoNotifications() {
private fun MutableList<NotificationUM>.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<NotificationUM>.addEnterInfoNotifications(