diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt index dda1e33f8e..fbe711f0b8 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt @@ -12,12 +12,12 @@ data class HotCryptoResponse( @JsonClass(generateAdapter = true) data class Token( - @Json(name = "id") val id: String, - @Json(name = "symbol") val symbol: String, - @Json(name = "name") val name: String, - @Json(name = "network_id") val networkId: String, - @Json(name = "current_price") val currentPrice: BigDecimal, - @Json(name = "price_change_percentage_24h") val priceChangePercentage: BigDecimal, + @Json(name = "id") val id: String? = null, + @Json(name = "symbol") val symbol: String? = null, + @Json(name = "name") val name: String? = null, + @Json(name = "network_id") val networkId: String? = null, + @Json(name = "current_price") val currentPrice: BigDecimal? = null, + @Json(name = "price_change_percentage_24h") val priceChangePercentage: BigDecimal? = null, @Json(name = "contract_address") val contractAddress: String? = null, // specific for token @Json(name = "decimal_count") val decimalCount: Int? = null, // specific for token ) diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt index 5e296aa7dd..2a6a2aecf2 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultHotCryptoRepository.kt @@ -35,7 +35,9 @@ internal class DefaultHotCryptoRepository( scanResponse = userWallet.scanResponse, imageHost = it.imageHost, excludedBlockchains = excludedBlockchains, - ).convertList(input = it.tokens) + ) + .convertList(input = it.tokens) + .filterNotNull() } } } \ No newline at end of file diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt b/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt index 884f659b20..aa3713de22 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/converters/HotCryptoCurrencyConverter.kt @@ -10,7 +10,9 @@ import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.onramp.model.HotCryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.Quote import com.tangem.utils.converter.Converter +import java.math.BigDecimal /** * Converter from [HotCryptoResponse.Token] to [HotCryptoCurrency] @@ -25,44 +27,75 @@ internal class HotCryptoCurrencyConverter( private val scanResponse: ScanResponse, private val imageHost: String?, private val excludedBlockchains: ExcludedBlockchains, -) : Converter { +) : Converter { private val cryptoCurrencyFactory by lazy { CryptoCurrencyFactory(excludedBlockchains) } - override fun convert(value: HotCryptoResponse.Token): HotCryptoCurrency { - val network = createNetwork(value.networkId) + override fun convert(value: HotCryptoResponse.Token): HotCryptoCurrency? { + val rawId = value.id?.let(CryptoCurrency::RawID) ?: return null + val network = value.networkId?.let(::createNetwork) ?: return null + val currency = createCryptoCurrencyOrNull(rawId, value, network) ?: return null + + return HotCryptoCurrency( + cryptoCurrency = currency.setupIconUrl(id = rawId.value), + quote = createQuote( + fiatRate = value.currentPrice, + priceChange = value.priceChangePercentage, + rawCurrencyId = rawId, + ), + ) + } + + private fun createCryptoCurrencyOrNull( + rawId: CryptoCurrency.RawID, + value: HotCryptoResponse.Token, + network: Network, + ): CryptoCurrency? { + val name = value.name + val symbol = value.symbol + + if (name.isNullOrBlank() || symbol.isNullOrBlank()) return null val contractAddress = value.contractAddress val decimals = value.decimalCount - val currency = if (contractAddress != null && decimals != null) { + + return if (contractAddress != null && decimals != null) { cryptoCurrencyFactory.createToken( network = network, - rawId = CryptoCurrency.RawID(value.id), - name = value.name, - symbol = value.symbol, + rawId = rawId, + name = name, + symbol = symbol, decimals = decimals, contractAddress = contractAddress, ) } else { cryptoCurrencyFactory.createCoin(network = network) } + } - return HotCryptoCurrency( - cryptoCurrency = currency.setupIconUrl(id = value.id), - fiatRate = value.currentPrice, - priceChange = value.priceChangePercentage, + private fun createNetwork(networkId: String): Network? { + return getNetwork( + blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)), + extraDerivationPath = null, + scanResponse = scanResponse, + excludedBlockchains = excludedBlockchains, ) } - private fun createNetwork(networkId: String): Network { - return requireNotNull( - getNetwork( - blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)), - extraDerivationPath = null, - scanResponse = scanResponse, - excludedBlockchains = excludedBlockchains, - ), - ) + private fun createQuote( + fiatRate: BigDecimal?, + priceChange: BigDecimal?, + rawCurrencyId: CryptoCurrency.RawID, + ): Quote { + return if (fiatRate != null && priceChange != null) { + Quote.Value( + rawCurrencyId = rawCurrencyId, + fiatRate = fiatRate, + priceChange = priceChange.movePointLeft(2), + ) + } else { + Quote.Empty(rawCurrencyId) + } } private fun CryptoCurrency.setupIconUrl(id: String): CryptoCurrency { diff --git a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/HotCryptoCurrency.kt b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/HotCryptoCurrency.kt index ad722d847a..7bc6378fd0 100644 --- a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/HotCryptoCurrency.kt +++ b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/HotCryptoCurrency.kt @@ -1,19 +1,17 @@ package com.tangem.domain.onramp.model import com.tangem.domain.tokens.model.CryptoCurrency -import java.math.BigDecimal +import com.tangem.domain.tokens.model.Quote /** * Hot crypto currency * * @property cryptoCurrency crypto currency - * @property fiatRate fiat rate - * @property priceChange price change + * @property quote quote * [REDACTED_AUTHOR] */ data class HotCryptoCurrency( val cryptoCurrency: CryptoCurrency, - val fiatRate: BigDecimal, - val priceChange: BigDecimal, + val quote: Quote, ) \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/converter/HotTokenItemStateConverter.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/converter/HotTokenItemStateConverter.kt index 0e1d514176..a6e5e646ce 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/converter/HotTokenItemStateConverter.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/converter/HotTokenItemStateConverter.kt @@ -10,6 +10,7 @@ import com.tangem.core.ui.format.bigdecimal.format import com.tangem.core.ui.format.bigdecimal.percent import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.onramp.model.HotCryptoCurrency +import com.tangem.domain.tokens.model.Quote import com.tangem.utils.converter.Converter import java.math.BigDecimal @@ -29,7 +30,7 @@ internal class HotTokenItemStateConverter( id = value.cryptoCurrency.id.value, iconState = CryptoCurrencyToIconStateConverter().convert(value.cryptoCurrency), titleState = TokenItemState.TitleState.Content(text = stringReference(value.cryptoCurrency.name)), - subtitleState = value.getCryptoPriceState(appCurrency), + subtitleState = value.quote.getCryptoPriceState(appCurrency), fiatAmountState = null, subtitle2State = null, onItemClick = onItemClick.let { onItemClick -> { onItemClick(it, value) } }, @@ -37,12 +38,17 @@ internal class HotTokenItemStateConverter( ) } - private fun HotCryptoCurrency.getCryptoPriceState(appCurrency: AppCurrency): TokenItemState.SubtitleState { - return TokenItemState.SubtitleState.CryptoPriceContent( - price = fiatRate.getFormattedCryptoPrice(appCurrency), - priceChangePercent = priceChange.format { percent() }, - type = priceChange.getPriceChangeType(), - ) + private fun Quote.getCryptoPriceState(appCurrency: AppCurrency): TokenItemState.SubtitleState { + return when (this) { + is Quote.Empty -> TokenItemState.SubtitleState.Unknown + is Quote.Value -> { + TokenItemState.SubtitleState.CryptoPriceContent( + price = fiatRate.getFormattedCryptoPrice(appCurrency), + priceChangePercent = priceChange.format { percent() }, + type = priceChange.getPriceChangeType(), + ) + } + } } private fun BigDecimal.getFormattedCryptoPrice(appCurrency: AppCurrency): String {