Updated on 2026-08-14

This commit is contained in:
Tangem 2025-03-11 12:31:07 +05:00
parent c2ef661a16
commit 72d9b99348
7 changed files with 26 additions and 27 deletions

View file

@ -46,6 +46,14 @@ data class Yield(
val address: AddressArgument, val address: AddressArgument,
val additionalAddresses: Map<ArgType, AddressArgument>? = null, val additionalAddresses: Map<ArgType, AddressArgument>? = null,
) )
val isPartialAmountDisabled: Boolean
get() {
val enterAmount = args[ArgType.AMOUNT] ?: return false
val min = enterAmount.minimum ?: return false
val max = enterAmount.maximum ?: return false
return min.signum() == -1 && max.signum() == -1
}
} }
enum class ArgType { enum class ArgType {

View file

@ -5,6 +5,7 @@ sealed class StakingActionCommonType {
data class Enter(val skipEnterAmount: Boolean) : StakingActionCommonType() data class Enter(val skipEnterAmount: Boolean) : StakingActionCommonType()
data class Exit(val partiallyUnstakeDisabled: Boolean) : StakingActionCommonType() data class Exit(val partiallyUnstakeDisabled: Boolean) : StakingActionCommonType()
sealed class Pending : StakingActionCommonType() { sealed class Pending : StakingActionCommonType() {
data class Stake(val skipEnterAmount: Boolean) : Pending()
data object Restake : Pending() data object Restake : Pending()
data object Rewards : Pending() data object Rewards : Pending()
data object Other : Pending() data object Other : Pending()

View file

@ -66,7 +66,6 @@ import com.tangem.features.staking.impl.presentation.state.transformers.validato
import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalculateSubtractedAmount import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalculateSubtractedAmount
import com.tangem.features.staking.impl.presentation.state.utils.isSingleAction import com.tangem.features.staking.impl.presentation.state.utils.isSingleAction
import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstakeAction import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstakeAction
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.Provider import com.tangem.utils.Provider
import com.tangem.utils.coroutines.* import com.tangem.utils.coroutines.*
import com.tangem.utils.extensions.isSingleItem import com.tangem.utils.extensions.isSingleItem
@ -250,7 +249,7 @@ internal class StakingModel @Inject constructor(
stakingAllowance = stakingAllowance, stakingAllowance = stakingAllowance,
yieldArgs = yield.args, yieldArgs = yield.args,
).let(::add) ).let(::add)
if (BlockchainUtils.isSkipAmountEnter(uiState.value.cryptoCurrencyBlockchainId)) { if (yield.args.enter.isPartialAmountDisabled) {
ValidatorSelectChangeTransformer( ValidatorSelectChangeTransformer(
selectedValidator = yield.preferredValidators.firstOrNull(), selectedValidator = yield.preferredValidators.firstOrNull(),
yield = yield, yield = yield,
@ -859,7 +858,7 @@ internal class StakingModel @Inject constructor(
} }
private suspend fun setupIsAnyTokenStaked() { private suspend fun setupIsAnyTokenStaked() {
isAnyTokenStaked = isAnyTokenStakedUseCase(userWalletId).getOrNull() ?: false isAnyTokenStaked = isAnyTokenStakedUseCase(userWalletId).getOrNull() == true
} }
private fun subscribeOnCurrencyStatusUpdates() { private fun subscribeOnCurrencyStatusUpdates() {

View file

@ -32,7 +32,9 @@ internal class StakingStateRouter(
StakingActionCommonType.Pending.Other, StakingActionCommonType.Pending.Other,
StakingActionCommonType.Pending.Rewards, StakingActionCommonType.Pending.Rewards,
-> showConfirmation() -> showConfirmation()
StakingActionCommonType.Pending.Restake -> showRestakeValidators() is StakingActionCommonType.Pending.Stake,
StakingActionCommonType.Pending.Restake,
-> showRestakeValidators()
} }
StakingStep.RestakeValidator, StakingStep.RestakeValidator,
StakingStep.RewardsValidators, StakingStep.RewardsValidators,

View file

@ -11,8 +11,6 @@ import com.tangem.features.staking.impl.presentation.state.*
import com.tangem.features.staking.impl.presentation.state.utils.isCompositePendingActions import com.tangem.features.staking.impl.presentation.state.utils.isCompositePendingActions
import com.tangem.features.staking.impl.presentation.state.utils.isTronStakedBalance import com.tangem.features.staking.impl.presentation.state.utils.isTronStakedBalance
import com.tangem.lib.crypto.BlockchainUtils import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.lib.crypto.BlockchainUtils.isSkipAmountEnter
import com.tangem.utils.extensions.isPositive
import com.tangem.utils.transformer.Transformer import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -46,12 +44,12 @@ internal class SetConfirmationStateInitTransformer(
override fun transform(prevState: StakingUiState): StakingUiState { override fun transform(prevState: StakingUiState): StakingUiState {
val actionType = when { val actionType = when {
isEnter -> StakingActionCommonType.Enter( isEnter -> StakingActionCommonType.Enter(
skipEnterAmount = isSkipAmountEnter(prevState.cryptoCurrencyBlockchainId), skipEnterAmount = yieldArgs.enter.isPartialAmountDisabled,
) )
isImplicitExit || isExplicitExit -> StakingActionCommonType.Exit(isPartiallyUnstakeDisabled(prevState)) isImplicitExit || isExplicitExit -> StakingActionCommonType.Exit(isPartiallyUnstakeDisabled(prevState))
else -> when (pendingAction?.type) { else -> when (pendingAction?.type) {
StakingActionType.STAKE -> StakingActionCommonType.Enter( StakingActionType.STAKE -> StakingActionCommonType.Pending.Stake(
skipEnterAmount = isSkipAmountEnter(prevState.cryptoCurrencyBlockchainId), skipEnterAmount = yieldArgs.enter.isPartialAmountDisabled,
) )
StakingActionType.UNSTAKE -> StakingActionCommonType.Exit( StakingActionType.UNSTAKE -> StakingActionCommonType.Exit(
partiallyUnstakeDisabled = isPartiallyUnstakeDisabled(prevState), partiallyUnstakeDisabled = isPartiallyUnstakeDisabled(prevState),
@ -80,9 +78,8 @@ internal class SetConfirmationStateInitTransformer(
transactionDoneState = TransactionDoneState.Empty, transactionDoneState = TransactionDoneState.Empty,
isApprovalNeeded = stakingApproval is StakingApproval.Needed, isApprovalNeeded = stakingApproval is StakingApproval.Needed,
allowance = stakingAllowance, allowance = stakingAllowance,
isAmountEditable = actionType is StakingActionCommonType.Enter || isAmountEditable = actionType is StakingActionCommonType.Enter && !actionType.skipEnterAmount ||
actionType is StakingActionCommonType.Exit && actionType is StakingActionCommonType.Exit && !actionType.partiallyUnstakeDisabled,
!actionType.partiallyUnstakeDisabled,
reduceAmountBy = null, reduceAmountBy = null,
pendingAction = pendingAction, pendingAction = pendingAction,
pendingActions = pendingActions.takeIf { isComposePendingActions }, pendingActions = pendingActions.takeIf { isComposePendingActions },
@ -93,14 +90,11 @@ internal class SetConfirmationStateInitTransformer(
private fun isPartiallyUnstakeDisabled(state: StakingUiState): Boolean { private fun isPartiallyUnstakeDisabled(state: StakingUiState): Boolean {
val isSolana = BlockchainUtils.isSolana(state.cryptoCurrencyBlockchainId) val isSolana = BlockchainUtils.isSolana(state.cryptoCurrencyBlockchainId)
val isValidatorPreferred = balanceState?.validator?.preferred == true val isValidatorPreferred = balanceState?.validator?.preferred == true
if (isSolana && !isValidatorPreferred) {
return true
}
val exitArgs = yieldArgs.exit ?: return false return if (isSolana && !isValidatorPreferred) {
val exitAmount = exitArgs.args[Yield.Args.ArgType.AMOUNT] ?: return false true
val min = exitAmount.minimum ?: return false } else {
val max = exitAmount.maximum ?: return false yieldArgs.exit?.isPartialAmountDisabled == true
return !min.isPositive() && !max.isPositive() }
} }
} }

View file

@ -17,7 +17,8 @@ internal class ValidatorSelectChangeTransformer(
val validatorState = prevState.validatorState as? StakingStates.ValidatorState.Data val validatorState = prevState.validatorState as? StakingStates.ValidatorState.Data
val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
val isRestake = prevState.actionType == StakingActionCommonType.Pending.Restake val isRestake = prevState.actionType == StakingActionCommonType.Pending.Restake ||
prevState.actionType is StakingActionCommonType.Pending.Stake
val isEnter = prevState.actionType is StakingActionCommonType.Enter val isEnter = prevState.actionType is StakingActionCommonType.Enter
val isFromInfoScreen = prevState.currentStep == StakingStep.InitialInfo val isFromInfoScreen = prevState.currentStep == StakingStep.InitialInfo
val isVoteLocked = confirmationState?.pendingAction?.type == StakingActionType.VOTE_LOCKED val isVoteLocked = confirmationState?.pendingAction?.type == StakingActionType.VOTE_LOCKED

View file

@ -144,12 +144,6 @@ object BlockchainUtils {
return blockchain != Blockchain.Cardano return blockchain != Blockchain.Cardano
} }
fun isSkipAmountEnter(blockchainId: String): Boolean {
val blockchain = Blockchain.fromId(blockchainId)
return blockchain == Blockchain.Cardano
}
private fun getNetworkStandardName(blockchain: Blockchain): String { private fun getNetworkStandardName(blockchain: Blockchain): String {
return when (blockchain) { return when (blockchain) {
Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20" Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20"