diff --git a/app/src/androidTest/kotlin/com/tangem/common/BaseTestCase.kt b/app/src/androidTest/kotlin/com/tangem/common/BaseTestCase.kt index a7213a50ec..ee0a5ce91f 100644 --- a/app/src/androidTest/kotlin/com/tangem/common/BaseTestCase.kt +++ b/app/src/androidTest/kotlin/com/tangem/common/BaseTestCase.kt @@ -198,20 +198,9 @@ abstract class BaseTestCase : TestCase( // Version-gated toggles released in versions <= 6.0 — forced on so tests run against the actual // build even when the app version resolves to 1.0.0-SNAPSHOT on CI (then 1.0.0 < x.xx would // disable them). On the releases/6.0 branch every toggle with version <= 6.0 ships enabled. - // 5.40 - "TWI_1377_MANAGE_FUNDS" to true, // 6.0 "APP_REDESIGN_ENABLED" to true, "TWI_1326_YIELD_MODE_SWAP_ENABLED" to true, - "AND_15207_SWAP_SWITCH_TO_TRANSFER_ENABLED" to true, - "AND_15120_SWAP_INTEGRATED_APPROVE" to true, - "AND_15596_ONBOARDING_PUSH_NOTIFICATION_DOUBLE_ASK_AB_ENABLED" to true, - "AND_15258_QUICK_TOP_UP_ENABLED" to true, - "AND_15368_VISA_PAY_REDESIGN" to true, - "AND_15364_VISA_PAY_CARD_CLOSE" to true, - "AND_15489_EXPRESS_SHARE_BUTTON_ENABLED" to true, - "AND_15235_VISA_MULTIPLE_CARDS" to true, - "AND_15715_SWAP_BEST_DEX_RATE_ENABLED" to true, // 6.1 "TWI_1638_VA_MVP0_ENABLED" to true, ) diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json index 51ef362a67..7feb32e9ad 100644 --- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json @@ -39,26 +39,10 @@ "name": "ADDRESS_SYNC_ENABLED", "version": "undefined" }, - { - "name": "AND_15207_SWAP_SWITCH_TO_TRANSFER_ENABLED", - "version": "6.0" - }, - { - "name": "AND_15120_SWAP_INTEGRATED_APPROVE", - "version": "6.0" - }, { "name": "TWI_1403_PUSH_NOTIFICATION_SETTINGS_ENABLED", "version": "undefined" }, - { - "name": "AND_15596_ONBOARDING_PUSH_NOTIFICATION_DOUBLE_ASK_AB_ENABLED", - "version": "6.0" - }, - { - "name": "TWI_1377_MANAGE_FUNDS", - "version": "6.0" - }, { "name": "AND_15438_BACKEND_AUTHENTICATION_ENABLED", "version": "undefined" @@ -67,18 +51,6 @@ "name": "AND_15482_SURVEYSPARROW_ENABLED", "version": "undefined" }, - { - "name": "AND_15258_QUICK_TOP_UP_ENABLED", - "version": "6.0" - }, - { - "name": "AND_15368_VISA_PAY_REDESIGN", - "version": "6.0" - }, - { - "name": "AND_15364_VISA_PAY_CARD_CLOSE", - "version": "6.0" - }, { "name": "AND_15741_VISA_PAY_REMOVE_ACCOUNT", "version": "undefined" @@ -95,18 +67,6 @@ "name": "AND_15632_GASLESS_YIELD_WITHDRAW_ENABLED", "version": "undefined" }, - { - "name": "AND_15489_EXPRESS_SHARE_BUTTON_ENABLED", - "version": "6.0" - }, - { - "name": "AND_15235_VISA_MULTIPLE_CARDS", - "version": "6.0" - }, - { - "name": "AND_15715_SWAP_BEST_DEX_RATE_ENABLED", - "version": "6.0" - }, { "name": "AND_15767_NEW_TX_HISTORY_ENABLED", "version": "undefined" @@ -115,10 +75,6 @@ "name": "AND_14829_WARNINGS_REFACTORING_ENABLED", "version": "undefined" }, - { - "name": "AND_16148_SOLANA_UNSTAKE_VALIDATION_ENABLED", - "version": "6.0" - }, { "name": "TWI_1522_MARKETING_BANNERS_ENABLED", "version": "undefined" diff --git a/data/staking/src/main/java/com/tangem/data/staking/toggles/DefaultStakingFeatureToggles.kt b/data/staking/src/main/java/com/tangem/data/staking/toggles/DefaultStakingFeatureToggles.kt index 4a03e81627..a962af37c6 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/toggles/DefaultStakingFeatureToggles.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/toggles/DefaultStakingFeatureToggles.kt @@ -14,12 +14,6 @@ internal class DefaultStakingFeatureToggles( return featureTogglesManager.isFeatureEnabled(toggle) } - override fun isSolanaUnstakeValidationEnabled(): Boolean { - return featureTogglesManager.isFeatureEnabled( - FeatureToggles.AND_16148_SOLANA_UNSTAKE_VALIDATION_ENABLED, - ) - } - override fun isRegionUnavailableHandlingEnabled(): Boolean { return featureTogglesManager.isFeatureEnabled( FeatureToggles.AND_15231_STAKING_REGION_UNAVAILABLE_ENABLED, diff --git a/data/staking/src/test/kotlin/com/tangem/data/staking/toggles/DefaultStakingFeatureTogglesTest.kt b/data/staking/src/test/kotlin/com/tangem/data/staking/toggles/DefaultStakingFeatureTogglesTest.kt index f5bfab97a7..e8080005d3 100644 --- a/data/staking/src/test/kotlin/com/tangem/data/staking/toggles/DefaultStakingFeatureTogglesTest.kt +++ b/data/staking/src/test/kotlin/com/tangem/data/staking/toggles/DefaultStakingFeatureTogglesTest.kt @@ -48,32 +48,6 @@ internal class DefaultStakingFeatureTogglesTest { verify(exactly = 0) { featureTogglesManager.isFeatureEnabled(any()) } } - @Test - fun `isSolanaUnstakeValidationEnabled returns true when toggle enabled`() { - every { - featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_16148_SOLANA_UNSTAKE_VALIDATION_ENABLED) - } returns true - - assertThat(toggles.isSolanaUnstakeValidationEnabled()).isTrue() - - verify(exactly = 1) { - featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_16148_SOLANA_UNSTAKE_VALIDATION_ENABLED) - } - } - - @Test - fun `isSolanaUnstakeValidationEnabled returns false when toggle disabled`() { - every { - featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_16148_SOLANA_UNSTAKE_VALIDATION_ENABLED) - } returns false - - assertThat(toggles.isSolanaUnstakeValidationEnabled()).isFalse() - - verify(exactly = 1) { - featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_16148_SOLANA_UNSTAKE_VALIDATION_ENABLED) - } - } - @Test fun `GIVEN toggle enabled WHEN isRegionUnavailableHandlingEnabled THEN returns true`() { // Arrange diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/toggles/StakingFeatureToggles.kt b/domain/staking/src/main/java/com/tangem/domain/staking/toggles/StakingFeatureToggles.kt index 545fea00cf..8988ecfeca 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/toggles/StakingFeatureToggles.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/toggles/StakingFeatureToggles.kt @@ -6,7 +6,5 @@ interface StakingFeatureToggles { fun isIntegrationEnabled(integrationId: StakingIntegrationID): Boolean - fun isSolanaUnstakeValidationEnabled(): Boolean - fun isRegionUnavailableHandlingEnabled(): Boolean } \ No newline at end of file diff --git a/features/push-notifications/api/src/main/java/com/tangem/features/pushnotifications/PushNotificationsFeatureToggles.kt b/features/push-notifications/api/src/main/java/com/tangem/features/pushnotifications/PushNotificationsFeatureToggles.kt deleted file mode 100644 index ab66489854..0000000000 --- a/features/push-notifications/api/src/main/java/com/tangem/features/pushnotifications/PushNotificationsFeatureToggles.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.tangem.features.pushnotifications - -interface PushNotificationsFeatureToggles { - - /** Kill switch for the onboarding "Double Ask" A/B experiment (`twi_1403_onboarding_push_notification_double_ask`). */ - val isOnboardingPushDoubleAskAbEnabled: Boolean -} \ No newline at end of file diff --git a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/DefaultPushNotificationsFeatureToggles.kt b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/DefaultPushNotificationsFeatureToggles.kt deleted file mode 100644 index ac118aa569..0000000000 --- a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/DefaultPushNotificationsFeatureToggles.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.features.pushnotifications.impl - -import com.tangem.core.configtoggle.FeatureToggles -import com.tangem.core.configtoggle.feature.FeatureTogglesManager -import com.tangem.features.pushnotifications.PushNotificationsFeatureToggles -import javax.inject.Inject - -internal class DefaultPushNotificationsFeatureToggles @Inject constructor( - private val featureTogglesManager: FeatureTogglesManager, -) : PushNotificationsFeatureToggles { - - override val isOnboardingPushDoubleAskAbEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled( - FeatureToggles.AND_15596_ONBOARDING_PUSH_NOTIFICATION_DOUBLE_ASK_AB_ENABLED, - ) -} \ No newline at end of file diff --git a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/di/PushNotificationsModule.kt b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/di/PushNotificationsModule.kt index 278d4274a8..06d4376447 100644 --- a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/di/PushNotificationsModule.kt +++ b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/di/PushNotificationsModule.kt @@ -1,12 +1,10 @@ package com.tangem.features.pushnotifications.impl.di import com.tangem.core.decompose.model.Model -import com.tangem.features.pushnotifications.PushNotificationsFeatureToggles import com.tangem.features.pushnotifications.api.PushNotificationsBottomSheetComponent import com.tangem.features.pushnotifications.api.PushNotificationsComponent import com.tangem.features.pushnotifications.impl.DefaultPushNotificationsBottomSheetComponent import com.tangem.features.pushnotifications.impl.DefaultPushNotificationsComponent -import com.tangem.features.pushnotifications.impl.DefaultPushNotificationsFeatureToggles import com.tangem.features.pushnotifications.impl.model.PushNotificationsModel import dagger.Binds import dagger.Module @@ -14,7 +12,6 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import dagger.multibindings.ClassKey import dagger.multibindings.IntoMap -import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) @@ -32,8 +29,4 @@ internal interface PushNotificationsModule { @IntoMap @ClassKey(PushNotificationsModel::class) fun bindModel(model: PushNotificationsModel): Model - - @Binds - @Singleton - fun bindFeatureToggles(impl: DefaultPushNotificationsFeatureToggles): PushNotificationsFeatureToggles } \ No newline at end of file diff --git a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCase.kt b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCase.kt index 9d8bdc2024..6b1e8c5f72 100644 --- a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCase.kt +++ b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCase.kt @@ -1,18 +1,13 @@ package com.tangem.features.pushnotifications.impl.domain import com.tangem.core.abtests.manager.ABTestsManager -import com.tangem.features.pushnotifications.PushNotificationsFeatureToggles import javax.inject.Inject class GetPushNotificationsDoubleAskVariantUseCase @Inject constructor( - private val pushNotificationsFeatureToggles: PushNotificationsFeatureToggles, private val abTestsManager: ABTestsManager, ) { suspend operator fun invoke(): DoubleAskVariant { - if (!pushNotificationsFeatureToggles.isOnboardingPushDoubleAskAbEnabled) { - return DoubleAskVariant.Off - } val variant = abTestsManager.getValue(AMPLITUDE_ID, DoubleAskVariant.Off.key) return DoubleAskVariant.fromKey(variant) } diff --git a/features/push-notifications/impl/src/test/kotlin/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCaseTest.kt b/features/push-notifications/impl/src/test/kotlin/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCaseTest.kt index a42e32f434..151b04f878 100644 --- a/features/push-notifications/impl/src/test/kotlin/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCaseTest.kt +++ b/features/push-notifications/impl/src/test/kotlin/com/tangem/features/pushnotifications/impl/domain/GetPushNotificationsDoubleAskVariantUseCaseTest.kt @@ -2,37 +2,22 @@ package com.tangem.features.pushnotifications.impl.domain import com.google.common.truth.Truth.assertThat import com.tangem.core.abtests.manager.ABTestsManager -import com.tangem.features.pushnotifications.PushNotificationsFeatureToggles import io.mockk.coEvery import io.mockk.coVerify -import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test internal class GetPushNotificationsDoubleAskVariantUseCaseTest { - private val featureToggles: PushNotificationsFeatureToggles = mockk() private val abTestsManager: ABTestsManager = mockk() private val useCase = GetPushNotificationsDoubleAskVariantUseCase( - pushNotificationsFeatureToggles = featureToggles, abTestsManager = abTestsManager, ) @Test - fun `GIVEN toggle disabled WHEN invoke THEN returns Off and AB not queried`() = runTest { - every { featureToggles.isOnboardingPushDoubleAskAbEnabled } returns false - - val result = useCase() - - assertThat(result).isEqualTo(DoubleAskVariant.Off) - coVerify(exactly = 0) { abTestsManager.getValue(any(), any()) } - } - - @Test - fun `GIVEN toggle enabled AND AB returns treatment WHEN invoke THEN returns On`() = runTest { - every { featureToggles.isOnboardingPushDoubleAskAbEnabled } returns true + fun `GIVEN AB returns treatment WHEN invoke THEN returns On`() = runTest { coEvery { abTestsManager.getValue(KEY, "control") } returns "treatment" val result = useCase() @@ -42,16 +27,14 @@ internal class GetPushNotificationsDoubleAskVariantUseCaseTest { } @Test - fun `GIVEN toggle enabled AND AB returns control WHEN invoke THEN returns Off`() = runTest { - every { featureToggles.isOnboardingPushDoubleAskAbEnabled } returns true + fun `GIVEN AB returns control WHEN invoke THEN returns Off`() = runTest { coEvery { abTestsManager.getValue(KEY, "control") } returns "control" assertThat(useCase()).isEqualTo(DoubleAskVariant.Off) } @Test - fun `GIVEN toggle enabled AND AB returns unknown WHEN invoke THEN returns Off`() = runTest { - every { featureToggles.isOnboardingPushDoubleAskAbEnabled } returns true + fun `GIVEN AB returns unknown WHEN invoke THEN returns Off`() = runTest { coEvery { abTestsManager.getValue(KEY, "control") } returns "unexpected_value" assertThat(useCase()).isEqualTo(DoubleAskVariant.Off) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt index dee5741fd8..8bddf85ee5 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt @@ -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(), ), ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt index 7dd219e1b3..9c9c0d1595 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountChangeStateTransformer.kt @@ -14,7 +14,6 @@ internal class AmountChangeStateTransformer( private val minimumTransactionAmount: EnterAmountBoundary?, private val value: String, private val integration: StakingIntegration, - private val isSolanaUnstakeValidationEnabled: Boolean, ) : Transformer { private val maxEnterAmountConverter = MaxEnterAmountConverter() @@ -44,7 +43,6 @@ internal class AmountChangeStateTransformer( maxAmount = maxEnterAmount, integration = integration, actionType = prevState.actionType, - isSolanaUnstakeValidationEnabled = isSolanaUnstakeValidationEnabled, ).transform(updatedAmountState), ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt index 0e250e8b3c..94476c6be9 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountMaxValueStateTransformer.kt @@ -14,7 +14,6 @@ internal class AmountMaxValueStateTransformer( private val minimumTransactionAmount: EnterAmountBoundary?, private val actionType: StakingActionCommonType, private val integration: StakingIntegration, - private val isSolanaUnstakeValidationEnabled: Boolean, ) : Transformer { private val maxEnterAmountConverter = MaxEnterAmountConverter() @@ -41,7 +40,6 @@ internal class AmountMaxValueStateTransformer( cryptoCurrencyStatus = cryptoCurrencyStatus, integration = integration, actionType = prevState.actionType, - isSolanaUnstakeValidationEnabled = isSolanaUnstakeValidationEnabled, ).transform(updatedAmountState), ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt index 8874243fb5..543ee37f21 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformer.kt @@ -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 { 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( diff --git a/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTestBase.kt b/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTestBase.kt index 189a86477d..ad67e68795 100644 --- a/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTestBase.kt +++ b/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTestBase.kt @@ -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, ) } diff --git a/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformerTest.kt b/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformerTest.kt index 10b2ec7971..966f15d45a 100644 --- a/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformerTest.kt +++ b/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/state/transformers/amount/AmountRequirementStateTransformerTest.kt @@ -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 diff --git a/features/swap/api/src/main/kotlin/com/tangem/features/swap/SwapFeatureToggles.kt b/features/swap/api/src/main/kotlin/com/tangem/features/swap/SwapFeatureToggles.kt index 5d442dbf20..48c7404a23 100644 --- a/features/swap/api/src/main/kotlin/com/tangem/features/swap/SwapFeatureToggles.kt +++ b/features/swap/api/src/main/kotlin/com/tangem/features/swap/SwapFeatureToggles.kt @@ -2,10 +2,6 @@ package com.tangem.features.swap interface SwapFeatureToggles { val isYieldSwapEnabled: Boolean - val isSwapSwitchToTransferEnabled: Boolean - val isSwapIntegratedApproveEnabled: Boolean - val isExpressShareButtonEnabled: Boolean - val isSwapBestDexRateEnabled: Boolean val isHighFeeWarningEnabled: Boolean val isTronDexSwapEnabled: Boolean } \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt index 09b5ce82af..1c011ca512 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt @@ -157,9 +157,7 @@ interface SwapInteractor { * `LIMITED`), loads its [com.tangem.blockchain.common.transaction.TransactionFee] and returns * both as [IntegratedApprovalData]. * - * Used by the integrated approve+swap flow when - * `SwapFeatureToggles.isSwapIntegratedApproveEnabled` is ON and the quote requires an - * allowance bump. + * Used by the integrated approve+swap flow when the quote requires an allowance bump. * * @param approvalAmount LIMITED-mode swap amount (the user-input amount). Used when * [approveType] is `LIMITED`; ignored for `UNLIMITED`. diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 2e424aeb67..0989af8561 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -404,8 +404,7 @@ internal class SwapInteractorImpl @Inject constructor( ) } val isBalanceWithoutFeeEnough = isBalanceEnough(fromSwapCurrencyStatus, amount, null) - val isIntegratedApproveActive = swapFeatureToggles.isSwapIntegratedApproveEnabled && - !hasIntegratedApprovalFallenBack(fromSwapCurrencyStatus, spenderAddress) + val isIntegratedApproveActive = !hasIntegratedApprovalFallenBack(fromSwapCurrencyStatus, spenderAddress) val isAllowanceSatisfied = if (isIntegratedApproveActive) { allowanceInfo !is AllowanceInfo.ResetNeeded @@ -1973,7 +1972,6 @@ internal class SwapInteractorImpl @Inject constructor( val isYieldSwap = fromSwapCurrencyStatus.isYieldSwapActive && fromSwapCurrencyStatus.currency is CryptoCurrency.Token val isIntegratedApprovalNeeded = !isYieldSwap && - swapFeatureToggles.isSwapIntegratedApproveEnabled && allowanceInfo is AllowanceInfo.NotEnough && !hasIntegratedApprovalFallenBack(fromSwapCurrencyStatus, spenderAddress) swapState.copy( @@ -2120,7 +2118,6 @@ internal class SwapInteractorImpl @Inject constructor( ).getOrNull() ?: return quotesLoadedState.copy(permissionState = PermissionDataState.Empty) val isIntegratedApprovalNeeded = !isYieldSwap && - swapFeatureToggles.isSwapIntegratedApproveEnabled && allowanceInfo is AllowanceInfo.NotEnough && !hasIntegratedApprovalFallenBack(fromSwapCurrencyStatus, quoteModel.allowanceContract) return quotesLoadedState.copy( diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt index b1124566eb..6c9eca83b6 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt @@ -46,7 +46,6 @@ import com.tangem.feature.swap.domain.models.SwapAmount import com.tangem.feature.swap.domain.models.ui.SwapState import com.tangem.feature.swap.domain.models.ui.TokenSwapInfo import com.tangem.features.send.api.subcomponents.feeSelector.utils.FeeCalculationUtils.checkFeeCoverage -import com.tangem.features.swap.SwapFeatureToggles import com.tangem.utils.extensions.orZero import kotlinx.coroutines.flow.first import java.math.BigDecimal @@ -54,7 +53,6 @@ import javax.inject.Inject @Suppress("LongParameterList", "LargeClass") class SwapTransferInteractorImpl @Inject constructor( - private val swapFeatureToggles: SwapFeatureToggles, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase, @@ -306,7 +304,6 @@ class SwapTransferInteractorImpl @Inject constructor( fromSwapCurrency: CryptoCurrency?, toSwapCurrency: CryptoCurrency?, ): Boolean { - if (swapFeatureToggles.isSwapSwitchToTransferEnabled.not()) return false val isSameCurrency = when { fromSwapCurrency is CryptoCurrency.Coin && toSwapCurrency is CryptoCurrency.Coin -> { fromSwapCurrency.network.rawId == toSwapCurrency.network.rawId diff --git a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplFindBestQuoteTest.kt b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplFindBestQuoteTest.kt index 9e0f36436b..d836d0bc39 100644 --- a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplFindBestQuoteTest.kt +++ b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplFindBestQuoteTest.kt @@ -1618,11 +1618,6 @@ internal class SwapInteractorImplFindBestQuoteTest : SwapInteractorImplTestBase( private val spender = "0xDexRouter" private val tokenContract = "0xRegularToken" - @BeforeEach - fun enableIntegrated() { - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns true - } - @Test fun `NotEnough allowance with integrated active proceeds to PermissionSettings`() = runTest { stubAllowanceForSpender( diff --git a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplLoadDexSwapDataNoFeeTest.kt b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplLoadDexSwapDataNoFeeTest.kt index 5004c017ad..6cc97d80bf 100644 --- a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplLoadDexSwapDataNoFeeTest.kt +++ b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/SwapInteractorImplLoadDexSwapDataNoFeeTest.kt @@ -169,7 +169,6 @@ internal class SwapInteractorImplLoadDexSwapDataNoFeeTest : SwapInteractorImplTe @Test fun `GIVEN NotEnough allowance AND integrated active THEN permissionState is PermissionSettings`() = runTest { - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns true stubAllowance(AllowanceInfo.NotEnough(allowance = BigDecimal.ZERO, requiredAmount = BigDecimal.ONE)) val state = runFindBestQuoteForToken() @@ -181,7 +180,6 @@ internal class SwapInteractorImplLoadDexSwapDataNoFeeTest : SwapInteractorImplTe @Test fun `GIVEN Enough allowance THEN permissionState is Empty`() = runTest { - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns true stubAllowance(AllowanceInfo.Enough(allowance = BigDecimal("100"))) val state = runFindBestQuoteForToken() @@ -194,7 +192,6 @@ internal class SwapInteractorImplLoadDexSwapDataNoFeeTest : SwapInteractorImplTe runTest { // [REDACTED_TASK_KEY] / iOS parity: yield swaps must never use the integrated approve+swap path. // The yield-module proxy allowance is granted at enrollment, so no in-flow approval is shown. - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns true every { swapFeatureToggles.isYieldSwapEnabled } returns true coEvery { yieldModuleAddressProvider.getOrFetch(any(), any()) } returns YIELD_PROXY coEvery { walletManagersFacade.isSwapSpenderAllowed(any(), any(), any()) } returns true @@ -221,26 +218,6 @@ internal class SwapInteractorImplLoadDexSwapDataNoFeeTest : SwapInteractorImplTe assertThat(state.permissionState).isEqualTo(PermissionDataState.Empty) } - @Test - fun `GIVEN NotEnough allowance AND integrated toggle OFF THEN does not reach loadDexSwapDataNoFee`() = runTest { - // With the integrated toggle off, NotEnough is not allowance-satisfied (requires Enough), - // so manageDex does NOT enter loadDexSwapDataNoFee — getExchangeData is never called. - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns false - stubAllowance(AllowanceInfo.NotEnough(allowance = BigDecimal.ZERO, requiredAmount = BigDecimal.ONE)) - - runFindBestQuoteForTokenRaw() - - coVerify(exactly = 0) { - repository.getExchangeData( - userWallet = any(), fromContractAddress = any(), fromNetwork = any(), - toContractAddress = any(), fromAddress = any(), toNetwork = any(), - fromAmount = any(), fromDecimals = any(), toDecimals = any(), - providerId = any(), rateType = any(), toAddress = any(), - expressOperationType = any(), refundAddress = any(), - ) - } - } - // endregion private fun stubAllowance(info: AllowanceInfo) { @@ -261,11 +238,6 @@ internal class SwapInteractorImplLoadDexSwapDataNoFeeTest : SwapInteractorImplTe return result[dexProvider] as SwapState.QuotesLoadedState } - private suspend fun runFindBestQuoteForTokenRaw() { - val dexProvider = stubDexQuoteAndExchangeData() - invokeFindBestQuote(dexProvider) - } - private fun stubDexQuoteAndExchangeData(): com.tangem.feature.swap.domain.models.domain.SwapProvider { val dexProvider = buildSwapProvider(ExchangeProviderType.DEX) val quoteModel = buildQuoteModel(allowanceContract = SPENDER) diff --git a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt index a8c7256646..eca06f0ac2 100644 --- a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt +++ b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt @@ -38,7 +38,6 @@ import com.tangem.feature.swap.domain.fee.TransactionFeeResult import com.tangem.feature.swap.domain.models.SwapAmount import com.tangem.feature.swap.domain.models.ui.SwapState import com.tangem.feature.swap.domain.models.ui.TokenSwapInfo -import com.tangem.features.swap.SwapFeatureToggles import io.mockk.* import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf @@ -53,7 +52,6 @@ import java.math.BigDecimal @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class SwapTransferInteractorImplTest { - private val swapFeatureToggles: SwapFeatureToggles = mockk() private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase = mockk() private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase = mockk() private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase = mockk() @@ -72,7 +70,6 @@ internal class SwapTransferInteractorImplTest { private val validateTransactionUseCase: ValidateTransactionUseCase = mockk() private val sut = SwapTransferInteractorImpl( - swapFeatureToggles = swapFeatureToggles, getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase, getBalanceHidingSettingsUseCase = getBalanceHidingSettingsUseCase, isAccountsModeEnabledUseCase = isAccountsModeEnabledUseCase, @@ -1314,23 +1311,8 @@ internal class SwapTransferInteractorImplTest { // region shouldTransferInsteadOfSwap - @Test - fun `GIVEN feature toggle disabled WHEN shouldTransferInsteadOfSwap THEN return false`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns false - - val result = sut.shouldTransferInsteadOfSwap( - fromSwapCurrency = buildCoin(networkRawId = ETHEREUM), - toSwapCurrency = buildCoin(networkRawId = ETHEREUM), - ) - - assertThat(result).isFalse() - verify { swapFeatureToggles.isSwapSwitchToTransferEnabled } - } - @Test fun `GIVEN both coins on the same network WHEN shouldTransferInsteadOfSwap THEN return true`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns true - val result = sut.shouldTransferInsteadOfSwap( fromSwapCurrency = buildCoin(networkRawId = ETHEREUM), toSwapCurrency = buildCoin(networkRawId = ETHEREUM), @@ -1341,8 +1323,6 @@ internal class SwapTransferInteractorImplTest { @Test fun `GIVEN coins on different networks WHEN shouldTransferInsteadOfSwap THEN return false`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns true - val result = sut.shouldTransferInsteadOfSwap( fromSwapCurrency = buildCoin(networkRawId = ETHEREUM), toSwapCurrency = buildCoin(networkRawId = POLYGON), @@ -1353,8 +1333,6 @@ internal class SwapTransferInteractorImplTest { @Test fun `GIVEN tokens with same network and same contract WHEN shouldTransferInsteadOfSwap THEN return true`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns true - val result = sut.shouldTransferInsteadOfSwap( fromSwapCurrency = buildToken(networkRawId = ETHEREUM, contractAddress = USDT_CONTRACT), toSwapCurrency = buildToken(networkRawId = ETHEREUM, contractAddress = USDT_CONTRACT), @@ -1365,8 +1343,6 @@ internal class SwapTransferInteractorImplTest { @Test fun `GIVEN tokens with same network but different contract WHEN shouldTransferInsteadOfSwap THEN return false`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns true - val result = sut.shouldTransferInsteadOfSwap( fromSwapCurrency = buildToken(networkRawId = ETHEREUM, contractAddress = USDT_CONTRACT), toSwapCurrency = buildToken(networkRawId = ETHEREUM, contractAddress = USDC_CONTRACT), @@ -1377,8 +1353,6 @@ internal class SwapTransferInteractorImplTest { @Test fun `GIVEN tokens with same contract but different network WHEN shouldTransferInsteadOfSwap THEN return false`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns true - val result = sut.shouldTransferInsteadOfSwap( fromSwapCurrency = buildToken(networkRawId = ETHEREUM, contractAddress = USDT_CONTRACT), toSwapCurrency = buildToken(networkRawId = POLYGON, contractAddress = USDT_CONTRACT), @@ -1389,8 +1363,6 @@ internal class SwapTransferInteractorImplTest { @Test fun `GIVEN coin from and token to WHEN shouldTransferInsteadOfSwap THEN return false`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns true - val result = sut.shouldTransferInsteadOfSwap( fromSwapCurrency = buildCoin(networkRawId = ETHEREUM), toSwapCurrency = buildToken(networkRawId = ETHEREUM, contractAddress = USDT_CONTRACT), @@ -1401,8 +1373,6 @@ internal class SwapTransferInteractorImplTest { @Test fun `GIVEN token from and coin to WHEN shouldTransferInsteadOfSwap THEN return false`() { - every { swapFeatureToggles.isSwapSwitchToTransferEnabled } returns true - val result = sut.shouldTransferInsteadOfSwap( fromSwapCurrency = buildToken(networkRawId = ETHEREUM, contractAddress = USDT_CONTRACT), toSwapCurrency = buildCoin(networkRawId = ETHEREUM), diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapFeatureToggles.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapFeatureToggles.kt index 5f4acc636d..7d433b88b5 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapFeatureToggles.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapFeatureToggles.kt @@ -14,26 +14,6 @@ internal class DefaultSwapFeatureToggles @Inject constructor( toggle = FeatureToggles.TWI_1326_YIELD_MODE_SWAP_ENABLED, ) - override val isSwapSwitchToTransferEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled( - toggle = FeatureToggles.AND_15207_SWAP_SWITCH_TO_TRANSFER_ENABLED, - ) - - override val isSwapIntegratedApproveEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled( - toggle = FeatureToggles.AND_15120_SWAP_INTEGRATED_APPROVE, - ) - - override val isExpressShareButtonEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled( - toggle = FeatureToggles.AND_15489_EXPRESS_SHARE_BUTTON_ENABLED, - ) - - override val isSwapBestDexRateEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled( - toggle = FeatureToggles.AND_15715_SWAP_BEST_DEX_RATE_ENABLED, - ) && isSwapIntegratedApproveEnabled - override val isHighFeeWarningEnabled: Boolean get() = featureTogglesManager.isFeatureEnabled( toggle = FeatureToggles.TWI_1367_HIGH_FEE_WARNING_ENABLED, diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/SwapProviderResolver.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/SwapProviderResolver.kt index 8db946ff18..d2d070440e 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/SwapProviderResolver.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/SwapProviderResolver.kt @@ -28,18 +28,11 @@ internal object SwapProviderResolver { /** * Picks the best provider among [states]. * - * When [isSwapBestDexRateEnabled] is on and at least one DEX/DEX_BRIDGE provider is present, the - * best-rated DEX provider wins; otherwise the overall best-rated provider is returned (the best - * CEX when no DEX is available). "Best rated" = lowest from/to fiat ratio (most output per unit - * of input). Returns null when [states] is empty. - * - * @param isSwapBestDexRateEnabled whether the Best DEX Rate feature toggle is on. + * When at least one DEX/DEX_BRIDGE provider is present, the best-rated DEX provider wins; otherwise + * the overall best-rated provider is returned (the best CEX when no DEX is available). "Best rated" = + * lowest from/to fiat ratio (most output per unit of input). Returns null when [states] is empty. */ - fun findBest( - states: Map, - isSwapBestDexRateEnabled: Boolean, - ): SwapProvider? { - if (!isSwapBestDexRateEnabled) return findBestRated(states) + fun findBest(states: Map): SwapProvider? { val dexStates = states.filterKeys { it.type.isDex() } return if (dexStates.isNotEmpty()) { findBestRated(dexStates) @@ -54,7 +47,7 @@ internal object SwapProviderResolver { * Priority: FCA restriction → permission required → recommended → best rate → none. A best-rate * badge is shown only when more than one provider is considered, FCA restrictions are not applied, * and this row's quote carries no price-impact warning. Which best-rate badge it is depends on the - * provider mix (only relevant when [isSwapBestDexRateEnabled] is on): + * provider mix: * - [AdditionalBadge.BestTrade] ("Best rate") — always on the overall best-rated provider, * regardless of its type. * - [AdditionalBadge.BestDexRate] ("Best DEX rate") — only when both CEX and DEX providers are @@ -62,22 +55,17 @@ internal object SwapProviderResolver { * shown on the best-rated DEX. When a DEX already is the overall best, or the set is CEX-only / * DEX-only, no separate "Best DEX rate" badge is shown. * - * When [isSwapBestDexRateEnabled] is off, only the overall best provider gets [AdditionalBadge.BestTrade] - * (legacy behaviour) and [AdditionalBadge.BestDexRate] is never produced. - * * @param states all loaded quotes — used to find the best providers and to count considered providers. * @param provider the provider this row represents. * @param needApplyFCARestrictions whether FCA restrictions apply to the current user. * @param state this provider's [SwapState]; price-impact and permission are read from it when it * is a [SwapState.QuotesLoadedState]. Null for error rows (which only resolve to FCA / recommended / none). - * @param isSwapBestDexRateEnabled whether the Best DEX Rate feature toggle is on. */ fun resolveBadge( states: Map, provider: SwapProvider, needApplyFCARestrictions: Boolean, state: SwapState? = null, - isSwapBestDexRateEnabled: Boolean, ): AdditionalBadge { val priceImpact = (state as? SwapState.QuotesLoadedState)?.priceImpact val permissionState = (state as? SwapState.QuotesLoadedState)?.permissionState @@ -90,7 +78,7 @@ internal object SwapProviderResolver { needApplyFCARestrictions && provider.isFCARestricted() -> AdditionalBadge.FCAWarningList permissionState is PermissionDataState.PermissionRequired -> AdditionalBadge.PermissionRequired provider.isRecommended -> AdditionalBadge.Recommended - isBestRateBadgeAllowed -> resolveBestRateBadge(states, provider, isSwapBestDexRateEnabled) + isBestRateBadgeAllowed -> resolveBestRateBadge(states, provider) else -> AdditionalBadge.Empty } } @@ -102,16 +90,10 @@ internal object SwapProviderResolver { private fun resolveBestRateBadge( states: Map, provider: SwapProvider, - isSwapBestDexRateEnabled: Boolean, ): AdditionalBadge { val overallBest = findBestRated(states) val isOverallBest = provider.providerId == overallBest?.providerId - // Toggle off → legacy behaviour: only the overall best provider gets the "Best rate" badge. - if (!isSwapBestDexRateEnabled) { - return if (isOverallBest) AdditionalBadge.BestTrade else AdditionalBadge.Empty - } - val dexStates = states.filterKeys { it.type.isDex() } val hasDex = dexStates.isNotEmpty() val hasCex = states.keys.any { !it.type.isDex() } diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt index c0c79e3427..f50380fc4b 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt @@ -281,7 +281,6 @@ internal class SwapModel @Inject constructor( get() { val permissionState = dataState.getCurrentLoadedSwapState()?.permissionState return permissionState == PermissionDataState.Empty || - swapFeatureToggles.isSwapIntegratedApproveEnabled && permissionState is PermissionDataState.PermissionSettings } @@ -1175,7 +1174,6 @@ internal class SwapModel @Inject constructor( needApplyFCARestrictions = userCountry.needApplyFCARestrictions(), states = loadedStates, state = state, - isSwapBestDexRateEnabled = swapFeatureToggles.isSwapBestDexRateEnabled, ) val swapFee = getSelectedSwapFee() uiState = stateBuilder.createQuotesLoadedState( @@ -1272,7 +1270,6 @@ internal class SwapModel @Inject constructor( needApplyFCARestrictions = userCountry.needApplyFCARestrictions(), states = loadedStates, state = state, - isSwapBestDexRateEnabled = swapFeatureToggles.isSwapBestDexRateEnabled, ) uiState = stateBuilder.createQuotesErrorState( uiStateHolder = uiState, @@ -1327,10 +1324,7 @@ internal class SwapModel @Inject constructor( return if (consideredProviders.isNotEmpty()) { val successLoadedData = consideredProviders.getLastLoadedSuccessStates() - val bestQuotesProvider = SwapProviderResolver.findBest( - states = successLoadedData, - isSwapBestDexRateEnabled = swapFeatureToggles.isSwapBestDexRateEnabled, - ) + val bestQuotesProvider = SwapProviderResolver.findBest(states = successLoadedData) val currentSelected = dataState.selectedProvider if (currentSelected != null && consideredProviders.keys.contains(currentSelected)) { // logic for always choose best if already selected provider @@ -2111,7 +2105,6 @@ internal class SwapModel @Inject constructor( selectedProviderId = providerId, pricesLowerBest = pricesLowerBest, providersStates = dataState.lastLoadedSwapStates, - isSwapBestDexRateEnabled = swapFeatureToggles.isSwapBestDexRateEnabled, needApplyFCARestrictions = userCountry.needApplyFCARestrictions(), ) { uiState = stateBuilder.dismissBottomSheet(uiState) } }, @@ -2663,8 +2656,7 @@ internal class SwapModel @Inject constructor( val swapDataForCall = resolveDexSwapDataForFee(quoteState) .getOrElse { return Either.Left(it) } - val integratedSettings = (quoteState.permissionState as? PermissionDataState.PermissionSettings) - ?.takeIf { swapFeatureToggles.isSwapIntegratedApproveEnabled } + val integratedSettings = quoteState.permissionState as? PermissionDataState.PermissionSettings return swapInteractor.loadSwapFee( quotesLoadedState = quoteState, @@ -2833,8 +2825,7 @@ internal class SwapModel @Inject constructor( private fun isPermissionNotificationShown(): Boolean { val permissionState = dataState.getCurrentLoadedSwapState()?.permissionState - val isApprovalIntegrated = swapFeatureToggles.isSwapIntegratedApproveEnabled && - permissionState is PermissionDataState.PermissionSettings + val isApprovalIntegrated = permissionState is PermissionDataState.PermissionSettings return permissionState != null && permissionState !is PermissionDataState.Empty && !isApprovalIntegrated } diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index 7eac37851c..b4a62370f8 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -1220,7 +1220,6 @@ internal class StateBuilder( pricesLowerBest: Map, providersStates: Map, needApplyFCARestrictions: Boolean, - isSwapBestDexRateEnabled: Boolean, onDismiss: () -> Unit, ): SwapStateHolder { val successStates = providersStates.getLastLoadedSuccessStates() @@ -1231,7 +1230,6 @@ internal class StateBuilder( provider = entry.key, needApplyFCARestrictions = needApplyFCARestrictions, state = entry.value, - isSwapBestDexRateEnabled = isSwapBestDexRateEnabled, ) entry.convertToProviderBottomSheetState( pricesLowerBest = pricesLowerBest, diff --git a/features/swap/impl/src/test/java/com/tangem/feature/swap/converters/SwapProviderResolverTest.kt b/features/swap/impl/src/test/java/com/tangem/feature/swap/converters/SwapProviderResolverTest.kt index b723105404..5f55f424c8 100644 --- a/features/swap/impl/src/test/java/com/tangem/feature/swap/converters/SwapProviderResolverTest.kt +++ b/features/swap/impl/src/test/java/com/tangem/feature/swap/converters/SwapProviderResolverTest.kt @@ -20,8 +20,8 @@ import java.math.BigDecimal * row-badge resolution ([SwapProviderResolver.resolveBadge]). * * Ranking metric: best provider == lowest `from/to` fiat ratio == highest `to` fiat output for the - * same `from` input. "Best DEX Rate" prefers the best-rated DEX/DEX_BRIDGE provider when the feature - * is on and any DEX is present. + * same `from` input. "Best DEX Rate" prefers the best-rated DEX/DEX_BRIDGE provider when any DEX is + * present. */ internal class SwapProviderResolverTest { @@ -50,7 +50,7 @@ internal class SwapProviderResolverTest { dexBridge to quote(fromFiat = "100", toFiat = "105"), ) - val best = SwapProviderResolver.findBest(states, isSwapBestDexRateEnabled = true) + val best = SwapProviderResolver.findBest(states) assertThat(best).isEqualTo(dex1) } @@ -62,23 +62,11 @@ internal class SwapProviderResolverTest { cex2 to quote(fromFiat = "100", toFiat = "120"), // best CEX ) - val best = SwapProviderResolver.findBest(states, isSwapBestDexRateEnabled = true) + val best = SwapProviderResolver.findBest(states) assertThat(best).isEqualTo(cex2) } - @Test - fun `GIVEN best dex rate off WHEN findBest THEN best overall regardless of type`() { - val states = mapOf( - cex1 to quote(fromFiat = "100", toFiat = "120"), // best overall (a CEX) - dex1 to quote(fromFiat = "100", toFiat = "110"), - ) - - val best = SwapProviderResolver.findBest(states, isSwapBestDexRateEnabled = false) - - assertThat(best).isEqualTo(cex1) - } - @Test fun `GIVEN DEX_BRIDGE is the best DEX WHEN findBest with best dex rate on THEN DEX_BRIDGE selected`() { val states = mapOf( @@ -87,7 +75,7 @@ internal class SwapProviderResolverTest { dexBridge to quote(fromFiat = "100", toFiat = "115"), // best among DEX-based ) - val best = SwapProviderResolver.findBest(states, isSwapBestDexRateEnabled = true) + val best = SwapProviderResolver.findBest(states) assertThat(best).isEqualTo(dexBridge) } @@ -110,7 +98,6 @@ internal class SwapProviderResolverTest { provider = dex1, needApplyFCARestrictions = false, state = states.getValue(dex1), - isSwapBestDexRateEnabled = true, ) // Overall best is the DEX → it gets the single "Best rate" badge, NOT "Best DEX rate". @@ -129,7 +116,6 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = false, state = states.getValue(cex1), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) @@ -150,7 +136,6 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = false, state = states.getValue(cex1), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.BestTrade) @@ -169,7 +154,6 @@ internal class SwapProviderResolverTest { provider = dex1, needApplyFCARestrictions = false, state = states.getValue(dex1), - isSwapBestDexRateEnabled = true, ) // CEX wins overall, so the best DEX additionally gets the "Best DEX rate" badge. @@ -189,7 +173,6 @@ internal class SwapProviderResolverTest { provider = dexBridge, needApplyFCARestrictions = false, state = states.getValue(dexBridge), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) @@ -209,7 +192,6 @@ internal class SwapProviderResolverTest { provider = dex1, needApplyFCARestrictions = false, state = states.getValue(dex1), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.BestTrade) @@ -227,7 +209,6 @@ internal class SwapProviderResolverTest { provider = dexBridge, needApplyFCARestrictions = false, state = states.getValue(dexBridge), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) @@ -247,51 +228,11 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = false, state = states.getValue(cex1), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.BestTrade) } - // --- Toggle off → only the overall best gets BestTrade; "Best DEX rate" is never produced. - - @Test - fun `GIVEN toggle off AND both types present with CEX best WHEN resolveBadge for the CEX THEN BestTrade`() { - val states = mapOf( - cex1 to quote(fromFiat = "100", toFiat = "120"), // best overall - dex1 to quote(fromFiat = "100", toFiat = "110"), - ) - - val badge = SwapProviderResolver.resolveBadge( - states = states, - provider = cex1, - needApplyFCARestrictions = false, - state = states.getValue(cex1), - isSwapBestDexRateEnabled = false, - ) - - assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.BestTrade) - } - - @Test - fun `GIVEN toggle off AND both types present with CEX best WHEN resolveBadge for the DEX THEN Empty`() { - val states = mapOf( - cex1 to quote(fromFiat = "100", toFiat = "120"), // best overall - dex1 to quote(fromFiat = "100", toFiat = "110"), - ) - - val badge = SwapProviderResolver.resolveBadge( - states = states, - provider = dex1, - needApplyFCARestrictions = false, - state = states.getValue(dex1), - isSwapBestDexRateEnabled = false, - ) - - // Toggle off → no "Best DEX rate" badge even though a DEX is present and not the overall best. - assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) - } - @Test fun `GIVEN FCA restricted provider AND restrictions on WHEN resolveBadge THEN FCAWarningList`() { val restricted = provider(id = "changelly", type = ExchangeProviderType.CEX, isRecommended = true) @@ -305,7 +246,6 @@ internal class SwapProviderResolverTest { provider = restricted, needApplyFCARestrictions = true, state = states.getValue(restricted), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.FCAWarningList) @@ -326,7 +266,6 @@ internal class SwapProviderResolverTest { provider = restricted, needApplyFCARestrictions = true, state = states.getValue(restricted), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.FCAWarningList) @@ -346,7 +285,6 @@ internal class SwapProviderResolverTest { provider = restricted, needApplyFCARestrictions = false, state = states.getValue(restricted), - isSwapBestDexRateEnabled = false, ) // Restrictions are off → the restricted id is ignored and the normal best-rate badge wins. @@ -365,7 +303,6 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = true, state = states.getValue(cex1), - isSwapBestDexRateEnabled = true, ) // FCA restrictions globally on suppress the best-rate badge even for non-restricted providers. @@ -388,7 +325,6 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = false, state = states.getValue(cex1), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.PermissionRequired) @@ -407,7 +343,6 @@ internal class SwapProviderResolverTest { provider = recommended, needApplyFCARestrictions = false, state = states.getValue(recommended), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Recommended) @@ -422,7 +357,6 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = false, state = states.getValue(cex1), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) @@ -440,7 +374,6 @@ internal class SwapProviderResolverTest { provider = cex2, // not the best needApplyFCARestrictions = false, state = states.getValue(cex2), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) @@ -458,7 +391,6 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = false, state = states.getValue(cex1), - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) @@ -476,7 +408,6 @@ internal class SwapProviderResolverTest { provider = cex1, needApplyFCARestrictions = false, state = null, - isSwapBestDexRateEnabled = true, ) assertThat(badge).isEqualTo(ProviderState.AdditionalBadge.Empty) diff --git a/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelIsPermissionNotNeededTest.kt b/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelIsPermissionNotNeededTest.kt index 1e4a7a6efa..36f1d1776e 100644 --- a/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelIsPermissionNotNeededTest.kt +++ b/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelIsPermissionNotNeededTest.kt @@ -2,7 +2,6 @@ package com.tangem.feature.swap.model import com.google.common.truth.Truth.assertThat import com.tangem.feature.swap.domain.models.ui.PermissionDataState -import io.mockk.every import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -11,7 +10,7 @@ import org.junit.jupiter.api.Test * * The getter is `true` when the current loaded swap state needs no approval: * - always when [PermissionDataState.Empty] - * - additionally for [PermissionDataState.PermissionSettings] when the integrated-approve toggle is ON + * - additionally for [PermissionDataState.PermissionSettings] */ internal class SwapModelIsPermissionNotNeededTest : SwapModelTestBase() { @@ -20,11 +19,7 @@ internal class SwapModelIsPermissionNotNeededTest : SwapModelTestBase() { setUpBase() } - private fun modelWithPermissionState( - permissionState: PermissionDataState, - isIntegratedApproveEnabled: Boolean, - ): SwapModel { - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns isIntegratedApproveEnabled + private fun modelWithPermissionState(permissionState: PermissionDataState): SwapModel { val provider = swapProvider() val model = createModel() model.dataState = model.dataState.copy( @@ -35,48 +30,23 @@ internal class SwapModelIsPermissionNotNeededTest : SwapModelTestBase() { } @Test - fun `GIVEN toggle OFF and Empty permission THEN permission is not needed`() { - val model = modelWithPermissionState(PermissionDataState.Empty, isIntegratedApproveEnabled = false) + fun `GIVEN Empty permission THEN permission is not needed`() { + val model = modelWithPermissionState(PermissionDataState.Empty) assertThat(model.isPermissionNotNeeded).isTrue() } @Test - fun `GIVEN toggle OFF and PermissionSettings THEN permission is needed`() { - val model = modelWithPermissionState(permissionSettings(), isIntegratedApproveEnabled = false) + fun `GIVEN PermissionSettings THEN permission is not needed`() { + val model = modelWithPermissionState(permissionSettings()) - assertThat(model.isPermissionNotNeeded).isFalse() + assertThat(model.isPermissionNotNeeded).isTrue() } @Test - fun `GIVEN toggle OFF and PermissionRequired THEN permission is needed`() { + fun `GIVEN PermissionRequired THEN permission is needed`() { val model = modelWithPermissionState( PermissionDataState.PermissionRequired(isResetApproval = false, spenderAddress = "0x"), - isIntegratedApproveEnabled = false, - ) - - assertThat(model.isPermissionNotNeeded).isFalse() - } - - @Test - fun `GIVEN toggle ON and Empty permission THEN permission is not needed`() { - val model = modelWithPermissionState(PermissionDataState.Empty, isIntegratedApproveEnabled = true) - - assertThat(model.isPermissionNotNeeded).isTrue() - } - - @Test - fun `GIVEN toggle ON and PermissionSettings THEN permission is not needed`() { - val model = modelWithPermissionState(permissionSettings(), isIntegratedApproveEnabled = true) - - assertThat(model.isPermissionNotNeeded).isTrue() - } - - @Test - fun `GIVEN toggle ON and PermissionRequired THEN permission is needed`() { - val model = modelWithPermissionState( - PermissionDataState.PermissionRequired(isResetApproval = false, spenderAddress = "0x"), - isIntegratedApproveEnabled = true, ) assertThat(model.isPermissionNotNeeded).isFalse() @@ -84,7 +54,6 @@ internal class SwapModelIsPermissionNotNeededTest : SwapModelTestBase() { @Test fun `GIVEN no current loaded state THEN permission is needed`() { - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns true val model = createModel() assertThat(model.isPermissionNotNeeded).isFalse() diff --git a/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelTestBase.kt b/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelTestBase.kt index 0e2f75bbb4..1011e1c31a 100644 --- a/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelTestBase.kt +++ b/features/swap/impl/src/test/java/com/tangem/feature/swap/model/SwapModelTestBase.kt @@ -130,7 +130,6 @@ internal abstract class SwapModelTestBase { coEvery { shouldShowStoriesUseCase.invokeSync(any()) } returns false coEvery { initialCurrenciesResolver.invoke(any(), any(), any(), any()) } returns (null to null) every { getSelectedAppCurrencyUseCase.invoke() } returns emptyFlow() - every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns true } protected fun createParams(): SwapComponent.Params = SwapComponent.Params( diff --git a/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt b/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt index edba3aca26..5185c7092e 100644 --- a/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt +++ b/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt @@ -2,9 +2,7 @@ package com.tangem.features.tangempay interface TangemPayFeatureToggles { val isRedesignEnabled: Boolean - val isCloseCardEnabled: Boolean val isRemoveAccountEnabled: Boolean - val isMultipleCardsEnabled: Boolean val isTiersPlusPlanEnabled: Boolean val isCashbackEnabled: Boolean } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt index a921969c70..2e74ccc4d7 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt @@ -7,18 +7,11 @@ internal class DefaultTangemPayFeatureToggles( private val featureTogglesManager: FeatureTogglesManager, ) : TangemPayFeatureToggles { override val isRedesignEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15368_VISA_PAY_REDESIGN) && - featureTogglesManager.isFeatureEnabled(FeatureToggles.APP_REDESIGN_ENABLED) - - override val isCloseCardEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15364_VISA_PAY_CARD_CLOSE) + get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.APP_REDESIGN_ENABLED) override val isRemoveAccountEnabled: Boolean get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15741_VISA_PAY_REMOVE_ACCOUNT) - override val isMultipleCardsEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15235_VISA_MULTIPLE_CARDS) - override val isTiersPlusPlanEnabled: Boolean get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_16041_VISA_TIERS_PLUS_PLAN) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt index 9c45b8f7d6..cace3cf205 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt @@ -35,7 +35,6 @@ internal class TangemPayDetailsStateFactory( private val intents: TangemPayDetailIntents, private val isRedesignEnabled: Boolean, private val isRemoveAccountEnabled: Boolean, - private val isMultipleCardsEnabled: Boolean, private val isTiersPlusPlanEnabled: Boolean, ) { private val notificationFactory = TangemPayDetailsNotificationFactory( @@ -100,7 +99,6 @@ internal class TangemPayDetailsStateFactory( ), cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState( cards = status.cards - .let { if (isMultipleCardsEnabled) it else it.take(1) } .map { cardItem -> TangemPayDetailsBalanceBlockState.Card( lastDigits = cardItem.lastDigits, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt index 2468874e6a..19c91bb8f3 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt @@ -110,7 +110,6 @@ internal class TangemPayCardPageModel @Inject constructor( private val cryptoCurrency get() = currentStatus.value.cryptoCurrency - private val isMultipleCardsEnabled: Boolean get() = tangemPayFeatureToggles.isMultipleCardsEnabled val uiState: StateFlow field = MutableStateFlow( @@ -185,7 +184,7 @@ internal class TangemPayCardPageModel @Inject constructor( val status = state.value if (status !is PaymentAccountStatusValue.Loaded || status.source != StatusSource.ACTUAL) return - val cards = status.cards.let { if (isMultipleCardsEnabled) it else it.take(1) } + val cards = status.cards val newIds = cards.mapTo(mutableSetOf()) { it.id } cardControllers.keys.filterNot { it in newIds }.toList().forEach { removedId -> @@ -334,30 +333,28 @@ internal class TangemPayCardPageModel @Inject constructor( ), ), ) - if (tangemPayFeatureToggles.isCloseCardEnabled) { - add( - TangemPayDropDownItemUM( - title = TextReference.Res(R.string.tangem_pay_close_card_popup_primary_button_title), - onClick = ::onClickCloseCard, - icon = TangemIconUM.Icon( - iconRes = CoreUiR.drawable.ic_trash_24, - tintReference = { - if (isLastCard) { - TangemTheme.colors3.icon.tertiary - } else { - TangemTheme.colors3.icon.primary - } - }, - ), - subtitle = if (isLastCard) { - TextReference.Res(R.string.tangem_pay_close_card_disabled_last_card) - } else { - null + add( + TangemPayDropDownItemUM( + title = TextReference.Res(R.string.tangem_pay_close_card_popup_primary_button_title), + onClick = ::onClickCloseCard, + icon = TangemIconUM.Icon( + iconRes = CoreUiR.drawable.ic_trash_24, + tintReference = { + if (isLastCard) { + TangemTheme.colors3.icon.tertiary + } else { + TangemTheme.colors3.icon.primary + } }, - isEnabled = !isLastCard, ), - ) - } + subtitle = if (isLastCard) { + TextReference.Res(R.string.tangem_pay_close_card_disabled_last_card) + } else { + null + }, + isEnabled = !isLastCard, + ), + ) }.toImmutableList() } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt index 56b784437f..6d8ad20dc2 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt @@ -111,15 +111,12 @@ internal class TangemPayDetailsModel @Inject constructor( val cryptoCurrency get() = currentStatus.value.cryptoCurrency - private val isMultipleCardsEnabled: Boolean get() = tangemPayFeatureToggles.isMultipleCardsEnabled - private val stateFactory = TangemPayDetailsStateFactory( onBack = router::pop, onOpenMenu = ::onOpenMenu, intents = this, isRedesignEnabled = isRedesignEnabled(), isRemoveAccountEnabled = tangemPayFeatureToggles.isRemoveAccountEnabled, - isMultipleCardsEnabled = isMultipleCardsEnabled, isTiersPlusPlanEnabled = tangemPayFeatureToggles.isTiersPlusPlanEnabled, ) @@ -476,17 +473,6 @@ internal class TangemPayDetailsModel @Inject constructor( override fun onAddCardClick() { analytics.send(TangemPayAnalyticsEvents.AddExtraCardClicked()) - if (!isMultipleCardsEnabled) { - analytics.send(TangemPayAnalyticsEvents.FakeDoorPopupDisplayed()) - uiMessageSender.send( - TangemPayMessagesFactory.createFutureFeature( - onGotItClick = { - analytics.send(TangemPayAnalyticsEvents.FakeDoorGotitClicked()) - }, - ), - ) - return - } modelScope.launch { val offer = getCustomerOffers.additionalCardOffer(userWalletId).getOrNull() if (offer == null) { diff --git a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt index b284e0e22e..d066aa49af 100644 --- a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt +++ b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt @@ -31,7 +31,6 @@ internal class TangemPayDetailsStateFactoryTest { intents = intents, isRedesignEnabled = true, isRemoveAccountEnabled = true, - isMultipleCardsEnabled = true, isTiersPlusPlanEnabled = true, ) diff --git a/features/tokendetails/api/src/main/kotlin/com/tangem/features/tokendetails/TokenDetailsFeatureToggles.kt b/features/tokendetails/api/src/main/kotlin/com/tangem/features/tokendetails/TokenDetailsFeatureToggles.kt deleted file mode 100644 index 5cf0e73735..0000000000 --- a/features/tokendetails/api/src/main/kotlin/com/tangem/features/tokendetails/TokenDetailsFeatureToggles.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.tangem.features.tokendetails - -interface TokenDetailsFeatureToggles { - val isQuickTopUpEnabled: Boolean - val isManageFundsEnabled: Boolean -} \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/DefaultTokenDetailsFeatureToggles.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/DefaultTokenDetailsFeatureToggles.kt deleted file mode 100644 index 24b973acdd..0000000000 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/DefaultTokenDetailsFeatureToggles.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.feature.tokendetails - -import com.tangem.core.configtoggle.FeatureToggles -import com.tangem.core.configtoggle.feature.FeatureTogglesManager -import com.tangem.features.tokendetails.TokenDetailsFeatureToggles -import javax.inject.Inject - -internal class DefaultTokenDetailsFeatureToggles @Inject constructor( - private val featureTogglesManager: FeatureTogglesManager, -) : TokenDetailsFeatureToggles { - - override val isQuickTopUpEnabled: Boolean = featureTogglesManager.isFeatureEnabled( - toggle = FeatureToggles.AND_15258_QUICK_TOP_UP_ENABLED, - ) - - override val isManageFundsEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.TWI_1377_MANAGE_FUNDS) -} \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/di/TokenDetailsFeatureModule.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/di/TokenDetailsFeatureModule.kt deleted file mode 100644 index 7797aba8a9..0000000000 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/di/TokenDetailsFeatureModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.feature.tokendetails.di - -import com.tangem.core.configtoggle.feature.FeatureTogglesManager -import com.tangem.feature.tokendetails.DefaultTokenDetailsFeatureToggles -import com.tangem.features.tokendetails.TokenDetailsFeatureToggles -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal object TokenDetailsFeatureModule { - - @Provides - @Singleton - fun provideTokenDetailsFeatureToggles(featureTogglesManager: FeatureTogglesManager): TokenDetailsFeatureToggles { - return DefaultTokenDetailsFeatureToggles(featureTogglesManager) - } -} \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactory.kt index 8b9fa14111..0ace5ba9b8 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactory.kt @@ -8,15 +8,12 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.onramp.model.OnrampAvailability import com.tangem.domain.onramp.model.error.OnrampError import com.tangem.feature.tokendetails.presentation.tokendetails.state.QuickTopUpBlockUM -import com.tangem.features.tokendetails.TokenDetailsFeatureToggles import com.tangem.utils.extensions.isZero import kotlinx.collections.immutable.toImmutableList import java.math.BigDecimal import javax.inject.Inject -internal class QuickTopUpBlockFactory @Inject constructor( - private val featureToggles: TokenDetailsFeatureToggles, -) { +internal class QuickTopUpBlockFactory @Inject constructor() { fun build( currencyStatus: CryptoCurrencyStatus, @@ -25,8 +22,6 @@ internal class QuickTopUpBlockFactory @Inject constructor( onPresetClick: (BigDecimal, String) -> Unit, onOtherClick: () -> Unit, ): QuickTopUpBlockUM? { - if (!featureToggles.isQuickTopUpEnabled) return null - val amount = currencyStatus.value.amount if (amount == null || !amount.isZero()) return null diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt index 5f00f4eaac..22b6ef8480 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt @@ -20,7 +20,6 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTr import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.ExchangeStatusNotification import com.tangem.feature.tokendetails.presentation.tokendetails.state.express.ExchangeUM import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.express.ExpressStatusBottomSheet -import com.tangem.features.swap.SwapFeatureToggles import com.tangem.utils.Provider import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.assisted.Assisted @@ -47,7 +46,6 @@ internal class ExpressStatusFactory @AssistedInject constructor( private val analyticsEventsHandler: AnalyticsEventHandler, onrampStatusFactory: OnrampStatusFactory.Factory, exchangeStatusFactory: ExchangeStatusFactory.Factory, - private val swapFeatureToggles: SwapFeatureToggles, private val txHistoryFeatureToggles: TxHistoryFeatureToggles, ) { @@ -221,7 +219,6 @@ internal class ExpressStatusFactory @AssistedInject constructor( is ExpressStatusBottomSheetConfig -> ExpressStatusBottomSheet( config = this, extraContent = extraContent, - isExpressShareButtonEnabled = swapFeatureToggles.isExpressShareButtonEnabled, ) } } diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/ExpressStatusBottomSheet.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/ExpressStatusBottomSheet.kt index 4378035f1f..be9426edb2 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/ExpressStatusBottomSheet.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/ExpressStatusBottomSheet.kt @@ -21,44 +21,28 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.e @Composable internal fun ExpressStatusBottomSheet( config: TangemBottomSheetConfig, - isExpressShareButtonEnabled: Boolean, extraContent: (@Composable () -> Unit)? = null, ) { TangemBottomSheet( config = config, containerColor = TangemTheme.colors.background.tertiary, ) { content: ExpressStatusBottomSheetConfig -> - if (isExpressShareButtonEnabled) { - Box { - when (val state = content.value) { - is ExpressTransactionStateUM.OnrampUM -> OnrampStatusBottomSheetContent( - state = state, - isExpressShareButtonEnabled = true, - ) - is ExchangeUM -> ExchangeStatusBottomSheetContent( - state = state, - extraContent = extraContent, - isExpressShareButtonEnabled = true, - ) - } - BottomFade( - backgroundColor = TangemTheme.colors.background.tertiary, - modifier = Modifier.align(Alignment.BottomCenter), - ) - ExpressShareContent(state = content.value) - } - } else { + Box { when (val state = content.value) { is ExpressTransactionStateUM.OnrampUM -> OnrampStatusBottomSheetContent( state = state, - isExpressShareButtonEnabled = false, + isExpressShareButtonEnabled = true, ) is ExchangeUM -> ExchangeStatusBottomSheetContent( state = state, extraContent = extraContent, - isExpressShareButtonEnabled = false, ) } + BottomFade( + backgroundColor = TangemTheme.colors.background.tertiary, + modifier = Modifier.align(Alignment.BottomCenter), + ) + ExpressShareContent(state = content.value) } } } @@ -76,7 +60,6 @@ private fun PreviewExpressStatusBottomSheet( onDismissRequest = {}, content = param, ), - isExpressShareButtonEnabled = false, ) } } \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt index d28fe50927..72b22709c5 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt @@ -25,7 +25,6 @@ import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.SpacerH10 import com.tangem.core.ui.components.SpacerH12 import com.tangem.core.ui.components.SpacerH16 -import com.tangem.core.ui.components.SpacerH24 import com.tangem.core.ui.components.notifications.CurrencyNotification import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringResourceSafe @@ -38,11 +37,7 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.express.E import kotlinx.collections.immutable.toImmutableList @Composable -internal fun ExchangeStatusBottomSheetContent( - state: ExchangeUM, - isExpressShareButtonEnabled: Boolean, - extraContent: (@Composable () -> Unit)? = null, -) { +internal fun ExchangeStatusBottomSheetContent(state: ExchangeUM, extraContent: (@Composable () -> Unit)? = null) { Column( modifier = Modifier .padding(horizontal = TangemTheme.dimens.spacing16) @@ -97,11 +92,7 @@ internal fun ExchangeStatusBottomSheetContent( isAutoDisposable = state.activeStatus?.isAutoDisposable == true, onClick = state.info.onDisposeExpressStatus, ) - if (isExpressShareButtonEnabled) { - SpacerH(80.dp) - } else { - SpacerH24() - } + SpacerH(80.dp) } } diff --git a/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactoryTest.kt b/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactoryTest.kt index a9a6c479a3..0ca54aa561 100644 --- a/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactoryTest.kt +++ b/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/QuickTopUpBlockFactoryTest.kt @@ -11,7 +11,6 @@ import com.tangem.domain.onramp.model.OnrampAvailability import com.tangem.domain.onramp.model.OnrampCountry import com.tangem.domain.onramp.model.OnrampCurrency import com.tangem.domain.onramp.model.error.OnrampError -import com.tangem.features.tokendetails.TokenDetailsFeatureToggles import io.mockk.every import io.mockk.mockk import org.junit.jupiter.api.Test @@ -19,10 +18,7 @@ import java.math.BigDecimal internal class QuickTopUpBlockFactoryTest { - private val featureToggles: TokenDetailsFeatureToggles = mockk { - every { isQuickTopUpEnabled } returns true - } - private val factory = QuickTopUpBlockFactory(featureToggles) + private val factory = QuickTopUpBlockFactory() private val zeroBalanceStatus: CryptoCurrencyStatus = mockk { every { value } returns mockk { @@ -69,24 +65,6 @@ internal class QuickTopUpBlockFactoryTest { private val notSupported: OnrampAvailability = OnrampAvailability.NotSupported(country = countryMock) - @Test - fun `returns null when feature toggle is disabled`() { - val disabledToggles: TokenDetailsFeatureToggles = mockk { - every { isQuickTopUpEnabled } returns false - } - val disabledFactory = QuickTopUpBlockFactory(disabledToggles) - - val result = disabledFactory.build( - currencyStatus = zeroBalanceStatus, - isHistoryEmpty = true, - onrampAvailability = availableUsd.right(), - onPresetClick = { _, _ -> }, - onOtherClick = {}, - ) - - assertThat(result).isNull() - } - @Test fun `returns null when balance is non-zero`() { val result = factory.build( diff --git a/features/wallet/api/src/main/kotlin/com/tangem/features/wallet/featuretoggles/WalletFeatureToggles.kt b/features/wallet/api/src/main/kotlin/com/tangem/features/wallet/featuretoggles/WalletFeatureToggles.kt deleted file mode 100644 index fd5149ae02..0000000000 --- a/features/wallet/api/src/main/kotlin/com/tangem/features/wallet/featuretoggles/WalletFeatureToggles.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.tangem.features.wallet.featuretoggles - -/** - * Wallet feature toggles - * -[REDACTED_AUTHOR] - */ -interface WalletFeatureToggles { - - val isManageFundsEnabled: Boolean -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index 25f9789417..be97d76ac4 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -67,7 +67,6 @@ import com.tangem.features.biometry.AskBiometryComponent import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks import com.tangem.features.pushnotificationsettings.PushNotificationSettingsFeatureToggles import com.tangem.features.wallet.deeplink.WalletDeepLinkActionListener -import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import com.tangem.utils.Provider import com.tangem.utils.coroutines.* import com.tangem.utils.logging.TangemLogger @@ -125,7 +124,6 @@ internal class WalletModel @Inject constructor( private val resolveQrSendTargetsUseCase: ResolveQrSendTargetsUseCase, private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher, private val uiMessageSender: UiMessageSender, - private val walletFeatureToggles: WalletFeatureToggles, private val pushNotificationSettingsFeatureToggles: PushNotificationSettingsFeatureToggles, private val addressBookFeatureToggles: AddressBookFeatureToggles, private val startAssetsDiscoveryUseCase: StartAssetsDiscoveryUseCase, @@ -577,7 +575,6 @@ internal class WalletModel @Inject constructor( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = walletFeatureToggles.isManageFundsEnabled, ), ) @@ -624,7 +621,6 @@ internal class WalletModel @Inject constructor( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = walletFeatureToggles.isManageFundsEnabled, ), ) } @@ -646,7 +642,6 @@ internal class WalletModel @Inject constructor( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = walletFeatureToggles.isManageFundsEnabled, ), ) } @@ -663,7 +658,6 @@ internal class WalletModel @Inject constructor( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = walletFeatureToggles.isManageFundsEnabled, ), ) @@ -725,7 +719,6 @@ internal class WalletModel @Inject constructor( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = walletFeatureToggles.isManageFundsEnabled, ), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/di/WalletFeatureTogglesModule.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/di/WalletFeatureTogglesModule.kt deleted file mode 100644 index aa51974608..0000000000 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/di/WalletFeatureTogglesModule.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.feature.wallet.di - -import com.tangem.feature.wallet.featuretoggles.DefaultWalletFeatureToggles -import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal interface WalletFeatureTogglesModule { - - @Singleton - @Binds - fun bindWalletFeatureToggles(toggles: DefaultWalletFeatureToggles): WalletFeatureToggles -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/featuretoggles/DefaultWalletFeatureToggles.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/featuretoggles/DefaultWalletFeatureToggles.kt deleted file mode 100644 index 3f20073d42..0000000000 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/featuretoggles/DefaultWalletFeatureToggles.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.feature.wallet.featuretoggles - -import com.tangem.core.configtoggle.FeatureToggles -import com.tangem.core.configtoggle.feature.FeatureTogglesManager -import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles -import javax.inject.Inject - -internal class DefaultWalletFeatureToggles @Inject constructor( - private val featureToggles: FeatureTogglesManager, -) : WalletFeatureToggles { - - override val isManageFundsEnabled: Boolean - get() = featureToggles.isFeatureEnabled(FeatureToggles.TWI_1377_MANAGE_FUNDS) -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt index ea3bcea7f4..12121428f1 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt @@ -13,7 +13,6 @@ internal class AddWalletTransformer( private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, private val getWalletIconUseCase: GetWalletIconUseCase, - private val isManageFundsEnabled: Boolean, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { @@ -21,7 +20,6 @@ internal class AddWalletTransformer( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = isManageFundsEnabled, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt index 765ba717bd..64f0a4d958 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt @@ -28,7 +28,6 @@ internal class InitializeWalletsTransformer( private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, private val getWalletIconUseCase: GetWalletIconUseCase, - private val isManageFundsEnabled: Boolean, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { @@ -36,7 +35,6 @@ internal class InitializeWalletsTransformer( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = isManageFundsEnabled, ) } @@ -156,11 +154,7 @@ internal class InitializeWalletsTransformer( onClick = {}, ) - val lastButton = if (isManageFundsEnabled) { - WalletManageButton.Transfer(enabled = false, dimContent = false, onClick = {}) - } else { - WalletManageButton.Sell(enabled = false, dimContent = false, onClick = {}) - } + val lastButton = WalletManageButton.Transfer(enabled = false, dimContent = false, onClick = {}) return persistentListOf( firstButton, @@ -193,21 +187,12 @@ internal class InitializeWalletsTransformer( onClick = {}, ).buttonUM, ) - if (isManageFundsEnabled) { - add( - WalletActionButtons.Transfer( - isEnabled = false, - onClick = {}, - ).buttonUM, - ) - } else { - add( - WalletActionButtons.Sell( - isEnabled = false, - onClick = {}, - ).buttonUM, - ) - } + add( + WalletActionButtons.Transfer( + isEnabled = false, + onClick = {}, + ).buttonUM, + ) }.toPersistentList() } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt index 0d82b17d84..22744505bd 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt @@ -25,7 +25,6 @@ internal class ReinitializeNewWalletTransformer( private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, private val getWalletIconUseCase: GetWalletIconUseCase, - private val isManageFundsEnabled: Boolean, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { @@ -33,7 +32,6 @@ internal class ReinitializeNewWalletTransformer( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = isManageFundsEnabled, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt index 98cd5a5786..6dab085776 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt @@ -20,7 +20,6 @@ internal class ReinitializeWalletTransformer( private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, private val getWalletIconUseCase: GetWalletIconUseCase, - private val isManageFundsEnabled: Boolean, ) : WalletStateTransformer(userWalletId = userWallet.walletId) { private val walletLoadingStateFactory by lazy { @@ -28,7 +27,6 @@ internal class ReinitializeWalletTransformer( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = isManageFundsEnabled, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt index 938f21813a..338f14a576 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt @@ -18,7 +18,6 @@ internal class UnlockWalletTransformer( private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, private val getWalletIconUseCase: GetWalletIconUseCase, - private val isManageFundsEnabled: Boolean, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { @@ -26,7 +25,6 @@ internal class UnlockWalletTransformer( clickIntents = clickIntents, walletImageResolver = walletImageResolver, getWalletIconUseCase = getWalletIconUseCase, - isManageFundsEnabled = isManageFundsEnabled, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt index 8248f0d35c..edfaea0f65 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt @@ -34,7 +34,6 @@ internal class WalletLoadingStateFactory( private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, private val getWalletIconUseCase: GetWalletIconUseCase, - private val isManageFundsEnabled: Boolean, ) { fun create(userWallet: UserWallet): WalletState { @@ -157,19 +156,11 @@ internal class WalletLoadingStateFactory( onClick = { clickIntents.onAddFundsClick(userWallet.walletId) }, ) - val lastButton = if (isManageFundsEnabled) { - WalletManageButton.Transfer( - enabled = true, - dimContent = false, - onClick = { clickIntents.onTransferClick(userWallet.walletId) }, - ) - } else { - WalletManageButton.Sell( - enabled = true, - dimContent = false, - onClick = { clickIntents.onMultiWalletSellClick(userWalletId = userWallet.walletId) }, - ) - } + val lastButton = WalletManageButton.Transfer( + enabled = true, + dimContent = false, + onClick = { clickIntents.onTransferClick(userWallet.walletId) }, + ) return persistentListOf( firstButton, @@ -201,25 +192,14 @@ internal class WalletLoadingStateFactory( }, ).buttonUM, ) - if (isManageFundsEnabled) { - add( - WalletActionButtons.Transfer( - isEnabled = false, - onClick = { - clickIntents.onTransferClick(userWalletId = userWallet.walletId) - }, - ).buttonUM, - ) - } else { - add( - WalletActionButtons.Sell( - isEnabled = false, - onClick = { - clickIntents.onMultiWalletSellClick(userWalletId = userWallet.walletId) - }, - ).buttonUM, - ) - } + add( + WalletActionButtons.Transfer( + isEnabled = false, + onClick = { + clickIntents.onTransferClick(userWalletId = userWallet.walletId) + }, + ).buttonUM, + ) }.toPersistentList() } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt index d7fc0ea146..051fcae3a8 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt @@ -13,7 +13,6 @@ import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.account.AccountDependencies import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.features.polymarket.api.PolymarketFeatureToggles -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.utils.coroutines.combine7 import com.tangem.utils.logging.TangemLogger import dagger.assisted.Assisted @@ -39,7 +38,6 @@ internal class AccountListSubscriber @AssistedInject constructor( private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase, private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase, private val designFeatureToggles: DesignFeatureToggles, - private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val polymarketFeatureToggles: PolymarketFeatureToggles, ) : BasicAccountListSubscriber() { @@ -94,7 +92,7 @@ internal class AccountListSubscriber @AssistedInject constructor( yieldSupplyApyMap = yieldSupplyApyMap, stakingAvailabilityMap = stakingAvailabilityMap, shouldShowMainPromo = shouldShowMainPromo, - isMultipleCardsEnabled = tangemPayFeatureToggles.isMultipleCardsEnabled, + isMultipleCardsEnabled = true, isPolymarketEnabled = polymarketFeatureToggles.isPolymarketEnabled, ) } else { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletSubscriber.kt index e848c342a2..57900c51fe 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletSubscriber.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletSubscriber.kt @@ -5,7 +5,6 @@ import com.tangem.domain.models.wallet.UserWallet import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.account.AccountDependencies import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.features.tangempay.TangemPayFeatureToggles import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -21,7 +20,6 @@ internal class SingleWalletSubscriber @AssistedInject constructor( override val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, override val stateController: WalletStateController, override val clickIntents: WalletClickIntents, - private val tangemPayFeatureToggles: TangemPayFeatureToggles, ) : BasicAccountListSubscriber() { override fun create(coroutineScope: CoroutineScope): Flow = combine( @@ -29,7 +27,7 @@ internal class SingleWalletSubscriber @AssistedInject constructor( flow2 = getAppCurrencyFlow(), flow3 = accountDependencies.expandedAccountsHolder.expandedAccounts(userWallet), flow4 = accountDependencies.isAccountsModeEnabledUseCase(), - flow5 = flowOf(tangemPayFeatureToggles.isMultipleCardsEnabled), + flow5 = flowOf(true), transform = ::updateState2, ) diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/WalletManagerFactoryCreator.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/WalletManagerFactoryCreator.kt index 0c98fa60be..3466709d1c 100644 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/WalletManagerFactoryCreator.kt +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/WalletManagerFactoryCreator.kt @@ -42,7 +42,7 @@ internal class WalletManagerFactoryCreator @Inject constructor( isSolanaTxHistoryEnabled = true, isSolanaScaledUiAmountEnabled = true, isHederaErc20Enabled = true, - isStateOverrideGasEstimateEnabled = featureToggleValues.isStateOverrideGasEstimateEnabled, + isStateOverrideGasEstimateEnabled = true, ), blockchainDataStorage = blockchainDataStorage, loggers = listOf(blockchainSDKLogger), @@ -51,6 +51,5 @@ internal class WalletManagerFactoryCreator @Inject constructor( data class FeatureToggleValues( val isYieldModeSwapEnabled: Boolean, - val isStateOverrideGasEstimateEnabled: Boolean, ) } \ No newline at end of file diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/di/BlockchainSDKFactoryModule.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/di/BlockchainSDKFactoryModule.kt index 040608ca93..5aee40a60f 100644 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/di/BlockchainSDKFactoryModule.kt +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/di/BlockchainSDKFactoryModule.kt @@ -101,9 +101,6 @@ internal object BlockchainSDKFactoryModule { isYieldModeSwapEnabled = featureTogglesManager.isFeatureEnabled( FeatureToggles.TWI_1326_YIELD_MODE_SWAP_ENABLED, ), - isStateOverrideGasEstimateEnabled = featureTogglesManager.isFeatureEnabled( - FeatureToggles.AND_15120_SWAP_INTEGRATED_APPROVE, - ), ), ) }