Updated on 2026-08-14

This commit is contained in:
Tangem 2024-02-08 11:17:26 +03:00
parent 8106b36fd6
commit 1e0876eea6
45 changed files with 301 additions and 292 deletions

View file

@ -1,29 +0,0 @@
package com.tangem.datasource.api.promotion
import com.tangem.datasource.api.promotion.models.*
import retrofit2.http.*
/**
*
* Promotion API
* @see <a href = "https://www.notion.so/tangem/Promotion-Program-API-0907159c3fdb4975aac761be632f44da">Documentation<a/>
[REDACTED_AUTHOR]
*/
interface PromotionApi {
@Headers("Cache-Control: max-age=3600")
@GET("promotion")
suspend fun getPromotionInfo(@Query("programName") name: String): PromotionInfoResponse
@POST("promotion/code/validate")
suspend fun validateCode(@Body request: CodeValidateRequestBody): CodeValidateResponse
@POST("promotion/code/award")
suspend fun requestAwardByCode(@Body request: CodeAwardRequestBody): CodeAwardResponse
@POST("promotion/validate")
suspend fun validate(@Body request: ValidateRequestBody): ValidateResponse
@POST("promotion/award")
suspend fun requestAward(@Body request: AwardRequestBody): AwardResponse
}

View file

@ -1,18 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
abstract class AbstractPromotionResponse {
abstract val error: Error?
fun isError(): Boolean = error != null
data class Error(
@Json(name = "code") val code: Int,
@Json(name = "message") val message: String,
)
}

View file

@ -1,12 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class AwardRequestBody(
@Json(name = "walletId") val walletId: String,
@Json(name = "address") val address: String,
@Json(name = "programName") val programName: String,
)

View file

@ -1,11 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class AwardResponse(
@Json(name = "status") val status: Boolean?,
@Json(name = "error") override val error: Error? = null,
) : AbstractPromotionResponse()

View file

@ -1,12 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class CodeAwardRequestBody(
@Json(name = "walletId") val walletId: String,
@Json(name = "address") val address: String,
@Json(name = "code") val code: String?,
)

View file

@ -1,11 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class CodeAwardResponse(
@Json(name = "status") val status: Boolean?,
@Json(name = "error") override val error: Error? = null,
) : AbstractPromotionResponse()

View file

@ -1,11 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class CodeValidateRequestBody(
@Json(name = "walletId") val walletId: String,
@Json(name = "code") val code: String?,
)

View file

@ -1,11 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class CodeValidateResponse(
@Json(name = "valid") val valid: Boolean?,
@Json(name = "error") override val error: Error? = null,
) : AbstractPromotionResponse()

View file

@ -1,40 +1,23 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
[REDACTED_AUTHOR]
*/
@JsonClass(generateAdapter = true)
data class PromotionInfoResponse(
@Json(name = "newCard") val newCard: Data?,
@Json(name = "oldCard") val oldCard: Data?,
@Json(name = "awardPaymentToken") val awardPaymentToken: TokenData?,
@Json(name = "error") override val error: Error? = null,
) : AbstractPromotionResponse() {
@Json(name = "name") val name: String,
@Json(name = "all") val bannerState: BannerState?,
) {
data class Data(
@Json(name = "status") val status: Status,
@Json(name = "award") val award: Double,
@JsonClass(generateAdapter = true)
data class BannerState(
@Json(name = "timeline") val timeline: Timeline,
@Json(name = "status") val status: String,
)
enum class Status(val value: String) {
@Json(name = "pending")
PENDING("pending"),
@Json(name = "active")
ACTIVE("active"),
@Json(name = "finished")
FINISHED("finished"),
}
data class TokenData(
@Json(name = "id") val id: String,
@Json(name = "name") val name: String,
@Json(name = "symbol") val symbol: String,
@Json(name = "active") val active: Boolean,
@Json(name = "networkId") val networkId: String,
@Json(name = "contractAddress") val contractAddress: String,
@Json(name = "decimalCount") val decimalCount: Int,
@JsonClass(generateAdapter = true)
data class Timeline(
@Json(name = "start") val start: String,
@Json(name = "end") val end: String,
)
}

View file

@ -1,11 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class ValidateRequestBody(
@Json(name = "walletId") val walletId: String,
@Json(name = "programName") val programName: String,
)

View file

@ -1,11 +0,0 @@
package com.tangem.datasource.api.promotion.models
import com.squareup.moshi.Json
/**
[REDACTED_AUTHOR]
*/
data class ValidateResponse(
@Json(name = "valid") val valid: Boolean?,
@Json(name = "error") override val error: Error? = null,
) : AbstractPromotionResponse()

View file

@ -1,6 +1,7 @@
package com.tangem.datasource.api.tangemTech
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.promotion.models.PromotionInfoResponse
import com.tangem.datasource.api.tangemTech.models.*
import retrofit2.http.*
@ -71,4 +72,7 @@ interface TangemTechApi {
@Query("coinIds") coinIds: String,
@Query("fields") fields: String = "price,priceChange24h,lastUpdatedAt",
): ApiResponse<QuotesResponse>
@GET("promotion")
suspend fun getPromotionInfo(@Query("programName") name: String): ApiResponse<PromotionInfoResponse>
}

View file

@ -5,4 +5,4 @@ import javax.inject.Qualifier
@Qualifier
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class PromotionOneInch
annotation class DevTangemApi

View file

@ -5,12 +5,10 @@ import com.squareup.moshi.Moshi
import com.tangem.datasource.BuildConfig
import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory
import com.tangem.datasource.api.express.TangemExpressApi
import com.tangem.datasource.api.promotion.PromotionApi
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.utils.RequestHeader.*
import com.tangem.datasource.utils.addHeaders
import com.tangem.datasource.utils.addLoggers
import com.tangem.lib.auth.AuthProvider
import com.tangem.lib.auth.ExpressAuthProvider
import dagger.Module
import dagger.Provides
@ -20,7 +18,6 @@ import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
@Module
@ -75,31 +72,25 @@ class NetworkModule {
}
@Provides
@DevTangemApi
@Singleton
@PromotionOneInch
fun providePromotionOneInchApi(
authProvider: AuthProvider,
@NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context,
): PromotionApi {
val okClient = OkHttpClient.Builder()
.addHeaders(AuthenticationHeader(authProvider))
.addLoggers(context)
.callTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.connectTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.readTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.writeTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.build()
return createBasePromotionRetrofit(okClient, moshi)
}
private fun createBasePromotionRetrofit(okHttpClient: OkHttpClient, moshi: Moshi): PromotionApi {
fun provideTangemTechDevApi(@NetworkMoshi moshi: Moshi, @ApplicationContext context: Context): TangemTechApi {
return Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(PROD_TANGEM_TECH_BASE_URL)
.client(okHttpClient)
.addCallAdapterFactory(ApiResponseCallAdapterFactory.create())
.baseUrl(DEV_TANGEM_TECH_BASE_URL)
.client(
OkHttpClient.Builder()
.addHeaders(
CacheControlHeader,
// TODO("refactor header init") get auth data after biometric auth to avoid race condition
// AuthenticationHeader(authProvider),
)
.addLoggers(context)
.build(),
)
.build()
.create(PromotionApi::class.java)
.create(TangemTechApi::class.java)
}
private companion object {

View file

@ -45,9 +45,13 @@ object PreferencesKeys {
val LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY by lazy { stringPreferencesKey(name = "lastSwappedCryptoCurrency") }
val IS_WALLET_SWAP_PROMO_SHOW_KEY by lazy { booleanPreferencesKey(name = "isWalletSwapPromoShown") }
val IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY by lazy {
booleanPreferencesKey(name = "isWalletSwapPromoChangellyShown")
}
val IS_TOKEN_SWAP_PROMO_SHOW_KEY by lazy { booleanPreferencesKey(name = "isTokenSwapPromoShown") }
val IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY by lazy {
booleanPreferencesKey(name = "isTokenSwapPromoChangellyShown")
}
}
/** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore<Preferences> */