diff --git a/app/src/main/assets/tangem-app-config b/app/src/main/assets/tangem-app-config index d6e348cf2f..4ec5de6632 160000 --- a/app/src/main/assets/tangem-app-config +++ b/app/src/main/assets/tangem-app-config @@ -1 +1 @@ -Subproject commit d6e348cf2f9a1f5a4e96fbf627fec71c2d17c9c1 +Subproject commit 4ec5de66321afa82c04104746015ea9e6bc9fe64 diff --git a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt index 52a6dc9646..a005dd97cb 100644 --- a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt +++ b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt @@ -34,7 +34,7 @@ import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.domain.onboarding.repository.OnboardingRepository import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.walletmanager.WalletManagersFacade -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles @@ -142,7 +142,7 @@ interface ApplicationEntryPoint { fun getOnlineCardVerifier(): OnlineCardVerifier - fun getUserWalletBuilderFactory(): UserWalletBuilder.Factory + fun getColdUserWalletBuilderFactory(): ColdUserWalletBuilder.Factory fun getApiConfigsManager(): ApiConfigsManager } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index 03c39c9727..0114cc78ba 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -53,7 +53,7 @@ import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.domain.onboarding.repository.OnboardingRepository import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.walletmanager.WalletManagersFacade -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles @@ -226,8 +226,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat private val onlineCardVerifier: OnlineCardVerifier get() = entryPoint.getOnlineCardVerifier() - private val userWalletBuilderFactory: UserWalletBuilder.Factory - get() = entryPoint.getUserWalletBuilderFactory() + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory + get() = entryPoint.getColdUserWalletBuilderFactory() private val apiConfigsManager: ApiConfigsManager get() = entryPoint.getApiConfigsManager() @@ -368,7 +368,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat settingsManager = settingsManager, uiMessageSender = uiMessageSender, onlineCardVerifier = onlineCardVerifier, - userWalletBuilderFactory = userWalletBuilderFactory, + coldUserWalletBuilderFactory = coldUserWalletBuilderFactory, ), ), ) diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt index e7f1d6613d..a75849544c 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt @@ -10,6 +10,7 @@ import com.tangem.domain.common.LogConfig import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.StateDialog +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.tap.common.extensions.* import com.tangem.tap.common.redux.AppState import com.tangem.tap.network.exchangeServices.CardExchangeRules @@ -59,7 +60,7 @@ private fun handleAction(action: Action, appState: () -> AppState?) { scope.launch { val scanResponseProvider: () -> ScanResponse? = { val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - userWalletsListManager.selectedUserWalletSync?.scanResponse + userWalletsListManager.selectedUserWalletSync?.requireColdWallet()?.scanResponse // TODO [REDACTED_TASK_KEY] } val cardProvider: () -> CardDTO? = { scanResponseProvider.invoke()?.card } diff --git a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt index 1eea5ec1a0..a950925df9 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt @@ -2,6 +2,7 @@ package com.tangem.tap.common.redux.legacy import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.redux.LegacyAction +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.redux.AppState @@ -36,7 +37,8 @@ internal object LegacyMiddleware { ) store.dispatchWithMain( DetailsAction.PrepareScreen( - scanResponse = selectedUserWallet.scanResponse, + // TODO [REDACTED_TASK_KEY] + scanResponse = selectedUserWallet.requireColdWallet().scanResponse, initializedAppSettingsState = initializedAppSettingsStateContent, ), ) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 63058e7738..b812453401 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -5,6 +5,7 @@ import com.tangem.blockchain.common.Wallet import com.tangem.core.analytics.Analytics import com.tangem.domain.common.extensions.withMainContext import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.tap.common.extensions.setContext import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.store @@ -34,7 +35,7 @@ class TapWalletManager( } private suspend fun loadUserWalletData(userWallet: UserWallet) { - Analytics.setContext(userWallet.scanResponse) + Analytics.setContext(userWallet.requireColdWallet().scanResponse) // [REDACTED_TASK_KEY] val scanResponse = userWallet.scanResponse tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse) diff --git a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt b/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt index e888c4599d..4c6e048c73 100644 --- a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt @@ -19,6 +19,7 @@ import com.tangem.domain.models.network.Network import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.operations.derivation.ExtendedPublicKeysMap import com.tangem.sdk.api.TangemSdkManager import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter @@ -49,7 +50,7 @@ internal class DefaultDerivationsRepository( networkFactory.create( blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, extraDerivationPath = null, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) }, ) @@ -60,6 +61,8 @@ internal class DefaultDerivationsRepository( userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found") } + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] + if (!userWallet.scanResponse.card.settings.isHDWalletAllowed) { Timber.d("Nothing to derive") return @@ -81,16 +84,17 @@ internal class DefaultDerivationsRepository( ): Boolean { val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found") - val derivations = MissedDerivationsFinder(scanResponse = userWallet.scanResponse) - .findByNetworks( - networksWithDerivationPath.mapNotNull { (backendId, extraDerivationPath) -> - networkFactory.create( - blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null, - extraDerivationPath = extraDerivationPath, - scanResponse = userWallet.scanResponse, - ) - }, - ) + val derivations = + MissedDerivationsFinder(scanResponse = userWallet.requireColdWallet().scanResponse) // TODO [REDACTED_TASK_KEY] + .findByNetworks( + networksWithDerivationPath.mapNotNull { (backendId, extraDerivationPath) -> + networkFactory.create( + blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null, + extraDerivationPath = extraDerivationPath, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] + ) + }, + ) return derivations.isNotEmpty() } @@ -105,7 +109,8 @@ internal class DefaultDerivationsRepository( ).doOnSuccess { response -> updatePublicKeys(userWalletId = userWalletId, keys = response.entries) .doOnSuccess { - validateDerivations(scanResponse = it.scanResponse, derivations = derivations) + // TODO [REDACTED_TASK_KEY] + validateDerivations(scanResponse = it.requireColdWallet().scanResponse, derivations = derivations) return response.entries } .doOnFailure { throw it } @@ -135,12 +140,12 @@ internal class DefaultDerivationsRepository( return withContext(dispatchers.io) { userWalletsStore.update( userWalletId = userWalletId, - update = { userWallet -> userWallet.updateDerivedKeys(keys) }, + update = { userWallet -> userWallet.requireColdWallet().updateDerivedKeys(keys) }, // TODO [REDACTED_TASK_KEY] ) } } - private fun UserWallet.updateDerivedKeys(keys: DerivedKeys): UserWallet { + private fun UserWallet.Cold.updateDerivedKeys(keys: DerivedKeys): UserWallet { return copy( scanResponse = scanResponse.copy( derivedKeys = getUpdatedDerivedKeys(oldKeys = scanResponse.derivedKeys, newKeys = keys), diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt index fe02ce769f..2d52d344fe 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt @@ -6,6 +6,8 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isLocked +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository @@ -206,6 +208,7 @@ internal class BiometricUserWalletsListManager( changeSelectedUserWallet: Boolean, canOverridePublicInfo: Boolean, ): CompletionResult { + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] val encryptionKey = userWallet.scanResponse.card.encryptionKey ?.let { UserWalletEncryptionKey(userWallet.walletId, it) } ?: return CompletionResult.Success(Unit) // No encryption key, no need to save diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt index 8dca07bec0..df0951fab2 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt @@ -6,28 +6,34 @@ import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation internal val UserWallet.sensitiveInformation: UserWalletSensitiveInformation - get() = UserWalletSensitiveInformation( - wallets = scanResponse.card.wallets, - visaCardActivationStatus = scanResponse.visaCardActivationStatus, - ) + get() = when (this) { + is UserWallet.Cold -> UserWalletSensitiveInformation( + wallets = scanResponse.card.wallets, + visaCardActivationStatus = scanResponse.visaCardActivationStatus, + ) + is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]") + } internal val UserWallet.publicInformation: UserWalletPublicInformation - get() = UserWalletPublicInformation( - name = name, - walletId = walletId, - cardsInWallet = cardsInWallet, - isMultiCurrency = isMultiCurrency, - scanResponse = scanResponse.copy( - card = scanResponse.card.copy( - wallets = emptyList(), + get() = when (this) { + is UserWallet.Cold -> UserWalletPublicInformation( + name = name, + walletId = walletId, + cardsInWallet = cardsInWallet, + isMultiCurrency = isMultiCurrency, + scanResponse = scanResponse.copy( + card = scanResponse.card.copy( + wallets = emptyList(), + ), + visaCardActivationStatus = null, ), - visaCardActivationStatus = null, - ), - hasBackupError = hasBackupError, - ) + hasBackupError = hasBackupError, + ) + is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]") + } internal fun UserWalletPublicInformation.toUserWallet(): UserWallet { - return UserWallet( + return UserWallet.Cold( name = name, walletId = walletId, cardsInWallet = cardsInWallet, @@ -42,14 +48,19 @@ internal fun List.toUserWallets(): List } internal fun UserWallet.updateWith(sensitiveInformation: UserWalletSensitiveInformation): UserWallet { - return copy( - scanResponse = scanResponse.copy( - card = scanResponse.card.copy( - wallets = sensitiveInformation.wallets, - ), - visaCardActivationStatus = sensitiveInformation.visaCardActivationStatus, - ), - ) + return when (this) { + is UserWallet.Cold -> { + copy( + scanResponse = scanResponse.copy( + card = scanResponse.card.copy( + wallets = sensitiveInformation.wallets, + ), + visaCardActivationStatus = sensitiveInformation.visaCardActivationStatus, + ), + ) + } + is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]") + } } internal fun List.updateWith( @@ -68,11 +79,16 @@ internal fun List.updateWith( internal fun List.lockAll(): List = map(UserWallet::lock) -internal fun UserWallet.lock(): UserWallet = copy( - scanResponse = scanResponse.copy( - card = scanResponse.card.copy( - wallets = emptyList(), - ), - visaCardActivationStatus = null, - ), -) \ No newline at end of file +internal fun UserWallet.lock(): UserWallet = when (this) { + is UserWallet.Cold -> { + copy( + scanResponse = scanResponse.copy( + card = scanResponse.card.copy( + wallets = emptyList(), + ), + visaCardActivationStatus = null, + ), + ) + } + is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]") +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt index ab00fc7cfa..02c60262fc 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt @@ -17,6 +17,7 @@ import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.Basic import com.tangem.core.analytics.models.Basic.TransactionSent.MemoType import com.tangem.data.walletconnect.network.ethereum.LegacySdkHelper +import com.tangem.domain.wallets.models.UserWallet import com.tangem.operations.sign.SignHashCommand import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.extensions.safeUpdate @@ -133,7 +134,7 @@ class WalletConnectSdkHelper { fun isDemoCard(): Boolean { val userWallet = userWalletsListManager.selectedUserWalletSync ?: return false - return userWallet.scanResponse.isDemoCard() + return userWallet is UserWallet.Cold && userWallet.scanResponse.isDemoCard() } private suspend fun getWalletManager(blockchain: Blockchain, derivationPath: String?): WalletManager? { diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt index b42a994dd6..0487bee8ce 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt @@ -13,6 +13,8 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.extensions.filterNotNull @@ -410,6 +412,7 @@ class WalletConnectInteractor( } private fun getCardId(userWallet: UserWallet): String? { + userWallet.requireColdWallet() // [REDACTED_TASK_KEY] return if (userWallet.scanResponse.card.backupStatus?.isActive != true) { userWallet.cardId } else { // if wallet has backup, any card from wallet can be used to sign diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt index 1390b8d0bd..3ae653038c 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt @@ -19,6 +19,7 @@ import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.wallets.builder.UserWalletIdBuilder +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.sdk.api.TangemSdkManager import com.tangem.tap.common.analytics.events.AnalyticsParam @@ -86,7 +87,8 @@ internal class CardSettingsModel @Inject constructor( val userWallet = getUserWalletUseCase(userWalletId) .getOrElse { error("User wallet $userWalletId not found") } - cardSdkConfigRepository.isBiometricsRequestPolicy = userWallet.scanResponse.card.isAccessCodeSet && + cardSdkConfigRepository.isBiometricsRequestPolicy = + userWallet.requireColdWallet().scanResponse.card.isAccessCodeSet && // TODO [REDACTED_TASK_KEY] settingsRepository.shouldSaveAccessCodes() } } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt index f401bbfc09..34aa6d687a 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt @@ -14,6 +14,7 @@ import com.tangem.domain.card.ResetCardUserCodeParams import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.legacy.asLockable +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.DeleteWalletUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase @@ -59,6 +60,7 @@ internal class ResetCardModel @Inject constructor( // Use only for card-specific data private val userWallet = getUserWalletUseCase(userWalletId = currentUserWalletId) .getOrElse { error("Failed to get user wallet: $it") } + .requireColdWallet() private val currentCardTypesResolver = userWallet.cardTypesResolver private val currentUserCodeParams = ResetCardUserCodeParams( diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeModel.kt b/app/src/main/java/com/tangem/tap/features/home/HomeModel.kt index a3b184dc8e..132cbd1773 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeModel.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeModel.kt @@ -20,7 +20,7 @@ import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.tokens.TokensAction -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.usecase.SaveWalletUseCase import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter import com.tangem.tap.common.analytics.events.IntroductionProcess @@ -53,7 +53,7 @@ internal class HomeModel @Inject constructor( private val settingsRepository: SettingsRepository, private val urlOpener: UrlOpener, private val analyticsEventHandler: AnalyticsEventHandler, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, getUserCountryUseCase: GetUserCountryUseCase, ) : Model() { @@ -117,7 +117,7 @@ internal class HomeModel @Inject constructor( } private suspend fun proceedWithScanResponse(scanResponse: ScanResponse) { - val userWallet = userWalletBuilderFactory.create(scanResponse = scanResponse).build() + val userWallet = coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build() if (userWallet == null) { Timber.e("User wallet not created") diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt index f43a2d6aa6..d020b24f18 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt @@ -100,7 +100,7 @@ private suspend fun readCard() { } private fun proceedWithScanResponse(scanResponse: ScanResponse) = scope.launch { - val userWalletBuilder = store.inject(DaggerGraphState::userWalletBuilderFactory).create(scanResponse) + val userWalletBuilder = store.inject(DaggerGraphState::coldUserWalletBuilderFactory).create(scanResponse) val userWallet = userWalletBuilder.build().guard { Timber.e("User wallet not created") diff --git a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt index 7dee2ef45c..29b1eb08c8 100644 --- a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt @@ -36,6 +36,7 @@ import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase import com.tangem.domain.staking.FetchStakingTokensUseCase import com.tangem.domain.wallets.legacy.UserWalletsListManager +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.AssociateWalletsWithApplicationIdUseCase import com.tangem.domain.wallets.usecase.GetSavedWalletChangesUseCase import com.tangem.domain.wallets.usecase.UpdateRemoteWalletsInfoUseCase @@ -178,7 +179,7 @@ internal class MainViewModel @Inject constructor( userWalletsListManager.selectedUserWallet .distinctUntilChanged() .onEach { userWallet -> - Analytics.setContext(userWallet.scanResponse) + Analytics.setContext(userWallet.requireColdWallet().scanResponse) // TODO [REDACTED_TASK_KEY] } .flowOn(dispatchers.io) .launchIn(viewModelScope) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt index 6496defc91..2e92c8c5f4 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt @@ -10,6 +10,7 @@ import com.tangem.domain.models.network.NetworkAddress import com.tangem.domain.onramp.model.OnrampSource import com.tangem.domain.tokens.legacy.TradeCryptoAction import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.tap.common.analytics.events.Token import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder import com.tangem.tap.common.extensions.dispatchDebugErrorNotification @@ -104,7 +105,7 @@ object TradeCryptoMiddleware { } buyErc20TestnetTokens( - card = action.userWallet.scanResponse.card, + card = action.userWallet.requireColdWallet().scanResponse.card, // TODO [REDACTED_TASK_KEY] walletManager = walletManager, destinationAddress = currency.contractAddress, ) diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt index 26275a69eb..ef31519427 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt @@ -15,6 +15,7 @@ import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.legacy.unlockIfLockable +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.tap.backupService import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter import com.tangem.tap.common.extensions.* @@ -94,7 +95,7 @@ internal class WelcomeMiddleware { } .doOnSuccess { selectedUserWallet -> sendSignedInAnalyticsEvent( - scanResponse = selectedUserWallet.scanResponse, + scanResponse = selectedUserWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] signInType = Basic.SignedIn.SignInType.Biometric, ) @@ -117,7 +118,7 @@ internal class WelcomeMiddleware { ) scanCardInternal { scanResponse -> - val userWalletBuilder = store.inject(DaggerGraphState::userWalletBuilderFactory).create(scanResponse) + val userWalletBuilder = store.inject(DaggerGraphState::coldUserWalletBuilderFactory).create(scanResponse) val userWallet = userWalletBuilder.build() ?: return@scanCardInternal diff --git a/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt b/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt index be40dc6f87..2820d0ed44 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt @@ -3,19 +3,23 @@ package com.tangem.tap.network.auth import com.tangem.common.extensions.toHexString import com.tangem.datasource.api.common.AuthProvider import com.tangem.domain.wallets.legacy.UserWalletsListManager +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet internal class DefaultAuthProvider(private val userWalletsListManager: UserWalletsListManager) : AuthProvider { override fun getCardPublicKey(): String { - return userWalletsListManager.selectedUserWalletSync?.scanResponse?.card?.cardPublicKey?.toHexString() ?: "" + return userWalletsListManager.selectedUserWalletSync + ?.requireColdWallet()?.scanResponse?.card?.cardPublicKey?.toHexString() ?: "" } override fun getCardId(): String { - return userWalletsListManager.selectedUserWalletSync?.scanResponse?.card?.cardId ?: "" + return userWalletsListManager.selectedUserWalletSync + ?.requireColdWallet()?.scanResponse?.card?.cardId ?: "" } override fun getCardsPublicKeys(): Map { - return userWalletsListManager.userWalletsSync.associate { + return userWalletsListManager.userWalletsSync.filterIsInstance().associate { it.scanResponse.card.cardId to it.scanResponse.card.cardPublicKey.toHexString() } } diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt index 4082725f10..e69337350b 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt @@ -6,6 +6,7 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.blockchainsdk.utils.toBlockchain import com.tangem.data.common.currency.CryptoCurrencyFactory import com.tangem.domain.models.currency.CryptoCurrency +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.tap.common.extensions.inject import com.tangem.tap.domain.model.Currency import com.tangem.tap.proxy.redux.DaggerGraphState @@ -26,6 +27,7 @@ internal class CryptoCurrencyConverter( extraDerivationPath = value.derivationPath, scanResponse = requireNotNull( store.inject(DaggerGraphState::generalUserWalletsListManager).selectedUserWalletSync + ?.requireColdWallet() // TODO [REDACTED_TASK_KEY] ?.scanResponse, ), ), @@ -37,6 +39,7 @@ internal class CryptoCurrencyConverter( extraDerivationPath = value.derivationPath, scanResponse = requireNotNull( store.inject(DaggerGraphState::generalUserWalletsListManager).selectedUserWalletSync + ?.requireColdWallet() // TODO [REDACTED_TASK_KEY] ?.scanResponse, ), ), diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt index 9d8ccb0fbb..526d65968d 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt @@ -27,7 +27,7 @@ import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.domain.onboarding.repository.OnboardingRepository import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.walletmanager.WalletManagersFacade -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles @@ -78,5 +78,5 @@ data class DaggerGraphState( val uiMessageSender: UiMessageSender? = null, val onlineCardVerifier: OnlineCardVerifier? = null, val cardArworksProvider: CardArtworksProvider? = null, - val userWalletBuilderFactory: UserWalletBuilder.Factory? = null, + val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory? = null, ) : StateType \ No newline at end of file diff --git a/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt b/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt index c54a0f2e2f..3b75f3bc36 100644 --- a/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt +++ b/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt @@ -37,7 +37,7 @@ internal class DefaultDerivationsRepositoryTest { ) private val defaultUserWalletId = UserWalletId("011") - private val defaultUserWallet = UserWallet( + private val defaultUserWallet = UserWallet.Cold( name = "", walletId = defaultUserWalletId, cardsInWallet = setOf(), diff --git a/app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt b/app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt index 209dcbb443..fc6ecdab82 100644 --- a/app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt +++ b/app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt @@ -191,7 +191,7 @@ internal class BiometricUserWalletsListManagerTest(private val model: Model) { ) fun createUserWallet(id: String, isLocked: Boolean): UserWallet { - return UserWallet( + return UserWallet.Cold( name = "Wallet $id", walletId = UserWalletId(stringValue = id), cardsInWallet = emptySet(), diff --git a/common/test/src/main/java/com/tangem/common/test/domain/wallet/MockUserWalletFactory.kt b/common/test/src/main/java/com/tangem/common/test/domain/wallet/MockUserWalletFactory.kt index 4c16726aa0..14759ee6ab 100644 --- a/common/test/src/main/java/com/tangem/common/test/domain/wallet/MockUserWalletFactory.kt +++ b/common/test/src/main/java/com/tangem/common/test/domain/wallet/MockUserWalletFactory.kt @@ -17,10 +17,10 @@ object MockUserWalletFactory { derivedKeys = emptyMap(), ) - fun create(scanResponse: ScanResponse = defaultScanResponse): UserWallet { + fun create(scanResponse: ScanResponse = defaultScanResponse): UserWallet.Cold { val userWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build()!! - return UserWallet( + return UserWallet.Cold( walletId = userWalletId, name = "Wallet 1", cardsInWallet = emptySet(), diff --git a/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt index ae4c0443bf..875f1044f8 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt @@ -15,6 +15,8 @@ import com.tangem.domain.models.StatusSource import com.tangem.domain.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isLocked +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.converter.Converter /** @@ -54,6 +56,7 @@ class UserWalletItemUMConverter( } private fun getInfo(userWallet: UserWallet): UserWalletItemUM.Information.Loaded { + userWallet.requireColdWallet() val cardCount = userWallet.getCardsCount() ?: 1 val text = TextReference.PluralRes( id = R.plurals.card_label_card_count, diff --git a/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/swap/ExpressUtils.kt b/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/swap/ExpressUtils.kt index d1176e7256..23b96be742 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/swap/ExpressUtils.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/exchangeservice/swap/ExpressUtils.kt @@ -12,15 +12,20 @@ object ExpressUtils { private const val BATCH_ID_PARTNER = "AF990015" fun getRefCode(userWallet: UserWallet, appPreferencesStore: AppPreferencesStore): String? { - return when { - isRing(userWallet, appPreferencesStore) -> "ring" - isChangeNow(userWallet) -> "ChangeNow" - isPartner(userWallet) -> "partner" + return when (userWallet) { + is UserWallet.Cold -> { + when { + isRing(userWallet, appPreferencesStore) -> "ring" + isChangeNow(userWallet) -> "ChangeNow" + isPartner(userWallet) -> "partner" + else -> null + } + } else -> null } } - private fun isRing(selectedUserWallet: UserWallet, appPreferencesStore: AppPreferencesStore): Boolean { + private fun isRing(selectedUserWallet: UserWallet.Cold, appPreferencesStore: AppPreferencesStore): Boolean { val addedWalletsWithRings = runBlocking { appPreferencesStore.getSyncOrDefault( key = PreferencesKeys.ADDED_WALLETS_WITH_RING_KEY, @@ -31,7 +36,7 @@ object ExpressUtils { return addedWalletsWithRings.contains(selectedUserWallet.walletId.stringValue) } - private fun isChangeNow(selectedUserWallet: UserWallet): Boolean { + private fun isChangeNow(selectedUserWallet: UserWallet.Cold): Boolean { val changeNowRange = CardIdRangeDec( start = "AF99001800554008", end = "AF99001800559994", @@ -40,7 +45,7 @@ object ExpressUtils { return card.batchId == BATCH_ID_CHANGENOW || changeNowRange?.contains(card.cardId) == true } - private fun isPartner(selectedUserWallet: UserWallet): Boolean { + private fun isPartner(selectedUserWallet: UserWallet.Cold): Boolean { return selectedUserWallet.scanResponse.card.batchId == BATCH_ID_PARTNER } } \ No newline at end of file diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt index 397f26a256..a82af53a79 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt @@ -15,6 +15,8 @@ import com.tangem.domain.models.network.Network import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency +import com.tangem.domain.wallets.models.requireColdWallet /** * Default implementation of factory for creating list of [CryptoCurrency] for selected card @@ -39,7 +41,7 @@ internal class DefaultCardCryptoCurrencyFactory( val blockchain = Blockchain.fromNetworkId(networkId = network.backendId) // multi-currency wallet - if (userWallet.isMultiCurrency) { + if (userWallet !is UserWallet.Cold || userWallet.isMultiCurrency) { return getMultiWalletCurrencies(userWallet = userWallet, networks = setOf(network))[network].orEmpty() } @@ -62,7 +64,7 @@ internal class DefaultCardCryptoCurrencyFactory( val blockchain = networkRawId.toBlockchain() // multi-currency wallet - if (userWallet.isMultiCurrency) { + if (userWallet.isMultiCurrency || userWallet !is UserWallet.Cold) { return getMultiWalletCurrenciesByRawId( userWallet = userWallet, rawIds = setOf(networkRawId), @@ -146,7 +148,7 @@ internal class DefaultCardCryptoCurrencyFactory( tokens = response.tokens.filter { token -> networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath } }, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) .groupBy(CryptoCurrency::network) } @@ -164,7 +166,7 @@ internal class DefaultCardCryptoCurrencyFactory( return responseCurrenciesFactory.createCurrencies( tokens = response.tokens.filter { token -> token.networkId in networkIds }, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) .groupBy { it.network.id.rawId } } diff --git a/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt b/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt index c1f68e38c2..5b757925b0 100644 --- a/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt +++ b/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt @@ -333,7 +333,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { ) } - data class CreateDefaultForMultiWalletModel(val multiWallet: UserWallet, val expected: List) + data class CreateDefaultForMultiWalletModel(val multiWallet: UserWallet.Cold, val expected: List) @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -381,7 +381,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { } data class CreatePrimaryCurrencyForSingleWalletModel( - val singleWallet: UserWallet, + val singleWallet: UserWallet.Cold, val expected: Result, ) @@ -424,7 +424,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { private fun provideTestModels() = listOf( CreateForSingleWalletWithTokenModel( - singleWalletWithToken = UserWallet( + singleWalletWithToken = UserWallet.Cold( name = "NODL", walletId = UserWalletId("011"), cardsInWallet = setOf(), @@ -457,13 +457,13 @@ internal class DefaultCardCryptoCurrencyFactoryTest { } data class CreateForSingleWalletWithTokenModel( - val singleWalletWithToken: UserWallet, + val singleWalletWithToken: UserWallet.Cold, val isPrimaryTokenExpected: Boolean = false, val expected: Result>, ) - private fun createMultiWallet(cardId: String? = null, batchId: String? = null): UserWallet { - return UserWallet( + private fun createMultiWallet(cardId: String? = null, batchId: String? = null): UserWallet.Cold { + return UserWallet.Cold( name = "Wallet 1", walletId = UserWalletId("011"), cardsInWallet = setOf(), @@ -483,8 +483,8 @@ internal class DefaultCardCryptoCurrencyFactoryTest { ) } - private fun createSingleWallet(batchId: String? = null, addWalletData: Boolean = false): UserWallet { - return UserWallet( + private fun createSingleWallet(batchId: String? = null, addWalletData: Boolean = false): UserWallet.Cold { + return UserWallet.Cold( name = "Note", walletId = UserWalletId("011"), cardsInWallet = setOf(), @@ -515,8 +515,8 @@ internal class DefaultCardCryptoCurrencyFactoryTest { ) } - private fun createSingleWalletWithToken(): UserWallet { - return UserWallet( + private fun createSingleWalletWithToken(): UserWallet.Cold { + return UserWallet.Cold( name = "NODL", walletId = UserWalletId("011"), cardsInWallet = setOf(), diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt index d71e1db8a7..b426db7892 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt @@ -27,6 +27,7 @@ import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext @@ -96,7 +97,7 @@ internal class DefaultCustomTokensRepository( networkFactory.create( networkId = networkId, derivationPath = derivationPath, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ), ) { "Network [$networkId] not found while finding token" @@ -152,7 +153,7 @@ internal class DefaultCustomTokensRepository( networkFactory.create( networkId = networkId, derivationPath = derivationPath, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ), ) { "Network [$networkId] not found while creating coin" @@ -189,7 +190,7 @@ internal class DefaultCustomTokensRepository( networkFactory.create( networkId = networkId, derivationPath = derivationPath, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ), ) { "Network [$networkId] not found while creating custom token" @@ -249,7 +250,7 @@ internal class DefaultCustomTokensRepository( val userWallet = requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) { "User wallet [$userWalletId] not found while getting supported networks" } - val scanResponse = userWallet.scanResponse + val scanResponse = userWallet.requireColdWallet().scanResponse // TODO [REDACTED_TASK_KEY] Blockchain.entries .mapNotNull { blockchain -> diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt index e57c96ffbc..7b4aef4179 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt @@ -33,6 +33,7 @@ import com.tangem.domain.managetokens.repository.ManageTokensRepository import com.tangem.domain.models.network.Network import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.pagination.BatchFetchResult import com.tangem.pagination.BatchListSource import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher @@ -80,7 +81,7 @@ internal class DefaultManageTokensRepository( subFetcher = { request, _, isFirstBatchFetching -> val userWallet = request.params.userWalletId?.let(userWalletsStore::getSyncStrict) - if (userWallet?.scanResponse?.card?.isTestCard == true) { + if (userWallet is UserWallet.Cold && userWallet.scanResponse.card.isTestCard) { fetchTestnetCurrencies(userWallet, request) } else { fetchCurrencies( @@ -143,13 +144,13 @@ internal class DefaultManageTokensRepository( managedCryptoCurrencyFactory.createWithCustomTokens( coinsResponse = updatedCoinsResponse, tokensResponse = tokensResponse, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) } else { managedCryptoCurrencyFactory.create( coinsResponse = updatedCoinsResponse, tokensResponse = tokensResponse, - scanResponse = userWallet?.scanResponse, + scanResponse = userWallet?.requireColdWallet()?.scanResponse, // TODO [REDACTED_TASK_KEY] ) } @@ -179,7 +180,7 @@ internal class DefaultManageTokensRepository( testnetTokensConfig }, tokensResponse = getSavedUserTokensResponseSync(userWallet.walletId), - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) return BatchFetchResult.Success( @@ -191,14 +192,16 @@ internal class DefaultManageTokensRepository( private fun createDefaultUserTokensResponse(userWallet: UserWallet) = userTokensResponseFactory.createUserTokensResponse( - currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(userWallet.scanResponse), + currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard( + userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] + ), isGroupedByNetwork = false, isSortedByBalance = false, ) private fun getSupportedBlockchains(userWallet: UserWallet?): List { - return userWallet?.scanResponse?.let { - it.card.supportedBlockchains(it.cardTypesResolver, excludedBlockchains) + return (userWallet as? UserWallet.Cold)?.scanResponse?.let { + it.card.supportedBlockchains(it.cardTypesResolver, excludedBlockchains) // TODO [REDACTED_TASK_KEY] } ?: Blockchain.entries.filter { !it.isTestnet() && it !in excludedBlockchains } @@ -285,6 +288,10 @@ internal class DefaultManageTokensRepository( userWallet: UserWallet, blockchain: Blockchain, ): CurrencyUnsupportedState? { + if (userWallet !is UserWallet.Cold) { + return null + } + val canHandleBlockchain = userWallet.scanResponse.card.canHandleBlockchain( blockchain = blockchain, cardTypesResolver = userWallet.cardTypesResolver, @@ -302,6 +309,10 @@ internal class DefaultManageTokensRepository( userWallet: UserWallet, blockchain: Blockchain, ): CurrencyUnsupportedState.Token? { + if (userWallet !is UserWallet.Cold) { + return null + } + val cardTypesResolver = userWallet.scanResponse.cardTypesResolver val supportedTokens = userWallet.scanResponse.card.supportedTokens( cardTypesResolver, diff --git a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt index 01cf2d40ff..cba7c2bf69 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt @@ -24,6 +24,7 @@ import com.tangem.domain.markets.* import com.tangem.domain.markets.repositories.MarketsTokenRepository import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.pagination.* import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher import com.tangem.utils.coroutines.CoroutineDispatcherProvider @@ -250,13 +251,13 @@ internal class DefaultMarketsTokenRepository( cryptoCurrencyFactory.createCoin( blockchain = blockchain, extraDerivationPath = null, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) } else { val currencyNetwork = networkFactory.create( blockchain = blockchain, extraDerivationPath = null, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) ?: return null cryptoCurrencyFactory.createToken( diff --git a/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcher.kt b/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcher.kt index 3c8ae5b060..aa05c31589 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcher.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcher.kt @@ -11,6 +11,7 @@ import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.core.utils.eitherOn import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -52,7 +53,7 @@ internal class DefaultMultiNetworkStatusFetcher @Inject constructor( }, ) - val cardTypesResolver = userWallet.cardTypesResolver + val cardTypesResolver = userWallet.requireColdWallet().cardTypesResolver // TODO [REDACTED_TASK_KEY] val isWalletSupported = with(cardTypesResolver) { isMultiwalletAllowed() || isSingleWalletWithToken() } diff --git a/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt b/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt index 0bef8fea06..4b46ecc55d 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt @@ -5,6 +5,7 @@ import com.tangem.data.networks.store.NetworksStatusesStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.models.network.NetworkStatus import com.tangem.domain.networks.multi.MultiNetworkStatusProducer +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -47,7 +48,7 @@ internal class DefaultMultiNetworkStatusProducer @AssistedInject constructor( val network = networkFactory.create( networkId = status.id, derivationPath = status.id.derivationPath, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, ) ?: return@mapNotNullTo null NetworkStatus(network = network, value = status.value) diff --git a/data/networks/src/test/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcherTest.kt b/data/networks/src/test/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcherTest.kt index 2357fdf65b..4284eb4610 100644 --- a/data/networks/src/test/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcherTest.kt +++ b/data/networks/src/test/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusFetcherTest.kt @@ -63,7 +63,7 @@ internal class DefaultMultiNetworkStatusFetcherTest { coEvery { networksStatusesStore.setSourceAsCache(params.userWalletId, params.networks) } returns Unit every { userWalletsStore.getSyncStrict(key = userWalletId) } returns userWallet - mockkStatic(UserWallet::cardTypesResolver) + mockkStatic(UserWallet.Cold::cardTypesResolver) every { userWallet.cardTypesResolver } returns cardTypesResolver coEvery { cardTypesResolver.isMultiwalletAllowed() } returns true @@ -132,7 +132,7 @@ internal class DefaultMultiNetworkStatusFetcherTest { coEvery { networksStatusesStore.setSourceAsCache(params.userWalletId, params.networks) } returns Unit every { userWalletsStore.getSyncStrict(key = userWalletId) } returns userWallet - mockkStatic(UserWallet::cardTypesResolver) + mockkStatic(UserWallet.Cold::cardTypesResolver) every { userWallet.cardTypesResolver } returns cardTypesResolver coEvery { cardTypesResolver.isMultiwalletAllowed() } returns false coEvery { cardTypesResolver.isSingleWalletWithToken() } returns true @@ -193,7 +193,7 @@ internal class DefaultMultiNetworkStatusFetcherTest { coEvery { networksStatusesStore.setSourceAsCache(params.userWalletId, params.networks) } returns Unit every { userWalletsStore.getSyncStrict(key = userWalletId) } returns userWallet - mockkStatic(UserWallet::cardTypesResolver) + mockkStatic(UserWallet.Cold::cardTypesResolver) every { userWallet.cardTypesResolver } returns cardTypesResolver coEvery { cardTypesResolver.isMultiwalletAllowed() } returns true @@ -267,7 +267,7 @@ internal class DefaultMultiNetworkStatusFetcherTest { coEvery { networksStatusesStore.setSourceAsCache(params.userWalletId, params.networks) } returns Unit every { userWalletsStore.getSyncStrict(key = userWalletId) } returns userWallet - mockkStatic(UserWallet::cardTypesResolver) + mockkStatic(UserWallet.Cold::cardTypesResolver) every { userWallet.cardTypesResolver } returns cardTypesResolver coEvery { cardTypesResolver.isMultiwalletAllowed() } returns true @@ -367,7 +367,7 @@ internal class DefaultMultiNetworkStatusFetcherTest { coEvery { networksStatusesStore.setSourceAsCache(params.userWalletId, params.networks) } returns Unit every { userWalletsStore.getSyncStrict(key = userWalletId) } returns userWallet - mockkStatic(UserWallet::cardTypesResolver) + mockkStatic(UserWallet.Cold::cardTypesResolver) every { userWallet.cardTypesResolver } returns cardTypesResolver coEvery { cardTypesResolver.isMultiwalletAllowed() } returns false coEvery { cardTypesResolver.isSingleWalletWithToken() } returns false diff --git a/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt b/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt index be8119323d..86dfb3f5d9 100644 --- a/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt +++ b/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt @@ -26,6 +26,7 @@ import com.tangem.domain.nft.models.NFTSalePrice import com.tangem.domain.nft.repository.NFTRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.features.nft.NFTFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.JobHolder @@ -204,7 +205,7 @@ internal class DefaultNFTRepository @Inject constructor( networkFactory.create( blockchain = it, extraDerivationPath = null, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) } } diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt index dd1fb830b0..e0d1ec226d 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt @@ -26,6 +26,7 @@ import com.tangem.domain.onramp.model.HotCryptoCurrency import com.tangem.domain.onramp.repositories.HotCryptoRepository import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.runCatching @@ -90,7 +91,7 @@ internal class DefaultHotCryptoRepository( ?: error("UserWalletId [$userWalletId] not found") HotCryptoCurrencyConverter( - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] imageHost = it.imageHost, excludedBlockchains = excludedBlockchains, ) @@ -170,6 +171,10 @@ internal class DefaultHotCryptoRepository( // TODO: [REDACTED_JIRA] private fun UserWallet.canHandleHotCrypto(hotToken: HotCryptoResponse.Token): Boolean { + if (this !is UserWallet.Cold) { + return true // TODO [REDACTED_TASK_KEY] + } + val isToken = hotToken.contractAddress != null && hotToken.decimalCount != null val blockchain = hotToken.networkId?.let { Blockchain.fromNetworkId(it) } ?: return false diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt index b19d89c694..fd08381f40 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt @@ -60,6 +60,7 @@ import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.staking.toggles.StakingFeatureToggles import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.lib.crypto.BlockchainUtils.isCardano @@ -257,6 +258,11 @@ internal class DefaultStakingRepository( val userWallet = getUserWalletUseCase(userWalletId).getOrElse { error("Failed to get user wallet") } + + if (userWallet !is UserWallet.Cold) { + return false + } + val blockchainId = cryptoCurrency.network.rawId return when { isSolana(blockchainId) -> INVALID_BATCHES_FOR_SOLANA.contains(userWallet.scanResponse.card.batchId) diff --git a/data/staking/src/main/java/com/tangem/data/staking/fetcher/CommonYieldBalanceFetcherDelegate.kt b/data/staking/src/main/java/com/tangem/data/staking/fetcher/CommonYieldBalanceFetcherDelegate.kt index 37a6f4a8b5..3376520131 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/fetcher/CommonYieldBalanceFetcherDelegate.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/fetcher/CommonYieldBalanceFetcherDelegate.kt @@ -17,6 +17,7 @@ import com.tangem.domain.staking.fetcher.YieldBalanceFetcherParams import com.tangem.domain.staking.model.StakingID import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.utils.coroutines.CoroutineDispatcherProvider import timber.log.Timber diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 13eea18e86..52142a7581 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -30,6 +30,9 @@ import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isLocked +import com.tangem.domain.wallets.models.isMultiCurrency +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.* import kotlinx.coroutines.flow.* @@ -222,7 +225,9 @@ internal class DefaultCurrenciesRepository( val userWallet = getUserWallet(userWalletId) ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false) - val currency = cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse) + val currency = cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard( + userWallet.requireColdWallet().scanResponse, + ) fetchExpressAssetsByNetworkIds(userWalletId, listOf(currency), refresh) currency } @@ -233,7 +238,7 @@ internal class DefaultCurrenciesRepository( refresh: Boolean, ): List { return withContext(dispatchers.io) { - val scanResponse = getUserWallet(userWalletId).scanResponse + val scanResponse = getUserWallet(userWalletId).requireColdWallet().scanResponse val currencies = if (scanResponse.cardTypesResolver.isSingleWalletWithToken()) { cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(scanResponse = scanResponse) @@ -257,7 +262,7 @@ internal class DefaultCurrenciesRepository( ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false) val currency = cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken( - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, ) .find { it.id == id } requireNotNull(currency) { "Unable to find currency with provided ID: $id" } @@ -297,7 +302,7 @@ internal class DefaultCurrenciesRepository( }, ) - responseCurrenciesFactory.createCurrencies(storedTokens, userWallet.scanResponse) + responseCurrenciesFactory.createCurrencies(storedTokens, userWallet.requireColdWallet().scanResponse) } override suspend fun getMultiCurrencyWalletCachedCurrenciesSync(userWalletId: UserWalletId) = @@ -312,7 +317,7 @@ internal class DefaultCurrenciesRepository( }, ) - responseCurrenciesFactory.createCurrencies(storedTokens, userWallet.scanResponse) + responseCurrenciesFactory.createCurrencies(storedTokens, userWallet.requireColdWallet().scanResponse) } override suspend fun getMultiCurrencyWalletCurrency( @@ -337,7 +342,7 @@ internal class DefaultCurrenciesRepository( responseCurrenciesFactory.createCurrency( currencyId = id, response = response, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, ) } @@ -369,7 +374,7 @@ internal class DefaultCurrenciesRepository( it.derivationPath == derivationPath.value } ?: error("Coin in this network $networkId not found") - val coin = responseCurrenciesFactory.createCurrency(storedCoin, userWallet.scanResponse) + val coin = responseCurrenciesFactory.createCurrency(storedCoin, userWallet.requireColdWallet().scanResponse) coin as? CryptoCurrency.Coin ?: error("Unable to create currency") } @@ -488,7 +493,7 @@ internal class DefaultCurrenciesRepository( token = token, networkId = networkId, extraDerivationPath = null, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) ?: error("Unable to create token") } @@ -510,7 +515,7 @@ internal class DefaultCurrenciesRepository( responseCurrenciesFactory.createCurrencies( response = storedTokens.copy(tokens = filterResponse), - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, ) } } else { @@ -544,8 +549,8 @@ internal class DefaultCurrenciesRepository( lazyMessage = { "Saved tokens empty. Can not perform add currencies action" }, ) userTokensSaver.push( - userWalletId, - savedCurrencies, + userWalletId = userWalletId, + response = savedCurrencies, onFailSend = { throw IllegalStateException("Unable to push tokens") }, @@ -556,7 +561,7 @@ internal class DefaultCurrenciesRepository( return getSavedUserTokensResponse(userWallet.walletId).map { storedTokens -> responseCurrenciesFactory.createCurrencies( response = storedTokens, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, ) } } @@ -579,7 +584,7 @@ internal class DefaultCurrenciesRepository( private suspend fun fetchTokens(userWallet: UserWallet) { val userWalletId = userWallet.walletId - val response = if (checkIsEmptyDemoWallet(userWallet)) { + val response = if (userWallet is UserWallet.Cold && checkIsEmptyDemoWallet(userWallet)) { createDefaultUserTokensResponse(userWallet) } else { safeApiCall({ tangemTechApi.getUserTokens(userWalletId.stringValue).bind() }) { @@ -596,7 +601,7 @@ internal class DefaultCurrenciesRepository( fetchExpressAssetsByNetworkIds(userWalletId, compatibleUserTokensResponse) } - private suspend fun checkIsEmptyDemoWallet(userWallet: UserWallet): Boolean { + private suspend fun checkIsEmptyDemoWallet(userWallet: UserWallet.Cold): Boolean { val response = getSavedUserTokensResponseSync(key = userWallet.walletId) return demoConfig.isDemoCardId(userWallet.cardId) && response == null @@ -659,7 +664,9 @@ internal class DefaultCurrenciesRepository( private fun createDefaultUserTokensResponse(userWallet: UserWallet) = userTokensResponseFactory.createUserTokensResponse( - currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(userWallet.scanResponse), + currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard( + userWallet.requireColdWallet().scanResponse, + ), isGroupedByNetwork = false, isSortedByBalance = false, ) diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaRepository.kt index b513244dfc..3e3faade06 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaRepository.kt @@ -24,6 +24,7 @@ import com.tangem.domain.visa.model.VisaTxHistoryItem import com.tangem.domain.visa.repository.VisaRepository import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -142,7 +143,7 @@ internal class DefaultVisaRepository @Inject constructor( txDetailsFactory.create( transaction = transaction, - walletBlockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain(), + walletBlockchain = userWallet.requireColdWallet().scanResponse.cardTypesResolver.getBlockchain(), ) } } @@ -153,7 +154,7 @@ internal class DefaultVisaRepository @Inject constructor( val customerInfo = visaApiRequestMaker.request(userWalletId) { authHeader, _ -> visaApi.getCustomerInfo( authHeader = authHeader, - cardId = userWallet.scanResponse.card.cardId, + cardId = userWallet.requireColdWallet().scanResponse.card.cardId, ) } @@ -198,7 +199,7 @@ internal class DefaultVisaRepository @Inject constructor( } private fun makeWalletAddresses(userWallet: UserWallet): Set
{ - val walletBlockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain() + val walletBlockchain = userWallet.requireColdWallet().scanResponse.cardTypesResolver.getBlockchain() return walletBlockchain.makeAddresses(getCardPubKey(userWallet).hexToBytes()) } @@ -206,7 +207,7 @@ internal class DefaultVisaRepository @Inject constructor( private fun getCardPubKey(userWallet: UserWallet): String { if (VisaConstants.IS_DEMO_MODE_ENABLED) return getDemoPublicKey() - val cardWallet = userWallet.scanResponse.card.wallets.firstOrNull { + val cardWallet = userWallet.requireColdWallet().scanResponse.card.wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 } requireNotNull(cardWallet) { "Visa card wallet not found" } @@ -218,7 +219,7 @@ internal class DefaultVisaRepository @Inject constructor( val userWallet = requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) { "No user wallet found: $userWalletId" } - if (!userWallet.scanResponse.cardTypesResolver.isVisaWallet()) { + if (!userWallet.requireColdWallet().scanResponse.cardTypesResolver.isVisaWallet()) { error("VISA wallet required: $userWalletId") } diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaApiRequestMaker.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaApiRequestMaker.kt index 73b1f217b9..147f558037 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaApiRequestMaker.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaApiRequestMaker.kt @@ -15,6 +15,7 @@ import com.tangem.domain.visa.model.VisaCardActivationStatus import com.tangem.domain.visa.model.getAuthHeader import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext import javax.inject.Inject @@ -52,7 +53,7 @@ internal class VisaApiRequestMaker @Inject constructor( it.code == ApiResponseError.HttpException.Code.UNAUTHORIZED ) { userWalletsStore.update(userWalletId) { userWallet -> - userWallet.copy( + userWallet.requireColdWallet().copy( scanResponse = userWallet.scanResponse.copy( visaCardActivationStatus = VisaCardActivationStatus.RefreshTokenExpired, ), @@ -63,7 +64,7 @@ internal class VisaApiRequestMaker @Inject constructor( } userWalletsStore.update(userWalletId) { userWallet -> - userWallet.copy( + userWallet.requireColdWallet().copy( scanResponse = userWallet.scanResponse.copy( visaCardActivationStatus = VisaCardActivationStatus.Activated( visaAuthTokens = newTokens, @@ -93,7 +94,8 @@ internal class VisaApiRequestMaker @Inject constructor( @Throws private fun getAuthTokens(userWalletId: UserWalletId): VisaAuthTokens { val userWallet = findVisaUserWallet(userWalletId) - val status = userWallet.scanResponse.visaCardActivationStatus ?: error("Visa card activation status not found") + val status = userWallet.requireColdWallet().scanResponse.visaCardActivationStatus + ?: error("Visa card activation status not found") if (status is VisaCardActivationStatus.RefreshTokenExpired) { throw RefreshTokenExpiredException() @@ -106,7 +108,7 @@ internal class VisaApiRequestMaker @Inject constructor( val userWallet = requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) { "No user wallet found: $userWalletId" } - if (!userWallet.scanResponse.cardTypesResolver.isVisaWallet()) { + if (!userWallet.requireColdWallet().scanResponse.cardTypesResolver.isVisaWallet()) { error("VISA wallet required: $userWalletId") } diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt index eb27b1bbf1..ef587b5c24 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt @@ -8,6 +8,7 @@ import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.NetworkAddress import com.tangem.domain.visa.model.VisaCurrency import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.lib.visa.model.VisaContractInfo import org.joda.time.DateTime import org.joda.time.DateTimeZone @@ -33,7 +34,7 @@ internal class VisaCurrencyFactory @Inject constructor( val currencyNetwork = networkFactory.create( blockchain = Blockchain.Polygon, extraDerivationPath = null, - derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider, + derivationStyleProvider = userWallet.requireColdWallet().scanResponse.derivationStyleProvider, canHandleTokens = true, ) ?: error("Unable to create network for Visa currency") diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/DefaultWalletConnectRepository.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/DefaultWalletConnectRepository.kt index f701e44de9..2361fb2afa 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/DefaultWalletConnectRepository.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/DefaultWalletConnectRepository.kt @@ -3,6 +3,7 @@ package com.tangem.data.walletconnect import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.walletconnect.repository.WalletConnectRepository import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt index 48fe67a9e8..7208eea4c4 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt @@ -9,6 +9,7 @@ import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletconnect.model.WcPairError import com.tangem.domain.walletconnect.model.WcSessionProposal.ProposalNetwork import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.domain.wallets.usecase.GetWalletsUseCase internal class AssociateNetworksDelegate( diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/utils/WcNamespaceConverter.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/utils/WcNamespaceConverter.kt index 2dba0c115b..258733919d 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/utils/WcNamespaceConverter.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/utils/WcNamespaceConverter.kt @@ -7,6 +7,7 @@ import com.tangem.data.walletconnect.model.CAIP2 import com.tangem.data.walletconnect.model.NamespaceKey import com.tangem.domain.models.network.Network import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet internal interface WcNamespaceConverter { @@ -25,7 +26,7 @@ internal interface WcNamespaceConverter { return NetworkFactory(excludedBlockchains).create( blockchain = blockchain, extraDerivationPath = null, - scanResponse = wallet.scanResponse, + scanResponse = wallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) } } \ No newline at end of file diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt index 2e686eac78..5baba2e05e 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt @@ -89,6 +89,11 @@ internal class DefaultWalletsRepository( private suspend fun fetchSeedPhraseNotificationStatus(userWalletId: UserWalletId) { val userWallet = userWalletsStore.getSyncOrNull(key = userWalletId) + if (userWallet != null && userWallet !is UserWallet.Cold) { + updateNotificationVisibility(id = userWalletId, value = SeedPhraseNotificationsStatus.NOT_NEEDED) + return + } + val status = if (userWallet?.isImported == false) { Status.NOT_NEEDED } else { @@ -291,7 +296,7 @@ internal class DefaultWalletsRepository( override suspend fun associateWallets(applicationId: String, wallets: List) = withContext(dispatchers.io) { val publicKeys = authProvider.getCardsPublicKeys() - val walletsBody = wallets.map { userWallet -> + val walletsBody = wallets.filterIsInstance().map { userWallet -> WalletIdBodyConverter.convert( userWallet = userWallet, publicKeys = publicKeys.filterKeys { userWallet.cardsInWallet.contains(it) }, diff --git a/data/wallets/src/test/java/com/tangem/data/wallets/DefaultWalletsRepositoryTest.kt b/data/wallets/src/test/java/com/tangem/data/wallets/DefaultWalletsRepositoryTest.kt index 1d130bcda4..02f3bbf6eb 100644 --- a/data/wallets/src/test/java/com/tangem/data/wallets/DefaultWalletsRepositoryTest.kt +++ b/data/wallets/src/test/java/com/tangem/data/wallets/DefaultWalletsRepositoryTest.kt @@ -176,12 +176,12 @@ class DefaultWalletsRepositoryTest { val card2PublicKey = "card2_public_key" val userWallets = listOf( - mockk { + mockk { every { cardsInWallet } returns setOf(card1PublicKey) every { walletId } returns UserWalletId(wallet1Id) every { name } returns "Wallet 1" }, - mockk { + mockk { every { cardsInWallet } returns setOf(card2PublicKey) every { walletId } returns UserWalletId(wallet2Id) every { name } returns "Wallet 2" diff --git a/data/wallets/src/test/java/com/tangem/data/wallets/converters/WalletIdBodyConverterTest.kt b/data/wallets/src/test/java/com/tangem/data/wallets/converters/WalletIdBodyConverterTest.kt index 2aa327b6d9..3a197969b0 100644 --- a/data/wallets/src/test/java/com/tangem/data/wallets/converters/WalletIdBodyConverterTest.kt +++ b/data/wallets/src/test/java/com/tangem/data/wallets/converters/WalletIdBodyConverterTest.kt @@ -15,7 +15,7 @@ class WalletIdBodyConverterTest { // GIVEN val walletId = UserWalletId("1234567890abcdef") val walletName = "Test Wallet" - val userWallet = UserWallet( + val userWallet = UserWallet.Cold( walletId = walletId, name = walletName, cardsInWallet = setOf("card1", "card2"), @@ -55,7 +55,7 @@ class WalletIdBodyConverterTest { // GIVEN val walletId = UserWalletId("1234567890abcdef") val walletName = "Test Wallet" - val userWallet = UserWallet( + val userWallet = UserWallet.Cold( walletId = walletId, name = walletName, cardsInWallet = emptySet(), diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExt.kt b/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExt.kt index 3314e43f63..60c72030bc 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExt.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/util/ScanResponseExt.kt @@ -29,7 +29,7 @@ val ScanResponse.derivationStyleProvider: DerivationStyleProvider val CardDTO.derivationStyleProvider: DerivationStyleProvider get() = TangemDerivationStyleProvider(this) -val UserWallet.cardTypesResolver: CardTypesResolver +val UserWallet.Cold.cardTypesResolver: CardTypesResolver get() = scanResponse.cardTypesResolver fun ScanResponse.twinsIsTwinned(): Boolean = card.isTangemTwins && walletData != null && secondTwinPublicKey != null diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/util/UserWalletExt.kt b/domain/legacy/src/main/java/com/tangem/domain/common/util/UserWalletExt.kt index 0b5ef6f2fd..c2b1028845 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/util/UserWalletExt.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/util/UserWalletExt.kt @@ -7,11 +7,11 @@ import com.tangem.domain.wallets.models.UserWallet * * @return null if wallet is not multi-currency or total cards count */ -fun UserWallet.getCardsCount(): Int? = scanResponse.getCardsCount() +fun UserWallet.Cold.getCardsCount(): Int? = scanResponse.getCardsCount() /** * Get backup cards count for a card that was saved in [UserWallet] * * @return null if wallet is not multi-currency or total cards count */ -fun UserWallet.getBackupCardsCount(): Int? = scanResponse.getBackupCardsCount() \ No newline at end of file +fun UserWallet.Cold.getBackupCardsCount(): Int? = scanResponse.getBackupCardsCount() \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index a950826024..ebbb56ce04 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -41,6 +41,7 @@ import com.tangem.domain.walletmanager.utils.* import com.tangem.domain.walletmanager.utils.WalletManagerFactory import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.sync.Mutex @@ -162,7 +163,10 @@ class DefaultWalletManagersFacade( val blockchain = network.toBlockchain() val derivationPath = network.derivationPath.value - if (derivationPath != null && !userWallet.scanResponse.hasDerivation(blockchain, derivationPath)) { + if (derivationPath != null && + userWallet is UserWallet.Cold && + !userWallet.scanResponse.hasDerivation(blockchain, derivationPath) + ) { Timber.w("Derivation missed for: $blockchain") return UpdateWalletManagerResult.MissedDerivation } @@ -286,9 +290,10 @@ class DefaultWalletManagersFacade( derivationPath: String?, extraTokens: Set, ): UpdateWalletManagerResult { - val scanResponse = userWallet.scanResponse - - if (derivationPath != null && !scanResponse.hasDerivation(blockchain, derivationPath)) { + if (derivationPath != null && + userWallet is UserWallet.Cold && + !userWallet.scanResponse.hasDerivation(blockchain, derivationPath) + ) { Timber.w("Derivation missed for: $blockchain") return UpdateWalletManagerResult.MissedDerivation } @@ -306,7 +311,7 @@ class DefaultWalletManagersFacade( updateWalletManagerTokensIfNeeded(walletManager, extraTokens) return try { - if (demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) { + if (userWallet is UserWallet.Cold && demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) { updateDemoWalletManager(walletManager) } else { updateWalletManager(walletManager) @@ -365,6 +370,9 @@ class DefaultWalletManagersFacade( ): WalletManager? { initMutex.withLock { val userWallet = getUserWallet(userWalletId) + + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] + var walletManager = walletManagersStore.getSyncOrNull( userWalletId = userWalletId, blockchain = blockchain, diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt index 1b645a2d53..928d513a7e 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt @@ -6,6 +6,7 @@ import com.tangem.blockchainsdk.utils.fromNetworkId import com.tangem.domain.common.extensions.supportedBlockchains import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.wallets.legacy.UserWalletsListManager +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId class FilterAvailableNetworksForWalletUseCase( @@ -25,14 +26,21 @@ class FilterAvailableNetworksForWalletUseCase( it.walletId == userWalletId } ?: return networks.toSet() - val supportedBlockchains = userWallet.scanResponse.card.supportedBlockchains( - cardTypesResolver = userWallet.scanResponse.cardTypesResolver, - excludedBlockchains = excludedBlockchains, - ) + return when (userWallet) { + is UserWallet.Cold -> { + val supportedBlockchains = userWallet.scanResponse.card.supportedBlockchains( + cardTypesResolver = userWallet.scanResponse.cardTypesResolver, + excludedBlockchains = excludedBlockchains, + ) - return networks.filter { - val blockchain = Blockchain.fromNetworkId(it.networkId) - supportedBlockchains.contains(blockchain) - }.toSet() + networks.filter { + val blockchain = Blockchain.fromNetworkId(it.networkId) + supportedBlockchains.contains(blockchain) + }.toSet() + } + is UserWallet.Hot -> { + networks.toSet() // TODO [REDACTED_TASK_KEY] + } + } } } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt index aefd1ac565..77f16153ff 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt @@ -17,6 +17,7 @@ import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.transaction.models.AssetRequirementsCondition import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.isNullOrZero import kotlinx.coroutines.flow.* @@ -41,6 +42,20 @@ class GetCryptoCurrencyActionsUseCase( suspend operator fun invoke( userWallet: UserWallet, cryptoCurrencyStatus: CryptoCurrencyStatus, + ): Flow { + return when (userWallet) { + is UserWallet.Cold -> { + coldFlow(userWallet, cryptoCurrencyStatus) + } + is UserWallet.Hot -> { + TODO("[REDACTED_TASK_KEY]") + } + } + } + + private suspend fun coldFlow( + userWallet: UserWallet.Cold, + cryptoCurrencyStatus: CryptoCurrencyStatus, ): Flow { val networkId = cryptoCurrencyStatus.currency.network.id val requirements = withTimeoutOrNull(REQUEST_EXCHANGE_DATA_TIMEOUT) { @@ -398,7 +413,10 @@ class GetCryptoCurrencyActionsUseCase( shouldShowSwapStories: Boolean, ): TokenActionsState.ActionState { val cryptoCurrency = cryptoCurrencyStatus.currency - return if (userWallet.isMultiCurrency) { + val isMultiCurrency = + userWallet is UserWallet.Hot || userWallet is UserWallet.Cold && userWallet.isMultiCurrency + + return if (isMultiCurrency) { if (cryptoCurrency.isCustom) { return TokenActionsState.ActionState.Swap( unavailabilityReason = ScenarioUnavailabilityReason.CustomToken(cryptoCurrency.name), @@ -429,6 +447,8 @@ class GetCryptoCurrencyActionsUseCase( userWallet: UserWallet, cryptoCurrencyStatus: CryptoCurrencyStatus, ): TokenActionsState.ActionState { + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] + val cryptoCurrency = cryptoCurrencyStatus.currency val reason = rampManager.availableForBuy(userWallet.scanResponse, userWallet.walletId, cryptoCurrency) return TokenActionsState.ActionState.Buy(unavailabilityReason = reason) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt index 41c738b897..a6241655a5 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt @@ -9,6 +9,7 @@ import com.tangem.domain.tokens.error.CurrencyStatusError import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency class GetCryptoCurrencyUseCase( private val currenciesRepository: CurrenciesRepository, diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt index b7b26d3b3b..dc7bda437b 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt @@ -30,7 +30,9 @@ class EstimateFeeUseCase( cryptoCurrency: CryptoCurrency, ): Either { val amountData = convertCryptoCurrencyToAmount(cryptoCurrency, amount) - val result = if (demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) { + val result = if (userWallet is UserWallet.Cold && + demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId) + ) { demoTransactionSender(userWallet, cryptoCurrency).estimateFee( amount = amountData, destination = "", diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt index 1bb55633b6..4a17628b39 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt @@ -30,7 +30,9 @@ class GetFeeUseCase( suspend operator fun invoke(userWallet: UserWallet, network: Network, transactionData: TransactionData) = either { catch( block = { - val transactionSender = if (demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) { + val transactionSender = if (userWallet is UserWallet.Cold && + demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId) + ) { demoTransactionSender(userWallet, network) } else { walletManagersFacade.getOrCreateWalletManager( @@ -63,7 +65,9 @@ class GetFeeUseCase( block = { val amountData = convertCryptoCurrencyToAmount(cryptoCurrency, amount) - val result = if (demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) { + val result = if (userWallet is UserWallet.Cold && + demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId) + ) { demoTransactionSender(userWallet, cryptoCurrency.network).getFee( amount = amountData, destination = destination, diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareForSendUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareForSendUseCase.kt index e89ec4901c..dab4a7f379 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareForSendUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/PrepareForSendUseCase.kt @@ -11,6 +11,7 @@ import com.tangem.domain.common.TapWorkarounds.isTangemTwins import com.tangem.domain.models.network.Network import com.tangem.domain.transaction.TransactionRepository import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet class PrepareForSendUseCase( private val transactionRepository: TransactionRepository, @@ -47,6 +48,7 @@ class PrepareForSendUseCase( } private fun createSigner(userWallet: UserWallet): TransactionSigner { + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] val card = userWallet.scanResponse.card val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SendTransactionUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SendTransactionUseCase.kt index b950197dc6..9b8a7e80c2 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SendTransactionUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SendTransactionUseCase.kt @@ -25,6 +25,7 @@ import com.tangem.domain.transaction.error.SendTransactionError import com.tangem.domain.transaction.error.parseWrappedError import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet class SendTransactionUseCase( private val demoConfig: DemoConfig, @@ -39,6 +40,8 @@ class SendTransactionUseCase( network: Network, sendMode: TransactionSender.MultipleTransactionSendMode, ): Either> { + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] + val card = userWallet.scanResponse.card val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SignUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SignUseCase.kt index b529e0b7b6..6dc5a843ad 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SignUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/SignUseCase.kt @@ -11,6 +11,7 @@ import com.tangem.domain.common.TapWorkarounds.isTangemTwins import com.tangem.domain.models.network.Network import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet class SignUseCase( private val cardSdkConfigRepository: CardSdkConfigRepository, @@ -21,6 +22,7 @@ class SignUseCase( userWallet: UserWallet, network: Network, ): Either { + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] val card = userWallet.scanResponse.card val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins diff --git a/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWallet.kt b/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWallet.kt index df15cfd819..459195dd77 100644 --- a/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWallet.kt +++ b/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWallet.kt @@ -1,45 +1,88 @@ package com.tangem.domain.wallets.models -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.wallets.models.UserWallet.Cold +import kotlinx.serialization.Serializable +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract /** * Represents user's wallet which stored in app persistence * * @property name User wallet name * @property walletId User wallet [UserWalletId] - * @property cardsInWallet List of cards IDs assigned with this user's wallet. The list will be empty if the wallet - * has been backed up on another device. - * @property isMultiCurrency Indicates whether this user wallet can work with more than one currency - * @property scanResponse [ScanResponse] of primary user's wallet card. */ -@JsonClass(generateAdapter = true) -data class UserWallet( - @Json(name = "name") - val name: String, - @Json(name = "walletId") - val walletId: UserWalletId, - @Json(name = "cardsInWallet") - val cardsInWallet: Set, - @Json(name = "isMultiCurrency") - val isMultiCurrency: Boolean, - @Json(name = "hasBackupError") - val hasBackupError: Boolean, - @Json(name = "scanResponse") - val scanResponse: ScanResponse, // TODO: Replace with [com.tangem.domain.models.scan.CardDTO] -) { +@Serializable +sealed interface UserWallet { - /** ID of user's wallet primary card */ - val cardId: String get() = scanResponse.card.cardId + val name: String + val walletId: UserWalletId - /** Indicates if the user's wallet primary card has access code */ - val hasAccessCode: Boolean get() = scanResponse.card.isAccessCodeSet + /** + * Represents user's wallet backed by tangem card. + * + * @property name User wallet name + * @property walletId User wallet [UserWalletId] + * @property cardsInWallet List of cards IDs assigned with this user's wallet. The list will be empty if the wallet + * has been backed up on another device. + * @property isMultiCurrency Indicates whether this user wallet can work with more than one currency + * @property scanResponse [ScanResponse] of primary user's wallet card. + */ + @Serializable + data class Cold( + override val name: String, + override val walletId: UserWalletId, + val cardsInWallet: Set, + val isMultiCurrency: Boolean, + val hasBackupError: Boolean, + val scanResponse: ScanResponse, // TODO: Replace with [com.tangem.domain.models.scan.CardDTO] + ) : UserWallet { - /** Indicates if this primary card has no currency wallets */ - val isLocked: Boolean get() = scanResponse.card.wallets.isEmpty() + /** ID of user's wallet primary card */ + val cardId: String get() = scanResponse.card.cardId - /** Indicated if this primary card is imported */ - val isImported: Boolean get() = scanResponse.card.wallets.any(CardDTO.Wallet::isImported) -} \ No newline at end of file + /** Indicates if the user's wallet primary card has access code */ + val hasAccessCode: Boolean get() = scanResponse.card.isAccessCodeSet + + /** Indicates if this primary card has no currency wallets */ + val isLocked: Boolean get() = scanResponse.card.wallets.isEmpty() + + /** Indicated if this primary card is imported */ + val isImported: Boolean get() = scanResponse.card.wallets.any(CardDTO.Wallet::isImported) + } + + @Serializable + data class Hot( + override val name: String, + override val walletId: UserWalletId, + val isLocked: Boolean, + ) : UserWallet +} + +@OptIn(ExperimentalContracts::class) +fun UserWallet.requireColdWallet(): Cold { + contract { + returns() implies (this@requireColdWallet is Cold) + } + + return this as? Cold + ?: error("This user wallet is not a cold wallet") +} + +fun UserWallet.copy(name: String = this.name, walletId: UserWalletId = this.walletId): UserWallet = when (this) { + is UserWallet.Cold -> this.copy(name = name, walletId = walletId) + is UserWallet.Hot -> this.copy(name = name, walletId = walletId) +} + +val UserWallet.isMultiCurrency + get() = when (this) { + is UserWallet.Cold -> isMultiCurrency + is UserWallet.Hot -> true + } + +val UserWallet.isLocked + get() = when (this) { + is UserWallet.Cold -> isLocked + is UserWallet.Hot -> isLocked + } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/UserWalletBuilder.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/ColdUserWalletBuilder.kt similarity index 91% rename from domain/wallets/src/main/java/com/tangem/domain/wallets/builder/UserWalletBuilder.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/builder/ColdUserWalletBuilder.kt index 7053d98d7d..7d94126619 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/UserWalletBuilder.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/ColdUserWalletBuilder.kt @@ -9,7 +9,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -class UserWalletBuilder @AssistedInject constructor( +class ColdUserWalletBuilder @AssistedInject constructor( @Assisted private val scanResponse: ScanResponse, private val generateWalletNameUseCase: GenerateWalletNameUseCase, ) { @@ -36,12 +36,12 @@ class UserWalletBuilder @AssistedInject constructor( this.hasBackupError = hasBackupError } - fun build(): UserWallet? { + fun build(): UserWallet.Cold? { return with(scanResponse) { UserWalletIdBuilder.scanResponse(scanResponse) .build() ?.let { - UserWallet( + UserWallet.Cold( walletId = it, name = generateWalletNameUseCase( productType = productType, @@ -60,6 +60,6 @@ class UserWalletBuilder @AssistedInject constructor( @AssistedFactory interface Factory { - fun create(scanResponse: ScanResponse): UserWalletBuilder + fun create(scanResponse: ScanResponse): ColdUserWalletBuilder } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt index 37ab17d016..77a7a1644e 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt @@ -9,6 +9,7 @@ import com.tangem.domain.wallets.models.UpdateWalletError import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.models.UserWalletRemoteInfo +import com.tangem.domain.wallets.models.copy import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt index e403101dd5..2842430ae8 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt @@ -2,6 +2,7 @@ package com.tangem.domain.wallets.usecase import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.wallets.legacy.UserWalletsListManager +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map @@ -20,7 +21,7 @@ class IsNeedToBackupUseCase(private val userWalletsListManager: UserWalletsListM if (wallet == null) { false } else { - wallet.scanResponse.card.backupStatus is CardDTO.BackupStatus.NoBackup + wallet is UserWallet.Cold && wallet.scanResponse.card.backupStatus is CardDTO.BackupStatus.NoBackup } } } diff --git a/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt b/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt index 505727f1f7..2d59a4b3c4 100644 --- a/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt +++ b/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt @@ -109,9 +109,11 @@ internal class AskBiometryModel @Inject constructor( walletsRepository.saveShouldSaveUserWallets(item = true) settingsRepository.setShouldSaveAccessCodes(value = true) - cardSdkConfigRepository.setAccessCodeRequestPolicy( - isBiometricsRequestPolicy = userWallet.hasAccessCode, - ) + if (userWallet is UserWallet.Cold) { + cardSdkConfigRepository.setAccessCodeRequestPolicy( + isBiometricsRequestPolicy = userWallet.hasAccessCode, + ) + } if (_uiState.value.bottomSheetVariant) { dismissBSFlow.emit(Unit) diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt index 10afab1fde..8c0878fae5 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt @@ -17,6 +17,8 @@ import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.redux.LegacyAction import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.walletconnect.CheckIsWalletConnectAvailableUseCase +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.details.component.DetailsComponent @@ -111,14 +113,17 @@ internal class DetailsModel @Inject constructor( modelScope.launch { val userWallets = getWalletsUseCase.invokeSync() - val scanResponse = getSelectedWalletSyncUseCase().getOrNull()?.scanResponse - ?: error("Selected wallet is null") + val scanResponse = + getSelectedWalletSyncUseCase().getOrNull()?.requireColdWallet()?.scanResponse // TODO [REDACTED_TASK_KEY] + ?: error("Selected wallet is null") val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch val feedbackType = when { - userWallets.all { it.scanResponse.card.isVisa } -> FeedbackEmailType.Visa.DirectUserRequest(cardInfo) - userWallets.all { it.scanResponse.card.isVisa.not() } -> FeedbackEmailType.DirectUserRequest(cardInfo) + userWallets.all { it is UserWallet.Cold && it.scanResponse.card.isVisa } -> + FeedbackEmailType.Visa.DirectUserRequest(cardInfo) + userWallets.all { it !is UserWallet.Cold || it.scanResponse.card.isVisa.not() } -> + FeedbackEmailType.DirectUserRequest(cardInfo) else -> { showFeedbackEmailTypeOptionBS(cardInfo) return@launch @@ -173,7 +178,9 @@ internal class DetailsModel @Inject constructor( FeedbackEmailType.DirectUserRequest(selectedCardInfo) } else { val scanResponse = getWalletsUseCase.invokeSync() - .firstOrNull { it.scanResponse.card.isVisa.not() }?.scanResponse ?: return@launch + .firstOrNull { it is UserWallet.Cold && it.scanResponse.card.isVisa.not() } + ?.requireColdWallet()?.scanResponse ?: return@launch + val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch FeedbackEmailType.DirectUserRequest(cardInfo) } @@ -183,7 +190,8 @@ internal class DetailsModel @Inject constructor( FeedbackEmailType.Visa.DirectUserRequest(selectedCardInfo) } else { val scanResponse = getWalletsUseCase.invokeSync() - .firstOrNull { it.scanResponse.card.isVisa }?.scanResponse ?: return@launch + .firstOrNull { it is UserWallet.Cold && it.scanResponse.card.isVisa } + ?.requireColdWallet()?.scanResponse ?: return@launch val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch FeedbackEmailType.Visa.DirectUserRequest(cardInfo) } diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt index 1c193139a2..a05d8557e1 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt @@ -20,7 +20,7 @@ import com.tangem.core.ui.message.SnackbarMessage import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.ReduxStateHolder -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.models.SaveWalletError import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.SaveWalletUseCase @@ -37,7 +37,7 @@ import kotlin.coroutines.resume internal class UserWalletSaver @Inject constructor( private val scanCardProcessor: ScanCardProcessor, private val saveWalletUseCase: SaveWalletUseCase, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val shouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase, private val reduxStateHolder: ReduxStateHolder, private val messageSender: UiMessageSender, @@ -112,7 +112,7 @@ internal class UserWalletSaver @Inject constructor( } private suspend fun Raise.createUserWallet(response: ScanResponse): UserWallet { - val userWallet = userWalletBuilderFactory.create(scanResponse = response).build() + val userWallet = coldUserWalletBuilderFactory.create(scanResponse = response).build() return ensureNotNull(userWallet) { Error.Unknown } } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt index aecd1f943e..acd79ae798 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt @@ -9,6 +9,7 @@ import com.tangem.domain.markets.TokenMarketInfo import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.features.markets.portfolio.impl.loader.PortfolioData import com.tangem.features.markets.portfolio.impl.ui.state.AddToPortfolioBSContentUM import com.tangem.features.markets.portfolio.impl.ui.state.WalletSelectorBSContentUM diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt index aa930886b0..13034c0d21 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt @@ -21,6 +21,7 @@ import com.tangem.domain.managetokens.model.CurrencyUnsupportedState import com.tangem.domain.markets.SaveMarketTokensUseCase import com.tangem.domain.markets.TokenMarketInfo import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase import com.tangem.features.markets.impl.R import com.tangem.features.markets.portfolio.api.MarketsPortfolioComponent diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMFactory.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMFactory.kt index 5729f632b6..51e961071a 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMFactory.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMFactory.kt @@ -4,6 +4,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.domain.markets.TokenMarketInfo import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.features.markets.portfolio.impl.loader.PortfolioData import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM.Tokens.AddButtonState diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt index acb35247e2..4454da2273 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt @@ -59,7 +59,8 @@ internal class TokenActionsHandler @AssistedInject constructor( cryptoCurrencyData = cryptoCurrencyData, ), ) - if (handleDemoMode(action, cryptoCurrencyData.userWallet)) return + val userWallet = cryptoCurrencyData.userWallet + if (userWallet is UserWallet.Cold && handleDemoMode(action, userWallet)) return when (action) { TokenActionsBSContentUM.Action.Buy -> onBuyClick(cryptoCurrencyData) @@ -72,7 +73,7 @@ internal class TokenActionsHandler @AssistedInject constructor( } } - private fun handleDemoMode(action: TokenActionsBSContentUM.Action, userWallet: UserWallet): Boolean { + private fun handleDemoMode(action: TokenActionsBSContentUM.Action, userWallet: UserWallet.Cold): Boolean { val demoCard = isDemoCardUseCase.invoke(userWallet.cardId) val needShowDemoWarning = demoCard && disabledActionsInDemoMode.contains(action) diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt index 2b9e393147..52a3c1f5a8 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt @@ -118,7 +118,7 @@ internal class OnboardingEntryModel @Inject constructor( } } - private fun onMultiWalletOnboardingDone(userWallet: UserWallet) { + private fun onMultiWalletOnboardingDone(userWallet: UserWallet.Cold) { when { params.mode == Mode.AddBackupWallet1 -> { stackNavigation.replaceAll( diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/routing/OnboardingRoute.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/routing/OnboardingRoute.kt index 4d0b03129a..687c15a8a2 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/routing/OnboardingRoute.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/routing/OnboardingRoute.kt @@ -24,7 +24,7 @@ sealed class OnboardingRoute : Route { val scanResponse: ScanResponse, val withSeedPhraseFlow: Boolean, val mode: OnboardingMultiWalletComponent.Mode, - val onDone: (UserWallet) -> Unit, + val onDone: (UserWallet.Cold) -> Unit, ) : OnboardingRoute() data class Visa( diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt index 76ceb4466e..1889ef1b56 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt @@ -14,7 +14,7 @@ interface OnboardingMultiWalletComponent : ComposableContentComponent, InnerNavi val scanResponse: ScanResponse, val withSeedPhraseFlow: Boolean, val mode: Mode, - val onDone: (UserWallet) -> Unit, + val onDone: (UserWallet.Cold) -> Unit, ) enum class Mode { diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt index c5cd73b286..ecfcf4cff9 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt @@ -8,7 +8,7 @@ import com.tangem.core.decompose.model.ParamsContainer import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.common.TapWorkarounds.canSkipBackup import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.SaveWalletUseCase import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent @@ -24,7 +24,7 @@ import javax.inject.Inject internal class Wallet1ChooseOptionModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, paramsContainer: ParamsContainer, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val cardRepository: CardRepository, private val saveWalletUseCase: SaveWalletUseCase, private val analyticsHandler: AnalyticsEventHandler, @@ -64,9 +64,9 @@ internal class Wallet1ChooseOptionModel @Inject constructor( } } - private suspend fun createUserWallet(scanResponse: ScanResponse): UserWallet { + private fun createUserWallet(scanResponse: ScanResponse): UserWallet.Cold { return requireNotNull( - value = userWalletBuilderFactory.create(scanResponse = scanResponse).build(), + value = coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build(), lazyMessage = { "User wallet not created" }, ) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt index 86226a42b6..de64378e47 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt @@ -13,7 +13,7 @@ import com.tangem.domain.feedback.GetCardInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.SaveWalletUseCase import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent @@ -42,7 +42,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor( private val getCardInfoUseCase: GetCardInfoUseCase, private val cardRepository: CardRepository, private val analyticsHandler: AnalyticsEventHandler, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val saveWalletUseCase: SaveWalletUseCase, ) : Model() { @@ -143,9 +143,9 @@ internal class MultiWalletCreateWalletModel @Inject constructor( } } - private suspend fun createUserWallet(scanResponse: ScanResponse): UserWallet { + private suspend fun createUserWallet(scanResponse: ScanResponse): UserWallet.Cold { return requireNotNull( - value = userWalletBuilderFactory.create(scanResponse = scanResponse).build(), + value = coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build(), lazyMessage = { "User wallet not created" }, ) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt index 4a4909fd27..8f2e4d12a3 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt @@ -16,9 +16,11 @@ import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.scan.isRing import com.tangem.domain.onboarding.repository.OnboardingRepository -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.copy +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.common.ui.CantLeaveBackupDialog import com.tangem.features.onboarding.v2.impl.R @@ -48,7 +50,7 @@ internal class MultiWalletFinalizeModel @Inject constructor( private val tangemSdkManager: TangemSdkManager, private val getCardInfoUseCase: GetCardInfoUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val userWalletsListManager: UserWalletsListManager, private val cardRepository: CardRepository, private val onboardingRepository: OnboardingRepository, @@ -240,13 +242,16 @@ internal class MultiWalletFinalizeModel @Inject constructor( } OnboardingMultiWalletComponent.Mode.AddBackup -> { val userWallet = userWalletsListManager.userWallets.first() - .firstOrNull { it.scanResponse.primaryCard?.cardId == scanResponse.primaryCard?.cardId } + .firstOrNull { + it is UserWallet.Cold && + it.scanResponse.primaryCard?.cardId == scanResponse.primaryCard?.cardId + } ?: userWalletCreated userWalletsListManager.update( userWalletId = userWallet.walletId, update = { wallet -> - wallet.copy( + wallet.requireColdWallet().copy( scanResponse = scanResponse.updateScanResponseAfterBackup(), ) }, @@ -254,7 +259,7 @@ internal class MultiWalletFinalizeModel @Inject constructor( userWallet } - } + }.requireColdWallet() if (hasRing) { walletsRepository.setHasWalletsWithRing(userWallet.walletId) @@ -279,9 +284,9 @@ internal class MultiWalletFinalizeModel @Inject constructor( } } - private suspend fun createUserWallet(scanResponse: ScanResponse): UserWallet { + private fun createUserWallet(scanResponse: ScanResponse): UserWallet.Cold { return requireNotNull( - value = userWalletBuilderFactory.create(scanResponse = scanResponse) + value = coldUserWalletBuilderFactory.create(scanResponse = scanResponse) .backupCardsIds(backupCardIds.toSet()) .hasBackupError(walletHasBackupError) .build(), diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt index 1347a7122b..9f1f17f18e 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt @@ -9,7 +9,7 @@ data class OnboardingMultiWalletState( val isThreeCards: Boolean, val currentScanResponse: ScanResponse, val startFromFinalize: FinalizeStage?, - val resultUserWallet: UserWallet?, + val resultUserWallet: UserWallet.Cold?, ) { enum class FinalizeStage { ScanPrimaryCard, ScanBackupFirstCard, ScanBackupSecondCard diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/create/model/OnboardingNoteCreateWalletModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/create/model/OnboardingNoteCreateWalletModel.kt index ce79faeb51..1fd13214ee 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/create/model/OnboardingNoteCreateWalletModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/create/model/OnboardingNoteCreateWalletModel.kt @@ -8,7 +8,7 @@ import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.ui.components.artwork.ArtworkUM import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.SaveWalletUseCase import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent @@ -28,7 +28,7 @@ internal class OnboardingNoteCreateWalletModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val tangemSdkManager: TangemSdkManager, private val cardRepository: CardRepository, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val saveWalletUseCase: SaveWalletUseCase, ) : Model() { @@ -87,7 +87,7 @@ internal class OnboardingNoteCreateWalletModel @Inject constructor( private suspend fun createUserWallet(scanResponse: ScanResponse): UserWallet { return requireNotNull( - value = userWalletBuilderFactory.create(scanResponse = scanResponse).build(), + value = coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build(), lazyMessage = { "User wallet not created" }, ) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt index 53e4fcc1c8..29d8601ba0 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt @@ -22,7 +22,7 @@ import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason import com.tangem.domain.tokens.model.analytics.TokenReceiveAnalyticsEvent -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.SaveWalletUseCase import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent @@ -41,7 +41,7 @@ internal class OnboardingNoteTopUpModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase, private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val getLegacyTopUpUrlUseCase: GetLegacyTopUpUrlUseCase, private val urlOpener: UrlOpener, private val clipboardManager: ClipboardManager, @@ -240,7 +240,7 @@ internal class OnboardingNoteTopUpModel @Inject constructor( private suspend fun createAndSaveUserWallet(scanResponse: ScanResponse): UserWallet { val wallet = requireNotNull( - value = userWalletBuilderFactory.create(scanResponse = scanResponse).build(), + value = coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build(), lazyMessage = { "User wallet not created" }, ) saveWalletUseCase(wallet, false) diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt index cd836cbb93..f4b803c505 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt @@ -38,7 +38,7 @@ import com.tangem.domain.tokens.FetchCurrencyStatusUseCase import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.analytics.TokenReceiveAnalyticsEvent -import com.tangem.domain.wallets.builder.UserWalletBuilder +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.models.UserWallet @@ -70,7 +70,7 @@ import javax.inject.Inject internal class OnboardingTwinModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, paramsContainer: ParamsContainer, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val userWalletsListManager: UserWalletsListManager, private val analyticsEventHandler: AnalyticsEventHandler, private val saveTwinsOnboardingShownUseCase: SaveTwinsOnboardingShownUseCase, @@ -319,7 +319,7 @@ internal class OnboardingTwinModel @Inject constructor( } private suspend fun setTopUpState(scanResponse: ScanResponse) = coroutineScope { - val userWallet = userWalletBuilderFactory.create(scanResponse).build() ?: run { + val userWallet = coldUserWalletBuilderFactory.create(scanResponse).build() ?: run { Timber.e("User wallet not created") setLoading(false) return@coroutineScope @@ -442,7 +442,7 @@ internal class OnboardingTwinModel @Inject constructor( setLoading(true) modelScope.launch { - val userWallet = userWalletBuilderFactory.create(params.scanResponse).build() ?: run { + val userWallet = coldUserWalletBuilderFactory.create(params.scanResponse).build() ?: run { Timber.e("User wallet not created") setLoading(false) return@launch diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt index 91b4061115..343731c83b 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt @@ -19,7 +19,7 @@ import com.tangem.domain.visa.model.VisaCardActivationStatus 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.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.UserWallet import com.tangem.features.onboarding.v2.visa.impl.child.inprogress.OnboardingVisaInProgressComponent.Config @@ -45,7 +45,7 @@ internal class OnboardingVisaInProgressModel @Inject constructor( private val visaAuthRepository: VisaAuthRepository, private val visaAuthTokenStorage: VisaAuthTokenStorage, private val otpStorage: VisaOTPStorage, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, private val userWalletsListManager: UserWalletsListManager, private val uiMessageSender: UiMessageSender, private val analyticsEventHandler: AnalyticsEventHandler, @@ -185,7 +185,7 @@ internal class OnboardingVisaInProgressModel @Inject constructor( val newActivationStatus = VisaCardActivationStatus.Activated(visaAuthTokens = authTokens) requireNotNull( - value = userWalletBuilderFactory.create( + value = coldUserWalletBuilderFactory.create( scanResponse = scanResponse.copy(visaCardActivationStatus = newActivationStatus), ).build(), lazyMessage = { "User wallet not created" }, diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/model/OnboardingVisaModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/model/OnboardingVisaModel.kt index 9961ec2459..884e1daf49 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/model/OnboardingVisaModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/model/OnboardingVisaModel.kt @@ -14,6 +14,8 @@ import com.tangem.domain.visa.model.VisaActivationRemoteState import com.tangem.domain.visa.model.VisaCardActivationStatus import com.tangem.domain.visa.model.VisaCardWalletDataToSignRequest import com.tangem.domain.visa.model.VisaCustomerWalletDataToSignRequest +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isLocked import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.onboarding.v2.visa.api.OnboardingVisaComponent import com.tangem.features.onboarding.v2.visa.impl.OnboardingVisaInnerNavigationState @@ -213,7 +215,7 @@ internal class OnboardingVisaModel @Inject constructor( private fun tryToFindExistingWalletCardId(targetAddress: String): String? { val wallets = getWalletsUseCase.invokeSync().filter { it.isLocked.not() } - return wallets.firstOrNull { wallet -> + return wallets.filterIsInstance().firstOrNull { wallet -> // TODO [REDACTED_TASK_KEY] wallet.scanResponse.card.wallets.any { val derivedKey = it.derivedKeys[VisaUtilities.visaDefaultDerivationPath] ?: return@any false diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/deeplink/DefaultBuyDeepLinkHandler.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/deeplink/DefaultBuyDeepLinkHandler.kt index 07c655873a..32029a1244 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/deeplink/DefaultBuyDeepLinkHandler.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/deeplink/DefaultBuyDeepLinkHandler.kt @@ -4,6 +4,7 @@ import arrow.core.getOrElse import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.domain.tokens.GetCryptoCurrencyUseCase import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.features.onramp.OnrampFeatureToggles import dagger.assisted.Assisted diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt index 8ff42661ed..8fc90cf011 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt @@ -23,6 +23,7 @@ import com.tangem.domain.onramp.model.error.OnrampError import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.onramp.main.OnrampMainComponent import com.tangem.features.onramp.main.entity.* @@ -233,7 +234,7 @@ internal class OnrampMainComponentModel @Inject constructor( } override fun onBuyClick(quote: OnrampProviderWithQuote.Data) { - if (isDemoCardUseCase.invoke(userWallet.cardId)) { + if (userWallet is UserWallet.Cold && isDemoCardUseCase.invoke(userWallet.cardId)) { showDemoWarning() } else { val currentContentState = state.value as? OnrampMainComponentUM.Content ?: return diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt index e2f4d63942..00ed212513 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt @@ -21,6 +21,7 @@ import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.tokens.legacy.TradeCryptoAction import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.onramp.OnrampFeatureToggles import com.tangem.features.onramp.impl.R @@ -55,7 +56,9 @@ internal class OnrampOperationModel @Inject constructor( private val _state = MutableStateFlow(value = getInitialState()) - private val selectedUserWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId } + private val selectedUserWallet = getWalletsUseCase.invokeSync() + .first { it.walletId == params.userWalletId } + .requireColdWallet() init { analyticsEventHandler.send( diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt index ee6457f6af..7086e3f10c 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt @@ -20,6 +20,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason import com.tangem.domain.tokens.model.TokenList import com.tangem.domain.tokens.model.TotalFiatBalance +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.onramp.impl.R import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent @@ -59,7 +60,8 @@ internal class OnrampTokenListModel @Inject constructor( private val params: OnrampTokenListComponent.Params = paramsContainer.require() private val scanResponse by lazy { - getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }.scanResponse + getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId } + .requireColdWallet().scanResponse // TODO [REDACTED_TASK_KEY] } init { diff --git a/features/referral/data/src/main/java/com/tangem/feature/referral/data/ReferralRepositoryImpl.kt b/features/referral/data/src/main/java/com/tangem/feature/referral/data/ReferralRepositoryImpl.kt index c1c05b9e40..8b079dc717 100644 --- a/features/referral/data/src/main/java/com/tangem/feature/referral/data/ReferralRepositoryImpl.kt +++ b/features/referral/data/src/main/java/com/tangem/feature/referral/data/ReferralRepositoryImpl.kt @@ -11,6 +11,7 @@ import com.tangem.datasource.api.tangemTech.models.StartReferralBody import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.referral.converters.ReferralConverter import com.tangem.feature.referral.domain.ReferralRepository import com.tangem.feature.referral.domain.models.ReferralData @@ -96,13 +97,13 @@ internal class ReferralRepositoryImpl @Inject constructor( sdkToken = sdkToken, blockchain = blockchain, extraDerivationPath = null, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) } else { cryptoCurrencyFactory.createCoin( blockchain = blockchain, extraDerivationPath = null, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] ) } } diff --git a/features/referral/impl/src/main/java/com/tangem/feature/referral/deeplink/DefaultReferralDeepLinkHandler.kt b/features/referral/impl/src/main/java/com/tangem/feature/referral/deeplink/DefaultReferralDeepLinkHandler.kt index a4f80621ef..e9cc05725b 100644 --- a/features/referral/impl/src/main/java/com/tangem/feature/referral/deeplink/DefaultReferralDeepLinkHandler.kt +++ b/features/referral/impl/src/main/java/com/tangem/feature/referral/deeplink/DefaultReferralDeepLinkHandler.kt @@ -3,6 +3,7 @@ package com.tangem.feature.referral.deeplink import com.tangem.common.routing.AppRoute import com.tangem.common.routing.AppRouter import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.feature.referral.api.deeplink.ReferralDeepLinkHandler import dagger.assisted.AssistedFactory @@ -21,7 +22,7 @@ internal class DefaultReferralDeepLinkHandler @AssistedInject constructor( Timber.e("Error on getting user wallet: $it") }, ifRight = { userWallet -> - if (userWallet.cardTypesResolver.isTangemWallet()) { + if (userWallet !is UserWallet.Cold || userWallet.cardTypesResolver.isTangemWallet()) { appRouter.push( AppRoute.ReferralProgram(userWalletId = userWallet.walletId), ) diff --git a/features/referral/impl/src/main/java/com/tangem/feature/referral/model/ReferralModel.kt b/features/referral/impl/src/main/java/com/tangem/feature/referral/model/ReferralModel.kt index 943c75b40d..e44c1ab3bd 100644 --- a/features/referral/impl/src/main/java/com/tangem/feature/referral/model/ReferralModel.kt +++ b/features/referral/impl/src/main/java/com/tangem/feature/referral/model/ReferralModel.kt @@ -12,6 +12,7 @@ import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.navigation.share.ShareManager import com.tangem.core.navigation.url.UrlOpener import com.tangem.domain.demo.IsDemoCardUseCase +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.referral.analytics.ReferralEvents import com.tangem.feature.referral.api.ReferralComponent @@ -84,7 +85,7 @@ internal class ReferralModel @Inject constructor( private fun participate() { val userWallet = getUserWalletUseCase(params.userWalletId).getOrNull() ?: error("User wallet not found") - if (isDemoCardUseCase(cardId = userWallet.cardId)) { + if (userWallet is UserWallet.Cold && isDemoCardUseCase(cardId = userWallet.cardId)) { showErrorSnackbar(DemoModeException()) } else { analyticsEventHandler.send(ReferralEvents.ClickParticipate) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt index 904dda59a5..d5dcfadac4 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt @@ -31,6 +31,7 @@ import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase import com.tangem.domain.transaction.usecase.SendTransactionUseCase import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.utils.convertToSdkAmount +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.features.send.v2.common.CommonSendRoute import com.tangem.features.send.v2.common.SendBalanceUpdater import com.tangem.features.send.v2.common.SendConfirmAlertFactory @@ -270,7 +271,8 @@ internal class SendConfirmModel @Inject constructor( ), ) - val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrNull() ?: return + val cardInfo = + getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY] modelScope.launch { sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo)) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt index edfc1b27ca..9e82a35a76 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt @@ -33,6 +33,8 @@ import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase import com.tangem.domain.transaction.usecase.GetFeeUseCase import com.tangem.domain.utils.convertToSdkAmount import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isMultiCurrency +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.features.send.v2.api.SendComponent import com.tangem.features.send.v2.common.CommonSendRoute @@ -217,7 +219,8 @@ internal class SendModel @Inject constructor( ifRight = { wallet -> userWallet = wallet - val isSingleWalletWithToken = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() + val isSingleWalletWithToken = wallet is UserWallet.Cold && + wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() val isMultiCurrency = wallet.isMultiCurrency getCurrenciesStatusUpdates( isSingleWalletWithToken = isSingleWalletWithToken, @@ -342,7 +345,8 @@ internal class SendModel @Inject constructor( ), ) - val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrNull() ?: return + val cardInfo = + getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY] modelScope.launch { sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo)) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt index 46744101eb..68dce3b0dc 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt @@ -24,6 +24,7 @@ import com.tangem.domain.settings.NeverShowTapHelpUseCase import com.tangem.domain.transaction.usecase.CreateNFTTransferTransactionUseCase import com.tangem.domain.transaction.usecase.SendTransactionUseCase import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.features.nft.entity.NFTSendSuccessTrigger import com.tangem.features.send.v2.common.CommonSendRoute import com.tangem.features.send.v2.common.SendBalanceUpdater @@ -212,7 +213,8 @@ internal class NFTSendConfirmModel @Inject constructor( ), ) - val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrNull() ?: return + val cardInfo = + getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY] modelScope.launch { sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo)) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt index 527f5f5fea..4bf63dbc36 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt @@ -27,6 +27,7 @@ import com.tangem.domain.transaction.error.GetFeeError import com.tangem.domain.transaction.usecase.CreateNFTTransferTransactionUseCase import com.tangem.domain.transaction.usecase.GetFeeUseCase import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.features.send.v2.api.NFTSendComponent import com.tangem.features.send.v2.common.CommonSendRoute @@ -151,7 +152,8 @@ internal class NFTSendModel @Inject constructor( ?: return@launch getCurrenciesStatusUpdates( - isSingleWalletWithToken = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), + isSingleWalletWithToken = wallet is UserWallet.Cold && + wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), ) }, ifLeft = { @@ -175,7 +177,8 @@ internal class NFTSendModel @Inject constructor( ), ) - val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrNull() ?: return + val cardInfo = + getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY] modelScope.launch { sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo)) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt index 9f86aa9c34..8ccf0bd907 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt @@ -20,6 +20,8 @@ import com.tangem.domain.transaction.usecase.ValidateWalletAddressUseCase import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase import com.tangem.domain.txhistory.usecase.GetFixedTxHistoryItemsUseCase import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isLocked +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.send.v2.common.PredefinedValues import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt index bee4fd13bd..29d669c62a 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt @@ -49,6 +49,9 @@ import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase import com.tangem.domain.utils.convertToSdkAmount import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isLocked +import com.tangem.domain.wallets.models.isMultiCurrency +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.send.api.SendComponent @@ -272,7 +275,8 @@ internal class SendModel @Inject constructor( checkIfSubtractAvailable() checkIfUtxoConsolidationAvailable() - val isSingleWalletWithToken = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() + val isSingleWalletWithToken = wallet is UserWallet.Cold && + wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() val isMultiCurrency = wallet.isMultiCurrency getCurrenciesStatusUpdates( isSingleWalletWithToken = isSingleWalletWithToken, @@ -612,6 +616,7 @@ internal class SendModel @Inject constructor( ), ) + val userWallet = userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrNull() ?: return modelScope.launch { diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt index 6c4ea5950f..7794e5ff8d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt @@ -46,6 +46,7 @@ import com.tangem.domain.transaction.usecase.GetAllowanceUseCase import com.tangem.domain.transaction.usecase.SendTransactionUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.features.staking.api.StakingComponent import com.tangem.features.staking.impl.analytics.StakingParamsInterceptor @@ -842,7 +843,9 @@ internal class StakingModel @Inject constructor( modelScope.launch { val network = cryptoCurrencyStatus.currency.network - val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrElse { error("CardInfo must be not null") } + val cardInfo = + getCardInfoUseCase(userWallet.requireColdWallet().scanResponse) + .getOrElse { error("CardInfo must be not null") } val amountState = uiState.value.amountState as? AmountState.Data val confirmationState = uiState.value.confirmationState as? StakingStates.ConfirmationState.Data val validatorState = uiState.value.validatorState as? StakingStates.ValidatorState.Data diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt index 98de62ae0e..28db912457 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt @@ -30,6 +30,7 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.swap.converters.* import com.tangem.feature.swap.domain.api.SwapRepository import com.tangem.feature.swap.domain.models.ExpressDataError @@ -406,6 +407,7 @@ internal class DefaultSwapRepository( scanResponse = requireNotNull( userWalletsListManager .selectedUserWalletSync + ?.requireColdWallet() // TODO [REDACTED_TASK_KEY] ?.scanResponse, ), ), diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt index 841111746a..09acf15c65 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt @@ -10,6 +10,7 @@ import com.tangem.datasource.local.preferences.utils.getObjectMapSync import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.swap.converters.SavedSwapTransactionListConverter import com.tangem.feature.swap.domain.SwapTransactionRepository import com.tangem.feature.swap.domain.models.domain.* @@ -102,7 +103,7 @@ internal class DefaultSwapTransactionRepository( currencyTxs?.mapNotNull { converter.convertBack( value = it, - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] txStatuses = txStatuses, ) } diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 30e26920fe..2ec3189410 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -505,8 +505,10 @@ internal class SwapInteractorImpl @AssistedInject constructor( """.trimIndent(), ) - val cardId = userWallet.scanResponse.card.cardId - if (isDemoCardUseCase(cardId)) return SwapTransactionState.DemoMode + val userWallet = userWallet + if (userWallet is UserWallet.Cold && isDemoCardUseCase(userWallet.scanResponse.card.cardId)) { + return SwapTransactionState.DemoMode + } return when (swapProvider.type) { ExchangeProviderType.CEX -> { @@ -691,9 +693,10 @@ internal class SwapInteractorImpl @AssistedInject constructor( val exchangeDataCex = exchangeData.transaction as? ExpressTransactionModel.CEX ?: return SwapTransactionState.Error.UnknownError - val cardId = userWallet.scanResponse.card.cardId - - if (isDemoCardUseCase(cardId)) return SwapTransactionState.Error.UnknownError + val userWallet = userWallet + if (userWallet is UserWallet.Cold && isDemoCardUseCase(userWallet.scanResponse.card.cardId)) { + return SwapTransactionState.Error.UnknownError + } val txData = createTransferTransactionUseCase( amount = amount.value.convertToSdkAmount(currencyToSend.currency), diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt index 3524961802..9c29b2fa46 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt @@ -44,6 +44,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.swap.analytics.StoriesEvents import com.tangem.feature.swap.analytics.SwapEvents @@ -1348,7 +1349,8 @@ internal class SwapModel @Inject constructor( val transaction = dataState.swapDataModel?.transaction val fromCurrencyStatus = dataState.fromCryptoCurrency ?: initialFromStatus val network = fromCurrencyStatus.currency.network - val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrElse { error("CardInfo must be not null") } + val cardInfo = getCardInfoUseCase(userWallet.requireColdWallet().scanResponse) // TODO [REDACTED_TASK_KEY] + .getOrElse { error("CardInfo must be not null") } saveBlockchainErrorUseCase( error = BlockchainErrorInfo( diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt index 256af80fdb..c80b1c3bd7 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt @@ -65,6 +65,7 @@ import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter @@ -288,7 +289,8 @@ internal class TokenDetailsModel @Inject constructor( userWalletId = userWalletId, currencyStatus = cryptoCurrencyStatus, derivationPath = cryptoCurrency.network.derivationPath, - isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), + isSingleWalletWithTokens = userWallet is UserWallet.Cold && + userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), ) .distinctUntilChanged() .onEach { @@ -306,7 +308,8 @@ internal class TokenDetailsModel @Inject constructor( getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet( userWalletId = userWalletId, currencyId = cryptoCurrency.id, - isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), + isSingleWalletWithTokens = userWallet is UserWallet.Cold && + userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), ) .distinctUntilChanged() .onEach { maybeCurrencyStatus -> @@ -440,7 +443,10 @@ internal class TokenDetailsModel @Inject constructor( private fun updateTopBarMenu() { modelScope.launch(dispatchers.main) { val hasDerivations = - networkHasDerivationUseCase(userWallet.scanResponse, cryptoCurrency.network).getOrElse { false } + networkHasDerivationUseCase( + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] + network = cryptoCurrency.network, + ).getOrElse { false } val isSupported = getExtendedPublicKeyForCurrencyUseCase.isSupported(userWalletId, cryptoCurrency.network) @@ -720,7 +726,7 @@ internal class TokenDetailsModel @Inject constructor( } private fun showErrorIfDemoModeOrElse(action: () -> Unit) { - if (isDemoCardUseCase(cardId = userWallet.cardId)) { + if (userWallet is UserWallet.Cold && isDemoCardUseCase(cardId = userWallet.cardId)) { internalUiState.value = stateFactory.getStateWithClosedBottomSheet() uiMessageSender.send( diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt index 4704c599b9..05bb854ee4 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt @@ -14,6 +14,7 @@ import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.staking.GetStakingIntegrationIdUseCase import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents import com.tangem.feature.tokendetails.presentation.tokendetails.state.* @@ -100,7 +101,7 @@ internal class TokenDetailsSkeletonStateConverter( val isBitcoin = isBitcoin(cryptoCurrency.network.rawId) val hasDerivations = networkHasDerivationUseCase( - scanResponse = userWallet.scanResponse, + scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY] network = cryptoCurrency.network, ).getOrElse { false } diff --git a/features/txhistory/impl/src/main/kotlin/com/tangem/features/txhistory/model/TxHistoryModel.kt b/features/txhistory/impl/src/main/kotlin/com/tangem/features/txhistory/model/TxHistoryModel.kt index c91a8c7bda..13b07b8fa2 100644 --- a/features/txhistory/impl/src/main/kotlin/com/tangem/features/txhistory/model/TxHistoryModel.kt +++ b/features/txhistory/impl/src/main/kotlin/com/tangem/features/txhistory/model/TxHistoryModel.kt @@ -190,7 +190,8 @@ internal class TxHistoryModel @Inject constructor( getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet( userWalletId = params.userWalletId, currencyId = params.currency.id, - isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), + isSingleWalletWithTokens = userWallet is UserWallet.Cold && + userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), ) .distinctUntilChanged() .onEach(::handlePendingTxsChanges) diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt index 7af69bbd73..b00f2acc62 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt @@ -25,6 +25,8 @@ import com.tangem.domain.nft.EnableWalletNFTUseCase import com.tangem.domain.nft.GetWalletNFTEnabledUseCase import com.tangem.domain.notifications.toggles.NotificationsFeatureToggles import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isMultiCurrency +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.* import com.tangem.feature.walletsettings.analytics.Settings import com.tangem.feature.walletsettings.component.WalletSettingsComponent @@ -114,8 +116,9 @@ internal class WalletSettingsModel @Inject constructor( ): PersistentList = itemsBuilder.buildItems( userWalletId = userWallet.walletId, userWalletName = userWallet.name, - isReferralAvailable = userWallet.cardTypesResolver.isTangemWallet(), - isLinkMoreCardsAvailable = userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup, + isReferralAvailable = userWallet !is UserWallet.Cold || userWallet.cardTypesResolver.isTangemWallet(), + isLinkMoreCardsAvailable = userWallet is UserWallet.Cold && + userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup, isManageTokensAvailable = userWallet.isMultiCurrency, isRenameWalletAvailable = isRenameWalletAvailable, renameWallet = { openRenameWalletDialog(userWallet, dialogNavigation) }, @@ -138,6 +141,7 @@ internal class WalletSettingsModel @Inject constructor( messageSender.send(message) }, onLinkMoreCardsClick = { + userWallet.requireColdWallet() onLinkMoreCardsClick(scanResponse = userWallet.scanResponse) }, onReferralClick = { onReferralClick(userWallet) }, @@ -251,7 +255,7 @@ internal class WalletSettingsModel @Inject constructor( } private fun onReferralClick(userWallet: UserWallet) { - if (isDemoCardUseCase(userWallet.cardId)) { + if (userWallet is UserWallet.Cold && isDemoCardUseCase(userWallet.cardId)) { messageSender.send( DialogMessage(message = resourceReference(R.string.alert_demo_feature_disabled)), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index d9546079df..fe3e58ff9e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -22,6 +22,7 @@ import com.tangem.domain.tokens.FetchCurrencyStatusUseCase import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents @@ -243,7 +244,7 @@ internal class WalletModel @Inject constructor( deepLinksRegistry.register( ReferralDeepLink( onReceive = { - if (userWallet.cardTypesResolver.isTangemWallet()) { + if (userWallet !is UserWallet.Cold || userWallet.cardTypesResolver.isTangemWallet()) { appRouter.push( AppRoute.ReferralProgram(userWalletId = userWallet.walletId), ) @@ -517,7 +518,7 @@ internal class WalletModel @Inject constructor( } private fun fetchIfSingleWallet(userWallet: UserWallet) { - if (userWallet.scanResponse.cardTypesResolver.isSingleWallet()) { + if (userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isSingleWallet()) { modelScope.launch { fetchCurrencyStatusUseCase(userWalletId = userWallet.walletId) .onLeft { Timber.e(it.toString()) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletsUpdateActionResolver.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletsUpdateActionResolver.kt index 35cf3a44cd..59d7e1baa2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletsUpdateActionResolver.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletsUpdateActionResolver.kt @@ -5,6 +5,7 @@ import com.tangem.core.decompose.di.ModelScoped import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isLocked import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.feature.wallet.presentation.wallet.state.model.NOT_INITIALIZED_WALLET_INDEX import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState @@ -175,6 +176,7 @@ internal class WalletsUpdateActionResolver @Inject constructor( } private fun isSelectedWalletCardsCountChanged(state: WalletScreenState, selectedWallet: UserWallet): Boolean { + if (selectedWallet !is UserWallet.Cold) return false val prevSelectedWallet = state.getPrevSelectedWallet() return prevSelectedWallet is WalletCardState.Content && prevSelectedWallet.cardCount != selectedWallet.getCardsCount() diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/VisaWalletIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/VisaWalletIntents.kt index 9aed66d0f3..3f270ccc99 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/VisaWalletIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/VisaWalletIntents.kt @@ -10,6 +10,7 @@ import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.visa.GetVisaCurrencyUseCase import com.tangem.domain.visa.GetVisaTxDetailsUseCase import com.tangem.domain.visa.model.VisaTxDetails +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.BalancesAndLimitsBottomSheetConverter @@ -100,7 +101,9 @@ internal class VisaWalletIntentsImplementor @Inject constructor( val userWalletId = stateController.getSelectedWalletId() val userWallet = getUserWalletsUseCase.invokeSync() .firstOrNull { it.walletId == userWalletId } ?: return@launch - val cardInfo = getCardInfoUseCase.invoke(userWallet.scanResponse).getOrNull() ?: return@launch + val cardInfo = getCardInfoUseCase.invoke( + userWallet.requireColdWallet().scanResponse, + ).getOrNull() ?: return@launch sendFeedbackEmailUseCase( FeedbackEmailType.Visa.Dispute( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt index fcabcee5ad..515197501f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt @@ -8,6 +8,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ModelScoped import com.tangem.domain.card.DeleteSavedAccessCodesUseCase import com.tangem.domain.redux.ReduxStateHolder +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.DeleteWalletUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase @@ -86,8 +87,10 @@ internal class WalletCardClickIntentsImplementor @Inject constructor( return@launch } - deleteSavedAccessCodesUseCase(cardId = walletToDelete.cardId).onLeft { - Timber.e("Unable to delete user wallet access code: $it") + if (walletToDelete is UserWallet.Cold) { + deleteSavedAccessCodesUseCase(cardId = walletToDelete.cardId).onLeft { + Timber.e("Unable to delete user wallet access code: $it") + } } if (hasUserWallets) { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt index 000fb49bf3..1537149e1a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt @@ -11,6 +11,7 @@ import com.tangem.domain.tokens.FetchCardTokenListUseCase import com.tangem.domain.tokens.FetchCurrencyStatusUseCase import com.tangem.domain.tokens.FetchTokenListUseCase import com.tangem.domain.tokens.FetchTokenListUseCase.RefreshMode +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.domain.wallets.usecase.SelectWalletUseCase import com.tangem.feature.wallet.presentation.router.InnerWalletRouter @@ -126,7 +127,10 @@ internal class WalletClickIntents @Inject constructor( ) modelScope.launch { - val maybeFetchResult = if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) { + val maybeFetchResult = if ( + userWallet is UserWallet.Cold && + userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() + ) { fetchCardTokenListUseCase(userWalletId = userWallet.walletId, refresh = true) } else { fetchTokenListUseCase(userWalletId = userWallet.walletId, mode = RefreshMode.FULL) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt index 4695f54f1a..93572eb403 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt @@ -14,6 +14,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.TokenActionsState import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isLocked import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.wallet.presentation.wallet.domain.OnrampStatusFactory import com.tangem.feature.wallet.presentation.wallet.domain.unwrap diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCurrencyActionsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCurrencyActionsClickIntents.kt index e7624f4dd7..966927724f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCurrencyActionsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCurrencyActionsClickIntents.kt @@ -48,6 +48,7 @@ import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent.Companion.AVAILABLE import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent.Companion.toReasonAnalyticsText import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase @@ -561,9 +562,9 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( } private fun showErrorIfDemoModeOrElse(action: () -> Unit) { - val cardId = getSelectedWalletSyncUseCase.unwrap()?.cardId ?: return + val selectedWallet = getSelectedWalletSyncUseCase.unwrap() ?: return - if (isDemoCardUseCase(cardId = cardId)) { + if (selectedWallet is UserWallet.Cold && isDemoCardUseCase(cardId = selectedWallet.cardId)) { stateHolder.update(CloseBottomSheetTransformer(userWalletId = stateHolder.getSelectedWalletId())) walletEventSender.send( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt index 4143d3d5e7..724ac04b1b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt @@ -24,6 +24,7 @@ import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.models.UnlockWalletsError import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.SeedPhraseNotificationUseCase import com.tangem.domain.wallets.usecase.UnlockWalletsUseCase @@ -113,7 +114,7 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( private fun prepareAndStartOnboardingProcess() { modelScope.launch(dispatchers.main) { - getSelectedUserWallet()?.let { + getSelectedUserWallet()?.requireColdWallet()?.let { router.openOnboardingScreen( scanResponse = it.scanResponse, continueBackup = true, @@ -126,7 +127,9 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( modelScope.launch(dispatchers.main) { val userWallet = getSelectedUserWallet() ?: return@launch - setCardWasScannedUseCase(cardId = userWallet.cardId) + if (userWallet is UserWallet.Cold) { + setCardWasScannedUseCase(cardId = userWallet.cardId) + } } } @@ -234,7 +237,8 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( modelScope.launch(dispatchers.main) { neverToSuggestRateAppUseCase() - val scanResponse = getSelectedUserWallet()?.scanResponse ?: return@launch + val scanResponse = + getSelectedUserWallet()?.requireColdWallet()?.scanResponse ?: return@launch // TODO [REDACTED_TASK_KEY] val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch sendFeedbackEmailUseCase(type = FeedbackEmailType.RateCanBeBetter(cardInfo = cardInfo)) @@ -275,7 +279,7 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( } override fun onSupportClick() { - val scanResponse = getSelectedUserWallet()?.scanResponse ?: return + val scanResponse = getSelectedUserWallet()?.requireColdWallet()?.scanResponse ?: return // TODO [REDACTED_TASK_KEY] val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return modelScope.launch { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt index 132d29572c..f95e4c5404 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt @@ -11,6 +11,7 @@ import com.tangem.domain.tokens.GetCryptoCurrencyUseCase import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.features.onramp.OnrampFeatureToggles import com.tangem.utils.coroutines.launchOnCancellation import kotlinx.coroutines.CoroutineScope diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/SelectedWalletAnalyticsSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/SelectedWalletAnalyticsSender.kt index ca5a6989b8..96ac45dfb7 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/SelectedWalletAnalyticsSender.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/SelectedWalletAnalyticsSender.kt @@ -3,6 +3,7 @@ package com.tangem.feature.wallet.presentation.wallet.analytics.utils import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isLocked import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent import javax.inject.Inject diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt index f6b3183538..4ea500469c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt @@ -17,6 +17,7 @@ import com.tangem.domain.tokens.model.TokenList import com.tangem.domain.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.Basic import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt index 2d582be20b..d8755f0f4a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt @@ -41,7 +41,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( @Suppress("MagicNumber", "MaximumLineLength") fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): Flow> { - val cardTypesResolver = userWallet.scanResponse.cardTypesResolver + val cardTypesResolver = (userWallet as? UserWallet.Cold)?.scanResponse?.cardTypesResolver return combine( flow = tokenListStore.getOrThrow(userWallet.walletId), @@ -94,6 +94,10 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( seedPhraseIssueStatus: SeedPhraseNotificationsStatus, clickIntents: WalletClickIntents, ) { + if (userWallet !is UserWallet.Cold) { + return + } + addSeedNotificationIfNeeded(userWallet, seedPhraseIssueStatus, clickIntents) val cardTypesResolver = userWallet.scanResponse.cardTypesResolver @@ -121,7 +125,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( } private fun MutableList.addSeedNotificationIfNeeded( - userWallet: UserWallet, + userWallet: UserWallet.Cold, seedPhraseIssueStatus: SeedPhraseNotificationsStatus, clickIntents: WalletClickIntents, ) { @@ -154,13 +158,13 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( } private fun MutableList.addInformationalNotifications( - cardTypesResolver: CardTypesResolver, + cardTypesResolver: CardTypesResolver?, maybeTokenList: Lce, clickIntents: WalletClickIntents, ) { addIf( element = WalletNotification.Informational.DemoCard, - condition = isDemoCardUseCase(cardId = cardTypesResolver.getCardId()), + condition = cardTypesResolver != null && isDemoCardUseCase(cardId = cardTypesResolver.getCardId()), ) addMissingAddressesNotification(maybeTokenList, clickIntents) @@ -194,7 +198,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( } private fun MutableList.addReferralPromoNotification( - cardTypesResolver: CardTypesResolver, + cardTypesResolver: CardTypesResolver?, clickIntents: WalletClickIntents, shouldShowPromo: Boolean, ) { @@ -203,12 +207,12 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.Referral) }, onClick = { clickIntents.onPromoClick(promoId = PromoId.Referral) }, ), - condition = shouldShowPromo && cardTypesResolver.isTangemWallet(), + condition = shouldShowPromo && (cardTypesResolver == null || cardTypesResolver.isTangemWallet()), ) } private fun MutableList.addWarningNotifications( - cardTypesResolver: CardTypesResolver, + cardTypesResolver: CardTypesResolver?, tokenList: Lce, isNeedToBackup: Boolean, clickIntents: WalletClickIntents, @@ -222,7 +226,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( addIf( element = WalletNotification.Warning.TestNetCard, - condition = cardTypesResolver.isTestCard(), + condition = cardTypesResolver?.isTestCard() == true, ) addIf( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt index e8b3b2aacb..89f0ecd47b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt @@ -33,6 +33,9 @@ internal class GetSingleWalletWarningsFactory @Inject constructor( private var readyForRateAppNotification = false fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): Flow> { + if (userWallet !is UserWallet.Cold) { + return flowOf(emptyList().toImmutableList()) + } val cardTypesResolver = userWallet.scanResponse.cardTypesResolver return combine( @@ -107,10 +110,11 @@ internal class GetSingleWalletWarningsFactory @Inject constructor( cardTypesResolver: CardTypesResolver, clickIntents: WalletClickIntents, ) { - val userHasWalletOrWallet2 = userWallets.any { + val userHasWalletOrWallet2 = userWallets.filterIsInstance().any { val typesResolver = it.scanResponse.cardTypesResolver typesResolver.isTangemWallet() || typesResolver.isWallet2() } + addIf( element = WalletNotification.NoteMigration( onClick = { clickIntents.onNoteMigrationButtonClick(NOTE_MIGRATION_URL) }, @@ -125,7 +129,7 @@ internal class GetSingleWalletWarningsFactory @Inject constructor( } private suspend fun MutableList.addWarningNotifications( - userWallet: UserWallet, + userWallet: UserWallet.Cold, cardTypesResolver: CardTypesResolver, maybePrimaryCurrencyStatus: Either, isNeedToBackup: Boolean, @@ -174,7 +178,7 @@ internal class GetSingleWalletWarningsFactory @Inject constructor( } private suspend fun hasSignedHashes( - selectedWallet: UserWallet, + selectedWallet: UserWallet.Cold, cryptoCurrencyStatus: CryptoCurrencyStatus?, ): Boolean { return cryptoCurrencyStatus?.currency?.network?.let { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/HasSingleWalletSignedHashesUseCase.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/HasSingleWalletSignedHashesUseCase.kt index 157cdc90c7..7c97b56240 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/HasSingleWalletSignedHashesUseCase.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/HasSingleWalletSignedHashesUseCase.kt @@ -17,7 +17,7 @@ class HasSingleWalletSignedHashesUseCase @Inject constructor( private val walletManagersFacade: WalletManagersFacade, ) { - operator fun invoke(userWallet: UserWallet, network: Network): Flow { + operator fun invoke(userWallet: UserWallet.Cold, network: Network): Flow { return cardRepository.wasCardScanned(cardId = userWallet.cardId) .map { wasCardScanned -> if (wasCardScanned || !userWallet.isCorrectCardType()) return@map false @@ -42,7 +42,7 @@ class HasSingleWalletSignedHashesUseCase @Inject constructor( } } - private fun UserWallet.isCorrectCardType(): Boolean { + private fun UserWallet.Cold.isCorrectCardType(): Boolean { return with(scanResponse.cardTypesResolver) { !DemoConfig().isDemoCardId(cardId) && isReleaseFirmwareType() && !isMultiwalletAllowed() && !isTangemTwins() } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt index 136f5c811d..2c8e82f09b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt @@ -7,7 +7,7 @@ import com.tangem.common.CompletionResult import com.tangem.common.core.TangemSdkError import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.domain.card.ScanCardProcessor -import com.tangem.domain.wallets.builder.UserWalletBuilder +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.SaveWalletUseCase import javax.inject.Inject @@ -15,7 +15,7 @@ import javax.inject.Inject internal class ScanCardToUnlockWalletClickHandler @Inject constructor( private val scanCardProcessor: ScanCardProcessor, private val saveWalletUseCase: SaveWalletUseCase, - private val userWalletBuilderFactory: UserWalletBuilder.Factory, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, ) { private var scanFailsCounter = 0 @@ -33,7 +33,7 @@ internal class ScanCardToUnlockWalletClickHandler @Inject constructor( scanFailsCounter = 0 // If card's public key is null then user wallet will be null - val scannedWallet = userWalletBuilderFactory.create(scanResponse = result.data).build() + val scannedWallet = coldUserWalletBuilderFactory.create(scanResponse = result.data).build() ensure(walletId == scannedWallet?.walletId) { ScanCardToUnlockWalletError.WrongCardIsScanned diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletAdditionalInfoFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletAdditionalInfoFactory.kt index f258bf29b6..789ebeb403 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletAdditionalInfoFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletAdditionalInfoFactory.kt @@ -9,6 +9,8 @@ import com.tangem.core.ui.format.bigdecimal.format import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isLocked +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo import java.math.BigDecimal @@ -29,14 +31,19 @@ internal object WalletAdditionalInfoFactory { * @param currencyAmount amount of currency */ fun resolve(wallet: UserWallet, currencyAmount: BigDecimal? = null): WalletAdditionalInfo { - return if (wallet.isMultiCurrency) { - wallet.resolveMultiCurrencyInfo() - } else { - wallet.resolveSingleCurrencyInfo(currencyAmount) + return when (wallet) { + is UserWallet.Cold -> { + if (wallet.isMultiCurrency) { + wallet.resolveMultiCurrencyInfo() + } else { + wallet.resolveSingleCurrencyInfo(currencyAmount) + } + } + is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]") } } - private fun UserWallet.resolveMultiCurrencyInfo(): WalletAdditionalInfo { + private fun UserWallet.Cold.resolveMultiCurrencyInfo(): WalletAdditionalInfo { return if (isLocked) { WalletAdditionalInfo( hideable = false, @@ -54,7 +61,7 @@ internal object WalletAdditionalInfoFactory { } } - private fun UserWallet.resolveWallet2Info(): WalletAdditionalInfo { + private fun UserWallet.Cold.resolveWallet2Info(): WalletAdditionalInfo { return if (isImported) { WalletAdditionalInfo( hideable = false, @@ -93,7 +100,7 @@ internal object WalletAdditionalInfoFactory { ) } - private fun UserWallet.resolveSingleCurrencyInfo(currencyAmount: BigDecimal?): WalletAdditionalInfo { + private fun UserWallet.Cold.resolveSingleCurrencyInfo(currencyAmount: BigDecimal?): WalletAdditionalInfo { return if (isLocked) { WalletAdditionalInfo(hideable = false, content = TextReference.Res(R.string.common_locked)) } else { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt index f83b3840fe..ed1f9e71a9 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt @@ -24,7 +24,7 @@ internal class WalletImageResolver @Inject constructor( /** Get a specified wallet [userWallet] image */ @Suppress("CyclomaticComplexMethod") @DrawableRes - fun resolve(userWallet: UserWallet): Int? { + fun resolve(userWallet: UserWallet.Cold): Int? { val cardTypesResolver = userWallet.scanResponse.cardTypesResolver val cobrandImage = Wallet2CobrandImage.entries.firstOrNull { @@ -52,30 +52,30 @@ internal class WalletImageResolver @Inject constructor( } } - private fun UserWallet.isRing(): Boolean { + private fun UserWallet.Cold.isRing(): Boolean { return scanResponse.cardTypesResolver.isRing() || runBlocking { walletsRepository.isWalletWithRing(userWalletId = this@isRing.walletId) } } - private fun UserWallet.resolveWalletWithRing(): Int? { + private fun UserWallet.Cold.resolveWalletWithRing(): Int? { return resolveWallet2( oneBackupResId = R.drawable.ill_card_with_ring_120_106, twoBackupResId = R.drawable.ill_card2_with_ring_120_106, ) } - private fun UserWallet.resolveWallet2Cobrand(image: Wallet2CobrandImage): Int? { + private fun UserWallet.Cold.resolveWallet2Cobrand(image: Wallet2CobrandImage): Int? { return resolveWallet2(oneBackupResId = image.cards2ResId, twoBackupResId = image.cards3ResId) } - private fun UserWallet.resolveShibaWallet(): Int? { + private fun UserWallet.Cold.resolveShibaWallet(): Int? { return resolveWallet2( oneBackupResId = R.drawable.ill_shiba_card2_120_106, twoBackupResId = R.drawable.ill_shiba_card3_120_106, ) } - private fun UserWallet.resolveWallet2( + private fun UserWallet.Cold.resolveWallet2( @DrawableRes oneBackupResId: Int = R.drawable.ill_wallet2_cards2_120_106, @DrawableRes twoBackupResId: Int = R.drawable.ill_wallet2_cards3_120_106, ): Int? { @@ -90,7 +90,7 @@ internal class WalletImageResolver @Inject constructor( } } - private fun UserWallet.resolveWallet1(): Int? { + private fun UserWallet.Cold.resolveWallet1(): Int? { return resolveWalletWithBackups { count -> when (count) { WALLET_WITHOUT_BACKUP_COUNT -> R.drawable.ill_wallet1_cards1_120_106 @@ -101,7 +101,7 @@ internal class WalletImageResolver @Inject constructor( } } - private fun UserWallet.resolveWalletWithBackups(resolve: (Int) -> Int?): Int? { + private fun UserWallet.Cold.resolveWalletWithBackups(resolve: (Int) -> Int?): Int? { val count = getCardsCount() return if (count != null) resolve(count) else null diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt index 99e60b3682..192864f851 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt @@ -1,6 +1,7 @@ package com.tangem.feature.wallet.presentation.wallet.domain import com.tangem.domain.wallets.legacy.UserWalletsListManager +import com.tangem.domain.wallets.models.copy import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository import timber.log.Timber diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletContentLoaderFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletContentLoaderFactory.kt index 95cb580695..31c9e2f4ac 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletContentLoaderFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletContentLoaderFactory.kt @@ -3,6 +3,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders import com.tangem.core.decompose.di.ModelScoped import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.loaders.implementors.* import javax.inject.Inject @@ -24,10 +25,10 @@ internal class WalletContentLoaderFactory @Inject constructor( userWallet.isMultiCurrency -> { multiWalletContentLoaderFactory.create(userWallet, clickIntents) } - userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() -> { + userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() -> { singleWalletWithTokenContentLoaderFactory.create(userWallet, clickIntents) } - userWallet.scanResponse.cardTypesResolver.isVisaWallet() -> { + userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isVisaWallet() -> { visaWalletContentLoaderFactory.create(userWallet, clickIntents, isRefresh) } !userWallet.isMultiCurrency -> { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletScreenContentLoader.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletScreenContentLoader.kt index 83675a0199..e0224a9858 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletScreenContentLoader.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/WalletScreenContentLoader.kt @@ -3,6 +3,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders import com.tangem.core.decompose.di.ModelScoped import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.isLocked import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.CoroutineScope diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt index ee9f47ff70..1fe2ece7a1 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt @@ -2,6 +2,8 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.isLocked +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver import com.tangem.feature.wallet.presentation.wallet.state.model.* @@ -53,6 +55,8 @@ internal class InitializeWalletsTransformer( } private fun createLockedState(userWallet: UserWallet): WalletState { + userWallet.requireColdWallet() + return userWallet.createStateByWalletType( multiCurrencyCreator = { WalletState.MultiCurrency.Locked( @@ -83,7 +87,7 @@ internal class InitializeWalletsTransformer( ) } - private fun UserWallet.toLockedWalletCardState(): WalletCardState { + private fun UserWallet.Cold.toLockedWalletCardState(): WalletCardState { return WalletCardState.LockedContent( id = walletId, title = name, @@ -94,7 +98,8 @@ internal class InitializeWalletsTransformer( } private fun createMultiWalletEnabledButtons(userWallet: UserWallet): PersistentList { - val isSingleWalletWithToken = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() + val isSingleWalletWithToken = userWallet is UserWallet.Cold && + userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() if (isSingleWalletWithToken) return persistentListOf() return persistentListOf( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetCryptoCurrencyActionsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetCryptoCurrencyActionsTransformer.kt index 0853da92e3..61a84bb6d6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetCryptoCurrencyActionsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetCryptoCurrencyActionsTransformer.kt @@ -99,7 +99,7 @@ internal class SetCryptoCurrencyActionsTransformer( } private fun List.filterIfS2C(): List { - return if (userWallet.scanResponse.cardTypesResolver.isStart2Coin()) { + return if (userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isStart2Coin()) { filterNot { it is TokenActionsState.ActionState.Buy || it is TokenActionsState.ActionState.Sell } } else { this diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt index 009caf2327..bbb5f0894b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt @@ -6,6 +6,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState @@ -56,6 +57,8 @@ internal class SetTokenListErrorTransformer( } private fun WalletCardState.toLoadedState(): WalletCardState { + selectedWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] + return WalletCardState.Content( id = id, title = title, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTxHistoryCountErrorTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTxHistoryCountErrorTransformer.kt index beb301abac..437673da58 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTxHistoryCountErrorTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTxHistoryCountErrorTransformer.kt @@ -1,5 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers +import com.tangem.blockchain.common.Blockchain import com.tangem.core.ui.components.transactions.state.TxHistoryState import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.models.network.TxInfo @@ -19,7 +20,11 @@ internal class SetTxHistoryCountErrorTransformer( ) : WalletStateTransformer(userWallet.walletId) { private val txHistoryItemConverter by lazy { - val blockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain() + val blockchain = when (userWallet) { + is UserWallet.Cold -> userWallet.scanResponse.cardTypesResolver.getBlockchain() + is UserWallet.Hot -> Blockchain.Unknown + } + TxHistoryItemStateConverter( symbol = blockchain.currency, decimals = blockchain.decimals(), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetVisaInfoTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetVisaInfoTransformer.kt index 1dc3f95565..afa9bd0b99 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetVisaInfoTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetVisaInfoTransformer.kt @@ -13,6 +13,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.visa.exception.RefreshTokenExpiredException import com.tangem.domain.visa.model.VisaCurrency import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.presentation.wallet.state.model.BalancesAndLimitsBlockState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState @@ -75,6 +76,8 @@ internal class SetVisaInfoTransformer( } private fun getContentWalletCardState(prevState: WalletCardState, visaCurrency: VisaCurrency): WalletCardState { + userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] + return with(prevState) { WalletCardState.Content( id = id, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateWalletCardsCountTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateWalletCardsCountTransformer.kt index 55634425fa..550a2135aa 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateWalletCardsCountTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateWalletCardsCountTransformer.kt @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState @@ -39,8 +40,8 @@ internal class UpdateWalletCardsCountTransformer( return when (this) { is WalletCardState.Content -> copy( additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet), - imageResId = walletImageResolver.resolve(userWallet = userWallet), - cardCount = userWallet.getCardsCount(), + imageResId = walletImageResolver.resolve(userWallet = userWallet.requireColdWallet()), // TODO [REDACTED_TASK_KEY] + cardCount = userWallet.requireColdWallet().getCardsCount(), // TODO [REDACTED_TASK_KEY] ) else -> this } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt index 252f77384f..4cca1c04bb 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt @@ -7,6 +7,7 @@ import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.models.StatusSource import com.tangem.domain.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.utils.converter.Converter @@ -47,6 +48,8 @@ internal class MultiWalletCardStateConverter( } private fun WalletCardState.toWalletCardState(fiatBalance: TotalFiatBalance.Loaded): WalletCardState { + selectedWallet.requireColdWallet() + return WalletCardState.Content( id = id, title = title, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt index d00bb304d0..9efa0dcf02 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt @@ -30,7 +30,9 @@ internal class MultiWalletCurrencyActionsConverter( } private fun List.filterIfSingleWithToken(): List { - return if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) { + return if (userWallet is UserWallet.Cold && + userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() + ) { filter { it !is TokenActionsState.ActionState.HideToken } } else { this diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt index c23ed71b36..809632aca9 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt @@ -7,6 +7,7 @@ import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.models.StatusSource import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.utils.StringsSigns.DASH_SIGN @@ -63,7 +64,7 @@ internal class SingleWalletCardStateConverter( imageResId = imageResId, dropDownItems = dropDownItems, balance = formatFiatAmount(status = status, appCurrency = appCurrency), - cardCount = selectedWallet.getCardsCount(), + cardCount = selectedWallet.requireColdWallet().getCardsCount(), // TODO [REDACTED_TASK_KEY] isZeroBalance = status.fiatAmount?.isZero(), isBalanceFlickering = (status as? CryptoCurrencyStatus.Loaded)?.sources?.total == StatusSource.CACHE, ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt index ac8b4feb69..b2ac85ccca 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt @@ -95,6 +95,7 @@ internal class TokenListStateConverter( } private fun isSingleCurrencyWalletWithToken(): Boolean { - return selectedWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() + return selectedWallet is UserWallet.Cold && + selectedWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/UserWalletConverterExt.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/UserWalletConverterExt.kt index c7a8830b71..a99ddbd3a5 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/UserWalletConverterExt.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/UserWalletConverterExt.kt @@ -4,7 +4,7 @@ import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState -internal inline fun UserWallet.createStateByWalletType( +internal inline fun UserWallet.Cold.createStateByWalletType( multiCurrencyCreator: () -> WalletState.MultiCurrency, singleCurrencyCreator: () -> WalletState.SingleCurrency, visaWalletCreator: () -> WalletState.Visa, @@ -14,10 +14,10 @@ internal inline fun UserWallet.createStateByWalletType( else -> singleCurrencyCreator() } -private fun UserWallet.isWalletWithTokens(): Boolean { +private fun UserWallet.Cold.isWalletWithTokens(): Boolean { return isMultiCurrency || scanResponse.cardTypesResolver.isSingleWalletWithToken() } -private fun UserWallet.isVisaWallet(): Boolean { +private fun UserWallet.Cold.isVisaWallet(): Boolean { return scanResponse.cardTypesResolver.isVisaWallet() } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt index 4cb5daf3c1..5efd04f762 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt @@ -6,6 +6,7 @@ import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.transactions.state.TxHistoryState import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver @@ -25,6 +26,8 @@ internal class WalletLoadingStateFactory( ) { fun create(userWallet: UserWallet): WalletState { + userWallet.requireColdWallet() + return userWallet.createStateByWalletType( multiCurrencyCreator = { createLoadingMultiCurrencyContent(userWallet) }, singleCurrencyCreator = { createLoadingSingleCurrencyContent(userWallet) }, @@ -32,7 +35,7 @@ internal class WalletLoadingStateFactory( ) } - private fun createLoadingMultiCurrencyContent(userWallet: UserWallet): WalletState.MultiCurrency.Content { + private fun createLoadingMultiCurrencyContent(userWallet: UserWallet.Cold): WalletState.MultiCurrency.Content { return WalletState.MultiCurrency.Content( pullToRefreshConfig = createPullToRefreshConfig(), walletCardState = userWallet.toLoadingWalletCardState(), @@ -44,7 +47,7 @@ internal class WalletLoadingStateFactory( ) } - private fun createLoadingSingleCurrencyContent(userWallet: UserWallet): WalletState.SingleCurrency.Content { + private fun createLoadingSingleCurrencyContent(userWallet: UserWallet.Cold): WalletState.SingleCurrency.Content { val currencySymbol = userWallet.scanResponse.cardTypesResolver.getBlockchain().currency return WalletState.SingleCurrency.Content( pullToRefreshConfig = createPullToRefreshConfig(), @@ -63,7 +66,7 @@ internal class WalletLoadingStateFactory( ) } - private fun createLoadingVisaWalletContent(userWallet: UserWallet): WalletState.Visa.Content { + private fun createLoadingVisaWalletContent(userWallet: UserWallet.Cold): WalletState.Visa.Content { return WalletState.Visa.Content( pullToRefreshConfig = createPullToRefreshConfig(), walletCardState = userWallet.toLoadingWalletCardState(), @@ -86,7 +89,7 @@ internal class WalletLoadingStateFactory( ) } - private fun UserWallet.toLoadingWalletCardState(): WalletCardState { + private fun UserWallet.Cold.toLoadingWalletCardState(): WalletCardState { return WalletCardState.Loading( id = walletId, title = name, @@ -96,7 +99,7 @@ internal class WalletLoadingStateFactory( ) } - private fun createMultiWalletActions(userWallet: UserWallet): PersistentList { + private fun createMultiWalletActions(userWallet: UserWallet.Cold): PersistentList { val isSingleWalletWithToken = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() if (isSingleWalletWithToken) return persistentListOf() diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TxHistorySubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TxHistorySubscriber.kt index b2dcb6e7eb..efb3aae1cd 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TxHistorySubscriber.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TxHistorySubscriber.kt @@ -13,6 +13,7 @@ import com.tangem.domain.txhistory.models.TxHistoryStateError import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.domain.collectLatest import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController @@ -96,7 +97,7 @@ internal class TxHistorySubscriber( ) }, ifRight = { itemsFlow -> - val blockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain() + val blockchain = userWallet.requireColdWallet().scanResponse.cardTypesResolver.getBlockchain() val itemConverter = TxHistoryItemStateConverter( symbol = blockchain.currency, decimals = blockchain.decimals(), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/utils/DefaultUserWalletsFetcher.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/utils/DefaultUserWalletsFetcher.kt index 09cfabc38b..f0b457cbca 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/utils/DefaultUserWalletsFetcher.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/utils/DefaultUserWalletsFetcher.kt @@ -22,6 +22,7 @@ import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetCardImageUseCase import com.tangem.domain.wallets.usecase.GetWalletsUseCase import com.tangem.features.wallet.utils.UserWalletsFetcher @@ -84,6 +85,7 @@ internal class DefaultUserWalletsFetcher @AssistedInject constructor( return flow { emit(hashMapOf()) // emits right away so the transform doesn't wait for the images' loading to finish wallets.forEach { wallet -> + wallet.requireColdWallet() val artwork = getCardImageUseCase( cardId = wallet.cardId, manufacturerName = wallet.scanResponse.card.manufacturer.name,