Updated on 2026-08-14

This commit is contained in:
Tangem 2022-09-22 15:52:22 +03:00
commit db94141499
9 changed files with 121 additions and 25 deletions

View file

@ -126,8 +126,9 @@ dependencies {
implementation 'com.google.firebase:firebase-config-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
// AppsFlyer
// Analytics
implementation 'com.appsflyer:af-android-sdk:6.5.1'
implementation 'com.amplitude:android-sdk:2.36.1'
// WalletConnect
implementation 'com.github.salomonbrys.kotson:kotson:2.5.0'

View file

@ -16,6 +16,7 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

View file

@ -0,0 +1,56 @@
package com.tangem.tap.common.analytics
import com.amplitude.api.Amplitude
import com.amplitude.api.AmplitudeClient
import com.shopify.buy3.Storefront
import com.tangem.common.card.Card
import com.tangem.common.core.TangemSdkError
import org.json.JSONObject
class AmplitudeAnalyticsHandler : AnalyticsHandler() {
private val client: AmplitudeClient = Amplitude.getInstance()
override fun triggerEvent(
event: AnalyticsEvent,
card: Card?,
blockchain: String?,
params: Map<String, String>
) {
client.logEvent(event.event, prepareParams(card, blockchain, params).toJson())
}
override fun triggerEvent(event: String, params: Map<String, String>) {
client.logEvent(event, params.toJson())
}
override fun logCardSdkError(
error: TangemSdkError,
actionToLog: Analytics.ActionToLog,
parameters: Map<AnalyticsParam, String>?,
card: Card?
) {
//TODO
}
override fun logError(error: Throwable, params: Map<String, String>) {
//TODO
}
override fun getOrderEvent(): String {
//TODO
return ""
}
override fun getOrderParams(order: Storefront.Order): Map<String, String> {
//TODO
return emptyMap()
}
private fun Map<String, String>.toJson(): JSONObject {
val json = JSONObject()
this.map { json.put(it.key, it.value) }
return json
}
}

View file

@ -31,12 +31,16 @@ abstract class AnalyticsHandler {
params: Map<String, String> = emptyMap()
)
protected fun prepareParams(card: Card?, blockchain: String? = null): Map<String, String> {
protected fun prepareParams(
card: Card?,
blockchain: String? = null,
params: Map<String, String> = emptyMap()
): Map<String, String> {
return mapOf(
AnalyticsParam.FIRMWARE.param to card?.firmwareVersion?.stringValue,
AnalyticsParam.BATCH_ID.param to card?.batchId,
AnalyticsParam.BLOCKCHAIN.param to blockchain,
).filterNotNull()
).filterNotNull() + params
}
fun logWcEvent(event: Analytics.WcAnalyticsEvent) {

View file

@ -16,7 +16,11 @@ class AppsFlyerAnalyticsHandler(val context: Context): AnalyticsHandler() {
blockchain: String?,
params: Map<String, String>
) {
AppsFlyerLib.getInstance().logEvent(context, event.event, prepareParams(card, blockchain))
AppsFlyerLib.getInstance().logEvent(
context,
event.event,
prepareParams(card, blockchain, params)
)
}
override fun logCardSdkError(

View file

@ -17,7 +17,7 @@ object FirebaseAnalyticsHandler : AnalyticsHandler() {
blockchain: String?,
params: Map<String, String>
) {
val fullParams = prepareParams(card, blockchain) + params
val fullParams = prepareParams(card, blockchain, params)
Firebase.analytics.logEvent(event.event, fullParams.toBundle())
}
@ -42,7 +42,7 @@ object FirebaseAnalyticsHandler : AnalyticsHandler() {
if (error is TangemSdkError.UserCancelled) return
val params = parameters?.toMutableMap() ?: mutableMapOf()
if (card != null) params + prepareParams(card)
if (card != null) params + prepareParams(card)
params[AnalyticsParam.ACTION] = actionToLog.key
params[AnalyticsParam.ERROR_CODE] = error.code.toString()
params[AnalyticsParam.ERROR_DESCRIPTION] = error.javaClass.simpleName

View file

@ -1,9 +1,12 @@
package com.tangem.tap.common.analytics
import android.content.Context
import com.amplitude.api.Amplitude
import com.appsflyer.AppsFlyerLib
import com.shopify.buy3.Storefront
import com.tangem.common.card.Card
import com.tangem.common.core.TangemSdkError
import com.tangem.tap.store
class GlobalAnalyticsHandler(val analyticsHandlers: List<AnalyticsHandler>) :
AnalyticsHandler() {
@ -46,9 +49,29 @@ class GlobalAnalyticsHandler(val analyticsHandlers: List<AnalyticsHandler>) :
return GlobalAnalyticsHandler(
listOf(
FirebaseAnalyticsHandler,
AppsFlyerAnalyticsHandler(context)
AppsFlyerAnalyticsHandler(context),
AmplitudeAnalyticsHandler()
)
)
}
private fun initAnalytics(context: Context) {
initAppsFlyer(context)
initAmplitude(context)
}
private fun initAppsFlyer(context: Context) {
val devKey = store.state.globalState.configManager?.config?.appsFlyerDevKey ?: return
AppsFlyerLib.getInstance().init(devKey, null, context)
AppsFlyerLib.getInstance().start(context)
}
private fun initAmplitude(context: Context) {
val apiKey = store.state.globalState.configManager?.config?.amplitudeApiKey ?: return
Amplitude.getInstance()
.initialize(context.applicationContext, apiKey)
.enableForegroundTracking(context)
}
}
}

View file

@ -15,6 +15,7 @@ data class Config(
val mercuryoWidgetId: String = "",
val mercuryoSecret: String = "",
val appsFlyerDevKey: String = "",
val amplitudeApiKey: String = "",
val blockchainSdkConfig: BlockchainSdkConfig = BlockchainSdkConfig(),
val isSendingToPayIdEnabled: Boolean = true,
val isTopUpEnabled: Boolean = false,
@ -88,6 +89,7 @@ class ConfigManager {
tronGridApiKey = values.tronGridApiKey
),
appsFlyerDevKey = values.appsFlyerDevKey,
amplitudeApiKey = values.amplitudeApiKey,
shopify = values.shopifyShop,
zendesk = values.zendesk,
)
@ -104,6 +106,7 @@ class ConfigManager {
infuraProjectId = values.infuraProjectId
),
appsFlyerDevKey = values.appsFlyerDevKey,
amplitudeApiKey = values.amplitudeApiKey,
shopify = values.shopifyShop,
zendesk = values.zendesk,
)

View file

@ -8,29 +8,33 @@ import com.tangem.tap.common.zendesk.ZendeskConfig
*/
class FeatureModel(
val isWalletPayIdEnabled: Boolean,
val isTopUpEnabled: Boolean,
val isSendingToPayIdEnabled: Boolean,
val isCreatingTwinCardsAllowed: Boolean,
val isWalletPayIdEnabled: Boolean,
val isTopUpEnabled: Boolean,
val isSendingToPayIdEnabled: Boolean,
val isCreatingTwinCardsAllowed: Boolean,
)
class ConfigValueModel(
val coinMarketCapKey: String,
val mercuryoWidgetId: String,
val mercuryoSecret: String,
val moonPayApiKey: String,
val moonPayApiSecretKey: String,
val blockchairApiKey: String?,
val blockchairAuthorizationToken: String?,
val blockcypherTokens: Set<String>?,
val infuraProjectId: String?,
val appsFlyerDevKey: String,
val shopifyShop: ShopifyShop?,
val zendesk: ZendeskConfig?,
val tronGridApiKey: String,
val coinMarketCapKey: String,
val mercuryoWidgetId: String,
val mercuryoSecret: String,
val moonPayApiKey: String,
val moonPayApiSecretKey: String,
val blockchairApiKey: String?,
val blockchairAuthorizationToken: String?,
val blockcypherTokens: Set<String>?,
val infuraProjectId: String?,
val appsFlyerDevKey: String,
val shopifyShop: ShopifyShop?,
val zendesk: ZendeskConfig?,
val tronGridApiKey: String,
val amplitudeApiKey: String,
)
class ConfigModel(val features: FeatureModel?, val configValues: ConfigValueModel?) {
class ConfigModel(
val features: FeatureModel?,
val configValues: ConfigValueModel?,
) {
companion object {
fun empty(): ConfigModel = ConfigModel(null, null)
}