Updated on 2026-08-14
This commit is contained in:
parent
e33bd4d849
commit
b98b0f659c
138 changed files with 686 additions and 346 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit d6e348cf2f9a1f5a4e96fbf627fec71c2d17c9c1
|
||||
Subproject commit 4ec5de66321afa82c04104746015ea9e6bc9fe64
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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<Unit> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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<UserWalletPublicInformation>.toUserWallets(): List<UserWallet>
|
|||
}
|
||||
|
||||
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<UserWallet>.updateWith(
|
||||
|
|
@ -68,11 +79,16 @@ internal fun List<UserWallet>.updateWith(
|
|||
|
||||
internal fun List<UserWallet>.lockAll(): List<UserWallet> = map(UserWallet::lock)
|
||||
|
||||
internal fun UserWallet.lock(): UserWallet = copy(
|
||||
scanResponse = scanResponse.copy(
|
||||
card = scanResponse.card.copy(
|
||||
wallets = emptyList(),
|
||||
),
|
||||
visaCardActivationStatus = null,
|
||||
),
|
||||
)
|
||||
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]")
|
||||
}
|
||||
|
|
@ -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? {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String, String> {
|
||||
return userWalletsListManager.userWalletsSync.associate {
|
||||
return userWalletsListManager.userWalletsSync.filterIsInstance<UserWallet.Cold>().associate {
|
||||
it.scanResponse.card.cardId to it.scanResponse.card.cardPublicKey.toHexString()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
|||
)
|
||||
}
|
||||
|
||||
data class CreateDefaultForMultiWalletModel(val multiWallet: UserWallet, val expected: List<CryptoCurrency>)
|
||||
data class CreateDefaultForMultiWalletModel(val multiWallet: UserWallet.Cold, val expected: List<CryptoCurrency>)
|
||||
|
||||
@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<CryptoCurrency>,
|
||||
)
|
||||
|
||||
|
|
@ -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<List<CryptoCurrency>>,
|
||||
)
|
||||
|
||||
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(),
|
||||
|
|
|
|||
|
|
@ -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 ->
|
||||
|
|
|
|||
|
|
@ -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<Blockchain> {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<CryptoCurrency> {
|
||||
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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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<Address> {
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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<UserWallet>) =
|
||||
withContext(dispatchers.io) {
|
||||
val publicKeys = authProvider.getCardsPublicKeys()
|
||||
val walletsBody = wallets.map { userWallet ->
|
||||
val walletsBody = wallets.filterIsInstance<UserWallet.Cold>().map { userWallet ->
|
||||
WalletIdBodyConverter.convert(
|
||||
userWallet = userWallet,
|
||||
publicKeys = publicKeys.filterKeys { userWallet.cardsInWallet.contains(it) },
|
||||
|
|
|
|||
|
|
@ -176,12 +176,12 @@ class DefaultWalletsRepositoryTest {
|
|||
val card2PublicKey = "card2_public_key"
|
||||
|
||||
val userWallets = listOf(
|
||||
mockk<UserWallet> {
|
||||
mockk<UserWallet.Cold> {
|
||||
every { cardsInWallet } returns setOf(card1PublicKey)
|
||||
every { walletId } returns UserWalletId(wallet1Id)
|
||||
every { name } returns "Wallet 1"
|
||||
},
|
||||
mockk<UserWallet> {
|
||||
mockk<UserWallet.Cold> {
|
||||
every { cardsInWallet } returns setOf(card2PublicKey)
|
||||
every { walletId } returns UserWalletId(wallet2Id)
|
||||
every { name } returns "Wallet 2"
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
fun UserWallet.Cold.getBackupCardsCount(): Int? = scanResponse.getBackupCardsCount()
|
||||
|
|
@ -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<CryptoCurrency.Token>,
|
||||
): 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,
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TokenActionsState> {
|
||||
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<TokenActionsState> {
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ class EstimateFeeUseCase(
|
|||
cryptoCurrency: CryptoCurrency,
|
||||
): Either<GetFeeError, TransactionFee> {
|
||||
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 = "",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<SendTransactionError?, List<String>> {
|
||||
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
||||
|
||||
val card = userWallet.scanResponse.card
|
||||
val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins
|
||||
|
||||
|
|
|
|||
|
|
@ -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<TangemError, ByteArray> {
|
||||
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
||||
val card = userWallet.scanResponse.card
|
||||
val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String>,
|
||||
@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<String>,
|
||||
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)
|
||||
}
|
||||
/** 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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Error>.createUserWallet(response: ScanResponse): UserWallet {
|
||||
val userWallet = userWalletBuilderFactory.create(scanResponse = response).build()
|
||||
val userWallet = coldUserWalletBuilderFactory.create(scanResponse = response).build()
|
||||
|
||||
return ensureNotNull(userWallet) { Error.Unknown }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
|
|
|
|||
|
|
@ -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<UserWallet.Cold>().firstOrNull { wallet -> // TODO [REDACTED_TASK_KEY]
|
||||
wallet.scanResponse.card.wallets.any {
|
||||
val derivedKey = it.derivedKeys[VisaUtilities.visaDefaultDerivationPath] ?: return@any false
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue