From e3593c69822941bed85e9b49afdcedf53b921f65 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 2 Dec 2024 09:55:53 +0300 Subject: [PATCH 1/2] Updated on 2026-08-14 --- .../tokens/operations/CurrencyStatusOperations.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt index 3e4f3a77ae..41d94b2cf2 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrencyStatusOperations.kt @@ -85,14 +85,8 @@ internal class CurrencyStatusOperations( } else { null } + // order is important for correct total balance calculation return when { - quote is Quote.Empty || ignoreQuote -> CryptoCurrencyStatus.NoQuote( - amount = amount, - hasCurrentNetworkTransactions = hasCurrentNetworkTransactions, - pendingTransactions = currentTransactions, - networkAddress = status.address, - yieldBalance = currentYieldBalance, - ) currency is CryptoCurrency.Token && currency.isCustom -> CryptoCurrencyStatus.Custom( amount = amount, fiatAmount = calculateFiatAmountOrNull(amount, quote?.fiatRate), @@ -103,6 +97,13 @@ internal class CurrencyStatusOperations( networkAddress = status.address, yieldBalance = currentYieldBalance, ) + quote is Quote.Empty || ignoreQuote -> CryptoCurrencyStatus.NoQuote( + amount = amount, + hasCurrentNetworkTransactions = hasCurrentNetworkTransactions, + pendingTransactions = currentTransactions, + networkAddress = status.address, + yieldBalance = currentYieldBalance, + ) quote is Quote.Value -> CryptoCurrencyStatus.Loaded( amount = amount, fiatAmount = calculateFiatAmount(amount, quote.fiatRate), From 877d47db98a9db177ac8b73f35d79b57dadab1d8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 2 Dec 2024 12:47:42 +0300 Subject: [PATCH 2/2] Updated on 2026-08-14 --- Gemfile.lock | 2 +- .../tokens/GetCryptoCurrencyActionsUseCase.kt | 21 +++++++++---- .../CurrenciesStatusesOperations.kt | 30 ++++++++++++------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b4221a320d..535cdb9a32 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -217,4 +217,4 @@ DEPENDENCIES fastlane-plugin-firebase_app_distribution BUNDLED WITH - 1.17.2 + 2.5.23 diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt index ad321616d3..e6981db812 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt @@ -17,6 +17,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.isNullOrZero import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.* +import kotlinx.coroutines.withTimeoutOrNull /** * Use case to determine which TokenActions are available for a [CryptoCurrency] @@ -54,9 +55,13 @@ class GetCryptoCurrencyActionsUseCase( val networkFlow = if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) { operations.getNetworkCoinForSingleWalletWithTokenFlow(networkId) } else if (!userWallet.isMultiCurrency) { - operations.getPrimaryCurrencyStatusFlow() + operations.getPrimaryCurrencyStatusFlow(includeQuotes = false) } else { - operations.getNetworkCoinFlow(networkId, cryptoCurrencyStatus.currency.network.derivationPath) + operations.getNetworkCoinFlow( + networkId = networkId, + derivationPath = cryptoCurrencyStatus.currency.network.derivationPath, + includeQuotes = false, + ) } val flow = networkFlow.mapLatest { maybeCoinStatus -> @@ -171,10 +176,10 @@ class GetCryptoCurrencyActionsUseCase( // swap if (userWallet.isMultiCurrency) { - if ( - marketCryptoCurrencyRepository.isExchangeable(userWallet.walletId, cryptoCurrency) && - cryptoCurrencyStatus.value !is CryptoCurrencyStatus.NoQuote - ) { + val isExchangeable = withTimeoutOrNull(REQUEST_EXCHANGE_DATA_TIMEOUT) { + marketCryptoCurrencyRepository.isExchangeable(userWallet.walletId, cryptoCurrency) + } ?: false + if (isExchangeable && cryptoCurrencyStatus.value !is CryptoCurrencyStatus.NoQuote) { activeList.add(TokenActionsState.ActionState.Swap(ScenarioUnavailabilityReason.None)) } else { disabledList.add( @@ -312,4 +317,8 @@ class GetCryptoCurrencyActionsUseCase( cryptoCurrency = cryptoCurrency, ) is StakingAvailability.Available } + + private companion object { + const val REQUEST_EXCHANGE_DATA_TIMEOUT = 1000L + } } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt index 639ccd6991..9a4dcf3728 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt @@ -143,13 +143,14 @@ internal class CurrenciesStatusesOperations( suspend fun getNetworkCoinFlow( networkId: Network.ID, derivationPath: Network.DerivationPath, + includeQuotes: Boolean = true, ): Flow> { val currency = recover( block = { getNetworkCoin(networkId, derivationPath) }, recover = { return flowOf(it.left()) }, ) - return getCurrencyStatusFlow(currency) + return getCurrencyStatusFlow(currency, includeQuotes) } suspend fun getNetworkCoinForSingleWalletWithTokenFlow( @@ -163,25 +164,34 @@ internal class CurrenciesStatusesOperations( return getCurrencyStatusFlow(currency) } - suspend fun getPrimaryCurrencyStatusFlow(): Flow> { + suspend fun getPrimaryCurrencyStatusFlow(includeQuotes: Boolean = true): Flow> { val currency = recover( block = { getPrimaryCurrency() }, recover = { return flowOf(it.left()) }, ) - return getCurrencyStatusFlow(currency) + return getCurrencyStatusFlow(currency, includeQuotes) } - fun getCurrencyStatusFlow(currency: CryptoCurrency): Flow> { + fun getCurrencyStatusFlow( + currency: CryptoCurrency, + includeQuotes: Boolean = true, + ): Flow,> { val (networks, currenciesIds) = getIds(nonEmptyListOf(currency)) - val quoteFlow = getQuotes(currenciesIds) - .map { maybeQuotes -> - maybeQuotes.flatMap { quotes -> - quotes.singleOrNull { it.rawCurrencyId == currency.id.rawCurrencyId }?.right() - ?: Error.EmptyQuotes.left() + val quoteFlow = if (includeQuotes) { + getQuotes(currenciesIds) + .map { maybeQuotes -> + maybeQuotes.flatMap { quotes -> + quotes.singleOrNull { it.rawCurrencyId == currency.id.rawCurrencyId }?.right() + ?: Error.EmptyQuotes.left() + } } - } + } else { + // don't use emptyFlow() + flow { emit(Error.EmptyQuotes.left()) } + } val statusFlow = getNetworksStatuses(networks) .map { maybeStatuses ->