Updated on 2026-08-14
This commit is contained in:
parent
70617df9ad
commit
dfbec1dee4
5 changed files with 34 additions and 30 deletions
|
|
@ -34,10 +34,10 @@ internal object SwapAmountQuoteUtils {
|
|||
secondaryFiatRateUSD: BigDecimal?,
|
||||
primaryCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
secondaryCryptoCurrencyStatus: CryptoCurrencyStatus?,
|
||||
): PriceImpact {
|
||||
if (quoteContent == null) return PriceImpact.Empty
|
||||
): PriceImpact? {
|
||||
if (quoteContent == null) return null
|
||||
|
||||
val fromAmount = quoteContent.fromAmount ?: return PriceImpact.Empty
|
||||
val fromAmount = quoteContent.fromAmount ?: return null
|
||||
val toAmount = quoteContent.toAmount
|
||||
|
||||
val (fromRate, toRate) = if (swapDirection == SwapDirection.Direct) {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ internal fun SwapAmountBlockContent(
|
|||
val quoteContent = amountUM.selectedQuote as? SwapQuoteUM.Content
|
||||
val isBestRate = quoteContent?.diffPercent is SwapQuoteUM.Content.DifferencePercent.Best
|
||||
SwapChooseProviderContent(
|
||||
isBestRate = isBestRate && amountUM.priceImpact?.shouldShowWarning() == true,
|
||||
isBestRate = isBestRate && amountUM.priceImpact?.shouldShowWarning() != true,
|
||||
isSingleProvider = quoteContent?.isSingleProvider == true,
|
||||
showBestRateAnimation = amountUM.isShowBestRateAnimation,
|
||||
expressProvider = amountUM.selectedQuote.provider,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ import com.tangem.feature.swap.domain.models.toStringWithRightOffset
|
|||
import com.tangem.feature.swap.domain.models.ui.*
|
||||
import com.tangem.lib.crypto.BlockchainUtils.SOLANA_TRANSACTION_SIZE_THRESHOLD_BYTES
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
|
@ -2457,7 +2456,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
if (fromQuoteStatus == null) return PriceImpact.Empty
|
||||
|
||||
val fromTokenFiatValue = fromTokenAmount.multiply(fromQuoteStatus.fiatRate)
|
||||
val toTokenFiatValue = toTokenAmount.multiply(toRate.orZero())
|
||||
val toTokenFiatValue = toRate?.let { toTokenAmount.multiply(toRate) } ?: return PriceImpact.Empty
|
||||
|
||||
val value = BigDecimal.ONE - toTokenFiatValue.divide(fromTokenFiatValue, 2, RoundingMode.HALF_UP)
|
||||
|
||||
val fromAmountUSD = if (fromQuoteStatus.fiatRateUSD != BigDecimal.ZERO) {
|
||||
|
|
@ -2467,7 +2467,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
}
|
||||
|
||||
val amountSignificance = when {
|
||||
fromAmountUSD < PRICE_IMPACT_AMOUNT_MIN_THRESHOLD -> PriceImpact.AmountSignificance.LOW
|
||||
fromAmountUSD <= PRICE_IMPACT_AMOUNT_MIN_THRESHOLD -> PriceImpact.AmountSignificance.LOW
|
||||
fromAmountUSD > PRICE_IMPACT_AMOUNT_MAX_THRESHOLD -> PriceImpact.AmountSignificance.HIGH
|
||||
else -> PriceImpact.AmountSignificance.MEDIUM
|
||||
}
|
||||
|
|
@ -2552,7 +2552,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
companion object {
|
||||
private const val INCREASE_GAS_LIMIT_FOR_DEX = 112 // 12%
|
||||
private const val INCREASE_GAS_LIMIT_FOR_SEND = 105 // 5%
|
||||
private val PRICE_IMPACT_AMOUNT_MIN_THRESHOLD = 50.toBigDecimal() // in USD
|
||||
private val PRICE_IMPACT_AMOUNT_MIN_THRESHOLD = 25.toBigDecimal() // in USD
|
||||
private val PRICE_IMPACT_AMOUNT_MAX_THRESHOLD = 5000.toBigDecimal() // in USD
|
||||
private val PRICE_IMPACT_LOW_THRESHOLD = 0.1.toBigDecimal() // 10%
|
||||
private val PRICE_IMPACT_HIGH_THRESHOLD = 0.5.toBigDecimal() // 50%
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ data class PriceImpact(
|
|||
return type == Type.HIGH && amountSignificance == AmountSignificance.HIGH
|
||||
}
|
||||
|
||||
fun shouldShowWarning(): Boolean {
|
||||
return type.ordinal > Type.LOW.ordinal || amountSignificance.ordinal > AmountSignificance.LOW.ordinal
|
||||
}
|
||||
|
||||
companion object {
|
||||
val Empty = PriceImpact(
|
||||
value = BigDecimal.ZERO,
|
||||
|
|
|
|||
|
|
@ -387,26 +387,26 @@ internal class StateBuilder(
|
|||
.formatToUIRepresentation()
|
||||
.appendApproximateSign(),
|
||||
),
|
||||
amountEquivalent = combinedReference(
|
||||
getFormattedFiatAmount(quoteModel.toTokenInfo.amountFiat),
|
||||
stringReference(StringsSigns.WHITE_SPACE),
|
||||
styledStringReference(
|
||||
priceImpact.value.format {
|
||||
percent(withoutSign = false)
|
||||
},
|
||||
spanStyleReference = {
|
||||
SpanStyle(
|
||||
color = when (priceImpact.type) {
|
||||
PriceImpact.Type.HIGH -> TangemTheme.colors.text.warning
|
||||
PriceImpact.Type.MEDIUM -> TangemTheme.colors.text.attention
|
||||
PriceImpact.Type.LOW,
|
||||
PriceImpact.Type.NONE,
|
||||
-> TangemTheme.colors.text.tertiary
|
||||
},
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
amountEquivalent = if (priceImpact.type.ordinal > PriceImpact.Type.LOW.ordinal) {
|
||||
combinedReference(
|
||||
getFormattedFiatAmount(quoteModel.toTokenInfo.amountFiat),
|
||||
stringReference(StringsSigns.WHITE_SPACE),
|
||||
styledStringReference(
|
||||
value = "(${StringsSigns.MINUS}${priceImpact.value.format { percent() }})",
|
||||
spanStyleReference = {
|
||||
SpanStyle(
|
||||
color = when (priceImpact.type) {
|
||||
PriceImpact.Type.HIGH -> TangemTheme.colors.text.warning
|
||||
PriceImpact.Type.MEDIUM -> TangemTheme.colors.text.attention
|
||||
else -> TangemTheme.colors.text.tertiary
|
||||
},
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
getFormattedFiatAmount(quoteModel.toTokenInfo.amountFiat)
|
||||
},
|
||||
token = toCurrencyStatus,
|
||||
tokenIconUrl = uiStateHolder.receiveCardData.tokenIconUrl,
|
||||
coinId = toCurrencyStatus.currency.network.backendId,
|
||||
|
|
@ -436,7 +436,7 @@ internal class StateBuilder(
|
|||
),
|
||||
changeCardsButtonState = getChangeCardsButtonState(isReverseSwapPossible),
|
||||
providerState = swapProvider.convertToContentClickableProviderState(
|
||||
isBestRate = bestRatedProviderId == swapProvider.providerId,
|
||||
isBestRate = bestRatedProviderId == swapProvider.providerId && !priceImpact.shouldShowWarning(),
|
||||
fromTokenInfo = quoteModel.fromTokenInfo,
|
||||
toTokenInfo = quoteModel.toTokenInfo,
|
||||
isNeedBestRateBadge = isNeedBestRateBadge,
|
||||
|
|
@ -444,7 +444,7 @@ internal class StateBuilder(
|
|||
onProviderClick = actions.onProviderClick,
|
||||
needApplyFCARestrictions = needApplyFCARestrictions,
|
||||
),
|
||||
priceImpact = quoteModel.priceImpact,
|
||||
priceImpact = priceImpact,
|
||||
tosState = createTosState(swapProvider),
|
||||
shouldShowMaxAmount = shouldShowMaxAmount(fromToken, toCurrencyStatus.currency),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue