Updated on 2026-08-14
This commit is contained in:
parent
c68cf7165b
commit
bea775e94b
46 changed files with 749 additions and 178 deletions
|
|
@ -7,6 +7,8 @@ import androidx.work.WorkerParameters
|
|||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.legacy.asLockable
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import timber.log.Timber
|
||||
|
|
@ -17,13 +19,22 @@ class LockTimerWorker @AssistedInject constructor(
|
|||
@Assisted params: WorkerParameters,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : CoroutineWorker(context, params) {
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
Timber.i("onStart job")
|
||||
val userWalletsListManagerLockable = userWalletsListManager.asLockable() ?: return Result.failure()
|
||||
userWalletsListManagerLockable.lock()
|
||||
settingsRepository.setShouldOpenWelcomeScreenOnResume(value = true)
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
userWalletsListRepository.lockAllWallets()
|
||||
.onRight {
|
||||
settingsRepository.setShouldOpenWelcomeScreenOnResume(value = true)
|
||||
}
|
||||
} else {
|
||||
val userWalletsListManagerLockable = userWalletsListManager.asLockable() ?: return Result.failure()
|
||||
userWalletsListManagerLockable.lock()
|
||||
settingsRepository.setShouldOpenWelcomeScreenOnResume(value = true)
|
||||
}
|
||||
Timber.i("onStart job complete")
|
||||
return Result.success()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import com.tangem.common.routing.AppRoute
|
|||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.legacy.asLockable
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.tap.LockTimerWorker.Companion.TAG
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -25,6 +27,8 @@ internal class LockUserWalletsTimer(
|
|||
private val settingsRepository: SettingsRepository,
|
||||
private val duration: Duration = with(Duration) { 5.minutes },
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
) : LifecycleOwner by context as LifecycleOwner,
|
||||
DefaultLifecycleObserver {
|
||||
|
|
@ -108,20 +112,33 @@ internal class LockUserWalletsTimer(
|
|||
|
||||
delay(duration)
|
||||
|
||||
val userWalletsListManager = userWalletsListManager.asLockable() ?: return@launch
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
val userWallets = userWalletsListRepository.userWalletsSync()
|
||||
if (userWallets.isNotEmpty()) {
|
||||
userWalletsListRepository.lockAllWallets()
|
||||
.onLeft {
|
||||
start()
|
||||
}
|
||||
.onRight {
|
||||
store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val userWalletsListManager = userWalletsListManager.asLockable() ?: return@launch
|
||||
|
||||
if (userWalletsListManager.hasUserWallets) {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (userWalletsListManager.hasUserWallets) {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
|
||||
Timber.i(
|
||||
"""
|
||||
Timber.i(
|
||||
"""
|
||||
Finished
|
||||
|- Millis passed: ${currentTime - startTime}
|
||||
""".trimIndent(),
|
||||
)
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
userWalletsListManager.lock()
|
||||
store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) }
|
||||
userWalletsListManager.lock()
|
||||
store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@ import com.tangem.domain.apptheme.model.AppThemeMode
|
|||
import com.tangem.domain.card.ScanCardUseCase
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
import com.tangem.domain.settings.SetGooglePayAvailabilityUseCase
|
||||
import com.tangem.domain.settings.SetGoogleServicesAvailabilityUseCase
|
||||
import com.tangem.domain.settings.ShouldInitiallyAskPermissionUseCase
|
||||
|
|
@ -48,7 +49,9 @@ import com.tangem.domain.staking.SendUnsubmittedHashesUseCase
|
|||
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
|
||||
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.tester.api.TesterMenuLauncher
|
||||
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
||||
import com.tangem.google.GoogleServicesHelper
|
||||
|
|
@ -188,6 +191,12 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
@Inject
|
||||
internal lateinit var backgroundScanIntentHandler: BackgroundScanIntentHandler
|
||||
|
||||
@Inject
|
||||
internal lateinit var userWalletsListRepository: UserWalletsListRepository
|
||||
|
||||
@Inject
|
||||
internal lateinit var hotWalletFeatureToggles: HotWalletFeatureToggles
|
||||
|
||||
internal val viewModel: MainViewModel by viewModels()
|
||||
|
||||
private lateinit var appThemeModeFlow: SharedFlow<AppThemeMode>
|
||||
|
|
@ -271,6 +280,8 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
settingsRepository = settingsRepository,
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
coroutineScope = mainScope,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
)
|
||||
|
||||
initIntentHandlers()
|
||||
|
|
@ -429,6 +440,12 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
}
|
||||
|
||||
private fun navigateToInitialScreenIfNeeded(intentWhichStartedActivity: Intent?) {
|
||||
// TODO refactor this method to return a route instead of navigating directly
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
navigateToInitialScreenIfNeededNew(intentWhichStartedActivity)
|
||||
return
|
||||
}
|
||||
|
||||
val backStack = appRouterConfig.stack ?: emptyList()
|
||||
// TODO move inital navigation to navigation component ([REDACTED_JIRA])
|
||||
val isOnlyInitialRoute = backStack.all { it is AppRoute.Initial }
|
||||
|
|
@ -448,6 +465,57 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated("Refactor this method to return a route instead of navigating directly")
|
||||
private fun navigateToInitialScreenIfNeededNew(intentWhichStartedActivity: Intent?) {
|
||||
lifecycleScope.launch {
|
||||
val userWallets = userWalletsListRepository.userWalletsSync()
|
||||
val launchMode = backgroundScanIntentHandler.getInitScreenLaunchMode(intentWhichStartedActivity)
|
||||
if (userWallets.isEmpty()) {
|
||||
val shouldShowTos = !cardRepository.isTangemTOSAccepted()
|
||||
|
||||
val route = if (shouldShowTos) {
|
||||
AppRoute.Disclaimer(isTosAccepted = false)
|
||||
} else {
|
||||
AppRoute.Home(launchMode = launchMode)
|
||||
}
|
||||
|
||||
store.dispatchNavigationAction { replaceAll(route) }
|
||||
intentProcessor.handleIntent(
|
||||
intent = intentWhichStartedActivity,
|
||||
isFromForeground = false,
|
||||
skipNavigationHandlers = false,
|
||||
)
|
||||
} else {
|
||||
if (userWallets.any { it.isLocked }) {
|
||||
store.dispatchNavigationAction {
|
||||
replaceAll(
|
||||
AppRoute.Welcome(
|
||||
launchMode = launchMode,
|
||||
intent = intentWhichStartedActivity?.let(::SerializableIntent),
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
store.dispatchNavigationAction {
|
||||
replaceAll(AppRoute.Wallet)
|
||||
}
|
||||
}
|
||||
|
||||
intentProcessor.handleIntent(
|
||||
intent = intentWhichStartedActivity,
|
||||
isFromForeground = false,
|
||||
skipNavigationHandlers = true,
|
||||
)
|
||||
}
|
||||
|
||||
if (intent != null) {
|
||||
handleDeepLink(intent = intent, isFromOnNewIntent = false)
|
||||
}
|
||||
|
||||
viewModel.checkForUnfinishedBackup()
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToInitialScreen(intentWhichStartedActivity: Intent?) {
|
||||
val launchMode = backgroundScanIntentHandler.getInitScreenLaunchMode(intentWhichStartedActivity)
|
||||
if (userWalletsListManager.isLockable && userWalletsListManager.hasUserWallets) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
|
||||
// FIXME: Workaround, remove it once the normal UserWalletsStore has been implemented
|
||||
// [REDACTED_JIRA]
|
||||
|
|
@ -28,10 +27,6 @@ internal class RuntimeUserWalletsStore(
|
|||
return requireNotNull(getSyncOrNull(key)) { "Unable to find user wallet with provided ID: $key" }
|
||||
}
|
||||
|
||||
override suspend fun getAllSyncOrNull(): List<UserWallet>? {
|
||||
return userWalletsListManager.userWallets.firstOrNull()
|
||||
}
|
||||
|
||||
override suspend fun update(
|
||||
userWalletId: UserWalletId,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.tap.data
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.catching
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
class UserWalletsStoreRepositoryProxy(
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
) : UserWalletsStore {
|
||||
|
||||
override val selectedUserWalletOrNull: UserWallet?
|
||||
get() = userWalletsListRepository.selectedUserWallet.value
|
||||
|
||||
override val userWallets: Flow<List<UserWallet>>
|
||||
get() = flow {
|
||||
userWalletsListRepository.load()
|
||||
userWalletsListRepository.userWallets.collect {
|
||||
emit(requireNotNull(it))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSyncOrNull(key: UserWalletId): UserWallet? {
|
||||
return userWalletsListRepository.userWallets.value?.find { it.walletId == key }
|
||||
}
|
||||
|
||||
override fun getSyncStrict(key: UserWalletId): UserWallet {
|
||||
return requireNotNull(getSyncOrNull(key)) { "Unable to find user wallet with provided ID: $key" }
|
||||
}
|
||||
|
||||
override suspend fun update(
|
||||
userWalletId: UserWalletId,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
): CompletionResult<UserWallet> {
|
||||
return catching {
|
||||
val userWallet = userWalletsListRepository.userWallets.value?.find { it.walletId == userWalletId }
|
||||
requireNotNull(userWallet) { "Unable to find user wallet with provided ID: $userWalletId" }
|
||||
val updatedUserWallet = update(userWallet)
|
||||
userWalletsListRepository.saveWithoutLock(
|
||||
userWallet = updatedUserWallet,
|
||||
canOverride = true,
|
||||
)
|
||||
updatedUserWallet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,10 @@ package com.tangem.tap.di.data
|
|||
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.tap.data.RuntimeUserWalletsStore
|
||||
import com.tangem.tap.data.UserWalletsStoreRepositoryProxy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -15,7 +18,15 @@ internal object UserWalletsStoreModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUserWalletsStore(userWalletsListManager: UserWalletsListManager): UserWalletsStore {
|
||||
return RuntimeUserWalletsStore(userWalletsListManager = userWalletsListManager)
|
||||
fun provideUserWalletsStore(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): UserWalletsStore {
|
||||
return if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
UserWalletsStoreRepositoryProxy(userWalletsListRepository)
|
||||
} else {
|
||||
RuntimeUserWalletsStore(userWalletsListManager = userWalletsListManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,13 @@ import com.tangem.domain.demo.models.DemoConfig
|
|||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase
|
||||
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
|
||||
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
||||
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase
|
||||
import com.tangem.tap.domain.card.DefaultResetCardUseCase
|
||||
|
|
@ -42,9 +44,16 @@ internal object CardDomainModule {
|
|||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideIsNeedToBackupUseCase(userWalletsListManager: UserWalletsListManager): IsNeedToBackupUseCase {
|
||||
return IsNeedToBackupUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun provideIsNeedToBackupUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): IsNeedToBackupUseCase {
|
||||
return IsNeedToBackupUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ package com.tangem.tap.di.domain
|
|||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
|
||||
import com.tangem.tap.domain.scanCard.DefaultScanCardProcessor
|
||||
import com.tangem.tap.domain.scanCard.LegacyScanProcessor
|
||||
|
|
@ -31,7 +33,15 @@ internal object CardLegacyDomainModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesWalletNameGenerateUseCase(userWalletsListManager: UserWalletsListManager): GenerateWalletNameUseCase {
|
||||
return GenerateWalletNameUseCase(userWalletsListManager)
|
||||
fun providesWalletNameGenerateUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): GenerateWalletNameUseCase {
|
||||
return GenerateWalletNameUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,8 @@ import com.tangem.domain.staking.StakingIdFactory
|
|||
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -81,10 +83,14 @@ object MarketsDomainModule {
|
|||
@Singleton
|
||||
fun provideFilterNetworksUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
): FilterAvailableNetworksForWalletUseCase {
|
||||
return FilterAvailableNetworksForWalletUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@ import com.tangem.domain.walletmanager.WalletManagersFacade
|
|||
import com.tangem.domain.wallets.delegate.DefaultUserWalletsSyncDelegate
|
||||
import com.tangem.domain.wallets.delegate.UserWalletsSyncDelegate
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.IsWalletNFTEnabledSyncUseCase
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletNameMigrationUseCase
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.operations.attestation.CardArtworksProvider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
|
|
@ -31,18 +33,30 @@ internal object WalletsDomainModule {
|
|||
@Provides
|
||||
fun providesUserWalletsSyncDelegate(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): UserWalletsSyncDelegate {
|
||||
return DefaultUserWalletsSyncDelegate(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesGetWalletsUseCase(userWalletsListManager: UserWalletsListManager): GetWalletsUseCase {
|
||||
return GetWalletsUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun providesGetWalletsUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): GetWalletsUseCase {
|
||||
return GetWalletsUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -50,37 +64,71 @@ internal object WalletsDomainModule {
|
|||
fun providesWalletNameMigrationUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
walletNamesMigrationRepository: WalletNamesMigrationRepository,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): WalletNameMigrationUseCase {
|
||||
return WalletNameMigrationUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
walletNamesMigrationRepository = walletNamesMigrationRepository,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesGetUserWalletUseCase(userWalletsListManager: UserWalletsListManager): GetUserWalletUseCase {
|
||||
return GetUserWalletUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun providesGetUserWalletUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): GetUserWalletUseCase {
|
||||
return GetUserWalletUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesGetSelectedWalletSyncUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): GetSelectedWalletSyncUseCase {
|
||||
return GetSelectedWalletSyncUseCase(userWalletsListManager = userWalletsListManager)
|
||||
return GetSelectedWalletSyncUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesGetSelectedWalletUseCase(userWalletsListManager: UserWalletsListManager): GetSelectedWalletUseCase {
|
||||
return GetSelectedWalletUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun providesGetSelectedWalletUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): GetSelectedWalletUseCase {
|
||||
return GetSelectedWalletUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesSaveWalletUseCase(userWalletsListManager: UserWalletsListManager): SaveWalletUseCase {
|
||||
return SaveWalletUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun providesSaveWalletUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): SaveWalletUseCase {
|
||||
return SaveWalletUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -99,15 +147,30 @@ internal object WalletsDomainModule {
|
|||
@Singleton
|
||||
fun providesSelectWalletUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
reduxStateHolder: ReduxStateHolder,
|
||||
): SelectWalletUseCase {
|
||||
return SelectWalletUseCase(userWalletsListManager = userWalletsListManager, reduxStateHolder = reduxStateHolder)
|
||||
return SelectWalletUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
reduxStateHolder = reduxStateHolder,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesUpdateWalletUseCase(userWalletsListManager: UserWalletsListManager): UpdateWalletUseCase {
|
||||
return UpdateWalletUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun providesUpdateWalletUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): UpdateWalletUseCase {
|
||||
return UpdateWalletUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -124,14 +187,30 @@ internal object WalletsDomainModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesGetWalletsSyncUseCase(userWalletsListManager: UserWalletsListManager): GetWalletNamesUseCase {
|
||||
return GetWalletNamesUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun providesGetWalletsSyncUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): GetWalletNamesUseCase {
|
||||
return GetWalletNamesUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesDeleteWalletUseCase(userWalletsListManager: UserWalletsListManager): DeleteWalletUseCase {
|
||||
return DeleteWalletUseCase(userWalletsListManager = userWalletsListManager)
|
||||
fun providesDeleteWalletUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): DeleteWalletUseCase {
|
||||
return DeleteWalletUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -214,9 +293,13 @@ internal object WalletsDomainModule {
|
|||
@Singleton
|
||||
fun providesGetSavedWalletChangesIdUseCase(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): GetSavedWalletsCountUseCase {
|
||||
return GetSavedWalletsCountUseCase(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.tangem.tap.domain.userWalletList.utils.toUserWallets
|
|||
import com.tangem.tap.domain.userWalletList.utils.updateWith
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.ProviderSuspend
|
||||
import com.tangem.utils.extensions.indexOfFirstOrNull
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
|
|
@ -173,6 +174,8 @@ internal class DefaultUserWalletsListRepository(
|
|||
|
||||
userWalletEncryptionKeysRepository.delete(userWalletIds)
|
||||
|
||||
val userWalletsBeforeDelete = userWallets.value ?: return@either
|
||||
|
||||
userWallets.update { currentWallets ->
|
||||
currentWallets?.filterNot { it.walletId in userWalletIds }
|
||||
}
|
||||
|
|
@ -181,7 +184,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
if (currentSelected == null) return@update null
|
||||
|
||||
userWallets.value?.findAvailableUserWallet(
|
||||
userWallets.value?.indexOfFirst { it.walletId == currentSelected.walletId } ?: 0,
|
||||
userWalletsBeforeDelete.indexOfFirstOrNull { it.walletId == currentSelected.walletId } ?: 0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -199,7 +202,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
|
||||
when (unlockMethod) {
|
||||
UserWalletsListRepository.UnlockMethod.Biometric -> {
|
||||
unlockAllWallets()
|
||||
unlockAllWallets().bind()
|
||||
select(userWalletId)
|
||||
}
|
||||
UserWalletsListRepository.UnlockMethod.AccessCode -> {
|
||||
|
|
@ -225,7 +228,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
}
|
||||
|
||||
sensitiveInformationRepository.getAll(listOf(encryptionKey))
|
||||
.doOnSuccess { userWallets.value?.updateWith(it) }
|
||||
.doOnSuccess { sensitiveInfo -> userWallets.update { it?.updateWith(sensitiveInfo) } }
|
||||
.doOnFailure { error ->
|
||||
raise(UnlockWalletError.UnableToUnlock)
|
||||
}
|
||||
|
|
@ -255,6 +258,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
}
|
||||
|
||||
override suspend fun unlockAllWallets(): Either<UnlockWalletError, Unit> = either {
|
||||
val userWalletIds = userWalletsSync().map { it.walletId }.toSet()
|
||||
val biometricKeys = runCatching {
|
||||
userWalletEncryptionKeysRepository.getAllBiometric()
|
||||
}.getOrElse {
|
||||
|
|
@ -264,8 +268,14 @@ internal class DefaultUserWalletsListRepository(
|
|||
|
||||
val unsecuredKeys = userWalletEncryptionKeysRepository.getAllUnsecured()
|
||||
val allKeys = biometricKeys + unsecuredKeys
|
||||
|
||||
if (allKeys.all { it.walletId in userWalletIds }.not()) {
|
||||
raise(UnlockWalletError.UnableToUnlock)
|
||||
}
|
||||
|
||||
sensitiveInformationRepository.getAll(allKeys)
|
||||
.doOnSuccess { userWallets.value?.updateWith(it) }
|
||||
.doOnSuccess { sensitiveInfo -> userWallets.update { it?.updateWith(sensitiveInfo) } }
|
||||
.doOnFailure { raise(UnlockWalletError.UnableToUnlock) }
|
||||
}
|
||||
|
||||
override suspend fun lockAllWallets(): Either<LockWalletsError, Unit> = either {
|
||||
|
|
@ -297,7 +307,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
biometryFallback: suspend () -> Either<UnlockWalletError, Unit>,
|
||||
): Either<UnlockWalletError, UserWalletEncryptionKey?> {
|
||||
val result = passwordRequester.requestPassword(
|
||||
hasBiometry = tangemSdkManagerProvider.invoke().needEnrollBiometrics,
|
||||
hasBiometry = tangemSdkManagerProvider.invoke().canUseBiometry,
|
||||
)
|
||||
|
||||
return when (result) {
|
||||
|
|
@ -312,6 +322,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
requestPasswordRecursive(block, biometryFallback)
|
||||
} else {
|
||||
passwordRequester.successfulAuthentication()
|
||||
passwordRequester.dismiss()
|
||||
decrypted.right()
|
||||
}
|
||||
}
|
||||
|
|
@ -319,9 +330,9 @@ internal class DefaultUserWalletsListRepository(
|
|||
biometryFallback()
|
||||
.onRight {
|
||||
passwordRequester.successfulAuthentication()
|
||||
passwordRequester.dismiss()
|
||||
}
|
||||
passwordRequester.dismiss()
|
||||
null.right()
|
||||
.map { null }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,15 +62,16 @@ internal class UserWalletEncryptionKeysRepository(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun getEncryptedWithPassword(userWalletId: UserWalletId, password: CharArray): UserWalletEncryptionKey? {
|
||||
val encrypted = secureStorage.get(
|
||||
account = StorageKey.UserWalletEncryptionKeyEncrypted(userWalletId).name,
|
||||
) ?: return null
|
||||
suspend fun getEncryptedWithPassword(userWalletId: UserWalletId, password: CharArray): UserWalletEncryptionKey? =
|
||||
withContext(dispatchers.io) {
|
||||
val encrypted = secureStorage.get(
|
||||
account = StorageKey.UserWalletEncryptionKeyEncrypted(userWalletId).name,
|
||||
) ?: return@withContext null
|
||||
|
||||
val decrypted = AESEncryptionProtocol.decryptWithPassword(password, encrypted)
|
||||
|
||||
return decrypted.decodeToKey()
|
||||
}
|
||||
withContext(dispatchers.default) {
|
||||
AESEncryptionProtocol.decryptWithPassword(password, encrypted).decodeToKey()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getAllBiometric(): List<UserWalletEncryptionKey> = withContext(dispatchers.io) {
|
||||
val keys = getUserWalletsIds().map { userWalletId ->
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import com.tangem.domain.walletconnect.WcPairService
|
|||
import com.tangem.domain.walletconnect.model.legacy.WalletConnectSessionsRepository
|
||||
import com.tangem.domain.walletconnect.usecase.initialize.WcInitializeUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
||||
import com.tangem.tap.domain.walletconnect.WalletConnectSdkHelper
|
||||
import com.tangem.tap.domain.walletconnect2.app.TangemWcBlockchainHelper
|
||||
|
|
@ -42,9 +42,9 @@ internal object WalletConnectInteractorModule {
|
|||
wcSessionsRepository: WalletConnectSessionsRepository,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
walletConnectFeatureToggles: WalletConnectFeatureToggles,
|
||||
coroutineDispatcherProvider: CoroutineDispatcherProvider,
|
||||
getSelectedWalletUseCase: GetSelectedWalletUseCase,
|
||||
): WalletConnectInteractor {
|
||||
return WalletConnectInteractor(
|
||||
handler = WalletConnectEventsHandlerImpl(),
|
||||
|
|
@ -54,7 +54,7 @@ internal object WalletConnectInteractorModule {
|
|||
blockchainHelper = TangemWcBlockchainHelper(),
|
||||
currenciesRepository = currenciesRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
getSelectedWalletUseCase = getSelectedWalletUseCase,
|
||||
dispatchers = coroutineDispatcherProvider,
|
||||
walletConnectFeatureToggles = walletConnectFeatureToggles,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import com.tangem.domain.walletconnect.model.legacy.Account
|
|||
import com.tangem.domain.walletconnect.model.legacy.Session
|
||||
import com.tangem.domain.walletconnect.model.legacy.WalletConnectSessionsRepository
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
|
|
@ -38,18 +37,14 @@ class WalletConnectInteractor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val walletConnectFeatureToggles: WalletConnectFeatureToggles,
|
||||
private val getSelectedWalletUseCase: GetSelectedWalletUseCase,
|
||||
val blockchainHelper: WcBlockchainHelper,
|
||||
) {
|
||||
private val isNewWc by lazy { walletConnectFeatureToggles.isRedesignedWalletConnectEnabled }
|
||||
|
||||
private var isWalletConnectReadyForDeepLinks = false
|
||||
|
||||
private val getSelectedWalletUseCase by lazy(LazyThreadSafetyMode.NONE) {
|
||||
GetSelectedWalletUseCase(userWalletsListManager)
|
||||
}
|
||||
|
||||
private val wcScope = CoroutineScope(
|
||||
SupervisorJob() + dispatchers.io + CoroutineExceptionHandler { _, throwable ->
|
||||
Timber.e("CoroutineException: from: LISTENER SCOPE, exception: $throwable")
|
||||
|
|
|
|||
|
|
@ -4,11 +4,16 @@ import com.tangem.common.extensions.toHexString
|
|||
import com.tangem.datasource.api.common.AuthProvider
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
|
||||
internal class DefaultAuthProvider(private val userWalletsListManager: UserWalletsListManager) : AuthProvider {
|
||||
internal class DefaultAuthProvider(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewListRepository: Boolean = false,
|
||||
) : AuthProvider {
|
||||
|
||||
override fun getCardPublicKey(): String {
|
||||
val userWallet = userWalletsListManager.selectedUserWalletSync
|
||||
override suspend fun getCardPublicKey(): String {
|
||||
val userWallet = getSelectedWallet()
|
||||
|
||||
if (userWallet !is UserWallet.Cold) {
|
||||
return ""
|
||||
|
|
@ -17,8 +22,8 @@ internal class DefaultAuthProvider(private val userWalletsListManager: UserWalle
|
|||
return userWallet.scanResponse.card.cardPublicKey.toHexString()
|
||||
}
|
||||
|
||||
override fun getCardId(): String {
|
||||
val userWallet = userWalletsListManager.selectedUserWalletSync
|
||||
override suspend fun getCardId(): String {
|
||||
val userWallet = getSelectedWallet()
|
||||
|
||||
if (userWallet !is UserWallet.Cold) {
|
||||
return ""
|
||||
|
|
@ -27,9 +32,25 @@ internal class DefaultAuthProvider(private val userWalletsListManager: UserWalle
|
|||
return userWallet.scanResponse.card.cardId
|
||||
}
|
||||
|
||||
override fun getCardsPublicKeys(): Map<String, String> {
|
||||
return userWalletsListManager.userWalletsSync.filterIsInstance<UserWallet.Cold>().associate {
|
||||
override suspend fun getCardsPublicKeys(): Map<String, String> {
|
||||
return getWallets().filterIsInstance<UserWallet.Cold>().associate {
|
||||
it.scanResponse.card.cardId to it.scanResponse.card.cardPublicKey.toHexString()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getWallets(): List<UserWallet> {
|
||||
return if (useNewListRepository) {
|
||||
userWalletsListRepository.userWalletsSync()
|
||||
} else {
|
||||
userWalletsListManager.userWalletsSync
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getSelectedWallet(): UserWallet? {
|
||||
return if (useNewListRepository) {
|
||||
userWalletsListRepository.selectedUserWalletSync()
|
||||
} else {
|
||||
userWalletsListManager.selectedUserWalletSync
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ package com.tangem.tap.network.auth.di
|
|||
import com.tangem.datasource.api.common.AuthProvider
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.lib.auth.ExpressAuthProvider
|
||||
import com.tangem.lib.auth.StakeKitAuthProvider
|
||||
import com.tangem.tap.network.auth.DefaultAppVersionProvider
|
||||
|
|
@ -22,8 +24,16 @@ internal class AuthModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideAuthProvider(userWalletsListManager: UserWalletsListManager): AuthProvider {
|
||||
return DefaultAuthProvider(userWalletsListManager)
|
||||
fun provideAuthProvider(
|
||||
userWalletsListManager: UserWalletsListManager,
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
): AuthProvider {
|
||||
return DefaultAuthProvider(
|
||||
userWalletsListManager = userWalletsListManager,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
useNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import dagger.Provides
|
|||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
|
|
@ -41,6 +42,12 @@ internal object FeatureTogglesManagerModule {
|
|||
localTogglesStorage = localTogglesStorage,
|
||||
versionProvider = versionProvider,
|
||||
)
|
||||
}.also {
|
||||
// We need to initialize during the hilt graph creation
|
||||
// in order to provide the feature toggles correctly to other dependencies.
|
||||
runBlocking {
|
||||
it.init()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore
|
|||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
/**
|
||||
* Feature toggles manager implementation in DEV build
|
||||
|
|
@ -24,10 +23,14 @@ internal class DevFeatureTogglesManager(
|
|||
private val versionProvider: VersionProvider,
|
||||
) : MutableFeatureTogglesManager {
|
||||
|
||||
private var featureTogglesMap: MutableMap<String, Boolean> by Delegates.notNull()
|
||||
private var localFeatureTogglesMap: Map<String, Boolean> by Delegates.notNull()
|
||||
private var featureTogglesMap: MutableMap<String, Boolean>? = null
|
||||
private var localFeatureTogglesMap: Map<String, Boolean>? = null
|
||||
|
||||
override suspend fun init() {
|
||||
if (featureTogglesMap != null && localFeatureTogglesMap != null) {
|
||||
return // Already initialized
|
||||
}
|
||||
|
||||
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||
|
||||
val savedFeatureToggles = appPreferencesStore.getObjectSyncOrNull<Map<String, Boolean>>(
|
||||
|
|
@ -46,21 +49,21 @@ internal class DevFeatureTogglesManager(
|
|||
.toMutableMap()
|
||||
}
|
||||
|
||||
override fun isFeatureEnabled(name: String): Boolean = featureTogglesMap[name] ?: false
|
||||
override fun isFeatureEnabled(name: String): Boolean = featureTogglesMap!![name] ?: false
|
||||
|
||||
override fun isMatchLocalConfig(): Boolean = featureTogglesMap == localFeatureTogglesMap
|
||||
|
||||
override fun getFeatureToggles(): Map<String, Boolean> = featureTogglesMap
|
||||
override fun getFeatureToggles(): Map<String, Boolean> = featureTogglesMap!!
|
||||
|
||||
override suspend fun changeToggle(name: String, isEnabled: Boolean) {
|
||||
featureTogglesMap[name] ?: return
|
||||
featureTogglesMap[name] = isEnabled
|
||||
appPreferencesStore.storeFeatureToggles(value = featureTogglesMap)
|
||||
featureTogglesMap!![name] ?: return
|
||||
featureTogglesMap!![name] = isEnabled
|
||||
appPreferencesStore.storeFeatureToggles(value = featureTogglesMap!!)
|
||||
}
|
||||
|
||||
override suspend fun recoverLocalConfig() {
|
||||
featureTogglesMap = localFeatureTogglesMap.toMutableMap()
|
||||
appPreferencesStore.storeFeatureToggles(value = localFeatureTogglesMap)
|
||||
featureTogglesMap = localFeatureTogglesMap!!.toMutableMap()
|
||||
appPreferencesStore.storeFeatureToggles(value = localFeatureTogglesMap!!)
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
|||
import com.tangem.core.configtoggle.storage.TogglesStorage
|
||||
import com.tangem.core.configtoggle.utils.associateToggles
|
||||
import com.tangem.core.configtoggle.version.VersionProvider
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
/**
|
||||
* Feature toggles manager implementation in PROD build
|
||||
|
|
@ -18,18 +17,22 @@ internal class ProdFeatureTogglesManager(
|
|||
private val versionProvider: VersionProvider,
|
||||
) : FeatureTogglesManager {
|
||||
|
||||
private var featureToggles: Map<String, Boolean> by Delegates.notNull()
|
||||
private var featureToggles: Map<String, Boolean>? = null
|
||||
|
||||
override suspend fun init() {
|
||||
if (featureToggles != null) {
|
||||
return // Already initialized
|
||||
}
|
||||
|
||||
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||
featureToggles = localTogglesStorage.toggles
|
||||
.associateToggles(currentVersion = versionProvider.get() ?: "")
|
||||
}
|
||||
|
||||
override fun isFeatureEnabled(name: String): Boolean = featureToggles[name] ?: false
|
||||
override fun isFeatureEnabled(name: String): Boolean = featureToggles!![name] ?: false
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
fun getProdFeatureToggles() = featureToggles
|
||||
fun getProdFeatureToggles() = featureToggles!!
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
fun setProdFeatureToggles(map: Map<String, Boolean>) {
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ interface AuthProvider {
|
|||
/**
|
||||
* Returns authToken for tangem tech api
|
||||
*/
|
||||
fun getCardPublicKey(): String
|
||||
suspend fun getCardPublicKey(): String
|
||||
|
||||
fun getCardId(): String
|
||||
suspend fun getCardId(): String
|
||||
|
||||
/**
|
||||
* Returns map where keys(cardId) associated with cardPublicKey
|
||||
*/
|
||||
fun getCardsPublicKeys(): Map<String, String>
|
||||
suspend fun getCardsPublicKeys(): Map<String, String>
|
||||
}
|
||||
|
|
@ -5,6 +5,10 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Deprecated(
|
||||
message = "Use UserWalletsListRepository instead",
|
||||
replaceWith = ReplaceWith("UserWalletsListRepository"),
|
||||
)
|
||||
interface UserWalletsStore {
|
||||
|
||||
val selectedUserWalletOrNull: UserWallet?
|
||||
|
|
@ -15,8 +19,6 @@ interface UserWalletsStore {
|
|||
|
||||
fun getSyncStrict(key: UserWalletId): UserWallet
|
||||
|
||||
suspend fun getAllSyncOrNull(): List<UserWallet>?
|
||||
|
||||
suspend fun update(
|
||||
userWalletId: UserWalletId,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import com.tangem.utils.ProviderSuspend
|
|||
import com.tangem.utils.info.AppInfoProvider
|
||||
import com.tangem.utils.version.AppVersionProvider
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
|
@ -55,8 +56,8 @@ internal class ProdApiConfigsManagerTest {
|
|||
every { appVersionProvider.versionName } returns VERSION_NAME
|
||||
every { expressAuthProvider.getSessionId() } returns EXPRESS_SESSION_ID
|
||||
every { stakeKitAuthProvider.getApiKey() } returns STAKE_KIT_API_KEY
|
||||
every { appAuthProvider.getCardId() } returns APP_CARD_ID
|
||||
every { appAuthProvider.getCardPublicKey() } returns APP_CARD_PUBLIC_KEY
|
||||
coEvery { appAuthProvider.getCardId() } returns APP_CARD_ID
|
||||
coEvery { appAuthProvider.getCardPublicKey() } returns APP_CARD_PUBLIC_KEY
|
||||
every { appInfoProvider.osVersion } returns "Android 16"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ class DefaultWalletsRepositoryTest {
|
|||
)
|
||||
|
||||
val authProvider = mockk<AuthProvider> {
|
||||
every { getCardsPublicKeys() } returns publicKeys
|
||||
coEvery { getCardsPublicKeys() } returns publicKeys
|
||||
}
|
||||
|
||||
repository = DefaultWalletsRepository(
|
||||
|
|
|
|||
|
|
@ -6,9 +6,13 @@ import com.tangem.blockchainsdk.utils.fromNetworkId
|
|||
import com.tangem.domain.card.common.extensions.supportedBlockchains
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.core.wallets.requireUserWalletsSync
|
||||
|
||||
class FilterAvailableNetworksForWalletUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
) {
|
||||
|
||||
|
|
@ -20,7 +24,7 @@ class FilterAvailableNetworksForWalletUseCase(
|
|||
userWalletId: UserWalletId,
|
||||
networks: Set<TokenMarketInfo.Network>,
|
||||
): Set<TokenMarketInfo.Network> {
|
||||
val userWallet = userWalletsListManager.userWalletsSync.firstOrNull {
|
||||
val userWallet = getWallets().firstOrNull {
|
||||
it.walletId == userWalletId
|
||||
} ?: return networks.toSet()
|
||||
|
||||
|
|
@ -33,4 +37,10 @@ class FilterAvailableNetworksForWalletUseCase(
|
|||
supportedBlockchains.contains(blockchain)
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
private fun getWallets() = if (useNewRepository) {
|
||||
userWalletsListRepository.requireUserWalletsSync()
|
||||
} else {
|
||||
userWalletsListManager.userWalletsSync
|
||||
}
|
||||
}
|
||||
|
|
@ -10,11 +10,14 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.models.UserWalletRemoteInfo
|
||||
import com.tangem.domain.models.wallet.copy
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DefaultUserWalletsSyncDelegate(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : UserWalletsSyncDelegate {
|
||||
|
||||
|
|
@ -28,10 +31,43 @@ class DefaultUserWalletsSyncDelegate(
|
|||
}
|
||||
}
|
||||
|
||||
// TODO remove dispatchers whnen UserWalletsListManager will be main safe
|
||||
private suspend fun renameUserWallet(
|
||||
userWalletId: UserWalletId,
|
||||
name: String,
|
||||
): Either<UpdateWalletError, UserWallet> = if (useNewRepository) {
|
||||
renameUserWalletInNewRepository(userWalletId, name)
|
||||
} else {
|
||||
renameUserWalletInLegacyRepository(userWalletId, name)
|
||||
}
|
||||
|
||||
private suspend fun renameUserWalletInNewRepository(
|
||||
userWalletId: UserWalletId,
|
||||
name: String,
|
||||
): Either<UpdateWalletError, UserWallet> = either {
|
||||
val userWallets = userWalletsListRepository.userWalletsSync()
|
||||
val userWallet = userWallets.find { it.walletId == userWalletId }
|
||||
?: raise(UpdateWalletError.DataError(IllegalStateException("User wallet with id $userWalletId not found")))
|
||||
|
||||
ensure(userWallets.none { it.name == name && it.walletId != userWalletId }) {
|
||||
UpdateWalletError.NameAlreadyExists
|
||||
}
|
||||
|
||||
ensure(name != userWallet.name) {
|
||||
UpdateWalletError.NameAlreadyExists
|
||||
}
|
||||
|
||||
val updatedWallet = userWallet.copy(name = name)
|
||||
|
||||
userWalletsListRepository.saveWithoutLock(updatedWallet, canOverride = true)
|
||||
.map { updatedWallet }
|
||||
.mapLeft { error -> UpdateWalletError.DataError(IllegalStateException("")) }
|
||||
.bind()
|
||||
}
|
||||
|
||||
// TODO remove dispatchers whnen UserWalletsListManager will be main safe
|
||||
private suspend fun renameUserWalletInLegacyRepository(
|
||||
userWalletId: UserWalletId,
|
||||
name: String,
|
||||
): Either<UpdateWalletError, UserWallet> = withContext(dispatchers.io) {
|
||||
either {
|
||||
val existingNames = userWalletsListManager.userWalletsSync
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
package com.tangem.domain.wallets.models
|
||||
|
||||
sealed interface SelectWalletError {
|
||||
|
||||
object UnableToSelectUserWallet : SelectWalletError
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.tangem.common.doOnFailure
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.error.DeleteWalletError
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
|
||||
/**
|
||||
* Use case for deleting user wallet
|
||||
|
|
@ -14,7 +15,11 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class DeleteWalletUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class DeleteWalletUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Deletes user wallet with provided ID.
|
||||
|
|
@ -24,6 +29,12 @@ class DeleteWalletUseCase(private val userWalletsListManager: UserWalletsListMan
|
|||
* @return [Either] with [DeleteWalletError] or [Boolean] which indicates that there are still saved wallets.
|
||||
* */
|
||||
suspend operator fun invoke(userWalletId: UserWalletId): Either<DeleteWalletError, Boolean> {
|
||||
if (useNewRepository) {
|
||||
return userWalletsListRepository.delete(userWalletIds = listOf(userWalletId)).map {
|
||||
userWalletsListRepository.selectedUserWallet.value != null
|
||||
}
|
||||
}
|
||||
|
||||
return either {
|
||||
userWalletsListManager.delete(userWalletIds = listOf(userWalletId))
|
||||
.doOnFailure {
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@ package com.tangem.domain.wallets.usecase
|
|||
|
||||
import com.tangem.domain.models.scan.ProductType
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.core.wallets.requireUserWalletsSync
|
||||
|
||||
/**
|
||||
* Use case for user wallet name generation
|
||||
*/
|
||||
class GenerateWalletNameUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
operator fun invoke(productType: ProductType, isBackupNotAllowed: Boolean, isStartToCoin: Boolean): String {
|
||||
|
|
@ -17,16 +21,24 @@ class GenerateWalletNameUseCase(
|
|||
isStartToCoin = isStartToCoin,
|
||||
)
|
||||
|
||||
val existingNames = userWalletsListManager.userWalletsSync.map { it.name }.toSet()
|
||||
val existingNames = getNamesSet()
|
||||
return suggestedWalletName(defaultName, existingNames)
|
||||
}
|
||||
|
||||
fun invokeForHot(): String {
|
||||
val defaultName = "Wallet"
|
||||
val existingNames = userWalletsListManager.userWalletsSync.map { it.name }.toSet()
|
||||
val existingNames = getNamesSet()
|
||||
return suggestedWalletName(defaultName, existingNames)
|
||||
}
|
||||
|
||||
private fun getNamesSet(): Set<String> {
|
||||
return if (useNewRepository) {
|
||||
userWalletsListRepository.requireUserWalletsSync().map { it.name }.toSet()
|
||||
} else {
|
||||
userWalletsListManager.userWalletsSync.map { it.name }.toSet()
|
||||
}
|
||||
}
|
||||
|
||||
private fun suggestedWalletName(defaultName: String, existingNames: Set<String>): String {
|
||||
val startIndex = 2
|
||||
if (!existingNames.contains(defaultName)) {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,20 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
|||
import com.tangem.domain.wallets.legacy.asLockable
|
||||
import com.tangem.domain.wallets.legacy.isLockedSync
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
class GetSavedWalletsCountUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
operator fun invoke(): Flow<List<UserWallet>> {
|
||||
if (useNewRepository) {
|
||||
return userWalletsListRepository.userWallets.map { requireNotNull(it) }
|
||||
}
|
||||
|
||||
return userWalletsListManager.savedWalletsCount
|
||||
.filter { count ->
|
||||
if (count == 0) return@filter true
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import arrow.core.raise.ensureNotNull
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.GetUserWalletError
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
|
||||
/**
|
||||
* Use case for getting selected wallet.
|
||||
|
|
@ -15,10 +16,20 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class GetSelectedWalletSyncUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class GetSelectedWalletSyncUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean = false,
|
||||
) {
|
||||
|
||||
@Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features")
|
||||
operator fun invoke(): Either<GetUserWalletError, UserWallet> {
|
||||
if (useNewRepository) {
|
||||
return either {
|
||||
userWalletsListRepository.selectedUserWallet.value ?: raise(GetUserWalletError.UserWalletNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
return either {
|
||||
ensureNotNull(
|
||||
value = userWalletsListManager.selectedUserWalletSync,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import arrow.core.raise.either
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.GetUserWalletError
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
|
||||
/**
|
||||
* Use case for getting flow of selected wallet.
|
||||
|
|
@ -14,12 +16,32 @@ import kotlinx.coroutines.flow.Flow
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class GetSelectedWalletUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
@Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features")
|
||||
class GetSelectedWalletUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean = false,
|
||||
) {
|
||||
|
||||
@Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features")
|
||||
operator fun invoke(): Either<GetUserWalletError, Flow<UserWallet>> {
|
||||
return either {
|
||||
userWalletsListManager.selectedUserWallet
|
||||
if (useNewRepository) {
|
||||
userWalletsListRepository.selectedUserWallet.filterNotNull()
|
||||
} else {
|
||||
userWalletsListManager.selectedUserWallet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features")
|
||||
fun sync(): Either<GetUserWalletError, UserWallet?> {
|
||||
return either {
|
||||
if (useNewRepository) {
|
||||
userWalletsListRepository.selectedUserWallet.value
|
||||
} else {
|
||||
userWalletsListManager.selectedUserWalletSync
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,13 +10,24 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
|||
import com.tangem.domain.wallets.models.GetUserWalletError
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.core.wallets.requireUserWalletsSync
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
class GetUserWalletUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class GetUserWalletUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewListRepository: Boolean,
|
||||
) {
|
||||
|
||||
operator fun invoke(userWalletId: UserWalletId): Either<GetUserWalletError, UserWallet> = either {
|
||||
val userWallets = userWalletsListManager.userWalletsSync
|
||||
val userWallets = if (useNewListRepository) {
|
||||
userWalletsListRepository.requireUserWalletsSync()
|
||||
} else {
|
||||
userWalletsListManager.userWalletsSync
|
||||
}
|
||||
|
||||
ensureNotNull(userWallets.firstOrNull { it.walletId == userWalletId }) {
|
||||
raise(GetUserWalletError.UserWalletNotFound)
|
||||
|
|
@ -25,7 +36,13 @@ class GetUserWalletUseCase(private val userWalletsListManager: UserWalletsListMa
|
|||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun invokeFlow(userWalletId: UserWalletId): EitherFlow<GetUserWalletError, UserWallet> {
|
||||
return userWalletsListManager.userWallets.transformLatest { userWallets ->
|
||||
val flow = if (useNewListRepository) {
|
||||
userWalletsListRepository.userWallets.map { requireNotNull(it) }
|
||||
} else {
|
||||
userWalletsListManager.userWallets
|
||||
}
|
||||
|
||||
return flow.transformLatest { userWallets ->
|
||||
userWallets.firstOrNull { it.walletId == userWalletId }
|
||||
?.let { emit(it.right()) }
|
||||
?: emit(GetUserWalletError.UserWalletNotFound.left())
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
package com.tangem.domain.wallets.usecase
|
||||
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.core.wallets.requireUserWalletsSync
|
||||
|
||||
/**
|
||||
* Use case for getting list of user wallets names.
|
||||
*
|
||||
* @property userWalletsListManager user wallets list manager
|
||||
*/
|
||||
class GetWalletNamesUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class GetWalletNamesUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
operator fun invoke(): List<String> = userWalletsListManager.userWalletsSync.map { it.name }
|
||||
operator fun invoke(): List<String> = if (useNewRepository) {
|
||||
userWalletsListRepository.requireUserWalletsSync().map { it.name }
|
||||
} else {
|
||||
userWalletsListManager.userWalletsSync.map { it.name }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.domain.wallets.usecase
|
||||
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
/**
|
||||
* Use case for getting list of user wallets
|
||||
|
|
@ -11,11 +13,23 @@ import kotlinx.coroutines.flow.Flow
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class GetWalletsUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class GetWalletsUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewListRepository: Boolean,
|
||||
) {
|
||||
|
||||
@Throws(IllegalArgumentException::class)
|
||||
operator fun invoke(): Flow<List<UserWallet>> = userWalletsListManager.userWallets
|
||||
operator fun invoke(): Flow<List<UserWallet>> = if (useNewListRepository) {
|
||||
userWalletsListRepository.userWallets.map { requireNotNull(it) }
|
||||
} else {
|
||||
userWalletsListManager.userWallets
|
||||
}
|
||||
|
||||
@Throws(IllegalArgumentException::class)
|
||||
fun invokeSync(): List<UserWallet> = userWalletsListManager.userWalletsSync
|
||||
fun invokeSync(): List<UserWallet> = if (useNewListRepository) {
|
||||
userWalletsListRepository.userWallets.value!!
|
||||
} else {
|
||||
userWalletsListManager.userWalletsSync
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.domain.models.scan.CardDTO
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
|
|
@ -12,12 +13,22 @@ import kotlinx.coroutines.flow.map
|
|||
*
|
||||
* @property userWalletsListManager user wallets list manager
|
||||
*/
|
||||
class IsNeedToBackupUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class IsNeedToBackupUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
operator fun invoke(id: UserWalletId): Flow<Boolean> {
|
||||
return userWalletsListManager.userWallets
|
||||
val userWalletsFlow = if (useNewRepository) {
|
||||
userWalletsListRepository.userWallets
|
||||
} else {
|
||||
userWalletsListManager.userWallets
|
||||
}
|
||||
|
||||
return userWalletsFlow
|
||||
.map { wallets ->
|
||||
val wallet = wallets.firstOrNull { it.walletId == id }
|
||||
val wallet = wallets?.firstOrNull { it.walletId == id }
|
||||
if (wallet == null) {
|
||||
false
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.domain.wallets.legacy.UserWalletsListError
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.core.wallets.error.SaveWalletError
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
|
||||
/**
|
||||
* Use case for saving user wallet
|
||||
|
|
@ -18,22 +19,51 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class SaveWalletUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class SaveWalletUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(userWallet: UserWallet, canOverride: Boolean = false): Either<SaveWalletError, Unit> {
|
||||
return either {
|
||||
userWalletsListManager.save(userWallet, canOverride)
|
||||
.doOnSuccess { return Unit.right() }
|
||||
.doOnFailure {
|
||||
return when (it) {
|
||||
is UserWalletsListError.WalletAlreadySaved -> SaveWalletError.WalletAlreadySaved(
|
||||
it.messageResId,
|
||||
)
|
||||
else -> SaveWalletError.DataError(it.messageResId)
|
||||
}.left()
|
||||
}
|
||||
return if (useNewRepository) {
|
||||
either {
|
||||
val newUserWallet =
|
||||
userWalletsListRepository.userWalletsSync().none { it.walletId == userWallet.walletId }
|
||||
val userWallet = userWalletsListRepository.saveWithoutLock(userWallet, canOverride).bind()
|
||||
|
||||
return Unit.right()
|
||||
if (newUserWallet) {
|
||||
when (userWallet) {
|
||||
is UserWallet.Cold -> {
|
||||
userWalletsListRepository.setLock(
|
||||
userWallet.walletId,
|
||||
UserWalletsListRepository.LockMethod.Biometric,
|
||||
)
|
||||
}
|
||||
is UserWallet.Hot -> {
|
||||
userWalletsListRepository.setLock(
|
||||
userWallet.walletId,
|
||||
UserWalletsListRepository.LockMethod.NoLock,
|
||||
)
|
||||
}
|
||||
}.mapLeft { SaveWalletError.DataError(null) }.bind()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
either {
|
||||
userWalletsListManager.save(userWallet, canOverride)
|
||||
.doOnSuccess { return Unit.right() }
|
||||
.doOnFailure {
|
||||
return when (it) {
|
||||
is UserWalletsListError.WalletAlreadySaved -> SaveWalletError.WalletAlreadySaved(
|
||||
it.messageResId,
|
||||
)
|
||||
else -> SaveWalletError.DataError(it.messageResId)
|
||||
}.left()
|
||||
}
|
||||
|
||||
return Unit.right()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,10 @@ import arrow.core.right
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.SelectWalletError
|
||||
import com.tangem.domain.core.wallets.error.SelectWalletError
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
|
||||
/**
|
||||
* Use case for selecting wallet
|
||||
|
|
@ -20,10 +21,19 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
*/
|
||||
class SelectWalletUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(userWalletId: UserWalletId): Either<SelectWalletError, UserWallet> {
|
||||
if (useNewRepository) {
|
||||
return userWalletsListRepository.select(userWalletId).map {
|
||||
reduxStateHolder.onUserWalletSelected(it)
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
return either {
|
||||
return when (val result = userWalletsListManager.select(userWalletId)) {
|
||||
is CompletionResult.Failure -> raise(SelectWalletError.UnableToSelectUserWallet)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
|||
import com.tangem.domain.wallets.models.UpdateWalletError
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.core.wallets.error.SaveWalletError
|
||||
import com.tangem.domain.wallets.models.UpdateWalletError.*
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
|
||||
/**
|
||||
* Use case for updating user wallet
|
||||
|
|
@ -15,15 +18,38 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class UpdateWalletUseCase(private val userWalletsListManager: UserWalletsListManager) {
|
||||
class UpdateWalletUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
): Either<UpdateWalletError, UserWallet> = either {
|
||||
when (val result = userWalletsListManager.update(userWalletId, update)) {
|
||||
is CompletionResult.Failure -> raise(UpdateWalletError.DataError(result.error))
|
||||
is CompletionResult.Success -> result.data
|
||||
): Either<UpdateWalletError, UserWallet> {
|
||||
if (useNewRepository) {
|
||||
val userWallet = userWalletsListRepository.userWallets.value?.find { it.walletId == userWalletId }
|
||||
?: return Either.Left(
|
||||
UpdateWalletError.DataError(IllegalStateException("User wallet with id $userWalletId not found")),
|
||||
)
|
||||
val updatedWallet = update(userWallet)
|
||||
return userWalletsListRepository.saveWithoutLock(updatedWallet, canOverride = true)
|
||||
.mapLeft {
|
||||
when (it) {
|
||||
is SaveWalletError.DataError -> DataError(
|
||||
IllegalStateException("Failed to update wallet: ${it.messageId}"),
|
||||
)
|
||||
is SaveWalletError.WalletAlreadySaved -> UpdateWalletError.NameAlreadyExists
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return either {
|
||||
when (val result = userWalletsListManager.update(userWalletId, update)) {
|
||||
is CompletionResult.Failure -> raise(UpdateWalletError.DataError(result.error))
|
||||
is CompletionResult.Success -> result.data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,11 @@ class GetSavedWalletsCountUseCaseTest {
|
|||
@Before
|
||||
fun setup() {
|
||||
userWalletsListManager = mockk()
|
||||
useCase = GetSavedWalletsCountUseCase(userWalletsListManager)
|
||||
useCase = GetSavedWalletsCountUseCase(
|
||||
userWalletsListManager,
|
||||
userWalletsListRepository = mockk(),
|
||||
useNewRepository = false,
|
||||
)
|
||||
mockkStatic("com.tangem.domain.wallets.legacy.UserWalletsListManagerExtensionsKt")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue