Updated on 2026-08-14
This commit is contained in:
parent
fec0f14952
commit
5030c571c5
32 changed files with 298 additions and 658 deletions
|
|
@ -15,7 +15,7 @@ import com.tangem.network.common.MoshiConverter
|
|||
import com.tangem.tap.common.AndroidAssetReader
|
||||
import com.tangem.tap.common.AssetReader
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsHandlersFactory
|
||||
import com.tangem.tap.common.analytics.AnalyticsFactory
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.filters.BasicSignInFilter
|
||||
import com.tangem.tap.common.analytics.filters.BasicTopUpFilter
|
||||
|
|
@ -110,10 +110,14 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
}
|
||||
|
||||
private fun initAnalytics(application: Application, config: Config) {
|
||||
val factory = AnalyticsHandlersFactory()
|
||||
factory.addBuilder(AmplitudeAnalyticsHandler.Builder())
|
||||
factory.addBuilder(AppsFlyerAnalyticsHandler.Builder())
|
||||
factory.addBuilder(FirebaseAnalyticsHandler.Builder())
|
||||
val factory = AnalyticsFactory()
|
||||
factory.addHandlerBuilder(AmplitudeAnalyticsHandler.Builder())
|
||||
factory.addHandlerBuilder(AppsFlyerAnalyticsHandler.Builder())
|
||||
factory.addHandlerBuilder(FirebaseAnalyticsHandler.Builder())
|
||||
|
||||
factory.addFilter(ShopPurchasedEventFilter())
|
||||
factory.addFilter(BasicSignInFilter())
|
||||
factory.addFilter(BasicTopUpFilter(preferencesStorage.toppedUpWalletStorage))
|
||||
|
||||
val buildData = AnalyticsHandlerBuilder.Data(
|
||||
application = application,
|
||||
|
|
@ -122,14 +126,7 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
logConfig = LogConfig.analyticsHandlers,
|
||||
jsonConverter = MoshiJsonConverter.INSTANCE,
|
||||
)
|
||||
factory.build(buildData).forEach {
|
||||
Analytics.addHandler(it.id(), it)
|
||||
}
|
||||
listOf(
|
||||
ShopPurchasedEventFilter(),
|
||||
BasicSignInFilter(),
|
||||
BasicTopUpFilter(preferencesStorage.toppedUpWalletStorage),
|
||||
).forEach { Analytics.addFilter(it) }
|
||||
factory.build(Analytics, buildData)
|
||||
}
|
||||
|
||||
private fun initFeedbackManager(context: Context, preferencesStorage: PreferencesStorage, config: Config) {
|
||||
|
|
|
|||
|
|
@ -1,22 +1,14 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import com.tangem.blockchain.common.BlockchainError
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.domain.common.FeatureCoroutineExceptionHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventFilter
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsFilterHolder
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerHolder
|
||||
import com.tangem.tap.common.analytics.api.BlockchainSdkErrorEventHandler
|
||||
import com.tangem.tap.common.analytics.api.CardSdkErrorEventHandler
|
||||
import com.tangem.tap.common.analytics.api.ErrorEventHandler
|
||||
import com.tangem.tap.common.analytics.api.ErrorEventLogger
|
||||
import com.tangem.tap.common.analytics.api.ParamsInterceptor
|
||||
import com.tangem.tap.common.analytics.api.ParamsInterceptorHolder
|
||||
import com.tangem.tap.common.analytics.api.SdkErrorEventHandler
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -28,33 +20,26 @@ import java.util.concurrent.Executors
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface GlobalAnalyticsEventHandler : AnalyticsEventHandler,
|
||||
ErrorEventHandler,
|
||||
SdkErrorEventHandler,
|
||||
AnalyticsHandlerHolder,
|
||||
AnalyticsFilterHolder,
|
||||
ParamsInterceptorHolder {
|
||||
|
||||
fun send(event: AnalyticsEvent, card: Card? = null, blockchain: String? = null)
|
||||
}
|
||||
ParamsInterceptorHolder
|
||||
|
||||
object Analytics : GlobalAnalyticsEventHandler {
|
||||
|
||||
private val analyticsScope: CoroutineScope by lazy { createScope() }
|
||||
|
||||
private val handlers = mutableMapOf<String, AnalyticsEventHandler>()
|
||||
private val analyticsFilters = mutableSetOf<AnalyticsEventFilter>()
|
||||
private val handlers = mutableMapOf<String, AnalyticsHandler>()
|
||||
private val paramsInterceptors = mutableMapOf<String, ParamsInterceptor>()
|
||||
private val analyticsFilters = mutableSetOf<AnalyticsEventFilter>()
|
||||
|
||||
private val analyticsHandlers: List<AnalyticsEventHandler>
|
||||
private val analyticsHandlers: List<AnalyticsHandler>
|
||||
get() = handlers.values.toList()
|
||||
|
||||
override fun id(): String = analyticsHandlers.joinToString(", ") { it.id() }
|
||||
|
||||
override fun addHandler(name: String, handler: AnalyticsEventHandler) {
|
||||
override fun addHandler(name: String, handler: AnalyticsHandler) {
|
||||
handlers[name] = handler
|
||||
}
|
||||
|
||||
override fun removeHandler(name: String): AnalyticsEventHandler? {
|
||||
override fun removeHandler(name: String): AnalyticsHandler? {
|
||||
return handlers.remove(name)
|
||||
}
|
||||
|
||||
|
|
@ -74,84 +59,29 @@ object Analytics : GlobalAnalyticsEventHandler {
|
|||
return paramsInterceptors.remove(interceptor.id())
|
||||
}
|
||||
|
||||
override fun send(event: String, params: Map<String, String>) {
|
||||
override fun send(event: AnalyticsEvent) {
|
||||
analyticsScope.launch {
|
||||
analyticsHandlers.forEach { it.send(event, params.interceptParams()) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun send(event: AnalyticsEvent, card: Card?, blockchain: String?) {
|
||||
analyticsScope.launch {
|
||||
val eventString = prepareEventString(event.category, event.event)
|
||||
val eventParams = prepareParams(card, blockchain, event.interceptParams())
|
||||
|
||||
event.params = applyParamsInterceptors(event)
|
||||
val eventFilter = analyticsFilters.firstOrNull { it.canBeAppliedTo(event) }
|
||||
|
||||
when {
|
||||
eventFilter == null -> analyticsHandlers.forEach { handler -> handler.send(eventString, eventParams) }
|
||||
eventFilter == null -> analyticsHandlers.forEach { handler -> handler.send(event) }
|
||||
eventFilter.canBeSent(event) -> {
|
||||
analyticsHandlers
|
||||
.filter { handler -> eventFilter.canBeConsumedByHandler(handler, event) }
|
||||
.forEach { handler -> handler.send(eventString, eventParams) }
|
||||
.forEach { handler -> handler.send(event) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleAnalyticsEvent(
|
||||
event: AnalyticsEventAnOld,
|
||||
params: Map<String, String>,
|
||||
card: Card?,
|
||||
blockchain: String?,
|
||||
) {
|
||||
analyticsScope.launch {
|
||||
analyticsHandlers.forEach {
|
||||
it.handleAnalyticsEvent(event, params.interceptParams(), card, blockchain)
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun applyParamsInterceptors(event: AnalyticsEvent): MutableMap<String, String> {
|
||||
val interceptedParams = event.params.toMutableMap()
|
||||
paramsInterceptors.values
|
||||
.filter { it.canBeAppliedTo(event) }
|
||||
.forEach { it.intercept(interceptedParams) }
|
||||
|
||||
override fun send(error: Throwable, params: Map<String, String>) {
|
||||
analyticsScope.launch {
|
||||
analyticsHandlers.filterIsInstance<ErrorEventLogger>().forEach {
|
||||
it.logErrorEvent(error, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun send(
|
||||
error: TangemSdkError,
|
||||
action: AnalyticsAnOld.ActionToLog,
|
||||
params: Map<AnalyticsParamAnOld, String>,
|
||||
card: Card?,
|
||||
) {
|
||||
analyticsScope.launch {
|
||||
analyticsHandlers.filterIsInstance<CardSdkErrorEventHandler>().forEach {
|
||||
it.send(error, action, params, card)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun send(
|
||||
error: BlockchainError,
|
||||
action: AnalyticsAnOld.ActionToLog,
|
||||
params: Map<AnalyticsParamAnOld, String>,
|
||||
card: Card?,
|
||||
) {
|
||||
analyticsScope.launch {
|
||||
analyticsHandlers.filterIsInstance<BlockchainSdkErrorEventHandler>().forEach {
|
||||
it.send(error, action, params, card)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun AnalyticsEvent.interceptParams(): Map<String, String> = params.interceptParams()
|
||||
|
||||
private fun Map<String, String>.interceptParams(): Map<String, String> {
|
||||
return this.toMutableMap().apply { interceptParams() }
|
||||
}
|
||||
|
||||
private fun MutableMap<String, String>.interceptParams() {
|
||||
paramsInterceptors.values.forEach { it.intercept(this) }
|
||||
return interceptedParams
|
||||
}
|
||||
|
||||
private fun createScope(): CoroutineScope {
|
||||
|
|
@ -160,43 +90,4 @@ object Analytics : GlobalAnalyticsEventHandler {
|
|||
val exHandler = FeatureCoroutineExceptionHandler.create(name)
|
||||
return CoroutineScope(Job() + dispatcher + CoroutineName(name) + exHandler)
|
||||
}
|
||||
}
|
||||
|
||||
fun GlobalAnalyticsEventHandler.logWcEvent(event: AnalyticsAnOld.WcAnalyticsEvent) {
|
||||
when (event) {
|
||||
is AnalyticsAnOld.WcAnalyticsEvent.Action -> {
|
||||
handleAnalyticsEvent(
|
||||
event = AnalyticsEventAnOld.WC_SUCCESS_RESPONSE,
|
||||
params = mapOf(
|
||||
AnalyticsParamAnOld.WALLET_CONNECT_ACTION.param to event.action.name,
|
||||
),
|
||||
)
|
||||
}
|
||||
is AnalyticsAnOld.WcAnalyticsEvent.Error -> {
|
||||
val params = mapOf(
|
||||
AnalyticsParamAnOld.WALLET_CONNECT_ACTION.param to event.action?.name,
|
||||
AnalyticsParamAnOld.ERROR_DESCRIPTION.param to event.error.message,
|
||||
).filterNotNull()
|
||||
send(event.error, params)
|
||||
}
|
||||
is AnalyticsAnOld.WcAnalyticsEvent.InvalidRequest ->
|
||||
handleAnalyticsEvent(
|
||||
event = AnalyticsEventAnOld.WC_INVALID_REQUEST,
|
||||
params = mapOf(
|
||||
AnalyticsParamAnOld.WALLET_CONNECT_REQUEST.param to event.json,
|
||||
).filterNotNull(),
|
||||
)
|
||||
is AnalyticsAnOld.WcAnalyticsEvent.Session -> {
|
||||
val analyticsEvent = when (event.event) {
|
||||
AnalyticsAnOld.WcSessionEvent.Disconnect -> AnalyticsEventAnOld.WC_SESSION_DISCONNECTED
|
||||
AnalyticsAnOld.WcSessionEvent.Connect -> AnalyticsEventAnOld.WC_NEW_SESSION
|
||||
}
|
||||
handleAnalyticsEvent(
|
||||
event = analyticsEvent,
|
||||
params = mapOf(
|
||||
AnalyticsParamAnOld.WALLET_CONNECT_DAPP_URL.param to event.url,
|
||||
).filterNotNull(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
enum class AnalyticsEventAnOld(val event: String) {
|
||||
CARD_IS_SCANNED("card_is_scanned"),
|
||||
TRANSACTION_IS_SENT("transaction_is_sent"),
|
||||
READY_TO_SCAN("ready_to_scan"),
|
||||
DEMO_MODE_ACTIVATED("demo_mode_activated"),
|
||||
|
||||
APP_RATING_DISPLAYED("rate_app_warning_displayed"),
|
||||
APP_RATING_DISMISS("dismiss_rate_app_warning"),
|
||||
APP_RATING_NEGATIVE("negative_rate_app_feedback"),
|
||||
APP_RATING_POSITIVE("positive_rate_app_feedback"),
|
||||
|
||||
WC_SUCCESS_RESPONSE("wallet_connect_success_response"),
|
||||
WC_INVALID_REQUEST("wallet_connect_invalid_request"),
|
||||
WC_NEW_SESSION("wallet_connect_new_session"),
|
||||
WC_SESSION_DISCONNECTED("wallet_connect_session_disconnected"),
|
||||
|
||||
GET_CARD("get_card"),
|
||||
}
|
||||
|
||||
enum class AnalyticsParamAnOld(val param: String) {
|
||||
BLOCKCHAIN("blockchain"),
|
||||
CARD_ID("cardId"),
|
||||
BATCH_ID("batch_id"),
|
||||
FIRMWARE("firmware"),
|
||||
ACTION("action"),
|
||||
ERROR_DESCRIPTION("error_description"),
|
||||
ERROR_CODE("error_code"),
|
||||
NEW_SECURITY_OPTION("new_security_option"),
|
||||
ERROR_KEY("Tangem SDK error key"),
|
||||
|
||||
WALLET_CONNECT_ACTION("wallet_connect_action"),
|
||||
WALLET_CONNECT_REQUEST("wallet_connect_request"),
|
||||
WALLET_CONNECT_DAPP_URL("wallet_connect_dapp_url"),
|
||||
|
||||
SOURCE("source"),
|
||||
}
|
||||
|
||||
enum class GetCardSourceParamsAnOld(val param: String) {
|
||||
WELCOME("welcome"),
|
||||
ONBOARDING_BUY_MORE("wallet_onboaring_buy_more_cards"),
|
||||
ONBOARDING("wallet_onboarding")
|
||||
}
|
||||
|
||||
object AnalyticsAnOld {
|
||||
enum class ActionToLog(val key: String) {
|
||||
Scan("tap_scan_task"),
|
||||
SendTransaction("send_transaction"),
|
||||
WalletConnectSign("wallet_connect_personal_sign"),
|
||||
WalletConnectTransaction("wallet_connect_tx_sign"),
|
||||
ReadPinSettings("read_pin_settings"),
|
||||
ChangeSecOptions("change_sec_options"),
|
||||
CreateWallet("create_wallet"),
|
||||
PurgeWallet("purge_wallet"),
|
||||
WriteIssuerData("write_issuer_data"),
|
||||
}
|
||||
|
||||
enum class WcSessionEvent { Disconnect, Connect }
|
||||
|
||||
enum class WcAction { PersonalSign, SignTransaction, SendTransaction }
|
||||
|
||||
sealed class WcAnalyticsEvent {
|
||||
data class Error(val error: Throwable, val action: WcAction?) :
|
||||
WcAnalyticsEvent()
|
||||
|
||||
data class Session(val event: WcSessionEvent, val url: String?) : WcAnalyticsEvent()
|
||||
data class Action(val action: WcAction) : WcAnalyticsEvent()
|
||||
data class InvalidRequest(val json: String?) : WcAnalyticsEvent()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventFilter
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.api.ParamsInterceptor
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class AnalyticsFactory {
|
||||
|
||||
private val builders = mutableListOf<AnalyticsHandlerBuilder>()
|
||||
private val filters = mutableListOf<AnalyticsEventFilter>()
|
||||
private val interceptors = mutableListOf<ParamsInterceptor>()
|
||||
|
||||
fun addHandlerBuilder(builder: AnalyticsHandlerBuilder) {
|
||||
builders.add(builder)
|
||||
}
|
||||
|
||||
fun addFilter(filter: AnalyticsEventFilter) {
|
||||
filters.add(filter)
|
||||
}
|
||||
|
||||
fun addParamsInterceptor(interceptor: ParamsInterceptor) {
|
||||
interceptors.add(interceptor)
|
||||
}
|
||||
|
||||
fun build(analytics: Analytics, data: AnalyticsHandlerBuilder.Data) {
|
||||
builders.mapNotNull { it.build(data) }.forEach { analytics.addHandler(it.id(), it) }
|
||||
filters.forEach { analytics.addFilter(it) }
|
||||
interceptors.forEach { analytics.addParamsInterceptor(it) }
|
||||
|
||||
builders.clear()
|
||||
filters.clear()
|
||||
interceptors.clear()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class AnalyticsHandlersFactory {
|
||||
|
||||
private val builders = mutableListOf<AnalyticsHandlerBuilder>()
|
||||
|
||||
fun addBuilder(builder: AnalyticsHandlerBuilder) {
|
||||
builders.add(builder)
|
||||
}
|
||||
|
||||
fun build(data: AnalyticsHandlerBuilder.Data): List<AnalyticsEventHandler> {
|
||||
val handlers = builders.mapNotNull { it.build(data) }
|
||||
builders.clear()
|
||||
|
||||
return handlers
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package com.tangem.tap.common.analytics.api
|
||||
|
||||
import com.tangem.blockchain.common.BlockchainError
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface ErrorEventHandler {
|
||||
fun send(
|
||||
error: Throwable,
|
||||
params: Map<String, String> = emptyMap(),
|
||||
)
|
||||
}
|
||||
|
||||
interface SdkErrorEventHandler : CardSdkErrorEventHandler, BlockchainSdkErrorEventHandler
|
||||
|
||||
interface CardSdkErrorEventHandler {
|
||||
fun send(
|
||||
error: TangemSdkError,
|
||||
action: AnalyticsAnOld.ActionToLog,
|
||||
params: Map<AnalyticsParamAnOld, String> = emptyMap(),
|
||||
card: Card? = null,
|
||||
)
|
||||
}
|
||||
|
||||
interface BlockchainSdkErrorEventHandler {
|
||||
fun send(
|
||||
error: BlockchainError,
|
||||
action: AnalyticsAnOld.ActionToLog,
|
||||
params: Map<AnalyticsParamAnOld, String> = mapOf(),
|
||||
card: Card? = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ interface AnalyticsEventFilter {
|
|||
/**
|
||||
* Performs a check to see if the event can be dispatched by a specific handler
|
||||
*/
|
||||
fun canBeConsumedByHandler(handler: AnalyticsEventHandler, event: AnalyticsEvent): Boolean
|
||||
fun canBeConsumedByHandler(handler: AnalyticsHandler, event: AnalyticsEvent): Boolean
|
||||
}
|
||||
|
||||
interface AnalyticsFilterHolder {
|
||||
|
|
|
|||
|
|
@ -1,53 +1,44 @@
|
|||
package com.tangem.tap.common.analytics.api
|
||||
|
||||
import android.app.Application
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.domain.common.AnalyticsHandlersLogConfig
|
||||
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
import com.tangem.tap.domain.configurable.config.Config
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface AnalyticsEventHandler {
|
||||
fun send(event: AnalyticsEvent)
|
||||
}
|
||||
|
||||
interface AnalyticsHandler : AnalyticsEventHandler {
|
||||
fun id(): String
|
||||
|
||||
fun send(event: String, params: Map<String, String> = emptyMap())
|
||||
|
||||
@Deprecated("Migrate to AnalyticsEvent")
|
||||
fun handleAnalyticsEvent(
|
||||
event: AnalyticsEventAnOld,
|
||||
params: Map<String, String> = emptyMap(),
|
||||
card: Card? = null,
|
||||
blockchain: String? = null,
|
||||
) {
|
||||
send(event.event, prepareParams(card, blockchain, params))
|
||||
override fun send(event: AnalyticsEvent) {
|
||||
send(prepareEventString(event), event.params)
|
||||
}
|
||||
|
||||
fun prepareParams(
|
||||
card: Card? = null,
|
||||
blockchain: String? = null,
|
||||
params: Map<String, String> = emptyMap(),
|
||||
): Map<String, String> = mapOf(
|
||||
AnalyticsParam.Firmware to card?.firmwareVersion?.stringValue,
|
||||
AnalyticsParam.Blockchain to blockchain,
|
||||
).filterNotNull() + params
|
||||
fun prepareEventString(event: AnalyticsEvent): String = "[${event.category}] ${event.event}"
|
||||
}
|
||||
|
||||
fun prepareEventString(category: String, event: String): String {
|
||||
return "[$category] $event"
|
||||
}
|
||||
interface ErrorEventHandler {
|
||||
fun send(
|
||||
error: Throwable,
|
||||
params: Map<String, String> = emptyMap(),
|
||||
)
|
||||
}
|
||||
|
||||
interface AnalyticsHandlerHolder {
|
||||
fun addHandler(name: String, handler: AnalyticsEventHandler)
|
||||
fun removeHandler(name: String): AnalyticsEventHandler?
|
||||
fun addHandler(name: String, handler: AnalyticsHandler)
|
||||
fun removeHandler(name: String): AnalyticsHandler?
|
||||
}
|
||||
|
||||
interface AnalyticsHandlerBuilder {
|
||||
fun build(data: Data): AnalyticsEventHandler?
|
||||
fun build(data: Data): AnalyticsHandler?
|
||||
|
||||
data class Data(
|
||||
val application: Application,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package com.tangem.tap.common.analytics.converters
|
||||
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.common.Converter
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.features.demo.DemoTransactionSender
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class AnalyticsErrorConverter : Converter<Throwable, Map<String, String>> {
|
||||
fun canBeHandled(error: Throwable): Boolean {
|
||||
return when (error) {
|
||||
is TangemSdkError.UserCancelled -> false
|
||||
is BlockchainSdkError -> !error.customMessage.contains(DemoTransactionSender.ID)
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
override fun convert(value: Throwable): Map<String, String> {
|
||||
return when (value) {
|
||||
is BlockchainSdkError -> BlockchainSdkErrorConverter(CardSdkErrorConverter()).convert(value)
|
||||
is TangemSdkError -> CardSdkErrorConverter().convert(value)
|
||||
else -> ThrowableErrorConverter().convert(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ThrowableErrorConverter : Converter<Throwable, Map<String, String>> {
|
||||
override fun convert(value: Throwable): Map<String, String> {
|
||||
val unknown = "unknown"
|
||||
return mapOf(
|
||||
AnalyticsParam.ErrorKey to AnalyticsParam.Error.App.value,
|
||||
AnalyticsParam.ErrorDescription to (value.message ?: value.cause?.message ?: unknown),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class CardSdkErrorConverter : Converter<TangemSdkError, Map<String, String>> {
|
||||
|
||||
override fun convert(value: TangemSdkError): Map<String, String> {
|
||||
if (value is TangemSdkError.UserCancelled) return emptyMap()
|
||||
|
||||
return mapOf(
|
||||
AnalyticsParam.ErrorKey to AnalyticsParam.Error.CardSdk.value,
|
||||
AnalyticsParam.ErrorCode to value.code.toString(),
|
||||
AnalyticsParam.ErrorDescription to value.toString(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class BlockchainSdkErrorConverter(
|
||||
private val cardSdkErrorConverter: CardSdkErrorConverter,
|
||||
) : Converter<BlockchainSdkError, Map<String, String>> {
|
||||
|
||||
override fun convert(value: BlockchainSdkError): Map<String, String> {
|
||||
if (value.customMessage.contains(DemoTransactionSender.ID)) return emptyMap()
|
||||
|
||||
if (value is BlockchainSdkError.WrappedTangemError) {
|
||||
return (value.tangemError as? TangemSdkError)?.let { cardSdkErrorConverter.convert(it) } ?: emptyMap()
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
AnalyticsParam.ErrorKey to AnalyticsParam.Error.BlockchainSdk.value,
|
||||
AnalyticsParam.ErrorCode to value.code.toString(),
|
||||
AnalyticsParam.ErrorDescription to "${value.javaClass.simpleName}: ${value.customMessage}",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
package com.tangem.tap.common.analytics.converters
|
||||
|
||||
import com.tangem.blockchain.common.BlockchainError
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.common.Converter
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
||||
import com.tangem.tap.common.analytics.TangemSdk
|
||||
import com.tangem.tap.features.demo.DemoTransactionSender
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal data class ErrorEvent(
|
||||
val throwable: Throwable,
|
||||
val params: Map<String, String>,
|
||||
)
|
||||
|
||||
internal class CardSdkErrorConverter : Converter<CardSdkErrorConverter.Model, ErrorEvent?> {
|
||||
|
||||
override fun convert(value: Model): ErrorEvent? {
|
||||
if (value.error is TangemSdkError.UserCancelled) return null
|
||||
|
||||
val mutableParams = value.params.convertToParamValue().toMutableMap().apply {
|
||||
putAll(value.cardParams)
|
||||
}
|
||||
mutableParams[AnalyticsParamAnOld.ACTION.param] = value.action.key
|
||||
mutableParams[AnalyticsParamAnOld.ERROR_CODE.param] = value.error.code.toString()
|
||||
mutableParams[AnalyticsParamAnOld.ERROR_DESCRIPTION.param] = value.error.javaClass.simpleName
|
||||
mutableParams[AnalyticsParamAnOld.ERROR_KEY.param] = "TangemSdkError"
|
||||
|
||||
return ErrorEvent(TangemSdk.map(value.error), mutableParams)
|
||||
}
|
||||
|
||||
internal data class Model(
|
||||
val error: TangemSdkError,
|
||||
val action: AnalyticsAnOld.ActionToLog,
|
||||
val params: Map<AnalyticsParamAnOld, String>,
|
||||
val cardParams: Map<String, String>,
|
||||
)
|
||||
}
|
||||
|
||||
internal class BlockchainSdkErrorConverter(
|
||||
private val cardSdkErrorConverter: CardSdkErrorConverter,
|
||||
) : Converter<BlockchainSdkErrorConverter.Model, ErrorEvent?> {
|
||||
|
||||
override fun convert(value: Model): ErrorEvent? {
|
||||
val error = (value.error as? BlockchainSdkError) ?: return null
|
||||
|
||||
if (error is BlockchainSdkError.WrappedTangemError) {
|
||||
val tangemSdkError = (error.tangemError as? TangemSdkError) ?: return null
|
||||
|
||||
val cardSdkModel = CardSdkErrorConverter.Model(
|
||||
error = tangemSdkError,
|
||||
action = value.action,
|
||||
params = value.params,
|
||||
cardParams = value.cardParams,
|
||||
)
|
||||
return cardSdkErrorConverter.convert(cardSdkModel)
|
||||
}
|
||||
|
||||
if (error.customMessage.contains(DemoTransactionSender.ID)) return null
|
||||
|
||||
val mutableParams = value.params.convertToParamValue().toMutableMap()
|
||||
mutableParams[AnalyticsParamAnOld.ACTION.param] = value.action.key
|
||||
mutableParams[AnalyticsParamAnOld.ERROR_CODE.param] = error.code.toString()
|
||||
mutableParams[AnalyticsParamAnOld.ERROR_DESCRIPTION.param] = "${error.javaClass.simpleName}: ${error.customMessage}"
|
||||
mutableParams[AnalyticsParamAnOld.ERROR_KEY.param] = "BlockchainSdkError"
|
||||
|
||||
return ErrorEvent(value.error, mutableParams)
|
||||
}
|
||||
|
||||
data class Model(
|
||||
val error: BlockchainError,
|
||||
val action: AnalyticsAnOld.ActionToLog,
|
||||
val params: Map<AnalyticsParamAnOld, String>,
|
||||
val cardParams: Map<String, String>,
|
||||
)
|
||||
}
|
||||
|
||||
internal fun Map<AnalyticsParamAnOld, String>.convertToParamValue(): Map<String, String> {
|
||||
return mutableMapOf<String, String>().also { newMap ->
|
||||
this.forEach {
|
||||
newMap[it.key.param] = it.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ package com.tangem.tap.common.analytics.events
|
|||
sealed class AnalyticsEvent(
|
||||
val category: String,
|
||||
val event: String,
|
||||
val params: Map<String, String> = mapOf(),
|
||||
var params: Map<String, String> = mapOf(),
|
||||
val error: Throwable? = null,
|
||||
var filterData: Any? = null,
|
||||
)
|
||||
|
|
@ -54,11 +54,16 @@ sealed class AnalyticsParam {
|
|||
}
|
||||
}
|
||||
|
||||
sealed class Error(val value: String) {
|
||||
object App : Error("App Error")
|
||||
object CardSdk : Error("Card Sdk Error")
|
||||
object BlockchainSdk : Error("Blockchain Sdk Error")
|
||||
}
|
||||
|
||||
companion object Key {
|
||||
const val BatchId = "Batch"
|
||||
|
||||
// old keys
|
||||
const val Blockchain = "blockchain"
|
||||
const val Firmware = "firmware"
|
||||
const val ErrorDescription = "Error Description"
|
||||
const val ErrorCode = "Error Code"
|
||||
const val ErrorKey = "Error Key"
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,8 @@ package com.tangem.tap.common.analytics.events
|
|||
sealed class Basic(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : AnalyticsEvent("Basic", event, params) {
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent("Basic", event, params, error) {
|
||||
|
||||
class SignedIn(
|
||||
state: AnalyticsParam.CardBalanceState,
|
||||
|
|
@ -25,4 +26,9 @@ sealed class Basic(
|
|||
event = "Topped up",
|
||||
params = mapOf("Currency" to currency.value),
|
||||
)
|
||||
|
||||
class ScanError(error: Throwable) : Basic(
|
||||
event = "Scan",
|
||||
error = error,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ sealed class Settings(
|
|||
category: String = "Settings",
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : AnalyticsEvent(category, event, params) {
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent(category, event, params, error) {
|
||||
|
||||
class ScreenOpened : Settings(event = "Settings Screen Opened")
|
||||
class ButtonChat : Settings(event = "Button - Chat")
|
||||
|
|
@ -28,10 +29,15 @@ sealed class Settings(
|
|||
sealed class CardSettings(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : Settings("Settings / Card Settings", event, params) {
|
||||
error: Throwable? = null,
|
||||
) : Settings("Settings / Card Settings", event, params, error) {
|
||||
|
||||
class ButtonFactoryReset : CardSettings("Button - Factory Reset")
|
||||
class FactoryResetFinished : CardSettings("Factory Reset Finished")
|
||||
class FactoryResetFinished(error: Throwable? = null) : CardSettings(
|
||||
event = "Factory Reset Finished",
|
||||
error = error,
|
||||
)
|
||||
|
||||
class UserCodeChanged : CardSettings("User Code Changed")
|
||||
class ButtonChangeSecurityMode : CardSettings("Button - Change Security Mode")
|
||||
|
||||
|
|
@ -40,9 +46,10 @@ sealed class Settings(
|
|||
params = mapOf("Type" to type.value),
|
||||
)
|
||||
|
||||
class SecurityModeChanged(mode: AnalyticsParam.SecurityMode) : CardSettings(
|
||||
class SecurityModeChanged(mode: AnalyticsParam.SecurityMode, error: Throwable? = null) : CardSettings(
|
||||
event = "Security Mode Changed",
|
||||
params = mapOf("Mode" to mode.value),
|
||||
error = error,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ sealed class Token(
|
|||
category: String,
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : AnalyticsEvent(category, event, params) {
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent(category, event, params, error) {
|
||||
|
||||
class Refreshed : Token("Token", "Refreshed")
|
||||
class ButtonExplore : Token("Token", "Button - Explore")
|
||||
|
|
@ -57,16 +58,18 @@ sealed class Token(
|
|||
sealed class Send(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : Token("Token / Send", event, params) {
|
||||
error: Throwable? = null,
|
||||
) : Token("Token / Send", event, params, error) {
|
||||
|
||||
class ScreenOpened : Send("Send Screen Opened")
|
||||
class ButtonPaste : Send("Button - Paste")
|
||||
class ButtonQRCode : Send("Button - QR Code")
|
||||
class ButtonSwapCurrency : Send("Button - Swap Currency")
|
||||
|
||||
class TransactionSent(type: CurrencyType) : Send(
|
||||
class TransactionSent(type: CurrencyType, error: Throwable? = null) : Send(
|
||||
event = "Transaction Sent",
|
||||
params = mapOf("Token" to type.value),
|
||||
error = error,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,13 @@ package com.tangem.tap.common.analytics.events
|
|||
sealed class WalletConnect(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : AnalyticsEvent("Wallet Connect", event, params) {
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent("Wallet Connect", event, params, error) {
|
||||
|
||||
class NewSessionEstablished : WalletConnect("New Session Established")
|
||||
class SessionDisconnected : WalletConnect("Session Disconnected")
|
||||
class RequestSigned : WalletConnect("Request Signed")
|
||||
|
||||
class SignError(error: Throwable) : WalletConnect("Sign", error = error)
|
||||
class TransactionError(error: Throwable) : WalletConnect("Transaction", error = error)
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.common.analytics.filters
|
||||
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventFilter
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
|
||||
|
|
@ -23,5 +23,5 @@ class BasicSignInFilter : AnalyticsEventFilter {
|
|||
return canBeSent
|
||||
}
|
||||
|
||||
override fun canBeConsumedByHandler(handler: AnalyticsEventHandler, event: AnalyticsEvent): Boolean = true
|
||||
override fun canBeConsumedByHandler(handler: AnalyticsHandler, event: AnalyticsEvent): Boolean = true
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.common.analytics.filters
|
|||
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventFilter
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
|
|
@ -39,7 +39,7 @@ class BasicTopUpFilter(
|
|||
}
|
||||
}
|
||||
|
||||
override fun canBeConsumedByHandler(handler: AnalyticsEventHandler, event: AnalyticsEvent): Boolean = true
|
||||
override fun canBeConsumedByHandler(handler: AnalyticsHandler, event: AnalyticsEvent): Boolean = true
|
||||
|
||||
data class Data(
|
||||
val walletId: String,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.common.analytics.filters
|
||||
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventFilter
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
import com.tangem.tap.common.analytics.handlers.appsFlyer.AppsFlyerAnalyticsHandler
|
||||
|
|
@ -16,7 +16,7 @@ class ShopPurchasedEventFilter : AnalyticsEventFilter {
|
|||
|
||||
override fun canBeSent(event: AnalyticsEvent): Boolean = true
|
||||
|
||||
override fun canBeConsumedByHandler(handler: AnalyticsEventHandler, event: AnalyticsEvent): Boolean {
|
||||
override fun canBeConsumedByHandler(handler: AnalyticsHandler, event: AnalyticsEvent): Boolean {
|
||||
return when (handler) {
|
||||
is AppsFlyerAnalyticsHandler, is FirebaseAnalyticsHandler -> true
|
||||
else -> false
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.tap.common.analytics.handlers.amplitude
|
||||
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
|
||||
class AmplitudeAnalyticsHandler(
|
||||
private val client: AmplitudeAnalyticsClient,
|
||||
) : AnalyticsEventHandler {
|
||||
) : AnalyticsHandler {
|
||||
|
||||
override fun id(): String = ID
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ class AmplitudeAnalyticsHandler(
|
|||
}
|
||||
|
||||
class Builder : AnalyticsHandlerBuilder {
|
||||
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsEventHandler? = when {
|
||||
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler? = when {
|
||||
!data.isDebug -> AmplitudeClient(data.application, data.config.amplitudeApiKey)
|
||||
data.isDebug && data.logConfig.amplitude -> AmplitudeLogClient(data.jsonConverter)
|
||||
else -> null
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.tap.common.analytics.handlers.appsFlyer
|
||||
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
|
||||
class AppsFlyerAnalyticsHandler(
|
||||
private val client: AppsFlyerAnalyticsClient,
|
||||
) : AnalyticsEventHandler {
|
||||
) : AnalyticsHandler {
|
||||
|
||||
override fun id(): String = ID
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ class AppsFlyerAnalyticsHandler(
|
|||
}
|
||||
|
||||
class Builder : AnalyticsHandlerBuilder {
|
||||
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsEventHandler? = when {
|
||||
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler? = when {
|
||||
!data.isDebug -> AppsFlyerClient(data.application, data.config.appsFlyerDevKey)
|
||||
data.isDebug && data.logConfig.appsFlyer -> AppsFlyerLogClient(data.jsonConverter)
|
||||
else -> null
|
||||
|
|
|
|||
|
|
@ -1,20 +1,14 @@
|
|||
package com.tangem.tap.common.analytics.handlers.firebase
|
||||
|
||||
import com.tangem.blockchain.common.BlockchainError
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.api.ErrorEventHandler
|
||||
import com.tangem.tap.common.analytics.api.SdkErrorEventHandler
|
||||
import com.tangem.tap.common.analytics.converters.BlockchainSdkErrorConverter
|
||||
import com.tangem.tap.common.analytics.converters.CardSdkErrorConverter
|
||||
import com.tangem.tap.common.analytics.converters.AnalyticsErrorConverter
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
|
||||
class FirebaseAnalyticsHandler(
|
||||
private val client: FirebaseAnalyticsClient,
|
||||
) : AnalyticsEventHandler, ErrorEventHandler, SdkErrorEventHandler {
|
||||
) : AnalyticsHandler, ErrorEventHandler {
|
||||
|
||||
override fun id(): String = ID
|
||||
|
||||
|
|
@ -22,43 +16,32 @@ class FirebaseAnalyticsHandler(
|
|||
client.logEvent(event, params)
|
||||
}
|
||||
|
||||
override fun send(event: AnalyticsEvent) {
|
||||
when (event.error) {
|
||||
null -> super.send(event)
|
||||
else -> {
|
||||
val errorConverter = AnalyticsErrorConverter()
|
||||
if (!errorConverter.canBeHandled(event.error)) return
|
||||
|
||||
val errorParams = errorConverter.convert(event.error).toMutableMap()
|
||||
errorParams["Category"] = event.category
|
||||
errorParams["Event"] = event.event
|
||||
errorParams.putAll(event.params)
|
||||
send(event.error, errorParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun send(error: Throwable, params: Map<String, String>) {
|
||||
client.logErrorEvent(error, params)
|
||||
}
|
||||
|
||||
override fun send(
|
||||
error: TangemSdkError,
|
||||
action: AnalyticsAnOld.ActionToLog,
|
||||
params: Map<AnalyticsParamAnOld, String>,
|
||||
card: Card?,
|
||||
) {
|
||||
val model = CardSdkErrorConverter.Model(error, action, params, prepareParams(card))
|
||||
val converter = CardSdkErrorConverter()
|
||||
converter.convert(model)?.let {
|
||||
send(it.throwable, it.params)
|
||||
}
|
||||
}
|
||||
|
||||
override fun send(
|
||||
error: BlockchainError,
|
||||
action: AnalyticsAnOld.ActionToLog,
|
||||
params: Map<AnalyticsParamAnOld, String>,
|
||||
card: Card?,
|
||||
) {
|
||||
|
||||
val model = BlockchainSdkErrorConverter.Model(error, action, params, prepareParams(card))
|
||||
val converter = BlockchainSdkErrorConverter(CardSdkErrorConverter())
|
||||
converter.convert(model)?.let {
|
||||
send(it.throwable, it.params)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ID = "Firebase"
|
||||
}
|
||||
|
||||
class Builder : AnalyticsHandlerBuilder {
|
||||
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsEventHandler? = when {
|
||||
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler? = when {
|
||||
!data.isDebug -> FirebaseClient()
|
||||
data.isDebug && data.logConfig.firebase -> FirebaseLogClient(data.jsonConverter)
|
||||
else -> null
|
||||
|
|
|
|||
|
|
@ -27,14 +27,11 @@ import com.tangem.operations.pins.CheckUserCodesCommand
|
|||
import com.tangem.operations.pins.CheckUserCodesResponse
|
||||
import com.tangem.operations.pins.SetUserCodeCommand
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask
|
||||
import com.tangem.tap.domain.tasks.product.ResetToFactorySettingsTask
|
||||
import com.tangem.tap.domain.tasks.product.ScanProductTask
|
||||
import com.tangem.tap.domain.tokens.UserTokensRepository
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.isActive
|
||||
|
|
@ -49,8 +46,6 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co
|
|||
additionalBlockchainsToDerive: Collection<Blockchain>? = null,
|
||||
messageRes: Int? = null,
|
||||
): CompletionResult<ScanResponse> {
|
||||
Analytics.handleAnalyticsEvent(AnalyticsEventAnOld.READY_TO_SCAN, card = null)
|
||||
|
||||
val message = Message(context.getString(messageRes ?: R.string.initial_message_scan_header))
|
||||
return runTaskAsyncReturnOnMain(
|
||||
runnable = ScanProductTask(null, userTokensRepository, additionalBlockchainsToDerive),
|
||||
|
|
@ -71,29 +66,10 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co
|
|||
private fun sendScanResultsToAnalytics(
|
||||
result: CompletionResult<ScanResponse>,
|
||||
) {
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
Analytics.handleAnalyticsEvent(
|
||||
event = AnalyticsEventAnOld.CARD_IS_SCANNED,
|
||||
card = result.data.card,
|
||||
blockchain = result.data.walletData?.blockchain,
|
||||
)
|
||||
if (DemoHelper.isDemoCard(result.data)) {
|
||||
Analytics.handleAnalyticsEvent(
|
||||
event = AnalyticsEventAnOld.DEMO_MODE_ACTIVATED,
|
||||
params = mapOf(AnalyticsParamAnOld.CARD_ID.param to result.data.card.cardId),
|
||||
card = result.data.card,
|
||||
blockchain = result.data.walletData?.blockchain,
|
||||
)
|
||||
}
|
||||
if (result is CompletionResult.Failure) {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(Basic.ScanError(error))
|
||||
}
|
||||
is CompletionResult.Failure ->
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(
|
||||
error = error,
|
||||
action = AnalyticsAnOld.ActionToLog.Scan,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,19 +7,16 @@ import com.tangem.blockchain.extensions.Result
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.KeyPair
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
import com.tangem.tap.common.AssetReader
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
|
||||
class TwinCardsManager(
|
||||
private val card: Card,
|
||||
card: Card,
|
||||
assetReader: AssetReader,
|
||||
) {
|
||||
|
||||
|
|
@ -34,15 +31,7 @@ class TwinCardsManager(
|
|||
val response = tangemSdkManager.runTaskAsync(CreateFirstTwinWalletTask(), currentCardId, message)
|
||||
when (response) {
|
||||
is CompletionResult.Success -> currentCardPublicKey = response.data.wallet.publicKey.toHexString()
|
||||
is CompletionResult.Failure -> {
|
||||
(response.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.CreateWallet,
|
||||
card = card
|
||||
)
|
||||
}
|
||||
}
|
||||
is CompletionResult.Failure -> {}
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
|
@ -57,22 +46,14 @@ class TwinCardsManager(
|
|||
firstCardId = currentCardId,
|
||||
issuerKeys = issuerKeyPair,
|
||||
preparingMessage = preparingMessage,
|
||||
creatingWalletMessage = creatingWalletMessage
|
||||
creatingWalletMessage = creatingWalletMessage,
|
||||
)
|
||||
val response = tangemSdkManager.runTaskAsync(task, null, initialMessage)
|
||||
when (response) {
|
||||
is CompletionResult.Success -> {
|
||||
secondCardPublicKey = response.data.wallet.publicKey.toHexString()
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(response.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.CreateWallet,
|
||||
card = card
|
||||
)
|
||||
}
|
||||
}
|
||||
is CompletionResult.Failure -> {}
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
|
@ -80,20 +61,11 @@ class TwinCardsManager(
|
|||
suspend fun complete(message: Message): Result<ScanResponse> {
|
||||
val response = tangemSdkManager.runTaskAsync(
|
||||
FinalizeTwinTask(secondCardPublicKey!!.hexToBytes(), issuerKeyPair),
|
||||
currentCardId, message
|
||||
currentCardId, message,
|
||||
)
|
||||
return when (response) {
|
||||
is CompletionResult.Success -> Result.Success(response.data)
|
||||
is CompletionResult.Failure -> {
|
||||
(response.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.WriteIssuerData,
|
||||
card = card
|
||||
)
|
||||
}
|
||||
Result.fromTangemSdkError(response.error)
|
||||
}
|
||||
is CompletionResult.Failure -> Result.fromTangemSdkError(response.error)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,13 +74,13 @@ class TwinCardsManager(
|
|||
val issuer = getIssuers(reader).first { it.publicKey == publicKey }
|
||||
return KeyPair(
|
||||
publicKey = issuer.publicKey.hexToBytes(),
|
||||
privateKey = issuer.privateKey.hexToBytes()
|
||||
privateKey = issuer.privateKey.hexToBytes(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getAdapter(): JsonAdapter<List<Issuer>> {
|
||||
return MoshiConverter.defaultMoshi().adapter(
|
||||
Types.newParameterizedType(List::class.java, Issuer::class.java)
|
||||
Types.newParameterizedType(List::class.java, Issuer::class.java),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@ import com.tangem.common.card.EllipticCurve
|
|||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.events.WalletConnect
|
||||
import com.tangem.tap.common.analytics.logWcEvent
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
|
|
@ -226,11 +224,6 @@ class WalletConnectManager {
|
|||
|
||||
private fun onSessionClosed(session: WCSession) {
|
||||
Analytics.send(WalletConnect.SessionDisconnected())
|
||||
Analytics.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Session(
|
||||
AnalyticsAnOld.WcSessionEvent.Disconnect, sessions[session]?.peerMeta?.url
|
||||
)
|
||||
)
|
||||
sessions.remove(session)
|
||||
walletConnectRepository.removeSession(session)
|
||||
store.dispatchOnMain(WalletConnectAction.RemoveSession(session))
|
||||
|
|
@ -376,11 +369,6 @@ class WalletConnectManager {
|
|||
)
|
||||
}
|
||||
Analytics.send(WalletConnect.NewSessionEstablished())
|
||||
Analytics.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Session(
|
||||
AnalyticsAnOld.WcSessionEvent.Connect, peer.url,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -391,11 +379,11 @@ class WalletConnectManager {
|
|||
}
|
||||
client.onEthSendTransaction = { id: Long, transaction: WCEthereumTransaction ->
|
||||
Timber.d("onEthSendTransaction: $transaction")
|
||||
Analytics.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.SendTransaction
|
||||
)
|
||||
)
|
||||
// Analytics.logWcEvent(
|
||||
// AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
// AnalyticsAnOld.WcAction.SendTransaction
|
||||
// )
|
||||
// )
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
WalletConnectAction.HandleTransactionRequest(
|
||||
|
|
@ -409,11 +397,11 @@ class WalletConnectManager {
|
|||
}
|
||||
client.onEthSignTransaction = { id: Long, transaction: WCEthereumTransaction ->
|
||||
Timber.d("onEthSignTransaction: $transaction")
|
||||
Analytics.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.SignTransaction
|
||||
)
|
||||
)
|
||||
// Analytics.logWcEvent(
|
||||
// AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
// AnalyticsAnOld.WcAction.SignTransaction
|
||||
// )
|
||||
// )
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
WalletConnectAction.HandleTransactionRequest(
|
||||
|
|
@ -427,11 +415,11 @@ class WalletConnectManager {
|
|||
}
|
||||
client.onEthSign = { id: Long, message: WCEthereumSignMessage ->
|
||||
Timber.d("onEthSign: $message")
|
||||
Analytics.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.PersonalSign
|
||||
)
|
||||
)
|
||||
// Analytics.logWcEvent(
|
||||
// AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
// AnalyticsAnOld.WcAction.PersonalSign
|
||||
// )
|
||||
// )
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
WalletConnectAction.HandlePersonalSignRequest(
|
||||
|
|
@ -503,11 +491,11 @@ class WalletConnectManager {
|
|||
val message = EthSignHelper.tryToParseEthTypedMessage(request)
|
||||
if (message != null) {
|
||||
Timber.d("onEthSign_v4: $message")
|
||||
Analytics.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.PersonalSign
|
||||
)
|
||||
)
|
||||
// Analytics.logWcEvent(
|
||||
// AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
// AnalyticsAnOld.WcAction.PersonalSign
|
||||
// )
|
||||
// )
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
WalletConnectAction.HandlePersonalSignRequest(
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.tangem.common.extensions.toHexString
|
|||
import com.tangem.crypto.CryptoUtils
|
||||
import com.tangem.operations.sign.SignHashCommand
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.events.WalletConnect
|
||||
import com.tangem.tap.common.extensions.safeUpdate
|
||||
import com.tangem.tap.common.extensions.toFormattedString
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession
|
||||
|
|
@ -88,8 +88,8 @@ class WalletConnectSdkHelper {
|
|||
extras = EthereumTransactionExtras(
|
||||
data = transaction.data.removePrefix(HEX_PREFIX).hexToBytes(),
|
||||
gasLimit = gas.toBigInteger(),
|
||||
nonce = transaction.nonce?.hexToBigDecimal()?.toBigInteger()
|
||||
)
|
||||
nonce = transaction.nonce?.hexToBigDecimal()?.toBigInteger(),
|
||||
),
|
||||
)
|
||||
val dialogData = TransactionRequestDialogData(
|
||||
dAppName = session.peerMeta.name,
|
||||
|
|
@ -101,7 +101,7 @@ class WalletConnectSdkHelper {
|
|||
isEnoughFundsToSend = (balance - total) >= BigDecimal.ZERO,
|
||||
session = session.session,
|
||||
id = id,
|
||||
type = type
|
||||
type = type,
|
||||
)
|
||||
return WcTransactionData(
|
||||
type = type,
|
||||
|
|
@ -109,7 +109,7 @@ class WalletConnectSdkHelper {
|
|||
session = session,
|
||||
id = id,
|
||||
walletManager = walletManager,
|
||||
dialogData = dialogData
|
||||
dialogData = dialogData,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ class WalletConnectSdkHelper {
|
|||
val blockchain = session.wallet.getBlockchainForSession()
|
||||
return factory.makeWalletManager(
|
||||
blockchain = blockchain,
|
||||
publicKey = publicKey
|
||||
publicKey = publicKey,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -137,14 +137,14 @@ class WalletConnectSdkHelper {
|
|||
private suspend fun sendTransaction(data: WcTransactionData): String? {
|
||||
val result = (data.walletManager as TransactionSender).send(
|
||||
transactionData = data.transaction,
|
||||
signer = CommonSigner(tangemSdk)
|
||||
signer = CommonSigner(tangemSdk),
|
||||
)
|
||||
return when (result) {
|
||||
SimpleResult.Success -> {
|
||||
HEX_PREFIX + data.walletManager.wallet.recentTransactions.last().hash
|
||||
}
|
||||
is SimpleResult.Failure -> {
|
||||
Analytics.send(result.error, AnalyticsAnOld.ActionToLog.WalletConnectTransaction)
|
||||
(result.error as? TangemSdkError)?.let { Analytics.send(WalletConnect.TransactionError(it)) }
|
||||
Timber.e(result.error as BlockchainSdkError)
|
||||
null
|
||||
}
|
||||
|
|
@ -156,13 +156,13 @@ class WalletConnectSdkHelper {
|
|||
transactionData = data.transaction,
|
||||
nonce = null,
|
||||
blockchain = data.walletManager.wallet.blockchain,
|
||||
gasLimit = null
|
||||
gasLimit = null,
|
||||
) ?: return null
|
||||
|
||||
val command = SignHashCommand(
|
||||
hash = dataToSign.hash,
|
||||
walletPublicKey = data.walletManager.wallet.publicKey.seedKey,
|
||||
derivationPath = data.walletManager.wallet.publicKey.derivationPath
|
||||
derivationPath = data.walletManager.wallet.publicKey.derivationPath,
|
||||
)
|
||||
val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message())
|
||||
return when (result) {
|
||||
|
|
@ -170,9 +170,7 @@ class WalletConnectSdkHelper {
|
|||
HEX_PREFIX + result.data
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(error, AnalyticsAnOld.ActionToLog.WalletConnectSign)
|
||||
}
|
||||
(result.error as? TangemSdkError)?.let { Analytics.send(WalletConnect.SignError(it)) }
|
||||
Timber.e(result.error.customMessage)
|
||||
null
|
||||
}
|
||||
|
|
@ -183,7 +181,7 @@ class WalletConnectSdkHelper {
|
|||
val command = SignHashCommand(
|
||||
hash = data,
|
||||
walletPublicKey = session.wallet.walletPublicKey ?: return null,
|
||||
derivationPath = session.wallet.derivationPath
|
||||
derivationPath = session.wallet.derivationPath,
|
||||
)
|
||||
val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message())
|
||||
return when (result) {
|
||||
|
|
@ -192,13 +190,11 @@ class WalletConnectSdkHelper {
|
|||
?: session.wallet.walletPublicKey.toDecompressedPublicKey()
|
||||
getBnbResultString(
|
||||
key.toHexString(),
|
||||
result.data.signature.toHexString()
|
||||
result.data.signature.toHexString(),
|
||||
)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(error, AnalyticsAnOld.ActionToLog.WalletConnectTransaction)
|
||||
}
|
||||
(result.error as? TangemSdkError)?.let { Analytics.send(WalletConnect.TransactionError(it)) }
|
||||
Timber.e(result.error.customMessage)
|
||||
null
|
||||
}
|
||||
|
|
@ -223,18 +219,17 @@ class WalletConnectSdkHelper {
|
|||
val prefixData = (ETH_MESSAGE_PREFIX + messageData.size.toString()).toByteArray()
|
||||
val hashToSign = (prefixData + messageData).toKeccak()
|
||||
|
||||
|
||||
val dialogData = PersonalSignDialogData(
|
||||
dAppName = session.peerMeta.name,
|
||||
message = messageString,
|
||||
session = session.session,
|
||||
id = id
|
||||
id = id,
|
||||
)
|
||||
return WcPersonalSignData(
|
||||
hash = hashToSign,
|
||||
session = session,
|
||||
id = id,
|
||||
dialogData = dialogData
|
||||
dialogData = dialogData,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -269,9 +264,7 @@ class WalletConnectSdkHelper {
|
|||
)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(error, AnalyticsAnOld.ActionToLog.WalletConnectSign)
|
||||
}
|
||||
(result.error as? TangemSdkError)?.let { Analytics.send(WalletConnect.SignError(it)) }
|
||||
Timber.e(result.error.customMessage)
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Settings
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
|
|
@ -129,11 +127,7 @@ class DetailsMiddleware {
|
|||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.PurgeWallet,
|
||||
card = store.state.detailsState.scanResponse?.card,
|
||||
)
|
||||
Analytics.send(Settings.CardSettings.FactoryResetFinished(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -160,30 +154,20 @@ class DetailsMiddleware {
|
|||
SecurityOption.LongTap -> tangemSdkManager.setLongTap(cardId)
|
||||
SecurityOption.PassCode -> tangemSdkManager.setPasscode(cardId)
|
||||
SecurityOption.AccessCode -> tangemSdkManager.setAccessCode(cardId)
|
||||
else -> null
|
||||
else -> return@launch
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
val paramValue = AnalyticsParam.SecurityMode.from(selectedOption)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
selectedOption?.let {
|
||||
val paramValue = AnalyticsParam.SecurityMode.from(it)
|
||||
Analytics.send(Settings.CardSettings.SecurityModeChanged(paramValue))
|
||||
store.dispatch(GlobalAction.UpdateSecurityOptions(it))
|
||||
}
|
||||
Analytics.send(Settings.CardSettings.SecurityModeChanged(paramValue))
|
||||
store.dispatch(GlobalAction.UpdateSecurityOptions(selectedOption))
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
store.dispatch(DetailsAction.ManageSecurity.SaveChanges.Success)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(
|
||||
error = error,
|
||||
action = AnalyticsAnOld.ActionToLog.ChangeSecOptions,
|
||||
params = mapOf(
|
||||
AnalyticsParamAnOld.NEW_SECURITY_OPTION to
|
||||
(selectedOption?.name ?: ""),
|
||||
),
|
||||
card = store.state.detailsState.scanResponse?.card,
|
||||
)
|
||||
Analytics.send(Settings.CardSettings.SecurityModeChanged(paramValue, error))
|
||||
}
|
||||
store.dispatch(DetailsAction.ManageSecurity.SaveChanges.Failure)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ import com.tangem.operations.backup.BackupService
|
|||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
import com.tangem.tap.backupService
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
||||
import com.tangem.tap.common.analytics.GetCardSourceParamsAnOld
|
||||
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
||||
import com.tangem.tap.common.analytics.paramsInterceptor.BatchIdParamsInterceptor
|
||||
import com.tangem.tap.common.entities.IndeterminateProgressButton
|
||||
|
|
@ -107,10 +104,6 @@ private fun handleHomeAction(appState: () -> AppState?, action: Action, dispatch
|
|||
RUSSIA_COUNTRY_CODE, BELARUS_COUNTRY_CODE -> store.dispatchOpenUrl(BUY_WALLET_URL)
|
||||
else -> store.dispatch(NavigationAction.NavigateTo(AppScreen.Shop))
|
||||
}
|
||||
Analytics.handleAnalyticsEvent(
|
||||
event = AnalyticsEventAnOld.GET_CARD,
|
||||
params = mapOf(AnalyticsParamAnOld.SOURCE.param to GetCardSourceParamsAnOld.WELCOME.param),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
|||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
|
||||
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Token
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
|
|
@ -222,14 +219,10 @@ private fun sendTransaction(
|
|||
dispatch(SendAction.ChangeSendButtonState(ButtonState.ENABLED))
|
||||
tangemSdk.config.linkedTerminal = isLinkedTerminal
|
||||
|
||||
val currencyType = AnalyticsParam.CurrencyType.Amount(amountToSend)
|
||||
when (sendResult) {
|
||||
is SimpleResult.Success -> {
|
||||
Analytics.send(Token.Send.TransactionSent(AnalyticsParam.CurrencyType.Amount(amountToSend)))
|
||||
Analytics.handleAnalyticsEvent(
|
||||
event = AnalyticsEventAnOld.TRANSACTION_IS_SENT,
|
||||
card = card,
|
||||
blockchain = walletManager.wallet.blockchain.currency,
|
||||
)
|
||||
Analytics.send(Token.Send.TransactionSent(currencyType))
|
||||
dispatch(SendAction.SendSuccess)
|
||||
|
||||
if (externalTransactionData != null) {
|
||||
|
|
@ -254,15 +247,10 @@ private fun sendTransaction(
|
|||
feeAmount = feeAmount,
|
||||
destinationAddress = destinationAddress,
|
||||
)
|
||||
Analytics.send(
|
||||
error = sendResult.error,
|
||||
action = AnalyticsAnOld.ActionToLog.SendTransaction,
|
||||
params = mapOf(AnalyticsParamAnOld.BLOCKCHAIN to walletManager.wallet.blockchain.currency),
|
||||
card = card,
|
||||
)
|
||||
|
||||
val error = (sendResult.error as? BlockchainSdkError) ?: return@withMainContext
|
||||
|
||||
Analytics.send(Token.Send.TransactionSent(currencyType, error))
|
||||
|
||||
when (error) {
|
||||
is BlockchainSdkError.WrappedTangemError -> {
|
||||
val tangemSdkError = (error.tangemError as? TangemSdkError) ?: return@withMainContext
|
||||
|
|
|
|||
|
|
@ -5,14 +5,12 @@ import com.tangem.blockchain.common.Amount
|
|||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.operations.attestation.Attestation
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
import com.tangem.tap.common.analytics.events.Token
|
||||
import com.tangem.tap.common.extensions.copyToClipboard
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
|
|
@ -189,15 +187,7 @@ class WalletMiddleware {
|
|||
globalState.scanResponse?.copy(card = result.data)
|
||||
scanNoteResponse?.let { store.onCardScanned(scanNoteResponse) }
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.CreateWallet,
|
||||
card = store.state.detailsState.scanResponse?.card,
|
||||
)
|
||||
}
|
||||
}
|
||||
is CompletionResult.Failure -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ import com.tangem.common.card.Card
|
|||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.extensions.isGreaterThan
|
||||
import com.tangem.tap.common.redux.global.GlobalState
|
||||
|
|
@ -55,14 +53,10 @@ class WarningsMiddleware {
|
|||
if (action.remainingSignatures != null &&
|
||||
action.remainingSignatures <= WarningMessagesManager.REMAINING_SIGNATURES_WARNING
|
||||
) {
|
||||
store.state.globalState.warningManager
|
||||
?.removeWarnings(
|
||||
messageRes = R.string.warning_low_signatures_format
|
||||
)
|
||||
store.state.globalState.warningManager?.removeWarnings(R.string.warning_low_signatures_format)
|
||||
addWarningMessage(
|
||||
warning =
|
||||
WarningMessagesManager.remainingSignaturesNotEnough(action.remainingSignatures),
|
||||
autoUpdate = true
|
||||
warning = WarningMessagesManager.remainingSignaturesNotEnough(action.remainingSignatures),
|
||||
autoUpdate = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +64,8 @@ class WarningsMiddleware {
|
|||
is WalletAction.Warnings.CheckHashesCount,
|
||||
is WalletAction.Warnings.CheckHashesCount.ConfirmHashesCount,
|
||||
is WalletAction.Warnings.CheckHashesCount.NeedToCheckHashesCountOnline,
|
||||
is WalletAction.Warnings.Set -> Unit
|
||||
is WalletAction.Warnings.Set,
|
||||
-> Unit
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +77,6 @@ class WarningsMiddleware {
|
|||
preferencesStorage.appRatingLaunchObserver.foundWalletWithFunds()
|
||||
}
|
||||
if (preferencesStorage.appRatingLaunchObserver.isReadyToShow()) {
|
||||
Analytics.handleAnalyticsEvent(AnalyticsEventAnOld.APP_RATING_DISPLAYED)
|
||||
addWarningMessage(WarningMessagesManager.appRatingWarning(), true)
|
||||
}
|
||||
}
|
||||
|
|
@ -119,11 +113,7 @@ class WarningsMiddleware {
|
|||
if (remainingSignatures != null &&
|
||||
remainingSignatures <= WarningMessagesManager.REMAINING_SIGNATURES_WARNING
|
||||
) {
|
||||
addWarningMessage(
|
||||
WarningMessagesManager.remainingSignaturesNotEnough(
|
||||
remainingSignatures
|
||||
)
|
||||
)
|
||||
addWarningMessage(WarningMessagesManager.remainingSignaturesNotEnough(remainingSignatures))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,15 +169,9 @@ class WarningsMiddleware {
|
|||
}
|
||||
is SimpleResult.Failure ->
|
||||
if (result.error is BlockchainSdkError.SignatureCountNotMatched) {
|
||||
addWarningMessage(
|
||||
WarningMessagesManager.alreadySignedHashesWarning(),
|
||||
true
|
||||
)
|
||||
addWarningMessage(WarningMessagesManager.alreadySignedHashesWarning(), true)
|
||||
} else if (signedHashes > 0) {
|
||||
addWarningMessage(
|
||||
WarningMessagesManager.alreadySignedHashesWarning(),
|
||||
true
|
||||
)
|
||||
addWarningMessage(WarningMessagesManager.alreadySignedHashesWarning(), true)
|
||||
}
|
||||
null -> Unit
|
||||
}
|
||||
|
|
@ -208,7 +192,7 @@ class WarningsMiddleware {
|
|||
val warningManager = store.state.globalState.warningManager ?: return emptyList()
|
||||
return warningManager.getWarnings(
|
||||
WarningMessage.Location.MainScreen,
|
||||
store.state.walletState.blockchains
|
||||
store.state.walletState.blockchains,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import androidx.recyclerview.widget.ListAdapter
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.play.core.review.ReviewManagerFactory
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
import com.tangem.tap.common.extensions.getActivity
|
||||
|
|
@ -29,7 +28,7 @@ class WarningMessagesAdapter : ListAdapter<WarningMessage, WarningMessageVH>(Dif
|
|||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WarningMessageVH {
|
||||
val binding = LayoutWarningCardActionBinding.inflate(
|
||||
LayoutInflater.from(parent.context), parent, false
|
||||
LayoutInflater.from(parent.context), parent, false,
|
||||
)
|
||||
return WarningMessageVH(binding)
|
||||
}
|
||||
|
|
@ -63,7 +62,7 @@ class WarningMessageVH(val binding: LayoutWarningCardActionBinding) : RecyclerVi
|
|||
tvMessage.text = getString(
|
||||
resId = warning.messageResId,
|
||||
default = warning.message,
|
||||
formatArgs = warning.messageFormatArg
|
||||
formatArgs = warning.messageFormatArg,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +100,7 @@ class WarningMessageVH(val binding: LayoutWarningCardActionBinding) : RecyclerVi
|
|||
}
|
||||
}
|
||||
val buttonTitle = binding.root.getString(
|
||||
warning.buttonTextId ?: R.string.how_to_got_it_button
|
||||
warning.buttonTextId ?: R.string.how_to_got_it_button,
|
||||
)
|
||||
binding.btnGotIt.setOnClickListener(buttonAction)
|
||||
binding.btnGotIt.text = buttonTitle
|
||||
|
|
@ -112,13 +111,11 @@ class WarningMessageVH(val binding: LayoutWarningCardActionBinding) : RecyclerVi
|
|||
binding.btnClose.show()
|
||||
binding.btnClose.setOnClickListener {
|
||||
Analytics.send(MainScreen.NoticeRateAppButton(AnalyticsParam.RateApp.Closed))
|
||||
Analytics.handleAnalyticsEvent(AnalyticsEventAnOld.APP_RATING_DISMISS)
|
||||
store.dispatch(GlobalAction.HideWarningMessage(warning))
|
||||
store.dispatch(WalletAction.Warnings.AppRating.RemindLater)
|
||||
}
|
||||
binding.btnCanBeBetter.setOnClickListener {
|
||||
Analytics.send(MainScreen.NoticeRateAppButton(AnalyticsParam.RateApp.Disliked))
|
||||
Analytics.handleAnalyticsEvent(AnalyticsEventAnOld.APP_RATING_NEGATIVE)
|
||||
store.dispatch(WalletAction.Warnings.AppRating.SetNeverToShow)
|
||||
store.dispatch(GlobalAction.HideWarningMessage(warning))
|
||||
store.dispatch(GlobalAction.SendEmail(RateCanBeBetterEmail()))
|
||||
|
|
@ -127,7 +124,6 @@ class WarningMessageVH(val binding: LayoutWarningCardActionBinding) : RecyclerVi
|
|||
val activity = binding.root.context.getActivity() ?: return@setOnClickListener
|
||||
|
||||
Analytics.send(MainScreen.NoticeRateAppButton(AnalyticsParam.RateApp.Liked))
|
||||
Analytics.handleAnalyticsEvent(AnalyticsEventAnOld.APP_RATING_POSITIVE)
|
||||
store.dispatch(WalletAction.Warnings.AppRating.SetNeverToShow)
|
||||
val reviewManager = ReviewManagerFactory.create(activity)
|
||||
val task = reviewManager.requestReviewFlow()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue