Updated on 2026-08-14
This commit is contained in:
parent
b08892762c
commit
f095f3a508
24 changed files with 184 additions and 26 deletions
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ internal class WcEthSendTransactionUseCase @AssistedInject constructor(
|
|||
blockchain = network.name,
|
||||
token = network.currencySymbol,
|
||||
feeType = null,
|
||||
feeToken = network.currencySymbol,
|
||||
),
|
||||
memoType = MemoType.Null,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -88,20 +88,29 @@ internal class DefaultFeeSelectorComponent @AssistedInject constructor(
|
|||
)
|
||||
|
||||
return when (config) {
|
||||
FeeSelectorRoute.NetworkFee -> feeExtendedSelectorComponentFactory.create(
|
||||
FeeSelectorRoute.NetworkFee -> {
|
||||
model.onFeeScreenOpened()
|
||||
feeExtendedSelectorComponentFactory.create(
|
||||
appComponentContext = appComponentContext,
|
||||
params = componentParams,
|
||||
)
|
||||
FeeSelectorRoute.ChooseSpeed -> feeSpeedSelectorComponentFactory.create(
|
||||
}
|
||||
FeeSelectorRoute.ChooseSpeed -> {
|
||||
model.onChooseSpeedScreenOpened()
|
||||
feeSpeedSelectorComponentFactory.create(
|
||||
appComponentContext = appComponentContext,
|
||||
params = componentParams,
|
||||
)
|
||||
FeeSelectorRoute.ChooseToken -> feeTokenSelectorComponentFactory.create(
|
||||
}
|
||||
FeeSelectorRoute.ChooseToken -> {
|
||||
model.onChooseTokenScreenOpened()
|
||||
feeTokenSelectorComponentFactory.create(
|
||||
appComponentContext = appComponentContext,
|
||||
params = componentParams,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : FeeSelectorComponent.Factory {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<GetFeeError, CryptoCurrencyStatus> =
|
||||
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")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<FeeSelectorParams.FeeSelectorDetailsParams>()
|
||||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 ->
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<SwapProvider, SwapState.QuotesLoadedState>
|
||||
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue