Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-21 17:12:52 +03:00
parent 309f1cda20
commit 081128f2cf
16 changed files with 40 additions and 50 deletions

View file

@ -26,8 +26,9 @@ class AppsFlyerAnalyticsHandler(
}
is AppsFlyerIncludedEvent -> {
Timber.tag("AppsFlyer").i("Sending event to AppsFlyer: ${event.id} with params: ${event.params}")
val replacedEvent = event.appsFlyerReplacedEvent ?: event.event
client.logEvent(
event = AnalyticsEvent(category = event.category, event = event.appsFlyerReplacedEvent).id,
event = AnalyticsEvent(category = event.category, event = replacedEvent).id,
params = event.params,
)
}

View file

@ -11,5 +11,6 @@ interface AppsFlyerOnlyEvent
* Events implementing this interface will be sent to AppsFlyer along with other analytics handlers
*/
interface AppsFlyerIncludedEvent {
val appsFlyerReplacedEvent: String
val appsFlyerReplacedEvent: String?
get() = null
}

View file

@ -93,7 +93,7 @@ sealed class Basic(
}
this["Memo"] = memoType.name
},
) {
), AppsFlyerIncludedEvent {
enum class MemoType {
Empty, Full, Null
}

View file

@ -3,7 +3,6 @@ package com.tangem.core.analytics.models.event
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.core.analytics.models.AppsFlyerOnlyEvent
sealed class OnboardingAnalyticsEvent(
category: String,
@ -16,8 +15,6 @@ sealed class OnboardingAnalyticsEvent(
params: Map<String, String> = mapOf(),
) : OnboardingAnalyticsEvent(category = "Onboarding", event = event, params = params) {
class AppsFlyerOnlyEntryScreenView : Onboarding(event = "wallet_entry_screen_view"), AppsFlyerOnlyEvent
class Started(
source: String,
) : Onboarding(
@ -68,12 +65,7 @@ sealed class OnboardingAnalyticsEvent(
put("Seed Phrase Length", seedPhraseLength.toString())
}
},
), AppsFlyerIncludedEvent {
override val appsFlyerReplacedEvent = when (creationType) {
WalletCreationType.NewSeed -> "wallet_created_successfully"
WalletCreationType.SeedImport -> "wallet_imported"
}
}
), AppsFlyerIncludedEvent
sealed class WalletCreationType(val value: String) {
data object NewSeed : WalletCreationType(value = "New Seed")
@ -93,7 +85,7 @@ sealed class OnboardingAnalyticsEvent(
params = mapOf(
AnalyticsParam.SOURCE to source,
),
)
), AppsFlyerIncludedEvent
class ButtonImportWallet : SeedPhrase("Button - Import Wallet")
class ImportSeedPhraseScreenOpened : SeedPhrase("Import Seed Phrase Screen Opened")

View file

@ -8,6 +8,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.PROVIDER
import com.tangem.core.analytics.models.AnalyticsParam.Key.RESIDENCE
import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.domain.onramp.model.OnrampSource
sealed class OnrampAnalyticsEvent(
@ -28,7 +29,7 @@ sealed class OnrampAnalyticsEvent(
SOURCE to source.analyticsName,
TOKEN_PARAM to tokenSymbol,
),
)
), AppsFlyerIncludedEvent
class SelectCurrencyScreenOpened : OnrampAnalyticsEvent(event = "Currency Screen Opened")
@ -133,7 +134,7 @@ sealed class OnrampAnalyticsEvent(
"Currency Type" to currency,
PAYMENT_METHOD to paymentMethod,
),
)
), AppsFlyerIncludedEvent
class MinAmountError : OnrampAnalyticsEvent(event = "Error - Min Amount")
class MaxAmountError : OnrampAnalyticsEvent(event = "Error - Max Amount")

View file

@ -2,6 +2,7 @@ package com.tangem.domain.staking.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.domain.staking.model.stakekit.StakingError
import com.tangem.domain.models.staking.action.StakingActionType
@ -21,7 +22,7 @@ sealed class StakingAnalyticsEvent(
params = mapOf(
"Validators Count" to validatorsCount.toString(),
),
)
), AppsFlyerIncludedEvent
class WhatIsStaking : StakingAnalyticsEvent(
event = "Link - What Is Staking",
@ -40,7 +41,7 @@ sealed class StakingAnalyticsEvent(
"Validator" to validator,
"Action" to action.asAnalyticName,
),
)
), AppsFlyerIncludedEvent
data class StakeInProgressScreenOpened(
val validator: String,
@ -51,7 +52,7 @@ sealed class StakingAnalyticsEvent(
"Validator" to validator,
"Action" to action.asAnalyticName,
),
)
), AppsFlyerIncludedEvent
class RewardScreenOpened : StakingAnalyticsEvent(
event = "Reward Screen Opened",

View file

@ -4,6 +4,7 @@ import com.domain.blockaid.models.dapp.CheckDAppResult
import com.domain.blockaid.models.dapp.CheckDAppResult.*
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.domain.models.network.Network
import com.tangem.domain.walletconnect.WcAnalyticEvents.DAppVerificationStatus
import com.tangem.domain.walletconnect.model.WcPairRequest
@ -19,7 +20,8 @@ sealed class WcAnalyticEvents(
params: Map<String, String> = emptyMap(),
) : AnalyticsEvent(category = WC_CATEGORY_NAME, event = event, params = params) {
class ScreenOpened : WcAnalyticEvents(event = "WC Screen Opened")
class ScreenOpened : WcAnalyticEvents(event = "WC Screen Opened"), AppsFlyerIncludedEvent
class NewPairInitiated(source: WcPairRequest.Source) : WcAnalyticEvents(
event = "Session Initiated",
params = mapOf(
@ -74,7 +76,7 @@ sealed class WcAnalyticEvents(
AnalyticsParam.BLOCKCHAIN to sessionForApprove.network.joinToString(",") { it.name },
DOMAIN_VERIFICATION to securityStatus.toAnalyticVerificationStatus(),
),
)
), AppsFlyerIncludedEvent
class DAppConnectionFailed(
errorCode: String,
@ -85,7 +87,7 @@ sealed class WcAnalyticEvents(
AnalyticsParam.ERROR_CODE to errorCode,
AnalyticsParam.ERROR_DESCRIPTION to errorMessage,
),
)
), AppsFlyerIncludedEvent
class SessionDisconnected(dAppMetaData: WcAppMetaData) : WcAnalyticEvents(
event = "dApp Disconnected",

View file

@ -61,7 +61,6 @@ internal class CreateMobileWalletModel @Inject constructor(
init {
trackingContextProxy.addHotWalletContext()
analyticsEventHandler.send(event = OnboardingAnalyticsEvent.Onboarding.Started(source = params.source))
analyticsEventHandler.send(event = OnboardingAnalyticsEvent.Onboarding.AppsFlyerOnlyEntryScreenView())
analyticsEventHandler.send(
event = OnboardingAnalyticsEvent.SeedPhrase.CreateMobileScreenOpened(source = params.source),
)

View file

@ -34,12 +34,7 @@ sealed class OnboardingEvent(
put("Seed Phrase Length", seedPhraseLength.toString())
}
},
), AppsFlyerIncludedEvent {
override val appsFlyerReplacedEvent = when (creationType) {
WalletCreationType.NewSeed, WalletCreationType.PrivateKey -> "wallet_created_successfully"
WalletCreationType.SeedImport -> "wallet_imported"
}
}
), AppsFlyerIncludedEvent
sealed class WalletCreationType(val value: String) {
data object PrivateKey : WalletCreationType(value = "Private Key")
@ -92,7 +87,6 @@ sealed class OnboardingEvent(
) : OnboardingEvent("Onboarding / Twins", event, params) {
class ScreenOpened : Twins("Twinning Screen Opened")
class SetupStarted : Twins("Twin Setup Started")
class SetupFinished : Twins("Twin Setup Finished")
}

View file

@ -5,6 +5,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.ERROR_CODE
import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
/**
* Send analytics
@ -25,7 +26,7 @@ sealed class CommonSendAnalyticEvents(
params = mapOf(
SOURCE to source.analyticsName,
),
)
), AppsFlyerIncludedEvent
/** Amount screen opened */
data class AmountScreenOpened(
@ -37,7 +38,7 @@ sealed class CommonSendAnalyticEvents(
params = mapOf(
SOURCE to source.analyticsName,
),
)
), AppsFlyerIncludedEvent
/** Fee screen opened */
data class FeeScreenOpened(
@ -74,7 +75,7 @@ sealed class CommonSendAnalyticEvents(
)
}
},
)
), AppsFlyerIncludedEvent
/** If transaction delays notification is present */
data class NoticeTransactionDelays(

View file

@ -8,6 +8,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.ENS_ADDRESS
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.analytics.models.AppsFlyerIncludedEvent
import com.tangem.core.ui.extensions.capitalize
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
@ -41,7 +42,7 @@ internal sealed class SendAnalyticEvents(
}
put(ENS_ADDRESS, ensAddress)
},
)
), AppsFlyerIncludedEvent
data class ConvertTokenButtonClicked(
val token: String,

View file

@ -8,6 +8,7 @@ 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.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
@ -31,7 +32,7 @@ internal sealed class SendWithSwapAnalyticEvents(
SEND_BLOCKCHAIN to fromToken.network.name,
RECEIVE_BLOCKCHAIN to toToken.network.name,
),
)
), AppsFlyerIncludedEvent
data class NoticeCanNotSwapToken(
val fromToken: CryptoCurrency,

View file

@ -7,6 +7,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.ERROR_MESSAGE
import com.tangem.core.analytics.models.AnalyticsParam.Key.PROVIDER
import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_TOKEN
import com.tangem.core.analytics.models.AnalyticsParam.Key.SEND_TOKEN
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.feature.swap.domain.models.domain.SwapProvider
import com.tangem.feature.swap.domain.models.ui.FeeType
@ -21,7 +22,7 @@ sealed class SwapEvents(
data class SwapScreenOpened(val token: String) : SwapEvents(
event = "Swap Screen Opened",
params = mapOf("Token" to token),
)
), AppsFlyerIncludedEvent
class SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked")
@ -96,7 +97,7 @@ sealed class SwapEvents(
"Receive Blockchain" to receiveBlockchain,
"Account Derivation From or To (optional)" to "$fromDerivationIndex, $toDerivationIndex",
),
)
), AppsFlyerIncludedEvent
class ProviderClicked : SwapEvents("Provider Clicked")

View file

@ -2,7 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.AppsFlyerOnlyEvent
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.core.analytics.models.OneTimeAnalyticsEvent
import com.tangem.domain.models.wallet.UserWalletId
@ -18,16 +18,11 @@ sealed class WalletScreenAnalyticsEvent {
event = "Topped up",
params = mapOf(AnalyticsParam.CURRENCY to walletType.value),
),
OneTimeAnalyticsEvent {
OneTimeAnalyticsEvent, AppsFlyerIncludedEvent {
override val oneTimeEventId: String = id + userWalletId.stringValue
}
class AppsFlyerWalletFunded(userWalletId: UserWalletId) : Basic(event = "wallet_funded"),
AppsFlyerOnlyEvent, OneTimeAnalyticsEvent {
override val oneTimeEventId: String = id + userWalletId.stringValue
}
class CardWasScanned(source: AnalyticsParam.ScreensSources) : Basic(
event = "Card Was Scanned",
params = mapOf(

View file

@ -208,7 +208,6 @@ internal class TokenListAnalyticsSender @Inject constructor(
}
analyticsEventHandler.send(Basic.WalletToppedUp(userWallet.walletId, walletType))
analyticsEventHandler.send(Basic.AppsFlyerWalletFunded(userWallet.walletId))
}
}

View file

@ -5,6 +5,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.ACTION
import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.ERROR_DESCRIPTION
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
sealed class YieldSupplyAnalytics(
event: String,
@ -20,7 +21,7 @@ sealed class YieldSupplyAnalytics(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
), AppsFlyerIncludedEvent
data class StartEarningScreen(
val token: String,
@ -31,7 +32,7 @@ sealed class YieldSupplyAnalytics(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
), AppsFlyerIncludedEvent
data class StopEarningScreen(
val token: String,
@ -42,7 +43,7 @@ sealed class YieldSupplyAnalytics(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
), AppsFlyerIncludedEvent
data class ButtonStartEarning(
val token: String,
@ -97,7 +98,7 @@ sealed class YieldSupplyAnalytics(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
), AppsFlyerIncludedEvent
data class FundsEarned(
val token: String,
@ -108,7 +109,7 @@ sealed class YieldSupplyAnalytics(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
), AppsFlyerIncludedEvent
data class FundsWithdrawn(
val token: String,
@ -119,7 +120,7 @@ sealed class YieldSupplyAnalytics(
TOKEN_PARAM to token,
BLOCKCHAIN to blockchain,
),
)
), AppsFlyerIncludedEvent
data class EarnedFundsInfo(
val token: String,