From 47f5ac82df354a3bbebf4b876bd378af4f66b6e1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 28 Oct 2024 17:27:49 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/TokensDomainModule.kt | 11 --- .../repository/DefaultCurrenciesRepository.kt | 34 +++++--- .../domain/tokens/GetNodlTokenListUseCase.kt | 79 ------------------- .../CurrenciesStatusesOperations.kt | 50 ------------ .../tokens/operations/TokenListOperations.kt | 26 ------ .../SingleWalletWithTokenContentLoader.kt | 6 +- ...ngleWalletWithTokenContentLoaderFactory.kt | 6 +- .../SingleWalletWithTokenListSubscriber.kt | 16 ++-- 8 files changed, 34 insertions(+), 194 deletions(-) delete mode 100644 domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNodlTokenListUseCase.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 c28ded59d7..c72518ff14 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 @@ -67,17 +67,6 @@ internal object TokensDomainModule { ) } - @Provides - @Singleton - fun provideGetCardTokensListUseCase( - currenciesRepository: CurrenciesRepository, - quotesRepository: QuotesRepository, - networksRepository: NetworksRepository, - stakingRepository: StakingRepository, - ): GetNodlTokenListUseCase { - return GetNodlTokenListUseCase(currenciesRepository, quotesRepository, networksRepository, stakingRepository) - } - @Provides @Singleton fun provideRemoveCurrencyUseCase( 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 e5b5f561bd..a739407505 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 @@ -38,7 +38,6 @@ 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.plus import kotlinx.coroutines.withContext import timber.log.Timber @@ -207,8 +206,9 @@ internal class DefaultCurrenciesRepository( if (userWallet.isMultiCurrency) { getMultiCurrencyWalletCurrenciesUpdates(userWalletId).collect(::send) } else { - val currency = getSingleCurrencyWalletPrimaryCurrency(userWalletId) - send(listOf(currency)) + val currencies = getSingleCurrencyWalletWithCardCurrencies(userWalletId) + + send(currencies) } } } @@ -349,26 +349,34 @@ internal class DefaultCurrenciesRepository( override fun isTokensGrouped(userWalletId: UserWalletId): Flow { return channelFlow { - ensureIsCorrectUserWallet(userWalletId, isMultiCurrencyWalletExpected = true) + val userWallet = getUserWallet(userWalletId) - launch(dispatchers.io) { + if (userWallet.isMultiCurrency) { getSavedUserTokensResponse(userWalletId) - .map { it.group == UserTokensResponse.GroupType.NETWORK } - .collect(::send) + .map { response -> response.group == UserTokensResponse.GroupType.NETWORK } + .distinctUntilChanged() + .onEach { isGrouped -> send(isGrouped) } + .launchIn(scope = this + dispatchers.io) + } else { + send(element = false) } - }.cancellable() + } } override fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow { return channelFlow { - ensureIsCorrectUserWallet(userWalletId, isMultiCurrencyWalletExpected = true) + val userWallet = getUserWallet(userWalletId) - launch(dispatchers.io) { + if (userWallet.isMultiCurrency) { getSavedUserTokensResponse(userWalletId) - .map { it.sort == UserTokensResponse.SortType.BALANCE } - .collect(::send) + .map { response -> response.sort == UserTokensResponse.SortType.BALANCE } + .distinctUntilChanged() + .onEach { isSorted -> send(isSorted) } + .launchIn(scope = this + dispatchers.io) + } else { + send(element = false) } - }.cancellable() + } } override fun isSendBlockedByPendingTransactions( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNodlTokenListUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNodlTokenListUseCase.kt deleted file mode 100644 index abbe7fa327..0000000000 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNodlTokenListUseCase.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.tangem.domain.tokens - -import arrow.core.left -import com.tangem.domain.core.utils.EitherFlow -import com.tangem.domain.staking.repositories.StakingRepository -import com.tangem.domain.tokens.error.TokenListError -import com.tangem.domain.tokens.error.mapper.mapToTokenListError -import com.tangem.domain.tokens.model.CryptoCurrencyStatus -import com.tangem.domain.tokens.model.TokenList -import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations -import com.tangem.domain.tokens.operations.TokenListOperations -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.UserWalletId -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.transformLatest - -/** - * Use case for getting a list of tokens for NODL card - * - * @property currenciesRepository currencies repository - * @property quotesRepository quotes repository - * @property networksRepository networks repository - * @property stakingRepository staking repository - */ -class GetNodlTokenListUseCase( - private val currenciesRepository: CurrenciesRepository, - private val quotesRepository: QuotesRepository, - private val networksRepository: NetworksRepository, - private val stakingRepository: StakingRepository, -) { - - @OptIn(ExperimentalCoroutinesApi::class) - operator fun invoke(userWalletId: UserWalletId): EitherFlow { - return getTokensStatuses(userWalletId).transformLatest { maybeTokens -> - maybeTokens.fold( - ifLeft = { error -> - emit(error.left()) - }, - ifRight = { tokens -> - emitAll(createTokenList(userWalletId, tokens)) - }, - ) - } - } - - private fun getTokensStatuses(userWalletId: UserWalletId): EitherFlow> { - val operations = CurrenciesStatusesOperations( - userWalletId = userWalletId, - currenciesRepository = currenciesRepository, - quotesRepository = quotesRepository, - networksRepository = networksRepository, - stakingRepository = stakingRepository, - ) - - return operations.getCardCurrenciesStatusesFlow() - .map { maybeCurrenciesStatuses -> - maybeCurrenciesStatuses.mapLeft(CurrenciesStatusesOperations.Error::mapToTokenListError) - } - } - - private fun createTokenList( - userWalletId: UserWalletId, - tokens: List, - ): EitherFlow { - val operations = TokenListOperations( - userWalletId = userWalletId, - tokens = tokens, - currenciesRepository = currenciesRepository, - ) - - return operations.getTokenListForSingleCurrencyFlow().map { maybeTokenList -> - maybeTokenList.mapLeft(TokenListOperations.Error::mapToTokenListError) - } - } -} \ 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 34ac4153c2..639ccd6991 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 @@ -120,50 +120,6 @@ internal class CurrenciesStatusesOperations( return createCurrencyStatus(currency, quotes, networkStatus, yieldBalances) } - fun getCardCurrenciesStatusesFlow(): Flow>> { - return flow { - val nonEmptyCurrencies = recover( - block = { getCurrenciesFromCard(userWalletId) }, - recover = { - emit(it.left()) - return@flow - }, - ).toNonEmptyListOrNull() - - if (nonEmptyCurrencies == null) { - val emptyCurrenciesStatuses = emptyList() - - emit(emptyCurrenciesStatuses.right()) - return@flow - } - - val maybeLoadingCurrenciesStatuses = createCurrenciesStatuses( - currencies = nonEmptyCurrencies, - maybeNetworkStatuses = null, - maybeQuotes = null, - maybeYieldBalances = null, - ) - - emit(maybeLoadingCurrenciesStatuses) - - val (networks, currenciesIds) = getIds(nonEmptyCurrencies) - - val currenciesFlow = combine( - getQuotes(currenciesIds), - getNetworksStatuses(networks), - ) { maybeQuotes, maybeNetworksStatuses -> - createCurrenciesStatuses( - currencies = nonEmptyCurrencies, - maybeQuotes = maybeQuotes, - maybeNetworkStatuses = maybeNetworksStatuses, - maybeYieldBalances = null, - ) - } - - emitAll(currenciesFlow) - } - } - suspend fun getCurrencyStatusFlow(currencyId: CryptoCurrency.ID): Flow> { val currency = recover( block = { getMultiCurrencyWalletCurrency(currencyId) }, @@ -377,12 +333,6 @@ internal class CurrenciesStatusesOperations( ) } - private suspend fun Raise.getCurrenciesFromCard(userWalletId: UserWalletId): List { - return catch({ currenciesRepository.getSingleCurrencyWalletWithCardCurrencies(userWalletId) }) { - raise(Error.DataError(it)) - } - } - private fun getQuotes(tokensIds: NonEmptySet): Flow>> { return quotesRepository.getQuotesUpdates(tokensIds) .map, Either>> { quotes -> diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListOperations.kt index 0af48b7898..8f2404de68 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListOperations.kt @@ -29,16 +29,6 @@ internal class TokenListOperations( } } - fun getTokenListForSingleCurrencyFlow(): Flow> { - return flow { - emit( - either { - createTokenList() - }, - ) - } - } - private fun Raise.createTokenList(isGrouped: Boolean, isSortedByBalance: Boolean): TokenList { val nonEmptyCurrencies = tokens.toNonEmptyListOrNull() ?: return TokenList.Empty @@ -54,22 +44,6 @@ internal class TokenListOperations( ) } - private fun Raise.createTokenList(): TokenList { - val nonEmptyCurrencies = tokens.toNonEmptyListOrNull() - ?: return TokenList.Empty - - val isAnyTokenLoading = nonEmptyCurrencies.any { it.value is CryptoCurrencyStatus.Loading } - val fiatBalanceOperations = TokenListFiatBalanceOperations(nonEmptyCurrencies, isAnyTokenLoading) - - return createTokenList( - currencies = nonEmptyCurrencies, - fiatBalance = fiatBalanceOperations.calculateFiatBalance(), - isAnyTokenLoading = isAnyTokenLoading, - isGrouped = false, - isSortedByBalance = false, - ) - } - private fun Raise.createTokenList( currencies: NonEmptyList, fiatBalance: TotalFiatBalance, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt index f3829783da..897b44ae92 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt @@ -1,12 +1,12 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase -import com.tangem.domain.tokens.GetNodlTokenListUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory +import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber @@ -23,7 +23,7 @@ internal class SingleWalletWithTokenContentLoader( private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val walletWithFundsChecker: WalletWithFundsChecker, private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, - private val getNodlTokenListUseCase: GetNodlTokenListUseCase, + private val tokenListStore: MultiWalletTokenListStore, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, ) : WalletContentLoader(id = userWallet.walletId) { @@ -36,7 +36,7 @@ internal class SingleWalletWithTokenContentLoader( clickIntents = clickIntents, tokenListAnalyticsSender = tokenListAnalyticsSender, walletWithFundsChecker = walletWithFundsChecker, - getNodlTokenListUseCase = getNodlTokenListUseCase, + tokenListStore = tokenListStore, getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase, runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase, ), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt index 5d820846c7..1c433dc756 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt @@ -1,12 +1,12 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase -import com.tangem.domain.tokens.GetNodlTokenListUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory +import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents @@ -19,7 +19,7 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor( private val tokenListAnalyticsSender: TokenListAnalyticsSender, private val walletWithFundsChecker: WalletWithFundsChecker, private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, - private val getNodlTokenListUseCase: GetNodlTokenListUseCase, + private val tokenListStore: MultiWalletTokenListStore, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, @@ -33,7 +33,7 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor( tokenListAnalyticsSender = tokenListAnalyticsSender, walletWithFundsChecker = walletWithFundsChecker, getMultiWalletWarningsFactory = getMultiWalletWarningsFactory, - getNodlTokenListUseCase = getNodlTokenListUseCase, + tokenListStore = tokenListStore, getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase, walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletWithTokenListSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletWithTokenListSubscriber.kt index c8848d06e9..2d37fea506 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletWithTokenListSubscriber.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/SingleWalletWithTokenListSubscriber.kt @@ -2,23 +2,21 @@ package com.tangem.feature.wallet.presentation.wallet.subscribers import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.core.lce.LceFlow -import com.tangem.domain.core.utils.toLce -import com.tangem.domain.tokens.GetNodlTokenListUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.tokens.model.TokenList import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender +import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.map @Suppress("LongParameterList") internal class SingleWalletWithTokenListSubscriber( private val userWallet: UserWallet, - private val getNodlTokenListUseCase: GetNodlTokenListUseCase, + private val tokenListStore: MultiWalletTokenListStore, stateHolder: WalletStateController, clickIntents: WalletClickIntents, tokenListAnalyticsSender: TokenListAnalyticsSender, @@ -35,9 +33,9 @@ internal class SingleWalletWithTokenListSubscriber( runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase, ) { - override fun tokenListFlow(coroutineScope: CoroutineScope): LceFlow = - getNodlTokenListUseCase( - userWallet.walletId, - ) - .map { it.toLce() } + override fun tokenListFlow(coroutineScope: CoroutineScope): LceFlow { + tokenListStore.addIfNot(userWallet.walletId, coroutineScope) + + return tokenListStore.getOrThrow(userWallet.walletId) + } } \ No newline at end of file