Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-17 12:23:30 +03:00
commit 75802c1551
16 changed files with 365 additions and 0 deletions

View file

@ -0,0 +1,26 @@
package com.tangem.datasource.api.polymarket
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.polymarket.models.PolymarketEventsResponse
import retrofit2.http.GET
import retrofit2.http.Query
/**
* Polymarket predictions BFF Discovery API (`api/predictions/v1`).
*
* Provided in [com.tangem.datasource.di.NetworkModule] via the [ApiConfig.ID.Predictions] config.
*/
interface PolymarketApi {
/**
* Discovery feed: paginated prediction events, each with its top active markets.
*
* @param limit page size (BFF default 20)
* @param cursor keyset pagination cursor; `null` for the first page
*/
@GET("api/predictions/v1/events")
suspend fun getEvents(
@Query("limit") limit: Int,
@Query("cursor") cursor: String?,
): ApiResponse<PolymarketEventsResponse>
}

View file

@ -0,0 +1,45 @@
package com.tangem.datasource.api.polymarket.models
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
* Response of `GET /api/predictions/v1/events` (BFF `EventsPageResponse`).
*/
@JsonClass(generateAdapter = true)
data class PolymarketEventsResponse(
@Json(name = "events") val events: List<PolymarketEventDto>,
@Json(name = "cursor") val cursor: String?,
@Json(name = "hasNext") val hasNext: Boolean,
)
/** BFF `Event`. Only the fields consumed by the app are declared; unknown JSON is ignored. */
@JsonClass(generateAdapter = true)
data class PolymarketEventDto(
@Json(name = "eventId") val eventId: String,
@Json(name = "slug") val slug: String,
@Json(name = "title") val title: String,
@Json(name = "icon") val icon: String?,
@Json(name = "image") val image: String?,
@Json(name = "volume") val volume: Double?,
@Json(name = "totalMarketsCount") val totalMarketsCount: Int,
@Json(name = "markets") val markets: List<PolymarketMarketDto>,
)
/** BFF `Market` (reduced preview inside an [PolymarketEventDto]). */
@JsonClass(generateAdapter = true)
data class PolymarketMarketDto(
@Json(name = "id") val id: String,
@Json(name = "question") val question: String,
@Json(name = "icon") val icon: String?,
@Json(name = "volume") val volume: Double?,
@Json(name = "outcomes") val outcomes: List<PolymarketOutcomeDto>,
)
/** BFF `OutcomeSummary`. */
@JsonClass(generateAdapter = true)
data class PolymarketOutcomeDto(
@Json(name = "assetId") val assetId: String,
@Json(name = "label") val label: String,
@Json(name = "probability") val probability: Double?,
)

View file

@ -22,6 +22,7 @@ import com.tangem.datasource.api.gasless.GaslessTxServiceApi
import com.tangem.datasource.api.gasless.GaslessTxServiceApiV2
import com.tangem.datasource.api.pay.TangemPayApi
import com.tangem.datasource.api.pay.TangemPayAuthApi
import com.tangem.datasource.api.polymarket.PolymarketApi
import com.tangem.datasource.api.stakekit.StakeKitApi
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.YieldSupplyApi
@ -36,6 +37,7 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Suppress("TooManyFunctions")
@Module
@InstallIn(SingletonComponent::class)
internal object NetworkModule {
@ -235,6 +237,17 @@ internal object NetworkModule {
)
}
@Provides
@Singleton
fun providePolymarketApi(retrofitApiBuilder: RetrofitApiBuilder): PolymarketApi {
// Polymarket BFF Discovery lives on the main Tangem gateway — reuse the TangemTech config.
return retrofitApiBuilder.build(
apiConfigId = ApiConfig.ID.TangemTech,
applyTimeoutAnnotations = false,
sessionAuth = false,
)
}
@Provides
@Singleton
fun provideAuthApi(retrofitApiBuilder: RetrofitApiBuilder): AuthApi {