Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-06 11:22:18 +05:00
parent 51c7e4e10b
commit 173ee13120
21 changed files with 155 additions and 44 deletions

View file

@ -63,6 +63,12 @@ internal class YieldSupply(
)
private fun createHeaders(apiEnvironment: ApiEnvironment) = buildMap {
put(
key = "Authorization",
value = ProviderSuspend {
"Bearer " + environmentConfigStorage.getConfigSync().yieldModuleApiKey
},
)
put(key = "api-key", value = ProviderSuspend { getApiKey(apiEnvironment) })
putAll(from = RequestHeader.AppVersionPlatformHeaders(appVersionProvider, appInfoProvider).values)
putAll(from = RequestHeader.AuthenticationHeader(authProvider).values)

View file

@ -2,19 +2,42 @@ package com.tangem.datasource.api.tangemTech
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.tangemTech.models.YieldMarketsResponse
import com.tangem.datasource.api.tangemTech.models.YieldModuleStatusResponse
import com.tangem.datasource.api.tangemTech.models.YieldSupplyChangeTokenStatusBody
import com.tangem.datasource.api.tangemTech.models.YieldTokenStatusResponse
import com.tangem.datasource.api.tangemTech.models.YieldTokenChartResponse
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
interface YieldSupplyApi {
@GET("api/v1/yield/markets")
suspend fun getYieldMarkets(): ApiResponse<YieldMarketsResponse>
suspend fun getYieldMarkets(@Query("chainId") chainId: Int? = null): ApiResponse<YieldMarketsResponse>
@GET("api/v1/yield/token/{tokenAddress}")
suspend fun getYieldTokenStatus(@Path("tokenAddress") tokenAddress: String): ApiResponse<YieldTokenStatusResponse>
@GET("api/v1/yield/token/{chainId}/{tokenAddress}")
suspend fun getYieldTokenStatus(
@Path("chainId") chainId: Int,
@Path("tokenAddress") tokenAddress: String,
): ApiResponse<YieldTokenStatusResponse>
@GET("api/v1/yield/token/{tokenAddress}/chart")
suspend fun getYieldTokenChart(@Path("tokenAddress") tokenAddress: String): ApiResponse<YieldTokenChartResponse>
@GET("api/v1/yield/token/{chainId}/{tokenAddress}/chart")
suspend fun getYieldTokenChart(
@Path("chainId") chainId: Int,
@Path("tokenAddress") tokenAddress: String,
@Query("window") window: String? = null,
@Query("bucketSizeDays") bucketSizeDays: Int? = null,
): ApiResponse<YieldTokenChartResponse>
@POST("api/v1/module/activate")
suspend fun activateYieldModule(
@Body body: YieldSupplyChangeTokenStatusBody,
): ApiResponse<YieldModuleStatusResponse>
@POST("api/v1/module/deactivate")
suspend fun deactivateYieldModule(
@Body body: YieldSupplyChangeTokenStatusBody,
): ApiResponse<YieldModuleStatusResponse>
}

View file

@ -12,10 +12,11 @@ data class YieldMarketsResponse(
@JsonClass(generateAdapter = true)
data class MarketDto(
@Json(name = "tokenAddress") val tokenAddress: String,
@Json(name = "tokenSymbol") val tokenSymbol: String,
@Json(name = "tokenName") val tokenName: String,
@Json(name = "tokenAddress") val tokenAddress: String? = null,
@Json(name = "tokenSymbol") val tokenSymbol: String? = null,
@Json(name = "tokenName") val tokenName: String? = null,
@Json(name = "apy") val apy: BigDecimal,
@Json(name = "isActive") val isActive: Boolean,
@Json(name = "chainId") val chainId: Int? = null,
)
}

View file

@ -0,0 +1,13 @@
package com.tangem.datasource.api.tangemTech.models
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class YieldModuleStatusResponse(
@Json(name = "tokenAddress") val tokenAddress: String,
@Json(name = "chainId") val chainId: Int,
@Json(name = "isActive") val isActive: Boolean,
@Json(name = "activatedAt") val activatedAt: String?,
@Json(name = "deactivatedAt") val deactivatedAt: String?,
)

View file

@ -0,0 +1,10 @@
package com.tangem.datasource.api.tangemTech.models
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class YieldSupplyChangeTokenStatusBody(
@Json(name = "tokenAddress") val tokenAddress: String,
@Json(name = "chainId") val chainId: Int,
)

View file

@ -6,9 +6,12 @@ import java.math.BigDecimal
@JsonClass(generateAdapter = true)
data class YieldTokenStatusResponse(
@Json(name = "tokenAddress") val tokenAddress: String,
@Json(name = "tokenSymbol") val tokenSymbol: String,
@Json(name = "tokenName") val tokenName: String,
@Json(name = "apy") val apy: BigDecimal,
@Json(name = "isActive") val isActive: Boolean,
@Json(name = "tokenAddress") val tokenAddress: String? = null,
@Json(name = "tokenSymbol") val tokenSymbol: String? = null,
@Json(name = "tokenName") val tokenName: String? = null,
@Json(name = "apy") val apy: BigDecimal? = null,
@Json(name = "isActive") val isActive: Boolean? = null,
@Json(name = "chainId") val chainId: Int? = null,
@Json(name = "maxFeeNative") val maxFeeNative: String? = null,
@Json(name = "maxFeeUSD") val maxFeeUSD: String? = null,
)

View file

@ -20,4 +20,5 @@ data class EnvironmentConfig(
val tangemApiKey: String? = null,
val tangemApiKeyDev: String? = null,
val tangemApiKeyStage: String? = null,
val yieldModuleApiKey: String? = null,
)

View file

@ -29,6 +29,7 @@ internal object EnvironmentConfigConverter : Converter<EnvironmentConfigModel, E
tangemApiKey = value.tangemApiKey,
tangemApiKeyDev = value.tangemApiKeyDev,
tangemApiKeyStage = value.tangemApiKeyStage,
yieldModuleApiKey = value.yieldModuleApiKey,
)
}
}

View file

@ -44,6 +44,7 @@ class EnvironmentConfigModel(
@Json(name = "tangemApiKeyDev") val tangemApiKeyDev: String?,
@Json(name = "tangemApiKeyStage") val tangemApiKeyStage: String?,
@Json(name = "etherscanApiKey") val etherScanApiKey: String?,
@Json(name = "yieldModuleApiKey") val yieldModuleApiKey: String?,
)
@JsonClass(generateAdapter = true)

View file

@ -19,6 +19,7 @@ internal class MockEnvironmentConfigStorage : EnvironmentConfigStorage {
tangemApiKey = TANGEM_API_KEY,
tangemApiKeyDev = TANGEM_API_KEY_DEV,
tangemApiKeyStage = TANGEM_API_KEY_STAGE,
yieldModuleApiKey = YIELD_MODULE_KEY,
)
override suspend fun initialize() = environmentConfig
@ -32,5 +33,6 @@ internal class MockEnvironmentConfigStorage : EnvironmentConfigStorage {
const val TANGEM_API_KEY = "tangem_api_key"
const val TANGEM_API_KEY_DEV = "tangem_api_key_dev"
const val TANGEM_API_KEY_STAGE = "tangem_api_key_stage"
const val YIELD_MODULE_KEY = "yield_module_api_key"
}
}

View file

@ -198,6 +198,7 @@ internal class ProdApiConfigsManagerTest {
environment = ApiEnvironment.PROD,
baseUrl = "https://yield.tangem.org/",
headers = mapOf(
"Authorization" to ProviderSuspend { "Bearer " + MockEnvironmentConfigStorage.YIELD_MODULE_KEY },
"api-key" to ProviderSuspend { MockEnvironmentConfigStorage.TANGEM_API_KEY },
"card_id" to ProviderSuspend { APP_CARD_ID },
"card_public_key" to ProviderSuspend { APP_CARD_PUBLIC_KEY },
@ -276,6 +277,6 @@ internal class ProdApiConfigsManagerTest {
const val EXPRESS_SESSION_ID = "express_session_id"
const val STAKE_KIT_API_KEY = "stake_kit_api_key"
const val APP_CARD_ID = "app_card_id"
const val APP_CARD_PUBLIC_KEY = "app_public_key"
const val APP_CARD_PUBLIC_KEY = "Bearer app_public_key"
}
}