Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-09 20:26:31 +05:00
parent 58d7b0f393
commit 94c46ca16d
19 changed files with 61 additions and 126 deletions

View file

@ -102,7 +102,7 @@ data class AccountList private constructor(
return accounts.flatMap { account ->
when (account) {
is Account.CryptoPortfolio -> account.cryptoCurrencies
is Account.Payment -> TODO("[REDACTED_JIRA]")
is Account.Payment -> emptyList()
}
}
}

View file

@ -363,7 +363,7 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
private fun createLoadingAccountStatusList(accountList: AccountList): AccountStatusList {
return AccountStatusList(
userWalletId = accountList.userWalletId,
accountStatuses = accountList.accounts.map { account ->
accountStatuses = accountList.accounts.mapNotNull { account ->
when (account) {
is Account.CryptoPortfolio -> {
val currencyStatuses = account.cryptoCurrencies.map {
@ -380,7 +380,7 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
priceChangeLce = lceLoading(),
)
}
is Account.Payment -> TODO("[REDACTED_JIRA]")
is Account.Payment -> null
}
},
totalAccounts = accountList.totalAccounts,

View file

@ -3,7 +3,7 @@ package com.tangem.domain.nft.models
import com.tangem.domain.models.account.Account
data class WalletNFTCollections(
val collections: Map<Account, List<NFTCollections>>,
val collections: Map<Account.CryptoPortfolio, List<NFTCollections>>,
) {
val flattenCollections by lazy { collections.values.flatten() }
}

View file

@ -18,14 +18,18 @@ class GetNFTCollectionsUseCase(
@OptIn(ExperimentalCoroutinesApi::class)
operator fun invoke(userWalletId: UserWalletId): Flow<WalletNFTCollections> {
return singleAccountListSupplier(userWalletId)
.mapLatest { statusList -> statusList.accounts.mapNotNull(::flowOfNFTCollections) }
.mapLatest { statusList ->
statusList.accounts.filterIsInstance<Account.CryptoPortfolio>().mapNotNull(::flowOfNFTCollections)
}
.flatMapLatest { flows ->
combine(flows) { WalletNFTCollections(it.toMap()) }
}
}
private fun flowOfNFTCollections(account: Account): Flow<Pair<Account, List<NFTCollections>>>? {
val currencies = (account as? Account.CryptoPortfolio)?.cryptoCurrencies.orEmpty()
private fun flowOfNFTCollections(
account: Account.CryptoPortfolio,
): Flow<Pair<Account.CryptoPortfolio, List<NFTCollections>>>? {
val currencies = account.cryptoCurrencies
if (currencies.isEmpty()) return null

View file

@ -33,7 +33,6 @@ import com.tangem.features.account.analytics.AccountSettingsAnalyticEvents.Compa
import com.tangem.features.account.analytics.WalletSettingsAccountAnalyticEvents
import com.tangem.features.account.createedit.entity.AccountCreateEditUM
import com.tangem.features.account.createedit.entity.AccountCreateEditUMBuilder
import com.tangem.features.account.createedit.entity.AccountCreateEditUMBuilder.Companion.portfolioIcon
import com.tangem.features.account.createedit.entity.AccountCreateEditUMBuilder.Companion.toggleProgress
import com.tangem.features.account.createedit.entity.AccountCreateEditUMBuilder.Companion.updateButton
import com.tangem.features.account.createedit.entity.AccountCreateEditUMBuilder.Companion.updateColorSelect
@ -173,7 +172,7 @@ internal class AccountCreateEditModel @Inject constructor(
val name = state.account.name.toDomain().getOrNull() ?: return
val icon = CryptoPortfolioIconConverter.convertBack(state.account.portfolioIcon)
val isNewName = name != params.account.accountName
val isNewIcon = icon != params.account.portfolioIcon
val isNewIcon = icon != params.account.icon
val derivationIndex = params.account.derivationIndex.value
analyticsEventHandler.send(AccountSettingsAnalyticEvents.ButtonSave(name, icon, derivationIndex))
@ -258,7 +257,7 @@ internal class AccountCreateEditModel @Inject constructor(
is AccountCreateEditComponent.Params.Create -> isValidName
is AccountCreateEditComponent.Params.Edit -> {
val oldName = params.account.accountName.toUM()
val oldIcon = CryptoPortfolioIconConverter.convert(params.account.portfolioIcon)
val oldIcon = CryptoPortfolioIconConverter.convert(params.account.icon)
val isNewName = this.account.name.trim() != oldName
val isNewIcon = this.account.portfolioIcon != oldIcon

View file

@ -7,7 +7,6 @@ import com.tangem.core.res.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.CryptoPortfolioIcon
import com.tangem.features.account.AccountCreateEditComponent
import kotlinx.collections.immutable.toImmutableList
@ -37,10 +36,8 @@ internal class AccountCreateEditUMBuilder(
)
is AccountCreateEditComponent.Params.Edit -> AccountCreateEditUM.Account(
name = params.account.accountName.toUM(),
portfolioIcon = CryptoPortfolioIconConverter.convert(params.account.portfolioIcon),
derivationInfo = createAccountDerivationInfo(
index = (params.account as Account.CryptoPortfolio).derivationIndex.value,
),
portfolioIcon = CryptoPortfolioIconConverter.convert(params.account.icon),
derivationInfo = createAccountDerivationInfo(index = params.account.derivationIndex.value),
inputPlaceholder = resourceReference(R.string.account_form_placeholder_edit_account),
onNameChange = onNameChange,
)
@ -50,7 +47,7 @@ internal class AccountCreateEditUMBuilder(
fun initColorsUM(onColorSelect: (CryptoPortfolioIcon.Color) -> Unit): AccountCreateEditUM.Colors {
val selected: CryptoPortfolioIcon.Color = when (params) {
is AccountCreateEditComponent.Params.Create -> createIcon.color
is AccountCreateEditComponent.Params.Edit -> params.account.portfolioIcon.color
is AccountCreateEditComponent.Params.Edit -> params.account.icon.color
}
return AccountCreateEditUM.Colors(
selected = selected,
@ -62,7 +59,7 @@ internal class AccountCreateEditUMBuilder(
fun initIconsUM(onIconSelect: (CryptoPortfolioIcon.Icon) -> Unit): AccountCreateEditUM.Icons {
val selected: CryptoPortfolioIcon.Icon = when (params) {
is AccountCreateEditComponent.Params.Create -> createIcon.value
is AccountCreateEditComponent.Params.Edit -> params.account.portfolioIcon.value
is AccountCreateEditComponent.Params.Edit -> params.account.icon.value
}
return AccountCreateEditUM.Icons(
selected = selected,
@ -85,13 +82,6 @@ internal class AccountCreateEditUMBuilder(
}
internal companion object {
val Account.portfolioIcon: CryptoPortfolioIcon
get() = when (this) {
is Account.CryptoPortfolio -> this.icon
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
fun AccountCreateEditUM.updateColorSelect(color: CryptoPortfolioIcon.Color): AccountCreateEditUM {
val newIcon = this.account.portfolioIcon.copy(
color = color,

View file

@ -21,7 +21,6 @@ import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.account.AccountDetailsComponent
import com.tangem.features.account.analytics.AccountSettingsAnalyticEvents
import com.tangem.features.account.createedit.entity.AccountCreateEditUMBuilder.Companion.portfolioIcon
import com.tangem.features.account.details.entity.AccountDetailsUM
import com.tangem.features.account.details.entity.AccountDetailsUM.ArchiveMode
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -164,7 +163,7 @@ internal class AccountDetailsModel @Inject constructor(
?.isMultiCurrency == true
return AccountDetailsUM(
accountName = account.accountName.toUM().value,
accountIcon = CryptoPortfolioIconConverter.convert(account.portfolioIcon),
accountIcon = CryptoPortfolioIconConverter.convert(account.icon),
onCloseClick = { router.pop() },
onAccountEditClick = { onEditAccountClick(account) },
onManageTokensClick = { onManageTokensClick(account) },

View file

@ -28,7 +28,7 @@ data class AvailableToAddWallet(
@Serializable
data class AvailableToAddAccount(
val account: AccountStatus,
val account: AccountStatus.CryptoPortfolio,
val availableNetworks: Set<TokenMarketInfo.Network>,
val addedNetworks: Set<Network>,
) {

View file

@ -14,7 +14,6 @@ import com.tangem.core.ui.message.ToastMessage
import com.tangem.domain.account.status.usecase.GetCryptoCurrencyActionsUseCaseV2
import com.tangem.domain.markets.GetTokenMarketCryptoCurrency
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
@ -28,13 +27,13 @@ import com.tangem.features.feed.components.market.details.portfolio.impl.loader.
import com.tangem.features.feed.components.market.details.portfolio.impl.model.PortfolioTokenUMConverter.Companion.toQuickActions
import com.tangem.features.feed.impl.R
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import com.tangem.utils.logging.TangemLogger
import javax.inject.Inject
private const val TOKEN_ACTIONS_DELAY = 500L
@ -325,10 +324,7 @@ internal class AddToPortfolioModel @Inject constructor(
network: TokenMarketInfo.Network,
account: AvailableToAddAccount,
): CryptoCurrency? {
val accountIndex = when (val accountStatus = account.account) {
is AccountStatus.CryptoPortfolio -> accountStatus.account.derivationIndex
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
val accountIndex = account.account.account.derivationIndex
return getTokenMarketCryptoCurrency(
userWalletId = userWallet.walletId,
tokenMarketParams = addToPortfolioManager.token,

View file

@ -11,7 +11,6 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.message.ToastMessage
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
import com.tangem.domain.models.account.Account
import com.tangem.domain.wallets.usecase.ColdWalletAndHasMissedDerivationsUseCase
import com.tangem.features.feed.components.market.details.portfolio.add.SelectedNetwork
import com.tangem.features.feed.components.market.details.portfolio.add.SelectedPortfolio
@ -105,12 +104,9 @@ internal class AddTokenModel @Inject constructor(
if (status == null) {
processError(error = null)
} else {
when (account) {
is Account.CryptoPortfolio -> if (!account.isMainAccount) {
if (!account.isMainAccount) {
analyticsEventHandler.send(analyticsEventBuilder.addToNotMainAccount())
}
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
analyticsEventHandler.send(
event = analyticsEventBuilder.tokenAdded(status.status.currency.network.name),

View file

@ -275,15 +275,12 @@ internal class MarketsPortfolioDelegate @AssistedInject constructor(
)
}
private fun Account.toAccountPortfolioHeader(): PortfolioHeader = PortfolioHeader(
private fun Account.CryptoPortfolio.toAccountPortfolioHeader(): PortfolioHeader = PortfolioHeader(
id = this.accountId.value,
state = AccountTitleUM.Account(
prefixText = TextReference.EMPTY,
name = this.accountName.toUM().value,
icon = when (this) {
is Account.CryptoPortfolio -> CryptoPortfolioIconConverter.convert(this.icon)
is Account.Payment -> TODO("[REDACTED_JIRA]")
},
icon = CryptoPortfolioIconConverter.convert(this.icon),
),
)
@ -334,7 +331,7 @@ private data class Portfolio(
private data class AccountWithAdded(
val addedCurrency: List<CryptoCurrencyStatus>,
val accountStatus: AccountStatus,
val accountStatus: AccountStatus.CryptoPortfolio,
)
private data class SettingsBox(

View file

@ -17,8 +17,8 @@ import com.tangem.core.ui.message.EventMessageAction
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
import com.tangem.domain.managetokens.GetSupportedNetworksUseCase
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.network.Network
import com.tangem.features.managetokens.component.AddCustomTokenMode
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent
@ -214,23 +214,14 @@ internal class CustomTokenSelectorModel @Inject constructor(
this.account.derivationIndex.value.toLong() == accountNode
val accounts = singleAccountStatusListSupplier(mode.userWalletId)
.first().accountStatuses
.first().accountStatuses.filterCryptoPortfolio()
val accountStatus = accounts.find { account ->
when (account) {
is AccountStatus.CryptoPortfolio -> account.sameNodeAndNotMain()
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
accounts
.find { account -> account.sameNodeAndNotMain() }
?.account
}
accountStatus?.account
}
val accountName = when (account) {
is Account.CryptoPortfolio -> account.accountName
is Account.Payment -> TODO("[REDACTED_JIRA]")
null -> null
}
val accountName = account?.accountName
if (accountName == null) {
onDerivationPathSelected(derivationPath, null)

View file

@ -95,15 +95,12 @@ internal class UpdateDataStateTransformer(
createNFTsUM(mainAccountCollection).toPersistentList()
}
private fun Account.toAccountPortfolioUM(): NFTCollectionPortfolioUM = NFTCollectionPortfolioUM(
private fun Account.CryptoPortfolio.toAccountPortfolioUM(): NFTCollectionPortfolioUM = NFTCollectionPortfolioUM(
id = this.accountId.value,
title = AccountTitleUM.Account(
prefixText = TextReference.EMPTY,
name = this.accountName.toUM().value,
icon = when (this) {
is Account.CryptoPortfolio -> CryptoPortfolioIconConverter.convert(this.icon)
is Account.Payment -> TODO("[REDACTED_JIRA]")
},
icon = CryptoPortfolioIconConverter.convert(this.icon),
),
)

View file

@ -8,6 +8,7 @@ import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
@ -42,14 +43,10 @@ internal class HotCryptoPortfolioDataLoader @Inject constructor(
.invokeSync(userWalletId, hotCryptoCurrencies)
.getOrNull()
.orEmpty()
val accountsWithHotCrypto = walletAccounts.accountStatuses.map { accountStatus ->
val account: AccountStatus.CryptoPortfolio = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
val addedHotCrypto = mapOfAddedCurrencies[account.account].orEmpty()
val accountsWithHotCrypto = walletAccounts.accountStatuses.filterCryptoPortfolio().map { accountStatus ->
val addedHotCrypto = mapOfAddedCurrencies[accountStatus.account].orEmpty()
HotCryptoPortfolioData.Account(
account = account,
account = accountStatus,
addedHotCrypto = addedHotCrypto,
)
}

View file

@ -247,9 +247,8 @@ internal class AvailableSwapPairsModel @Inject constructor(
val (appCurrency, isBalanceHidden) = appCurrencyAndBalanceHiding
val filterByQueryAccountList: Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>> = accountList
.filterCryptoPortfolio()
.associate { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> {
val statuses = accountStatus.tokenList.flattenCurrencies()
.filterNot { status ->
status.currency.network.backendId == selectedStatus?.currency?.network?.backendId &&
@ -259,9 +258,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
accountStatus.account to statuses
}
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}
.filterValues { it.isNotEmpty() }
if (availablePairs.isEmpty()) {

View file

@ -21,12 +21,9 @@ internal class SetLoadingAccountTokenListTransformer(
private val accountListItemConverter = LoadingAccountTokenItemConverter(appCurrency)
override fun transform(prevState: TokenListUM): TokenListUM {
val totalTokensCount = accountList.sumOf { account ->
when (account) {
is AccountStatus.CryptoPortfolio -> account.tokenList.flattenCurrencies().size
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}
val totalTokensCount = accountList
.filterCryptoPortfolio()
.sumOf { account -> account.tokenList.flattenCurrencies().size }
return prevState.copy(
availableItems = persistentListOf(),
@ -40,13 +37,10 @@ internal class SetLoadingAccountTokenListTransformer(
)
} else {
TokenListUMData.TokenList(
tokensList = accountList.flatMap { account ->
when (account) {
is AccountStatus.CryptoPortfolio -> LoadingTokenListItemConverter.convertList(
tokensList = accountList.filterCryptoPortfolio().flatMap { account ->
LoadingTokenListItemConverter.convertList(
account.tokenList.flattenCurrencies().map(CryptoCurrencyStatus::currency),
)
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}.toPersistentList(),
totalTokensCount = totalTokensCount,
)

View file

@ -18,7 +18,6 @@ import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
@ -240,13 +239,8 @@ internal class OnrampTokenListModel @Inject constructor(
): Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>> = accountStatuses.asSequence()
.filterCryptoPortfolio()
.associate { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> {
val filteredList = accountStatus.tokenList.flattenCurrencies().filterByQuery(query = query)
accountStatus.account to filteredList
}
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}.filter { (_, value) -> value.isNotEmpty() }
private fun List<CryptoCurrencyStatus>.filterByQuery(query: String): List<CryptoCurrencyStatus> {

View file

@ -4,9 +4,9 @@ import com.tangem.common.core.TangemSdkError
import com.tangem.domain.account.producer.SingleAccountProducer
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
import com.tangem.domain.account.supplier.SingleAccountSupplier
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.walletmanager.WalletManagersFacade
@ -40,20 +40,13 @@ internal class ReferralInteractorImpl(
val account = singleAccountSupplier.getSyncOrNull(
params = SingleAccountProducer.Params(accountId = accountId),
)
?: error("Account not found: $accountId")
val accountIndex = when (account) {
is Account.CryptoPortfolio -> account.derivationIndex
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
) ?: error("Account not found: $accountId")
val cryptoCurrency = getCryptoCurrency(
userWalletId = accountId.userWalletId,
tokenData = tokenData,
accountIndex = accountIndex,
)
?: error("Failed to create crypto currency")
accountIndex = account.derivationIndex,
) ?: error("Failed to create crypto currency")
manageCryptoCurrenciesUseCase(
accountId = accountId,

View file

@ -30,7 +30,6 @@ import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.express.models.ExpressOperationType
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
@ -72,11 +71,7 @@ import com.tangem.utils.logging.TangemLogger
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.*
import java.math.BigDecimal
import java.math.BigInteger
import java.math.RoundingMode
@ -142,10 +137,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
val walletAccountCurrencyStatusesExceptInitial: Map<Account, List<CryptoCurrencyStatus>> =
walletAccountCurrencyStatuses.mapNotNull { accountStatus ->
val filteredCurrencies = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.flattenCurrencies().filterCurrencies(currency)
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
val filteredCurrencies = accountStatus.flattenCurrencies().filterCurrencies(currency)
if (filteredCurrencies.isNotEmpty()) {
accountStatus.account to filteredCurrencies