From 2985a541f15879b3ad537d4d948aa7d65b3203d7 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Oct 2023 20:11:01 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../data/tokens/utils/NetworkStatusFactory.kt | 37 +++++++++---------- .../tokens/model/CryptoCurrencyStatus.kt | 6 +++ .../domain/tokens/model/NetworkStatus.kt | 12 +++++- .../operations/CurrencyStatusOperations.kt | 12 +++++- .../TokenListFiatBalanceOperations.kt | 1 + .../tangem/domain/tokens/mock/MockNetworks.kt | 20 +++++----- .../domain/tokens/mock/MockTokensStates.kt | 6 ++- .../TokenDetailsLoadedBalanceConverter.kt | 2 + ...letSingleCurrencyLoadedBalanceConverter.kt | 2 + ...ryptoCurrencyStatusToTokenItemConverter.kt | 1 + 10 files changed, 66 insertions(+), 33 deletions(-) diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt index 8c55506020..3f0be2bd6f 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/NetworkStatusFactory.kt @@ -9,7 +9,6 @@ import com.tangem.domain.walletmanager.model.CryptoCurrencyAmount import com.tangem.domain.walletmanager.model.CryptoCurrencyTransaction import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult import timber.log.Timber -import java.math.BigDecimal internal class NetworkStatusFactory { @@ -43,27 +42,27 @@ internal class NetworkStatusFactory { private fun formatAmounts( amounts: Set, currencies: Set, - ): Map { - return amounts - .asSequence() - .mapNotNull { amount -> - val currency = when (amount) { - is CryptoCurrencyAmount.Coin -> currencies.singleOrNull { it is CryptoCurrency.Coin } - is CryptoCurrencyAmount.Token -> currencies.firstOrNull { - it is CryptoCurrency.Token && - it.id.rawCurrencyId == amount.tokenId && - it.contractAddress == amount.tokenContractAddress + ): Map { + return currencies.associate { currency -> + val amount = when (currency) { + is CryptoCurrency.Coin -> { + amounts.singleOrNull { it is CryptoCurrencyAmount.Coin } + } + is CryptoCurrency.Token -> { + amounts.firstOrNull { amount -> + amount is CryptoCurrencyAmount.Token && + currency.id.rawCurrencyId == amount.tokenId && + currency.contractAddress == amount.tokenContractAddress } } - - if (currency == null) { - Timber.e("Unable to find cryptocurrency for amount: $amount") - null - } else { - currency.id to amount.value - } } - .toMap() + if (amount == null) { + Timber.e("Unable to find amount for cryptoCurrency: $currency") + currency.id to NetworkStatus.UnreachableAmount + } else { + currency.id to NetworkStatus.LoadedAmount(amount.value) + } + } } private fun formatTransactions( diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrencyStatus.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrencyStatus.kt index 4558046ab1..8f49493cc5 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrencyStatus.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrencyStatus.kt @@ -56,6 +56,12 @@ data class CryptoCurrencyStatus( override val fiatRate: BigDecimal?, ) : Status(isError = true) + /** Represents a state where the cryptocurrency's network amount not found. */ + data class NoAmount( + override val priceChange: BigDecimal?, + override val fiatRate: BigDecimal?, + ) : Status(isError = true) + /** Represents a state where the cryptocurrency's derivation is missed. */ data class MissedDerivation( override val priceChange: BigDecimal?, diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/NetworkStatus.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/NetworkStatus.kt index 45f8faf7d8..df811a8f51 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/NetworkStatus.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/NetworkStatus.kt @@ -42,7 +42,7 @@ data class NetworkStatus( */ data class Verified( val address: NetworkAddress, - val amounts: Map, + val amounts: Map, val pendingTransactions: Map>, ) : Status() @@ -58,4 +58,14 @@ data class NetworkStatus( val amountToCreateAccount: BigDecimal, val errorMessage: String, ) : Status() + + /** + * Represents possible statuses of amount. + * + * This sealed class includes states as LoadedAmount, UnreachableAmount. + */ + sealed class AmountStatus + + data class LoadedAmount(val value: BigDecimal) : AmountStatus() + object UnreachableAmount : AmountStatus() } \ No newline at end of file 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 5717896c66..a4a39b5501 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 @@ -39,8 +39,16 @@ internal class CurrencyStatusOperations( ) private fun createStatus(status: NetworkStatus.Verified): CryptoCurrencyStatus.Status { - val amount = status.amounts[currency.id] - ?: return CryptoCurrencyStatus.Loading + val amount = status.amounts[currency.id]?.let { + when (it) { + is NetworkStatus.UnreachableAmount -> { + return CryptoCurrencyStatus.NoAmount(priceChange = quote?.priceChange, fiatRate = quote?.fiatRate) + } + is NetworkStatus.LoadedAmount -> { + it.value + } + } + } ?: return CryptoCurrencyStatus.Loading val hasCurrentNetworkTransactions = status.pendingTransactions.isNotEmpty() val currentTransactions = status.pendingTransactions.getOrElse(currency.id, ::emptySet) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt index ec63a9fa0c..326fceb11f 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt @@ -22,6 +22,7 @@ internal class TokenListFiatBalanceOperations( } is CryptoCurrencyStatus.MissedDerivation, is CryptoCurrencyStatus.Unreachable, + is CryptoCurrencyStatus.NoAmount, -> { fiatBalance = TokenList.FiatBalance.Failed break diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockNetworks.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockNetworks.kt index 8404ce4ed4..2980c80907 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockNetworks.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockNetworks.kt @@ -61,9 +61,9 @@ internal object MockNetworks { get() = networkStatus1.copy( value = NetworkStatus.Verified( amounts = mapOf( - MockTokens.token1.id to BigDecimal.TEN, - MockTokens.token2.id to BigDecimal.TEN, - MockTokens.token3.id to BigDecimal.TEN, + MockTokens.token1.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), + MockTokens.token2.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), + MockTokens.token3.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), ), pendingTransactions = emptyMap(), address = NetworkAddress.Single(defaultAddress = "mock"), @@ -74,9 +74,9 @@ internal object MockNetworks { get() = networkStatus2.copy( value = NetworkStatus.Verified( amounts = mapOf( - MockTokens.token4.id to BigDecimal.TEN, - MockTokens.token5.id to BigDecimal.TEN, - MockTokens.token6.id to BigDecimal.TEN, + MockTokens.token4.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), + MockTokens.token5.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), + MockTokens.token6.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), ), pendingTransactions = emptyMap(), address = NetworkAddress.Single(defaultAddress = "mock"), @@ -87,10 +87,10 @@ internal object MockNetworks { get() = networkStatus3.copy( value = NetworkStatus.Verified( amounts = mapOf( - MockTokens.token7.id to BigDecimal.TEN, - MockTokens.token8.id to BigDecimal.TEN, - MockTokens.token9.id to BigDecimal.TEN, - MockTokens.token10.id to BigDecimal.TEN, + MockTokens.token7.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), + MockTokens.token8.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), + MockTokens.token9.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), + MockTokens.token10.id to NetworkStatus.LoadedAmount(BigDecimal.TEN), ), pendingTransactions = emptyMap(), address = NetworkAddress.Single(defaultAddress = "mock"), diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt index d1410765aa..8424c5cf4f 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt @@ -3,6 +3,7 @@ package com.tangem.domain.tokens.mock import arrow.core.nonEmptyListOf import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.NetworkStatus +import java.math.BigDecimal @Suppress("MemberVisibilityCanBePrivate") internal object MockTokensStates { @@ -107,7 +108,10 @@ internal object MockTokensStates { val loadedTokensStates = failedTokenStates.map { status -> val networkStatus = MockNetworks.verifiedNetworksStatuses .first { it.network == status.currency.network } - val amount = (networkStatus.value as NetworkStatus.Verified).amounts[status.currency.id]!! + val amount = ( + (networkStatus.value as NetworkStatus.Verified).amounts[status.currency.id]!! + as? NetworkStatus.LoadedAmount + )?.value ?: BigDecimal.ZERO val quote = MockQuotes.quotes.first { it.rawCurrencyId == status.currency.id.rawCurrencyId } val fiatAmount = amount * quote.fiatRate diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt index 853c1cd0f0..8d05222a69 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt @@ -75,6 +75,7 @@ internal class TokenDetailsLoadedBalanceConverter( is CryptoCurrencyStatus.MissedDerivation, is CryptoCurrencyStatus.Custom, is CryptoCurrencyStatus.Unreachable, + is CryptoCurrencyStatus.NoAmount, -> TokenDetailsBalanceBlockState.Error(currentState.actionButtons) } } @@ -91,6 +92,7 @@ internal class TokenDetailsLoadedBalanceConverter( is CryptoCurrencyStatus.MissedDerivation, is CryptoCurrencyStatus.NoAccount, is CryptoCurrencyStatus.Unreachable, + is CryptoCurrencyStatus.NoAmount, -> MarketPriceBlockState.Content( currencySymbol = currencySymbol, price = formatPrice(status, appCurrencyProvider()), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt index 3b54e4d515..a44b929150 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt @@ -58,6 +58,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter( return when (status) { is CryptoCurrencyStatus.NoQuote, is CryptoCurrencyStatus.Loaded, + is CryptoCurrencyStatus.NoAmount, -> MarketPriceBlockState.Content( currencySymbol = currencyName, price = formatPrice(status, appCurrencyProvider()), @@ -92,6 +93,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter( is CryptoCurrencyStatus.NoQuote, is CryptoCurrencyStatus.Loaded, is CryptoCurrencyStatus.NoAccount, + is CryptoCurrencyStatus.NoAmount, -> { WalletCardState.Content( id = selectedWallet.id, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt index 2c387beee4..59b3b14b1e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt @@ -28,6 +28,7 @@ internal class CryptoCurrencyStatusToTokenItemConverter( -> value.mapToTokenItemState() is CryptoCurrencyStatus.MissedDerivation -> value.mapToNoAddressTokenItemState() is CryptoCurrencyStatus.Unreachable, + is CryptoCurrencyStatus.NoAmount, -> value.mapToUnreachableTokenItemState() } }