Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-14 14:47:48 +03:00
parent c68cf7165b
commit bea775e94b
46 changed files with 749 additions and 178 deletions

View file

@ -16,8 +16,8 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.settings.SetSaveWalletScreenShownUseCase
import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
import com.tangem.features.biometry.AskBiometryComponent
import com.tangem.features.biometry.impl.ui.state.AskBiometryUM
import com.tangem.sdk.api.TangemSdkManager
@ -40,7 +40,7 @@ internal class AskBiometryModel @Inject constructor(
private val setSaveWalletScreenShownUseCase: SetSaveWalletScreenShownUseCase,
private val settingsRepository: SettingsRepository,
private val tangemSdkManager: TangemSdkManager,
private val userWalletsListManager: UserWalletsListManager,
private val getSelectedWalletUseCase: GetSelectedWalletUseCase,
private val walletsRepository: WalletsRepository,
private val cardSdkConfigRepository: CardSdkConfigRepository,
private val settingsManager: SettingsManager,
@ -87,7 +87,7 @@ internal class AskBiometryModel @Inject constructor(
* because it will be automatically saved on UserWalletsListManager switch
*/
val selectedUserWallet = userWalletsListManager.selectedUserWalletSync ?: run {
val selectedUserWallet = getSelectedWalletUseCase.sync().getOrNull() ?: run {
Timber.e("Unable to save user wallet")
uiMessageSender.send(
SnackbarMessage(stringReference("No selected user wallet")),

View file

@ -21,6 +21,7 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
import com.tangem.features.onboarding.v2.common.ui.CantLeaveBackupDialog
import com.tangem.features.onboarding.v2.impl.R
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
@ -51,6 +52,7 @@ internal class MultiWalletFinalizeModel @Inject constructor(
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
private val userWalletsListManager: UserWalletsListManager,
private val saveWalletUseCase: SaveWalletUseCase,
private val cardRepository: CardRepository,
private val onboardingRepository: OnboardingRepository,
private val walletsRepository: WalletsRepository,
@ -231,7 +233,7 @@ internal class MultiWalletFinalizeModel @Inject constructor(
OnboardingMultiWalletComponent.Mode.Onboarding,
OnboardingMultiWalletComponent.Mode.ContinueFinalize,
-> {
userWalletsListManager.save(
saveWalletUseCase(
userWallet = userWalletCreated.copy(
scanResponse = scanResponse.updateScanResponseAfterBackup(),
),
@ -247,13 +249,11 @@ internal class MultiWalletFinalizeModel @Inject constructor(
}
?: userWalletCreated
userWalletsListManager.update(
userWalletId = userWallet.walletId,
update = { wallet ->
wallet.requireColdWallet().copy(
scanResponse = scanResponse.updateScanResponseAfterBackup(),
)
},
saveWalletUseCase(
userWallet = userWallet.requireColdWallet().copy(
scanResponse = scanResponse.updateScanResponseAfterBackup(),
),
canOverride = true,
)
userWallet

View file

@ -43,7 +43,8 @@ import com.tangem.domain.tokens.model.analytics.TokenReceiveAnalyticsEvent
import com.tangem.domain.tokens.wallet.WalletBalanceFetcher
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.usecase.DeleteWalletUseCase
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent
import com.tangem.features.onboarding.v2.common.ui.interruptBackupDialog
import com.tangem.features.onboarding.v2.impl.R
@ -73,7 +74,8 @@ internal class OnboardingTwinModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
paramsContainer: ParamsContainer,
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
private val userWalletsListManager: UserWalletsListManager,
private val saveWalletUseCase: SaveWalletUseCase,
private val deleteWalletUseCase: DeleteWalletUseCase,
private val analyticsEventHandler: AnalyticsEventHandler,
private val saveTwinsOnboardingShownUseCase: SaveTwinsOnboardingShownUseCase,
private val tangemSdkManager: TangemSdkManager,
@ -199,9 +201,9 @@ internal class OnboardingTwinModel @Inject constructor(
// remove wallet only after first step of retwin
if (params.mode == Mode.RecreateWallet) {
userWalletsListManager.delete(
listOfNotNull(UserWalletIdBuilder.scanResponse(params.scanResponse).build()),
)
UserWalletIdBuilder.scanResponse(params.scanResponse).build()?.let {
deleteWalletUseCase(it)
}
}
analyticsEventHandler.send(OnboardingEvent.CreateWallet.WalletCreatedSuccessfully())
@ -329,7 +331,14 @@ internal class OnboardingTwinModel @Inject constructor(
return@coroutineScope
}
userWalletsListManager.save(userWallet, canOverride = true)
saveWalletUseCase(
userWallet = userWallet,
canOverride = true,
).onLeft {
Timber.e("Unable to save user wallet: $it")
setLoading(false)
return@coroutineScope
}
cardRepository.finishCardActivation(params.scanResponse.card.cardId)
@ -456,7 +465,15 @@ internal class OnboardingTwinModel @Inject constructor(
return@launch
}
userWalletsListManager.save(userWallet, canOverride = true)
saveWalletUseCase(
userWallet = userWallet,
canOverride = true,
).onLeft {
Timber.e("Unable to save user wallet: $it")
setLoading(false)
return@launch
}
params.modelCallbacks.onDone()
}
}

View file

@ -20,8 +20,8 @@ import com.tangem.domain.visa.model.VisaCardId
import com.tangem.domain.visa.repository.VisaActivationRepository
import com.tangem.domain.visa.repository.VisaAuthRepository
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
import com.tangem.features.onboarding.v2.visa.impl.child.inprogress.OnboardingVisaInProgressComponent.Config
import com.tangem.features.onboarding.v2.visa.impl.child.inprogress.OnboardingVisaInProgressComponent.Params
import com.tangem.features.onboarding.v2.visa.impl.child.welcome.model.analytics.OnboardingVisaAnalyticsEvent
@ -46,7 +46,7 @@ internal class OnboardingVisaInProgressModel @Inject constructor(
private val visaAuthTokenStorage: VisaAuthTokenStorage,
private val otpStorage: VisaOTPStorage,
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
private val userWalletsListManager: UserWalletsListManager,
private val saveWalletUseCase: SaveWalletUseCase,
private val uiMessageSender: UiMessageSender,
private val analyticsEventHandler: AnalyticsEventHandler,
) : Model() {
@ -173,7 +173,7 @@ internal class OnboardingVisaInProgressModel @Inject constructor(
}
val userWallet = createUserWallet(params.scanResponse, newTokens)
userWalletsListManager.save(userWallet)
saveWalletUseCase(userWallet)
visaAuthTokenStorage.remove(params.scanResponse.card.cardId)
otpStorage.removeOTP(params.scanResponse.card.cardId)

View file

@ -25,12 +25,12 @@ import com.tangem.datasource.api.express.models.response.TxDetails
import com.tangem.datasource.crypto.DataSignatureVerifier
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.feature.swap.converters.*
import com.tangem.feature.swap.domain.api.SwapRepository
import com.tangem.feature.swap.domain.models.ExpressDataError
@ -51,7 +51,7 @@ internal class DefaultSwapRepository(
private val tangemExpressApi: TangemExpressApi,
private val coroutineDispatcher: CoroutineDispatcherProvider,
private val walletManagersFacade: WalletManagersFacade,
private val userWalletsListManager: UserWalletsListManager,
private val userWalletsStore: UserWalletsStore,
private val errorsDataConverter: ErrorsDataConverter,
private val dataSignatureVerifier: DataSignatureVerifier,
private val appPreferencesStore: AppPreferencesStore,
@ -409,7 +409,7 @@ internal class DefaultSwapRepository(
cryptoCurrencyFactory.createCoin(
blockchain = blockchain,
extraDerivationPath = null,
userWallet = requireNotNull(userWalletsListManager.selectedUserWalletSync),
userWallet = requireNotNull(userWalletsStore.selectedUserWalletOrNull),
),
)
}

View file

@ -8,8 +8,8 @@ import com.tangem.datasource.api.express.models.response.ExpressErrorResponse
import com.tangem.datasource.crypto.DataSignatureVerifier
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.feature.swap.DefaultSwapRepository
import com.tangem.feature.swap.DefaultSwapTransactionRepository
import com.tangem.feature.swap.converters.ErrorsDataConverter
@ -33,7 +33,7 @@ internal class SwapDataModule {
coroutineDispatcher: CoroutineDispatcherProvider,
dataSignature: DataSignatureVerifier,
walletManagerFacade: WalletManagersFacade,
userWalletsListManager: UserWalletsListManager,
userWalletsStore: UserWalletsStore,
errorsDataConverter: ErrorsDataConverter,
@NetworkMoshi moshi: Moshi,
excludedBlockchains: ExcludedBlockchains,
@ -43,7 +43,7 @@ internal class SwapDataModule {
tangemExpressApi = tangemExpressApi,
coroutineDispatcher = coroutineDispatcher,
walletManagersFacade = walletManagerFacade,
userWalletsListManager = userWalletsListManager,
userWalletsStore = userWalletsStore,
errorsDataConverter = errorsDataConverter,
dataSignatureVerifier = dataSignature,
moshi = moshi,

View file

@ -2,29 +2,44 @@ package com.tangem.feature.wallet.presentation.wallet.domain
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.models.wallet.copy
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository
import timber.log.Timber
class WalletNameMigrationUseCase(
private val userWalletsListManager: UserWalletsListManager,
private val userWalletsListRepository: UserWalletsListRepository,
private val useNewListRepository: Boolean,
private val walletNamesMigrationRepository: WalletNamesMigrationRepository,
) {
suspend operator fun invoke() {
val wallets = userWalletsListManager.userWalletsSync
if (walletNamesMigrationRepository.isMigrationDone()) {
return
}
val existingNames: MutableSet<String> = mutableSetOf()
wallets.indices.forEach { i ->
val defaultName = wallets[i].name
val suggestedWalletName = suggestedWalletName(defaultName, existingNames)
if (defaultName != suggestedWalletName) {
userWalletsListManager.update(wallets[i].walletId) { it.copy(name = suggestedWalletName) }
if (useNewListRepository) {
val wallets = userWalletsListRepository.userWalletsSync()
val existingNames: MutableSet<String> = mutableSetOf()
wallets.forEach {
val defaultName = it.name
val suggestedWalletName = suggestedWalletName(defaultName, existingNames)
if (defaultName != suggestedWalletName) {
userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true)
}
Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName)
}
} else {
val wallets = userWalletsListManager.userWalletsSync
val existingNames: MutableSet<String> = mutableSetOf()
wallets.indices.forEach { i ->
val defaultName = wallets[i].name
val suggestedWalletName = suggestedWalletName(defaultName, existingNames)
if (defaultName != suggestedWalletName) {
userWalletsListManager.update(wallets[i].walletId) { it.copy(name = suggestedWalletName) }
}
Timber.tag("Migrated names").e(i.toString() + " " + suggestedWalletName)
}
Timber.tag("Migrated names").e(i.toString() + " " + suggestedWalletName)
}
walletNamesMigrationRepository.setMigrationDone()