Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-17 20:11:01 +03:00
parent 93d91f0beb
commit 2985a541f1
10 changed files with 66 additions and 33 deletions

View file

@ -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<CryptoCurrencyAmount>,
currencies: Set<CryptoCurrency>,
): Map<CryptoCurrency.ID, BigDecimal> {
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<CryptoCurrency.ID, NetworkStatus.AmountStatus> {
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(

View file

@ -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?,

View file

@ -42,7 +42,7 @@ data class NetworkStatus(
*/
data class Verified(
val address: NetworkAddress,
val amounts: Map<CryptoCurrency.ID, BigDecimal>,
val amounts: Map<CryptoCurrency.ID, AmountStatus>,
val pendingTransactions: Map<CryptoCurrency.ID, Set<TxHistoryItem>>,
) : 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()
}

View file

@ -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)

View file

@ -22,6 +22,7 @@ internal class TokenListFiatBalanceOperations(
}
is CryptoCurrencyStatus.MissedDerivation,
is CryptoCurrencyStatus.Unreachable,
is CryptoCurrencyStatus.NoAmount,
-> {
fiatBalance = TokenList.FiatBalance.Failed
break

View file

@ -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"),

View file

@ -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

View file

@ -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()),

View file

@ -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,

View file

@ -28,6 +28,7 @@ internal class CryptoCurrencyStatusToTokenItemConverter(
-> value.mapToTokenItemState()
is CryptoCurrencyStatus.MissedDerivation -> value.mapToNoAddressTokenItemState()
is CryptoCurrencyStatus.Unreachable,
is CryptoCurrencyStatus.NoAmount,
-> value.mapToUnreachableTokenItemState()
}
}