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(
context = context,
params = when (val mode = route.mode) {
is AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding -> ContinueOnboarding
is AppRoute.TangemPayOnboarding.Mode.Deeplink -> Deeplink(deeplink = mode.deeplink)
is AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding -> ContinueOnboarding(
userWalletId = mode.userWalletId,
)
is AppRoute.TangemPayOnboarding.Mode.Deeplink -> Deeplink(
deeplink = mode.deeplink,
userWalletId = mode.userWalletId,
)
},
componentFactory = tangemPayOnboardingComponentFactory,
)

View file

@ -431,10 +431,13 @@ sealed class AppRoute(val path: String) : Route {
@Serializable
data class Deeplink(
val deeplink: String,
val userWalletId: UserWalletId?,
) : Mode()
@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 {
return userWallets?.find {
it is UserWallet.Cold && it.isMultiCurrency
} as? UserWallet.Cold
?: error("Cannot find cold user wallet")
} as? UserWallet.Cold ?: error("Cannot find cold user wallet")
}
}

View file

@ -13,6 +13,9 @@ dependencies {
implementation(projects.core.decompose)
implementation(projects.core.ui)
/** Domain */
implementation(projects.domain.models)
/** Compose */
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.ui.decompose.ComposableContentComponent
import com.tangem.domain.models.wallet.UserWalletId
interface TangemPayOnboardingComponent : ComposableContentComponent {
sealed class Params {
abstract val userWalletId: UserWalletId?
data class Deeplink(
val deeplink: String,
override val userWalletId: UserWalletId?,
) : Params()
object ContinueOnboarding : Params()
data class ContinueOnboarding(
override val userWalletId: UserWalletId?,
) : Params()
}
interface Factory : ComponentFactory<Params, TangemPayOnboardingComponent>

View file

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

View file

@ -1,10 +1,11 @@
package com.tangem.features.tangempay.deeplink
import android.net.Uri
import dagger.assisted.Assisted
import com.tangem.common.routing.AppRoute
import com.tangem.features.tangempay.TangemPayFeatureToggles
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.AssistedInject
@ -12,11 +13,16 @@ internal class DefaultOnboardVisaDeepLinkHandler @AssistedInject constructor(
@Assisted uri: Uri,
appRouter: AppRouter,
tangemPayFeatureToggles: TangemPayFeatureToggles,
getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
) : OnboardVisaDeepLinkHandler {
init {
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))
} else {
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.navigation.url.UrlOpener
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.usecase.ProduceTangemPayInitialDataUseCase
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.components.TangemPayOnboardingComponent
import com.tangem.features.tangempay.model.transformers.TangemPayOnboardingButtonLoadingTransformer
@ -37,6 +41,8 @@ internal class TangemPayOnboardingModel @Inject constructor(
private val produceInitialDataUseCase: ProduceTangemPayInitialDataUseCase,
private val urlOpener: UrlOpener,
private val tangemPayWalletsManager: TangemPayWalletsManager,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val getSelectedWalletUseCase: GetSelectedWalletUseCase,
) : Model() {
private val params = paramsContainer.require<TangemPayOnboardingComponent.Params>()
@ -74,8 +80,9 @@ internal class TangemPayOnboardingModel @Inject constructor(
private suspend fun checkCustomerInfo() {
// TODO implement selector
val userWalletId = getUserWalletForPay(params.userWalletId)
repository.getCustomerInfo(
userWalletId = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking().walletId,
userWalletId = userWalletId,
)
// selector
.onRight { customerInfo ->
@ -92,6 +99,24 @@ internal class TangemPayOnboardingModel @Inject constructor(
.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() {
analytics.send(TangemPayAnalyticsEvents.ViewTermsClicked)
urlOpener.openUrl(TangemPayConstants.TERMS_AND_LIMITS_LINK)
@ -102,7 +127,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = true))
modelScope.launch {
// TODO implement selector
val userWalletId = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking().walletId
val userWalletId = getUserWalletForPay(params.userWalletId)
val result = produceInitialDataUseCase(userWalletId)
if (result.isLeft()) {
Timber.e("Error producing initial data: ${result.leftOrNull()?.message}")
@ -134,7 +159,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
router.replaceAll(
AppRoute.Wallet,
AppRoute.Kyc(
userWalletId = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking().walletId,
userWalletId = getUserWalletForPay(params.userWalletId),
),
)
}

View file

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

View file

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

View file

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