From 99176f84ecf32b4d5cf6f2f1468861f61bcc9a5d Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 26 Aug 2024 16:13:39 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/TokensDomainModule.kt | 16 +++++ .../repository/DefaultCurrenciesRepository.kt | 37 +++++++++++ ...AllWalletsCryptoCurrencyStatusesUseCase.kt | 66 +++++++++++++++++++ .../CurrenciesStatusesOperations.kt | 2 +- .../tokens/repository/CurrenciesRepository.kt | 8 ++- .../repository/MockCurrenciesRepository.kt | 5 ++ 6 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt index 6e5da90b47..078e47c07e 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt @@ -104,6 +104,22 @@ internal object TokensDomainModule { ) } + @Provides + @Singleton + fun provideGetAllWalletsCryptoCurrencyStatusesUseCase( + currenciesRepository: CurrenciesRepository, + quotesRepository: QuotesRepository, + networksRepository: NetworksRepository, + stakingRepository: StakingRepository, + ): GetAllWalletsCryptoCurrencyStatusesUseCase { + return GetAllWalletsCryptoCurrencyStatusesUseCase( + currenciesRepository = currenciesRepository, + quotesRepository = quotesRepository, + networksRepository = networksRepository, + stakingRepository = stakingRepository, + ) + } + @Provides @Singleton fun provideGetCurrencyWarningsUseCase( diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 5e4c6b350e..83d87b583b 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -40,6 +40,7 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -505,6 +506,42 @@ internal class DefaultCurrenciesRepository( } } + @OptIn(ExperimentalCoroutinesApi::class) + override fun getAllWalletsCryptoCurrencies(currencyRawId: String): Flow>> { + return userWalletsStore.userWallets.flatMapLatest { userWallets -> + val userWalletsWithCurrencies = userWallets + .filterNot(UserWallet::isLocked) + .map { userWallet -> + if (userWallet.isMultiCurrency) { + getSavedUserTokensResponse(userWallet.walletId).map { storedTokens -> + val filterResponse = storedTokens.tokens.filter { it.id == currencyRawId } + + responseCurrenciesFactory.createCurrencies( + response = storedTokens.copy(tokens = filterResponse), + scanResponse = userWallet.scanResponse, + ) + } + } else { + flow { + val currency = getSingleCurrencyWalletPrimaryCurrency(userWalletId = userWallet.walletId) + + val currencies = if (currency.id.rawCurrencyId == currencyRawId) { + listOf(currency) + } else { + emptyList() + } + + emit(currencies) + } + } + .map { userWallet to it } + } + + combine(userWalletsWithCurrencies) { it.toMap() } + .onEmpty { emit(value = emptyMap()) } + } + } + private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow> { return getSavedUserTokensResponse(userWallet.walletId).map { storedTokens -> responseCurrenciesFactory.createCurrencies( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt new file mode 100644 index 0000000000..816433f7be --- /dev/null +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetAllWalletsCryptoCurrencyStatusesUseCase.kt @@ -0,0 +1,66 @@ +package com.tangem.domain.tokens + +import arrow.core.Either +import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.error.CurrencyStatusError +import com.tangem.domain.tokens.error.mapper.mapToCurrencyError +import com.tangem.domain.tokens.model.CryptoCurrency +import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations +import com.tangem.domain.tokens.repository.CurrenciesRepository +import com.tangem.domain.tokens.repository.NetworksRepository +import com.tangem.domain.tokens.repository.QuotesRepository +import com.tangem.domain.wallets.models.UserWallet +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.* + +/** + * Get crypto currency statuses by raw ID for all wallets + * + * @property currenciesRepository currencies repository + * @property quotesRepository quotes repository + * @property networksRepository networks repository + * @property stakingRepository staking repository + * +[REDACTED_AUTHOR] + */ +class GetAllWalletsCryptoCurrencyStatusesUseCase( + private val currenciesRepository: CurrenciesRepository, + private val quotesRepository: QuotesRepository, + private val networksRepository: NetworksRepository, + private val stakingRepository: StakingRepository, +) { + + /** + * Get crypto currency statuses by [currencyRawId] for all wallets + * + * @param currencyRawId currency raw ID + */ + @OptIn(ExperimentalCoroutinesApi::class) + operator fun invoke( + currencyRawId: String, + ): Flow>>> { + return currenciesRepository.getAllWalletsCryptoCurrencies(currencyRawId) + .flatMapLatest { userWalletsWithCurrencies: Map> -> + val walletStatusFlows = userWalletsWithCurrencies.map { (userWallet, cryptoCurrencies) -> + val operations = CurrenciesStatusesOperations( + userWalletId = userWallet.walletId, + currenciesRepository = currenciesRepository, + quotesRepository = quotesRepository, + networksRepository = networksRepository, + stakingRepository = stakingRepository, + ) + + val currencyStatusFlows = cryptoCurrencies.map { cryptoCurrency -> + operations.getCurrencyStatusFlow(cryptoCurrency) + .map { it.mapLeft(CurrenciesStatusesOperations.Error::mapToCurrencyError) } + } + + combine(currencyStatusFlows) { statuses -> userWallet to statuses.toList() } + .onEmpty { emit(userWallet to emptyList()) } + } + + combine(walletStatusFlows) { it.toMap() } + } + } +} \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt index 74e207b2e7..1a9304db56 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt @@ -207,7 +207,7 @@ internal class CurrenciesStatusesOperations( return getCurrencyStatusFlow(currency) } - private fun getCurrencyStatusFlow(currency: CryptoCurrency): Flow> { + fun getCurrencyStatusFlow(currency: CryptoCurrency): Flow> { val (networks, currenciesIds) = getIds(nonEmptyListOf(currency)) val quoteFlow = getQuotes(currenciesIds) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt index 1bd10511b8..dcf638ef97 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt @@ -6,6 +6,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.FeePaidCurrency import com.tangem.domain.tokens.model.Network +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import kotlinx.coroutines.flow.Flow @@ -226,9 +227,7 @@ interface CurrenciesRepository { */ fun createTokenCurrency(cryptoCurrency: CryptoCurrency.Token, network: Network): CryptoCurrency.Token - /** - * Creates token [cryptoCurrency] based on [contractAddress] and [networkId] it`s will be added - */ + /** Creates token [CryptoCurrency.Token] based on [contractAddress] and [networkId] for specified [userWalletId] */ suspend fun createTokenCurrency( userWalletId: UserWalletId, contractAddress: String, @@ -236,4 +235,7 @@ interface CurrenciesRepository { ): CryptoCurrency.Token suspend fun hasTokens(userWalletId: UserWalletId, network: Network): Boolean + + /** Get crypto currencies by [currencyRawId] from all user wallets */ + fun getAllWalletsCryptoCurrencies(currencyRawId: String): Flow>> } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt index 17f718c351..317a1a3dbe 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt @@ -9,6 +9,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.FeePaidCurrency import com.tangem.domain.tokens.model.Network +import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow @@ -152,4 +153,8 @@ internal class MockCurrenciesRepository( override suspend fun hasTokens(userWalletId: UserWalletId, network: Network): Boolean { return false } + + override fun getAllWalletsCryptoCurrencies(currencyRawId: String): Flow>> { + return emptyFlow() + } } \ No newline at end of file