Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-12 10:33:18 +03:00
parent 0548571089
commit 4c8af6b8e9
5 changed files with 38 additions and 19 deletions

View file

@ -3,6 +3,7 @@ package com.tangem.features.send.v2.send.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.AnalyticsParam.Key.ACCOUNT_DERIVATION_FROM
import com.tangem.core.analytics.models.AnalyticsParam.Key.ACCOUNT_DERIVATION_TO
import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.ENS_ADDRESS
import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TOKEN
@ -29,14 +30,16 @@ internal sealed class SendAnalyticEvents(
val isNonceNotEmpty: Boolean,
private val ensStatus: AnalyticsParam.EmptyFull,
private val feeToken: String,
val derivationIndex: Int?,
private val fromDerivationIndex: Int?,
private val toDerivationIndex: Int?,
) : SendAnalyticEvents(
event = "Transaction Sent Screen Opened",
params = buildMap {
put(TOKEN_PARAM, token)
put(FEE_TYPE, feeType.value)
put(BLOCKCHAIN, blockchain)
if (derivationIndex != null) put(ACCOUNT_DERIVATION_FROM, derivationIndex.toString())
if (fromDerivationIndex != null) put(ACCOUNT_DERIVATION_FROM, fromDerivationIndex.toString())
if (toDerivationIndex != null) put(ACCOUNT_DERIVATION_TO, toDerivationIndex.toString())
put(NONCE, isNonceNotEmpty.toString().capitalize())
val ensAddress = when (ensStatus) {
AnalyticsParam.EmptyFull.Empty -> false.toString().capitalize()

View file

@ -4,7 +4,9 @@ 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.domain.account.status.usecase.GetAccountCurrencyByAddressUseCase
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.api.entity.FeeNonce
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
@ -16,9 +18,10 @@ import javax.inject.Inject
@ModelScoped
internal class SendAnalyticHelper @Inject constructor(
private val analyticsEventHandler: AnalyticsEventHandler,
private val getAccountCurrencyByAddressUseCase: GetAccountCurrencyByAddressUseCase,
) {
fun sendSuccessAnalytics(
suspend fun sendSuccessAnalytics(
cryptoCurrency: CryptoCurrency,
sendUM: SendUM,
feeToken: CryptoCurrency,
@ -28,11 +31,11 @@ internal class SendAnalyticHelper @Inject constructor(
val feeSelectorUM = sendUM.feeSelectorUM as? FeeSelectorUM.Content ?: return
val feeType = feeSelectorUM.toAnalyticType()
val feeTokenSymbol = feeToken.symbol
val derivationIndex = when (account) {
is Account.CryptoPortfolio -> if (!account.isMainAccount) account.derivationIndex else null
is Account.Payment -> null
null -> null
}
val fromDerivationIndex = account?.derivationIndex?.value
val destination = destinationUM?.addressTextField?.actualAddress ?: return
val destinationAccount = getAccountCurrencyByAddressUseCase(destination)
.getOrNull()?.account
val toDerivationIndex = destinationAccount?.derivationIndex?.value
analyticsEventHandler.send(
SendAnalyticEvents.TransactionScreenOpened(
token = cryptoCurrency.symbol,
@ -40,7 +43,8 @@ internal class SendAnalyticHelper @Inject constructor(
blockchain = cryptoCurrency.network.name,
isNonceNotEmpty = feeSelectorUM.feeNonce is FeeNonce.Nonce,
ensStatus = getEnsStatus(sendUM),
derivationIndex = derivationIndex?.value,
fromDerivationIndex = fromDerivationIndex,
toDerivationIndex = toDerivationIndex,
feeToken = feeTokenSymbol,
),
)
@ -52,7 +56,7 @@ internal class SendAnalyticHelper @Inject constructor(
feeType = feeType,
feeToken = feeTokenSymbol,
),
memoType = getSendTransactionMemoType(destinationUM?.memoTextField),
memoType = getSendTransactionMemoType(destinationUM.memoTextField),
),
)
}

View file

@ -24,7 +24,6 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.models.wallet.isHotWallet
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
@ -35,6 +34,7 @@ import com.tangem.domain.feedback.models.BlockchainErrorInfo
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.isHotWallet
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
import com.tangem.domain.settings.NeverShowTapHelpUseCase
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
@ -435,12 +435,14 @@ internal class SendConfirmModel @Inject constructor(
updateTransactionStatus(txData, txHash)
addTokenToWalletIfNeeded()
sendBalanceUpdater.scheduleUpdates()
sendAnalyticHelper.sendSuccessAnalytics(
cryptoCurrency = cryptoCurrency,
sendUM = uiState.value,
account = params.accountFlow.value,
feeToken = feeToken,
)
modelScope.launch(dispatchers.default) {
sendAnalyticHelper.sendSuccessAnalytics(
cryptoCurrency = cryptoCurrency,
sendUM = uiState.value,
account = params.accountFlow.value,
feeToken = feeToken,
)
}
params.callback.onResult(uiState.value)
params.onSendTransaction()
},

View file

@ -3,6 +3,7 @@ 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.ACCOUNT_DERIVATION_FROM
import com.tangem.core.analytics.models.AnalyticsParam.Key.ACCOUNT_DERIVATION_TO
import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE
import com.tangem.core.analytics.models.AnalyticsParam.Key.PROVIDER
import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_BLOCKCHAIN
@ -24,6 +25,7 @@ internal sealed class SendWithSwapAnalyticEvents(
val fromToken: CryptoCurrency,
val toToken: CryptoCurrency,
val fromDerivationIndex: Int?,
val toDerivationIndex: Int?,
) : SendWithSwapAnalyticEvents(
event = "Send With Swap In Progress Screen Opened",
params = buildMap {
@ -34,6 +36,7 @@ internal sealed class SendWithSwapAnalyticEvents(
put(SEND_BLOCKCHAIN, fromToken.network.name)
put(RECEIVE_BLOCKCHAIN, toToken.network.name)
if (fromDerivationIndex != null) put(ACCOUNT_DERIVATION_FROM, fromDerivationIndex.toString())
if (toDerivationIndex != null) put(ACCOUNT_DERIVATION_TO, toDerivationIndex.toString())
},
), AppsFlyerIncludedEvent

View file

@ -22,6 +22,7 @@ import com.tangem.core.ui.HoldToConfirmButtonFeatureToggles
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.account.status.usecase.GetAccountCurrencyByAddressUseCase
import com.tangem.domain.express.models.ExpressOperationType
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.models.account.derivationIndex
@ -92,6 +93,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
private val swapNotificationsUpdateTrigger: SwapNotificationsUpdateTrigger,
private val sendNotificationsUpdateListener: SendNotificationsUpdateListener,
private val swapNotificationsUpdateListener: SwapNotificationsUpdateListener,
private val getAccountCurrencyByAddressUseCase: GetAccountCurrencyByAddressUseCase,
private val swapAmountReduceTrigger: SwapAmountReduceTrigger,
private val swapAmountUpdateTrigger: SwapAmountUpdateTrigger,
private val feeSelectorReloadTrigger: FeeSelectorReloadTrigger,
@ -347,7 +349,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
txHash = txHash,
currency = primaryCurrencyStatus.currency,
).getOrNull().orEmpty()
sendSuccessAnalytics()
modelScope.launch(dispatchers.default) { sendSuccessAnalytics() }
uiState.transformerUpdate(
SendWithSwapConfirmSentStateTransformer(
timestamp = timestamp,
@ -454,13 +456,17 @@ internal class SendWithSwapConfirmModel @Inject constructor(
}.launchIn(modelScope)
}
private fun sendSuccessAnalytics() {
private suspend 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()
val fromDerivationIndex = confirmData.fromAccount?.derivationIndex?.value
val destination = destinationUM?.addressTextField?.actualAddress ?: return
val destinationAccount = getAccountCurrencyByAddressUseCase(destination)
.getOrNull()?.account
val toDerivationIndex = destinationAccount?.derivationIndex?.value
analyticsEventHandler.send(
SendWithSwapAnalyticEvents.TransactionScreenOpened(
@ -469,6 +475,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
fromToken = fromCurrency,
toToken = toCurrency,
fromDerivationIndex = fromDerivationIndex,
toDerivationIndex = toDerivationIndex,
),
)
analyticsEventHandler.send(