diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index de5864d8b1..5f9f07af38 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -79,8 +79,6 @@ dependencies {
/** Features */
implementation(projects.features.onboarding)
- implementation(projects.features.learn2earn.api)
- implementation(projects.features.learn2earn.impl)
implementation(projects.features.referral.presentation)
implementation(projects.features.referral.domain)
implementation(projects.features.referral.data)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3eb4bc059b..c0cbec6b1b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -141,10 +141,6 @@
android:name="com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity"
android:theme="@style/AppTheme" />
-
-
{
private var homeState: MutableState = mutableStateOf(store.state.homeState)
- // private val learn2earnViewModel by activityViewModels()
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
store.dispatch(HomeAction.OnCreate)
@@ -44,11 +42,6 @@ class HomeFragment : ComposeFragment(), StoreSubscriber {
@Composable
override fun ScreenContent(modifier: Modifier) {
- // sync adding story before screen creation
- // if (learn2earnViewModel.uiState.storyScreenState.isVisible) {
- // store.dispatch(HomeAction.InsertStory(position = 0, Stories.OneInchPromo))
- // homeState.value = store.state.homeState
- // }
BackHandler(onBack = requireActivity()::finish)
SystemBarsEffect {
setSystemBarsColor(color = Color.Transparent, darkIcons = false)
@@ -83,7 +76,6 @@ class HomeFragment : ComposeFragment(), StoreSubscriber {
private fun ScreenContent() {
StoriesScreen(
homeState = homeState,
- onLearn2earnClick = {}, // learn2earnViewModel.uiState.storyScreenState.onClick,
onScanButtonClick = {
Analytics.send(IntroductionProcess.ButtonScanCard())
store.dispatch(action = HomeAction.ReadCard(scope = requireActivity().lifecycleScope))
diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt
index 456084062b..79a40b22a9 100644
--- a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt
@@ -20,7 +20,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.feature.learn2earn.presentation.ui.Learn2earnStoriesScreen
import com.tangem.tap.features.home.compose.content.*
import com.tangem.tap.features.home.compose.views.HomeButtons
import com.tangem.tap.features.home.compose.views.SearchCurrenciesButton
@@ -33,7 +32,6 @@ import kotlin.math.max
@Composable
fun StoriesScreen(
homeState: MutableState,
- onLearn2earnClick: () -> Unit,
onScanButtonClick: () -> Unit,
onShopButtonClick: () -> Unit,
onSearchTokensClick: () -> Unit,
@@ -65,7 +63,6 @@ fun StoriesScreen(
isScanInProgress = homeState.value.scanInProgress,
onGoToPreviousStory = goToPreviousStory,
onGoToNextStory = goToNextStory,
- onLearn2earnClick = onLearn2earnClick,
onSearchTokensClick = onSearchTokensClick,
onScanButtonClick = onScanButtonClick,
onShopButtonClick = onShopButtonClick,
@@ -152,7 +149,6 @@ private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: M
.align(Alignment.Start),
)
when (config.currentStory) {
- Stories.OneInchPromo -> Learn2earnStoriesScreen(config.onLearn2earnClick)
Stories.TangemIntro -> FirstStoriesContent(
isPaused = isPaused,
duration = currentStoryDuration,
@@ -187,18 +183,12 @@ private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: M
)
}
- AnimatedVisibility(
- visible = config.currentStory != Stories.OneInchPromo,
- enter = fadeIn(),
- exit = fadeOut(),
- ) {
- HomeButtons(
- modifier = Modifier.fillMaxWidth(),
- btnScanStateInProgress = config.isScanInProgress,
- onScanButtonClick = config.onScanButtonClick,
- onShopButtonClick = config.onShopButtonClick,
- )
- }
+ HomeButtons(
+ modifier = Modifier.fillMaxWidth(),
+ btnScanStateInProgress = config.isScanInProgress,
+ onScanButtonClick = config.onScanButtonClick,
+ onShopButtonClick = config.onShopButtonClick,
+ )
}
}
}
@@ -210,7 +200,6 @@ private data class StoriesScreenContentConfig(
val isScanInProgress: Boolean,
val onGoToPreviousStory: () -> Unit = {},
val onGoToNextStory: () -> Unit = {},
- val onLearn2earnClick: () -> Unit = {},
val onSearchTokensClick: () -> Unit = {},
val onScanButtonClick: () -> Unit = {},
val onShopButtonClick: () -> Unit = {},
@@ -265,12 +254,6 @@ private class StoriesScreenContentConfigProvider : CollectionPreviewParameterPro
currentStory = Stories.WalletForEveryone,
isScanInProgress = false,
),
- StoriesScreenContentConfig(
- storiesSize = 6,
- currentStoryIndex = 6,
- currentStory = Stories.OneInchPromo,
- isScanInProgress = false,
- ),
),
)
// endregion Preview
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt
index 30d6372cf7..cb274cfb39 100644
--- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt
@@ -52,7 +52,6 @@ sealed class Stories(
val duration: Int,
val isNewWalletAvailable: MutableState = mutableStateOf(HomeState.isNewWalletAvailableInit()),
) {
- object OneInchPromo : Stories(duration = 8000)
object TangemIntro : Stories(duration = 6000)
object RevolutionaryWallet : Stories(duration = 6000)
object UltraSecureBackup : Stories(duration = 6000)
diff --git a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt
index af49c95cbd..836356c40e 100644
--- a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt
@@ -102,10 +102,6 @@ class UserWalletManagerImpl(
}
}
- override suspend fun addToken(currency: Currency, derivationPath: String?) {
- // FIXME: Can be removed, used only in learn2earn
- }
-
override suspend fun hideAllTokens() {
// FIXME: Used only in Tester Actions
Timber.w("Not implemented")
diff --git a/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt b/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt
index 9a35679fdb..263fc1eec8 100644
--- a/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt
@@ -1,15 +1,11 @@
package com.tangem.tap.proxy.di
-import com.tangem.common.Provider
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.card.repository.CardSdkConfigRepository
-import com.tangem.domain.common.CardTypesResolver
-import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
-import com.tangem.feature.learn2earn.domain.api.Learn2earnDependencyProvider
import com.tangem.lib.crypto.DerivationManager
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.UserWalletManager
@@ -18,7 +14,6 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import javax.inject.Singleton
@@ -77,27 +72,4 @@ internal object ProxyModule {
networksRepository = networksRepository,
)
}
-
- // regions FeatureConsumers
- @Provides
- @Singleton
- fun provideLear2earnDependencies(appStateHolder: AppStateHolder): Learn2earnDependencyProvider {
- return object : Learn2earnDependencyProvider {
-
- @OptIn(ExperimentalCoroutinesApi::class)
- override fun getCardTypeResolverFlow(): Flow {
- return appStateHolder.userWalletListManagerFlow
- .flatMapLatest { manager ->
- manager?.selectedUserWallet
- ?.map { it.scanResponse.cardTypesResolver }
- ?: flowOf(null)
- }
- }
-
- override fun getWebViewAuthCredentialsProvider(): Provider = Provider {
- appStateHolder.mainStore?.state?.globalState?.configManager?.config?.tangemComAuthorization
- }
- }
- }
- // endregion FeatureConsumers
}
\ No newline at end of file
diff --git a/features/learn2earn/api/.gitignore b/features/learn2earn/api/.gitignore
deleted file mode 100644
index 42afabfd2a..0000000000
--- a/features/learn2earn/api/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
\ No newline at end of file
diff --git a/features/learn2earn/api/build.gradle.kts b/features/learn2earn/api/build.gradle.kts
deleted file mode 100644
index 7ff7fb7522..0000000000
--- a/features/learn2earn/api/build.gradle.kts
+++ /dev/null
@@ -1,4 +0,0 @@
-plugins {
- alias(deps.plugins.kotlin.jvm)
- id("configuration")
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/.gitignore b/features/learn2earn/impl/.gitignore
deleted file mode 100644
index 42afabfd2a..0000000000
--- a/features/learn2earn/impl/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
\ No newline at end of file
diff --git a/features/learn2earn/impl/build.gradle.kts b/features/learn2earn/impl/build.gradle.kts
deleted file mode 100644
index b9fb7f48a6..0000000000
--- a/features/learn2earn/impl/build.gradle.kts
+++ /dev/null
@@ -1,60 +0,0 @@
-plugins {
- alias(deps.plugins.android.library)
- alias(deps.plugins.kotlin.android)
- alias(deps.plugins.kotlin.kapt)
- alias(deps.plugins.kotlin.serialization)
- alias(deps.plugins.hilt.android)
- id("configuration")
-}
-
-dependencies {
- /** Core modules */
- implementation(project(":common"))
- implementation(project(":domain:legacy"))
- implementation(project(":core:analytics"))
- implementation(projects.core.analytics.models)
- implementation(project(":core:featuretoggles"))
- implementation(project(":core:datasource"))
- implementation(project(":core:utils"))
- implementation(project(":core:ui"))
- implementation(project(":core:res"))
- implementation(project(":data:source:preferences"))
- implementation(project(":data:common"))
- implementation(project(":libs:auth"))
- implementation(project(":libs:crypto"))
-
- implementation(deps.material)
-
- /** AndroidX */
- implementation(deps.androidx.core.ktx)
- implementation(deps.androidx.appCompat)
- implementation(deps.androidx.fragment.ktx)
- implementation(deps.androidx.activity.compose)
- implementation(deps.androidx.browser)
-
- /** Compose */
- implementation(deps.compose.material)
- implementation(deps.compose.material3)
- implementation(deps.compose.foundation)
- implementation(deps.compose.ui)
- implementation(deps.compose.ui.tooling)
- implementation(deps.compose.accompanist.webView)
-
- /** Preferences */
- implementation(deps.krateSharedPref)
-
- /** Network */
- implementation(deps.moshi)
- implementation(deps.moshi.kotlin)
- implementation(deps.retrofit)
- implementation(deps.retrofit.moshi)
-
- /** Other libraries */
- implementation(deps.kotlin.immutable.collections)
- implementation(deps.kotlin.serialization)
- implementation(deps.timber)
-
- /** DI */
- implementation(deps.hilt.android)
- kapt(deps.hilt.kapt)
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/AndroidManifest.xml b/features/learn2earn/impl/src/main/AndroidManifest.xml
deleted file mode 100644
index 472f44a1a5..0000000000
--- a/features/learn2earn/impl/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/analytics/Learn2earnEvents.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/analytics/Learn2earnEvents.kt
deleted file mode 100644
index 5e4a01d002..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/analytics/Learn2earnEvents.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.tangem.feature.learn2earn.analytics
-
-import com.tangem.core.analytics.models.AnalyticsEvent
-
-internal sealed class Learn2earnEvents(
- category: String,
- event: String,
- params: Map = mapOf(),
-) : AnalyticsEvent(
- category = category,
- event = event,
- params = params + mapOf(
- "Program Name" to "1inch",
- ),
-) {
-
- sealed class IntroductionProcess(
- event: String,
- params: Map = mapOf(),
- ) : Learn2earnEvents(
- category = "Introduction Process",
- event = event,
- params = params,
- ) {
- class ButtonLearn : IntroductionProcess("Button - Learn")
- }
-
- sealed class MainScreen(
- event: String,
- params: Map = mapOf(),
- ) : Learn2earnEvents(
- category = "Main Screen",
- event = event,
- params = params,
- ) {
- class NoticeLear2earn(clientType: AnalyticsParam.ClientType) : MainScreen(
- event = "Notice - Learn&Earn",
- params = mapOf(AnalyticsParam.CLIENT_TYPE to clientType.value),
- )
-
- class NoticeClaimSuccess(clientType: AnalyticsParam.ClientType) : MainScreen(
- event = "Notice - Successful Claim",
- params = mapOf(AnalyticsParam.CLIENT_TYPE to clientType.value),
- )
- }
-
- sealed class PromoScreen(
- event: String,
- params: Map = mapOf(),
- ) : Learn2earnEvents(
- category = "Promo Screen",
- event = event,
- params = params,
- ) {
- class ButtonBuy : PromoScreen("Button - Buy")
-
- class SuccessScreenOpened(clientType: AnalyticsParam.ClientType) : PromoScreen(
- event = "Success Screen Opened",
- params = mapOf(AnalyticsParam.CLIENT_TYPE to clientType.value),
- )
- }
-}
-
-internal sealed class AnalyticsParam {
- sealed class ClientType(val value: String) {
- class New : ClientType("New")
- class Old : ClientType("Old")
- }
-
- companion object Key {
- const val CLIENT_TYPE = "Client Type"
- }
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt
deleted file mode 100644
index 0eefb517be..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt
+++ /dev/null
@@ -1,138 +0,0 @@
-package com.tangem.feature.learn2earn.data
-
-import com.squareup.moshi.Moshi
-import com.tangem.datasource.api.promotion.PromotionApi
-import com.tangem.datasource.api.promotion.models.*
-import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
-import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
-import com.tangem.feature.learn2earn.data.models.PromoUserData
-import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
-import kotlinx.coroutines.withContext
-import timber.log.Timber
-
-/**
-[REDACTED_AUTHOR]
- */
-internal class DefaultLearn2earnRepository(
- private val preferencesStorage: Learn2earnPreferenceStorage,
- private val api: PromotionApi,
- private val dispatchers: AppCoroutineDispatcherProvider,
- moshi: Moshi,
-) : Learn2earnRepository {
-
- private val promotionInfoAdapter = moshi.adapter(PromotionInfoResponse::class.java)
- private val userDataAdapter = moshi.adapter(PromoUserData::class.java)
-
- private var userData: PromoUserData = restoreUserData()
-
- override fun getUserData(): PromoUserData {
- return userData
- }
-
- override fun updateUserData(userData: PromoUserData) {
- this.userData = userData
- saveUserData(userData)
- }
-
- override fun getProgramName(): String {
- return PROGRAM_NAME
- }
-
- override suspend fun getPromotionInfo(): Result {
- return withContext(dispatchers.io) {
- val promotionInfo = restorePromotionInfo()
- val data = promotionInfo?.getData(userData.promoCode)
- if (data?.status == PromotionInfoResponse.Status.FINISHED) {
- Result.success(promotionInfo)
- } else {
- runCatching { api.getPromotionInfo(getProgramName()) }
- .fold(
- onSuccess = { infoResponse ->
- savePromotionInfo(infoResponse)
- Result.success(infoResponse)
- },
- onFailure = { exception -> Result.failure(exception) },
- )
- }
- }
- }
-
- override suspend fun validate(walletId: String): ValidateResponse {
- return withContext(dispatchers.io) {
- api.validate(ValidateRequestBody(walletId, getProgramName()))
- }
- }
-
- override suspend fun requestAward(walletId: String, address: String): AwardResponse {
- return withContext(dispatchers.io) {
- api.requestAward(AwardRequestBody(walletId, address, getProgramName()))
- }
- }
-
- override suspend fun validateCode(walletId: String, code: String?): CodeValidateResponse {
- return withContext(dispatchers.io) {
- api.validateCode(CodeValidateRequestBody(walletId, code))
- }
- }
-
- override suspend fun requestAwardByCode(walletId: String, address: String, code: String?): CodeAwardResponse {
- return withContext(dispatchers.io) {
- api.requestAwardByCode(CodeAwardRequestBody(walletId, address, code))
- }
- }
-
- private fun restorePromotionInfo(): PromotionInfoResponse? {
- return try {
- preferencesStorage.promotionInfo?.let { promotionInfoAdapter.fromJson(it) }
- } catch (ex: Exception) {
- Timber.e(ex)
- preferencesStorage.promotionInfo = null
- null
- }
- }
-
- private fun savePromotionInfo(infoResponse: PromotionInfoResponse) {
- try {
- preferencesStorage.promotionInfo = promotionInfoAdapter.toJson(infoResponse)
- } catch (ex: Exception) {
- Timber.e(ex)
- }
- }
-
- private fun restoreUserData(): PromoUserData {
- return try {
- preferencesStorage.userData?.let { userDataAdapter.fromJson(it) }
- ?: createEmptyUserData().apply { saveUserData(this) }
- } catch (ex: Exception) {
- Timber.e(ex)
- createEmptyUserData().apply { saveUserData(this) }
- }
- }
-
- private fun saveUserData(userData: PromoUserData) {
- try {
- preferencesStorage.userData = userDataAdapter.toJson(userData)
- } catch (ex: Exception) {
- Timber.e(ex)
- }
- }
-
- private fun createEmptyUserData(): PromoUserData = PromoUserData(
- promoCode = null,
- isRegisteredInPromotion = false,
- isAlreadyReceivedAward = false,
- isLearningStageFinished = false,
- )
-
- private companion object {
- const val PROGRAM_NAME: String = "1inch"
- }
-}
-
-private fun PromotionInfoResponse.getData(promoCode: String?): PromotionInfoResponse.Data? {
- return if (promoCode == null) {
- newCard
- } else {
- oldCard
- }
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt
deleted file mode 100644
index 4c3e39b9ae..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.tangem.feature.learn2earn.data
-
-import android.content.Context
-import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
-import hu.autsoft.krate.SimpleKrate
-import hu.autsoft.krate.default.withDefault
-import hu.autsoft.krate.stringPref
-
-/**
-[REDACTED_AUTHOR]
- */
-internal class DefaultPreferenceStorage(
- context: Context,
-) : SimpleKrate(context = context, name = "Lear2earnPromotion"), Learn2earnPreferenceStorage {
-
- override var promotionInfo: String? by stringPref().withDefault(null)
-
- override var userData: String? by stringPref().withDefault(null)
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt
deleted file mode 100644
index 8c8840bb74..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.tangem.feature.learn2earn.data.api
-
-/**
-[REDACTED_AUTHOR]
- */
-interface Learn2earnPreferenceStorage {
-
- var promotionInfo: String?
-
- var userData: String?
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt
deleted file mode 100644
index 06e95628d7..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.tangem.feature.learn2earn.data.api
-
-import com.tangem.datasource.api.promotion.models.*
-import com.tangem.feature.learn2earn.data.models.PromoUserData
-
-/**
-[REDACTED_AUTHOR]
- */
-interface Learn2earnRepository {
-
- fun getUserData(): PromoUserData
-
- fun updateUserData(userData: PromoUserData)
-
- fun getProgramName(): String
-
- suspend fun getPromotionInfo(): Result
-
- suspend fun validate(walletId: String): ValidateResponse
-
- suspend fun requestAward(walletId: String, address: String): AwardResponse
-
- suspend fun validateCode(walletId: String, code: String?): CodeValidateResponse
-
- suspend fun requestAwardByCode(walletId: String, address: String, code: String?): CodeAwardResponse
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt
deleted file mode 100644
index 186b3c8458..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.tangem.feature.learn2earn.data.di
-
-import android.content.Context
-import com.squareup.moshi.Moshi
-import com.tangem.datasource.api.promotion.PromotionApi
-import com.tangem.datasource.di.NetworkMoshi
-import com.tangem.datasource.di.PromotionOneInch
-import com.tangem.feature.learn2earn.data.DefaultLearn2earnRepository
-import com.tangem.feature.learn2earn.data.DefaultPreferenceStorage
-import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
-import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
-import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
-import dagger.Module
-import dagger.Provides
-import dagger.hilt.InstallIn
-import dagger.hilt.android.qualifiers.ApplicationContext
-import dagger.hilt.components.SingletonComponent
-import javax.inject.Singleton
-
-@Module
-@InstallIn(SingletonComponent::class)
-internal class Learn2earnDataModule {
-
- @Provides
- @Singleton
- fun providePreferenceStorage(@ApplicationContext context: Context): Learn2earnPreferenceStorage {
- return DefaultPreferenceStorage(context)
- }
-
- @Provides
- @Singleton
- fun provideRepository(
- preferenceStorage: Learn2earnPreferenceStorage,
- @NetworkMoshi moshi: Moshi,
- @PromotionOneInch promotionApi: PromotionApi,
- dispatchers: AppCoroutineDispatcherProvider,
- ): Learn2earnRepository {
- return DefaultLearn2earnRepository(
- preferencesStorage = preferenceStorage,
- api = promotionApi,
- dispatchers = dispatchers,
- moshi = moshi,
- )
- }
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/models/PromoUserData.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/models/PromoUserData.kt
deleted file mode 100644
index b5553c544e..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/models/PromoUserData.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.tangem.feature.learn2earn.data.models
-
-/**
-[REDACTED_AUTHOR]
- */
-data class PromoUserData(
- val promoCode: String?,
- val isLearningStageFinished: Boolean,
- val isRegisteredInPromotion: Boolean,
- val isAlreadyReceivedAward: Boolean,
-)
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/DefaultLearn2earnFeatureToggleManager.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/DefaultLearn2earnFeatureToggleManager.kt
deleted file mode 100644
index 19306c2aed..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/DefaultLearn2earnFeatureToggleManager.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.tangem.feature.learn2earn.data.toggles
-
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
-
-/**
-[REDACTED_AUTHOR]
- */
-internal class DefaultLearn2earnFeatureToggleManager(
- private val featureTogglesManager: FeatureTogglesManager,
-) : Learn2earnFeatureToggleManager {
-
- override val isLearn2earnEnabled: Boolean
- get() = featureTogglesManager.isFeatureEnabled(name = "1INCH_LEARN_2_EARN_ENABLED")
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/Learn2earnFeatureToggleManager.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/Learn2earnFeatureToggleManager.kt
deleted file mode 100644
index 64f5c4abfc..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/Learn2earnFeatureToggleManager.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.tangem.feature.learn2earn.data.toggles
-
-/**
- * Feature toggles manager implementation of "learn2earn" feature
- *
-[REDACTED_AUTHOR]
- */
-interface Learn2earnFeatureToggleManager {
-
- val isLearn2earnEnabled: Boolean
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt
deleted file mode 100644
index 59aa4de658..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt
+++ /dev/null
@@ -1,388 +0,0 @@
-package com.tangem.feature.learn2earn.domain
-
-import android.net.Uri
-import com.tangem.common.Provider
-import com.tangem.core.analytics.api.AnalyticsEventHandler
-import com.tangem.data.common.locale.LocaleProvider
-import com.tangem.datasource.api.promotion.models.PromotionInfoResponse
-import com.tangem.datasource.demo.DemoModeDatasource
-import com.tangem.feature.learn2earn.analytics.AnalyticsParam
-import com.tangem.feature.learn2earn.analytics.Learn2earnEvents.*
-import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
-import com.tangem.feature.learn2earn.data.models.PromoUserData
-import com.tangem.feature.learn2earn.data.toggles.Learn2earnFeatureToggleManager
-import com.tangem.feature.learn2earn.domain.api.*
-import com.tangem.feature.learn2earn.domain.models.Promotion
-import com.tangem.feature.learn2earn.domain.models.PromotionError
-import com.tangem.feature.learn2earn.domain.models.toDomainError
-import com.tangem.lib.crypto.DerivationManager
-import com.tangem.lib.crypto.UserWalletManager
-import com.tangem.lib.crypto.models.Currency
-import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
-import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import timber.log.Timber
-
-/**
-[REDACTED_AUTHOR]
- */
-@Suppress("LongParameterList", "LargeClass")
-internal class DefaultLearn2earnInteractor(
- private val featureToggleManager: Learn2earnFeatureToggleManager,
- private val repository: Learn2earnRepository,
- private val userWalletManager: UserWalletManager,
- private val derivationManager: DerivationManager,
- private val localeProvider: LocaleProvider,
- private val analytics: AnalyticsEventHandler,
- private val demoModeDatasource: DemoModeDatasource,
- private val dependencyProvider: Learn2earnDependencyProvider,
- dispatchers: AppCoroutineDispatcherProvider,
-) : Learn2earnInteractor {
-
- override var webViewResultHandler: WebViewResultHandler? = null
-
- private val promoUserData: PromoUserData
- get() = repository.getUserData()
-
- private lateinit var promotion: Promotion
-
- private val scope = CoroutineScope(Job() + dispatchers.io + FeatureCoroutineExceptionHandler.create("mainScope"))
-
- private val isTangemWalletFlow = MutableStateFlow(false)
- private var isTangemWalletFlowJob: Job? = null
- private var isTangemWalletSync = false
-
- private val webViewUriBuilder: WebViewUriBuilder by lazy {
- WebViewUriBuilder(
- authCredentialsProvider = dependencyProvider.getWebViewAuthCredentialsProvider(),
- localeProvider = localeProvider,
- promoCodeProvider = Provider { promoUserData.promoCode },
- )
- }
-
- private val webViewUriParser: WebViewUriParser by lazy {
- WebViewUriParser { repository.getProgramName() }
- }
-
- override suspend fun init() {
- initPromotionInfo()
- }
-
- override fun getIsTangemWalletFlow(): Flow = isTangemWalletFlow
-
- override fun isUserHadPromoCode(): Boolean {
- return promoUserData.promoCode != null
- }
-
- override suspend fun validateUserWallet(): Result {
- val promoCode = promoUserData.promoCode
- val userWalletId = userWalletManager.getWalletId()
- if (userWalletId.isEmpty()) return Result.failure(PromotionError.EmptyUserWalletId)
-
- val domainError = if (promoCode == null) {
- repository.validate(userWalletId).error
- } else {
- repository.validateCode(userWalletId, promoCode).error
- }?.toDomainError()
-
- return if (domainError == null) {
- Result.success(Unit)
- } else {
- handlePromotionError(domainError)
- Result.failure(domainError)
- }
- }
-
- override fun isUserRegisteredInPromotion(): Boolean {
- return promoUserData.isRegisteredInPromotion
- }
-
- override fun getAwardAmount(): Int = try {
- promotion.getPromotionInfo().getCardData().award.toInt()
- } catch (ex: NullPointerException) {
- Timber.w(ex)
- 0
- }
-
- override fun getAwardNetworkName(): String {
- val networkId = promotion.getPromotionInfo().awardPaymentToken.networkId
- return userWalletManager.getNativeTokenForNetwork(networkId).name
- }
-
- @Throws(IllegalArgumentException::class)
- override suspend fun requestAward(): Result {
- val awardCurrency = getCurrencyForAward()
- ?: return Result.failure(PromotionError.UnknownError("Currency for award is null"))
-
- val walletId = userWalletManager.getWalletId()
- val promoCode = promoUserData.promoCode
-
- val domainError = if (promoCode == null) {
- requestAward(walletId, awardCurrency)
- } else {
- requestAwardWithPromoCode(walletId, awardCurrency, promoCode)
- }
-
- return if (domainError == null) {
- Result.success(Unit)
- } else {
- handlePromotionError(domainError)
- Result.failure(domainError)
- }
- }
-
- private suspend fun requestAward(walletId: String, awardCurrency: Currency): PromotionError? {
- val validateResponse = repository.validate(walletId)
- return if (validateResponse.valid == true) {
- val address = getWalletAddressForAward(awardCurrency)
- val awardResponse = repository.requestAward(walletId, address)
- if (awardResponse.status == true) {
- updateUserData { it.copy(isAlreadyReceivedAward = true) }
- null
- } else {
- awardResponse.error
- }
- } else {
- validateResponse.error
- }?.toDomainError()
- }
-
- private suspend fun requestAwardWithPromoCode(
- walletId: String,
- awardCurrency: Currency,
- promoCode: String,
- ): PromotionError? {
- val codeValidateResponse = repository.validateCode(walletId, promoCode)
- return if (codeValidateResponse.valid == true) {
- val address = getWalletAddressForAward(awardCurrency)
- val awardWithCodeResponse = repository.requestAwardByCode(walletId, address, promoCode)
- if (awardWithCodeResponse.status == true) {
- updateUserData { it.copy(isAlreadyReceivedAward = true) }
- null
- } else {
- awardWithCodeResponse.error
- }
- } else {
- codeValidateResponse.error
- }?.toDomainError()
- }
-
- private suspend fun getWalletAddressForAward(currency: Currency): String {
- val derivationPath = deriveOrAddTokens(currency)
- return userWalletManager.getWalletAddress(currency.networkId, derivationPath)
- }
-
- private suspend fun deriveOrAddTokens(currency: Currency): String {
- val derivationPath = derivationManager.getDerivationPathForBlockchain(currency.networkId)
- if (derivationPath.isNullOrEmpty()) error("derivationPath shouldn't be empty")
-
- if (!derivationManager.hasDerivation(currency.networkId, derivationPath)) {
- derivationManager.deriveMissingBlockchains(currency)
- }
- if (!userWalletManager.isTokenAdded(currency, derivationPath)) {
- userWalletManager.addToken(currency, derivationPath)
- }
- return derivationPath
- }
-
- private fun handlePromotionError(error: PromotionError) {
- when (error) {
- is PromotionError.CodeNotFound -> {
- updateUserData { it.copy(promoCode = null) }
- }
- is PromotionError.CardAlreadyHasAward, is PromotionError.WalletAlreadyHasAward,
- is PromotionError.CodeWasAlreadyUsed,
- -> {
- updateUserData { it.copy(isAlreadyReceivedAward = true) }
- }
- else -> Unit
- }
- }
-
- override fun buildUriForNewUser(): Uri {
- return webViewUriBuilder.buildUriForNewUser(promoUserData.isLearningStageFinished)
- }
-
- override fun buildUriForOldUser(): Uri {
- return webViewUriBuilder.buildUriForOldUser(promoUserData.isLearningStageFinished)
- }
-
- override fun getBasicAuthHeaders(): ArrayList {
- return HeadersConverter().convert(webViewUriBuilder.getBasicAuthHeaders())
- }
-
- override fun handleRedirect(uri: Uri): WebViewAction {
- val result = webViewUriParser.parse(uri)
- when (result) {
- is WebViewResult.NewUserLearningFinished -> {
- analytics.send(PromoScreen.SuccessScreenOpened(AnalyticsParam.ClientType.New()))
- updateUserData {
- it.copy(
- promoCode = result.promoCode,
- isRegisteredInPromotion = true,
- isLearningStageFinished = true,
- )
- }
- }
- is WebViewResult.OldUserLearningFinished -> {
- analytics.send(PromoScreen.SuccessScreenOpened(AnalyticsParam.ClientType.Old()))
- updateUserData {
- it.copy(
- promoCode = null,
- isLearningStageFinished = true,
- )
- }
- }
- WebViewResult.ReadyForAward -> {
- updateUserData { it.copy(isRegisteredInPromotion = true) }
- }
- is WebViewResult.Learn2earnAnalyticsEvent -> {
- analytics.send(result.event)
- }
- WebViewResult.Empty -> Unit
- }
- webViewResultHandler?.handleResult(result)
-
- return result.toWebViewAction()
- }
-
- override fun isPromotionActive(): Boolean {
- subscribeToCardTypeResolverFlow()
-
- val isActive = when {
- demoModeDatasource.isDemoModeActive -> false
- !featureToggleManager.isLearn2earnEnabled -> false
- promoUserData.isAlreadyReceivedAward -> false
- else -> promotion.isReadyToUse()
- }
-
- return isActive
- }
-
- override fun isPromotionActiveOnStories(): Boolean {
- return if (isPromotionActive()) {
- promotion.getPromotionInfo().newCard.status == PromotionInfoResponse.Status.ACTIVE
- } else {
- false
- }
- }
-
- override fun isPromotionActiveOnMain(): Boolean {
- if (!isPromotionActive() || !isTangemWalletSync) return false
-
- val promotionInfo = promotion.getPromotionInfo()
- return if (isUseLogicForOldCards()) {
- promotionInfo.oldCard.status == PromotionInfoResponse.Status.ACTIVE
- } else {
- when (promotionInfo.newCard.status) {
- PromotionInfoResponse.Status.PENDING -> !promoUserData.isAlreadyReceivedAward
- PromotionInfoResponse.Status.ACTIVE -> true
- // disable promotion for a new user only if they have received an award
- PromotionInfoResponse.Status.FINISHED -> !promoUserData.isAlreadyReceivedAward
- }
- }
- }
-
- private suspend fun initPromotionInfo() {
- promotion = if (featureToggleManager.isLearn2earnEnabled) {
- repository.getPromotionInfo()
- .fold(
- onSuccess = { response ->
- val responseError = response.error
- if (responseError == null) {
- val npeMessage = { "Shouldn't be null" }
- Promotion(
- info = Promotion.PromotionInfo(
- newCard = requireNotNull(response.newCard, npeMessage),
- oldCard = requireNotNull(response.oldCard, npeMessage),
- awardPaymentToken = requireNotNull(response.awardPaymentToken, npeMessage),
- ),
- error = null,
- )
- } else {
- Promotion(
- info = null,
- error = responseError.toDomainError(),
- )
- }
- },
- onFailure = {
- Promotion(
- info = null,
- error = PromotionError.NetworkUnreachable,
- )
- },
- )
- } else {
- Promotion(
- info = null,
- error = null,
- )
- }
- }
-
- private fun getCurrencyForAward(): Currency? {
- val token = promotion.info?.awardPaymentToken ?: return null
-
- return Currency.NonNativeToken(
- id = token.id,
- name = token.name,
- symbol = token.symbol,
- networkId = token.networkId,
- contractAddress = token.contractAddress,
- decimalCount = token.decimalCount,
- )
- }
-
- private fun subscribeToCardTypeResolverFlow() {
- if (isTangemWalletFlowJob == null || isTangemWalletFlowJob?.isCancelled == true) {
- isTangemWalletFlowJob = dependencyProvider.getCardTypeResolverFlow()
- .onEach {
- val isTangemWallet = it?.isTangemWallet() ?: false
- isTangemWalletSync = isTangemWallet
- isTangemWalletFlow.emit(isTangemWallet)
- }
- .launchIn(scope)
- }
- }
-
- // region Utils
- private fun updateUserData(updateBlock: (PromoUserData) -> PromoUserData): PromoUserData {
- return updateBlock(promoUserData).apply {
- repository.updateUserData(this)
- }
- }
-
- private fun isUseLogicForOldCards(): Boolean {
- return promoUserData.promoCode == null
- }
-
- private fun Promotion.isReadyToUse(): Boolean {
- return info != null
- }
-
- private fun Promotion.PromotionInfo.getCardData(): PromotionInfoResponse.Data {
- return if (isUseLogicForOldCards()) {
- oldCard
- } else {
- newCard
- }
- }
-
- private fun WebViewResult.toWebViewAction(): WebViewAction {
- return when (this) {
- is WebViewResult.NewUserLearningFinished,
- WebViewResult.OldUserLearningFinished,
- is WebViewResult.Learn2earnAnalyticsEvent,
- -> WebViewAction.NOTHING
- WebViewResult.ReadyForAward -> WebViewAction.FINISH_SESSION
- WebViewResult.Empty -> WebViewAction.PROCEED
- }
- }
- // endregion Utils
-}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/HeadersConverter.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/HeadersConverter.kt
deleted file mode 100644
index 439091ba1a..0000000000
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/HeadersConverter.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.tangem.feature.learn2earn.domain
-
-import com.tangem.utils.converter.TwoWayConverter
-
-/**
- * A converter that helps prepare a list of headers to be added to the Bundle.
- * ArrayList is used to prevent cast exceptions when the convert result is placed in a Bundle.
- * @see Learn2earnRouter#openWebView() putStringArrayListExtra
- *
-[REDACTED_AUTHOR]
- */
-internal class HeadersConverter : TwoWayConverter