diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt index c1cc2d5702..117123d566 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/markets/TangemTechMarketsApi.kt @@ -34,6 +34,9 @@ interface TangemTechMarketsApi { @Query("interval") interval: String, ): ApiResponse + @GET("coins/{coin_id}/exchanges") + suspend fun getCoinExchanges(@Path("coin_id") coinId: String): ApiResponse + @GET("coins/history_preview") suspend fun getCoinsListCharts( @Query("coin_ids") coinIds: String, diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketExchangesResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketExchangesResponse.kt new file mode 100644 index 0000000000..e374f79fbd --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketExchangesResponse.kt @@ -0,0 +1,38 @@ +package com.tangem.datasource.api.markets.models.response + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import java.math.BigDecimal + +/** + * Token market exchanges response + * + * @property exchanges list of exchanges + * +[REDACTED_AUTHOR] + */ +@JsonClass(generateAdapter = true) +data class TokenMarketExchangesResponse( + @Json(name = "exchanges") val exchanges: List, +) { + + /** + * Exchange + * + * @property id id + * @property name name + * @property imageUrl image url + * @property isCentralized CEX (true), DEX (false) + * @property volumeInUsd aggregated volume in USD + * @property trustScore trust score + */ + @JsonClass(generateAdapter = true) + data class Exchange( + @Json(name = "exchange_id") val id: String, + @Json(name = "name") val name: String, + @Json(name = "image") val imageUrl: String?, + @Json(name = "centralized") val isCentralized: Boolean, + @Json(name = "volume_usd") val volumeInUsd: BigDecimal, + @Json(name = "trust_score") val trustScore: Int?, + ) +} \ No newline at end of file diff --git a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt index 6b98bead9e..a46ce3dda8 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt @@ -23,6 +23,7 @@ import com.tangem.domain.wallets.models.UserWalletId import com.tangem.pagination.* import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicLong @@ -262,6 +263,14 @@ internal class DefaultMarketsTokenRepository( } } + override suspend fun getTokenExchanges(tokenId: String): List { + return withContext(dispatcherProvider.io) { + val response = marketsApi.getCoinExchanges(coinId = tokenId).getOrThrow() + + TokenMarketExchangeConverter.convertList(input = response.exchanges) + } + } + private inline fun catchApiErrorAndSendEvent(errorEvent: MarketsDataAnalyticsEvent, block: () -> T): T { return try { block() diff --git a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketExchangeConverter.kt b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketExchangeConverter.kt new file mode 100644 index 0000000000..94aae7673a --- /dev/null +++ b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketExchangeConverter.kt @@ -0,0 +1,35 @@ +package com.tangem.data.markets.converters + +import com.tangem.datasource.api.markets.models.response.TokenMarketExchangesResponse +import com.tangem.domain.markets.TokenMarketExchange +import com.tangem.utils.converter.Converter + +/** + * Converter from [TokenMarketExchangesResponse.Exchange] to [TokenMarketExchange] + * +[REDACTED_AUTHOR] + */ +internal object TokenMarketExchangeConverter : Converter { + + private val RISKY_INTERVAL = 0..3 + private val CAUTION_INTERVAL = 4..7 + + override fun convert(value: TokenMarketExchangesResponse.Exchange): TokenMarketExchange { + return with(value) { + TokenMarketExchange( + id = id, + name = name, + imageUrl = imageUrl, + isCentralized = isCentralized, + volumeInUsd = volumeInUsd, + trustScore = when (trustScore) { + null, + in RISKY_INTERVAL, + -> TokenMarketExchange.TrustScore.Risky + in CAUTION_INTERVAL -> TokenMarketExchange.TrustScore.Caution + else -> TokenMarketExchange.TrustScore.Trusted + }, + ) + } + } +} \ No newline at end of file diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketExchange.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketExchange.kt new file mode 100644 index 0000000000..7816d14808 --- /dev/null +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketExchange.kt @@ -0,0 +1,31 @@ +package com.tangem.domain.markets + +import java.math.BigDecimal + +/** + * Token exchange + * + * @property id id + * @property name name + * @property imageUrl image url + * @property isCentralized CEX (true), DEX (false) + * @property volumeInUsd aggregated volume in USD + * @property trustScore trust score + * +[REDACTED_AUTHOR] + */ +data class TokenMarketExchange( + val id: String, + val name: String, + val imageUrl: String?, + val isCentralized: Boolean, + val volumeInUsd: BigDecimal, + val trustScore: TrustScore, +) { + + enum class TrustScore { + Risky, + Caution, + Trusted, + } +} \ No newline at end of file diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt index f28da22c7b..1f728f1a0f 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt @@ -40,4 +40,11 @@ interface MarketsTokenRepository { token: TokenMarketParams, network: TokenMarketInfo.Network, ): CryptoCurrency? + + /** + * Get token exchanges + * + * @param tokenId token id + */ + suspend fun getTokenExchanges(tokenId: String): List } \ No newline at end of file