Updated on 2026-08-14

This commit is contained in:
Tangem 2025-11-05 03:49:15 +07:00
parent 7fee3c6d3b
commit 70dd41a680
19 changed files with 594 additions and 184 deletions

View file

@ -17,6 +17,7 @@ dependencies {
// region Project Domain
implementation(projects.domain.core)
implementation(projects.domain.account.status)
implementation(projects.domain.models)
implementation(projects.domain.networks)
implementation(projects.domain.nft.models)

View file

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

View file

@ -1,25 +1,54 @@
package com.tangem.domain.nft
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.nft.models.NFTCollections
import com.tangem.domain.nft.models.WalletNFTCollections
import com.tangem.domain.nft.repository.NFTRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.models.wallet.UserWalletId
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.*
class GetNFTCollectionsUseCase(
private val currenciesRepository: CurrenciesRepository,
private val nftRepository: NFTRepository,
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
private val accountsFeatureToggles: AccountsFeatureToggles,
) {
@OptIn(ExperimentalCoroutinesApi::class)
operator fun invoke(userWalletId: UserWalletId): Flow<List<NFTCollections>> = currenciesRepository
.getWalletCurrenciesUpdates(userWalletId)
.flatMapLatest {
val networks = it
.map { cryptoCurrency -> cryptoCurrency.network }
.distinct()
nftRepository.observeCollections(userWalletId, networks)
operator fun invoke(userWalletId: UserWalletId): Flow<List<NFTCollections>> =
if (accountsFeatureToggles.isFeatureEnabled) {
invokeForAccounts(userWalletId).map { it.flattenCollections }
} else {
currenciesRepository
.getWalletCurrenciesUpdates(userWalletId)
.flatMapLatest {
nftCollections(userWalletId, it)
}
}
fun invokeForAccounts(userWalletId: UserWalletId): Flow<WalletNFTCollections> {
fun AccountStatus.flowOfNFTCollections(): Flow<Pair<Account, List<NFTCollections>>> =
nftCollections(userWalletId, this.flattenCurrencies().map { it.currency })
.map { nfts -> this.account to nfts }
return singleAccountStatusListSupplier(userWalletId)
.mapLatest { statusList -> statusList.accountStatuses.map { it.flowOfNFTCollections() } }
.flatMapLatest { flows -> combine(flows) { WalletNFTCollections(it.toMap()) } }
}
private fun nftCollections(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): Flow<List<NFTCollections>> {
val networks = cryptoCurrencies
.map { cryptoCurrency -> cryptoCurrency.network }
.distinct()
return nftRepository.observeCollections(userWalletId, networks)
}
}

View file

@ -1,32 +1,48 @@
package com.tangem.domain.nft
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
import com.tangem.domain.models.PortfolioId
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.nft.models.NFTNetworks
import com.tangem.domain.nft.repository.NFTRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.models.wallet.UserWalletId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.mapNotNull
class GetNFTNetworksUseCase(
private val currenciesRepository: CurrenciesRepository,
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
private val nftRepository: NFTRepository,
) {
operator fun invoke(userWalletId: UserWalletId): Flow<NFTNetworks> = currenciesRepository
.getWalletCurrenciesUpdates(userWalletId)
.map { cryptoCurrencies ->
val availableNetworks = cryptoCurrencies
.map { cryptoCurrency -> cryptoCurrency.network }
.filter { nftRepository.isNFTSupported(userWalletId, it) }
.sortedBy { it.name }
operator fun invoke(portfolioId: PortfolioId): Flow<NFTNetworks> = when (portfolioId) {
is PortfolioId.Account -> singleAccountStatusListSupplier(portfolioId.userWalletId)
.map { it.accountStatuses }
.mapNotNull { accountStatuses -> accountStatuses.find { it.account.accountId == portfolioId.accountId } }
.map { accountStatus -> accountStatus.flattenCurrencies().map { it.currency } }
.mapLatest { it.toNFTNetworks(portfolioId.userWalletId) }
is PortfolioId.Wallet ->
currenciesRepository
.getWalletCurrenciesUpdates(portfolioId.userWalletId)
.map { cryptoCurrencies -> cryptoCurrencies.toNFTNetworks(portfolioId.userWalletId) }
}
val unavailableNetworks = nftRepository
.getNFTSupportedNetworks(userWalletId)
.filter { supportedNetwork -> availableNetworks.none { it.id == supportedNetwork.id } }
.sortedBy { it.name }
private suspend fun List<CryptoCurrency>.toNFTNetworks(userWalletId: UserWalletId): NFTNetworks {
val availableNetworks = this
.map { cryptoCurrency -> cryptoCurrency.network }
.filter { nftRepository.isNFTSupported(userWalletId, it) }
.sortedBy { it.name }
NFTNetworks(
availableNetworks = availableNetworks,
unavailableNetworks = unavailableNetworks,
)
}
val unavailableNetworks = nftRepository
.getNFTSupportedNetworks(userWalletId)
.filter { supportedNetwork -> availableNetworks.none { it.id == supportedNetwork.id } }
.sortedBy { it.name }
return NFTNetworks(
availableNetworks = availableNetworks,
unavailableNetworks = unavailableNetworks,
)
}
}