From 319f62f0082033b831ff7bce8869c09391361327 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Dec 2025 17:45:47 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../main/assets/configs/feature_toggles_config.json | 4 ++++ data/visa/build.gradle.kts | 3 +++ .../data/pay/DefaultTangemPayEligibilityManager.kt | 12 +++++------- .../com/tangem/data/pay/di/TangemPayDataModule.kt | 3 +++ domain/visa/build.gradle.kts | 3 +++ .../TangemPayMainScreenCustomerInfoUseCase.kt | 13 ++++++++++--- .../tangem/features/details/model/DetailsModel.kt | 2 +- .../tangem/features/details/utils/ItemsBuilder.kt | 11 +++++++---- .../features/tangempay/TangemPayFeatureToggles.kt | 1 + .../tangempay/DefaultTangemPayFeatureToggles.kt | 2 ++ .../wallet/model/intents/TangemPayClickIntents.kt | 11 ++++++++++- 11 files changed, 49 insertions(+), 16 deletions(-) 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 dce534df8d..1cb7bb7d24 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,6 +39,10 @@ "name": "TANGEM_PAY_ENABLED", "version": "5.31.0" }, + { + "name": "TANGEM_PAY_ENTRYPOINT_ENABLED", + "version": "undefined" + }, { "name": "NEW_TOKEN_RECEIVE_ENABLED", "version": "5.28.0" diff --git a/data/visa/build.gradle.kts b/data/visa/build.gradle.kts index f893a530d6..e1e1568878 100644 --- a/data/visa/build.gradle.kts +++ b/data/visa/build.gradle.kts @@ -39,6 +39,9 @@ dependencies { /** Feature API - remove after removing [HotWalletFeatureToggles] */ implementation(projects.features.hotWallet.api) + /** Feature API - remove after removing [TangemPayFeatureToggles] */ + implementation(projects.features.tangempay.details.api) + /** Project - Utils */ implementation(projects.core.utils) implementation(projects.domain.legacy) diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt index 4ab4d074f2..7ccc87275c 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt @@ -9,15 +9,10 @@ import com.tangem.domain.pay.TangemPayEligibilityManager import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.features.hotwallet.HotWalletFeatureToggles +import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.* import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import javax.inject.Inject @@ -27,6 +22,7 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor( private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, private val hotWalletFeatureToggles: HotWalletFeatureToggles, + private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val onboardingRepository: OnboardingRepository, ) : TangemPayEligibilityManager { @@ -130,6 +126,8 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor( } private suspend fun checkTangemPayEligibility(): Boolean { + if (!tangemPayFeatureToggles.isEntryPointsEnabled) return true + return onboardingRepository.getCustomerEligibility() || onboardingRepository.checkCustomerEligibility() } diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt index 719542728a..93f2455ffb 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt @@ -13,6 +13,7 @@ import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase import com.tangem.domain.tangempay.TangemPayWithdrawUseCase import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository +import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.security.DeviceSecurityInfoProvider import dagger.Binds import dagger.Module @@ -77,12 +78,14 @@ internal interface TangemPayDataModule { customerOrderRepository: CustomerOrderRepository, tangemPayOnboardingRepository: OnboardingRepository, eligibilityManager: TangemPayEligibilityManager, + tangemPayFeatureToggles: TangemPayFeatureToggles, deviceSecurity: DeviceSecurityInfoProvider, ): TangemPayMainScreenCustomerInfoUseCase { return TangemPayMainScreenCustomerInfoUseCase( onboardingRepository = repository, customerOrderRepository = customerOrderRepository, eligibilityManager = eligibilityManager, + tangemPayFeatureToggles = tangemPayFeatureToggles, deviceSecurity = deviceSecurity, ) } diff --git a/domain/visa/build.gradle.kts b/domain/visa/build.gradle.kts index 3c13ebe644..3dfad027a7 100644 --- a/domain/visa/build.gradle.kts +++ b/domain/visa/build.gradle.kts @@ -25,6 +25,9 @@ dependencies { implementation(projects.domain.tokens.models) implementation(projects.domain.wallets.models) + /** Feature API - remove after removing [TangemPayFeatureToggles] */ + implementation(projects.features.tangempay.details.api) + /** Security */ implementation(deps.spongecastle.core) diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayMainScreenCustomerInfoUseCase.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayMainScreenCustomerInfoUseCase.kt index 16ebd064e6..78d8486b32 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayMainScreenCustomerInfoUseCase.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayMainScreenCustomerInfoUseCase.kt @@ -9,6 +9,7 @@ import com.tangem.domain.pay.model.* import com.tangem.domain.pay.repository.CustomerOrderRepository import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.visa.error.VisaApiError +import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.security.DeviceSecurityInfoProvider import com.tangem.security.isSecurityExposed import kotlinx.coroutines.flow.* @@ -24,6 +25,7 @@ class TangemPayMainScreenCustomerInfoUseCase( private val onboardingRepository: OnboardingRepository, private val customerOrderRepository: CustomerOrderRepository, private val eligibilityManager: TangemPayEligibilityManager, + private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val deviceSecurity: DeviceSecurityInfoProvider, ) { @@ -46,7 +48,7 @@ class TangemPayMainScreenCustomerInfoUseCase( .fold( ifLeft = { error -> Timber.tag(TAG).e("Failed checkCustomerWallet for $userWalletId: ${error.javaClass.simpleName}") - if (error is VisaApiError.NotPaeraCustomer) { + if (error is VisaApiError.NotPaeraCustomer && tangemPayFeatureToggles.isEntryPointsEnabled) { showOnboardingBannerIfEligible(userWalletId) } else { updateState(userWalletId, TangemPayCustomerInfoError.UnknownError.left()) @@ -64,8 +66,13 @@ class TangemPayMainScreenCustomerInfoUseCase( .map(MainCustomerInfoContentState::Content) updateState(userWalletId, result) } else { - // if there's no tangem pay, check eligibility and show onboarding banner - showOnboardingBannerIfEligible(userWalletId) + if (tangemPayFeatureToggles.isEntryPointsEnabled) { + // if there's no tangem pay, check eligibility and show onboarding banner + showOnboardingBannerIfEligible(userWalletId) + } else { + // ignore if there's no TangemPay + updateState(userWalletId, TangemPayCustomerInfoError.UnknownError.left()) + } } }, ) diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt index 992afae4ac..1c4c53f372 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt @@ -248,7 +248,7 @@ internal class DetailsModel @Inject constructor( } private fun addTangemPayItemIfEligible() { - if (!tangemPayFeatureToggles.isTangemPayEnabled) return + if (!tangemPayFeatureToggles.isEntryPointsEnabled) return modelScope.launch { val isEligible = tangemPayEligibilityManager .getEligibleWallets(shouldExcludePaeraCustomers = true) diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt index c8627bf1ea..7ee2b6eccd 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt @@ -54,10 +54,13 @@ internal class ItemsBuilder @Inject constructor(private val router: Router) { } fun removeTangemPayItem(items: ImmutableList): ImmutableList { - val tangemPayItem = items.find { it.id == TANGEM_PAY_ITEM_ID } ?: return items - return items.toMutableList() - .also { list -> list.remove(tangemPayItem) } - .toImmutableList() + return items.map { block -> + if (block is DetailsItemUM.Basic && block.items.any { it.id == TANGEM_PAY_ITEM_ID }) { + block.copy(items = block.items.filter { it.id != TANGEM_PAY_ITEM_ID }.toImmutableList()) + } else { + block + } + }.toImmutableList() } private fun buildWalletConnectBlock(isWalletConnectAvailable: Boolean, userWalletId: UserWalletId): DetailsItemUM? { 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 393e589bce..0345c3cb32 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,4 +2,5 @@ package com.tangem.features.tangempay interface TangemPayFeatureToggles { val isTangemPayEnabled: Boolean + val isEntryPointsEnabled: 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 a51c11a3bc..9b909186a0 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,4 +7,6 @@ internal class DefaultTangemPayFeatureToggles( ) : TangemPayFeatureToggles { override val isTangemPayEnabled get() = featureTogglesManager.isFeatureEnabled("TANGEM_PAY_ENABLED") + override val isEntryPointsEnabled: Boolean + get() = featureTogglesManager.isFeatureEnabled("TANGEM_PAY_ENTRYPOINT_ENABLED") } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt index 7fc89a52ab..1a485dbf1d 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt @@ -14,6 +14,7 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.TangemPayDetailsConfig +import com.tangem.domain.pay.TangemPayEligibilityManager import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase @@ -55,6 +56,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase, private val tangemPayOnboardingRepository: OnboardingRepository, + private val tangemPayEligibilityManager: TangemPayEligibilityManager, private val uiMessageSender: UiMessageSender, ) : BaseWalletClickIntents(), TangemPayIntents { @@ -176,7 +178,14 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( } override fun onOnboardingBannerClick(userWalletId: UserWalletId) { - router.openTangemPayOnboarding(mode = AppRoute.TangemPayOnboarding.Mode.FromBannerOnMain(userWalletId)) + modelScope.launch { + val isEligible = tangemPayEligibilityManager.getTangemPayAvailability() + if (isEligible) { + router.openTangemPayOnboarding(mode = AppRoute.TangemPayOnboarding.Mode.FromBannerOnMain(userWalletId)) + } else { + tangemPayMainScreenCustomerInfoUseCase.fetch(userWalletId) + } + } } override fun onOnboardingBannerCloseClick(userWalletId: UserWalletId) {