Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-08 19:26:33 +03:00
parent b3ed607c1a
commit b9a2ab5fed
11 changed files with 71 additions and 16 deletions

View file

@ -660,8 +660,13 @@ internal class ChildFactory @Inject constructor(
createComponentChild( createComponentChild(
context = context, context = context,
params = when (val mode = route.mode) { params = when (val mode = route.mode) {
is AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding -> ContinueOnboarding is AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding -> ContinueOnboarding(
is AppRoute.TangemPayOnboarding.Mode.Deeplink -> Deeplink(deeplink = mode.deeplink) userWalletId = mode.userWalletId,
)
is AppRoute.TangemPayOnboarding.Mode.Deeplink -> Deeplink(
deeplink = mode.deeplink,
userWalletId = mode.userWalletId,
)
}, },
componentFactory = tangemPayOnboardingComponentFactory, componentFactory = tangemPayOnboardingComponentFactory,
) )

View file

@ -431,10 +431,13 @@ sealed class AppRoute(val path: String) : Route {
@Serializable @Serializable
data class Deeplink( data class Deeplink(
val deeplink: String, val deeplink: String,
val userWalletId: UserWalletId?,
) : Mode() ) : Mode()
@Serializable @Serializable
object ContinueOnboarding : Mode() data class ContinueOnboarding(
val userWalletId: UserWalletId?,
) : Mode()
} }
} }

View file

@ -33,7 +33,6 @@ class TangemPayWalletsManager @Inject constructor(
private fun findColdWallet(userWallets: List<UserWallet>?): UserWallet.Cold { private fun findColdWallet(userWallets: List<UserWallet>?): UserWallet.Cold {
return userWallets?.find { return userWallets?.find {
it is UserWallet.Cold && it.isMultiCurrency it is UserWallet.Cold && it.isMultiCurrency
} as? UserWallet.Cold } as? UserWallet.Cold ?: error("Cannot find cold user wallet")
?: error("Cannot find cold user wallet")
} }
} }

View file

@ -13,6 +13,9 @@ dependencies {
implementation(projects.core.decompose) implementation(projects.core.decompose)
implementation(projects.core.ui) implementation(projects.core.ui)
/** Domain */
implementation(projects.domain.models)
/** Compose */ /** Compose */
implementation(deps.compose.runtime) implementation(deps.compose.runtime)
} }

View file

@ -2,15 +2,22 @@ package com.tangem.features.tangempay.components
import com.tangem.core.decompose.factory.ComponentFactory import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.models.wallet.UserWalletId
interface TangemPayOnboardingComponent : ComposableContentComponent { interface TangemPayOnboardingComponent : ComposableContentComponent {
sealed class Params { sealed class Params {
abstract val userWalletId: UserWalletId?
data class Deeplink( data class Deeplink(
val deeplink: String, val deeplink: String,
override val userWalletId: UserWalletId?,
) : Params() ) : Params()
object ContinueOnboarding : Params() data class ContinueOnboarding(
override val userWalletId: UserWalletId?,
) : Params()
} }
interface Factory : ComponentFactory<Params, TangemPayOnboardingComponent> interface Factory : ComponentFactory<Params, TangemPayOnboardingComponent>

View file

@ -30,6 +30,7 @@ dependencies {
/** Domain */ /** Domain */
implementation(projects.domain.visa) implementation(projects.domain.visa)
implementation(projects.domain.wallets)
/** Data **/ /** Data **/
implementation(projects.data.visa) implementation(projects.data.visa)

View file

@ -1,10 +1,11 @@
package com.tangem.features.tangempay.deeplink package com.tangem.features.tangempay.deeplink
import android.net.Uri import android.net.Uri
import dagger.assisted.Assisted
import com.tangem.common.routing.AppRoute import com.tangem.common.routing.AppRoute
import com.tangem.features.tangempay.TangemPayFeatureToggles
import com.tangem.common.routing.AppRouter import com.tangem.common.routing.AppRouter
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.features.tangempay.TangemPayFeatureToggles
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
@ -12,11 +13,16 @@ internal class DefaultOnboardVisaDeepLinkHandler @AssistedInject constructor(
@Assisted uri: Uri, @Assisted uri: Uri,
appRouter: AppRouter, appRouter: AppRouter,
tangemPayFeatureToggles: TangemPayFeatureToggles, tangemPayFeatureToggles: TangemPayFeatureToggles,
getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
) : OnboardVisaDeepLinkHandler { ) : OnboardVisaDeepLinkHandler {
init { init {
if (tangemPayFeatureToggles.isTangemPayEnabled) { if (tangemPayFeatureToggles.isTangemPayEnabled) {
val mode = AppRoute.TangemPayOnboarding.Mode.Deeplink(uri.toString()) val userWallet = getSelectedWalletSyncUseCase.invoke().getOrNull()
val mode = AppRoute.TangemPayOnboarding.Mode.Deeplink(
deeplink = uri.toString(),
userWalletId = userWallet?.walletId,
)
appRouter.push(AppRoute.TangemPayOnboarding(mode)) appRouter.push(AppRoute.TangemPayOnboarding(mode))
} else { } else {
appRouter.push(AppRoute.Home()) appRouter.push(AppRoute.Home())

View file

@ -9,9 +9,13 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router import com.tangem.core.decompose.navigation.Router
import com.tangem.core.navigation.url.UrlOpener import com.tangem.core.navigation.url.UrlOpener
import com.tangem.data.pay.util.TangemPayWalletsManager import com.tangem.data.pay.util.TangemPayWalletsManager
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.pay.repository.OnboardingRepository
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.tangempay.TangemPayConstants import com.tangem.features.tangempay.TangemPayConstants
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent import com.tangem.features.tangempay.components.TangemPayOnboardingComponent
import com.tangem.features.tangempay.model.transformers.TangemPayOnboardingButtonLoadingTransformer import com.tangem.features.tangempay.model.transformers.TangemPayOnboardingButtonLoadingTransformer
@ -37,6 +41,8 @@ internal class TangemPayOnboardingModel @Inject constructor(
private val produceInitialDataUseCase: ProduceTangemPayInitialDataUseCase, private val produceInitialDataUseCase: ProduceTangemPayInitialDataUseCase,
private val urlOpener: UrlOpener, private val urlOpener: UrlOpener,
private val tangemPayWalletsManager: TangemPayWalletsManager, private val tangemPayWalletsManager: TangemPayWalletsManager,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val getSelectedWalletUseCase: GetSelectedWalletUseCase,
) : Model() { ) : Model() {
private val params = paramsContainer.require<TangemPayOnboardingComponent.Params>() private val params = paramsContainer.require<TangemPayOnboardingComponent.Params>()
@ -74,8 +80,9 @@ internal class TangemPayOnboardingModel @Inject constructor(
private suspend fun checkCustomerInfo() { private suspend fun checkCustomerInfo() {
// TODO implement selector // TODO implement selector
val userWalletId = getUserWalletForPay(params.userWalletId)
repository.getCustomerInfo( repository.getCustomerInfo(
userWalletId = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking().walletId, userWalletId = userWalletId,
) )
// selector // selector
.onRight { customerInfo -> .onRight { customerInfo ->
@ -92,6 +99,24 @@ internal class TangemPayOnboardingModel @Inject constructor(
.onLeft { back() } .onLeft { back() }
} }
private fun getUserWalletForPay(userWalletId: UserWalletId?): UserWalletId {
val userWallet = userWalletId?.let { getUserWalletUseCase(it).getOrNull() }
return if (userWallet?.isMultiCurrency == true) {
userWallet.walletId
} else {
tryGetSelectedWalletId()
}
}
private fun tryGetSelectedWalletId(): UserWalletId {
val selectedWallet = getSelectedWalletUseCase.sync().getOrNull()
return if (selectedWallet?.isMultiCurrency == true) {
selectedWallet.walletId
} else {
tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking().walletId
}
}
private fun onTermsClick() { private fun onTermsClick() {
analytics.send(TangemPayAnalyticsEvents.ViewTermsClicked) analytics.send(TangemPayAnalyticsEvents.ViewTermsClicked)
urlOpener.openUrl(TangemPayConstants.TERMS_AND_LIMITS_LINK) urlOpener.openUrl(TangemPayConstants.TERMS_AND_LIMITS_LINK)
@ -102,7 +127,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = true)) uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = true))
modelScope.launch { modelScope.launch {
// TODO implement selector // TODO implement selector
val userWalletId = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking().walletId val userWalletId = getUserWalletForPay(params.userWalletId)
val result = produceInitialDataUseCase(userWalletId) val result = produceInitialDataUseCase(userWalletId)
if (result.isLeft()) { if (result.isLeft()) {
Timber.e("Error producing initial data: ${result.leftOrNull()?.message}") Timber.e("Error producing initial data: ${result.leftOrNull()?.message}")
@ -134,7 +159,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
router.replaceAll( router.replaceAll(
AppRoute.Wallet, AppRoute.Wallet,
AppRoute.Kyc( AppRoute.Kyc(
userWalletId = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking().walletId, userWalletId = getUserWalletForPay(params.userWalletId),
), ),
) )
} }

View file

@ -111,8 +111,14 @@ internal class DefaultWalletRouter @Inject constructor(
) )
} }
override fun openTangemPayOnboarding() { override fun openTangemPayOnboarding(userWalletId: UserWalletId) {
router.push(AppRoute.TangemPayOnboarding(AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding)) router.push(
AppRoute.TangemPayOnboarding(
AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding(
userWalletId = userWalletId,
),
),
)
} }
override fun openTangemPayDetails(userWalletId: UserWalletId, config: TangemPayDetailsConfig) { override fun openTangemPayDetails(userWalletId: UserWalletId, config: TangemPayDetailsConfig) {

View file

@ -63,7 +63,7 @@ internal interface InnerWalletRouter {
fun openTokenReceiveBottomSheet(tokenReceiveConfig: TokenReceiveConfig) fun openTokenReceiveBottomSheet(tokenReceiveConfig: TokenReceiveConfig)
fun openTangemPayOnboarding() fun openTangemPayOnboarding(userWalletId: UserWalletId)
fun openTangemPayDetails(userWalletId: UserWalletId, config: TangemPayDetailsConfig) fun openTangemPayDetails(userWalletId: UserWalletId, config: TangemPayDetailsConfig)

View file

@ -86,7 +86,7 @@ internal class TangemPayMainSubscriber @AssistedInject constructor(
userWalletId = userWalletId, userWalletId = userWalletId,
value = data, value = data,
cardFrozenState = cardFrozenState, cardFrozenState = cardFrozenState,
onClickKyc = innerWalletRouter::openTangemPayOnboarding, onClickKyc = { innerWalletRouter.openTangemPayOnboarding(userWalletId) },
onIssuingCard = clickIntents::onIssuingCardClicked, onIssuingCard = clickIntents::onIssuingCardClicked,
onIssuingFailed = clickIntents::onIssuingFailedClicked, onIssuingFailed = clickIntents::onIssuingFailedClicked,
openDetails = { config -> openDetails = { config ->