Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-08 13:31:42 +05:00
parent 94579f4af8
commit f69ee8bece
5 changed files with 98 additions and 21 deletions

View file

@ -161,6 +161,41 @@ sealed class SwapEvents(
),
)
class HighPriceImpact(
val sendToken: String,
val receiveToken: String,
val sendBlockchain: String,
val receiveBlockchain: String,
val providerName: String,
) : SwapEvents(
event = "Notice - High price impact",
params = mapOf(
SEND_TOKEN to sendToken,
RECEIVE_TOKEN to receiveToken,
"Send Blockchain" to sendBlockchain,
"Receive Blockchain" to receiveBlockchain,
PROVIDER to providerName,
),
)
class TradeTooLarge(
val sendToken: String,
val receiveToken: String,
val sendBlockchain: String,
val receiveBlockchain: String,
val providerName: String,
) : SwapEvents(
event = "Notice - Trade too large",
params = mapOf(
SEND_TOKEN to sendToken,
RECEIVE_TOKEN to receiveToken,
"Send Blockchain" to sendBlockchain,
"Receive Blockchain" to receiveBlockchain,
PROVIDER to providerName,
),
)
class NoticeProviderError(
val sendToken: String,
val receiveToken: String,

View file

@ -82,11 +82,7 @@ import com.tangem.feature.swap.domain.models.ExpressException
import com.tangem.feature.swap.domain.models.SwapAmount
import com.tangem.feature.swap.domain.models.domain.*
import com.tangem.feature.swap.domain.models.ui.*
import com.tangem.feature.swap.models.SwapAlertUM
import com.tangem.feature.swap.models.SwapCardState
import com.tangem.feature.swap.models.SwapStateHolder
import com.tangem.feature.swap.models.TransactionCardType
import com.tangem.feature.swap.models.UiActions
import com.tangem.feature.swap.models.*
import com.tangem.feature.swap.models.states.SwapNotificationUM
import com.tangem.feature.swap.router.SwapNavScreen
import com.tangem.feature.swap.router.SwapRouter
@ -712,7 +708,7 @@ internal class SwapModel @Inject constructor(
onSuccess = { providersState ->
if (providersState.isNotEmpty()) {
val (provider, state) = updateLoadedQuotes(providersState)
setupLoadedState(provider, state, fromToken)
setupLoadedState(provider = provider, state = state, fromToken = fromToken, toToken = toToken)
val successStates = providersState.getLastLoadedSuccessStates()
val pricesLowerBest = getPricesLowerBest(provider.providerId, successStates)
uiState = stateBuilder.updateProvidersBottomSheetContent(
@ -739,11 +735,16 @@ internal class SwapModel @Inject constructor(
)
}
private fun setupLoadedState(provider: SwapProvider, state: SwapState, fromToken: CryptoCurrencyStatus) {
private fun setupLoadedState(
provider: SwapProvider,
state: SwapState,
fromToken: CryptoCurrencyStatus,
toToken: CryptoCurrencyStatus?,
) {
when (state) {
is SwapState.QuotesLoadedState -> {
setupQuotesLoadedUiState(provider, state, fromToken)
sendAnalyticsForNotifications(fromToken)
sendAnalyticsForNotifications(provider, fromToken, toToken)
updatePermissionNotificationState(state)
}
is SwapState.EmptyAmountState -> {
@ -780,7 +781,11 @@ internal class SwapModel @Inject constructor(
)
}
private fun sendAnalyticsForNotifications(fromToken: CryptoCurrencyStatus) {
private fun sendAnalyticsForNotifications(
provider: SwapProvider,
fromToken: CryptoCurrencyStatus,
toToken: CryptoCurrencyStatus?,
) {
if (uiState.notifications.any { it is SwapNotificationUM.Error.UnableToCoverFeeWarning }) {
analyticsEventHandler.send(
SwapEvents.NoticeNotEnoughFee(
@ -789,6 +794,28 @@ internal class SwapModel @Inject constructor(
),
)
}
if (toToken != null && uiState.notifications.any { it is SwapNotificationUM.Warning.HighPriceImpact }) {
analyticsEventHandler.send(
SwapEvents.HighPriceImpact(
sendToken = fromToken.currency.symbol,
receiveToken = toToken.currency.network.name,
sendBlockchain = fromToken.currency.symbol,
receiveBlockchain = toToken.currency.network.name,
providerName = provider.name,
),
)
}
if (toToken != null && uiState.notifications.any { it is SwapNotificationUM.Warning.TradeTooHigh }) {
analyticsEventHandler.send(
SwapEvents.TradeTooLarge(
sendToken = fromToken.currency.symbol,
receiveToken = toToken.currency.network.name,
sendBlockchain = fromToken.currency.symbol,
receiveBlockchain = toToken.currency.network.name,
providerName = provider.name,
),
)
}
}
private fun updatePermissionNotificationState(state: SwapState.QuotesLoadedState) {
@ -1719,6 +1746,7 @@ internal class SwapModel @Inject constructor(
val provider = findAndSelectProvider(providerId)
val swapState = dataState.lastLoadedSwapStates[provider]
val fromToken = dataState.fromCryptoCurrency
val toToken = dataState.toCryptoCurrency
if (provider != null && swapState != null && fromToken != null) {
modelScope.launch {
feeSelectorRepository.state.value = FeeSelectorUM.Loading
@ -1730,6 +1758,7 @@ internal class SwapModel @Inject constructor(
provider = provider,
state = swapState,
fromToken = fromToken,
toToken = toToken,
)
}
},