From 6c16caedba28f3e21f303df2a3dd71476fb8294b Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 1 Apr 2025 14:42:30 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/ManageTokensDomainModule.kt | 6 ++ .../tap/di/domain/MarketsDomainModule.kt | 6 ++ .../tap/di/domain/TokensDomainModule.kt | 41 +++++++- .../tap/di/domain/TransactionDomainModule.kt | 6 ++ .../di/NetworksStatusesStoreModule.kt | 3 + .../tangem/domain/common/CardTypesResolver.kt | 2 + .../domain/common/TangemCardTypesResolver.kt | 2 + domain/manage-tokens/build.gradle.kts | 3 +- .../managetokens/SaveManagedTokensUseCase.kt | 23 ++++- domain/markets/build.gradle.kts | 9 +- .../domain/markets/SaveMarketTokensUseCase.kt | 24 ++++- .../tokens/AddCryptoCurrenciesUseCase.kt | 28 ++++-- .../tokens/FetchCardTokenListUseCase.kt | 18 +++- .../tokens/FetchCurrencyStatusUseCase.kt | 18 +++- .../domain/tokens/FetchTokenListUseCase.kt | 21 +++- .../UpdateDelayedNetworkStatusUseCase.kt | 18 +++- .../BaseCurrencyStatusOperations.kt | 95 ++++++++++++------- .../CachedCurrenciesStatusesOperations.kt | 12 ++- ...PrimaryCurrencyStatusUpdatesUseCaseTest.kt | 1 + domain/transaction/build.gradle.kts | 1 + .../usecase/AssociateAssetUseCase.kt | 26 ++++- .../wallet/child/wallet/model/WalletModel.kt | 7 ++ 22 files changed, 288 insertions(+), 82 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt index 6734b93464..f6467cc073 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt @@ -4,7 +4,9 @@ import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.managetokens.* import com.tangem.domain.managetokens.repository.CustomTokensRepository import com.tangem.domain.managetokens.repository.ManageTokensRepository +import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.tokens.repository.QuotesRepository @@ -70,6 +72,8 @@ internal object ManageTokensDomainModule { derivationsRepository: DerivationsRepository, stakingRepository: StakingRepository, quotesRepository: QuotesRepository, + multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + tokensFeatureToggles: TokensFeatureToggles, ): SaveManagedTokensUseCase { return SaveManagedTokensUseCase( customTokensRepository = customTokensRepository, @@ -79,6 +83,8 @@ internal object ManageTokensDomainModule { derivationsRepository = derivationsRepository, stakingRepository = stakingRepository, quotesRepository = quotesRepository, + multiNetworkStatusFetcher = multiNetworkStatusFetcher, + tokensFeatureToggles = tokensFeatureToggles, ) } diff --git a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt index 72b1e2451c..3a568db5e6 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt @@ -4,7 +4,9 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.markets.* import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.tokens.repository.QuotesRepository @@ -60,6 +62,8 @@ object MarketsDomainModule { networksRepository: NetworksRepository, stakingRepository: StakingRepository, quotesRepository: QuotesRepository, + multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + tokensFeatureToggles: TokensFeatureToggles, ): SaveMarketTokensUseCase { return SaveMarketTokensUseCase( derivationsRepository = derivationsRepository, @@ -68,6 +72,8 @@ object MarketsDomainModule { networksRepository = networksRepository, stakingRepository = stakingRepository, quotesRepository = quotesRepository, + multiNetworkStatusFetcher = multiNetworkStatusFetcher, + tokensFeatureToggles = tokensFeatureToggles, ) } 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 fc92ca427e..237b83807e 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 @@ -3,6 +3,8 @@ package com.tangem.tap.di.domain import com.tangem.core.configtoggle.feature.FeatureTogglesManager import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher +import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier +import com.tangem.domain.networks.single.SingleNetworkStatusFetcher import com.tangem.domain.networks.single.SingleNetworkStatusSupplier import com.tangem.domain.promo.PromoRepository import com.tangem.domain.staking.repositories.StakingRepository @@ -32,12 +34,16 @@ internal object TokensDomainModule { networksRepository: NetworksRepository, stakingRepository: StakingRepository, quotesRepository: QuotesRepository, + multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + tokensFeatureToggles: TokensFeatureToggles, ): AddCryptoCurrenciesUseCase { return AddCryptoCurrenciesUseCase( currenciesRepository = currenciesRepository, networksRepository = networksRepository, stakingRepository = stakingRepository, quotesRepository = quotesRepository, + multiNetworkStatusFetcher = multiNetworkStatusFetcher, + tokensFeatureToggles = tokensFeatureToggles, ) } @@ -48,12 +54,16 @@ internal object TokensDomainModule { quotesRepository: QuotesRepository, networksRepository: NetworksRepository, stakingRepository: StakingRepository, + multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + tokensFeatureToggles: TokensFeatureToggles, ): FetchTokenListUseCase { return FetchTokenListUseCase( currenciesRepository = currenciesRepository, networksRepository = networksRepository, quotesRepository = quotesRepository, stakingRepository = stakingRepository, + multiNetworkStatusFetcher = multiNetworkStatusFetcher, + tokensFeatureToggles = tokensFeatureToggles, ) } @@ -157,12 +167,16 @@ internal object TokensDomainModule { quotesRepository: QuotesRepository, networksRepository: NetworksRepository, stakingRepository: StakingRepository, + singleNetworkStatusFetcher: SingleNetworkStatusFetcher, + tokensFeatureToggles: TokensFeatureToggles, ): FetchCurrencyStatusUseCase { return FetchCurrencyStatusUseCase( - currenciesRepository, - networksRepository, - quotesRepository, - stakingRepository, + currenciesRepository = currenciesRepository, + networksRepository = networksRepository, + quotesRepository = quotesRepository, + stakingRepository = stakingRepository, + singleNetworkStatusFetcher = singleNetworkStatusFetcher, + tokensFeatureToggles = tokensFeatureToggles, ) } @@ -173,8 +187,17 @@ internal object TokensDomainModule { quotesRepository: QuotesRepository, networksRepository: NetworksRepository, stakingRepository: StakingRepository, + multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + tokensFeatureToggles: TokensFeatureToggles, ): FetchCardTokenListUseCase { - return FetchCardTokenListUseCase(currenciesRepository, networksRepository, quotesRepository, stakingRepository) + return FetchCardTokenListUseCase( + currenciesRepository = currenciesRepository, + networksRepository = networksRepository, + quotesRepository = quotesRepository, + stakingRepository = stakingRepository, + multiNetworkStatusFetcher = multiNetworkStatusFetcher, + tokensFeatureToggles = tokensFeatureToggles, + ) } @Provides @@ -284,9 +307,13 @@ internal object TokensDomainModule { @Singleton fun provideUpdateDelayedCurrencyStatusUseCase( networksRepository: NetworksRepository, + singleNetworkStatusFetcher: SingleNetworkStatusFetcher, + tokensFeatureToggles: TokensFeatureToggles, ): UpdateDelayedNetworkStatusUseCase { return UpdateDelayedNetworkStatusUseCase( networksRepository = networksRepository, + singleNetworkStatusFetcher = singleNetworkStatusFetcher, + tokensFeatureToggles = tokensFeatureToggles, ) } @@ -362,6 +389,7 @@ internal object TokensDomainModule { networksRepository: NetworksRepository, stakingRepository: StakingRepository, singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + multiNetworkStatusSupplier: MultiNetworkStatusSupplier, multiNetworkStatusFetcher: MultiNetworkStatusFetcher, ): BaseCurrenciesStatusesOperations { return CachedCurrenciesStatusesOperations( @@ -370,6 +398,7 @@ internal object TokensDomainModule { networksRepository = networksRepository, stakingRepository = stakingRepository, singleNetworkStatusSupplier = singleNetworkStatusSupplier, + multiNetworkStatusSupplier = multiNetworkStatusSupplier, multiNetworkStatusFetcher = multiNetworkStatusFetcher, tokensFeatureToggles = tokensFeatureToggles, ) @@ -384,6 +413,7 @@ internal object TokensDomainModule { networksRepository: NetworksRepository, stakingRepository: StakingRepository, singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + multiNetworkStatusSupplier: MultiNetworkStatusSupplier, multiNetworkStatusFetcher: MultiNetworkStatusFetcher, ): BaseCurrencyStatusOperations { return CachedCurrenciesStatusesOperations( @@ -392,6 +422,7 @@ internal object TokensDomainModule { networksRepository = networksRepository, stakingRepository = stakingRepository, singleNetworkStatusSupplier = singleNetworkStatusSupplier, + multiNetworkStatusSupplier = multiNetworkStatusSupplier, multiNetworkStatusFetcher = multiNetworkStatusFetcher, tokensFeatureToggles = tokensFeatureToggles, ) diff --git a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt index 507a284a76..a693b4963e 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt @@ -2,6 +2,8 @@ package com.tangem.tap.di.domain import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.demo.DemoConfig +import com.tangem.domain.networks.single.SingleNetworkStatusSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.transaction.FeeRepository @@ -49,12 +51,16 @@ internal object TransactionDomainModule { walletManagersFacade: WalletManagersFacade, currenciesRepository: CurrenciesRepository, networksRepository: NetworksRepository, + singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): AssociateAssetUseCase { return AssociateAssetUseCase( cardSdkConfigRepository = cardSdkConfigRepository, walletManagersFacade = walletManagersFacade, currenciesRepository = currenciesRepository, networksRepository = networksRepository, + singleNetworkStatusSupplier = singleNetworkStatusSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) } diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/NetworksStatusesStoreModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/NetworksStatusesStoreModule.kt index b258b16a24..f0cabaf025 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/NetworksStatusesStoreModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/NetworksStatusesStoreModule.kt @@ -20,11 +20,13 @@ import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob +import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) internal object NetworksStatusesStoreModule { + @Singleton @Provides fun providePersistenceNetworksStatusesStore( @NetworkMoshi moshi: Moshi, @@ -42,6 +44,7 @@ internal object NetworksStatusesStoreModule { ) } + @Singleton @Provides fun provideNetworksStatusesStore( persistenceNetworksStatusesStore: DataStore>>, diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt b/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt index 29ce08c107..a42c4a5b8d 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt @@ -26,6 +26,8 @@ interface CardTypesResolver { fun isDevKit(): Boolean + fun isSingleWallet(): Boolean + fun isSingleWalletWithToken(): Boolean fun isMultiwalletAllowed(): Boolean diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt index 46035bd37d..5b997342b9 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt @@ -50,6 +50,8 @@ internal class TangemCardTypesResolver( override fun isDevKit(): Boolean = card.batchId == DEV_KIT_CARD_BATCH_ID + override fun isSingleWallet(): Boolean = !isMultiwalletAllowed() && !isSingleWalletWithToken() && !isVisaWallet() + override fun isSingleWalletWithToken(): Boolean = walletData?.token != null && !isMultiwalletAllowed() override fun isMultiwalletAllowed(): Boolean { diff --git a/domain/manage-tokens/build.gradle.kts b/domain/manage-tokens/build.gradle.kts index da0b3d8595..ef5facece8 100644 --- a/domain/manage-tokens/build.gradle.kts +++ b/domain/manage-tokens/build.gradle.kts @@ -11,8 +11,9 @@ android { dependencies { /* Domain */ - api(projects.domain.manageTokens.models) api(projects.domain.core) + api(projects.domain.manageTokens.models) + api(projects.domain.networks) implementation(projects.domain.wallets.models) implementation(projects.domain.tokens.models) implementation(projects.domain.staking) diff --git a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt index 1cec10d0c1..9f78e90712 100644 --- a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt +++ b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt @@ -5,7 +5,9 @@ import arrow.core.flatten import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.managetokens.model.ManagedCryptoCurrency import com.tangem.domain.managetokens.repository.CustomTokensRepository +import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.repository.CurrenciesRepository @@ -23,6 +25,8 @@ class SaveManagedTokensUseCase( private val derivationsRepository: DerivationsRepository, private val stakingRepository: StakingRepository, private val quotesRepository: QuotesRepository, + private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke( @@ -92,11 +96,20 @@ class SaveManagedTokensUseCase( val networkToUpdate = currenciesToAdd.map { it.network } .subtract(existingCurrencies.map { it.network }.toSet()) - networksRepository.getNetworkStatusesSync( - userWalletId = userWalletId, - networks = networksToUpdate + networkToUpdate, - refresh = true, - ) + if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + multiNetworkStatusFetcher( + MultiNetworkStatusFetcher.Params( + userWalletId = userWalletId, + networks = networksToUpdate + networkToUpdate, + ), + ) + } else { + networksRepository.getNetworkStatusesSync( + userWalletId = userWalletId, + networks = networksToUpdate + networkToUpdate, + refresh = true, + ) + } } private suspend fun refreshUpdatedYieldBalances( diff --git a/domain/markets/build.gradle.kts b/domain/markets/build.gradle.kts index f5a22e3d18..6ba3a16199 100644 --- a/domain/markets/build.gradle.kts +++ b/domain/markets/build.gradle.kts @@ -15,12 +15,13 @@ dependencies { api(projects.domain.appCurrency.models) api(projects.domain.card) api(projects.domain.core) - api(projects.domain.markets.models) - api(projects.domain.wallets.models) - api(projects.domain.models) api(projects.domain.legacy) - api(projects.domain.wallets) + api(projects.domain.markets.models) + api(projects.domain.models) + api(projects.domain.networks) api(projects.domain.staking) + api(projects.domain.wallets) + api(projects.domain.wallets.models) implementation(projects.domain.tokens.models) implementation(projects.domain.tokens) diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt index 352fb55d85..4d086677b5 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt @@ -3,7 +3,9 @@ package com.tangem.domain.markets import arrow.core.Either import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.repository.CurrenciesRepository @@ -20,6 +22,7 @@ import com.tangem.domain.wallets.models.UserWalletId * [REDACTED_AUTHOR] */ +@Suppress("LongParameterList") class SaveMarketTokensUseCase( private val derivationsRepository: DerivationsRepository, private val marketsTokenRepository: MarketsTokenRepository, @@ -27,6 +30,8 @@ class SaveMarketTokensUseCase( private val networksRepository: NetworksRepository, private val stakingRepository: StakingRepository, private val quotesRepository: QuotesRepository, + private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke( @@ -73,11 +78,20 @@ class SaveMarketTokensUseCase( } private suspend fun refreshUpdatedNetworks(userWalletId: UserWalletId, addedCurrencies: List) { - networksRepository.getNetworkStatusesSync( - userWalletId = userWalletId, - networks = addedCurrencies.map(CryptoCurrency::network).toSet(), - refresh = true, - ) + if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + multiNetworkStatusFetcher( + MultiNetworkStatusFetcher.Params( + userWalletId = userWalletId, + networks = addedCurrencies.map(CryptoCurrency::network).toSet(), + ), + ) + } else { + networksRepository.getNetworkStatusesSync( + userWalletId = userWalletId, + networks = addedCurrencies.map(CryptoCurrency::network).toSet(), + refresh = true, + ) + } } private suspend fun refreshUpdatedYieldBalances( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt index 370a29ee8e..2b30de2785 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt @@ -5,6 +5,7 @@ import arrow.core.raise.Raise import arrow.core.raise.catch import arrow.core.raise.either import arrow.core.toNonEmptyListOrNull +import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network @@ -25,6 +26,8 @@ class AddCryptoCurrenciesUseCase( private val networksRepository: NetworksRepository, private val stakingRepository: StakingRepository, private val quotesRepository: QuotesRepository, + private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + private val tokensFeatureToggles: TokensFeatureToggles, ) { /** @@ -132,16 +135,25 @@ class AddCryptoCurrenciesUseCase( val networkToUpdate = currenciesToAdd.map { it.network } .subtract(existingCurrencies.map { it.network }.toSet()) - catch( - { - networksRepository.getNetworkStatusesSync( + if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + multiNetworkStatusFetcher( + MultiNetworkStatusFetcher.Params( userWalletId = userWalletId, networks = networksToUpdate + networkToUpdate, - refresh = true, - ) - }, - ) { - raise(it) + ), + ) + } else { + catch( + { + networksRepository.getNetworkStatusesSync( + userWalletId = userWalletId, + networks = networksToUpdate + networkToUpdate, + refresh = true, + ) + }, + ) { + raise(it) + } } } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt index 9bac51630e..2098e11d7b 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCardTokenListUseCase.kt @@ -4,6 +4,7 @@ import arrow.core.Either import arrow.core.raise.Raise import arrow.core.raise.catch import arrow.core.raise.either +import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.tokens.model.CryptoCurrency @@ -21,6 +22,8 @@ class FetchCardTokenListUseCase( private val networksRepository: NetworksRepository, private val quotesRepository: QuotesRepository, private val stakingRepository: StakingRepository, + private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke(userWalletId: UserWalletId, refresh: Boolean = false): Either { @@ -73,10 +76,17 @@ class FetchCardTokenListUseCase( networks: Set, refresh: Boolean, ) { - catch( - block = { networksRepository.getNetworkStatusesSync(userWalletId, networks, refresh) }, - catch = { raise(TokenListError.DataError(it)) }, - ) + if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + multiNetworkStatusFetcher( + MultiNetworkStatusFetcher.Params(userWalletId = userWalletId, networks = networks), + ) + .mapLeft { TokenListError.DataError(it) } + } else { + catch( + block = { networksRepository.getNetworkStatusesSync(userWalletId, networks, refresh) }, + catch = { raise(TokenListError.DataError(it)) }, + ) + } } private suspend fun fetchQuotes(currenciesIds: Set, refresh: Boolean) { diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt index a6455893a6..fa725b8c75 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchCurrencyStatusUseCase.kt @@ -4,6 +4,7 @@ import arrow.core.Either import arrow.core.raise.Raise import arrow.core.raise.catch import arrow.core.raise.either +import com.tangem.domain.networks.single.SingleNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.tokens.error.CurrencyStatusError import com.tangem.domain.tokens.model.CryptoCurrency @@ -31,6 +32,8 @@ class FetchCurrencyStatusUseCase( private val networksRepository: NetworksRepository, private val quotesRepository: QuotesRepository, private val stakingRepository: StakingRepository, + private val singleNetworkStatusFetcher: SingleNetworkStatusFetcher, + private val tokensFeatureToggles: TokensFeatureToggles, ) { /** @@ -116,10 +119,17 @@ class FetchCurrencyStatusUseCase( network: Network, refresh: Boolean, ) { - catch( - block = { networksRepository.getNetworkStatusesSync(userWalletId, setOf(network), refresh) }, - ) { - raise(CurrencyStatusError.DataError(it)) + if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + singleNetworkStatusFetcher( + params = SingleNetworkStatusFetcher.Params(userWalletId = userWalletId, network = network), + ) + .mapLeft { CurrencyStatusError.DataError(it) } + } else { + catch( + block = { networksRepository.getNetworkStatusesSync(userWalletId, setOf(network), refresh) }, + ) { + raise(CurrencyStatusError.DataError(it)) + } } } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt index 408c4e81ca..5344fecfd0 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt @@ -6,6 +6,7 @@ import arrow.core.raise.catch import arrow.core.raise.either import arrow.core.raise.ensureNotNull import arrow.core.toNonEmptyListOrNull +import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.tokens.model.CryptoCurrency @@ -33,6 +34,8 @@ class FetchTokenListUseCase( private val networksRepository: NetworksRepository, private val quotesRepository: QuotesRepository, private val stakingRepository: StakingRepository, + private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + private val tokensFeatureToggles: TokensFeatureToggles, ) { /** @@ -104,10 +107,20 @@ class FetchTokenListUseCase( networks: Set, refresh: Boolean, ) { - catch( - block = { networksRepository.getNetworkStatusesSync(userWalletId, networks, refresh) }, - ) { - raise(TokenListError.DataError(it)) + if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + if (refresh) { + multiNetworkStatusFetcher( + params = MultiNetworkStatusFetcher.Params(userWalletId, networks), + ) + .mapLeft { TokenListError.DataError(it) } + .bind() + } + } else { + catch( + block = { networksRepository.getNetworkStatusesSync(userWalletId, networks, refresh) }, + ) { + raise(TokenListError.DataError(it)) + } } } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/UpdateDelayedNetworkStatusUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/UpdateDelayedNetworkStatusUseCase.kt index 26d641497a..5be8ae95ef 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/UpdateDelayedNetworkStatusUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/UpdateDelayedNetworkStatusUseCase.kt @@ -4,6 +4,7 @@ import arrow.core.Either import arrow.core.raise.Raise import arrow.core.raise.catch import arrow.core.raise.either +import com.tangem.domain.networks.single.SingleNetworkStatusFetcher import com.tangem.domain.tokens.error.CurrencyStatusError import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.repository.NetworksRepository @@ -20,6 +21,8 @@ import kotlinx.coroutines.delay class UpdateDelayedNetworkStatusUseCase( private val networksRepository: NetworksRepository, + private val singleNetworkStatusFetcher: SingleNetworkStatusFetcher, + private val tokensFeatureToggles: TokensFeatureToggles, ) { /** @@ -47,10 +50,17 @@ class UpdateDelayedNetworkStatusUseCase( network: Network, refresh: Boolean, ) { - catch( - block = { networksRepository.getNetworkStatusesSync(userWalletId, setOf(network), refresh) }, - ) { - raise(CurrencyStatusError.DataError(it)) + if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + singleNetworkStatusFetcher( + params = SingleNetworkStatusFetcher.Params(userWalletId = userWalletId, network = network), + ) + .mapLeft { CurrencyStatusError.DataError(it) } + } else { + catch( + block = { networksRepository.getNetworkStatusesSync(userWalletId, setOf(network), refresh) }, + ) { + raise(CurrencyStatusError.DataError(it)) + } } } } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt index f765bd2dec..ac008a8ac8 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt @@ -6,9 +6,14 @@ import arrow.core.raise.catch import arrow.core.raise.either import arrow.core.raise.recover import com.tangem.domain.core.utils.EitherFlow +import com.tangem.domain.networks.multi.MultiNetworkStatusProducer +import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier +import com.tangem.domain.networks.single.SingleNetworkStatusProducer +import com.tangem.domain.networks.single.SingleNetworkStatusSupplier import com.tangem.domain.staking.model.stakekit.YieldBalance import com.tangem.domain.staking.model.stakekit.YieldBalanceList import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.model.* import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations.Error import com.tangem.domain.tokens.repository.CurrenciesRepository @@ -17,7 +22,6 @@ import com.tangem.domain.tokens.repository.QuotesRepository import com.tangem.domain.tokens.utils.CurrencyStatusProxyCreator import com.tangem.domain.wallets.models.UserWalletId import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch /** * Base operations for working with currency status @@ -29,12 +33,15 @@ import kotlinx.coroutines.launch * [REDACTED_AUTHOR] */ -@Suppress("LargeClass") +@Suppress("LargeClass", "LongParameterList") abstract class BaseCurrencyStatusOperations( private val currenciesRepository: CurrenciesRepository, private val quotesRepository: QuotesRepository, private val networksRepository: NetworksRepository, private val stakingRepository: StakingRepository, + private val multiNetworkStatusSupplier: MultiNetworkStatusSupplier, + private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { protected val currencyStatusProxyCreator = CurrencyStatusProxyCreator(stakingRepository) @@ -102,26 +109,13 @@ abstract class BaseCurrencyStatusOperations( val yieldBalanceFlow = getYieldBalance(userWalletId = userWalletId, cryptoCurrency = currency) - return channelFlow { - launch { - fetchComponents( - userWalletId = userWalletId, - networks = nonEmptySetOf(currency.network), - currenciesIds = nonEmptySetOf(currency.id), - currencies = nonEmptyListOf(currency), - ) - } - - combine(quoteFlow, statusFlow, yieldBalanceFlow) { maybeQuote, maybeNetworkStatus, maybeYieldBalance -> - currencyStatusProxyCreator.createCurrencyStatus( - currency = currency, - maybeQuote = maybeQuote, - maybeNetworkStatus = maybeNetworkStatus, - maybeYieldBalance = maybeYieldBalance, - ) - } - .onEach(::send) - .launchIn(this) + return combine(quoteFlow, statusFlow, yieldBalanceFlow) { maybeQuote, maybeNetworkStatus, maybeYieldBalance -> + currencyStatusProxyCreator.createCurrencyStatus( + currency = currency, + maybeQuote = maybeQuote, + maybeNetworkStatus = maybeNetworkStatus, + maybeYieldBalance = maybeYieldBalance, + ) } } @@ -179,12 +173,25 @@ abstract class BaseCurrencyStatusOperations( } val quote = cryptoCurrencyId.rawCurrencyId?.let { quotesRepository.getQuoteSync(it) }?.right() ?: Error.EmptyQuotes.left() - val networkStatuses = + + val networkStatuses = if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + singleNetworkStatusSupplier( + params = SingleNetworkStatusProducer.Params( + userWalletId = userWalletId, + network = currency.network, + ), + ) + .firstOrNull() + .right() + } else { networksRepository.getNetworkStatusesSync( userWalletId = userWalletId, networks = setOf(currency.network), refresh = false, - ).firstOrNull { it.network == currency.network }.right() + ) + .firstOrNull { it.network == currency.network } + .right() + } val yieldBalances = getYieldBalanceSync(userWalletId, currency) @@ -231,8 +238,17 @@ abstract class BaseCurrencyStatusOperations( val (networks, currenciesIds) = getIds(nonEmptyCurrencies) val rawIds = currenciesIds.mapNotNull { it.rawCurrencyId }.toSet() val quotes = quotesRepository.getQuotesSync(rawIds, false).right() - val networkStatuses = + + val networkStatuses = if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + multiNetworkStatusSupplier( + params = MultiNetworkStatusProducer.Params(userWalletId = userWalletId), + ) + .firstOrNull() + .orEmpty() + .right() + } else { networksRepository.getNetworkStatusesSync(userWalletId, networks, false).right() + } val yieldBalances = getYieldBalancesSync(userWalletId, nonEmptyCurrencies) return currencyStatusProxyCreator.createCurrenciesStatuses( @@ -259,14 +275,27 @@ abstract class BaseCurrencyStatusOperations( }, catch = { Error.DataError(it).left() }, ) - val networkStatus = catch( - block = { - networksRepository.getNetworkStatusesSync(userWalletId, setOf(currency.network)) - .firstOrNull { it.network == currency.network } - .right() - }, - catch = { Error.DataError(it).left() }, - ) + + val networkStatus = if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + singleNetworkStatusSupplier( + params = SingleNetworkStatusProducer.Params( + userWalletId = userWalletId, + network = currency.network, + ), + ) + .firstOrNull() + .right() + } else { + catch( + block = { + networksRepository.getNetworkStatusesSync(userWalletId, setOf(currency.network)) + .firstOrNull { it.network == currency.network } + .right() + }, + catch = { Error.DataError(it).left() }, + ) + } + val yieldBalances = getYieldBalanceSync(userWalletId, currency) return currencyStatusProxyCreator.createCurrencyStatus( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt index b4cf9ec8c4..b43e518a08 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt @@ -11,6 +11,7 @@ import com.tangem.domain.core.utils.EitherFlow import com.tangem.domain.core.utils.lceContent import com.tangem.domain.core.utils.lceError import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher +import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier import com.tangem.domain.networks.single.SingleNetworkStatusProducer import com.tangem.domain.networks.single.SingleNetworkStatusSupplier import com.tangem.domain.staking.model.stakekit.YieldBalance @@ -36,10 +37,19 @@ class CachedCurrenciesStatusesOperations( private val networksRepository: NetworksRepository, private val stakingRepository: StakingRepository, private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + multiNetworkStatusSupplier: MultiNetworkStatusSupplier, private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, private val tokensFeatureToggles: TokensFeatureToggles, ) : BaseCurrenciesStatusesOperations, - BaseCurrencyStatusOperations(currenciesRepository, quotesRepository, networksRepository, stakingRepository) { + BaseCurrencyStatusOperations( + currenciesRepository = currenciesRepository, + quotesRepository = quotesRepository, + networksRepository = networksRepository, + stakingRepository = stakingRepository, + multiNetworkStatusSupplier = multiNetworkStatusSupplier, + singleNetworkStatusSupplier = singleNetworkStatusSupplier, + tokensFeatureToggles = tokensFeatureToggles, + ) { override fun getCurrenciesStatuses( userWalletId: UserWalletId, diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/GetPrimaryCurrencyStatusUpdatesUseCaseTest.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/GetPrimaryCurrencyStatusUpdatesUseCaseTest.kt index 975da996c8..3e5e99c917 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/GetPrimaryCurrencyStatusUpdatesUseCaseTest.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/GetPrimaryCurrencyStatusUpdatesUseCaseTest.kt @@ -183,6 +183,7 @@ internal class GetPrimaryCurrencyStatusUpdatesUseCaseTest { }, singleNetworkStatusSupplier = mockk(), multiNetworkStatusFetcher = mockk(), + multiNetworkStatusSupplier = mockk(), ), dispatchers = dispatchers, ) diff --git a/domain/transaction/build.gradle.kts b/domain/transaction/build.gradle.kts index 154228ce40..dbae9c5373 100644 --- a/domain/transaction/build.gradle.kts +++ b/domain/transaction/build.gradle.kts @@ -32,4 +32,5 @@ dependencies { implementation(projects.domain.transaction.models) implementation(projects.domain.demo) implementation(projects.domain.card) + api(projects.domain.networks) } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/AssociateAssetUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/AssociateAssetUseCase.kt index b910f1c01c..3df20fa08d 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/AssociateAssetUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/AssociateAssetUseCase.kt @@ -5,6 +5,9 @@ import arrow.core.raise.catch import arrow.core.raise.either import com.tangem.blockchain.extensions.SimpleResult import com.tangem.domain.card.repository.CardSdkConfigRepository +import com.tangem.domain.networks.single.SingleNetworkStatusProducer +import com.tangem.domain.networks.single.SingleNetworkStatusSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus import com.tangem.domain.tokens.model.NetworkStatus @@ -14,12 +17,15 @@ import com.tangem.domain.transaction.error.AssociateAssetError import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWalletId import com.tangem.utils.isNullOrZero +import kotlinx.coroutines.flow.firstOrNull class AssociateAssetUseCase( private val cardSdkConfigRepository: CardSdkConfigRepository, private val walletManagersFacade: WalletManagersFacade, private val currenciesRepository: CurrenciesRepository, private val networksRepository: NetworksRepository, + private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke( @@ -53,13 +59,25 @@ class AssociateAssetUseCase( } private suspend fun isBalanceZero(userWalletId: UserWalletId, currency: CryptoCurrency): Boolean { - val networkStatus = networksRepository.getNetworkStatusesSync( - userWalletId = userWalletId, - networks = setOf(currency.network), - ).find { it.network == currency.network } + val networkStatus = if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) { + singleNetworkStatusSupplier( + params = SingleNetworkStatusProducer.Params( + userWalletId = userWalletId, + network = currency.network, + ), + ) + .firstOrNull() + } else { + networksRepository.getNetworkStatusesSync( + userWalletId = userWalletId, + networks = setOf(currency.network), + ).find { it.network == currency.network } + } + val networkCoinAmountStatus = (networkStatus?.value as? NetworkStatus.Verified) ?.amounts ?.get(currency.id) + return networkCoinAmountStatus is CryptoCurrencyAmountStatus.Loaded && networkCoinAmountStatus.value.isNullOrZero() } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index 80175b7ddf..5359f89098 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -10,8 +10,10 @@ import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.nft.FetchNFTCollectionsUseCase import com.tangem.domain.settings.* +import com.tangem.domain.tokens.FetchCurrencyStatusUseCase import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.repository.WalletsRepository @@ -79,6 +81,7 @@ internal class WalletModel @Inject constructor( private val analyticsEventsHandler: AnalyticsEventHandler, private val fetchNFTCollectionsUseCase: FetchNFTCollectionsUseCase, private val walletsRepository: WalletsRepository, + private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase, val screenLifecycleProvider: ScreenLifecycleProvider, val innerWalletRouter: InnerWalletRouter, ) : Model() { @@ -353,6 +356,10 @@ internal class WalletModel @Inject constructor( coroutineScope = modelScope, ) + if (action.selectedWallet.scanResponse.cardTypesResolver.isSingleWallet()) { + fetchCurrencyStatusUseCase(userWalletId = action.selectedWallet.walletId) + } + if (action.wallets.size > 1 && isWalletsScrollPreviewEnabled()) { withContext(dispatchers.io) { delay(timeMillis = 1_800) }