Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-16 20:41:42 +04:00
parent 50332186fa
commit 5f6767abaf
58 changed files with 85 additions and 717 deletions

View file

@ -60,7 +60,6 @@ import com.tangem.domain.staking.model.stakekit.action.StakingAction
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
import com.tangem.domain.staking.repositories.P2PEthPoolRepository
import com.tangem.domain.staking.toggles.StakingFeatureToggles
import com.tangem.domain.tokens.*
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
@ -156,7 +155,6 @@ internal class StakingModel @Inject constructor(
private val coroutineScope: AppCoroutineScope,
private val innerRouter: InnerStakingRouter,
private val messageSender: UiMessageSender,
private val stakingFeatureToggles: StakingFeatureToggles,
private val appRouter: AppRouter,
) : Model(), StakingClickIntents {
@ -399,8 +397,6 @@ internal class StakingModel @Inject constructor(
minimumTransactionAmount = minimumTransactionAmount,
actionType = uiState.value.actionType,
integration = integration,
isSolanaUnstakeValidationEnabled = stakingFeatureToggles
.isSolanaUnstakeValidationEnabled(),
)
addAll(
@ -663,7 +659,6 @@ internal class StakingModel @Inject constructor(
minimumTransactionAmount = minimumTransactionAmount,
value = value,
integration = integration,
isSolanaUnstakeValidationEnabled = stakingFeatureToggles.isSolanaUnstakeValidationEnabled(),
),
)
checkSumLimitExceeded()
@ -705,7 +700,6 @@ internal class StakingModel @Inject constructor(
minimumTransactionAmount = minimumTransactionAmount,
actionType = uiState.value.actionType,
integration = integration,
isSolanaUnstakeValidationEnabled = stakingFeatureToggles.isSolanaUnstakeValidationEnabled(),
),
)
checkSumLimitExceeded()
@ -1388,7 +1382,6 @@ internal class StakingModel @Inject constructor(
value = amountValue,
minimumTransactionAmount = minimumTransactionAmount,
integration = integration,
isSolanaUnstakeValidationEnabled = stakingFeatureToggles.isSolanaUnstakeValidationEnabled(),
),
)
}

View file

@ -14,7 +14,6 @@ internal class AmountChangeStateTransformer(
private val minimumTransactionAmount: EnterAmountBoundary?,
private val value: String,
private val integration: StakingIntegration,
private val isSolanaUnstakeValidationEnabled: Boolean,
) : Transformer<StakingUiState> {
private val maxEnterAmountConverter = MaxEnterAmountConverter()
@ -44,7 +43,6 @@ internal class AmountChangeStateTransformer(
maxAmount = maxEnterAmount,
integration = integration,
actionType = prevState.actionType,
isSolanaUnstakeValidationEnabled = isSolanaUnstakeValidationEnabled,
).transform(updatedAmountState),
)
}

View file

@ -14,7 +14,6 @@ internal class AmountMaxValueStateTransformer(
private val minimumTransactionAmount: EnterAmountBoundary?,
private val actionType: StakingActionCommonType,
private val integration: StakingIntegration,
private val isSolanaUnstakeValidationEnabled: Boolean,
) : Transformer<StakingUiState> {
private val maxEnterAmountConverter = MaxEnterAmountConverter()
@ -41,7 +40,6 @@ internal class AmountMaxValueStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus,
integration = integration,
actionType = prevState.actionType,
isSolanaUnstakeValidationEnabled = isSolanaUnstakeValidationEnabled,
).transform(updatedAmountState),
)
}

View file

@ -29,7 +29,6 @@ internal class AmountRequirementStateTransformer(
private val maxAmount: EnterAmountBoundary,
private val integration: StakingIntegration,
private val actionType: StakingActionCommonType,
private val isSolanaUnstakeValidationEnabled: Boolean = false,
) : Transformer<AmountState> {
override fun transform(prevState: AmountState): AmountState {
return if (prevState is AmountState.Data) {
@ -105,9 +104,7 @@ internal class AmountRequirementStateTransformer(
)
}
is StakingActionCommonType.Exit -> {
if (isSolanaUnstakeValidationEnabled &&
isSolana(cryptoCurrencyStatus.currency.network.rawId)
) {
if (isSolana(cryptoCurrencyStatus.currency.network.rawId)) {
getSolanaUnstakeError(amount = amountDecimal, staked = maxAmount.amount)
} else {
integration.exitArgs?.amountRequirement?.getError(

View file

@ -29,7 +29,6 @@ import com.tangem.domain.staking.*
import com.tangem.domain.staking.model.StakingIntegrationID
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.repositories.P2PEthPoolRepository
import com.tangem.domain.staking.toggles.StakingFeatureToggles
import com.tangem.domain.tokens.*
import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
@ -114,9 +113,6 @@ internal abstract class StakingModelTestBase {
private val coroutineScope: AppCoroutineScope = mockk()
protected val innerRouter: InnerStakingRouter = mockk()
protected val messageSender: UiMessageSender = mockk()
protected val stakingFeatureToggles: StakingFeatureToggles = mockk {
every { isSolanaUnstakeValidationEnabled() } returns false
}
@BeforeEach
fun setUp() {
@ -208,7 +204,6 @@ internal abstract class StakingModelTestBase {
coroutineScope = coroutineScope,
innerRouter = innerRouter,
messageSender = messageSender,
stakingFeatureToggles = stakingFeatureToggles,
appRouter = appRouter,
)
}

View file

@ -85,13 +85,11 @@ internal class AmountRequirementStateTransformerTest {
staked: BigDecimal,
exitMin: BigDecimal?,
enterMin: BigDecimal? = null,
enabled: Boolean = true,
) = AmountRequirementStateTransformer(
cryptoCurrencyStatus = solanaCryptoStatus(),
maxAmount = EnterAmountBoundary(amount = staked, fiatAmount = null, fiatRate = null),
integration = solanaExitIntegration(exitMin = exitMin, enterMin = enterMin),
actionType = StakingActionCommonType.Exit(partiallyUnstakeDisabled = false),
isSolanaUnstakeValidationEnabled = enabled,
)
@Test
@ -285,26 +283,12 @@ internal class AmountRequirementStateTransformerTest {
}
@Test
fun `WHEN Solana validation disabled THEN partial unstake below minimum allowed`() {
val transformer = solanaTransformer(
staked = BigDecimal("5"),
exitMin = BigDecimal("1"),
enabled = false,
)
val result = transformer.transform(amountState(BigDecimal("0.5"))) as AmountState.Data
assertThat(result.amountTextField.isError).isFalse()
}
@Test
fun `WHEN validation enabled but currency is not Solana THEN Solana rule does not apply`() {
fun `WHEN currency is not Solana THEN Solana rule does not apply`() {
val transformer = AmountRequirementStateTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatus, // relaxed mock: network.rawId is not "solana"
maxAmount = EnterAmountBoundary(amount = BigDecimal("5"), fiatAmount = null, fiatRate = null),
integration = exitIntegrationWith(minimum = null, maximum = null),
actionType = StakingActionCommonType.Exit(partiallyUnstakeDisabled = false),
isSolanaUnstakeValidationEnabled = true,
)
val result = transformer.transform(amountState(BigDecimal("0.5"))) as AmountState.Data