Updated on 2026-08-14

This commit is contained in:
Tangem 2023-11-22 22:19:24 +02:00
parent ccc9090907
commit c4b1dceb65
6 changed files with 50 additions and 46 deletions

View file

@ -22,6 +22,7 @@ dependencies {
implementation(project(":data:common"))
implementation(project(":libs:auth"))
implementation(project(":libs:crypto"))
implementation(projects.domain.tokens.models)
implementation(deps.material)

View file

@ -6,8 +6,10 @@ import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.tokens.model.Quote
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.feature.swap.domain.cache.SwapDataCache
@ -44,6 +46,7 @@ internal class SwapInteractorImpl @Inject constructor(
private val walletFeatureToggles: WalletFeatureToggles,
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
private val getMultiCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase,
private val quotesRepository: QuotesRepository,
) : SwapInteractor {
// TODO: Move to DI
@ -389,32 +392,6 @@ internal class SwapInteractorImpl @Inject constructor(
}
}
@Suppress("UnusedPrivateMember")
@Deprecated("used in old swap mechanism")
private fun getTokensWithBalance(
tokens: List<Currency>,
balances: Map<String, SwapAmount>,
rates: Map<String, Double>,
appCurrency: ProxyFiatCurrency,
): List<TokenWithBalance> {
return tokens.map {
val balance = balances[it.symbol]
TokenWithBalance(
token = it,
tokenBalanceData = TokenBalanceData(
amount = balance?.let { amount ->
amountFormatter.formatSwapAmountToUI(amount, it.symbol)
},
amountEquivalent = balance?.value?.toFiatString(
rateValue = rates[it.id]?.toBigDecimal() ?: BigDecimal.ZERO,
fiatCurrencyName = appCurrency.symbol,
formatWithSpaces = true,
),
),
)
}
}
private suspend fun isAllowedToSpend(networkId: String, fromToken: CryptoCurrency, amount: SwapAmount): Boolean {
if (fromToken is CryptoCurrency.Coin) return true
return getSelectedWalletSyncUseCase().fold(
@ -538,8 +515,8 @@ internal class SwapInteractorImpl @Inject constructor(
private suspend fun getFormattedFiatFees(networkId: String, vararg fees: BigDecimal): List<String> {
val appCurrency = userWalletManager.getUserAppCurrency()
val nativeToken = userWalletManager.getNativeTokenForNetwork(networkId)
val rates = repository.getRates(appCurrency.code, listOf(nativeToken.id))
return rates[nativeToken.id]?.toBigDecimal()?.let { rate ->
val rates = getQuotes(nativeToken.id)
return rates[nativeToken.id]?.fiatRate?.let { rate ->
fees.map { fee ->
" (${fee.toFiatString(rate, appCurrency.symbol, true)})"
}
@ -629,28 +606,26 @@ internal class SwapInteractorImpl @Inject constructor(
val toToken = toTokenStatus.currency
val appCurrency = userWalletManager.getUserAppCurrency()
val nativeToken = userWalletManager.getNativeTokenForNetwork(networkId)
val rates = repository.getRates(
appCurrency.code,
listOf(fromToken.network.backendId, toToken.network.backendId, nativeToken.id),
)
val rates = getQuotes(fromToken.id, toToken.id, nativeToken.id)
return SwapState.QuotesLoadedState(
fromTokenInfo = TokenSwapInfo(
tokenAmount = fromTokenAmount,
cryptoCurrencyStatus = fromTokenStatus,
amountFiat = rates[fromToken.network.backendId]?.toBigDecimal()?.multiply(fromTokenAmount.value)
amountFiat = rates[fromToken.id]?.fiatRate?.multiply(fromTokenAmount.value)
?: BigDecimal.ZERO,
),
toTokenInfo = TokenSwapInfo(
tokenAmount = toTokenAmount,
cryptoCurrencyStatus = toTokenStatus,
amountFiat = rates[toToken.network.backendId]?.toBigDecimal()?.multiply(toTokenAmount.value)
amountFiat = rates[toToken.id]?.fiatRate?.multiply(toTokenAmount.value)
?: BigDecimal.ZERO,
),
priceImpact = calculatePriceImpact(
fromTokenAmount = fromTokenAmount.value,
fromRate = rates[fromToken.network.backendId] ?: 0.0,
fromRate = rates[fromToken.id]?.fiatRate?.toDouble() ?: 0.0,
toTokenAmount = toTokenAmount.value,
toRate = rates[toToken.network.backendId] ?: 0.0,
toRate = rates[toToken.id]?.fiatRate?.toDouble() ?: 0.0,
),
networkCurrency = userWalletManager.getNetworkCurrency(networkId),
swapDataModel = swapStateData,
@ -687,7 +662,7 @@ internal class SwapInteractorImpl @Inject constructor(
val feeData = transactionManager.getFee(
networkId = networkId,
amountToSend = BigDecimal.ZERO,
currencyToSend = userWalletManager.getNativeTokenForNetwork(networkId),
currencyToSend = swapCurrencyConverter.convert(userWalletManager.getNativeTokenForNetwork(networkId)),
destinationAddress = getTokenAddress(fromToken),
increaseBy = INCREASE_GAS_LIMIT_BY,
data = transactionData,
@ -863,6 +838,15 @@ internal class SwapInteractorImpl @Inject constructor(
)
}
private suspend fun getQuotes(vararg ids: CryptoCurrency.ID) : Map<CryptoCurrency.ID, Quote> {
val set = quotesRepository.getQuotesSync(ids.toSet(), false)
return ids
.mapNotNull { id -> set.find { it.rawCurrencyId == id.rawCurrencyId }?.let { id to it } }
.toMap()
}
companion object {
private const val DEFAULT_SLIPPAGE = 2

View file

@ -35,6 +35,7 @@ class SwapDomainModule {
walletFeatureToggles: WalletFeatureToggles,
@SwapScope getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
@SwapScope getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase,
quotesRepository: QuotesRepository,
): SwapInteractor {
return SwapInteractorImpl(
transactionManager = transactionManager,
@ -47,6 +48,7 @@ class SwapDomainModule {
walletFeatureToggles = walletFeatureToggles,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
getMultiCryptoCurrencyStatusUseCase = getCryptoCurrencyStatusUseCase,
quotesRepository = quotesRepository,
)
}