diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt index 3eb907948a..d771aa4ecb 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt @@ -26,6 +26,7 @@ data class SavedSwapTransactionListModelInner( val transactions: List, ) +// TODO refactor to use separate models to store data class SavedSwapTransactionModel( val txId: String, val timestamp: Long, diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapPairLeast.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapPairLeast.kt index 4314fe1c81..9e82c4a39f 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapPairLeast.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapPairLeast.kt @@ -26,6 +26,9 @@ data class CryptoCurrencySwapInfo( * @property providerId provider id * @property rateTypes supported rate types * @property isRecommended flag that indicates if this provider is recommended + * + * Uses to store transaction data in datastore, when extends - should always add default value + * to support backward compatibility */ data class SwapProvider( val providerId: String, @@ -35,7 +38,7 @@ data class SwapProvider( val imageLarge: String, val termsOfUse: String?, val privacyPolicy: String?, - val isRecommended: Boolean, + val isRecommended: Boolean = false, ) enum class ExchangeProviderType(val providerName: String) { diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index eb1639b60d..df53e5e0e7 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -896,8 +896,9 @@ internal class SwapInteractorImpl @Inject constructor( txExternalUrl: String? = null, txExternalId: String? = null, ) { + val selectedWallet = getSelectedWallet() ?: return swapTransactionRepository.storeTransaction( - userWalletId = UserWalletId(userWalletManager.getWalletId()), + userWalletId = selectedWallet.walletId, fromCryptoCurrency = currencyToSend.currency, toCryptoCurrency = currencyToGet.currency, transaction = SavedSwapTransactionModel( diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt index 2fd8fa08ac..59fd338f5a 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt @@ -6,6 +6,7 @@ import com.tangem.feature.swap.domain.models.ui.FeeType import com.tangem.feature.swap.models.ApproveType private const val SWAP_CATEGORY = "Swap" +private const val PROMO_CATEGORY = "Promo" sealed class SwapEvents( event: String, @@ -17,7 +18,7 @@ sealed class SwapEvents( params = mapOf("Token" to token), ) - object SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked") + data object SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked") data class ChooseTokenScreenOpened(val availableTokens: Boolean) : SwapEvents( event = "Choose Token Screen Opened", @@ -37,7 +38,7 @@ sealed class SwapEvents( params = mapOf("Send Token" to sendToken, "Receive Token" to receiveToken), ) - object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission") + data object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission") data class ButtonPermissionApproveClicked( val sendToken: String, @@ -52,9 +53,9 @@ sealed class SwapEvents( ), ) - object ButtonPermissionCancelClicked : SwapEvents(event = "Button - Permission Cancel") + data object ButtonPermissionCancelClicked : SwapEvents(event = "Button - Permission Cancel") - object ButtonSwipeClicked : SwapEvents(event = "Button - Swipe") + data object ButtonSwipeClicked : SwapEvents(event = "Button - Swipe") data class SwapInProgressScreen( val provider: SwapProvider, @@ -71,7 +72,7 @@ sealed class SwapEvents( ), ) - object ProviderClicked : SwapEvents("Provider Clicked") + data object ProviderClicked : SwapEvents("Provider Clicked") data class ProviderChosen(val provider: SwapProvider) : SwapEvents( event = "Provider Chosen", @@ -88,7 +89,7 @@ sealed class SwapEvents( params = mapOf("Token" to token), ) - object NoticeNoAvailableTokensToSwap : SwapEvents("Notice - No Available Tokens To Swap") + data object NoticeNoAvailableTokensToSwap : SwapEvents("Notice - No Available Tokens To Swap") data class NoticeNotEnoughFee(val token: String, val blockchain: String) : SwapEvents( event = "Notice - Not Enough Fee", @@ -110,4 +111,20 @@ sealed class SwapEvents( "Error code" to errorCode.toString(), ), ) + + // region Promo activity + data class ChangellyActivity( + val promoState: PromoState, + ) : AnalyticsEvent( + category = PROMO_CATEGORY, + event = "Changelly Activity", + params = mapOf( + "State" to promoState.name, + ), + ) { + sealed class PromoState(val name: String) { + data object Native : PromoState("Native") + data object Recommended : PromoState("Recommended") + } + } } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt index ee09df73c4..58731f8a00 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt @@ -430,8 +430,11 @@ internal class SwapViewModel @Inject constructor( if (currentSelected != null && consideredProviders.keys.contains(currentSelected)) { currentSelected } else { - findBestQuoteProvider(consideredProviders.getLastLoadedSuccessStates()) - ?: consideredProviders.keys.first() + val successLoadedData = consideredProviders.getLastLoadedSuccessStates() + val recommendedProvider = successLoadedData.keys.firstOrNull { it.isRecommended } + val bestQuotesProvider = findBestQuoteProvider(successLoadedData) + triggerPromoProviderEvent(recommendedProvider, bestQuotesProvider) + recommendedProvider ?: bestQuotesProvider ?: consideredProviders.keys.first() } } else { state.keys.first() @@ -1169,11 +1172,28 @@ internal class SwapViewModel @Inject constructor( ) } + private fun triggerPromoProviderEvent(recommendedProvider: SwapProvider?, bestQuotesProvider: SwapProvider?) { + // for now send event only for changelly + if (recommendedProvider == null || + recommendedProvider.providerId != CHANGELLY_PROVIDER_ID || + bestQuotesProvider == null + ) { + return + } + val event = if (recommendedProvider.providerId == bestQuotesProvider.providerId) { + SwapEvents.ChangellyActivity(SwapEvents.ChangellyActivity.PromoState.Native) + } else { + SwapEvents.ChangellyActivity(SwapEvents.ChangellyActivity.PromoState.Recommended) + } + analyticsEventHandler.send(event = event) + } + private companion object { const val loggingTag = "SwapViewModel" const val INITIAL_AMOUNT = "" const val UPDATE_DELAY = 10000L const val DEBOUNCE_AMOUNT_DELAY = 1000L const val UPDATE_BALANCE_DELAY_MILLIS = 11000L + const val CHANGELLY_PROVIDER_ID = "changelly" } } \ No newline at end of file