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 38eae7aec7..43391888d5 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 @@ -8,6 +8,7 @@ import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletmanager.WalletManagersFacade @@ -75,6 +76,7 @@ internal object ManageTokensDomainModule { multiNetworkStatusFetcher: MultiNetworkStatusFetcher, multiQuoteStatusFetcher: MultiQuoteStatusFetcher, multiYieldBalanceFetcher: MultiYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, tokensFeatureToggles: TokensFeatureToggles, ): SaveManagedTokensUseCase { return SaveManagedTokensUseCase( @@ -86,6 +88,7 @@ internal object ManageTokensDomainModule { multiNetworkStatusFetcher = multiNetworkStatusFetcher, multiQuoteStatusFetcher = multiQuoteStatusFetcher, multiYieldBalanceFetcher = multiYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, tokensFeatureToggles = tokensFeatureToggles, ) } diff --git a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt index 5f525bc14c..dcedc27851 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt @@ -5,6 +5,8 @@ import com.tangem.domain.nft.* import com.tangem.domain.nft.repository.NFTRepository import com.tangem.domain.quotes.single.SingleQuoteStatusFetcher import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.utils.coroutines.CoroutineDispatcherProvider @@ -33,9 +35,13 @@ internal object NFTDomainModule { fun providesFetchNFTCollectionsUseCase( currenciesRepository: CurrenciesRepository, nftRepository: NFTRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): FetchNFTCollectionsUseCase = FetchNFTCollectionsUseCase( currenciesRepository = currenciesRepository, nftRepository = nftRepository, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) @Provides @@ -43,9 +49,13 @@ internal object NFTDomainModule { fun providesRefreshAllNFTUseCase( currenciesRepository: CurrenciesRepository, nftRepository: NFTRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): RefreshAllNFTUseCase = RefreshAllNFTUseCase( currenciesRepository = currenciesRepository, nftRepository = nftRepository, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) @Provides @@ -118,8 +128,16 @@ internal object NFTDomainModule { walletsRepository: WalletsRepository, nftRepository: NFTRepository, currenciesRepository: CurrenciesRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): DisableWalletNFTUseCase { - return DisableWalletNFTUseCase(walletsRepository, nftRepository, currenciesRepository) + return DisableWalletNFTUseCase( + walletsRepository = walletsRepository, + nftRepository = nftRepository, + currenciesRepository = currenciesRepository, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, + ) } @Provides 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 359aca0f8d..f83422933e 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 @@ -45,6 +45,7 @@ internal object TokensDomainModule { multiNetworkStatusFetcher: MultiNetworkStatusFetcher, multiQuoteStatusFetcher: MultiQuoteStatusFetcher, singleYieldBalanceFetcher: SingleYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, tokensFeatureToggles: TokensFeatureToggles, ): AddCryptoCurrenciesUseCase { return AddCryptoCurrenciesUseCase( @@ -53,6 +54,7 @@ internal object TokensDomainModule { multiNetworkStatusFetcher = multiNetworkStatusFetcher, multiQuoteStatusFetcher = multiQuoteStatusFetcher, singleYieldBalanceFetcher = singleYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, tokensFeatureToggles = tokensFeatureToggles, ) } @@ -108,8 +110,15 @@ internal object TokensDomainModule { fun provideRemoveCurrencyUseCase( currenciesRepository: CurrenciesRepository, walletManagersFacade: WalletManagersFacade, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): RemoveCurrencyUseCase { - return RemoveCurrencyUseCase(currenciesRepository, walletManagersFacade) + return RemoveCurrencyUseCase( + currenciesRepository = currenciesRepository, + walletManagersFacade = walletManagersFacade, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, + ) } @Provides @@ -146,6 +155,8 @@ internal object TokensDomainModule { currencyChecksRepository: CurrencyChecksRepository, dispatchers: CoroutineDispatcherProvider, baseCurrencyStatusOperations: BaseCurrencyStatusOperations, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): GetCurrencyWarningsUseCase { return GetCurrencyWarningsUseCase( walletManagersFacade = walletManagersFacade, @@ -153,6 +164,8 @@ internal object TokensDomainModule { dispatchers = dispatchers, currencyChecksRepository = currencyChecksRepository, currencyStatusOperations = baseCurrencyStatusOperations, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) } @@ -164,6 +177,7 @@ internal object TokensDomainModule { singleNetworkStatusFetcher: SingleNetworkStatusFetcher, multiQuoteStatusFetcher: MultiQuoteStatusFetcher, singleYieldBalanceFetcher: SingleYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, tokensFeatureToggles: TokensFeatureToggles, ): FetchCurrencyStatusUseCase { return FetchCurrencyStatusUseCase( @@ -172,6 +186,7 @@ internal object TokensDomainModule { singleNetworkStatusFetcher = singleNetworkStatusFetcher, multiQuoteStatusFetcher = multiQuoteStatusFetcher, singleYieldBalanceFetcher = singleYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, tokensFeatureToggles = tokensFeatureToggles, ) } @@ -198,8 +213,12 @@ internal object TokensDomainModule { @Provides @Singleton - fun provideGetCryptoCurrencyUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrencyUseCase { - return GetCryptoCurrencyUseCase(currenciesRepository) + fun provideGetCryptoCurrencyUseCase( + currenciesRepository: CurrenciesRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, + ): GetCryptoCurrencyUseCase { + return GetCryptoCurrencyUseCase(currenciesRepository, multiWalletCryptoCurrenciesSupplier, tokensFeatureToggles) } @Provides @@ -220,9 +239,16 @@ internal object TokensDomainModule { @Singleton fun provideApplyTokenListSortingUseCase( currenciesRepository: CurrenciesRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, dispatchers: CoroutineDispatcherProvider, ): ApplyTokenListSortingUseCase { - return ApplyTokenListSortingUseCase(currenciesRepository, dispatchers) + return ApplyTokenListSortingUseCase( + currenciesRepository = currenciesRepository, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, + dispatchers = dispatchers, + ) } @Provides @@ -285,9 +311,13 @@ internal object TokensDomainModule { @Singleton fun provideIsCryptoCurrencyCoinCouldHideUseCase( currenciesRepository: CurrenciesRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): IsCryptoCurrencyCoinCouldHideUseCase { return IsCryptoCurrencyCoinCouldHideUseCase( currenciesRepository = currenciesRepository, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) } @@ -305,9 +335,16 @@ internal object TokensDomainModule { @Singleton fun provideGetBalanceNotEnoughForFeeWarningUseCase( currenciesRepository: CurrenciesRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, dispatchers: CoroutineDispatcherProvider, ): GetBalanceNotEnoughForFeeWarningUseCase { - return GetBalanceNotEnoughForFeeWarningUseCase(currenciesRepository, dispatchers) + return GetBalanceNotEnoughForFeeWarningUseCase( + currenciesRepository = currenciesRepository, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, + dispatchers = dispatchers, + ) } @Provides @@ -348,10 +385,14 @@ internal object TokensDomainModule { fun provideRefreshMultiCurrencyWalletQuotesUseCase( currenciesRepository: CurrenciesRepository, multiQuoteStatusFetcher: MultiQuoteStatusFetcher, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): RefreshMultiCurrencyWalletQuotesUseCase { return RefreshMultiCurrencyWalletQuotesUseCase( currenciesRepository = currenciesRepository, multiQuoteStatusFetcher = multiQuoteStatusFetcher, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) } @@ -379,6 +420,7 @@ internal object TokensDomainModule { singleQuoteStatusSupplier: SingleQuoteStatusSupplier, singleYieldBalanceSupplier: SingleYieldBalanceSupplier, multiYieldBalanceFetcher: MultiYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, ): BaseCurrenciesStatusesOperations { return CachedCurrenciesStatusesOperations( currenciesRepository = currenciesRepository, @@ -393,6 +435,7 @@ internal object TokensDomainModule { singleYieldBalanceSupplier = singleYieldBalanceSupplier, multiYieldBalanceFetcher = multiYieldBalanceFetcher, tokensFeatureToggles = tokensFeatureToggles, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, ) } @@ -411,6 +454,7 @@ internal object TokensDomainModule { singleQuoteStatusSupplier: SingleQuoteStatusSupplier, singleYieldBalanceSupplier: SingleYieldBalanceSupplier, multiYieldBalanceFetcher: MultiYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, ): BaseCurrencyStatusOperations { return CachedCurrenciesStatusesOperations( currenciesRepository = currenciesRepository, @@ -424,6 +468,7 @@ internal object TokensDomainModule { singleQuoteStatusSupplier = singleQuoteStatusSupplier, singleYieldBalanceSupplier = singleYieldBalanceSupplier, multiYieldBalanceFetcher = multiYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, 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 8be21bb8cf..0e1a88fec9 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 @@ -4,6 +4,8 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.demo.DemoConfig import com.tangem.domain.networks.single.SingleNetworkStatusFetcher import com.tangem.domain.networks.single.SingleNetworkStatusSupplier +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.transaction.FeeRepository import com.tangem.domain.transaction.TransactionRepository @@ -58,12 +60,16 @@ internal object TransactionDomainModule { walletManagersFacade: WalletManagersFacade, currenciesRepository: CurrenciesRepository, singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): AssociateAssetUseCase { return AssociateAssetUseCase( cardSdkConfigRepository = cardSdkConfigRepository, walletManagersFacade = walletManagersFacade, currenciesRepository = currenciesRepository, singleNetworkStatusSupplier = singleNetworkStatusSupplier, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) } diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt index 4434c27f0e..8e39df4b21 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt @@ -19,6 +19,8 @@ import com.tangem.data.walletconnect.utils.WcNamespaceConverter import com.tangem.datasource.di.SdkMoshi import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.datasource.local.walletconnect.WalletConnectStore +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletconnect.WcPairService import com.tangem.domain.walletconnect.WcRequestService @@ -169,10 +171,14 @@ internal object WalletConnectDataModule { namespaceConverters: Set<@JvmSuppressWildcards WcNamespaceConverter>, getWallets: GetWalletsUseCase, currenciesRepository: CurrenciesRepository, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles: TokensFeatureToggles, ): AssociateNetworksDelegate = AssociateNetworksDelegate( namespaceConverters = namespaceConverters, getWallets = getWallets, currenciesRepository = currenciesRepository, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, + tokensFeatureToggles = tokensFeatureToggles, ) @Provides diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt index 4d2b72fc1e..f07d69157a 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/pair/AssociateNetworksDelegate.kt @@ -6,10 +6,14 @@ import com.tangem.data.common.currency.isCustomCoin import com.tangem.data.walletconnect.utils.WcNamespaceConverter import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletconnect.model.WcPairError import com.tangem.domain.walletconnect.model.WcSessionProposal.ProposalNetwork import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.models.isMultiCurrency import com.tangem.domain.wallets.usecase.GetWalletsUseCase @@ -17,10 +21,12 @@ internal class AssociateNetworksDelegate( private val namespaceConverters: Set, private val getWallets: GetWalletsUseCase, private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend fun associate(wallet: UserWallet, namespaces: Map): Set { - val walletNetworks = getWalletNetworks(wallet) + val walletNetworks = getWalletNetworks(userWalletId = wallet.walletId) val namespacesSet = namespaces.values.flatMap { proposal -> proposal.chains ?: listOf() }.toSet() return namespacesSet.mapNotNullTo(mutableSetOf()) { chainId -> val wcNetwork = namespaceConverters @@ -48,7 +54,7 @@ internal class AssociateNetworksDelegate( optionalNamespaces: Set, sessionProposal: Wallet.Model.SessionProposal, ): ProposalNetwork { - val walletNetworks = getWalletNetworks(wallet) + val walletNetworks = getWalletNetworks(userWalletId = wallet.walletId) val unknownRequired = mutableSetOf() val missingRequired = mutableSetOf() @@ -92,10 +98,18 @@ internal class AssociateNetworksDelegate( ) } - private suspend fun getWalletNetworks(wallet: UserWallet): List = - currenciesRepository.getMultiCurrencyWalletCurrenciesSync(wallet.walletId) + private suspend fun getWalletNetworks(userWalletId: UserWalletId): List { + return if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId = userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } .filterIsInstance() - .map { it.network } + .map(CryptoCurrency.Coin::network) + } private fun Map.setOfChainId(): Set = this.values.flatMap { proposal -> proposal.chains ?: listOf() }.toSet() diff --git a/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowSupplier.kt b/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowSupplier.kt index 8de04d12bd..ab1c15002a 100644 --- a/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowSupplier.kt +++ b/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowSupplier.kt @@ -1,6 +1,7 @@ package com.tangem.domain.core.flow import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.firstOrNull /** * [Flow] supplier @@ -14,4 +15,9 @@ interface FlowSupplier { /** Supply [Flow] by [params] */ operator fun invoke(params: Params): Flow + + /** Get first [Data] by [params] or null if [Flow] is empty */ + suspend fun getSyncOrNull(params: Params): Data? { + return invoke(params).firstOrNull() + } } \ No newline at end of file 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 0d15310592..4ee5733900 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 @@ -11,6 +11,8 @@ import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletmanager.WalletManagersFacade @@ -26,6 +28,7 @@ class SaveManagedTokensUseCase( private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher, private val multiYieldBalanceFetcher: MultiYieldBalanceFetcher, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, private val tokensFeatureToggles: TokensFeatureToggles, ) { @@ -42,7 +45,14 @@ class SaveManagedTokensUseCase( networks = currenciesToAdd.values.flatten(), ) - val existingCurrencies = currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + val existingCurrencies = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier + .getSyncOrNull(params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId)) + .orEmpty() + .toList() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } val newCurrenciesList = existingCurrencies .filterNot(removingCurrencies::contains) diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/DisableWalletNFTUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/DisableWalletNFTUseCase.kt index 75afd3e094..f71dfd62bd 100644 --- a/domain/nft/src/main/kotlin/com/tangem/domain/nft/DisableWalletNFTUseCase.kt +++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/DisableWalletNFTUseCase.kt @@ -1,6 +1,9 @@ package com.tangem.domain.nft import com.tangem.domain.nft.repository.NFTRepository +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.repository.WalletsRepository @@ -9,12 +12,22 @@ class DisableWalletNFTUseCase( private val walletsRepository: WalletsRepository, private val nftRepository: NFTRepository, private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke(userWalletId: UserWalletId) { walletsRepository.disableNFT(userWalletId) - val currencies = currenciesRepository.getMultiCurrencyWalletCachedCurrenciesSync(userWalletId) + val currencies = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCachedCurrenciesSync(userWalletId) + } + val networks = currencies.map { it.network } nftRepository.clearCache(userWalletId, networks) } diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/FetchNFTCollectionsUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/FetchNFTCollectionsUseCase.kt index e8ecd813c0..68c7af2bf7 100644 --- a/domain/nft/src/main/kotlin/com/tangem/domain/nft/FetchNFTCollectionsUseCase.kt +++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/FetchNFTCollectionsUseCase.kt @@ -1,16 +1,29 @@ package com.tangem.domain.nft import com.tangem.domain.nft.repository.NFTRepository +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.models.UserWalletId class FetchNFTCollectionsUseCase( private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, private val nftRepository: NFTRepository, ) { suspend operator fun invoke(userWalletId: UserWalletId) { - val currencies = currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + val currencies = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } + nftRepository.refreshCollections(userWalletId, currencies.map { it.network }.distinct()) } } \ No newline at end of file diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/RefreshAllNFTUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/RefreshAllNFTUseCase.kt index b99c2c7cad..33205829f8 100644 --- a/domain/nft/src/main/kotlin/com/tangem/domain/nft/RefreshAllNFTUseCase.kt +++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/RefreshAllNFTUseCase.kt @@ -2,16 +2,29 @@ package com.tangem.domain.nft import arrow.core.Either import com.tangem.domain.nft.repository.NFTRepository +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.models.UserWalletId class RefreshAllNFTUseCase( private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, private val nftRepository: NFTRepository, ) { suspend operator fun invoke(userWalletId: UserWalletId): Either = Either.catch { - val currencies = currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + val currencies = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } + nftRepository.refreshAll(userWalletId, currencies.map { it.network }.distinct()) } } \ No newline at end of file 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 290a8de379..48c2a1afd3 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 @@ -30,6 +30,7 @@ class AddCryptoCurrenciesUseCase( private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher, private val singleYieldBalanceFetcher: SingleYieldBalanceFetcher, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, private val tokensFeatureToggles: TokensFeatureToggles, ) { @@ -87,10 +88,21 @@ class AddCryptoCurrenciesUseCase( contractAddress: String, networkId: String, ): Either = either { - val existingCurrencies = - catch({ currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) }) { - raise(it) - } + val existingCurrencies = catch( + block = { + if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + .toList() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } + }, + catch = ::raise, + ) + val foundToken = existingCurrencies .filterIsInstance() .firstOrNull { diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCase.kt index 0754e15ddf..dc883ac0ca 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCase.kt @@ -18,6 +18,8 @@ import kotlin.collections.set class ApplyTokenListSortingUseCase( private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, private val dispatchers: CoroutineDispatcherProvider, ) { @@ -87,7 +89,14 @@ class ApplyTokenListSortingUseCase( private suspend fun Raise.getCurrencies(userWalletId: UserWalletId): List { val tokens = catch( block = { - currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId, refresh = false) + if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId, refresh = false) + } }, catch = { raise(TokenListSortingError.DataError(it)) }, ) 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 c4d88e77f7..1557ddcf64 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 @@ -33,6 +33,7 @@ class FetchCurrencyStatusUseCase( private val singleNetworkStatusFetcher: SingleNetworkStatusFetcher, private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher, private val singleYieldBalanceFetcher: SingleYieldBalanceFetcher, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, private val tokensFeatureToggles: TokensFeatureToggles, ) { @@ -99,7 +100,17 @@ class FetchCurrencyStatusUseCase( id: CryptoCurrency.ID, ): CryptoCurrency { return catch( - block = { currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId = userWalletId, id = id) }, + block = { + if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + ?.firstOrNull { it.id == id } + ?: error("Unable to find currency with ID: $id") + } else { + currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId = userWalletId, id = id) + } + }, ) { raise(CurrencyStatusError.DataError(it)) } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetBalanceNotEnoughForFeeWarningUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetBalanceNotEnoughForFeeWarningUseCase.kt index 3f8dff6280..2574bc59a5 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetBalanceNotEnoughForFeeWarningUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetBalanceNotEnoughForFeeWarningUseCase.kt @@ -25,6 +25,8 @@ import java.math.BigDecimal */ class GetBalanceNotEnoughForFeeWarningUseCase( private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, private val dispatchers: CoroutineDispatcherProvider, ) { suspend operator fun invoke( @@ -69,13 +71,21 @@ class GetBalanceNotEnoughForFeeWarningUseCase( tokenStatus: CryptoCurrencyStatus, feePaidToken: FeePaidCurrency.Token, ): CryptoCurrencyWarning { - val token = currenciesRepository - .getMultiCurrencyWalletCurrenciesSync(userWalletId) - .find { - it is CryptoCurrency.Token && - it.contractAddress.equals(feePaidToken.contractAddress, ignoreCase = true) && - it.network.derivationPath == tokenStatus.currency.network.derivationPath - } + val tokens = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } + + val token = tokens.find { + it is CryptoCurrency.Token && + it.contractAddress.equals(feePaidToken.contractAddress, ignoreCase = true) && + it.network.derivationPath == tokenStatus.currency.network.derivationPath + } + return if (token != null) { CryptoCurrencyWarning.CustomTokenNotEnoughForFee( currency = tokenStatus.currency, diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt index a6241655a5..0bf1c4600b 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyUseCase.kt @@ -13,6 +13,8 @@ import com.tangem.domain.wallets.models.isMultiCurrency class GetCryptoCurrencyUseCase( private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { /** @@ -53,7 +55,15 @@ class GetCryptoCurrencyUseCase( ): CryptoCurrency { return catch( block = { - currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, id) + if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + ?.firstOrNull { it.id.value == id } + ?: error("Unable to find currency with ID: $id") + } else { + currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, id) + } }, catch = { raise(CurrencyStatusError.DataError(it)) }, ) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt index b02e4b6dda..5486d028e5 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt @@ -28,6 +28,8 @@ class GetCurrencyWarningsUseCase( private val dispatchers: CoroutineDispatcherProvider, private val currencyChecksRepository: CurrencyChecksRepository, private val currencyStatusOperations: BaseCurrencyStatusOperations, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke( @@ -150,13 +152,21 @@ class GetCurrencyWarningsUseCase( tokenStatus: CryptoCurrencyStatus, feePaidToken: FeePaidCurrency.Token, ): CryptoCurrencyWarning { - val token = currenciesRepository - .getMultiCurrencyWalletCurrenciesSync(userWalletId) - .find { - it is CryptoCurrency.Token && - it.contractAddress.equals(feePaidToken.contractAddress, ignoreCase = true) && - it.network.derivationPath == tokenStatus.currency.network.derivationPath - } + val tokens = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } + + val token = tokens.find { + it is CryptoCurrency.Token && + it.contractAddress.equals(feePaidToken.contractAddress, ignoreCase = true) && + it.network.derivationPath == tokenStatus.currency.network.derivationPath + } + return if (token != null) { CryptoCurrencyWarning.CustomTokenNotEnoughForFee( currency = tokenStatus.currency, diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/IsCryptoCurrencyCoinCouldHideUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/IsCryptoCurrencyCoinCouldHideUseCase.kt index 6d394b32ff..44d653de4a 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/IsCryptoCurrencyCoinCouldHideUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/IsCryptoCurrencyCoinCouldHideUseCase.kt @@ -6,12 +6,22 @@ import com.tangem.domain.wallets.models.UserWalletId class IsCryptoCurrencyCoinCouldHideUseCase( private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke(userWalletId: UserWalletId, cryptoCurrencyCoin: CryptoCurrency.Coin): Boolean { - return currenciesRepository.getMultiCurrencyWalletCurrenciesSync( - userWalletId = userWalletId, - refresh = false, - ).none { it is CryptoCurrency.Token && it.network == cryptoCurrencyCoin.network } + return if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync( + userWalletId = userWalletId, + refresh = false, + ) + } + .none { it is CryptoCurrency.Token && it.network == cryptoCurrencyCoin.network } } } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt index e9b9d3925b..87345fea9d 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RefreshMultiCurrencyWalletQuotesUseCase.kt @@ -16,6 +16,8 @@ import kotlinx.coroutines.coroutineScope class RefreshMultiCurrencyWalletQuotesUseCase( private val currenciesRepository: CurrenciesRepository, private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke(userWalletId: UserWalletId): Either { @@ -38,8 +40,18 @@ class RefreshMultiCurrencyWalletQuotesUseCase( private suspend fun getCurrencies(userWalletId: UserWalletId): Either> { return either { catch( - block = { currenciesRepository.getMultiCurrencyWalletCachedCurrenciesSync(userWalletId) }, - catch = { raise(it) }, + block = { + if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + .toList() + } else { + currenciesRepository.getMultiCurrencyWalletCachedCurrenciesSync(userWalletId) + } + }, + catch = ::raise, ) } } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RemoveCurrencyUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RemoveCurrencyUseCase.kt index 541700f47d..aaac9efb12 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RemoveCurrencyUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/RemoveCurrencyUseCase.kt @@ -12,6 +12,8 @@ import com.tangem.domain.wallets.models.UserWalletId class RemoveCurrencyUseCase( private val currenciesRepository: CurrenciesRepository, private val walletManagersFacade: WalletManagersFacade, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke( @@ -44,10 +46,17 @@ class RemoveCurrencyUseCase( suspend fun hasLinkedTokens(userWalletId: UserWalletId, currency: CryptoCurrency): Boolean { return when (currency) { is CryptoCurrency.Coin -> { - val walletCurrencies = currenciesRepository.getMultiCurrencyWalletCurrenciesSync( - userWalletId = userWalletId, - refresh = false, - ) + val walletCurrencies = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync( + userWalletId = userWalletId, + refresh = false, + ) + } walletCurrencies.any { it is CryptoCurrency.Token && it.network == currency.network } } 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 9e8914bfdf..c2fd5396bb 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 @@ -22,6 +22,8 @@ import com.tangem.domain.staking.model.stakekit.YieldBalanceList import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.staking.single.SingleYieldBalanceProducer import com.tangem.domain.staking.single.SingleYieldBalanceSupplier +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations.Error @@ -47,6 +49,7 @@ abstract class BaseCurrencyStatusOperations( private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier, private val singleQuoteStatusSupplier: SingleQuoteStatusSupplier, private val singleYieldBalanceSupplier: SingleYieldBalanceSupplier, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, private val tokensFeatureToggles: TokensFeatureToggles, ) { @@ -176,7 +179,7 @@ abstract class BaseCurrencyStatusOperations( val currency = if (isSingleWalletWithTokens) { currenciesRepository.getSingleCurrencyWalletWithCardCurrency(userWalletId, cryptoCurrencyId) } else { - currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, cryptoCurrencyId) + getMultiCurrencyWalletCurrency(userWalletId, cryptoCurrencyId) } val quote = cryptoCurrencyId.rawCurrencyId?.let { rawId -> @@ -240,9 +243,16 @@ abstract class BaseCurrencyStatusOperations( return either { catch( block = { - val nonEmptyCurrencies = + val nonEmptyCurrencies = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + ?.toNonEmptyListOrNull() + } else { currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId).toNonEmptyListOrNull() - ?: return emptyList().right() + } + ?: return emptyList().right() + val (_, currenciesIds) = getIds(nonEmptyCurrencies) val rawIds = currenciesIds.mapNotNull { it.rawCurrencyId }.toSet() @@ -303,7 +313,15 @@ abstract class BaseCurrencyStatusOperations( currencyId: CryptoCurrency.ID, ): CryptoCurrency { return Either.catch { - currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId = userWalletId, id = currencyId) + if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + ?.firstOrNull { it.id == currencyId } + ?: error("Unable to find currency with ID: $currencyId") + } else { + currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId = userWalletId, id = currencyId) + } } .mapLeft(Error::DataError) .bind() @@ -352,7 +370,17 @@ abstract class BaseCurrencyStatusOperations( networkId: Network.ID, derivationPath: Network.DerivationPath, ): CryptoCurrency { - return Either.catch { currenciesRepository.getNetworkCoin(userWalletId, networkId, derivationPath) } + return Either.catch { + if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + ?.firstOrNull { it.network.id == networkId && it.network.derivationPath == derivationPath } + ?: error("Unable to create network coin with ID: $networkId and derivation path: $derivationPath") + } else { + currenciesRepository.getNetworkCoin(userWalletId, networkId, derivationPath) + } + } .mapLeft { Error.DataError(it) } .bind() } 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 00debb0cd3..6802d2efe6 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 @@ -29,6 +29,7 @@ import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher import com.tangem.domain.staking.repositories.StakingRepository import com.tangem.domain.staking.single.SingleYieldBalanceProducer import com.tangem.domain.staking.single.SingleYieldBalanceSupplier +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.tokens.model.CryptoCurrencyStatus @@ -54,6 +55,7 @@ class CachedCurrenciesStatusesOperations( private val singleQuoteStatusSupplier: SingleQuoteStatusSupplier, private val singleYieldBalanceSupplier: SingleYieldBalanceSupplier, private val multiYieldBalanceFetcher: MultiYieldBalanceFetcher, + multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, private val tokensFeatureToggles: TokensFeatureToggles, ) : BaseCurrenciesStatusesOperations, BaseCurrencyStatusOperations( @@ -64,6 +66,7 @@ class CachedCurrenciesStatusesOperations( singleNetworkStatusSupplier = singleNetworkStatusSupplier, singleQuoteStatusSupplier = singleQuoteStatusSupplier, singleYieldBalanceSupplier = singleYieldBalanceSupplier, + multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, tokensFeatureToggles = tokensFeatureToggles, ) { diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCaseTest.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCaseTest.kt index 5017be7437..7368b76718 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCaseTest.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/ApplyTokenListSortingUseCaseTest.kt @@ -10,6 +10,7 @@ import com.tangem.domain.tokens.mock.MockTokens import com.tangem.domain.tokens.repository.MockCurrenciesRepository import com.tangem.domain.wallets.models.UserWalletId import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider +import io.mockk.mockk import junit.framework.TestCase.assertEquals import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow @@ -186,6 +187,8 @@ internal class ApplyTokenListSortingUseCaseTest { ApplyTokenListSortingUseCase( currenciesRepository = tokensRepository, dispatchers = TestingCoroutineDispatcherProvider(), + multiWalletCryptoCurrenciesSupplier = mockk(), + tokensFeatureToggles = mockk(), ) private fun getTokensRepository( 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 b55b1528de..75fc494ebf 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 @@ -9,6 +9,9 @@ import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.NetworkStatus import com.tangem.domain.networks.single.SingleNetworkStatusProducer import com.tangem.domain.networks.single.SingleNetworkStatusSupplier +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.transaction.error.AssociateAssetError import com.tangem.domain.walletmanager.WalletManagersFacade @@ -21,6 +24,8 @@ class AssociateAssetUseCase( private val walletManagersFacade: WalletManagersFacade, private val currenciesRepository: CurrenciesRepository, private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, ) { suspend operator fun invoke( @@ -28,11 +33,22 @@ class AssociateAssetUseCase( currency: CryptoCurrency, ): Either { return either { - val networkCoin = currenciesRepository.getNetworkCoin( - userWalletId = userWalletId, - networkId = currency.network.id, - derivationPath = currency.network.derivationPath, - ) + val networkCoin = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + ?.firstOrNull { + val network = currency.network + it.network.id == network.id && it.network.derivationPath == network.derivationPath + } + ?: error("Unable to create network coin for currencyID: ${currency.id}") + } else { + currenciesRepository.getNetworkCoin( + userWalletId = userWalletId, + networkId = currency.network.id, + derivationPath = currency.network.derivationPath, + ) + } if (isBalanceZero(userWalletId, networkCoin)) { raise(AssociateAssetError.NotEnoughBalance(networkCoin)) } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt index 8944009d6b..b629bf2345 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/model/NFTSendModel.kt @@ -20,9 +20,7 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.BlockchainErrorInfo import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.currency.CryptoCurrency -import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase -import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase -import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase +import com.tangem.domain.tokens.* import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.transaction.error.GetFeeError import com.tangem.domain.transaction.usecase.CreateNFTTransferTransactionUseCase @@ -61,6 +59,8 @@ internal class NFTSendModel @Inject constructor( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getUserWalletUseCase: GetUserWalletUseCase, private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase, private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase, private val createNFTTransferTransactionUseCase: CreateNFTTransferTransactionUseCase, @@ -146,9 +146,16 @@ internal class NFTSendModel @Inject constructor( ifRight = { wallet -> userWallet = wallet - cryptoCurrency = getCryptoCurrenciesUseCase(userWalletId).getOrNull() - ?.filterIsInstance() - ?.firstOrNull { it.network == nftAsset.network } + cryptoCurrency = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + ?.firstOrNull { it is CryptoCurrency.Coin && it.network == nftAsset.network } + } else { + getCryptoCurrenciesUseCase(userWalletId).getOrNull() + ?.filterIsInstance() + ?.firstOrNull { it.network == nftAsset.network } + } ?: return@launch getCurrenciesStatusUpdates( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/deeplink/DefaultStakingDeepLinkHandler.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/deeplink/DefaultStakingDeepLinkHandler.kt index 4b5a2a090c..19c9e9e0b2 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/deeplink/DefaultStakingDeepLinkHandler.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/deeplink/DefaultStakingDeepLinkHandler.kt @@ -10,6 +10,9 @@ import com.tangem.domain.staking.GetStakingAvailabilityUseCase import com.tangem.domain.staking.GetYieldUseCase import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer +import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier +import com.tangem.domain.tokens.TokensFeatureToggles import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler @@ -27,6 +30,8 @@ internal class DefaultStakingDeepLinkHandler @AssistedInject constructor( private val appRouter: AppRouter, private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, private val getYieldUseCase: GetYieldUseCase, private val getStakingAvailabilityUseCase: GetStakingAvailabilityUseCase, ) : StakingDeepLinkHandler { @@ -51,14 +56,22 @@ internal class DefaultStakingDeepLinkHandler @AssistedInject constructor( } scope.launch { - val cryptoCurrency = getCryptoCurrenciesUseCase(userWalletId = selectedUserWalletId).getOrElse { - Timber.e("Error on getting crypto currency list") - return@launch - }.firstOrNull { - val isNetwork = it.network.backendId.equals(networkId, ignoreCase = true) - val isCurrency = it.id.rawCurrencyId?.value?.equals(tokenId, ignoreCase = true) == true - isNetwork && isCurrency + val cryptoCurrency = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(selectedUserWalletId), + ) + .orEmpty() + } else { + getCryptoCurrenciesUseCase(userWalletId = selectedUserWalletId).getOrElse { + Timber.e("Error on getting crypto currency list") + return@launch + } } + .firstOrNull { + val isNetwork = it.network.backendId.equals(networkId, ignoreCase = true) + val isCurrency = it.id.rawCurrencyId?.value?.equals(tokenId, ignoreCase = true) == true + isNetwork && isCurrency + } if (cryptoCurrency == null) { Timber.e( @@ -84,7 +97,7 @@ internal class DefaultStakingDeepLinkHandler @AssistedInject constructor( cryptoCurrencyId = cryptoCurrency.id, symbol = cryptoCurrency.symbol, ).getOrElse { - error("Staking is unavailable for ${cryptoCurrency.name}") + Timber.e("Staking is unavailable for ${cryptoCurrency.name}") return@launch } diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index cc21bc6469..c99f20d86a 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -21,9 +21,7 @@ import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.quote.QuoteStatus import com.tangem.domain.quotes.QuotesRepository -import com.tangem.domain.tokens.FetchCurrencyStatusUseCase -import com.tangem.domain.tokens.GetCurrencyCheckUseCase -import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase +import com.tangem.domain.tokens.* import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.FeePaidCurrency import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck @@ -70,6 +68,8 @@ internal class SwapInteractorImpl @AssistedInject constructor( private val currencyChecksRepository: CurrencyChecksRepository, private val appCurrencyRepository: AppCurrencyRepository, private val currenciesRepository: CurrenciesRepository, + private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, + private val tokensFeatureToggles: TokensFeatureToggles, private val initialToCurrencyResolver: InitialToCurrencyResolver, private val validateTransactionUseCase: ValidateTransactionUseCase, private val estimateFeeUseCase: EstimateFeeUseCase, @@ -1752,13 +1752,22 @@ internal class SwapInteractorImpl @AssistedInject constructor( if (feePaidCurrency.balance > fee.multiply(percentsToFeeIncrease)) { SwapFeeState.Enough } else { - val token = currenciesRepository - .getMultiCurrencyWalletCurrenciesSync(userWalletId) + val tokens = if (tokensFeatureToggles.isWalletBalanceFetcherEnabled) { + multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId), + ) + .orEmpty() + } else { + currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + } + + val token = tokens .filterIsInstance() .find { it.contractAddress.equals(feePaidCurrency.contractAddress, ignoreCase = true) && it.network.derivationPath == fromTokenStatus.currency.network.derivationPath } + SwapFeeState.NotEnough( feeCurrency = token, currencyName = feePaidCurrency.name, 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 41f5d92d70..4891a75416 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 @@ -394,14 +394,14 @@ internal class WalletModel @Inject constructor( ), ) - fetchWalletContent(userWallet = action.selectedWallet) - walletScreenContentLoader.load( userWallet = action.selectedWallet, clickIntents = clickIntents, coroutineScope = modelScope, ) + fetchWalletContent(userWallet = action.selectedWallet) + val otherWallets = action.wallets.minus(action.selectedWallet) otherWallets.onEach { userWallet -> @@ -423,14 +423,14 @@ internal class WalletModel @Inject constructor( walletScreenContentLoader.cancel(action.prevWalletId) tokenListStore.remove(action.prevWalletId) - fetchWalletContent(userWallet = action.selectedWallet) - walletScreenContentLoader.load( userWallet = action.selectedWallet, clickIntents = clickIntents, coroutineScope = modelScope, ) + fetchWalletContent(userWallet = action.selectedWallet) + stateHolder.update( ReinitializeWalletTransformer( prevWalletId = action.prevWalletId, @@ -442,14 +442,14 @@ internal class WalletModel @Inject constructor( } private suspend fun addWallet(action: WalletsUpdateActionResolver.Action.AddWallet) { - fetchWalletContent(userWallet = action.selectedWallet) - walletScreenContentLoader.load( userWallet = action.selectedWallet, clickIntents = clickIntents, coroutineScope = modelScope, ) + fetchWalletContent(userWallet = action.selectedWallet) + stateHolder.update( AddWalletTransformer( userWallet = action.selectedWallet,