Updated on 2026-08-14

This commit is contained in:
Tangem 2025-01-27 13:22:03 +03:00
parent 6cdd24067e
commit ae0eb0aff2
11 changed files with 41 additions and 10 deletions

View file

@ -13,7 +13,6 @@ sealed class Onboarding(
class Started : Onboarding("Onboarding", "Onboarding Started")
class Finished : Onboarding("Onboarding", "Onboarding Finished")
data object OfflineAttestationFailed : Onboarding(category = "Onboarding", event = "Offline Attestation Failed")
sealed class CreateWallet(
event: String,

View file

@ -19,11 +19,13 @@ internal class DefaultScanCardProcessor(
override suspend fun scan(
cardId: String?,
allowsRequestAccessCodeFromRepository: Boolean,
analyticsSource: AnalyticsParam.ScreensSources,
): CompletionResult<ScanResponse> {
return if (isNewCardScanningEnabled) {
UseCaseScanProcessor.scan(cardId, allowsRequestAccessCodeFromRepository)
} else {
legacyScanProcessor.scan(
analyticsSource = analyticsSource,
cardId = cardId,
allowsRequestAccessCodeFromRepository = allowsRequestAccessCodeFromRepository,
)

View file

@ -59,13 +59,14 @@ internal class LegacyScanProcessor @Inject constructor(
suspend fun scan(
cardId: String? = null,
allowsRequestAccessCodeFromRepository: Boolean = false,
analyticsSource: AnalyticsParam.ScreensSources,
): CompletionResult<ScanResponse> {
return tangemSdkManager.scanProduct(
cardId = cardId,
allowsRequestAccessCodeFromRepository = allowsRequestAccessCodeFromRepository,
)
.doOnFailure { error ->
onScanFailure(error = error, onFailure = {}, onCancel = {})
onScanFailure(analyticsSource = analyticsSource, error = error, onFailure = {}, onCancel = {})
}
}
@ -92,6 +93,7 @@ internal class LegacyScanProcessor @Inject constructor(
result
.doOnFailure { error ->
onScanFailure(
analyticsSource = analyticsSource,
error = error,
onFailure = onFailure,
onCancel = {
@ -162,12 +164,17 @@ internal class LegacyScanProcessor @Inject constructor(
}
private suspend inline fun onScanFailure(
analyticsSource: AnalyticsParam.ScreensSources,
error: TangemError,
crossinline onFailure: suspend (TangemError) -> Unit,
crossinline onCancel: () -> Unit,
) {
if (error is TangemSdkError.CardVerificationFailed) {
analyticsEventHandler.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
analyticsEventHandler.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(
analyticsSource,
),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: R.string.common_unknown_error

View file

@ -66,7 +66,10 @@ internal class CardSettingsViewModel @Inject constructor(
)
private fun scanCard() = viewModelScope.launch {
scanCardProcessor.scan(allowsRequestAccessCodeFromRepository = true)
scanCardProcessor.scan(
analyticsSource = com.tangem.core.analytics.models.AnalyticsParam.ScreensSources.Settings,
allowsRequestAccessCodeFromRepository = true,
)
.doOnSuccess { scanResponse ->
val scannedUserWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build()
if (userWalletId == scannedUserWalletId || scannedUserWalletId == null) {

View file

@ -7,6 +7,7 @@ import com.tangem.common.extensions.guard
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.utils.popTo
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
import com.tangem.core.ui.R
import com.tangem.core.ui.extensions.resourceReference
@ -356,7 +357,9 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
private fun showCardVerificationFailedDialog(error: TangemError) {
if (error is TangemSdkError.CardVerificationFailed) {
Analytics.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
Analytics.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(AnalyticsParam.ScreensSources.Backup),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: R.string.common_unknown_error

View file

@ -476,7 +476,11 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
when (val error = result.error) {
is TangemSdkError.CardVerificationFailed -> {
Analytics.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
Analytics.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(
com.tangem.core.analytics.models.AnalyticsParam.ScreensSources.Backup,
),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: com.tangem.core.ui.R.string.common_unknown_error

View file

@ -79,6 +79,8 @@ sealed class AnalyticsParam {
data object Buy : ScreensSources("Buy")
data object Swap : ScreensSources("Swap")
data object Sell : ScreensSources("Sell")
data object Backup : ScreensSources("Backup")
data object Onboarding : ScreensSources("Onboarding")
}
sealed class TxSentFrom(val value: String) {

View file

@ -1,6 +1,7 @@
package com.tangem.core.analytics.models.event
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
sealed class OnboardingAnalyticsEvent(
category: String,
@ -11,8 +12,13 @@ sealed class OnboardingAnalyticsEvent(
sealed class Onboarding(
event: String,
params: Map<String, String> = mapOf(),
) : OnboardingAnalyticsEvent(category = "Onboarding", event = event, params = params) {
) : OnboardingAnalyticsEvent(category = "Error", event = event, params = params) {
data object OfflineAttestationFailed : Onboarding(event = "Offline Attestation Failed")
data class OfflineAttestationFailed(
val source: AnalyticsParam.ScreensSources,
) : Onboarding(
event = "Offline Attestation Failed",
params = mapOf(AnalyticsParam.SOURCE to source.value),
)
}
}

View file

@ -10,6 +10,7 @@ interface ScanCardProcessor {
suspend fun scan(
cardId: String? = null,
allowsRequestAccessCodeFromRepository: Boolean = false,
analyticsSource: AnalyticsParam.ScreensSources,
): CompletionResult<ScanResponse>
suspend fun scan(

View file

@ -5,6 +5,7 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
@ -246,7 +247,9 @@ class MultiWalletBackupModel @Inject constructor(
}
private fun showCardVerificationFailedDialog(error: TangemSdkError.CardVerificationFailed) {
analyticsEventHandler.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
analyticsEventHandler.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(AnalyticsParam.ScreensSources.Backup),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: com.tangem.core.ui.R.string.common_unknown_error

View file

@ -5,6 +5,7 @@ import arrow.core.raise.either
import arrow.core.raise.ensure
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.wallets.builder.UserWalletBuilder
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
@ -22,7 +23,7 @@ internal class ScanCardToUnlockWalletClickHandler @Inject constructor(
suspend operator fun invoke(walletId: UserWalletId): Either<ScanCardToUnlockWalletError, Unit> {
return either {
when (val result = scanCardProcessor.scan()) {
when (val result = scanCardProcessor.scan(analyticsSource = AnalyticsParam.ScreensSources.Main)) {
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.UserCancelled) {
scanFailsCounter++