Updated on 2026-08-14
This commit is contained in:
parent
85545863e3
commit
926e89e975
16 changed files with 158 additions and 223 deletions
|
|
@ -239,6 +239,13 @@ sealed class AnalyticsParam {
|
|||
MobileWallet("Mobile Wallet"),
|
||||
}
|
||||
|
||||
enum class SignInType(val value: String) {
|
||||
Card("Card"),
|
||||
Biometric("Biometric"),
|
||||
NoSecurity("No Security"),
|
||||
AccessCode("Access Code"),
|
||||
}
|
||||
|
||||
companion object Key {
|
||||
const val BLOCKCHAIN = "Blockchain"
|
||||
const val TOKEN_PARAM = "Token"
|
||||
|
|
@ -297,6 +304,11 @@ sealed class AnalyticsParam {
|
|||
const val REFERRAL_ID = "Referral_ID"
|
||||
const val SEARCHED = "Searched"
|
||||
const val RATE_TYPE = "Rate Type"
|
||||
const val SIGN_IN_TYPE = "Sign in type"
|
||||
const val WALLETS_COUNT = "Wallets Count"
|
||||
const val WALLET_TYPE = "Wallet Type"
|
||||
const val BACKUPED = "Backuped"
|
||||
const val MEMO = "Memo"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,65 +2,41 @@ package com.tangem.core.analytics.models
|
|||
|
||||
sealed class Basic(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : AnalyticsEvent("Basic", event, params) {
|
||||
params: Map<String, String> = emptyMap(),
|
||||
) : AnalyticsEvent(category = "Basic", event = event, params = params) {
|
||||
|
||||
/**
|
||||
* Tracks card scanning from specific entry points (Introduction, Main, My Wallets, Sign In).
|
||||
* The originating screen is reported via the [AnalyticsParam.SOURCE] parameter.
|
||||
*/
|
||||
class CardWasScanned(
|
||||
source: AnalyticsParam.ScreensSources,
|
||||
) : Basic(
|
||||
event = "Card Was Scanned",
|
||||
params = mapOf(
|
||||
AnalyticsParam.Key.SOURCE to source.value,
|
||||
AnalyticsParam.SOURCE to source.value,
|
||||
),
|
||||
)
|
||||
|
||||
class SignedInLegacy(
|
||||
currency: AnalyticsParam.WalletType,
|
||||
batch: String,
|
||||
signInType: SignInType,
|
||||
walletsCount: String,
|
||||
isImported: Boolean,
|
||||
hasBackup: Boolean?,
|
||||
) : Basic(
|
||||
event = "Signed in",
|
||||
params = buildMap {
|
||||
put(AnalyticsParam.Key.CURRENCY, currency.value)
|
||||
put(AnalyticsParam.Key.BATCH, batch)
|
||||
put("Wallet Type", if (isImported) "Seed Phrase" else "Seedless")
|
||||
put("Sign in type", signInType.name)
|
||||
put("Wallets Count", walletsCount)
|
||||
if (hasBackup != null) {
|
||||
put("Backuped", if (hasBackup) "Yes" else "No")
|
||||
}
|
||||
},
|
||||
) {
|
||||
enum class SignInType {
|
||||
Card, Biometric
|
||||
}
|
||||
}
|
||||
), CriticalEvent
|
||||
|
||||
/**
|
||||
* Tracks any sign-in into a wallet (card scan, FaceID, or wallet switch).
|
||||
* Counted as a single sign-in per session — subsequent card scans within the same session are ignored.
|
||||
*/
|
||||
class SignedIn(
|
||||
signInType: SignInType,
|
||||
signInType: AnalyticsParam.SignInType,
|
||||
walletsCount: Int,
|
||||
isImported: Boolean,
|
||||
hasBackup: Boolean?,
|
||||
isBackedUp: Boolean,
|
||||
) : Basic(
|
||||
event = "Signed in",
|
||||
params = buildMap {
|
||||
put("Sign in type", signInType.value)
|
||||
put("Wallets Count", walletsCount.toString())
|
||||
put("Wallet Type", if (isImported) "Seed Phrase" else "Seedless")
|
||||
if (hasBackup != null) {
|
||||
put("Backuped", if (hasBackup) "Yes" else "No")
|
||||
}
|
||||
put(AnalyticsParam.SIGN_IN_TYPE, signInType.value)
|
||||
put(AnalyticsParam.WALLETS_COUNT, walletsCount.toString())
|
||||
put(AnalyticsParam.WALLET_TYPE, if (isImported) "Seed Phrase" else "Seedless")
|
||||
put(AnalyticsParam.BACKUPED, if (isBackedUp) "Yes" else "No")
|
||||
},
|
||||
) {
|
||||
enum class SignInType(val value: String) {
|
||||
Card("Card"),
|
||||
Biometric("Biometric"),
|
||||
NoSecurity("No Security"),
|
||||
AccessCode("Access Code"),
|
||||
}
|
||||
), CriticalEvent, OneTimePerSessionEvent {
|
||||
override val oneTimeEventId: String = id
|
||||
}
|
||||
|
||||
class ButtonBuy(
|
||||
|
|
@ -68,39 +44,46 @@ sealed class Basic(
|
|||
) : Basic(
|
||||
event = "Button - Buy",
|
||||
params = buildMap {
|
||||
put(AnalyticsParam.Key.SOURCE, source.value)
|
||||
put(AnalyticsParam.SOURCE, source.value)
|
||||
},
|
||||
)
|
||||
|
||||
class ToppedUp(userWalletId: String, currency: AnalyticsParam.WalletType) :
|
||||
/**
|
||||
* Tracks the first time a user wallet is topped up. Sent once per wallet, when the balance
|
||||
* transitions from zero to positive (Total Balance for multi-currency wallets, or Balance for Note).
|
||||
* A wallet scanned with a non-zero balance does not count as a top-up — the event must be sent
|
||||
* only after all tokens have finished loading.
|
||||
*/
|
||||
class ToppedUp(userWalletId: String, walletType: AnalyticsParam.WalletType) :
|
||||
Basic(
|
||||
event = "Topped up",
|
||||
params = mapOf(AnalyticsParam.Key.CURRENCY to currency.value),
|
||||
params = mapOf(AnalyticsParam.CURRENCY to walletType.value),
|
||||
),
|
||||
OneTimeAnalyticsEvent {
|
||||
OneTimeAnalyticsEvent, AppsFlyerIncludedEvent, CriticalEvent {
|
||||
|
||||
override val oneTimeEventId: String = id + userWalletId
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks transaction submission from various screens (Send, Swap, WalletConnect, Sell, Approve, Staking).
|
||||
*/
|
||||
class TransactionSent(sentFrom: AnalyticsParam.TxSentFrom, memoType: MemoType) :
|
||||
Basic(
|
||||
event = "Transaction sent",
|
||||
params = buildMap {
|
||||
this[AnalyticsParam.Key.SOURCE] = sentFrom.value
|
||||
put(AnalyticsParam.SOURCE, sentFrom.value)
|
||||
if (sentFrom is AnalyticsParam.TxData) {
|
||||
this[AnalyticsParam.Key.BLOCKCHAIN] = sentFrom.blockchain
|
||||
this[AnalyticsParam.Key.TOKEN_PARAM] = sentFrom.token
|
||||
sentFrom.feeType?.value?.let {
|
||||
this[AnalyticsParam.Key.FEE_TYPE] = it
|
||||
}
|
||||
this[AnalyticsParam.Key.FEE_TOKEN] = sentFrom.feeToken
|
||||
put(AnalyticsParam.BLOCKCHAIN, sentFrom.blockchain)
|
||||
put(AnalyticsParam.TOKEN_PARAM, sentFrom.token)
|
||||
sentFrom.feeType?.value?.let { put(AnalyticsParam.FEE_TYPE, it) }
|
||||
put(AnalyticsParam.FEE_TOKEN, sentFrom.feeToken)
|
||||
}
|
||||
if (sentFrom is AnalyticsParam.TxSentFrom.Approve) {
|
||||
this[AnalyticsParam.Key.PERMISSION_TYPE] = sentFrom.permissionType
|
||||
put(AnalyticsParam.PERMISSION_TYPE, sentFrom.permissionType)
|
||||
}
|
||||
this["Memo"] = memoType.name
|
||||
put(AnalyticsParam.MEMO, memoType.name)
|
||||
},
|
||||
), AppsFlyerIncludedEvent {
|
||||
), AppsFlyerIncludedEvent, CriticalEvent {
|
||||
enum class MemoType {
|
||||
Empty, Full, Null
|
||||
}
|
||||
|
|
@ -110,31 +93,33 @@ sealed class Basic(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks the user invoking the "Request Support" email flow from various screens of the app.
|
||||
*/
|
||||
class ButtonSupport(source: AnalyticsParam.ScreensSources) : Basic(
|
||||
event = "Request Support",
|
||||
params = mapOf(
|
||||
AnalyticsParam.Key.SOURCE to source.value,
|
||||
AnalyticsParam.SOURCE to source.value,
|
||||
),
|
||||
), CriticalEvent
|
||||
|
||||
/**
|
||||
* Tracks loading of the user's total balance after sign-in. Reports whether the balance is
|
||||
* empty, has funds, failed to load, or could not be returned because of a custom token.
|
||||
*/
|
||||
class BalanceLoaded(balance: AnalyticsParam.CardBalanceState, tokensCount: Int?) : Basic(
|
||||
event = "Balance Loaded",
|
||||
params = buildMap {
|
||||
put(AnalyticsParam.BALANCE, balance.value)
|
||||
tokensCount?.let { put(AnalyticsParam.TOKENS_COUNT, it.toString()) }
|
||||
},
|
||||
), AppsFlyerIncludedEvent, CriticalEvent
|
||||
|
||||
class TokenBalance(balance: AnalyticsParam.EmptyFull, token: String) : Basic(
|
||||
event = "Token Balance",
|
||||
params = mapOf(
|
||||
AnalyticsParam.STATE to balance.value,
|
||||
AnalyticsParam.TOKEN_PARAM to token,
|
||||
),
|
||||
)
|
||||
|
||||
class BiometryFailed(
|
||||
source: AnalyticsParam.ScreensSources,
|
||||
reason: BiometricFailReason,
|
||||
) : Basic(
|
||||
event = "Biometry Failed",
|
||||
params = mapOf(
|
||||
AnalyticsParam.Key.SOURCE to source.value,
|
||||
"Reason" to reason.value,
|
||||
),
|
||||
) {
|
||||
sealed class BiometricFailReason(val value: String) {
|
||||
data object AuthenticationLockout : BiometricFailReason("BiometricsAuthenticationLockout")
|
||||
data object AuthenticationLockoutPermanent : BiometricFailReason("BiometricsAuthenticationLockoutPermanent")
|
||||
data object BiometricsAuthenticationDisabled : BiometricFailReason("BiometricsAuthenticationDisabled")
|
||||
data object AllKeysInvalidated : BiometricFailReason("AllKeysInvalidated")
|
||||
data object AuthenticationCancelled : BiometricFailReason("AuthenticationCancelled")
|
||||
data object AuthenticationAlreadyInProgress : BiometricFailReason("AuthenticationAlreadyInProgress")
|
||||
data class Other(val reason: String) : BiometricFailReason(reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.core.analytics.models
|
||||
|
||||
/**
|
||||
* Marker interface for analytics events that require special attention.
|
||||
*
|
||||
* Implemented by events listed in the analytics specification (events.csv).
|
||||
*/
|
||||
interface CriticalEvent
|
||||
|
|
@ -2,20 +2,22 @@ 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.CriticalEvent
|
||||
|
||||
sealed class SignIn(
|
||||
event: String,
|
||||
params: Map<String, String> = emptyMap(),
|
||||
) : AnalyticsEvent("Sign In", event, params) {
|
||||
) : AnalyticsEvent(category = "Sign In", event = event, params = params) {
|
||||
|
||||
data class ScreenOpened(
|
||||
val walletsCount: Int,
|
||||
) : SignIn(
|
||||
/**
|
||||
* Tracks the user landing on the app's sign-in screen when a saved card exists.
|
||||
*/
|
||||
class ScreenOpened(walletsCount: Int) : SignIn(
|
||||
event = "Sign In Screen Opened",
|
||||
params = mapOf(
|
||||
"Wallets Count" to walletsCount.toString(),
|
||||
AnalyticsParam.WALLETS_COUNT to walletsCount.toString(),
|
||||
),
|
||||
)
|
||||
), CriticalEvent
|
||||
|
||||
class ButtonBiometricSignIn : SignIn(event = "Button - Biometric Sign In")
|
||||
|
||||
|
|
@ -26,24 +28,17 @@ sealed class SignIn(
|
|||
) : SignIn(event = "Error - Biometric Updated")
|
||||
|
||||
class ButtonWallet(
|
||||
signInType: SignInType,
|
||||
signInType: AnalyticsParam.SignInType,
|
||||
walletsCount: Int,
|
||||
) : SignIn(
|
||||
event = "Button - Wallet",
|
||||
params = buildMap {
|
||||
put("Wallets Count", walletsCount.toString())
|
||||
put("Sign in type", signInType.value)
|
||||
put(AnalyticsParam.WALLETS_COUNT, walletsCount.toString())
|
||||
put(AnalyticsParam.SIGN_IN_TYPE, signInType.value)
|
||||
},
|
||||
) {
|
||||
enum class SignInType(val value: String) {
|
||||
Card("Card"),
|
||||
Biometric("Biometric"),
|
||||
NoSecurity("No Security"),
|
||||
AccessCode("Access Code"),
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class ButtonAddWallet(
|
||||
class ButtonAddWallet(
|
||||
val sources: AnalyticsParam.ScreensSources,
|
||||
) : SignIn(
|
||||
event = "Button - Add Wallet",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue