From 905905a64ed8fe933845df1267e4214b21ea3b9e Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 16 Sep 2025 17:40:53 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/WalletsDomainModule.kt | 14 ++++ .../usecase/IsWalletAlreadySavedUseCase.kt | 32 +++++++++ .../model/MultiWalletSeedPhraseModel.kt | 70 ++++++++++++++----- 3 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index c116c9d81f..1ee802121b 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -134,6 +134,20 @@ internal object WalletsDomainModule { ) } + @Provides + @Singleton + fun providesIsWalletAlreadySavedUseCase( + userWalletsListManager: UserWalletsListManager, + userWalletsListRepository: UserWalletsListRepository, + hotWalletFeatureToggles: HotWalletFeatureToggles, + ): IsWalletAlreadySavedUseCase { + return IsWalletAlreadySavedUseCase( + userWalletsListManager = userWalletsListManager, + userWalletsListRepository = userWalletsListRepository, + useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, + ) + } + @Provides @Singleton fun providesOpenBuyTangemCardUseCase(): GenerateBuyTangemCardLinkUseCase { diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt new file mode 100644 index 0000000000..c620ca93ce --- /dev/null +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt @@ -0,0 +1,32 @@ +package com.tangem.domain.wallets.usecase + +import arrow.core.Either +import arrow.core.raise.either +import com.tangem.domain.core.wallets.UserWalletsListRepository +import com.tangem.domain.core.wallets.error.SaveWalletError +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.legacy.UserWalletsListManager + +class IsWalletAlreadySavedUseCase( + private val userWalletsListManager: UserWalletsListManager, + private val userWalletsListRepository: UserWalletsListRepository, + private val useNewRepository: Boolean, +) { + + suspend operator fun invoke( + userWallet: UserWallet, + canOverride: Boolean = false, + ): Either { + return if (useNewRepository) { + either { + userWalletsListRepository.userWalletsSync() + .any { it.walletId == userWallet.walletId } + } + } else { + either { + userWalletsListManager.userWalletsSync + .any { it.walletId == userWallet.walletId } + } + } + } +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt index 2bdce1a527..52538e1e92 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt @@ -1,18 +1,28 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model import androidx.compose.runtime.Stable +import arrow.core.getOrElse import com.tangem.common.CompletionResult import com.tangem.common.core.TangemSdkError import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.decompose.di.GlobalUiMessageSender import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer +import com.tangem.core.decompose.ui.UiMessageSender import com.tangem.core.navigation.url.UrlOpener +import com.tangem.core.ui.R +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.message.SnackbarMessage import com.tangem.crypto.bip39.Mnemonic import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.feedback.GetWalletMetaInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType +import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder +import com.tangem.domain.wallets.usecase.IsWalletAlreadySavedUseCase import com.tangem.features.hotwallet.MnemonicRepository import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.common.ui.OnboardingDialogUM @@ -47,6 +57,9 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val analyticsHandler: AnalyticsEventHandler, + private val isWalletAlreadySavedUseCase: IsWalletAlreadySavedUseCase, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, + @GlobalUiMessageSender private val uiMessageSender: UiMessageSender, ) : Model() { private val params = paramsContainer.require() @@ -198,30 +211,42 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( when (result) { is CompletionResult.Success -> { - analyticsHandler.send( - OnboardingEvent.CreateWallet.WalletCreatedSuccessfully( - creationType = if (generatedSeedPhrase) { - OnboardingEvent.CreateWallet.WalletCreationType.NewSeed - } else { - OnboardingEvent.CreateWallet.WalletCreationType.SeedImport - }, - seedPhraseLength = mnemonic.mnemonicComponents.size, - ), + val updatedScanResponse = multiWalletState.value.currentScanResponse.copy( + card = result.data.card, + derivedKeys = result.data.derivedKeys, + primaryCard = result.data.primaryCard, ) - multiWalletState.update { - it.copy( - currentScanResponse = it.currentScanResponse.copy( - card = result.data.card, - derivedKeys = result.data.derivedKeys, - primaryCard = result.data.primaryCard, + val wallet = createUserWallet(updatedScanResponse) + + val isWalletAlreadySaved = isWalletAlreadySavedUseCase + .invoke(wallet) + .getOrElse { false } + + if (!isWalletAlreadySaved) { + analyticsHandler.send( + OnboardingEvent.CreateWallet.WalletCreatedSuccessfully( + creationType = if (generatedSeedPhrase) { + OnboardingEvent.CreateWallet.WalletCreationType.NewSeed + } else { + OnboardingEvent.CreateWallet.WalletCreationType.SeedImport + }, + seedPhraseLength = mnemonic.mnemonicComponents.size, ), ) + + multiWalletState.update { + it.copy(currentScanResponse = updatedScanResponse) + } + + cardRepository.startCardActivation(cardId = result.data.card.cardId) + + onDone.emit(Unit) + } else { + uiMessageSender.send( + SnackbarMessage(resourceReference(R.string.hw_import_seed_phrase_already_imported)), + ) } - - cardRepository.startCardActivation(cardId = result.data.card.cardId) - - onDone.emit(Unit) } is CompletionResult.Failure -> { if (result.error is TangemSdkError.WalletAlreadyCreated) { @@ -255,6 +280,13 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( } } + private fun createUserWallet(scanResponse: ScanResponse): UserWallet.Cold { + return requireNotNull( + value = coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build(), + lazyMessage = { "User wallet not created" }, + ) + } + fun navigateToSupportScreen() { modelScope.launch { val cardInfo =