Updated on 2026-08-14

This commit is contained in:
Tangem 2023-11-14 14:22:43 +02:00
parent 95f66c8798
commit cfdcf4da41
16 changed files with 278 additions and 20 deletions

View file

@ -6,6 +6,9 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.extensions.Result
import com.tangem.data.tokens.utils.CryptoCurrencyFactory
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.express.TangemExpressApi
import com.tangem.datasource.api.express.models.request.PairsRequestBody
import com.tangem.datasource.api.oneinch.OneInchApi
import com.tangem.datasource.api.oneinch.OneInchApiFactory
import com.tangem.datasource.api.oneinch.OneInchErrorsHandler
@ -19,23 +22,23 @@ import com.tangem.domain.tokens.model.Network
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
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.converters.*
import com.tangem.feature.swap.domain.SwapRepository
import com.tangem.feature.swap.domain.models.data.AggregatedSwapDataModel
import com.tangem.feature.swap.domain.models.domain.Currency
import com.tangem.feature.swap.domain.models.domain.QuoteModel
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
import com.tangem.feature.swap.domain.models.domain.*
import com.tangem.feature.swap.domain.models.mapErrors
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext
import java.math.BigDecimal
import javax.inject.Inject
import com.tangem.blockchain.common.Token as SdkToken
import com.tangem.datasource.api.express.models.request.LeastTokenInfo as NetworkLeastTokenInfo
@Suppress("LongParameterList")
internal class SwapRepositoryImpl @Inject constructor(
private val tangemTechApi: TangemTechApi,
private val tangemExpressApi: TangemExpressApi,
private val oneInchApiFactory: OneInchApiFactory,
private val oneInchErrorsHandler: OneInchErrorsHandler,
private val coroutineDispatcher: CoroutineDispatcherProvider,
@ -46,6 +49,51 @@ internal class SwapRepositoryImpl @Inject constructor(
private val tokensConverter = TokensConverter()
private val quotesConverter = QuotesConverter()
private val swapConverter = SwapConverter()
private val leastTokenInfoConverter = LeastTokenInfoConverter()
private val swapPairInfoConverter = SwapPairInfoConverter()
override suspend fun getPairs(
initialCurrency: LeastTokenInfo,
currencyList: List<CryptoCurrency>,
): List<SwapPairLeast> {
return withContext(coroutineDispatcher.io) {
val initial = NetworkLeastTokenInfo(
contractAddress = initialCurrency.contractAddress,
network = initialCurrency.network,
)
val currenciesList = currencyList.map { leastTokenInfoConverter.convert(it) }
val pairs = async {
getPairsInternal(
from = arrayListOf(initial),
to = currenciesList,
)
}
val reversedPairs = async {
getPairsInternal(
from = currenciesList,
to = arrayListOf(initial),
)
}
pairs.await() + reversedPairs.await()
}
}
private suspend fun getPairsInternal(
from: List<NetworkLeastTokenInfo>,
to: List<NetworkLeastTokenInfo>,
): List<SwapPairLeast> {
return tangemExpressApi.getPairs(
PairsRequestBody(
from = from,
to = to,
),
)
.getOrThrow()
.map { swapPairInfoConverter.convert(it) }
}
override suspend fun getRates(currencyId: String, tokenIds: List<String>): Map<String, Double> {
// workaround cause backend do not return arbitrum and optimism rates

View file

@ -0,0 +1,17 @@
package com.tangem.feature.swap.converters
import com.tangem.blockchain.common.Blockchain
import com.tangem.datasource.api.express.models.request.LeastTokenInfo
import com.tangem.domain.common.extensions.toNetworkId
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.utils.converter.Converter
class LeastTokenInfoConverter : Converter<CryptoCurrency, LeastTokenInfo> {
override fun convert(value: CryptoCurrency): LeastTokenInfo {
return LeastTokenInfo(
contractAddress = (value as? CryptoCurrency.Token)?.contractAddress ?: "0",
network = Blockchain.fromId(value.id.rawNetworkId).toNetworkId(),
)
}
}

View file

@ -0,0 +1,43 @@
package com.tangem.feature.swap.converters
import com.tangem.datasource.api.express.models.response.RateType
import com.tangem.datasource.api.express.models.response.SwapPair
import com.tangem.datasource.api.express.models.response.SwapPairProvider
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
import com.tangem.feature.swap.domain.models.domain.SwapPairLeast as SwapPairDomain
import com.tangem.feature.swap.domain.models.domain.SwapPairProvider as SwapPairProviderDomain
import com.tangem.feature.swap.domain.models.domain.RateType as RateTypeDomain
import com.tangem.utils.converter.Converter
class SwapPairInfoConverter : Converter<SwapPair, SwapPairDomain> {
override fun convert(value: SwapPair): SwapPairDomain {
return SwapPairDomain(
from = LeastTokenInfo(
contractAddress = value.from.contractAddress,
network = value.from.network,
),
to = LeastTokenInfo(
contractAddress = value.to.contractAddress,
network = value.to.network,
),
providers = value.providers.map {
convertProvider(it)
},
)
}
private fun convertProvider(swapPairProvider: SwapPairProvider): SwapPairProviderDomain {
return SwapPairProviderDomain(
providerId = swapPairProvider.providerId,
rateTypes = swapPairProvider.rateTypes.map { convertRateType(it) },
)
}
private fun convertRateType(rateType: RateType): RateTypeDomain {
return when (rateType) {
RateType.FIXED -> RateTypeDomain.FIXED
RateType.FLOAT -> RateTypeDomain.FLOAT
}
}
}

View file

@ -1,5 +1,6 @@
package com.tangem.feature.swap.di
import com.tangem.datasource.api.express.TangemExpressApi
import com.tangem.datasource.api.oneinch.OneInchApiFactory
import com.tangem.datasource.api.oneinch.OneInchErrorsHandler
import com.tangem.datasource.api.tangemTech.TangemTechApi
@ -22,6 +23,7 @@ class SwapDataModule {
@Singleton
fun provideSwapRepository(
tangemTechApi: TangemTechApi,
tangemExpressApi: TangemExpressApi,
oneInchApiFactory: OneInchApiFactory,
oneInchErrorsHandler: OneInchErrorsHandler,
coroutineDispatcher: CoroutineDispatcherProvider,
@ -30,6 +32,7 @@ class SwapDataModule {
): SwapRepository {
return SwapRepositoryImpl(
tangemTechApi = tangemTechApi,
tangemExpressApi = tangemExpressApi,
oneInchApiFactory = oneInchApiFactory,
oneInchErrorsHandler = oneInchErrorsHandler,
coroutineDispatcher = coroutineDispatcher,