Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-30 16:56:10 +04:00
parent 3a4ba6dd5a
commit 3920719b01
6 changed files with 123 additions and 0 deletions

View file

@ -34,6 +34,9 @@ interface TangemTechMarketsApi {
@Query("interval") interval: String, @Query("interval") interval: String,
): ApiResponse<TokenMarketChartResponse> ): ApiResponse<TokenMarketChartResponse>
@GET("coins/{coin_id}/exchanges")
suspend fun getCoinExchanges(@Path("coin_id") coinId: String): ApiResponse<TokenMarketExchangesResponse>
@GET("coins/history_preview") @GET("coins/history_preview")
suspend fun getCoinsListCharts( suspend fun getCoinsListCharts(
@Query("coin_ids") coinIds: String, @Query("coin_ids") coinIds: String,

View file

@ -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>,
) {
/**
* 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?,
)
}

View file

@ -23,6 +23,7 @@ import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.pagination.* import com.tangem.pagination.*
import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.withContext
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
@ -262,6 +263,14 @@ internal class DefaultMarketsTokenRepository(
} }
} }
override suspend fun getTokenExchanges(tokenId: String): List<TokenMarketExchange> {
return withContext(dispatcherProvider.io) {
val response = marketsApi.getCoinExchanges(coinId = tokenId).getOrThrow()
TokenMarketExchangeConverter.convertList(input = response.exchanges)
}
}
private inline fun <T> catchApiErrorAndSendEvent(errorEvent: MarketsDataAnalyticsEvent, block: () -> T): T { private inline fun <T> catchApiErrorAndSendEvent(errorEvent: MarketsDataAnalyticsEvent, block: () -> T): T {
return try { return try {
block() block()

View file

@ -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<TokenMarketExchangesResponse.Exchange, TokenMarketExchange> {
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
},
)
}
}
}

View file

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

View file

@ -40,4 +40,11 @@ interface MarketsTokenRepository {
token: TokenMarketParams, token: TokenMarketParams,
network: TokenMarketInfo.Network, network: TokenMarketInfo.Network,
): CryptoCurrency? ): CryptoCurrency?
/**
* Get token exchanges
*
* @param tokenId token id
*/
suspend fun getTokenExchanges(tokenId: String): List<TokenMarketExchange>
} }