From 5a4b35a90e9983dbf9be923df9985fa792bf3e50 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 31 Oct 2025 10:06:00 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../core/analytics/models/AnalyticsParam.kt | 6 +++++ .../analytics/TokenScreenAnalyticsEvent.kt | 3 ++- .../api/analytics/YieldSupplyAnalytics.kt | 26 ++++++++++++++----- .../active/model/YieldSupplyActiveModel.kt | 11 ++++++-- .../YieldSupplyActiveFeeContentTransformer.kt | 12 +++++++++ .../approve/model/YieldSupplyApproveModel.kt | 6 +++++ .../YieldSupplyStartEarningEntryModel.kt | 5 +++- .../model/YieldSupplyStartEarningModel.kt | 15 +++++++++++ 8 files changed, 74 insertions(+), 10 deletions(-) diff --git a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt index 5879b1920e..f4690823fb 100644 --- a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt +++ b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt @@ -131,6 +131,12 @@ sealed class AnalyticsParam { override val token: String, override val feeType: FeeType, ) : TxSentFrom("Send&Swap"), TxData + + data class Earning( + override val blockchain: String, + override val token: String, + override val feeType: FeeType, + ) : TxSentFrom("Earning"), TxData } sealed interface TxData { diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt index 3365ce6d87..5c0c30da0d 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt @@ -184,6 +184,7 @@ sealed class TokenScreenAnalyticsEvent( private const val LOADING = "Loading" private const val ASSET_REQUIREMENT = "AssetRequirement" private const val TRUSTLINE_REQUIREMENT = "TrustlineRequirement" + private const val APPROVAL_REQUIRED = "Approval Required" @Suppress("CyclomaticComplexMethod") fun ScenarioUnavailabilityReason.toReasonAnalyticsText(): String { @@ -192,8 +193,8 @@ sealed class TokenScreenAnalyticsEvent( is ScenarioUnavailabilityReason.NotExchangeable, is ScenarioUnavailabilityReason.NotSupportedBySellService, is ScenarioUnavailabilityReason.StakingUnavailable, - ScenarioUnavailabilityReason.YieldSupplyApprovalRequired, -> UNAVAILABLE + is ScenarioUnavailabilityReason.YieldSupplyApprovalRequired -> APPROVAL_REQUIRED ScenarioUnavailabilityReason.UnassociatedAsset -> ASSET_REQUIREMENT ScenarioUnavailabilityReason.TrustlineRequired -> TRUSTLINE_REQUIREMENT is ScenarioUnavailabilityReason.EmptyBalance -> EMPTY diff --git a/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt b/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt index 596a7bb892..9b09110c29 100644 --- a/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt +++ b/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt @@ -77,12 +77,26 @@ sealed class YieldSupplyAnalytics( ), ) - data object ButtonFeePolicy : YieldSupplyAnalytics( + data class ButtonFeePolicy( + val token: String, + val blockchain: String, + ) : YieldSupplyAnalytics( event = "Button - Fee Policy", + params = mapOf( + TOKEN_PARAM to token, + BLOCKCHAIN to blockchain, + ), ) - data object EarnInProgressScreen : YieldSupplyAnalytics( + data class EarnInProgressScreen( + val token: String, + val blockchain: String, + ) : YieldSupplyAnalytics( event = "Earn In Progress Screen", + params = mapOf( + TOKEN_PARAM to token, + BLOCKCHAIN to blockchain, + ), ) data object FundsEarned : YieldSupplyAnalytics( @@ -162,10 +176,10 @@ sealed class YieldSupplyAnalytics( val errorDescription: String?, ) : YieldSupplyAnalytics( event = "Earn Errors", - params = buildMap { - ACTION to action - ERROR_DESCRIPTION to errorDescription.orEmpty() - }, + params = mapOf( + ACTION to action.value, + ERROR_DESCRIPTION to errorDescription.orEmpty(), + ), ) data object ApyChartViewed : YieldSupplyAnalytics( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt index 8d8bd96071..070ec52cb7 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt @@ -45,7 +45,7 @@ import javax.inject.Inject internal class YieldSupplyActiveModel @Inject constructor( paramsContainer: ParamsContainer, override val dispatchers: CoroutineDispatcherProvider, - analyticsHandler: AnalyticsEventHandler, + private val analyticsHandler: AnalyticsEventHandler, private val yieldSupplyGetProtocolBalanceUseCase: YieldSupplyGetProtocolBalanceUseCase, private val yieldSupplyGetTokenStatusUseCase: YieldSupplyGetTokenStatusUseCase, private val yieldSupplyMinAmountUseCase: YieldSupplyMinAmountUseCase, @@ -82,7 +82,7 @@ internal class YieldSupplyActiveModel @Inject constructor( init { analyticsHandler.send( - YieldSupplyAnalytics.EarningScreenInfoOpened( + YieldSupplyAnalytics.EarnInProgressScreen( token = cryptoCurrency.symbol, blockchain = cryptoCurrency.network.name, ), @@ -189,6 +189,12 @@ internal class YieldSupplyActiveModel @Inject constructor( return if (notDepositedAmount > BigDecimal.ZERO) { val formattedAmount = notDepositedAmount.format { crypto(symbol = "", decimals = cryptoCurrencyStatus.currency.decimals) } + analyticsHandler.send( + YieldSupplyAnalytics.NoticeAmountNotDeposited( + token = cryptoCurrency.symbol, + blockchain = cryptoCurrency.network.name, + ), + ) NotificationUM.Warning.YieldSupplyNotAllAmountSupplied( formattedAmount = formattedAmount, symbol = cryptoCurrency.symbol, @@ -243,6 +249,7 @@ internal class YieldSupplyActiveModel @Inject constructor( appCurrency = appCurrency, feeValue = currentFee, maxNetworkFee = maxFee, + analyticsHandler = analyticsHandler, ), ) } else { diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt index bcd2e22076..cc7f66e762 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt @@ -1,5 +1,6 @@ package com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.wrappedList @@ -9,6 +10,7 @@ import com.tangem.core.ui.format.bigdecimal.format import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus +import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics import com.tangem.features.yield.supply.impl.R import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM import com.tangem.utils.transformer.Transformer @@ -22,6 +24,7 @@ internal class YieldSupplyActiveFeeContentTransformer( private val appCurrency: AppCurrency, private val feeValue: BigDecimal, private val maxNetworkFee: BigDecimal, + private val analyticsHandler: AnalyticsEventHandler, ) : Transformer { override fun transform(prevState: YieldSupplyActiveContentUM): YieldSupplyActiveContentUM { @@ -48,6 +51,15 @@ internal class YieldSupplyActiveFeeContentTransformer( val isHighFee = feeValue > maxNetworkFee + if (isHighFee) { + analyticsHandler.send( + YieldSupplyAnalytics.NoticeHighNetworkFee( + token = cryptoCurrency.symbol, + blockchain = cryptoCurrency.network.name, + ), + ) + } + return prevState.copy( currentFee = stringReference(tokenFiatFeeValueText), feeDescription = feeNoteValue, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt index 0be362037a..5ccf1e1d6f 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt @@ -132,6 +132,12 @@ internal class YieldSupplyApproveModel @Inject constructor( ifLeft = { error -> Timber.e(error.toString()) uiState.update(YieldSupplyTransactionReadyTransformer) + analyticsEventHandler.send( + YieldSupplyAnalytics.EarnErrors( + action = YieldSupplyAnalytics.Action.Approve, + errorDescription = error.getAnalyticsDescription(), + ), + ) yieldSupplyAlertFactory.getSendTransactionErrorState( error = error, popBack = params.callback::onBackClick, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt index d6de1559ac..2037750020 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt @@ -59,7 +59,10 @@ internal class YieldSupplyStartEarningEntryModel @Inject constructor( override fun onFeePolicyClick() { analyticsEventHandler.send( - YieldSupplyAnalytics.ButtonFeePolicy, + YieldSupplyAnalytics.ButtonFeePolicy( + token = params.cryptoCurrency.symbol, + blockchain = params.cryptoCurrency.network.name, + ), ) router.push(YieldSupplyStartEarningRoute.FeePolicy) } diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt index fdb9493169..09949a382e 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt @@ -3,6 +3,8 @@ package com.tangem.features.yield.supply.impl.subcomponents.startearning.model import arrow.core.getOrElse import com.tangem.blockchain.common.TransactionSender import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.Basic import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -252,7 +254,20 @@ internal class YieldSupplyStartEarningModel @Inject constructor( }, ifRight = { yieldSupplyRepository.saveTokenProtocolStatus(cryptoCurrency, YieldSupplyEnterStatus.Enter) + val event = AnalyticsParam.TxSentFrom.Earning( + blockchain = cryptoCurrency.network.name, + token = cryptoCurrency.symbol, + feeType = AnalyticsParam.FeeType.Normal, + ) analytics.send(YieldSupplyAnalytics.FundsEarned) + yieldSupplyFeeUM.transactionDataList.forEach { + analytics.send( + Basic.TransactionSent( + sentFrom = event, + memoType = Basic.TransactionSent.MemoType.Null, + ), + ) + } val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value if (address != null) {