diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/BaseResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/BaseResponse.kt deleted file mode 100644 index 866c26d858..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/BaseResponse.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.datasource.api.oneinch - -import com.tangem.datasource.api.oneinch.models.SwapErrorDto - -data class BaseOneInchResponse( - val body: T?, - val errorDto: SwapErrorDto?, -) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchApi.kt index 613d5d1000..651e726ad3 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchApi.kt @@ -58,7 +58,7 @@ interface OneInchApi { suspend fun approveAllowance( @Query("tokenAddress") tokenAddress: String, @Query("walletAddress") walletAddress: String, - ): AllowanceResponse + ): Response //endregion Approve //region Info diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchErrorsHandler.kt b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchErrorsHandler.kt index 72e9cd5342..792c9866d7 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchErrorsHandler.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/OneInchErrorsHandler.kt @@ -1,25 +1,25 @@ package com.tangem.datasource.api.oneinch import com.squareup.moshi.Moshi +import com.tangem.datasource.api.oneinch.errors.OneIncResponseException import com.tangem.datasource.api.oneinch.models.SwapErrorDto import retrofit2.HttpException import retrofit2.Response import javax.inject.Inject -class OneInchErrorsHandler @Inject constructor(private val moshi: Moshi) { +class OneInchErrorsHandler @Inject constructor(moshi: Moshi) { - fun handleOneInchResponse(response: Response): BaseOneInchResponse { - val body = response.body() + private val errorMoshiAdapter = moshi.adapter(SwapErrorDto::class.java) + + @Throws(OneIncResponseException::class) + fun handleOneInchResponse(response: Response): T { return if (response.isSuccessful) { - return BaseOneInchResponse(body, null) + response.body() ?: error("response body is null") } else { when (response.code()) { HTTP_CODE_400 -> { - if (body != null) { - BaseOneInchResponse(null, moshi.adapter(SwapErrorDto::class.java).fromJson(body.toString())) - } else { - throw HttpException(response) - } + val swapErrorDto = errorMoshiAdapter.fromJson(response.errorBody()?.string() ?: "") + throw OneIncResponseException(swapErrorDto ?: throw HttpException(response)) } else -> { throw HttpException(response) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/errors/OneIncResponseException.kt b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/errors/OneIncResponseException.kt new file mode 100644 index 0000000000..94c94f6e32 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/api/oneinch/errors/OneIncResponseException.kt @@ -0,0 +1,5 @@ +package com.tangem.datasource.api.oneinch.errors + +import com.tangem.datasource.api.oneinch.models.SwapErrorDto + +class OneIncResponseException(val data: SwapErrorDto) : Exception() \ No newline at end of file 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 ca376c5d99..d37105e46e 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,6 +2,7 @@ package com.tangem.feature.swap import com.tangem.datasource.api.oneinch.OneInchApi import com.tangem.datasource.api.oneinch.OneInchErrorsHandler +import com.tangem.datasource.api.oneinch.errors.OneIncResponseException import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.feature.swap.converters.ApproveConverter import com.tangem.feature.swap.converters.QuotesConverter @@ -11,8 +12,9 @@ import com.tangem.feature.swap.domain.SwapRepository import com.tangem.feature.swap.domain.models.AggregatedSwapDataModel import com.tangem.feature.swap.domain.models.data.ApproveModel import com.tangem.feature.swap.domain.models.data.Currency -import com.tangem.feature.swap.domain.models.data.QuoteModel import com.tangem.feature.swap.domain.models.data.SwapDataModel +import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel +import com.tangem.feature.swap.domain.models.data.mapErrors import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext import javax.inject.Inject @@ -37,14 +39,18 @@ internal class SwapRepositoryImpl @Inject constructor( override suspend fun findBestQuote(fromTokenAddress: String, toTokenAddress: String, amount: String): AggregatedSwapDataModel { return withContext(coroutineDispatcher.io) { - val quoteResponse = oneInchErrorsHandler.handleOneInchResponse( - oneInchApi.quote( - fromTokenAddress = fromTokenAddress, - toTokenAddress = toTokenAddress, - amount = amount, - ), - ) - quotesConverter.convert(quoteResponse) + try { + val response = oneInchErrorsHandler.handleOneInchResponse( + oneInchApi.quote( + fromTokenAddress = fromTokenAddress, + toTokenAddress = toTokenAddress, + amount = amount, + ), + ) + AggregatedSwapDataModel(dataModel = quotesConverter.convert(response)) + } catch (ex: OneIncResponseException) { + AggregatedSwapDataModel(null, mapErrors(ex.data.description)) + } } } @@ -54,15 +60,23 @@ internal class SwapRepositoryImpl @Inject constructor( } } - override suspend fun dataToApprove(tokenAddress: String, amount: String): ApproveModel { + 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 { + override suspend fun checkTokensSpendAllowance(tokenAddress: String, walletAddress: String): + AggregatedSwapDataModel { return withContext(coroutineDispatcher.io) { - oneInchApi.approveAllowance(tokenAddress, walletAddress).allowance + try { + val response = oneInchErrorsHandler.handleOneInchResponse( + oneInchApi.approveAllowance(tokenAddress, walletAddress) + ) + AggregatedSwapDataModel(response.allowance) + } catch (ex: OneIncResponseException) { + AggregatedSwapDataModel(null, mapErrors(ex.data.description)) + } } } @@ -74,18 +88,20 @@ internal class SwapRepositoryImpl @Inject constructor( slippage: Int, ): AggregatedSwapDataModel { return withContext(coroutineDispatcher.io) { - val swapResponse = oneInchErrorsHandler.handleOneInchResponse( - oneInchApi.swap( - fromTokenAddress = fromTokenAddress, - toTokenAddress = toTokenAddress, - amount = amount, - fromAddress = fromWalletAddress, - slippage = slippage, - ), - ) - swapConverter.convert( - swapResponse, - ) + try { + val swapResponse = oneInchErrorsHandler.handleOneInchResponse( + oneInchApi.swap( + fromTokenAddress = fromTokenAddress, + toTokenAddress = toTokenAddress, + amount = amount, + fromAddress = fromWalletAddress, + slippage = slippage, + ), + ) + AggregatedSwapDataModel(swapConverter.convert(swapResponse)) + } catch (ex: OneIncResponseException) { + AggregatedSwapDataModel(null, mapErrors(ex.data.description)) + } } } } \ No newline at end of file diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/QuotesConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/QuotesConverter.kt index fe37564101..d6566ef6e3 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/QuotesConverter.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/QuotesConverter.kt @@ -1,30 +1,17 @@ package com.tangem.feature.swap.converters -import com.tangem.datasource.api.oneinch.BaseOneInchResponse import com.tangem.datasource.api.oneinch.models.QuoteResponse -import com.tangem.feature.swap.domain.models.AggregatedSwapDataModel -import com.tangem.feature.swap.domain.models.data.QuoteModel -import com.tangem.feature.swap.domain.models.data.mapErrors +import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel import com.tangem.utils.converter.Converter import javax.inject.Inject -class QuotesConverter @Inject constructor() : Converter, AggregatedSwapDataModel> { +class QuotesConverter @Inject constructor() : Converter { - override fun convert(value: BaseOneInchResponse): AggregatedSwapDataModel { - val body = value.body - return if (body != null) { - AggregatedSwapDataModel( - QuoteModel( - fromTokenAmount = body.fromTokenAmount, - toTokenAmount = body.toTokenAmount, - estimatedGas = body.estimatedGas, - ), - ) - } else { - AggregatedSwapDataModel( - null, - mapErrors(value.errorDto?.description), - ) - } + override fun convert(value: QuoteResponse): QuoteModel { + return QuoteModel( + fromTokenAmount = value.fromTokenAmount, + toTokenAmount = value.toTokenAmount, + estimatedGas = value.estimatedGas, + ) } } \ 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 index 1c2fb0e2c2..87dec263da 100644 --- 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 @@ -1,35 +1,22 @@ package com.tangem.feature.swap.converters -import com.tangem.datasource.api.oneinch.BaseOneInchResponse import com.tangem.datasource.api.oneinch.models.SwapResponse import com.tangem.datasource.api.oneinch.models.TransactionDto -import com.tangem.feature.swap.domain.models.AggregatedSwapDataModel import com.tangem.feature.swap.domain.models.data.SwapDataModel import com.tangem.feature.swap.domain.models.data.TransactionModel -import com.tangem.feature.swap.domain.models.data.mapErrors import com.tangem.utils.converter.Converter import javax.inject.Inject -class SwapConverter @Inject constructor() : Converter, AggregatedSwapDataModel> { +class SwapConverter @Inject constructor() : Converter { - override fun convert(value: BaseOneInchResponse): AggregatedSwapDataModel { - val body = value.body - return if (body != null) { - AggregatedSwapDataModel( - SwapDataModel( - fromTokenAddress = body.fromToken.address, - toTokenAddress = body.toToken.address, - toTokenAmount = body.fromTokenAmount, - fromTokenAmount = body.toTokenAmount, - transaction = convertTransaction(body.transaction), - ), - ) - } else { - AggregatedSwapDataModel( - null, - mapErrors(value.errorDto?.description), - ) - } + override fun convert(value: SwapResponse): SwapDataModel { + return SwapDataModel( + fromTokenAddress = value.fromToken.address, + toTokenAddress = value.toToken.address, + toTokenAmount = value.fromTokenAmount, + fromTokenAmount = value.toTokenAmount, + transaction = convertTransaction(value.transaction), + ) } private fun convertTransaction(transactionDto: TransactionDto): TransactionModel { diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt index f75c0842ad..be45612480 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt @@ -1,8 +1,7 @@ package com.tangem.feature.swap.domain -import com.tangem.feature.swap.domain.models.SwapResultModel import com.tangem.feature.swap.domain.models.data.Currency -import com.tangem.feature.swap.domain.models.data.QuoteModel +import com.tangem.feature.swap.domain.models.data.SwapState interface SwapInteractor { @@ -10,11 +9,13 @@ interface SwapInteractor { suspend fun getTokenBalance(tokenId: String): String + suspend fun givePermissionToSwap(tokenAddress: String) + suspend fun findBestQuote( fromTokenAddress: String, toTokenAddress: String, amount: String, - ): QuoteModel + ): SwapState - suspend fun onSwap(): SwapResultModel + suspend fun onSwap(): SwapState } \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 942a6d256d..3a989bb4c6 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -1,9 +1,9 @@ package com.tangem.feature.swap.domain import com.tangem.feature.swap.domain.cache.SwapDataCache -import com.tangem.feature.swap.domain.models.SwapResultModel import com.tangem.feature.swap.domain.models.data.Currency -import com.tangem.feature.swap.domain.models.data.QuoteModel +import com.tangem.feature.swap.domain.models.data.DataError +import com.tangem.feature.swap.domain.models.data.SwapState import com.tangem.feature.swap.domain.models.data.TransactionModel import com.tangem.lib.crypto.UserWalletManager import javax.inject.Inject @@ -28,12 +28,20 @@ internal class SwapInteractorImpl @Inject constructor( TODO("Not yet implemented") } - override suspend fun findBestQuote(fromTokenAddress: String, toTokenAddress: String, amount: String): QuoteModel { + override suspend fun givePermissionToSwap(tokenAddress: String) { + val oneInchAddress = repository.addressForTrust() + val transactionData = repository.dataToApprove(tokenAddress) + //todo sign transaction (next tasks) + } + + override suspend fun findBestQuote(fromTokenAddress: String, toTokenAddress: String, amount: String): SwapState { val networkId = cache.getNetworkId() val isAllowedToSpend = if (networkId.isNullOrEmpty()) { false } else { - repository.checkTokensSpendAllowance(fromTokenAddress, userWalletManager.getWalletAddress(networkId)) != "0" + val allowance = + repository.checkTokensSpendAllowance(fromTokenAddress, userWalletManager.getWalletAddress(networkId)) + allowance.error == DataError.NO_ERROR && allowance.dataModel != "0" } repository.findBestQuote(fromTokenAddress, toTokenAddress, amount).let { quotes -> val quoteDataModel = quotes.dataModel @@ -41,37 +49,37 @@ internal class SwapInteractorImpl @Inject constructor( cache.cacheSwapParams(quoteDataModel.copy(isAllowedToSpend = isAllowedToSpend), amount) return quoteDataModel } else { - error("") //todo handle error in domain layer(task [REDACTED_TASK_KEY]) + return SwapState.SwapError(quotes.error) } } } - override suspend fun onSwap(): SwapResultModel { + override suspend fun onSwap(): SwapState { val quoteModel = cache.getLastQuote() val amountToSwap = cache.getAmountToSwap() val networkId = cache.getNetworkId() if (quoteModel != null && amountToSwap != null && networkId != null) { - val swapData = repository.prepareSwapTransaction( + repository.prepareSwapTransaction( fromTokenAddress = quoteModel.fromTokenAmount, toTokenAddress = quoteModel.toTokenAmount, amount = amountToSwap, slippage = DEFAULT_SLIPPAGE, fromWalletAddress = getWalletAddress(networkId), - ).dataModel - if (swapData != null) { - signTransactionData(swapData.transaction) //todo implement - return SwapResultModel.SwapSuccess( - quoteModel.fromTokenAmount, - quoteModel.toTokenAmount, - ) - } else { - error("") //todo handle error in domain layer(task [REDACTED_TASK_KEY]) + ).let { + val swapData = it.dataModel + if (swapData != null) { + signTransactionData(swapData.transaction) //todo implement + return SwapState.SwapSuccess( + quoteModel.fromTokenAmount, + quoteModel.toTokenAmount, + ) + } else { + return SwapState.SwapError(it.error) + } } + } else { + throw IllegalStateException("cache is empty, call 'findBestQuote' first") } - return SwapResultModel.SwapError( - 0, - "", - ) } private fun getWalletAddress(networkId: String): String { 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 4c8254c809..01f534a296 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 @@ -3,8 +3,8 @@ package com.tangem.feature.swap.domain import com.tangem.feature.swap.domain.models.AggregatedSwapDataModel import com.tangem.feature.swap.domain.models.data.ApproveModel import com.tangem.feature.swap.domain.models.data.Currency -import com.tangem.feature.swap.domain.models.data.QuoteModel import com.tangem.feature.swap.domain.models.data.SwapDataModel +import com.tangem.feature.swap.domain.models.data.SwapState interface SwapRepository { @@ -14,7 +14,7 @@ interface SwapRepository { fromTokenAddress: String, toTokenAddress: String, amount: String, - ): AggregatedSwapDataModel + ): AggregatedSwapDataModel /** * Returns address of 1inch router that must be trusted @@ -31,7 +31,7 @@ interface SwapRepository { */ suspend fun dataToApprove( tokenAddress: String, - amount: String, + amount: String? = null, ): ApproveModel /** @@ -42,7 +42,7 @@ interface SwapRepository { * * @return amount of tokens allowed to spend */ - suspend fun checkTokensSpendAllowance(tokenAddress: String, walletAddress: String): String + suspend fun checkTokensSpendAllowance(tokenAddress: String, walletAddress: String): AggregatedSwapDataModel suspend fun prepareSwapTransaction( fromTokenAddress: String, diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCache.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCache.kt index 1f6d2373ef..13cdd8e17d 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCache.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCache.kt @@ -1,7 +1,7 @@ package com.tangem.feature.swap.domain.cache import com.tangem.feature.swap.domain.models.data.Currency -import com.tangem.feature.swap.domain.models.data.QuoteModel +import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel interface SwapDataCache { diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCacheImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCacheImpl.kt index f4fd1cd174..7aab37de03 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCacheImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/cache/SwapDataCacheImpl.kt @@ -2,7 +2,7 @@ package com.tangem.feature.swap.domain.cache import com.tangem.feature.swap.domain.models.SwapDataHolder import com.tangem.feature.swap.domain.models.data.Currency -import com.tangem.feature.swap.domain.models.data.QuoteModel +import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel class SwapDataCacheImpl : SwapDataCache { diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapDataHolder.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapDataHolder.kt index 60d62274de..4d50aa2da8 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapDataHolder.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapDataHolder.kt @@ -1,9 +1,10 @@ package com.tangem.feature.swap.domain.models -import com.tangem.feature.swap.domain.models.data.QuoteModel +import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel data class SwapDataHolder( - val quoteModel: QuoteModel? = null, + val quoteModel: + QuoteModel? = null, val amountToSwap: String? = null, val networkId: String? = null, ) \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapResultModel.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapResultModel.kt deleted file mode 100644 index 014fb40127..0000000000 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/SwapResultModel.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.feature.swap.domain.models - -sealed interface SwapResultModel { - - data class SwapSuccess( - val fromTokenAmount: String, - val toTokenAmount: String, - ) : SwapResultModel - - data class SwapError( - val errorCode: Int, - val errorMessage: String, - ) : SwapResultModel -} \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/DataError.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/DataError.kt index 6498ac07e0..60e80e094e 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/DataError.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/DataError.kt @@ -3,16 +3,19 @@ package com.tangem.feature.swap.domain.models.data enum class DataError { NO_ERROR, UNKNOWN_ERROR, - INSUFFICIENT_LIQUIDITY + INSUFFICIENT_LIQUIDITY, + CANNOT_SYNC } fun mapErrors(error: String?): DataError { return if (error == null) { DataError.UNKNOWN_ERROR - } else when (error) { - INSUFFICIENT_LIQUIDITY_ERROR -> DataError.INSUFFICIENT_LIQUIDITY + } else when { + error == INSUFFICIENT_LIQUIDITY_ERROR -> DataError.INSUFFICIENT_LIQUIDITY + error.startsWith(CANNOT_SYNC_ERROR) -> DataError.CANNOT_SYNC else -> DataError.UNKNOWN_ERROR } } -private const val INSUFFICIENT_LIQUIDITY_ERROR = "insufficient liquidity" \ No newline at end of file +private const val INSUFFICIENT_LIQUIDITY_ERROR = "insufficient liquidity" +private const val CANNOT_SYNC_ERROR = "cannot sync" \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/QuoteModel.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/QuoteModel.kt deleted file mode 100644 index 9a80b7c936..0000000000 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/QuoteModel.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.feature.swap.domain.models.data - -data class QuoteModel( - val fromTokenAmount: String, - val toTokenAmount: String, - val estimatedGas: Int, - val isAllowedToSpend: Boolean = false, -) \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/SwapState.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/SwapState.kt new file mode 100644 index 0000000000..7c269ea158 --- /dev/null +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/SwapState.kt @@ -0,0 +1,20 @@ +package com.tangem.feature.swap.domain.models.data + +sealed interface SwapState { + + data class QuoteModel( + val fromTokenAmount: String, + val toTokenAmount: String, + val estimatedGas: Int, + val isAllowedToSpend: Boolean = false, + ) : SwapState + + data class SwapSuccess( + val fromTokenAmount: String, + val toTokenAmount: String, + ) : SwapState + + data class SwapError( + val errorType: DataError, + ) : SwapState +} \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt index 84f79dad22..fd8a40070f 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt @@ -1,9 +1,13 @@ package com.tangem.feature.swap.viewmodels +import android.util.Log import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.tangem.feature.swap.domain.SwapInteractor +import com.tangem.feature.swap.domain.models.data.Currency import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel @@ -12,4 +16,28 @@ internal class SwapViewModel @Inject constructor( private val dispatchers: CoroutineDispatcherProvider, ) : ViewModel() { + // region temp for test + init { + viewModelScope.launch { + runCatching { + val tokens = referralInteractor.getTokensToSwap("binance-smart-chain") + val token = tokens[1] + val token2 = tokens[2] + if (token is Currency.NonNativeToken && token2 is Currency.NonNativeToken) { + findBestQuotes(token.contractAddress, token2.contractAddress) + } + }.onFailure { + Log.e("SwapViewModel", it.message ?: it.cause.toString()) + } + } + } + + private suspend fun findBestQuotes(fromTokenAddress: String, toTokenAddress: String) { + referralInteractor.findBestQuote( + fromTokenAddress, + toTokenAddress, + "1", + ) + } + // endregion temp for test } \ No newline at end of file