Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-04 12:52:08 +03:00
parent d664e6ecbb
commit 14df650f1a
34 changed files with 161 additions and 105 deletions

View file

@ -24,7 +24,7 @@ fun Analytics.setContext(scanResponse: ScanResponse) {
fun Analytics.setContext(userWallet: UserWallet) {
setUserId(userWallet.walletId.stringValue)
// TODO add product type for hot ([REDACTED_TASK_KEY])
// TODO add product type for hot ([REDACTED_TASK_KEY] [Hot Wallet] Analytics)
if (userWallet is UserWallet.Cold) {
addParamsInterceptor(LinkedCardContextInterceptor(userWallet.scanResponse))

View file

@ -180,8 +180,13 @@ internal object TransactionDomainModule {
fun providePrepareForSendUseCase(
transactionRepository: TransactionRepository,
cardSdkConfigRepository: CardSdkConfigRepository,
tangemHotWalletSignerFactory: TangemHotWalletSigner.Factory,
): PrepareForSendUseCase {
return PrepareForSendUseCase(transactionRepository, cardSdkConfigRepository)
return PrepareForSendUseCase(
transactionRepository = transactionRepository,
cardSdkConfigRepository = cardSdkConfigRepository,
getHotTransactionSigner = { tangemHotWalletSignerFactory.create(it) },
)
}
@Provides
@ -189,8 +194,13 @@ internal object TransactionDomainModule {
fun provideSignUseCase(
walletManagersFacade: WalletManagersFacade,
cardSdkConfigRepository: CardSdkConfigRepository,
tangemHotWalletSignerFactory: TangemHotWalletSigner.Factory,
): SignUseCase {
return SignUseCase(cardSdkConfigRepository, walletManagersFacade)
return SignUseCase(
cardSdkConfigRepository = cardSdkConfigRepository,
walletManagersFacade = walletManagersFacade,
getHotTransactionSigner = { tangemHotWalletSignerFactory.create(it) },
)
}
@Provides

View file

@ -87,9 +87,10 @@ internal class CardSettingsModel @Inject constructor(
val userWallet = getUserWalletUseCase(userWalletId)
.getOrElse { error("User wallet $userWalletId not found") }
.requireColdWallet()
cardSdkConfigRepository.isBiometricsRequestPolicy =
userWallet.requireColdWallet().scanResponse.card.isAccessCodeSet && // TODO [REDACTED_TASK_KEY]
userWallet.scanResponse.card.isAccessCodeSet &&
settingsRepository.shouldSaveAccessCodes()
}
}

View file

@ -24,8 +24,6 @@ import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase
import com.tangem.domain.common.LogConfig
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.notifications.GetApplicationIdUseCase
import com.tangem.domain.notifications.SendPushTokenUseCase
import com.tangem.domain.notifications.models.ApplicationId
@ -212,15 +210,11 @@ internal class MainViewModel @Inject constructor(
}
private fun makeSellExchangeService(environmentConfig: EnvironmentConfig): ExchangeService {
val cardProvider: () -> ScanResponse? = {
userWalletsListManager.selectedUserWalletSync?.requireColdWallet()?.scanResponse // TODO [REDACTED_TASK_KEY]
}
return MoonPayService(
apiKey = environmentConfig.moonPayApiKey,
secretKey = environmentConfig.moonPayApiSecretKey,
logEnabled = LogConfig.network.moonPayService,
cardProvider = { cardProvider.invoke()?.card },
userWalletProvider = { userWalletsListManager.selectedUserWalletSync },
)
}

View file

@ -134,7 +134,7 @@ internal class WelcomeMiddleware {
}
private fun sendSignedInAnalyticsEvent(userWallet: UserWallet, signInType: Basic.SignedIn.SignInType) {
// TODO [REDACTED_TASK_KEY]
// TODO [REDACTED_TASK_KEY] [Hot Wallet] Analytics
if (userWallet !is UserWallet.Cold) {
return

View file

@ -12,7 +12,7 @@ import com.tangem.domain.core.utils.lceContent
import com.tangem.domain.core.utils.lceError
import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.tap.domain.model.Currency
import com.tangem.tap.network.exchangeServices.ExchangeService
import com.tangem.tap.network.exchangeServices.ExchangeServiceInitializationStatus
@ -27,7 +27,7 @@ class MoonPayService(
private val apiKey: String,
private val secretKey: String,
private val logEnabled: Boolean,
private val cardProvider: () -> CardDTO?,
private val userWalletProvider: () -> UserWallet?,
) : ExchangeService {
override val initializationStatus: StateFlow<ExchangeServiceInitializationStatus>
@ -103,8 +103,8 @@ class MoonPayService(
}
override fun availableForSell(currency: Currency): Boolean {
val card = cardProvider() ?: return false
val checkCardExchange = !card.isStart2Coin
val userWallet = userWalletProvider() ?: return false
val checkCardExchange = userWallet !is UserWallet.Cold || !userWallet.scanResponse.card.isStart2Coin
if (!checkCardExchange) return false

View file

@ -197,11 +197,10 @@ internal class DefaultManageTokensRepository(
)
private fun getSupportedBlockchains(userWallet: UserWallet?): List<Blockchain> {
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
}
return userWallet?.supportedBlockchains(excludedBlockchains)
?: Blockchain.entries.filter {
!it.isTestnet() && it !in excludedBlockchains
}
}
// endregion

View file

@ -17,12 +17,10 @@ import com.tangem.datasource.local.nft.converter.NFTSdkCollectionConverter
import com.tangem.datasource.local.nft.converter.NFTSdkCollectionIdentifierConverter
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.card.common.extensions.canHandleToken
import com.tangem.domain.card.common.util.cardTypesResolver
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.nft.models.NFTAsset
import com.tangem.domain.nft.models.NFTCollection
import com.tangem.domain.nft.models.NFTCollections
@ -542,11 +540,10 @@ internal class DefaultNFTRepository @Inject constructor(
}
private fun Network.canHandleNFTs(userWalletId: UserWalletId): Boolean {
// TODO [REDACTED_TASK_KEY]
val scanResponse = userWalletsStore.getSyncStrict(userWalletId).requireColdWallet().scanResponse
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
val blockchain = Blockchain.fromNetworkId(backendId) ?: return false
return blockchain.canHandleNFTs() &&
scanResponse.card.canHandleToken(blockchain, scanResponse.cardTypesResolver, excludedBlockchains)
userWallet.canHandleToken(blockchain, excludedBlockchains)
}
}

View file

@ -22,7 +22,6 @@ import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.card.common.extensions.canHandleBlockchain
import com.tangem.domain.card.common.extensions.canHandleToken
import com.tangem.domain.card.common.util.cardTypesResolver
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.onramp.model.HotCryptoCurrency
@ -170,23 +169,17 @@ 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
return if (isToken) {
scanResponse.card.canHandleToken(
canHandleToken(
blockchain = blockchain,
cardTypesResolver = cardTypesResolver,
excludedBlockchains = excludedBlockchains,
)
} else {
scanResponse.card.canHandleBlockchain(
canHandleBlockchain(
blockchain = blockchain,
cardTypesResolver = cardTypesResolver,
excludedBlockchains = excludedBlockchains,
)
}

View file

@ -18,7 +18,6 @@ import com.tangem.domain.core.utils.catchOn
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher.Params
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -68,7 +67,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcher(
}
},
onError = {
handleFetchTokensError(error = it, userWallet = userWallet.requireColdWallet()) // TODO 11142
handleFetchTokensError(error = it, userWallet = userWallet)
},
)
}

View file

@ -4,7 +4,7 @@ import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.assisted.Assisted
@ -35,7 +35,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constr
get() = emptySet()
override fun produce(): Flow<Set<CryptoCurrency>> {
val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId).requireColdWallet() // TODO [REDACTED_TASK_KEY]
val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId)
if (!userWallet.isMultiCurrency) {
error("${this::class.simpleName} supports only multi-currency wallet")

View file

@ -53,7 +53,7 @@ internal class MissedDerivationsFinder(private val userWallet: UserWallet) {
private fun List<Network>.mapToNewDerivations(): List<DerivationData> {
val config = when (userWallet) {
is UserWallet.Cold -> CardConfig.createConfig(userWallet.scanResponse.card)
is UserWallet.Hot -> Wallet2CardConfig // TODO create config [REDACTED_TASK_KEY]
is UserWallet.Hot -> Wallet2CardConfig // TODO [REDACTED_TASK_KEY] [Hot Wallet] Derivation config for hot wallet
}
return mapNotNull { network ->
val blockchain = network.toBlockchain()

View file

@ -46,7 +46,8 @@ class HotWalletAccessor @Inject constructor(
auth = auth,
block = { blockAuth ->
block(blockAuth).also {
// TODO [REDACTED_TASK_KEY] if user has biometry enabled, we set it as the new auth method
// TODO [REDACTED_TASK_KEY] [Hot Wallet] Authorization by access code
// if user has biometry enabled, we set it as the new auth method
if (blockAuth is HotAuth.Password /*&& has biometry enabled */) {
tangemHotSdk.changeAuth(
unlockHotWallet = UnlockHotWallet(

View file

@ -100,6 +100,20 @@ fun UserWallet.canHandleToken(blockchain: Blockchain, excludedBlockchains: Exclu
}
}
fun UserWallet.canHandleBlockchain(blockchain: Blockchain, excludedBlockchains: ExcludedBlockchains): Boolean {
return when (this) {
is UserWallet.Cold -> {
scanResponse.card.canHandleBlockchain(
blockchain = blockchain,
excludedBlockchains = excludedBlockchains,
cardTypesResolver = scanResponse.cardTypesResolver,
)
}
is UserWallet.Hot -> blockchain.isTestnet().not() &&
blockchain !in excludedBlockchains
}
}
/**
* The same as [CardDTO.supportedTokens] but with supportedTokens input, if previously calculated
*/

View file

@ -4,8 +4,6 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.domain.card.common.extensions.supportedBlockchains
import com.tangem.domain.card.common.util.cardTypesResolver
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.wallets.legacy.UserWalletsListManager
@ -26,21 +24,13 @@ class FilterAvailableNetworksForWalletUseCase(
it.walletId == userWalletId
} ?: return networks.toSet()
return when (userWallet) {
is UserWallet.Cold -> {
val supportedBlockchains = userWallet.scanResponse.card.supportedBlockchains(
cardTypesResolver = userWallet.scanResponse.cardTypesResolver,
excludedBlockchains = excludedBlockchains,
)
val supportedBlockchains = userWallet.supportedBlockchains(
excludedBlockchains = excludedBlockchains,
)
networks.filter {
val blockchain = Blockchain.fromNetworkId(it.networkId)
supportedBlockchains.contains(blockchain)
}.toSet()
}
is UserWallet.Hot -> {
networks.toSet() // TODO [REDACTED_TASK_KEY]
}
}
return networks.filter {
val blockchain = Blockchain.fromNetworkId(it.networkId)
supportedBlockchains.contains(blockchain)
}.toSet()
}
}

View file

@ -10,14 +10,14 @@ import com.tangem.domain.card.common.TapWorkarounds.isTangemTwins
import com.tangem.domain.card.models.TwinKey
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.requireColdWallet
class PrepareForSendUseCase(
private val transactionRepository: TransactionRepository,
private val cardSdkConfigRepository: CardSdkConfigRepository,
private val getHotTransactionSigner: (UserWallet.Hot) -> TransactionSigner,
) {
suspend operator fun invoke(
transactionData: TransactionData,
@ -56,7 +56,13 @@ class PrepareForSendUseCase(
}
private fun createSigner(userWallet: UserWallet): TransactionSigner {
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
return when (userWallet) {
is UserWallet.Hot -> getHotTransactionSigner(userWallet)
is UserWallet.Cold -> getColdSigner(userWallet)
}
}
private fun getColdSigner(userWallet: UserWallet.Cold): TransactionSigner {
val card = userWallet.scanResponse.card
val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins

View file

@ -3,6 +3,7 @@ package com.tangem.domain.transaction.usecase
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import com.tangem.blockchain.common.TransactionSigner
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemError
import com.tangem.domain.card.common.TapWorkarounds.isTangemTwins
@ -11,25 +12,21 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.models.network.Network
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.requireColdWallet
class SignUseCase(
private val cardSdkConfigRepository: CardSdkConfigRepository,
private val walletManagersFacade: WalletManagersFacade,
private val getHotTransactionSigner: (UserWallet.Hot) -> TransactionSigner,
) {
suspend operator fun invoke(
hash: ByteArray,
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
val signer = cardSdkConfigRepository.getCommonSigner(
cardId = card.cardId.takeIf { isCardNotBackedUp },
twinKey = TwinKey.getOrNull(scanResponse = userWallet.scanResponse),
)
val signer = when (userWallet) {
is UserWallet.Hot -> getHotTransactionSigner(userWallet)
is UserWallet.Cold -> getColdSigner(userWallet)
}
val walletManager = walletManagersFacade.getOrCreateWalletManager(userWallet.walletId, network)
?: error("WalletManager not found")
@ -39,4 +36,14 @@ class SignUseCase(
is CompletionResult.Success -> signResult.data.right()
}
}
private fun getColdSigner(userWallet: UserWallet.Cold): TransactionSigner {
val card = userWallet.scanResponse.card
val isCardNotBackedUp = card.backupStatus?.isActive != true && !card.isTangemTwins
return cardSdkConfigRepository.getCommonSigner(
cardId = card.cardId.takeIf { isCardNotBackedUp },
twinKey = TwinKey.getOrNull(scanResponse = userWallet.scanResponse),
)
}
}

View file

@ -25,7 +25,7 @@ class HotUserWalletBuilder @AssistedInject constructor(
) {
suspend fun build(): UserWallet.Hot = withContext(dispatcherProvider.default) {
val allNetworks = Blockchain.entries // TODO [REDACTED_TASK_KEY] add derivation config
val allNetworks = Blockchain.entries // TODO [REDACTED_TASK_KEY] [Hot Wallet] Derivation config for hot wallet
val curves = allNetworks.map { it.getSupportedCurves() }.flatten().toSet()
val requests = curves.sortedBy { it.ordinal }.map { curve ->
val derivationPaths = allNetworks.filter { curve in it.getSupportedCurves() }

View file

@ -13,7 +13,8 @@ fun UserWallet.hasDerivation(blockchain: Blockchain, derivationPath: String): Bo
return when (this) {
is UserWallet.Cold -> scanResponse.hasDerivation(blockchain, derivationPath)
is UserWallet.Hot -> {
val primaryCurve = Wallet2CardConfig.primaryCurve(blockchain) // TODO [REDACTED_TASK_KEY]: handle hot wallet config
// TODO [REDACTED_TASK_KEY] [Hot Wallet] Derivation config for hot wallet
val primaryCurve = Wallet2CardConfig.primaryCurve(blockchain)
val list = if (blockchain == Blockchain.Cardano) {
listOf(
CardanoUtils.extendedDerivationPath(DerivationPath(derivationPath)),

View file

@ -118,10 +118,14 @@ internal class DetailsModel @Inject constructor(
modelScope.launch {
val userWallets = getWalletsUseCase.invokeSync()
val scanResponse =
getSelectedWalletSyncUseCase().getOrNull()?.requireColdWallet()?.scanResponse // TODO [REDACTED_TASK_KEY]
?: error("Selected wallet is null")
val selectedUserWallet = getSelectedWalletSyncUseCase().getOrNull()
?: error("Selected wallet is null")
if (selectedUserWallet is UserWallet.Hot) {
return@launch // TODO [REDACTED_TASK_KEY] [Hot Wallet] Send feedback
}
val scanResponse = selectedUserWallet.requireColdWallet().scanResponse
val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch
val feedbackType = when {
@ -140,11 +144,13 @@ internal class DetailsModel @Inject constructor(
}
private fun openUseDesk() {
val scanResponse =
getSelectedWalletSyncUseCase().getOrNull()?.requireColdWallet()?.scanResponse // TODO [REDACTED_TASK_KEY]
?: error("Selected wallet is null")
val userWallet = getSelectedWalletSyncUseCase().getOrNull() ?: error("Selected wallet is null")
val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return
if (userWallet is UserWallet.Hot) {
return // TODO [REDACTED_TASK_KEY] [Hot Wallet] UseDesk
}
val cardInfo = getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return
router.push(AppRoute.Usedesk(cardInfo))
}

View file

@ -215,7 +215,8 @@ internal class OnboardingVisaModel @Inject constructor(
private fun tryToFindExistingWalletCardId(targetAddress: String): String? {
val wallets = getWalletsUseCase.invokeSync().filter { it.isLocked.not() }
return wallets.filterIsInstance<UserWallet.Cold>().firstOrNull { wallet -> // TODO [REDACTED_TASK_KEY]
// TODO [REDACTED_TASK_KEY] [Hot Wallet] Visa 1.0 flow. Hot wallet as a customer wallet
return wallets.filterIsInstance<UserWallet.Cold>().firstOrNull { wallet ->
wallet.scanResponse.card.wallets.any {
val derivedKey = it.derivedKeys[VisaUtilities.visaDefaultDerivationPath] ?: return@any false

View file

@ -18,7 +18,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.onramp.model.OnrampSource
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.tokens.legacy.TradeCryptoAction
@ -57,7 +57,6 @@ internal class OnrampOperationModel @Inject constructor(
private val selectedUserWallet = getWalletsUseCase.invokeSync()
.first { it.walletId == params.userWalletId }
.requireColdWallet()
init {
analyticsEventHandler.send(
@ -154,7 +153,7 @@ internal class OnrampOperationModel @Inject constructor(
}
private fun showErrorIfDemoModeOrElse(action: () -> Unit) {
if (isDemoCardUseCase(cardId = selectedUserWallet.cardId)) {
if (selectedUserWallet is UserWallet.Cold && isDemoCardUseCase(cardId = selectedUserWallet.cardId)) {
val alertUM = AlertDemoModeUM(onConfirmClick = {})
val message = DialogMessage(

View file

@ -15,7 +15,6 @@ import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
import com.tangem.domain.settings.usercountry.models.UserCountry
import com.tangem.domain.tokens.GetTokenListUseCase
@ -61,7 +60,6 @@ internal class OnrampTokenListModel @Inject constructor(
private val params: OnrampTokenListComponent.Params = paramsContainer.require()
private val userWallet by lazy {
getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
.requireColdWallet() // TODO [REDACTED_TASK_KEY]
}
init {

View file

@ -26,6 +26,7 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.BlockchainErrorInfo
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
import com.tangem.domain.settings.NeverShowTapHelpUseCase
@ -325,8 +326,12 @@ internal class SendConfirmModel @Inject constructor(
),
)
if (userWallet is UserWallet.Hot) {
return // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val cardInfo =
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY]
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return
modelScope.launch {
sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo))

View file

@ -465,8 +465,12 @@ internal class SendModel @Inject constructor(
),
)
if (userWallet is UserWallet.Hot) {
return // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val cardInfo =
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY]
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return
modelScope.launch {
sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo))

View file

@ -21,6 +21,7 @@ import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.BlockchainErrorInfo
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
import com.tangem.domain.settings.NeverShowTapHelpUseCase
import com.tangem.domain.transaction.usecase.CreateNFTTransferTransactionUseCase
@ -231,8 +232,12 @@ internal class NFTSendConfirmModel @Inject constructor(
),
)
if (userWallet is UserWallet.Hot) {
return // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val cardInfo =
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY]
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return
modelScope.launch {
sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo))

View file

@ -206,8 +206,12 @@ internal class NFTSendModel @Inject constructor(
),
)
if (userWallet is UserWallet.Hot) {
return // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val cardInfo =
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY]
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return
modelScope.launch {
sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo))

View file

@ -859,6 +859,10 @@ internal class StakingModel @Inject constructor(
modelScope.launch {
val network = cryptoCurrencyStatus.currency.network
if (userWallet is UserWallet.Hot) {
return@launch // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val cardInfo =
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse)
.getOrElse { error("CardInfo must be not null") }

View file

@ -96,8 +96,12 @@ internal class SwapAlertFactory @Inject constructor(
),
)
if (userWallet is UserWallet.Hot) {
return // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val cardInfo =
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return // TODO [REDACTED_TASK_KEY]
getCardInfoUseCase(userWallet.requireColdWallet().scanResponse).getOrNull() ?: return
sendFeedbackEmailUseCase(
type = FeedbackEmailType.SwapProblem(

View file

@ -1351,8 +1351,6 @@ internal class SwapModel @Inject constructor(
val transaction = dataState.swapDataModel?.transaction
val fromCurrencyStatus = dataState.fromCryptoCurrency ?: initialFromStatus
val network = fromCurrencyStatus.currency.network
val cardInfo = getCardInfoUseCase(userWallet.requireColdWallet().scanResponse) // TODO [REDACTED_TASK_KEY]
.getOrElse { error("CardInfo must be not null") }
saveBlockchainErrorUseCase(
error = BlockchainErrorInfo(
@ -1366,6 +1364,13 @@ internal class SwapModel @Inject constructor(
),
)
if (userWallet is UserWallet.Hot) {
return@launch // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val cardInfo = getCardInfoUseCase(userWallet.requireColdWallet().scanResponse)
.getOrElse { error("CardInfo must be not null") }
val email = FeedbackEmailType.SwapProblem(
cardInfo = cardInfo,
providerName = dataState.selectedProvider?.name.orEmpty(),

View file

@ -96,6 +96,7 @@ internal class WalletSettingsModel @Inject constructor(
getWalletNotificationsEnabledUseCase(params.userWalletId),
) { maybeWallet, nftEnabled, notificationsEnabled ->
val wallet = maybeWallet.getOrNull() ?: return@combine
wallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] [Hot Wallet] Wallet Settings
val isRenameWalletAvailable = getShouldSaveUserWalletsSyncUseCase()
state.update { value ->
value.copy(
@ -126,7 +127,7 @@ internal class WalletSettingsModel @Inject constructor(
}
private fun buildItems(
userWallet: UserWallet,
userWallet: UserWallet.Cold,
dialogNavigation: SlotNavigation<DialogConfig>,
isRenameWalletAvailable: Boolean,
isNFTEnabled: Boolean,
@ -137,9 +138,8 @@ internal class WalletSettingsModel @Inject constructor(
): PersistentList<WalletSettingsItemUM> = itemsBuilder.buildItems(
userWalletId = userWallet.walletId,
userWalletName = userWallet.name,
isReferralAvailable = userWallet !is UserWallet.Cold || userWallet.cardTypesResolver.isTangemWallet(),
isLinkMoreCardsAvailable = userWallet is UserWallet.Cold &&
userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup,
isReferralAvailable = userWallet.cardTypesResolver.isTangemWallet(),
isLinkMoreCardsAvailable = userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup,
isManageTokensAvailable = userWallet.isMultiCurrency,
isRenameWalletAvailable = isRenameWalletAvailable,
renameWallet = { openRenameWalletDialog(userWallet, dialogNavigation) },
@ -162,7 +162,6 @@ internal class WalletSettingsModel @Inject constructor(
messageSender.send(message)
},
onLinkMoreCardsClick = {
userWallet.requireColdWallet()
onLinkMoreCardsClick(scanResponse = userWallet.scanResponse)
},
onReferralClick = { onReferralClick(userWallet) },

View file

@ -243,8 +243,13 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
modelScope.launch(dispatchers.main) {
neverToSuggestRateAppUseCase()
val scanResponse =
getSelectedUserWallet()?.requireColdWallet()?.scanResponse ?: return@launch // TODO [REDACTED_TASK_KEY]
val userWallet = getSelectedUserWallet() ?: return@launch
if (userWallet is UserWallet.Hot) {
return@launch // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val scanResponse = userWallet.requireColdWallet().scanResponse
val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch
sendFeedbackEmailUseCase(type = FeedbackEmailType.RateCanBeBetter(cardInfo = cardInfo))
@ -285,7 +290,13 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
}
override fun onSupportClick() {
val scanResponse = getSelectedUserWallet()?.requireColdWallet()?.scanResponse ?: return // TODO [REDACTED_TASK_KEY]
val userWallet = getSelectedUserWallet() ?: return
if (userWallet is UserWallet.Hot) {
return // TODO [REDACTED_TASK_KEY] [Hot Wallet] Email feedback flow
}
val scanResponse = userWallet.requireColdWallet().scanResponse
val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return
modelScope.launch {

View file

@ -2,7 +2,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.domain.card.common.util.getCardsCount
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
@ -40,8 +39,8 @@ internal class UpdateWalletCardsCountTransformer(
return when (this) {
is WalletCardState.Content -> copy(
additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet),
imageResId = walletImageResolver.resolve(userWallet = userWallet.requireColdWallet()), // TODO [REDACTED_TASK_KEY]
cardCount = userWallet.requireColdWallet().getCardsCount(), // TODO [REDACTED_TASK_KEY]
imageResId = walletImageResolver.resolve(userWallet = userWallet),
cardCount = (userWallet as? UserWallet.Cold)?.getCardsCount(),
)
else -> this
}

View file

@ -45,8 +45,8 @@ internal class WalletLoadingStateFactory(
walletCardState = WalletCardState.Loading(
id = userWallet.walletId,
title = userWallet.name,
additionalInfo = null, // TODO [REDACTED_TASK_KEY]
imageResId = null, // TODO [REDACTED_TASK_KEY]
additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet),
imageResId = null,
dropDownItems = persistentListOf(),
),
buttons = createMultiWalletActions(userWallet),