Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-06 15:45:04 +05:00
parent 5a42d4a84d
commit e6820c0898
18 changed files with 66 additions and 47 deletions

View file

@ -1,128 +0,0 @@
package com.tangem.features.send.v2.common.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
/**
* Send screen analytics
*/
internal sealed class CommonSendAnalyticEvents(
category: String,
event: String,
params: Map<String, String> = mapOf(),
) : AnalyticsEvent(category = category, event = event, params = params) {
/** Recipient address screen opened */
data class AddressScreenOpened(
val categoryName: String,
) : CommonSendAnalyticEvents(category = categoryName, event = "Address Screen Opened")
/** Amount screen opened */
data class AmountScreenOpened(
val categoryName: String,
) : CommonSendAnalyticEvents(category = categoryName, event = "Amount Screen Opened")
/** Fee screen opened */
data class FeeScreenOpened(
val categoryName: String,
) : CommonSendAnalyticEvents(category = categoryName, event = "Fee Screen Opened")
/** Confirmation screen opened */
data class ConfirmationScreenOpened(
val categoryName: String,
) : CommonSendAnalyticEvents(category = categoryName, event = "Confirm Screen Opened")
/** If transaction delays notification is present */
data class NoticeTransactionDelays(
val categoryName: String,
val token: String,
) : CommonSendAnalyticEvents(
category = categoryName,
event = "Notice - Transaction Delays Are Possible",
params = mapOf(TOKEN_PARAM to token),
)
/** If error occurs during send transactions */
data class TransactionError(
val categoryName: String,
val token: String,
val blockchain: String,
) : CommonSendAnalyticEvents(
category = categoryName,
event = "Error - Transaction Rejected",
params = mapOf(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
/** Close button clicked */
data class CloseButtonClicked(
val categoryName: String,
val source: SendScreenSource,
val isFromSummary: Boolean,
val isValid: Boolean,
) : CommonSendAnalyticEvents(
category = categoryName,
event = "Button - Close",
params = mapOf(
SOURCE to source.name,
"FromSummary" to if (isFromSummary) "Yes" else "No",
"isValid" to if (isValid) "Yes" else "No",
),
)
/** Share button clicked */
data class ShareButtonClicked(
val categoryName: String,
) : CommonSendAnalyticEvents(
category = categoryName,
event = "Button - Share",
)
/** Expore button clicked */
data class ExploreButtonClicked(
val categoryName: String,
) : CommonSendAnalyticEvents(
category = categoryName,
event = "Button - Explore",
)
/** Screen reopened from confirmation screen */
data class ScreenReopened(
val categoryName: String,
val source: SendScreenSource,
) : CommonSendAnalyticEvents(
category = categoryName,
event = "Screen Reopened",
params = mapOf(SOURCE to source.name),
)
/** Fee screen is closed with non empty nonce */
data class NonceInserted(
val categoryName: String,
val token: String,
val blockchain: String,
) : CommonSendAnalyticEvents(
category = categoryName,
event = "Nonce Inserted",
params = mapOf(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
companion object {
const val SEND_CATEGORY = "Token / Send"
const val NFT_SEND_CATEGORY = "NFT"
}
internal enum class SendScreenSource {
Address,
Amount,
Fee,
Confirm,
}
}

View file

@ -24,10 +24,10 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.SendComponent
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.ui.SendContent
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R

View file

@ -7,7 +7,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE
import com.tangem.core.analytics.models.AnalyticsParam.Key.NONCE
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
import com.tangem.core.ui.extensions.capitalize
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
/**
* Send screen analytics

View file

@ -38,6 +38,8 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.utils.convertToSdkAmount
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.FeeNonce
import com.tangem.features.send.v2.api.params.FeeSelectorParams.FeeStateConfiguration
@ -48,8 +50,6 @@ import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificat
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.SendBalanceUpdater
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.analytics.SendAnalyticHelper

View file

@ -14,10 +14,10 @@ import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.utils.formatFooterFiatFee
import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM

View file

@ -12,12 +12,12 @@ import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrency
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.feeSelector.utils.FeeCalculationUtils
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.api.utils.formatFooterFiatFee
import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toPersistentList

View file

@ -41,6 +41,8 @@ import com.tangem.domain.wallets.models.GetUserWalletError
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.send.v2.api.SendComponent
import com.tangem.features.send.v2.api.SendFeatureToggles
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.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent
@ -48,8 +50,6 @@ import com.tangem.features.send.v2.api.subcomponents.destination.entity.Destinat
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.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent

View file

@ -12,14 +12,17 @@ import com.tangem.core.navigation.share.ShareManager
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
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.common.CommonSendRoute
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
@Stable

View file

@ -20,10 +20,10 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.nft.component.NFTDetailsBlockComponent
import com.tangem.features.send.v2.api.NFTSendComponent
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.ui.SendContent
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R

View file

@ -7,7 +7,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE
import com.tangem.core.analytics.models.AnalyticsParam.Key.NONCE
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
import com.tangem.core.ui.extensions.capitalize
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
/**
* Send screen analytics

View file

@ -22,23 +22,23 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.BlockchainErrorInfo
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
import com.tangem.domain.settings.NeverShowTapHelpUseCase
import com.tangem.domain.transaction.usecase.CreateNFTTransferTransactionUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.features.nft.entity.NFTSendSuccessTrigger
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.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificationsUpdateListener
import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificationsUpdateTrigger
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.SendBalanceUpdater
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.sendnft.analytics.NFTSendAnalyticHelper

View file

@ -10,10 +10,10 @@ import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.utils.formatFooterFiatFee
import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM

View file

@ -1,31 +0,0 @@
package com.tangem.features.send.v2.subcomponents.amount.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam.Key.TYPE
internal sealed class SendAmountAnalyticEvents(
category: String,
event: String,
params: Map<String, String> = mapOf(),
) : AnalyticsEvent(category = category, event = event, params = params) {
/** Selected currency */
data class SelectedCurrency(
val categoryName: String,
val type: SelectedCurrencyType,
) : SendAmountAnalyticEvents(
category = categoryName,
event = "Selected Currency",
params = mapOf(TYPE to type.value),
)
/** Max amount button clicked */
data class MaxAmountButtonClicked(
val categoryName: String,
) : SendAmountAnalyticEvents(category = categoryName, event = "Max Amount Taped")
internal enum class SelectedCurrencyType(val value: String) {
Token("Token"),
AppCurrency("App Currency"),
}
}

View file

@ -30,14 +30,14 @@ import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.send.v2.api.SendFeatureToggles
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.api.subcomponents.amount.analytics.CommonSendAmountAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.amount.analytics.CommonSendAmountAnalyticEvents.SelectedCurrencyType
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParams
import com.tangem.features.send.v2.subcomponents.amount.SendAmountReduceListener
import com.tangem.features.send.v2.subcomponents.amount.SendAmountUpdateListener
import com.tangem.features.send.v2.subcomponents.amount.analytics.SendAmountAnalyticEvents
import com.tangem.features.send.v2.subcomponents.amount.analytics.SendAmountAnalyticEvents.SelectedCurrencyType
import com.tangem.features.send.v2.subcomponents.fee.SendFeeData
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadTrigger
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -218,7 +218,7 @@ internal class SendAmountModel @Inject constructor(
),
)
analyticsEventHandler.send(
SendAmountAnalyticEvents.MaxAmountButtonClicked(categoryName = analyticsCategoryName),
CommonSendAmountAnalyticEvents.MaxAmountButtonClicked(categoryName = analyticsCategoryName),
)
}
@ -229,7 +229,7 @@ internal class SendAmountModel @Inject constructor(
override fun onAmountNext() {
(uiState.value as? AmountState.Data)?.amountTextField?.isFiatValue?.let { isFiatSelected ->
analyticsEventHandler.send(
SendAmountAnalyticEvents.SelectedCurrency(
CommonSendAmountAnalyticEvents.SelectedCurrency(
categoryName = analyticsCategoryName,
type = if (isFiatSelected) {
SelectedCurrencyType.AppCurrency

View file

@ -26,12 +26,12 @@ import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase
import com.tangem.domain.txhistory.usecase.GetFixedTxHistoryItemsUseCase
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.send.v2.api.SendFeatureToggles
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.entity.PredefinedValues
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.destination.analytics.EnterAddressSource
import com.tangem.features.send.v2.subcomponents.destination.analytics.SendDestinationAnalyticEvents

View file

@ -1,39 +0,0 @@
package com.tangem.features.send.v2.subcomponents.fee.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
internal sealed class SendFeeAnalyticEvents(
category: String,
event: String,
params: Map<String, String> = mapOf(),
) : AnalyticsEvent(category = category, event = event, params = params) {
abstract val categoryName: String
/** Selected fee (send after next screen opened) */
data class SelectedFee(
override val categoryName: String,
val feeType: AnalyticsParam.FeeType,
) : SendFeeAnalyticEvents(
category = categoryName,
event = "Fee Selected",
params = mapOf("Fee Type" to feeType.value),
)
/** Custom fee selected */
data class CustomFeeButtonClicked(
override val categoryName: String,
) : SendFeeAnalyticEvents(
category = categoryName,
event = "Custom Fee Clicked",
)
/** Custom fee edited */
data class GasPriceInserter(
override val categoryName: String,
) : SendFeeAnalyticEvents(
category = categoryName,
event = "Gas Price Inserted",
)
}

View file

@ -11,14 +11,13 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.NonceInserted
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics.CommonSendFeeAnalyticEvents
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadListener
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadListener
import com.tangem.features.send.v2.subcomponents.fee.analytics.SendFeeAnalyticEvents
import com.tangem.features.send.v2.subcomponents.fee.analytics.SendFeeAnalyticEvents.GasPriceInserter
import com.tangem.features.send.v2.subcomponents.fee.model.transformers.*
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType
@ -112,7 +111,7 @@ internal class SendFeeModel @Inject constructor(
updateFeeNotifications()
if (feeType == FeeType.Custom) {
analyticsEventHandler.send(
SendFeeAnalyticEvents.CustomFeeButtonClicked(categoryName = analyticsCategoryName),
CommonSendFeeAnalyticEvents.CustomFeeButtonClicked(categoryName = analyticsCategoryName),
)
}
}
@ -155,10 +154,12 @@ internal class SendFeeModel @Inject constructor(
val isCustomFeeEdited =
feeSelectorUM.selectedFee?.amount?.value != feeSelectorUM.fees.normal.amount.value
if (feeSelectorUM.selectedType == FeeType.Custom && isCustomFeeEdited) {
analyticsEventHandler.send(GasPriceInserter(categoryName = analyticsCategoryName))
analyticsEventHandler.send(
CommonSendFeeAnalyticEvents.GasPriceInserter(categoryName = analyticsCategoryName),
)
}
analyticsEventHandler.send(
SendFeeAnalyticEvents.SelectedFee(
CommonSendFeeAnalyticEvents.SelectedFee(
categoryName = analyticsCategoryName,
feeType = feeSelectorUM.selectedType.toAnalyticType(feeSelectorUM),
),
@ -166,7 +167,7 @@ internal class SendFeeModel @Inject constructor(
if (feeSelectorUM.nonce != null) {
analyticsEventHandler.send(
NonceInserted(
CommonSendAnalyticEvents.NonceInserted(
categoryName = analyticsCategoryName,
token = cryptoCurrencyStatus.currency.symbol,
blockchain = cryptoCurrencyStatus.currency.network.name,