From 2413e9a3b704769ca9adcdcf9e8e2571b8a362bc Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 30 Nov 2022 22:13:41 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../api/oneinch/models/TransactionDto.kt | 2 +- .../tangem/feature/swap/SwapRepositoryImpl.kt | 37 +++++++++++++++++++ .../swap/converters/ApproveConverter.kt | 17 +++++++++ .../feature/swap/converters/SwapConverter.kt | 24 ++++++++++++ .../feature/swap/domain/SwapRepository.kt | 35 ++++++++++++++++++ .../swap/domain/models/ApproveModel.kt | 14 +++++++ .../domain/models/SwapTransactionModel.kt | 29 +++++++++++++++ 7 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 features/swap/data/src/main/java/com/tangem/feature/swap/converters/ApproveConverter.kt create mode 100644 features/swap/data/src/main/java/com/tangem/feature/swap/converters/SwapConverter.kt create mode 100644 features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ApproveModel.kt create mode 100644 features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapTransactionModel.kt diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/models/TransactionDto.kt b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/models/TransactionDto.kt index bd71ce74db..a32e827601 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/models/TransactionDto.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/models/TransactionDto.kt @@ -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 */ diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/SwapRepositoryImpl.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/SwapRepositoryImpl.kt index aab22f9b8c..2095876a1b 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/SwapRepositoryImpl.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/SwapRepositoryImpl.kt @@ -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, + ), + ) + } + } } \ No newline at end of file diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ApproveConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ApproveConverter.kt new file mode 100644 index 0000000000..4d3574869d --- /dev/null +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ApproveConverter.kt @@ -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 { + + override fun convert(value: ApproveCalldataResponse): ApproveModel { + return ApproveModel( + data = value.data, + gasPrice = value.gasPrice, + toAddress = value.toAddress, + ) + } +} \ No newline at end of file diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SwapConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SwapConverter.kt new file mode 100644 index 0000000000..244ae4f2a0 --- /dev/null +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SwapConverter.kt @@ -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 { + + 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, + ) + } +} \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapRepository.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapRepository.kt index 5aea22d2b8..963f87bfdb 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapRepository.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapRepository.kt @@ -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, + ) } \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ApproveModel.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ApproveModel.kt new file mode 100644 index 0000000000..2fce5634f9 --- /dev/null +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ApproveModel.kt @@ -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, +) \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapTransactionModel.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapTransactionModel.kt new file mode 100644 index 0000000000..f36d74eb61 --- /dev/null +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapTransactionModel.kt @@ -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, +) \ No newline at end of file