Updated on 2026-08-14

This commit is contained in:
Tangem 2022-11-30 22:13:41 +03:00
parent e47b11f29e
commit 2413e9a3b7
7 changed files with 157 additions and 1 deletions

View file

@ -9,7 +9,7 @@ import com.squareup.moshi.Json
* @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 gasPrice maximum amount of gas for a swap default: 11500000; max: 11500000
* @property gas estimated amount of the gas limit, increase this value by 25%
* @constructor Create empty Transaction dto
*/

View file

@ -2,9 +2,12 @@ package com.tangem.feature.swap
import com.tangem.datasource.api.oneinch.OneInchApi
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.feature.swap.converters.ApproveConverter
import com.tangem.feature.swap.converters.QuotesConverter
import com.tangem.feature.swap.converters.SwapConverter
import com.tangem.feature.swap.converters.TokensConverter
import com.tangem.feature.swap.domain.SwapRepository
import com.tangem.feature.swap.domain.models.ApproveModel
import com.tangem.feature.swap.domain.models.Currency
import com.tangem.feature.swap.domain.models.QuoteModel
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -16,6 +19,8 @@ class SwapRepositoryImpl @Inject constructor(
private val oneInchApi: OneInchApi,
private val tokensConverter: TokensConverter,
private val quotesConverter: QuotesConverter,
private val swapConverter: SwapConverter,
private val approveConverter: ApproveConverter,
private val coroutineDispatcher: CoroutineDispatcherProvider,
) : SwapRepository {
@ -42,4 +47,36 @@ class SwapRepositoryImpl @Inject constructor(
oneInchApi.approveSpender().address
}
}
override suspend fun dataToApprove(tokenAddress: String, amount: String): ApproveModel {
return withContext(coroutineDispatcher.io) {
approveConverter.convert(oneInchApi.approveTransaction(tokenAddress, amount))
}
}
override suspend fun checkTokensSpendAllowance(tokenAddress: String, walletAddress: String): String {
return withContext(coroutineDispatcher.io) {
oneInchApi.approveAllowance(tokenAddress, walletAddress).allowance
}
}
override suspend fun prepareSwapTransaction(
fromTokenAddress: String,
toTokenAddress: String,
amount: String,
fromAddress: String,
slippage: Int,
) {
return withContext(coroutineDispatcher.io) {
swapConverter.convert(
oneInchApi.swap(
fromTokenAddress = fromTokenAddress,
toTokenAddress = toTokenAddress,
amount = amount,
fromAddress = fromAddress,
slippage = slippage,
),
)
}
}
}

View file

@ -0,0 +1,17 @@
package com.tangem.feature.swap.converters
import com.tangem.datasource.api.oneinch.models.ApproveCalldataResponse
import com.tangem.feature.swap.domain.models.ApproveModel
import com.tangem.utils.converter.Converter
import javax.inject.Inject
class ApproveConverter @Inject constructor() : Converter<ApproveCalldataResponse, ApproveModel> {
override fun convert(value: ApproveCalldataResponse): ApproveModel {
return ApproveModel(
data = value.data,
gasPrice = value.gasPrice,
toAddress = value.toAddress,
)
}
}

View file

@ -0,0 +1,24 @@
package com.tangem.feature.swap.converters
import com.tangem.datasource.api.oneinch.models.SwapResponse
import com.tangem.feature.swap.domain.models.SwapTransactionModel
import com.tangem.utils.converter.Converter
import javax.inject.Inject
class SwapConverter @Inject constructor() : Converter<SwapResponse, SwapTransactionModel> {
override fun convert(value: SwapResponse): SwapTransactionModel {
return SwapTransactionModel(
fromTokenAddress = value.fromToken.address,
toTokenAddress = value.toToken.address,
toTokenAmount = value.fromTokenAmount,
fromTokenAmount = value.toTokenAmount,
fromWalletAddress = value.transaction.fromAddress,
toWalletAddress = value.transaction.toAddress,
data = value.transaction.data,
value = value.transaction.value,
gasPrice = value.transaction.gasPrice,
gas = value.transaction.gas,
)
}
}

View file

@ -1,5 +1,6 @@
package com.tangem.feature.swap.domain
import com.tangem.feature.swap.domain.models.ApproveModel
import com.tangem.feature.swap.domain.models.Currency
import com.tangem.feature.swap.domain.models.QuoteModel
@ -13,5 +14,39 @@ interface SwapRepository {
amount: String,
): QuoteModel
/**
* Returns address of 1inch router that must be trusted
*
* @return address
*/
suspend fun addressForTrust(): String
/**
* Generate "data" for calling contract in order to allow 1inch spend funds
*
* @param tokenAddress token you want to exchange
* @param amount number of tokens is allowed. By default infinite
*/
suspend fun dataToApprove(
tokenAddress: String,
amount: String,
): ApproveModel
/**
* Get the number of tokens that the 1inch router is allowed to spend
*
* @param tokenAddress Token address you want to exchange
* @param walletAddress address for which you want to check
*
* @return amount of tokens allowed to spend
*/
suspend fun checkTokensSpendAllowance(tokenAddress: String, walletAddress: String): String
suspend fun prepareSwapTransaction(
fromTokenAddress: String,
toTokenAddress: String,
amount: String,
fromAddress: String,
slippage: Int,
)
}

View file

@ -0,0 +1,14 @@
package com.tangem.feature.swap.domain.models
/**
* Approve model
*
* @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
*/
data class ApproveModel(
val data: String,
val gasPrice: String,
val toAddress: String,
)

View file

@ -0,0 +1,29 @@
package com.tangem.feature.swap.domain.models
/**
* Swap transaction model
*
* @property fromTokenAddress token from which want to convert
* @property toTokenAddress token to want to convert
* @property toTokenAmount amount "target" token
* @property fromTokenAmount amount "initial" token
* @property fromWalletAddress wallet from address (transactions will be sent from this address)
* @property toWalletAddress 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 maximum amount of gas for a swap default: 11500000; max: 11500000
* @property gas estimated amount of the gas limit, increase this value by 25%
* @constructor Create empty Swap transaction model
*/
data class SwapTransactionModel(
val fromTokenAddress: String,
val toTokenAddress: String,
val toTokenAmount: String,
val fromTokenAmount: String,
val fromWalletAddress: String,
val toWalletAddress: String,
val data: String,
val value: String,
val gasPrice: String,
val gas: String,
)