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..2599d4675c 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 @@ -34,36 +34,33 @@ class SaveManagedTokensUseCase( currenciesToAdd: Map>, currenciesToRemove: Map>, ): Either = Either.catch { - val removingCurrencies = currenciesToRemove.mapToCryptoCurrencies(userWalletId) - val addingCurrencies = currenciesToAdd.mapToCryptoCurrencies(userWalletId) + if (currenciesToRemove.isNotEmpty()) { + val removingCurrencies = currenciesToRemove.mapToCryptoCurrencies(userWalletId) - derivationsRepository.derivePublicKeysByNetworks( - userWalletId = userWalletId, - networks = currenciesToAdd.values.flatten(), - ) + currenciesRepository.removeCurrencies(userWalletId = userWalletId, currencies = removingCurrencies) - val existingCurrencies = currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + removeCurrenciesFromWalletManager(userWalletId = userWalletId, currencies = removingCurrencies) + } - val newCurrenciesList = existingCurrencies - .filterNot(removingCurrencies::contains) - .toMutableList() - .also { it.addAll(addingCurrencies) } + if (currenciesToAdd.isNotEmpty()) { + derivationsRepository.derivePublicKeysByNetworks( + userWalletId = userWalletId, + networks = currenciesToAdd.values.flatten(), + ) - currenciesRepository.saveNewCurrenciesList(userWalletId, newCurrenciesList) + val addingCurrencies = currenciesToAdd.mapToCryptoCurrencies(userWalletId) - removeCurrenciesFromWalletManager( - userWalletId = userWalletId, - currencies = removingCurrencies.filterNot(existingCurrencies::contains), - ) - refreshUpdatedNetworks( - userWalletId = userWalletId, - existingCurrencies = existingCurrencies, - currenciesToAdd = addingCurrencies, - ) + val savedCurrencies = currenciesRepository.addCurrencies( + userWalletId = userWalletId, + currencies = addingCurrencies, + ) - refreshUpdatedYieldBalances(userWalletId, existingCurrencies) + refreshUpdatedNetworks(userWalletId = userWalletId, addedCurrencies = savedCurrencies) - refreshUpdatedQuotes(addingCurrencies) + refreshUpdatedYieldBalances(userWalletId = userWalletId, addedCurrencies = savedCurrencies) + + refreshUpdatedQuotes(addedCurrencies = savedCurrencies) + } } private suspend fun removeCurrenciesFromWalletManager( @@ -83,43 +80,30 @@ class SaveManagedTokensUseCase( ) } - private suspend fun refreshUpdatedNetworks( - userWalletId: UserWalletId, - currenciesToAdd: List, - existingCurrencies: List, - ) { - val networksToUpdate = currenciesToAdd - .asSequence() - .filterIsInstance() - .map(CryptoCurrency.Token::network) - .filterTo(hashSetOf()) { hasCoinForNetwork(existingCurrencies, it) } - - val networkToUpdate = currenciesToAdd.map { it.network } - .subtract(existingCurrencies.map { it.network }.toSet()) - + private suspend fun refreshUpdatedNetworks(userWalletId: UserWalletId, addedCurrencies: List) { multiNetworkStatusFetcher( MultiNetworkStatusFetcher.Params( userWalletId = userWalletId, - networks = networksToUpdate + networkToUpdate, + networks = addedCurrencies.map(CryptoCurrency::network).toSet(), ), ) } private suspend fun refreshUpdatedYieldBalances( userWalletId: UserWalletId, - existingCurrencies: List, + addedCurrencies: List, ) { if (tokensFeatureToggles.isStakingLoadingRefactoringEnabled) { multiYieldBalanceFetcher( params = MultiYieldBalanceFetcher.Params( userWalletId = userWalletId, - currencyIdWithNetworkMap = existingCurrencies.associateTo(hashMapOf()) { it.id to it.network }, + currencyIdWithNetworkMap = addedCurrencies.associateTo(hashMapOf()) { it.id to it.network }, ), ) } else { stakingRepository.fetchMultiYieldBalance( userWalletId = userWalletId, - cryptoCurrencies = existingCurrencies, + cryptoCurrencies = addedCurrencies, refresh = true, ) } @@ -134,16 +118,6 @@ class SaveManagedTokensUseCase( ) } - /** - * Determines if the [existingCurrencies] list contains a coin that corresponds - * to the given [network]. - */ - private fun hasCoinForNetwork(existingCurrencies: List, network: Network): Boolean { - return existingCurrencies.any { currency -> - currency is CryptoCurrency.Coin && currency.network == network - } - } - private suspend fun Map>.mapToCryptoCurrencies( userWalletId: UserWalletId, ): List { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt index 724ac04b1b..a75781610c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt @@ -18,12 +18,15 @@ import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.promo.ShouldShowPromoWalletUseCase import com.tangem.domain.promo.models.PromoId +import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher import com.tangem.domain.settings.NeverToSuggestRateAppUseCase import com.tangem.domain.settings.RemindToRateAppLaterUseCase +import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.models.UnlockWalletsError import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.SeedPhraseNotificationUseCase @@ -40,6 +43,9 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject @@ -103,6 +109,8 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( private val seedPhraseNotificationUseCase: SeedPhraseNotificationUseCase, private val urlOpener: UrlOpener, private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher, + private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher, + private val multiYieldBalanceFetcher: MultiYieldBalanceFetcher, private val appRouter: AppRouter, ) : BaseWalletClickIntents(), WalletWarningsClickIntents { @@ -146,13 +154,7 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( ).fold( ifLeft = { Timber.e(it, "Failed to derive public keys") }, ifRight = { - multiNetworkStatusFetcher( - params = MultiNetworkStatusFetcher.Params( - userWalletId = userWallet.walletId, - networks = missedAddressCurrencies.map(CryptoCurrency::network).toSet(), - ), - ) - .onLeft { Timber.e("Unable to refresh token list: $it") } + fetchCryptoCurrencies(userWalletId = userWallet.walletId, currencies = missedAddressCurrencies) }, ) } @@ -369,6 +371,41 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( } } + private suspend fun fetchCryptoCurrencies(userWalletId: UserWalletId, currencies: List) { + coroutineScope { + listOf( + async { + multiNetworkStatusFetcher( + params = MultiNetworkStatusFetcher.Params( + userWalletId = userWalletId, + networks = currencies.map(CryptoCurrency::network).toSet(), + ), + ) + .onLeft { Timber.e("Unable to fetch networks: $it") } + }, + async { + multiQuoteStatusFetcher( + params = MultiQuoteStatusFetcher.Params( + currenciesIds = currencies.mapNotNull { it.id.rawCurrencyId }.toSet(), + appCurrencyId = null, + ), + ) + .onLeft { Timber.e("Unable to fetch quotes: $it") } + }, + async { + multiYieldBalanceFetcher( + params = MultiYieldBalanceFetcher.Params( + userWalletId = userWalletId, + currencyIdWithNetworkMap = currencies.associate { it.id to it.network }, + ), + ) + .onLeft { Timber.e("Unable to fetch yield balances: $it") } + }, + ) + .awaitAll() + } + } + private fun getSelectedUserWallet(): UserWallet? { val userWalletId = stateHolder.getSelectedWalletId() return getUserWalletUseCase(userWalletId).getOrElse {