Updated on 2026-08-14

This commit is contained in:
Tangem 2023-11-02 17:49:08 +02:00
parent 7cc069e066
commit d05a6271de
11 changed files with 278 additions and 0 deletions

View file

@ -15,6 +15,8 @@ dependencies {
/** Network */
implementation(deps.retrofit)
implementation(deps.moshi)
implementation(deps.moshi.kotlin)
/** Domain */
implementation(projects.domain.tokens.models)

View file

@ -0,0 +1,64 @@
package com.tangem.feature.swap
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.feature.swap.models.request.AssetsRequestBody
import com.tangem.feature.swap.models.request.PairsRequestBody
import com.tangem.feature.swap.models.response.*
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.POST
import retrofit2.http.Query
import java.math.BigDecimal
/**
* Interface of Tangem Express API (new swap mechanism)
*/
internal interface ExpressApi {
// TODO move first three params to retrofit interceptor
@POST("assets")
suspend fun getAssets(
@Header("api-key") apiKey: String,
@Header("user-id") userId: String,
@Header("session-id") sessionId: String,
@Body body: AssetsRequestBody,
): ApiResponse<List<Asset>>
@POST("pairs")
suspend fun getPairs(
@Body body: PairsRequestBody,
): ApiResponse<List<SwapPair>>
@GET("providers")
suspend fun getProviders(): ApiResponse<List<ExchangeProvider>>
@GET("exchange-quote")
suspend fun getExchangeQuote(
@Query("fromContractAddress") fromContractAddress: String,
@Query("fromNetwork") fromNetwork: String,
@Query("toContractAddress") toContractAddress: String,
@Query("toNetwork") toNetwork: String,
@Query("fromAmount") fromAmount: BigDecimal,
@Query("providerId") providerId: Int,
@Query("rateType") rateType: RateType,
): ApiResponse<ExchangeQuoteResponse>
@GET("exchange-data")
suspend fun getExchangeData(
@Query("fromContractAddress") fromContractAddress: String,
@Query("fromNetwork") fromNetwork: String,
@Query("toContractAddress") toContractAddress: String,
@Query("toNetwork") toNetwork: String,
@Query("fromAmount") fromAmount: BigDecimal,
@Query("providerId") providerId: Int,
@Query("rateType") rateType: RateType,
@Query("toAddress") toAddress: String,
): ApiResponse<ExchangeDataResponse>
@GET("exchange-results")
suspend fun getExchangeResults(
@Query("txId") txId: String,
): ApiResponse<ExchangeResultsResponse>
}

View file

@ -0,0 +1,7 @@
package com.tangem.feature.swap.models.request
import com.squareup.moshi.Json
internal data class AssetsRequestBody(
@Json(name = "filter") val filter: List<LeastTokenInfo>?,
)

View file

@ -0,0 +1,11 @@
package com.tangem.feature.swap.models.request
import com.squareup.moshi.Json
internal data class LeastTokenInfo(
@Json(name = "contractAddress")
val contractAddress: String,
@Json(name = "network")
val network: String,
)

View file

@ -0,0 +1,11 @@
package com.tangem.feature.swap.models.request
import com.squareup.moshi.Json
internal data class PairsRequestBody(
@Json(name = "from")
val from: List<LeastTokenInfo>,
@Json(name = "to")
val to: List<LeastTokenInfo>,
)

View file

@ -0,0 +1,29 @@
package com.tangem.feature.swap.models.response
import com.squareup.moshi.Json
data class Asset(
@Json(name = "contractAddress")
val contractAddress: String,
@Json(name = "network")
val network: String,
@Json(name = "token")
val token: String,
@Json(name = "name")
val name: String,
@Json(name = "symbol")
val symbol: String,
@Json(name = "decimals")
val decimals: Int,
@Json(name = "isActive")
val isActive: Boolean,
@Json(name = "exchangeAvailable")
val exchangeAvailable: Boolean
)

View file

@ -0,0 +1,41 @@
package com.tangem.feature.swap.models.response
import com.squareup.moshi.Json
import java.math.BigDecimal
data class ExchangeDataResponse(
@Json(name = "toAmount")
val toAmount: BigDecimal,
@Json(name = "txType")
val txType: TxType,
@Json(name = "txId")
val txId: String, // inner tangem-express transaction id
@Json(name = "txFrom")
val txFrom: String?, // account for debiting tokens (same as toAddress) if DEX, null if CEX
@Json(name = "txTo")
val txTo: String, // swap smart-contract address if DEX, address for sending transaction if CEX
@Json(name = "txData")
val txData: String?, // transaction data if DEX, null if CEX
@Json(name = "txValue")
val txValue: BigDecimal, // amount (same as fromAmount)
@Json(name = "externalTxId")
val externalTxId: String?, // null if DEX, provider transaction id if CEX
@Json(name = "externalTxUrl")
val externalTxUrl: String?, // null if DEX, url of provider exchange status page if CEX
)
enum class TxType {
@Json(name = "send")
SEND,
@Json(name = "swap")
SWAP,
}

View file

@ -0,0 +1,28 @@
package com.tangem.feature.swap.models.response
import com.squareup.moshi.Json
data class ExchangeProvider(
@Json(name = "id")
val id: Int,
@Json(name = "name")
val name: String,
@Json(name = "id")
val type: ExchangeProviderType,
@Json(name = "imageLarge")
val imageLargeUrl: Int,
@Json(name = "imageSmall")
val imageSmallUrl: Int,
)
enum class ExchangeProviderType {
@Json(name = "dex")
DEX,
@Json(name = "cex")
CEX,
}

View file

@ -0,0 +1,12 @@
package com.tangem.feature.swap.models.response
import com.squareup.moshi.Json
import java.math.BigDecimal
data class ExchangeQuoteResponse(
@Json(name = "toAmount")
val toAmount: BigDecimal,
@Json(name = "allowanceContract")
val allowanceContract: String?,
)

View file

@ -0,0 +1,42 @@
package com.tangem.feature.swap.models.response
import com.squareup.moshi.Json
data class ExchangeResultsResponse(
@Json(name = "status")
val status: ExchangeResultsStatus,
@Json(name = "externalStatus")
val externalStatus: String,
@Json(name = "externalTxUrl")
val externalTxUrl: String,
@Json(name = "error")
val error: ExchangeResultsError?,
)
enum class ExchangeResultsStatus {
@Json(name = "processing")
PROCESSING,
@Json(name = "done")
DONE,
@Json(name = "failed")
FAILED,
@Json(name = "refunded")
REFUNDED,
@Json(name = "verificationRequired")
VERIFICATION_REQUIRED,
}
data class ExchangeResultsError(
@Json(name = "code")
val code: Int,
@Json(name = "description")
val description: String,
)

View file

@ -0,0 +1,31 @@
package com.tangem.feature.swap.models.response
import com.squareup.moshi.Json
data class SwapPair(
@Json(name = "from")
val from: String,
@Json(name = "to")
val to: String,
@Json(name = "providers")
val providers: List<SwapPairProvider>,
)
data class SwapPairProvider(
@Json(name = "providerId")
val providerId: Int,
@Json(name = "providerId")
val rateType: RateType,
)
enum class RateType {
@Json(name = "float")
FLOAT,
@Json(name = "fixed")
FIXED,
}