Updated on 2026-08-14
This commit is contained in:
parent
b5af62f06b
commit
20e6ff8ef0
15 changed files with 448 additions and 0 deletions
|
|
@ -0,0 +1,200 @@
|
|||
package com.tangem.datasource.api.oneinch
|
||||
|
||||
import com.tangem.datasource.api.oneinch.models.AllowanceResponse
|
||||
import com.tangem.datasource.api.oneinch.models.ApproveCalldataResponse
|
||||
import com.tangem.datasource.api.oneinch.models.ApproveSpenderResponse
|
||||
import com.tangem.datasource.api.oneinch.models.ProtocolsResponse
|
||||
import com.tangem.datasource.api.oneinch.models.QuoteResponse
|
||||
import com.tangem.datasource.api.oneinch.models.StatusResponse
|
||||
import com.tangem.datasource.api.oneinch.models.SwapResponse
|
||||
import com.tangem.datasource.api.oneinch.models.TokensResponse
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface OneInchApi {
|
||||
|
||||
/**
|
||||
* Healthcheck return 200 if service is available
|
||||
*
|
||||
* @return [StatusResponse]
|
||||
*/
|
||||
@GET("healthcheck")
|
||||
suspend fun healthcheck(): StatusResponse
|
||||
|
||||
//region Approve
|
||||
/**
|
||||
* Address of the 1inch router that must be trusted to spend funds for the exchange
|
||||
*
|
||||
* @return [ApproveSpenderResponse]
|
||||
*/
|
||||
@GET("approve/spender")
|
||||
suspend fun approveSpender(): ApproveSpenderResponse
|
||||
|
||||
/**
|
||||
* Generate data for calling the contract in order to allow the 1inch router to spend funds
|
||||
*
|
||||
* @param tokenAddress Token address you want to exchange
|
||||
* @param amount The number of tokens that the 1inch router is allowed to spend.
|
||||
* If not specified, it will be allowed to spend an infinite amount of tokens.
|
||||
*
|
||||
* @return [ApproveCalldataResponse] Transaction body to allow the exchange with the 1inch router
|
||||
*/
|
||||
@GET("approve/transaction")
|
||||
suspend fun approveTransaction(
|
||||
@Query("tokenAddress") tokenAddress: String,
|
||||
@Query("amount") amount: String?,
|
||||
): ApproveCalldataResponse
|
||||
|
||||
/**
|
||||
* Get the number of tokens that the 1inch router is allowed to spend
|
||||
*
|
||||
* @param tokenAddress Token address you want to exchange
|
||||
* @param walletAddress Wallet address for which you want to check
|
||||
*
|
||||
* @return [AllowanceResponse]
|
||||
*/
|
||||
@GET("approve/allowance")
|
||||
suspend fun approveAllowance(
|
||||
@Query("tokenAddress") tokenAddress: String,
|
||||
@Query("walletAddress") walletAddress: String,
|
||||
): AllowanceResponse
|
||||
//endregion Approve
|
||||
|
||||
//region Info
|
||||
/**
|
||||
* List of tokens that are available for swap in the 1inch Aggregation protocol
|
||||
*
|
||||
* @return [TokensResponse]
|
||||
*/
|
||||
@GET("tokens")
|
||||
suspend fun tokensAvailable(): TokensResponse
|
||||
|
||||
/**
|
||||
* List of liquidity sources that are available for routing in the 1inch Aggregation protocol
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET("liquidity-sources")
|
||||
suspend fun liquiditySources(): ProtocolsResponse
|
||||
//endregion Info
|
||||
|
||||
//region Swap
|
||||
/**
|
||||
* Find the best quote to exchange via 1inch router
|
||||
*
|
||||
* @param fromTokenAddress Example : 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
|
||||
* @param toTokenAddress Example : 0x111111111117dc0aa78b770fa6a738034120c302
|
||||
* @param amount amount of a token to sell, set in minimal divisible units e.g.:
|
||||
* 1.00 DAI set as 1000000000000000000
|
||||
* 51.03 USDC set as 51030000
|
||||
*
|
||||
* @param protocols default: all
|
||||
* @param fee this percentage of fromTokenAddress token amount will be sent to referrerAddress,
|
||||
* the rest will be used as input for a swap
|
||||
* Min: 0; max: 3; Max: 0; max: 3; default: 0; !should be the same for quote and swap!
|
||||
*
|
||||
* @param gasLimit maximum amount of gas for a swap;
|
||||
* @param connectorTokens token-connectors can be specified via this parameter.
|
||||
* The more is set — the longer route estimation will take.
|
||||
* If not set, default token-connectors will be usedmax: 5; !should be the same for quote and swap!
|
||||
*
|
||||
* @param complexityLevel maximum number of token-connectors to be used in a transaction.
|
||||
* The more is used — the longer route estimation will take
|
||||
* min: 0; max: 3; default: 2; !should be the same for quote and swap!
|
||||
*
|
||||
* @param mainRouteParts default: 10; max: 50 !should be the same for quote and swap!
|
||||
* @param parts limit maximum number of parts each main route parts can be split into;
|
||||
* should be the same for a quote and swap
|
||||
* default: 20; max: 100
|
||||
*
|
||||
* @param gasPrice 1inch takes in account gas expenses to determine exchange route.
|
||||
* It is important to use the same gas price on the quote and swap methods.
|
||||
* Gas price set in wei: 12.5 GWEI set as 12500000000
|
||||
* default: fast from network
|
||||
*
|
||||
* @return [QuoteResponse]
|
||||
*/
|
||||
suspend fun quote(
|
||||
@Query("fromTokenAddress") fromTokenAddress: String,
|
||||
@Query("toTokenAddress") toTokenAddress: String,
|
||||
@Query("amount") amount: String,
|
||||
@Query("protocols") protocols: String?,
|
||||
@Query("fee") fee: String?,
|
||||
@Query("gasLimit") gasLimit: String?,
|
||||
@Query("connectorTokens") connectorTokens: String?,
|
||||
@Query("complexityLevel") complexityLevel: String?,
|
||||
@Query("mainRouteParts") mainRouteParts: String?,
|
||||
@Query("parts") parts: String?,
|
||||
@Query("gasPrice") gasPrice: String?,
|
||||
): QuoteResponse
|
||||
|
||||
/**
|
||||
* Generate data for calling the 1inch router for exchange
|
||||
*
|
||||
* @param fromTokenAddress Example : 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
|
||||
* @param toTokenAddress Example : 0x111111111117dc0aa78b770fa6a738034120c302
|
||||
* @param amount amount of a token to sell, set in minimal divisible units e.g.:
|
||||
* 1.00 DAI set as 1000000000000000000
|
||||
* 51.03 USDC set as 51030000
|
||||
*
|
||||
* @param fromAddress The address that calls the 1inch contract
|
||||
* @param slippage limit of price slippage you are willing to accept in percentage, may be set with decimals.
|
||||
* &slippage=0.5 means 0.5% slippage is acceptable. Low values increase chances that transaction will fail,
|
||||
* high values increase chances of front running. min: 0; max: 50;
|
||||
*
|
||||
* @param protocols default: all
|
||||
* @param destinationAddress Receiver of destination currency. default: fromAddress
|
||||
* @param fee this percentage of fromTokenAddress token amount will be sent to referrerAddress,
|
||||
* the rest will be used as input for a swap
|
||||
* Min: 0; max: 3; Max: 0; max: 3; default: 0; !should be the same for quote and swap!
|
||||
*
|
||||
* @param permit https://eips.ethereum.org/EIPS/eip-2612
|
||||
* @param compatibilityMode Allows to build calldata without optimized routers
|
||||
* @param burnChi If true, CHI will be burned from fromAddress to compensate gas.
|
||||
* Check CHI balance and allowance before turning that on. CHI should be approved for the spender address
|
||||
*
|
||||
* @param connectorTokens token-connectors can be specified via this parameter.
|
||||
* The more is set — the longer route estimation will take.
|
||||
* If not set, default token-connectors will be usedmax: 5; !should be the same for quote and swap!
|
||||
*
|
||||
* @param complexityLevel maximum number of token-connectors to be used in a transaction.
|
||||
* The more is used — the longer route estimation will take
|
||||
* min: 0; max: 3; default: 2; !should be the same for quote and swap!
|
||||
*
|
||||
* @param mainRouteParts default: 10; max: 50 !should be the same for quote and swap!
|
||||
* @param parts limit maximum number of parts each main route parts can be split into;
|
||||
* should be the same for a quote and swap
|
||||
* default: 20; max: 100
|
||||
*
|
||||
* @param gasLimit maximum amount of gas for a swap;
|
||||
* @param gasPrice 1inch takes in account gas expenses to determine exchange route.
|
||||
* It is important to use the same gas price on the quote and swap methods.
|
||||
* Gas price set in wei: 12.5 GWEI set as 12500000000
|
||||
* default: fast from network
|
||||
*
|
||||
* @return [SwapResponse]
|
||||
*/
|
||||
suspend fun swap(
|
||||
@Query("fromTokenAddress") fromTokenAddress: String,
|
||||
@Query("toTokenAddress") toTokenAddress: String,
|
||||
@Query("amount") amount: String,
|
||||
@Query("fromAddress") fromAddress: String,
|
||||
@Query("slippage") slippage: Int,
|
||||
@Query("protocols") protocols: String?,
|
||||
@Query("destReceiver") destinationAddress: String?,
|
||||
@Query("referrerAddress") referrerAddress: String?,
|
||||
@Query("fee") fee: String?,
|
||||
@Query("disableEstimate") disableEstimate: Boolean?,
|
||||
@Query("permit") permit: String?,
|
||||
@Query("compatibilityMode") compatibilityMode: Boolean?,
|
||||
@Query("burnChi") burnChi: Boolean?,
|
||||
@Query("allowPartialFill") allowPartialFill: Boolean?,
|
||||
@Query("parts") parts: String?,
|
||||
@Query("mainRouteParts") mainRouteParts: String?,
|
||||
@Query("connectorTokens") connectorTokens: String?,
|
||||
@Query("complexityLevel") complexityLevel: String?,
|
||||
@Query("gasLimit") gasLimit: String?,
|
||||
@Query("gasPrice") gasPrice: String?,
|
||||
): SwapResponse
|
||||
//endregion Swap
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class AllowanceResponse(
|
||||
@Json(name = "allowance") val allowance: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Approve calldata response
|
||||
*
|
||||
* @property data The encoded data to call the approve method on the swapped token contract
|
||||
* @property gasPrice Gas price for fast transaction processing
|
||||
* @property toAddress Token address that will be allowed to exchange through 1inch router
|
||||
* @property value Native token value in WEI (for approve is always 0)
|
||||
*/
|
||||
data class ApproveCalldataResponse(
|
||||
@Json(name = "data") val data: String,
|
||||
@Json(name = "gasPrice") val gasPrice: String,
|
||||
@Json(name = "to") val toAddress: String,
|
||||
@Json(name = "value") val value: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Approve spender response
|
||||
*
|
||||
* @property address Address of the 1inch router that must be trusted to spend funds for the exchange
|
||||
*/
|
||||
data class ApproveSpenderResponse(
|
||||
@Json(name = "address") val address: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Path view dto
|
||||
*/
|
||||
data class PathViewDto(
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "part") val part: Int,
|
||||
@Json(name = "fromTokenAddress") val fromTokenAddress: String,
|
||||
@Json(name = "toTokenAddress") val toTokenAddress: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Protocols response
|
||||
*
|
||||
* @property protocols List of protocols that are available for routing in the 1inch Aggregation protocol
|
||||
*/
|
||||
data class ProtocolsResponse(
|
||||
@Json(name = "protocols") val protocols: List<ProtocolImageDto>,
|
||||
)
|
||||
|
||||
/**
|
||||
* Protocol image
|
||||
*
|
||||
* @property id Protocol id
|
||||
* @property title Protocol title
|
||||
* @property image Protocol logo image
|
||||
* @property imageColor Protocol logo image in color
|
||||
*/
|
||||
data class ProtocolImageDto(
|
||||
@Json(name = "id") val id: String,
|
||||
@Json(name = "title") val title: String,
|
||||
@Json(name = "img") val image: String,
|
||||
@Json(name = "img_color") val imageColor: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Quote response
|
||||
*
|
||||
* @property fromToken Source token info
|
||||
* @property toToken Destination token info
|
||||
* @property toTokenAmount Expected amount of destination token
|
||||
* @property fromTokenAmount Amount of source token
|
||||
* @property protocols Selected protocols in a path
|
||||
* @property estimatedGas gas fee
|
||||
*/
|
||||
data class QuoteResponse(
|
||||
@Json(name = "fromToken") val fromToken: TokenOneInchDto,
|
||||
@Json(name = "toToken") val toToken: TokenOneInchDto,
|
||||
@Json(name = "toTokenAmount") val toTokenAmount: String,
|
||||
@Json(name = "fromTokenAmount") val fromTokenAmount: String,
|
||||
@Json(name = "protocols") val protocols: List<PathViewDto>,
|
||||
@Json(name = "estimatedGas") val estimatedGas: Int,
|
||||
)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class StatusResponse(
|
||||
@Json(name = "status") val status: String,
|
||||
@Json(name = "provider") val provider: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Swap error dto
|
||||
*
|
||||
* One of the following errors:
|
||||
*
|
||||
* -Insufficient liquidity
|
||||
* -Cannot estimate
|
||||
* -You may not have enough ETH balance for gas fee
|
||||
* -FromTokenAddress cannot be equals to toTokenAddress
|
||||
* -Cannot estimate. Don't forget about miner fee. Try to leave the buffer of ETH for gas
|
||||
* -Not enough balance
|
||||
* -Not enough allowance
|
||||
*
|
||||
* @property statusCode HTTP code
|
||||
* @property error Error code description
|
||||
* @property description Error description (one of the following)
|
||||
* @property requestId Request id
|
||||
* @property meta Meta information
|
||||
* @constructor Create empty Swap error dto
|
||||
*/
|
||||
data class SwapErrorDto(
|
||||
@Json(name = "statusCode") val statusCode: Int,
|
||||
@Json(name = "error") val error: String,
|
||||
@Json(name = "description") val description: String,
|
||||
@Json(name = "requestId") val requestId: String,
|
||||
@Json(name = "meta") val meta: List<NestErrorMeta>,
|
||||
)
|
||||
|
||||
/**
|
||||
* Nest error meta
|
||||
*
|
||||
* @property type Type of field
|
||||
* @property value Value of field
|
||||
*/
|
||||
data class NestErrorMeta(
|
||||
@Json(name = "type") val type: String,
|
||||
@Json(name = "value") val value: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class SwapResponse(
|
||||
@Json(name = "fromToken") val fromToken: TokenOneInchDto,
|
||||
@Json(name = "toToken") val toToken: TokenOneInchDto,
|
||||
@Json(name = "toTokenAmount") val toTokenAmount: String,
|
||||
@Json(name = "fromTokenAmount") val fromTokenAmount: String,
|
||||
@Json(name = "protocols") val protocols: List<PathViewDto>,
|
||||
@Json(name = "transaction") val transaction: TransactionDto,
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Token one inch
|
||||
*
|
||||
* @property symbol token symbol
|
||||
* @property name token name
|
||||
* @property address token address
|
||||
* @property decimals token decimals
|
||||
* @property logoURI token logo image url
|
||||
*/
|
||||
data class TokenOneInchDto(
|
||||
@Json(name = "symbol") val symbol: String,
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "address") val address: String,
|
||||
@Json(name = "decimals") val decimals: Int,
|
||||
@Json(name = "logoURI") val logoURI: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Tokens response
|
||||
*
|
||||
* @property tokens List of supported tokens
|
||||
*/
|
||||
data class TokensResponse(
|
||||
@Json(name = "tokens") val tokens: Map<String, TokenOneInchDto>,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Transaction dto
|
||||
*
|
||||
* @property fromAddress transactions will be sent from this address
|
||||
* @property toAddress transactions will be sent to our(1inch) contract address
|
||||
* @property data The encoded data to call the approve method on the swapped token contract
|
||||
* @property value Native token value in WEI (for approve is always 0)
|
||||
* @property gasPrice The encoded data to call the approve method on the swapped token contract
|
||||
* @property gas estimated amount of the gas limit, increase this value by 25%
|
||||
* @constructor Create empty Transaction dto
|
||||
*/
|
||||
data class TransactionDto(
|
||||
@Json(name = "from") val fromAddress: String,
|
||||
@Json(name = "to") val toAddress: String,
|
||||
@Json(name = "data") val data: String,
|
||||
@Json(name = "value") val value: String,
|
||||
@Json(name = "gasPrice") val gasPrice: String,
|
||||
@Json(name = "gas") val gas: String,
|
||||
)
|
||||
|
|
@ -3,7 +3,9 @@ package com.tangem.datasource.di
|
|||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import com.tangem.datasource.api.AuthHeaderInterceptor
|
||||
import com.tangem.datasource.api.oneinch.OneInchApi
|
||||
import com.tangem.datasource.api.referral.ReferralApi
|
||||
import com.tangem.datasource.di.qualifiers.OneInchEthereum
|
||||
import com.tangem.lib.auth.AuthProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -19,6 +21,20 @@ import javax.inject.Singleton
|
|||
@InstallIn(SingletonComponent::class)
|
||||
class NetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@OneInchEthereum
|
||||
fun provideOneInchEthereumApi(): OneInchApi {
|
||||
return Retrofit.Builder()
|
||||
.addConverterFactory(
|
||||
MoshiConverterFactory.create(),
|
||||
)
|
||||
.baseUrl(ONE_INCH_ETHER_BASE_URL)
|
||||
.client(OkHttpClient())
|
||||
.build()
|
||||
.create(OneInchApi::class.java)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideReferralApi(okHttpClient: OkHttpClient): ReferralApi {
|
||||
|
|
@ -49,5 +65,6 @@ class NetworkModule {
|
|||
|
||||
private companion object {
|
||||
const val PROD_REFERRAL_BASE_URL = "https://devapi.tangem-tech.com/v1/"//"https://api.tangem-tech.com/v1/"
|
||||
const val ONE_INCH_ETHER_BASE_URL = ""
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.datasource.di.qualifiers
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class OneInchEthereum
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class OneInchBinance
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class OneInchOptimism
|
||||
Loading…
Add table
Add a link
Reference in a new issue