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 f8528755c7..837e466433 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 @@ -100,24 +100,28 @@ sealed class AnalyticsParam { override val blockchain: String, override val token: String, override val feeType: FeeType, + override val feeToken: String, ) : TxSentFrom("Send"), TxData data class Swap( override val blockchain: String, override val token: String, override val feeType: FeeType, + override val feeToken: String, ) : TxSentFrom("Swap"), TxData data class Staking( override val blockchain: String, override val token: String, override val feeType: FeeType, + override val feeToken: String, ) : TxSentFrom("Staking"), TxData data class Approve( override val blockchain: String, override val token: String, override val feeType: FeeType, + override val feeToken: String, val permissionType: String, ) : TxSentFrom("Approve"), TxData @@ -125,6 +129,7 @@ sealed class AnalyticsParam { override val blockchain: String, override val token: String, override val feeType: FeeType?, + override val feeToken: String, ) : TxSentFrom("WalletConnect"), TxData data object Sell : TxSentFrom("Sell") @@ -133,24 +138,28 @@ sealed class AnalyticsParam { override val blockchain: String, override val token: String, override val feeType: FeeType, + override val feeToken: String, ) : TxSentFrom("NFT"), TxData data class SendWithSwap( override val blockchain: String, override val token: String, override val feeType: FeeType, + override val feeToken: String, ) : TxSentFrom("Send&Swap"), TxData data class Earning( override val blockchain: String, override val token: String, override val feeType: FeeType, + override val feeToken: String, ) : TxSentFrom("Earning"), TxData } sealed interface TxData { val blockchain: String val token: String + val feeToken: String val feeType: FeeType? } @@ -274,5 +283,6 @@ sealed class AnalyticsParam { const val ENS = "ENS" const val ENS_ADDRESS = "ENS Address" const val ACCOUNT_DERIVATION_FROM = "Account Derivation (from)" + const val FEE_TOKEN = "Fee Token" } } \ No newline at end of file diff --git a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/Basic.kt b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/Basic.kt index 7a67705605..3e71b47241 100644 --- a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/Basic.kt +++ b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/Basic.kt @@ -87,6 +87,7 @@ sealed class Basic( sentFrom.feeType?.value?.let { this[AnalyticsParam.Key.FEE_TYPE] = it } + this[AnalyticsParam.Key.FEE_TOKEN] = sentFrom.feeToken } if (sentFrom is AnalyticsParam.TxSentFrom.Approve) { this[AnalyticsParam.Key.PERMISSION_TYPE] = sentFrom.permissionType diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSendTransactionUseCase.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSendTransactionUseCase.kt index 165fe556d9..4b599ee4d7 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSendTransactionUseCase.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthSendTransactionUseCase.kt @@ -90,6 +90,7 @@ internal class WcEthSendTransactionUseCase @AssistedInject constructor( blockchain = network.name, token = network.currencySymbol, feeType = null, + feeToken = network.currencySymbol, ), memoType = MemoType.Null, ), diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/analytics/CommonSendAnalyticEvents.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/analytics/CommonSendAnalyticEvents.kt index 401205f025..ca4a28c1c6 100644 --- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/analytics/CommonSendAnalyticEvents.kt +++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/analytics/CommonSendAnalyticEvents.kt @@ -52,6 +52,30 @@ sealed class CommonSendAnalyticEvents( ), ) + data class FeeSummaryScreenOpened( + val categoryName: String, + val source: CommonSendSource, + ) : CommonSendAnalyticEvents( + category = categoryName, + event = "Fee Summary Screen Opened", + params = mapOf( + SOURCE to source.analyticsName, + ), + ) + + data class FeeTokenScreenOpened( + val categoryName: String, + val source: CommonSendSource, + val availableTokens: String, + ) : CommonSendAnalyticEvents( + category = categoryName, + event = "Fee Token Screen Opened", + params = mapOf( + SOURCE to source.analyticsName, + "Available Fee" to availableTokens, + ), + ) + @Suppress("NullableToStringCall") /** Confirmation screen opened */ data class ConfirmationScreenOpened( @@ -175,6 +199,7 @@ sealed class CommonSendAnalyticEvents( companion object { const val SEND_CATEGORY = "Token / Send" + const val SWAP_CATEGORY = "Swap" const val NFT_SEND_CATEGORY = "NFT" } diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/analytics/CommonSendFeeAnalyticEvents.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/analytics/CommonSendFeeAnalyticEvents.kt index 7294b5e0b8..92e455c7a7 100644 --- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/analytics/CommonSendFeeAnalyticEvents.kt +++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/feeSelector/analytics/CommonSendFeeAnalyticEvents.kt @@ -2,6 +2,7 @@ package com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TOKEN import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.CommonSendSource @@ -19,12 +20,14 @@ sealed class CommonSendFeeAnalyticEvents( override val categoryName: String, val feeType: AnalyticsParam.FeeType, val source: CommonSendSource, + val feeToken: String, ) : CommonSendFeeAnalyticEvents( category = categoryName, event = "Fee Selected", params = mapOf( FEE_TYPE to feeType.value, SOURCE to source.analyticsName, + FEE_TOKEN to feeToken, ), ) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorComponent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorComponent.kt index dc62754b5c..7966f36ffc 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorComponent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorComponent.kt @@ -88,18 +88,27 @@ internal class DefaultFeeSelectorComponent @AssistedInject constructor( ) return when (config) { - FeeSelectorRoute.NetworkFee -> feeExtendedSelectorComponentFactory.create( - appComponentContext = appComponentContext, - params = componentParams, - ) - FeeSelectorRoute.ChooseSpeed -> feeSpeedSelectorComponentFactory.create( - appComponentContext = appComponentContext, - params = componentParams, - ) - FeeSelectorRoute.ChooseToken -> feeTokenSelectorComponentFactory.create( - appComponentContext = appComponentContext, - params = componentParams, - ) + FeeSelectorRoute.NetworkFee -> { + model.onFeeScreenOpened() + feeExtendedSelectorComponentFactory.create( + appComponentContext = appComponentContext, + params = componentParams, + ) + } + FeeSelectorRoute.ChooseSpeed -> { + model.onChooseSpeedScreenOpened() + feeSpeedSelectorComponentFactory.create( + appComponentContext = appComponentContext, + params = componentParams, + ) + } + FeeSelectorRoute.ChooseToken -> { + model.onChooseTokenScreenOpened() + feeTokenSelectorComponentFactory.create( + appComponentContext = appComponentContext, + params = componentParams, + ) + } } } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorBlockModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorBlockModel.kt index 36fdc82031..a4890d88c5 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorBlockModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorBlockModel.kt @@ -58,12 +58,6 @@ internal class FeeSelectorBlockModel @Inject constructor( } fun showFeeSelector() { - analyticsEventHandler.send( - CommonSendAnalyticEvents.FeeScreenOpened( - categoryName = params.analyticsCategoryName, - source = params.analyticsSendSource, - ), - ) analyticsEventHandler.send( CommonSendAnalyticEvents.ScreenReopened( categoryName = params.analyticsCategoryName, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt index a6efb1b2dd..0d09b709ac 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt @@ -153,13 +153,15 @@ internal class FeeSelectorLogic @AssistedInject constructor( categoryName = params.analyticsCategoryName, feeType = feeSelectorUM.toAnalyticType(), source = params.analyticsSendSource, + feeToken = feeSelectorUM.feeExtraInfo.feeCryptoCurrencyStatus.currency.symbol, ), ) val isCustomFeeEdited = feeSelectorUM.selectedFeeItem.fee.amount.value != feeSelectorUM.fees.normal.amount.value if (feeSelectorUM.selectedFeeItem is FeeItem.Custom && isCustomFeeEdited) { analyticsEventHandler.send(GasPriceInserter(categoryName = params.analyticsCategoryName)) } - if (feeSelectorUM.feeNonce is FeeNonce.Nonce) { + val nonceField = feeSelectorUM.feeNonce as? FeeNonce.Nonce + if (nonceField != null && nonceField.nonce != null) { analyticsEventHandler.send( NonceInserted( categoryName = params.analyticsCategoryName, @@ -268,12 +270,11 @@ internal class FeeSelectorLogic @AssistedInject constructor( private suspend fun getSelectedTokenStatus(tokenId: CryptoCurrency.ID): Either = either { - val feeTokenId = tokenId - if (params.feeCryptoCurrencyStatus.currency.id != feeTokenId) { + if (params.feeCryptoCurrencyStatus.currency.id != tokenId) { getSingleCryptoCurrencyStatusUseCase .invokeMultiWalletSync( userWalletId = params.userWalletId, - cryptoCurrencyId = feeTokenId, + cryptoCurrencyId = tokenId, ).getOrElse { raise(GetFeeError.DataError(IllegalStateException("No token found for id: $tokenId"))) } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt index 39db4c6f51..f4abb899d9 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt @@ -3,11 +3,13 @@ package com.tangem.features.send.v2.feeselector.model import androidx.compose.runtime.Stable import com.arkivanov.decompose.router.stack.StackNavigation import com.arkivanov.decompose.router.stack.pop +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.utils.stack import com.tangem.domain.models.currency.CryptoCurrencyStatus +import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents import com.tangem.features.send.v2.api.entity.FeeItem import com.tangem.features.send.v2.api.entity.FeeSelectorUM import com.tangem.features.send.v2.api.params.FeeSelectorParams @@ -23,6 +25,7 @@ internal class FeeSelectorModel @Inject constructor( paramsContainer: ParamsContainer, feeSelectorLogicFactory: FeeSelectorLogic.Factory, override val dispatchers: CoroutineDispatcherProvider, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model(), FeeSelectorIntents { private val params = paramsContainer.require() @@ -78,6 +81,42 @@ internal class FeeSelectorModel @Inject constructor( } } + fun onFeeScreenOpened() { + analyticsEventHandler.send( + CommonSendAnalyticEvents.FeeSummaryScreenOpened( + categoryName = params.analyticsCategoryName, + source = params.analyticsSendSource, + ), + ) + } + + fun onChooseSpeedScreenOpened() { + analyticsEventHandler.send( + CommonSendAnalyticEvents.FeeScreenOpened( + categoryName = params.analyticsCategoryName, + source = params.analyticsSendSource, + ), + ) + } + + fun onChooseTokenScreenOpened() { + analyticsEventHandler.send( + CommonSendAnalyticEvents.FeeTokenScreenOpened( + categoryName = params.analyticsCategoryName, + source = params.analyticsSendSource, + availableTokens = getAvailableTokensString(), + ), + ) + } + + private fun getAvailableTokensString(): String { + return (uiState.value as? FeeSelectorUM.Content) + ?.feeExtraInfo + ?.availableFeeCurrencies + ?.joinToString(", ") { it.currency.symbol } + .orEmpty() + } + private fun contentState(): FeeSelectorUM.Content { val currentState = uiState.value require(currentState is FeeSelectorUM.Content) { "Current state must be FeeSelectorUM.Content" } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt index 7deca5c48b..6b40402b66 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt @@ -65,7 +65,7 @@ internal fun FeeSelectorModalBottomSheet( .fillMaxWidth() .padding(horizontal = 16.dp), enabled = state.isPrimaryButtonEnabled, - text = stringResourceSafe(R.string.common_confirm), + text = stringResourceSafe(R.string.common_apply), onClick = feeSelectorIntents::onDoneClick, ) } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticEvents.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticEvents.kt index c732a34b77..e837d589cf 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticEvents.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticEvents.kt @@ -27,6 +27,7 @@ internal sealed class SendAnalyticEvents( val blockchain: String, val isNonceNotEmpty: Boolean, private val ensStatus: AnalyticsParam.EmptyFull, + private val feeToken: String, val derivationIndex: Int?, ) : SendAnalyticEvents( event = "Transaction Sent Screen Opened", diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticHelper.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticHelper.kt index e65f75d699..5626f5a93c 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticHelper.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/analytics/SendAnalyticHelper.kt @@ -18,10 +18,16 @@ internal class SendAnalyticHelper @Inject constructor( private val analyticsEventHandler: AnalyticsEventHandler, ) { - fun sendSuccessAnalytics(cryptoCurrency: CryptoCurrency, sendUM: SendUM, account: Account.CryptoPortfolio?) { + fun sendSuccessAnalytics( + cryptoCurrency: CryptoCurrency, + sendUM: SendUM, + feeToken: CryptoCurrency, + account: Account.CryptoPortfolio?, + ) { val destinationUM = sendUM.destinationUM as? DestinationUM.Content val feeSelectorUM = sendUM.feeSelectorUM as? FeeSelectorUM.Content ?: return val feeType = feeSelectorUM.toAnalyticType() + val feeTokenSymbol = feeToken.symbol val isNotMainAccount = account != null && !account.isMainAccount val derivationIndex = if (isNotMainAccount) account.derivationIndex.value else null analyticsEventHandler.send( @@ -32,6 +38,7 @@ internal class SendAnalyticHelper @Inject constructor( isNonceNotEmpty = feeSelectorUM.feeNonce is FeeNonce.Nonce, ensStatus = getEnsStatus(sendUM), derivationIndex = derivationIndex, + feeToken = feeTokenSymbol, ), ) analyticsEventHandler.send( @@ -40,6 +47,7 @@ internal class SendAnalyticHelper @Inject constructor( blockchain = cryptoCurrency.network.name, token = cryptoCurrency.symbol, feeType = feeType, + feeToken = feeTokenSymbol, ), memoType = getSendTransactionMemoType(destinationUM?.memoTextField), ), diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt index 45bea2d435..31b351c7d3 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt @@ -390,6 +390,7 @@ internal class SendConfirmModel @Inject constructor( private suspend fun sendTransaction(txData: TransactionData.Uncompiled) { val feeExtended = feeUMV2?.feeExtraInfo?.transactionFeeExtended + val feeToken = getCurrencyStatusForFeePayment().currency val isFeeInTokenCurrency = feeExtended?.transactionFee?.normal is Fee.Ethereum.TokenCurrency @@ -433,6 +434,7 @@ internal class SendConfirmModel @Inject constructor( cryptoCurrency = cryptoCurrency, sendUM = uiState.value, account = params.accountFlow.value, + feeToken = feeToken, ) params.callback.onResult(uiState.value) params.onSendTransaction() diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt index d6b190dd5d..2f0b7ffd83 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt @@ -5,6 +5,7 @@ import arrow.core.Either import arrow.core.getOrElse import arrow.core.left import com.tangem.blockchain.common.TransactionData +import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.navigationButtons.NavigationUM @@ -28,6 +29,7 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.BlockchainErrorInfo import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.account.Account +import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.isMultiCurrency @@ -72,6 +74,7 @@ import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject import kotlin.properties.Delegates +import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned internal interface SendComponentCallback : SendAmountComponent.ModelCallback, @@ -452,6 +455,17 @@ internal class SendModel @Inject constructor( } } + fun getSelectedFeeToken(): CryptoCurrency { + val feeUMV2 = uiState.value.feeSelectorUM as? FeeSelectorUMRedesigned.Content + val feeExtended = feeUMV2?.feeExtraInfo?.transactionFeeExtended + val isFeeInTokenCurrency = feeExtended?.transactionFee?.normal is Fee.Ethereum.TokenCurrency + return if (isFeeInTokenCurrency) { + feeUMV2.feeExtraInfo.feeCryptoCurrencyStatus.currency + } else { + feeCryptoCurrencyStatusFlow.value.currency + } + } + private suspend fun getFeeCurrencyStatus( cryptoCurrencyStatus: CryptoCurrencyStatus, isMultiCurrency: Boolean, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/analytics/NFTSendAnalyticHelper.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/analytics/NFTSendAnalyticHelper.kt index bab316c20f..b8c6f2e66c 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/analytics/NFTSendAnalyticHelper.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/analytics/NFTSendAnalyticHelper.kt @@ -36,6 +36,7 @@ internal class NFTSendAnalyticHelper @Inject constructor( blockchain = cryptoCurrency.network.name, token = NFT_SEND_CATEGORY, // should send "NFT" in token param feeType = feeType, + feeToken = cryptoCurrency.symbol, ), memoType = getSendTransactionMemoType(destinationUM?.memoTextField), ), diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt index 5b97de21cf..d02f06b8ba 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt @@ -72,6 +72,7 @@ internal class StakingAnalyticSender( token = tokenCryptoCurrency.symbol, feeType = AnalyticsParam.FeeType.Normal, permissionType = ApproveType.LIMITED.name, + feeToken = tokenCryptoCurrency.symbol, ), memoType = Basic.TransactionSent.MemoType.Null, ), @@ -88,6 +89,7 @@ internal class StakingAnalyticSender( blockchain = cryptoCurrencyStatus.currency.network.name, token = value.cryptoCurrencySymbol, feeType = AnalyticsParam.FeeType.Normal, + feeToken = cryptoCurrencyStatus.currency.symbol, ), memoType = Basic.TransactionSent.MemoType.Null, ), diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt index d2d3497c2f..6f6b6b2c2e 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt @@ -3,6 +3,7 @@ package com.tangem.features.swap.v2.impl.sendviaswap.confirm.model import arrow.core.Either import arrow.core.getOrElse import arrow.core.left +import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.common.routing.AppRouter import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer @@ -457,12 +458,24 @@ internal class SendWithSwapConfirmModel @Inject constructor( blockchain = fromCurrency.network.name, token = fromCurrency.symbol, feeType = feeType, + feeToken = getSelectedFeeToken().symbol, ), memoType = Basic.TransactionSent.MemoType.Null, ), ) } + private fun getSelectedFeeToken(): CryptoCurrency { + val feeUMV2 = uiState.value.feeSelectorUM as? FeeSelectorUMRedesigned.Content + val feeExtended = feeUMV2?.feeExtraInfo?.transactionFeeExtended + val isFeeInTokenCurrency = feeExtended?.transactionFee?.normal is Fee.Ethereum.TokenCurrency + return if (isFeeInTokenCurrency) { + feeUMV2.feeExtraInfo.feeCryptoCurrencyStatus.currency + } else { + primaryCurrencyStatus.currency + } + } + private fun configConfirmNavigation() { combine( flow = uiState, diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt index 629d37898d..8b366f9bd8 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt @@ -2,6 +2,7 @@ package com.tangem.features.swap.v2.impl.sendviaswap.model import arrow.core.Either import arrow.core.getOrElse +import com.tangem.blockchain.common.transaction.Fee import com.tangem.common.ui.navigationButtons.NavigationUM import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model @@ -43,6 +44,7 @@ import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject import kotlin.properties.Delegates +import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned @Suppress("LongParameterList") @ModelScoped @@ -160,6 +162,17 @@ internal class SendWithSwapModel @Inject constructor( } } + fun getSelectedFeeToken(): CryptoCurrency { + val feeUMV2 = uiState.value.feeSelectorUM as? FeeSelectorUMRedesigned.Content + val feeExtended = feeUMV2?.feeExtraInfo?.transactionFeeExtended + val isFeeInTokenCurrency = feeExtended?.transactionFee?.normal is Fee.Ethereum.TokenCurrency + return if (isFeeInTokenCurrency) { + feeUMV2.feeExtraInfo.feeCryptoCurrencyStatus.currency + } else { + primaryFeePaidCurrencyStatusFlow.value.currency + } + } + private fun initUserWallet() { getUserWalletUseCase(params.userWalletId).fold( ifRight = { wallet -> diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt index 3cde40dc0c..cb01f7cde4 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt @@ -88,7 +88,7 @@ internal class DefaultSwapComponent @AssistedInject constructor( sendingCryptoCurrencyStatus = config.sendingCurrencyStatus, feeCryptoCurrencyStatus = config.feeCurrencyStatus, analyticsParams = SwapFeeSelectorBlockComponent.AnalyticsParams( - analyticsCategoryName = CommonSendAnalyticEvents.SEND_CATEGORY, + analyticsCategoryName = CommonSendAnalyticEvents.SWAP_CATEGORY, analyticsSendSource = CommonSendAnalyticEvents.CommonSendSource.Swap, ), ), diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt index fe69da29ce..1e0c855abc 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt @@ -4,6 +4,7 @@ import com.tangem.common.ui.bottomsheet.permission.state.ApproveType import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.core.analytics.models.AnalyticsParam.Key.ERROR_CODE import com.tangem.core.analytics.models.AnalyticsParam.Key.ERROR_MESSAGE +import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TOKEN import com.tangem.core.analytics.models.AnalyticsParam.Key.PROVIDER import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_TOKEN import com.tangem.core.analytics.models.AnalyticsParam.Key.SEND_TOKEN @@ -84,6 +85,7 @@ sealed class SwapEvents( val receiveBlockchain: String, val sendToken: String, val receiveToken: String, + val feeToken: String, val fromDerivationIndex: Int?, val toDerivationIndex: Int?, ) : SwapEvents( @@ -96,6 +98,7 @@ sealed class SwapEvents( "Send Blockchain" to sendBlockchain, "Receive Blockchain" to receiveBlockchain, "Account Derivation From or To (optional)" to "$fromDerivationIndex, $toDerivationIndex", + FEE_TOKEN to feeToken, ), ), AppsFlyerIncludedEvent diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt index 9a4b5d8027..78baa4057b 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt @@ -114,7 +114,6 @@ import java.text.DecimalFormat import java.text.NumberFormat import java.util.Locale import javax.inject.Inject -import kotlin.collections.filter typealias SuccessLoadedSwapData = Map @@ -1098,6 +1097,7 @@ internal class SwapModel @Inject constructor( receiveBlockchain = toCurrency.network.name, sendToken = fromCurrency.symbol, receiveToken = toCurrency.symbol, + feeToken = getFeeToken().symbol, fromDerivationIndex = fromDerivationIndex, toDerivationIndex = toDerivationIndex, ), @@ -1713,6 +1713,7 @@ internal class SwapModel @Inject constructor( blockchain = fromToken.network.name, token = fromToken.symbol, feeType = AnalyticsParam.FeeType.fromString(feeType.getNameForAnalytics()), + feeToken = getFeeToken().symbol, ) analyticsEventHandler.send( Basic.TransactionSent( @@ -1722,12 +1723,26 @@ internal class SwapModel @Inject constructor( ) } + private fun getFeeToken(): CryptoCurrency { + val fromToken = requireNotNull(dataState.fromCryptoCurrency) { + "fromCryptoCurrency should not be null" + } + return when (val fee = getSelectedFee()) { + is TxFee.FeeComponent -> fee.selectedToken?.currency ?: fromToken.currency + is TxFee.Legacy, + null, + -> fromToken.currency + } + } + private fun sendApproveSuccessEvent(fromToken: CryptoCurrency, feeType: FeeType, approveType: SwapApproveType) { + val feeToken = getFeeToken().symbol val event = AnalyticsParam.TxSentFrom.Approve( blockchain = fromToken.network.name, token = fromToken.symbol, feeType = AnalyticsParam.FeeType.fromString(feeType.getNameForAnalytics()), permissionType = approveType.getNameForAnalytics(), + feeToken = feeToken, ) analyticsEventHandler.send( Basic.TransactionSent( 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 dd17066a2d..88123f909a 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 @@ -162,6 +162,7 @@ internal class YieldSupplyApproveModel @Inject constructor( blockchain = cryptoCurrency.network.name, token = cryptoCurrency.symbol, feeType = AnalyticsParam.FeeType.Normal, + feeToken = feeCryptoCurrencyStatus.currency.symbol, ) analyticsEventHandler.send( Basic.TransactionSent( 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 aae5996e1a..c5fda7511e 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 @@ -266,6 +266,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor( blockchain = cryptoCurrency.network.name, token = cryptoCurrency.symbol, feeType = AnalyticsParam.FeeType.Normal, + feeToken = feeCryptoCurrencyStatusFlow.value.currency.symbol, ) analytics.send( YieldSupplyAnalytics.FundsEarned( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt index e79191dc86..fc7f22db11 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt @@ -192,6 +192,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor( blockchain = cryptoCurrency.network.name, token = cryptoCurrency.symbol, feeType = AnalyticsParam.FeeType.Normal, + feeToken = feeCryptoCurrencyStatus.currency.symbol, ) analytics.send( Basic.TransactionSent(