Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-08 15:36:53 +05:00
commit 2f7c5451e6
15 changed files with 233 additions and 28 deletions

View file

@ -120,6 +120,12 @@ sealed class AnalyticsParam {
override val token: String,
override val feeType: FeeType,
) : TxSentFrom("NFT"), TxData
data class SendWithSwap(
override val blockchain: String,
override val token: String,
override val feeType: FeeType,
) : TxSentFrom("Send&Swap"), TxData
}
sealed interface TxData {
@ -224,5 +230,9 @@ sealed class AnalyticsParam {
const val STANDARD = "Standard"
const val NO_COLLECTION = "No collection"
const val EMULATION_STATUS = "Emulation Status"
const val SEND_TOKEN = "Send Token"
const val RECEIVE_TOKEN = "Receive Token"
const val SEND_BLOCKCHAIN = "Send Blockchain"
const val RECEIVE_BLOCKCHAIN = "Receive Blockchain"
}
}

View file

@ -3,9 +3,11 @@ package com.tangem.features.send.v2.api.entity
import androidx.compose.runtime.Immutable
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.features.send.v2.api.entity.FeeItem.*
import kotlinx.collections.immutable.ImmutableList
import java.math.BigDecimal
import java.math.BigInteger
@ -31,7 +33,19 @@ sealed class FeeSelectorUM {
val feeExtraInfo: FeeExtraInfo,
val feeFiatRateUM: FeeFiatRateUM?,
val feeNonce: FeeNonce,
) : FeeSelectorUM()
) : FeeSelectorUM() {
fun toAnalyticType(): AnalyticsParam.FeeType = when (fees) {
is TransactionFee.Single -> AnalyticsParam.FeeType.Fixed
is TransactionFee.Choosable -> when (selectedFeeItem) {
is Suggested,
is Custom,
-> AnalyticsParam.FeeType.Custom
is Fast -> AnalyticsParam.FeeType.Max
is Market -> AnalyticsParam.FeeType.Normal
is Slow -> AnalyticsParam.FeeType.Min
}
}
}
}
@Immutable

View file

@ -90,13 +90,15 @@ internal class DefaultSendComponent @AssistedInject constructor(
) { stack ->
componentScope.launch {
when (val activeComponent = stack.active.instance) {
is SendConfirmComponent -> if (model.currentRoute.value.isEditMode) {
is SendConfirmComponent -> {
analyticsEventHandler.send(
CommonSendAnalyticEvents.ConfirmationScreenOpened(
categoryName = model.analyticCategoryName,
),
)
activeComponent.updateState(model.uiState.value)
if (model.currentRoute.value.isEditMode) {
activeComponent.updateState(model.uiState.value)
}
}
is SendAmountComponent -> {
analyticsEventHandler.send(

View file

@ -32,4 +32,15 @@ internal sealed class SendAnalyticEvents(
NONCE to nonceNotEmpty.toString().capitalize(),
),
)
data class ConvertTokenButtonClicked(
val token: String,
val blockchain: String,
) : SendAnalyticEvents(
event = "Button - Convert Token",
params = mapOf(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
}

View file

@ -51,6 +51,7 @@ import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.CommonSendRoute.*
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.send.analytics.SendAnalyticEvents
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
import com.tangem.features.send.v2.send.ui.state.SendUM
@ -227,6 +228,12 @@ internal class SendModel @Inject constructor(
}
override fun onConvertToAnotherToken(lastAmount: String) {
analyticsEventHandler.send(
SendAnalyticEvents.ConvertTokenButtonClicked(
token = cryptoCurrency.symbol,
blockchain = cryptoCurrency.network.name,
),
)
params.callback?.onConvertToAnotherToken(lastAmount = lastAmount)
}

View file

@ -30,6 +30,7 @@ dependencies {
implementation(projects.core.navigation)
implementation(projects.core.configToggles)
implementation(projects.core.datasource)
implementation(projects.core.analytics)
/** Common */
implementation(projects.common.ui)

View file

@ -6,7 +6,6 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.activate
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.arkivanov.essenty.lifecycle.subscribe
@ -69,20 +68,7 @@ internal class SwapAmountBlockComponent(
isClickEnabled = isClickEnabled,
onClick = onClick,
onFinishAnimation = model::onFinishAnimation,
onProviderSelectClick = {
val amountUM = model.uiState.value as? SwapAmountUM.Content ?: return@SwapAmountBlockContent
val selectedProvider = amountUM.selectedQuote.provider ?: return@SwapAmountBlockContent
val cryptoCurrency = params.secondaryCryptoCurrency ?: return@SwapAmountBlockContent
model.bottomSheetNavigation.activate(
SwapChooseProviderConfig(
providers = amountUM.swapQuotes,
cryptoCurrency = cryptoCurrency,
selectedProvider = selectedProvider,
userCountry = model.userCountry,
),
)
},
onProviderSelectClick = model::onProviderClick,
)
bottomSheet.child?.instance?.BottomSheet()

View file

@ -0,0 +1,27 @@
package com.tangem.features.swap.v2.impl.amount.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam.Key.PROVIDER
internal sealed class SwapAmountAnalyticEvents(
category: String,
event: String,
params: Map<String, String> = mapOf(),
) : AnalyticsEvent(category = category, event = event, params = params) {
data class ProviderSelectorClicked(
val categoryName: String,
) : SwapAmountAnalyticEvents(
category = categoryName,
event = "Provider Clicked",
)
data class ProviderChosen(
val categoryName: String,
val providerName: String,
) : SwapAmountAnalyticEvents(
category = categoryName,
event = "Provider Chosen",
params = mapOf(PROVIDER to providerName),
)
}

View file

@ -9,4 +9,5 @@ internal interface SwapAmountClickIntents : AmountScreenClickIntents {
fun onInfoClick()
fun onSelectTokenClick()
fun onSeparatorClick()
fun onProviderClick()
}

View file

@ -2,6 +2,7 @@ package com.tangem.features.swap.v2.impl.amount.model
import arrow.core.getOrElse
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
@ -10,6 +11,7 @@ import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.navigationButtons.NavigationButton
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.common.ui.notifications.NotificationId
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
@ -33,6 +35,7 @@ import com.tangem.domain.swap.usecase.GetSwapQuoteUseCase
import com.tangem.domain.swap.usecase.SelectInitialPairUseCase
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
import com.tangem.domain.transaction.usecase.GetAllowanceUseCase
import com.tangem.features.send.v2.api.subcomponents.amount.analytics.CommonSendAmountAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.swap.v2.api.choosetoken.SwapChooseTokenNetworkListener
import com.tangem.features.swap.v2.impl.R
@ -40,6 +43,7 @@ import com.tangem.features.swap.v2.impl.amount.SwapAmountBlockComponent.SwapChoo
import com.tangem.features.swap.v2.impl.amount.SwapAmountComponentParams
import com.tangem.features.swap.v2.impl.amount.SwapAmountReduceListener
import com.tangem.features.swap.v2.impl.amount.SwapAmountUpdateListener
import com.tangem.features.swap.v2.impl.amount.analytics.SwapAmountAnalyticEvents
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountFieldUM
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountType
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM
@ -86,6 +90,7 @@ internal class SwapAmountModel @Inject constructor(
private val swapAmountReduceListener: SwapAmountReduceListener,
private val feeSelectorReloadTrigger: FeeSelectorReloadTrigger,
private val shouldShowNotificationUseCase: ShouldShowNotificationUseCase,
private val analyticsEventHandler: AnalyticsEventHandler,
) : Model(), SwapAmountClickIntents, SwapChooseProviderComponent.ModelCallback {
private val params: SwapAmountComponentParams = paramsContainer.require()
@ -146,6 +151,12 @@ internal class SwapAmountModel @Inject constructor(
}
override fun onProviderResult(quoteUM: SwapQuoteUM) {
analyticsEventHandler.send(
SwapAmountAnalyticEvents.ProviderChosen(
categoryName = params.analyticsCategoryName,
providerName = quoteUM.provider?.name.orEmpty(),
),
)
uiState.transformerUpdate(
SwapAmountSelectQuoteTransformer(
quoteUM = quoteUM,
@ -201,6 +212,9 @@ internal class SwapAmountModel @Inject constructor(
}
override fun onMaxValueClick() {
analyticsEventHandler.send(
CommonSendAmountAnalyticEvents.MaxAmountButtonClicked(categoryName = params.analyticsCategoryName),
)
uiState.transformerUpdate(
SwapAmountValueMaxTransformer(
primaryMaximumAmountBoundary = primaryMaximumAmountBoundary,
@ -221,6 +235,23 @@ internal class SwapAmountModel @Inject constructor(
}
override fun onAmountNext() {
val amountState = uiState.value.swapDirection.withSwapDirection(
onDirect = { uiState.value.primaryAmount.amountField },
onReverse = { uiState.value.secondaryAmount.amountField },
) as? AmountState.Data
amountState?.amountTextField?.isFiatValue?.let { isFiatSelected ->
analyticsEventHandler.send(
CommonSendAmountAnalyticEvents.SelectedCurrency(
categoryName = params.analyticsCategoryName,
type = if (isFiatSelected) {
CommonSendAmountAnalyticEvents.SelectedCurrencyType.AppCurrency
} else {
CommonSendAmountAnalyticEvents.SelectedCurrencyType.Token
},
),
)
}
saveResult()
}
@ -266,10 +297,30 @@ internal class SwapAmountModel @Inject constructor(
}
}
override fun onProviderClick() {
val amountUM = uiState.value as? SwapAmountUM.Content ?: return
val selectedProvider = amountUM.selectedQuote.provider ?: return
val cryptoCurrency = params.secondaryCryptoCurrency ?: return
analyticsEventHandler.send(
SwapAmountAnalyticEvents.ProviderSelectorClicked(
categoryName = params.analyticsCategoryName,
),
)
bottomSheetNavigation.activate(
SwapChooseProviderConfig(
providers = amountUM.swapQuotes,
cryptoCurrency = cryptoCurrency,
selectedProvider = selectedProvider,
userCountry = userCountry,
),
)
}
private fun confirmSendWithSwapClose() {
val amountParams = params as? SwapAmountComponentParams.AmountParams ?: return
val amountFieldData = uiState.value.primaryAmount.amountField as? AmountState.Data
val callback = (params as? SwapAmountComponentParams.AmountParams)?.callback ?: return
val primaryCryptoCurrencyStatus = (uiState.value as? SwapAmountUM.Content)?.primaryCryptoCurrencyStatus
if (primaryCryptoCurrencyStatus != null) {
@ -625,7 +676,7 @@ internal class SwapAmountModel @Inject constructor(
},
isEnabled = state.isPrimaryButtonEnabled,
onClick = {
saveResult()
onAmountNext()
params.callback.onNextClick()
},
),

View file

@ -12,6 +12,8 @@ internal object SwapAmountClickIntentsStub : SwapAmountClickIntents {
override fun onSeparatorClick() {}
override fun onProviderClick() {}
override fun onAmountValueChange(value: String) {}
override fun onAmountPasteTriggerDismiss() {}

View file

@ -12,6 +12,7 @@ import com.arkivanov.decompose.router.stack.pop
import com.arkivanov.decompose.value.ObserveLifecycleMode
import com.arkivanov.decompose.value.subscribe
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
@ -21,6 +22,7 @@ import com.tangem.core.ui.decompose.getEmptyComposableContentComponent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.swap.models.R
import com.tangem.domain.swap.models.SwapDirection
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.destination.DestinationRoute
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
@ -44,6 +46,7 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
@Assisted private val params: SendWithSwapComponent.Params,
private val sendDestinationComponentFactory: SendDestinationComponent.Factory,
private val confirmComponentFactory: SendWithSwapConfirmComponent.Factory,
private val analyticsEventHandler: AnalyticsEventHandler,
) : SendWithSwapComponent, AppComponentContext by appComponentContext {
private val stackNavigation = StackNavigation<SendWithSwapRoute>()
@ -80,15 +83,23 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
componentScope.launch {
when (val activeComponent = stack.active.instance) {
is SwapAmountComponent -> {
// todo send with swap analytics
analyticsEventHandler.send(
CommonSendAnalyticEvents.AmountScreenOpened(categoryName = model.analyticCategoryName),
)
activeComponent.updateState(model.uiState.value.amountUM)
}
is SendDestinationComponent -> {
// todo send with swap analytics
analyticsEventHandler.send(
CommonSendAnalyticEvents.AddressScreenOpened(categoryName = model.analyticCategoryName),
)
activeComponent.updateState(model.uiState.value.destinationUM)
}
is SendWithSwapConfirmComponent -> if (model.currentRoute.value.isEditMode) {
// todo send with swap analytics
analyticsEventHandler.send(
CommonSendAnalyticEvents.ConfirmationScreenOpened(
categoryName = model.analyticCategoryName,
),
)
activeComponent.updateState(model.uiState.value)
}
}
@ -125,7 +136,7 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
title = resourceReference(R.string.common_send),
currentRoute = model.currentRoute.filterIsInstance<SendWithSwapRoute.Amount>(),
isBalanceHidingFlow = model.isBalanceHiddenFlow,
analyticsCategoryName = "",
analyticsCategoryName = model.analyticCategoryName,
primaryCryptoCurrencyStatusFlow = model.primaryCryptoCurrencyStatusFlow,
secondaryCryptoCurrency = null,
swapDirection = SwapDirection.Direct,
@ -148,7 +159,7 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
state = model.uiState.value.destinationUM,
currentRoute = model.currentRoute.filterIsInstance<DestinationRoute>(),
isBalanceHidingFlow = model.isBalanceHiddenFlow,
analyticsCategoryName = "",
analyticsCategoryName = model.analyticCategoryName,
title = resourceReference(R.string.send_recipient_label),
userWalletId = params.userWalletId,
cryptoCurrency = secondaryCryptoCurrency,
@ -167,7 +178,7 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
appCurrency = model.appCurrency,
userWallet = model.userWallet,
callback = model,
analyticsCategoryName = "",
analyticsCategoryName = model.analyticCategoryName,
primaryCryptoCurrencyStatusFlow = model.primaryCryptoCurrencyStatusFlow,
primaryFeePaidCurrencyStatusFlow = model.primaryFeePaidCurrencyStatusFlow,
swapDirection = SwapDirection.Direct,
@ -182,7 +193,7 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
sendWithSwapUMFlow = model.uiState,
currentRoute = model.currentRoute.filterIsInstance<SendWithSwapRoute.Success>(),
callback = model,
analyticsCategoryName = "",
analyticsCategoryName = model.analyticCategoryName,
),
)
}

View file

@ -0,0 +1,34 @@
package com.tangem.features.swap.v2.impl.sendviaswap.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.AnalyticsParam.Key.PROVIDER
import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_TOKEN
import com.tangem.core.analytics.models.AnalyticsParam.Key.SEND_BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.SEND_TOKEN
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
internal sealed class SendWithSwapAnalyticEvents(
event: String,
params: Map<String, String> = mapOf(),
) : AnalyticsEvent(category = CommonSendAnalyticEvents.SEND_CATEGORY, event = event, params = params) {
data class TransactionScreenOpened(
val providerName: String,
val feeType: AnalyticsParam.FeeType,
val fromToken: CryptoCurrency,
val toToken: CryptoCurrency,
) : SendWithSwapAnalyticEvents(
event = "Send With Swap In Progress Screen Opened",
params = mapOf(
PROVIDER to providerName,
"Commission" to if (feeType is AnalyticsParam.FeeType.Normal) "Market" else "Fast",
SEND_TOKEN to fromToken.symbol,
RECEIVE_TOKEN to toToken.symbol,
SEND_BLOCKCHAIN to fromToken.network.name,
RECEIVE_BLOCKCHAIN to toToken.network.name,
),
)
}

View file

@ -9,6 +9,9 @@ import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.navigationButtons.NavigationButton
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
@ -25,6 +28,8 @@ import com.tangem.domain.transaction.usecase.EstimateFeeUseCase
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.features.send.v2.api.SendNotificationsComponent
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
@ -43,6 +48,7 @@ import com.tangem.features.swap.v2.impl.notifications.SwapNotificationsComponent
import com.tangem.features.swap.v2.impl.notifications.SwapNotificationsUpdateListener
import com.tangem.features.swap.v2.impl.notifications.SwapNotificationsUpdateTrigger
import com.tangem.features.swap.v2.impl.sendviaswap.SendWithSwapRoute
import com.tangem.features.swap.v2.impl.sendviaswap.analytics.SendWithSwapAnalyticEvents
import com.tangem.features.swap.v2.impl.sendviaswap.confirm.SendWithSwapConfirmComponent
import com.tangem.features.swap.v2.impl.sendviaswap.confirm.model.transformers.SendWithSwapConfirmInitialStateTransformer
import com.tangem.features.swap.v2.impl.sendviaswap.confirm.model.transformers.SendWithSwapConfirmationNotificationsTransformer
@ -73,6 +79,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
private val feeSelectorReloadTrigger: FeeSelectorReloadTrigger,
private val swapAlertFactory: SwapAlertFactory,
private val appRouter: AppRouter,
private val analyticsEventHandler: AnalyticsEventHandler,
swapTransactionSenderFactory: SwapTransactionSender.Factory,
paramsContainer: ParamsContainer,
) : Model(), FeeSelectorModelCallback, SendNotificationsComponent.ModelCallback {
@ -185,10 +192,22 @@ internal class SendWithSwapConfirmModel @Inject constructor(
}
fun showEditAmount() {
analyticsEventHandler.send(
CommonSendAnalyticEvents.ScreenReopened(
categoryName = params.analyticsCategoryName,
source = SendScreenSource.Amount,
),
)
router.push(SendWithSwapRoute.Amount(isEditMode = true))
}
fun showEditDestination() {
analyticsEventHandler.send(
CommonSendAnalyticEvents.ScreenReopened(
categoryName = params.analyticsCategoryName,
source = SendScreenSource.Address,
),
)
router.push(SendWithSwapRoute.Destination(isEditMode = true))
}
@ -260,7 +279,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
txHash = txHash,
networkId = primaryCurrencyStatus.currency.network.id,
).getOrNull().orEmpty()
sendSuccessAnalytics()
uiState.update {
it.copy(
confirmUM = ConfirmUM.Success(
@ -348,6 +367,33 @@ internal class SendWithSwapConfirmModel @Inject constructor(
}.launchIn(modelScope)
}
private fun sendSuccessAnalytics() {
val selectedProvider = confirmData.quote?.provider ?: return
val fromCurrency = confirmData.fromCryptoCurrencyStatus?.currency ?: return
val toCurrency = confirmData.toCryptoCurrencyStatus?.currency ?: return
val feeSelectorUM = uiState.value.feeSelectorUM as? FeeSelectorUM.Content ?: return
val feeType = feeSelectorUM.toAnalyticType()
analyticsEventHandler.send(
SendWithSwapAnalyticEvents.TransactionScreenOpened(
providerName = selectedProvider.name,
feeType = feeType,
fromToken = fromCurrency,
toToken = toCurrency,
),
)
analyticsEventHandler.send(
Basic.TransactionSent(
sentFrom = AnalyticsParam.TxSentFrom.SendWithSwap(
blockchain = fromCurrency.network.name,
token = fromCurrency.symbol,
feeType = feeType,
),
memoType = Basic.TransactionSent.MemoType.Null,
),
)
}
private fun configConfirmNavigation() {
combine(
flow = uiState,

View file

@ -21,6 +21,7 @@ import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
@ -58,6 +59,7 @@ internal class SendWithSwapModel @Inject constructor(
private val params: SendWithSwapComponent.Params = paramsContainer.require()
val analyticCategoryName = CommonSendAnalyticEvents.SEND_CATEGORY
val initialRoute = SendWithSwapRoute.Amount(false)
val currentRoute = MutableStateFlow<SendWithSwapRoute>(initialRoute)