diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 6edc1d9d21..5647ad7cfc 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -4,8 +4,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -19,6 +47,10 @@
+
+
+
+
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9029856167..e6d30a7cc6 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -74,13 +74,14 @@ dependencies {
implementation(projects.domain.walletConnect)
implementation(projects.domain.markets)
implementation(projects.domain.manageTokens)
+ implementation(projects.domain.onramp)
implementation(projects.common)
implementation(projects.common.routing)
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
implementation(projects.core.navigation)
- implementation(projects.core.featuretoggles)
+ implementation(projects.core.configToggles)
implementation(projects.core.res)
implementation(projects.core.ui)
implementation(projects.core.datasource)
@@ -112,6 +113,7 @@ dependencies {
implementation(projects.data.walletConnect)
implementation(projects.data.markets)
implementation(projects.data.manageTokens)
+ implementation(projects.data.onramp)
/** Features */
implementation(projects.features.onboarding)
diff --git a/app/src/main/assets/testnet_tokens.json b/app/src/main/assets/testnet_tokens.json
index 30fa60f3c4..67b96dd4a9 100644
--- a/app/src/main/assets/testnet_tokens.json
+++ b/app/src/main/assets/testnet_tokens.json
@@ -749,6 +749,16 @@
}
]
},
+ {
+ "id": "chiliz",
+ "name": "Chiliz",
+ "symbol": "CHZ",
+ "networks": [
+ {
+ "networkId": "chiliz/test"
+ }
+ ]
+ },
{
"id": "casper-network",
"name": "Casper",
diff --git a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt
index b116caf952..22e43ff3d2 100644
--- a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt
+++ b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt
@@ -3,9 +3,11 @@ package com.tangem.tap
import com.tangem.TangemSdkLogger
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.common.routing.AppRouter
import com.tangem.core.analytics.filter.OneTimeEventFilter
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.core.navigation.share.ShareManager
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.datasource.connection.NetworkConnectionManager
@@ -34,6 +36,7 @@ import com.tangem.tap.common.log.TangemAppLoggerInitializer
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
import com.tangem.tap.proxy.AppStateHolder
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@@ -52,6 +55,8 @@ interface ApplicationEntryPoint {
fun getFeatureTogglesManager(): FeatureTogglesManager
+ fun getExcludedBlockchainsManager(): ExcludedBlockchainsManager
+
fun getNetworkConnectionManager(): NetworkConnectionManager
fun getCardScanningFeatureToggles(): CardScanningFeatureToggles
@@ -113,4 +118,8 @@ interface ApplicationEntryPoint {
fun getOnrampFeatureToggles(): OnrampFeatureToggles
fun getOnboardingV2FeatureToggles(): OnboardingV2FeatureToggles
+
+ fun getCoroutineDispatcherProvider(): CoroutineDispatcherProvider
+
+ fun getExcludedBlockchains(): ExcludedBlockchains
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt
index e456f93295..61af04c644 100644
--- a/app/src/main/java/com/tangem/tap/MainActivity.kt
+++ b/app/src/main/java/com/tangem/tap/MainActivity.kt
@@ -52,6 +52,7 @@ import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.feature.qrscanning.QrScanningRouter
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
+import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
import com.tangem.features.send.api.navigation.SendRouter
@@ -59,6 +60,7 @@ import com.tangem.features.staking.api.navigation.StakingRouter
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
import com.tangem.features.wallet.navigation.WalletRouter
import com.tangem.operations.backup.BackupService
+import com.tangem.sdk.api.BackupServiceHolder
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.sdk.extensions.init
import com.tangem.tap.common.ActivityResultCallbackHolder
@@ -72,6 +74,7 @@ import com.tangem.tap.common.redux.NotificationsHandler
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
import com.tangem.tap.features.intentHandler.IntentProcessor
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
+import com.tangem.tap.features.intentHandler.handlers.OnPushClickedIntentHandler
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
import com.tangem.tap.features.main.MainViewModel
import com.tangem.tap.features.main.model.Toast
@@ -186,6 +189,12 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
@Inject
lateinit var shouldInitiallyAskPermissionUseCase: ShouldInitiallyAskPermissionUseCase
+ @Inject
+ lateinit var backupServiceHolder: BackupServiceHolder
+
+ @Inject
+ lateinit var onboardingV2FeatureToggles: OnboardingV2FeatureToggles
+
internal val viewModel: MainViewModel by viewModels()
private lateinit var appThemeModeFlow: SharedFlow
@@ -295,7 +304,14 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
cardSdkOwner.register(activity = this)
tangemSdkManager = injectedTangemSdkManager
appStateHolder.tangemSdkManager = tangemSdkManager
- backupService = BackupService.init(cardSdkConfigRepository.sdk, this)
+
+ if (onboardingV2FeatureToggles.isOnboardingV2Enabled) {
+ backupServiceHolder.createAndSetService(cardSdkConfigRepository.sdk, this)
+ backupService = backupServiceHolder.backupService.get()!! // will be deleted eventually
+ } else {
+ backupService = BackupService.init(cardSdkConfigRepository.sdk, this)
+ }
+
lockUserWalletsTimer = LockUserWalletsTimer(
owner = this,
settingsRepository = settingsRepository,
@@ -382,6 +398,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
private fun initIntentHandlers() {
val hasSavedWalletsProvider = { userWalletsListManager.hasUserWallets }
+ intentProcessor.addHandler(OnPushClickedIntentHandler(analyticsEventsHandler))
intentProcessor.addHandler(BackgroundScanIntentHandler(hasSavedWalletsProvider, lifecycleScope))
intentProcessor.addHandler(WalletConnectLinkIntentHandler())
}
@@ -555,6 +572,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
}
}
+ // TODO add onboarding v2 handling
store.dispatch(BackupAction.CheckForUnfinishedBackup)
}
diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt
index 0e2e83f67f..0cb1183a0c 100644
--- a/app/src/main/java/com/tangem/tap/TangemApplication.kt
+++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt
@@ -9,6 +9,7 @@ import com.tangem.TangemSdkLogger
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.common.routing.AppRouter
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.api.ParamsInterceptor
@@ -17,7 +18,8 @@ import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.datasource.api.common.MoshiConverter
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
import com.tangem.datasource.connection.NetworkConnectionManager
@@ -57,9 +59,11 @@ import com.tangem.tap.domain.tasks.product.DerivationsFinder
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
import com.tangem.tap.proxy.AppStateHolder
import com.tangem.tap.proxy.redux.DaggerGraphState
-import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.wallet.BuildConfig
import dagger.hilt.EntryPoints
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import org.rekotlin.Store
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository
@@ -88,6 +92,9 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
private val featureTogglesManager: FeatureTogglesManager
get() = entryPoint.getFeatureTogglesManager()
+ private val excludedBlockchainsManager: ExcludedBlockchainsManager
+ get() = entryPoint.getExcludedBlockchainsManager()
+
private val networkConnectionManager: NetworkConnectionManager
get() = entryPoint.getNetworkConnectionManager()
@@ -180,6 +187,12 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles
get() = entryPoint.getOnboardingV2FeatureToggles()
+
+ private val dispatchers: CoroutineDispatcherProvider
+ get() = entryPoint.getCoroutineDispatcherProvider()
+
+ private val excludedBlockchains: ExcludedBlockchains
+ get() = entryPoint.getExcludedBlockchains()
// endregion
override fun onCreate() {
@@ -200,9 +213,11 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
// TODO: Try to performance and user experience.
// [REDACTED_JIRA]
runBlocking {
- featureTogglesManager.init()
-
- initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize())
+ awaitAll(
+ async { featureTogglesManager.init() },
+ async { excludedBlockchainsManager.init() },
+ async { initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize()) },
+ )
}
loadNativeLibraries()
@@ -216,7 +231,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
derivationsFinder = DerivationsFinder(
appPreferencesStore = appPreferencesStore,
- dispatchers = AppCoroutineDispatcherProvider(),
+ dispatchers = dispatchers,
)
appStateHolder.mainStore = store
@@ -258,6 +273,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
onrampFeatureToggles = onrampFeatureToggles,
environmentConfigStorage = environmentConfigStorage,
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
+ excludedBlockchains = excludedBlockchains,
),
),
)
diff --git a/app/src/main/java/com/tangem/tap/common/DialogManager.kt b/app/src/main/java/com/tangem/tap/common/DialogManager.kt
index 8bc1f8e7ae..c48a2988f8 100644
--- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt
+++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt
@@ -140,6 +140,11 @@ class DialogManager : StoreSubscriber {
message = state.dialog.error.message,
context = context,
)
+ is WalletConnectDialog.UnsupportedWcVersion -> SimpleAlertDialog.create(
+ titleRes = R.string.common_error,
+ messageRes = R.string.unsupported_wc_version,
+ context = context,
+ )
is BackupDialog.AttestationFailed -> AttestationFailedDialog.create(context)
is BackupDialog.AddMoreBackupCards -> AddMoreBackupCardsDialog.create(context)
is BackupDialog.BackupInProgress -> BackupInProgressDialog.create(context)
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/MainScreen.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/MainScreen.kt
deleted file mode 100644
index f97dca3a02..0000000000
--- a/app/src/main/java/com/tangem/tap/common/analytics/events/MainScreen.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.tangem.tap.common.analytics.events
-
-import com.tangem.core.analytics.models.AnalyticsEvent
-
-/**
-[REDACTED_AUTHOR]
- */
-sealed class MainScreen(
- event: String,
- params: Map = mapOf(),
-) : AnalyticsEvent("Main Screen", event, params) {
-
- class ScreenOpened : MainScreen("Screen opened")
- class ButtonScanCard : MainScreen("Button - Scan Card")
-
- class EnableBiometrics(state: AnalyticsParam.OnOffState) : MainScreen(
- event = "Enable Biometric",
- params = mapOf("State" to state.value),
- )
-
- class NoticeRateAppButton(result: AnalyticsParam.RateApp) : MainScreen(
- event = "Notice - Rate The App Button Tapped",
- params = mapOf("Result" to result.value),
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Push.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Push.kt
new file mode 100644
index 0000000000..46c647b06f
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Push.kt
@@ -0,0 +1,13 @@
+package com.tangem.tap.common.analytics.events
+
+import com.tangem.core.analytics.models.AnalyticsEvent
+
+internal sealed class Push(event: String) : AnalyticsEvent(
+ category = "Push",
+ event = event,
+ params = emptyMap(),
+ error = null,
+) {
+
+ data object PushNotificationOpened : Push(event = "Push Notification Opened")
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt
index de174fd193..212969481a 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt
@@ -11,7 +11,7 @@ sealed class SignIn(
error: Throwable? = null,
) : AnalyticsEvent("Sign In", event, params, error) {
- class ScreenOpened : SignIn(event = "Sing In Screen Opened")
+ class ScreenOpened : SignIn(event = "Sign In Screen Opened")
class ButtonBiometricSignIn : SignIn(event = "Button - Biometric Sign In")
class ButtonCardSignIn : SignIn(event = "Button - Card Sign In")
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt
index 6ea8b5b88f..d2870bbb6a 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt
@@ -12,11 +12,12 @@ internal sealed class WalletConnect(
) : AnalyticsEvent("Wallet Connect", event, params, error) {
class ScreenOpened : WalletConnect(event = "WC Screen Opened")
- class NewSessionEstablished(dAppName: String, dAppUrl: String) : WalletConnect(
+ class NewSessionEstablished(dAppName: String, dAppUrl: String, blockchainNames: List) : WalletConnect(
event = "New Session Established",
params = mapOf(
AnalyticsParam.DAPP_NAME to dAppName,
AnalyticsParam.DAPP_URL to dAppUrl,
+ AnalyticsParam.BLOCKCHAIN to blockchainNames.joinToString(","),
),
)
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt b/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt
index edc221250e..42a7f46c75 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt
@@ -9,7 +9,6 @@ import com.tangem.domain.wallets.builder.UserWalletIdBuilder
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.IntroductionProcess
-import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.extensions.inject
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.proxy.redux.DaggerGraphState
@@ -31,7 +30,7 @@ class CardContextInterceptor(
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean {
return when (event) {
- is IntroductionProcess.ButtonScanCard, is MainScreen.ButtonScanCard -> false
+ is IntroductionProcess.ButtonScanCard -> false
else -> true
}
}
diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt
deleted file mode 100644
index 08c1b72a81..0000000000
--- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.tangem.tap.common.extensions
-
-import com.tangem.blockchain.common.Blockchain
-import com.tangem.common.extensions.remove
-
-fun Blockchain.getNetworkStandardName(): String {
- return when (this) {
- Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20"
- Blockchain.BSC, Blockchain.BSCTestnet -> "BEP20"
- Blockchain.Binance, Blockchain.BinanceTestnet -> "BEP2"
- Blockchain.Tron, Blockchain.TronTestnet -> "TRC20"
- Blockchain.TON -> "TON"
- else -> ""
- }
-}
-
-val Blockchain.networkNameWithoutTestnet
- get() = this.getNetworkName().remove(" Testnet")
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/pushes/TangemPushNotificationService.kt b/app/src/main/java/com/tangem/tap/common/pushes/TangemPushNotificationService.kt
index 4a207104ca..c80f34373b 100644
--- a/app/src/main/java/com/tangem/tap/common/pushes/TangemPushNotificationService.kt
+++ b/app/src/main/java/com/tangem/tap/common/pushes/TangemPushNotificationService.kt
@@ -18,6 +18,7 @@ import com.google.firebase.messaging.RemoteMessage
import com.tangem.domain.common.LogConfig
import com.tangem.tap.MainActivity
import com.tangem.tap.common.images.createCoilImageLoader
+import com.tangem.tap.features.intentHandler.handlers.OnPushClickedIntentHandler
import com.tangem.wallet.R
import timber.log.Timber
@@ -37,6 +38,7 @@ internal class TangemPushNotificationService : FirebaseMessagingService() {
// TODO refactoring: [REDACTED_JIRA]
val intent = Intent(applicationContext, MainActivity::class.java)
+ intent.putExtra(OnPushClickedIntentHandler.IS_OPENED_FROM_PUSH, true)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(
/* context = */ this,
diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt
index c4366e8215..b8865305c5 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt
@@ -64,12 +64,16 @@ private fun handleAction(action: Action, appState: () -> AppState?) {
}
val cardProvider: () -> CardDTO? = { scanResponseProvider.invoke()?.card }
+ val buyService = makeBuyExchangeService(config)
+ val sellService = makeSellExchangeService(config)
val exchangeManager = CurrencyExchangeManager(
- buyService = makeBuyExchangeService(config),
- sellService = makeSellExchangeService(config),
+ buyService = buyService,
+ sellService = sellService,
primaryRules = CardExchangeRules(cardProvider),
)
// TODO: for refactoring (after remove old design refactor CurrencyExchangeManager and use 1 instance)
+ store.inject(DaggerGraphState::appStateHolder).buyService = buyService
+ store.inject(DaggerGraphState::appStateHolder).sellService = sellService
store.inject(DaggerGraphState::appStateHolder).exchangeService = exchangeManager
store.dispatchOnMain(GlobalAction.ExchangeManager.Init.Success(exchangeManager))
store.dispatchOnMain(GlobalAction.ExchangeManager.Update)
diff --git a/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt b/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt
index 7fe3ef0081..e189ec9e68 100644
--- a/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt
+++ b/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt
@@ -1,6 +1,7 @@
package com.tangem.tap.common.url
import android.content.Context
+import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
@@ -34,6 +35,8 @@ internal class CustomTabsUrlOpener : UrlOpener {
)
.build()
+ customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+
customTabsIntent.launchUrl(context, Uri.parse(url))
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/di/ActivityModule.kt b/app/src/main/java/com/tangem/tap/di/ActivityModule.kt
index c8d8c5c2bf..f6252946fb 100644
--- a/app/src/main/java/com/tangem/tap/di/ActivityModule.kt
+++ b/app/src/main/java/com/tangem/tap/di/ActivityModule.kt
@@ -1,15 +1,21 @@
package com.tangem.tap.di
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
+import com.tangem.datasource.exchangeservice.swap.SwapServiceLoader
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.exchange.RampStateManager
+import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
+import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
import com.tangem.tap.network.exchangeServices.DefaultRampManager
import com.tangem.tap.proxy.AppStateHolder
+import com.tangem.utils.Provider
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -39,8 +45,24 @@ internal object ActivityModule {
@Provides
@Singleton
- fun provideDefaultRampManager(appStateHolder: AppStateHolder): RampStateManager {
- return DefaultRampManager(appStateHolder.exchangeService)
+ fun provideDefaultRampManager(
+ appStateHolder: AppStateHolder,
+ swapServiceLoader: SwapServiceLoader,
+ currenciesRepository: CurrenciesRepository,
+ getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
+ excludedBlockchains: ExcludedBlockchains,
+ dispatchers: CoroutineDispatcherProvider,
+ ): RampStateManager {
+ return DefaultRampManager(
+ exchangeService = appStateHolder.exchangeService,
+ buyService = Provider { requireNotNull(appStateHolder.buyService) },
+ sellService = Provider { requireNotNull(appStateHolder.sellService) },
+ swapServiceLoader = swapServiceLoader,
+ currenciesRepository = currenciesRepository,
+ getNetworkCoinStatusUseCase = getNetworkCoinStatusUseCase,
+ excludedBlockchains = excludedBlockchains,
+ dispatchers = dispatchers,
+ )
}
@Provides
diff --git a/app/src/main/java/com/tangem/tap/di/TangemSdkModule.kt b/app/src/main/java/com/tangem/tap/di/TangemSdkModule.kt
new file mode 100644
index 0000000000..b2f2f6d5c5
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/di/TangemSdkModule.kt
@@ -0,0 +1,17 @@
+package com.tangem.tap.di
+
+import com.tangem.sdk.api.BackupServiceHolder
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+internal object TangemSdkModule {
+
+ @Provides
+ @Singleton
+ fun provideBackupServiceHolder(): BackupServiceHolder = BackupServiceHolder()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/di/data/CardDataModule.kt b/app/src/main/java/com/tangem/tap/di/data/CardDataModule.kt
index 66d63389c9..34411415bf 100644
--- a/app/src/main/java/com/tangem/tap/di/data/CardDataModule.kt
+++ b/app/src/main/java/com/tangem/tap/di/data/CardDataModule.kt
@@ -1,5 +1,6 @@
package com.tangem.tap.di.data
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.card.repository.DerivationsRepository
import com.tangem.sdk.api.TangemSdkManager
@@ -20,8 +21,9 @@ internal object CardDataModule {
fun providesDerivationsRepository(
tangemSdkManager: TangemSdkManager,
userWalletsStore: UserWalletsStore,
+ excludedBlockchains: ExcludedBlockchains,
dispatchers: CoroutineDispatcherProvider,
): DerivationsRepository {
- return DefaultDerivationsRepository(tangemSdkManager, userWalletsStore, dispatchers)
+ return DefaultDerivationsRepository(tangemSdkManager, userWalletsStore, excludedBlockchains, dispatchers)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt
index 12b071ad16..38adc6ec9e 100644
--- a/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt
+++ b/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.di.domain
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
diff --git a/app/src/main/java/com/tangem/tap/di/domain/OnrampDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/OnrampDomainModule.kt
new file mode 100644
index 0000000000..db4247ca10
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/di/domain/OnrampDomainModule.kt
@@ -0,0 +1,160 @@
+package com.tangem.tap.di.domain
+
+import com.tangem.domain.onramp.*
+import com.tangem.domain.onramp.repositories.OnrampErrorResolver
+import com.tangem.domain.onramp.repositories.OnrampRepository
+import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Suppress("TooManyFunctions")
+@Module
+@InstallIn(SingletonComponent::class)
+internal object OnrampDomainModule {
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampCurrenciesUseCase(onrampRepository: OnrampRepository): GetOnrampCurrenciesUseCase {
+ return GetOnrampCurrenciesUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideOnrampSaveDefaultCurrencyUseCase(onrampRepository: OnrampRepository): OnrampSaveDefaultCurrencyUseCase {
+ return OnrampSaveDefaultCurrencyUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampCountriesUseCase(onrampRepository: OnrampRepository): GetOnrampCountriesUseCase {
+ return GetOnrampCountriesUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampCountryUseCase(onrampRepository: OnrampRepository): GetOnrampCountryUseCase {
+ return GetOnrampCountryUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideOnrampSaveDefaultCountryUseCase(onrampRepository: OnrampRepository): OnrampSaveDefaultCountryUseCase {
+ return OnrampSaveDefaultCountryUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideCheckOnrampAvailabilityUseCase(onrampRepository: OnrampRepository): CheckOnrampAvailabilityUseCase {
+ return CheckOnrampAvailabilityUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampStatusUseCase(
+ onrampRepository: OnrampRepository,
+ onrampTransactionRepository: OnrampTransactionRepository,
+ onrampErrorResolver: OnrampErrorResolver,
+ ): GetOnrampStatusUseCase {
+ return GetOnrampStatusUseCase(
+ onrampRepository,
+ onrampTransactionRepository,
+ onrampErrorResolver,
+ )
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampCurrencyUseCase(onrampRepository: OnrampRepository): GetOnrampCurrencyUseCase {
+ return GetOnrampCurrencyUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampTransactionsUseCase(
+ onrampTransactionRepository: OnrampTransactionRepository,
+ ): GetOnrampTransactionsUseCase {
+ return GetOnrampTransactionsUseCase(onrampTransactionRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampTransactionUseCase(
+ onrampTransactionRepository: OnrampTransactionRepository,
+ ): GetOnrampTransactionUseCase {
+ return GetOnrampTransactionUseCase(onrampTransactionRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideOnrampRemoveTransactionUseCase(
+ onrampTransactionRepository: OnrampTransactionRepository,
+ ): OnrampRemoveTransactionUseCase {
+ return OnrampRemoveTransactionUseCase(onrampTransactionRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideOnrampSaveTransactionUseCase(
+ onrampTransactionRepository: OnrampTransactionRepository,
+ ): OnrampSaveTransactionUseCase {
+ return OnrampSaveTransactionUseCase(onrampTransactionRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampPaymentMethodsUseCase(onrampRepository: OnrampRepository): GetOnrampPaymentMethodsUseCase {
+ return GetOnrampPaymentMethodsUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideClearOnrampCacheUseCase(onrampRepository: OnrampRepository): ClearOnrampCacheUseCase {
+ return ClearOnrampCacheUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideOnrampFetchQuotesUseCase(onrampRepository: OnrampRepository): OnrampFetchQuotesUseCase {
+ return OnrampFetchQuotesUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampQuotesUseCase(onrampRepository: OnrampRepository): GetOnrampQuotesUseCase {
+ return GetOnrampQuotesUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampSelectedPaymentMethodUseCase(
+ onrampRepository: OnrampRepository,
+ ): GetOnrampSelectedPaymentMethodUseCase {
+ return GetOnrampSelectedPaymentMethodUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampProviderWithQuoteUseCase(
+ onrampRepository: OnrampRepository,
+ ): GetOnrampProviderWithQuoteUseCase {
+ return GetOnrampProviderWithQuoteUseCase(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideOnrampSaveSelectedPaymentMethod(onrampRepository: OnrampRepository): OnrampSaveSelectedPaymentMethod {
+ return OnrampSaveSelectedPaymentMethod(onrampRepository)
+ }
+
+ @Provides
+ @Singleton
+ fun provideGetOnrampRedirectUrlUseCase(
+ onrampRepository: OnrampRepository,
+ transactionRepository: OnrampTransactionRepository,
+ ): GetOnrampRedirectUrlUseCase {
+ return GetOnrampRedirectUrlUseCase(onrampRepository, transactionRepository)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt
index 8ec26eb230..9d42683053 100644
--- a/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt
+++ b/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt
@@ -133,14 +133,6 @@ internal object SettingsDomainModule {
return ShouldShowRingPromoUseCase(promoSettingsRepository)
}
- @Provides
- @Singleton
- fun provideShouldShowTravalaPromoWalletUseCase(
- promoSettingsRepository: PromoSettingsRepository,
- ): ShouldShowTravalaPromoWalletUseCase {
- return ShouldShowTravalaPromoWalletUseCase(promoSettingsRepository)
- }
-
@Provides
@Singleton
fun provideShouldShowSwapPromoTokenUseCase(
diff --git a/app/src/main/java/com/tangem/tap/di/domain/SwapDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/SwapDomainModule.kt
new file mode 100644
index 0000000000..e94429b646
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/di/domain/SwapDomainModule.kt
@@ -0,0 +1,23 @@
+package com.tangem.tap.di.domain
+
+import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
+import com.tangem.feature.swap.domain.api.SwapRepository
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+/**
+[REDACTED_AUTHOR]
+ */
+@Module
+@InstallIn(SingletonComponent::class)
+internal object SwapDomainModule {
+
+ @Provides
+ @Singleton
+ fun provideGetAvailablePairsUseCase(swapRepository: SwapRepository): GetAvailablePairsUseCase {
+ return GetAvailablePairsUseCase(swapRepository = swapRepository)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt
index 7e547182ce..9bea3ac624 100644
--- a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt
+++ b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt
@@ -7,7 +7,6 @@ import com.tangem.domain.tokens.*
import com.tangem.domain.tokens.repository.*
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.feature.swap.domain.api.SwapRepository
-import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
@@ -119,26 +118,26 @@ internal object TokensDomainModule {
currenciesRepository: CurrenciesRepository,
quotesRepository: QuotesRepository,
networksRepository: NetworksRepository,
- marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
swapRepository: SwapRepository,
currencyChecksRepository: CurrencyChecksRepository,
showSwapPromoTokenUseCase: ShouldShowSwapPromoTokenUseCase,
promoRepository: PromoRepository,
stakingRepository: StakingRepository,
dispatchers: CoroutineDispatcherProvider,
+ rampStateManager: RampStateManager,
): GetCurrencyWarningsUseCase {
return GetCurrencyWarningsUseCase(
walletManagersFacade = walletManagersFacade,
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
networksRepository = networksRepository,
- marketCryptoCurrencyRepository = marketCryptoCurrencyRepository,
currencyChecksRepository = currencyChecksRepository,
swapRepository = swapRepository,
showSwapPromoTokenUseCase = showSwapPromoTokenUseCase,
promoRepository = promoRepository,
stakingRepository = stakingRepository,
dispatchers = dispatchers,
+ rampStateManager = rampStateManager,
)
}
@@ -216,23 +215,19 @@ internal object TokensDomainModule {
fun provideGetCryptoCurrencyActionsUseCase(
rampStateManager: RampStateManager,
walletManagersFacade: WalletManagersFacade,
- marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
currenciesRepository: CurrenciesRepository,
quotesRepository: QuotesRepository,
networksRepository: NetworksRepository,
stakingRepository: StakingRepository,
- stakingFeatureToggles: StakingFeatureToggles,
dispatchers: CoroutineDispatcherProvider,
): GetCryptoCurrencyActionsUseCase {
return GetCryptoCurrencyActionsUseCase(
rampManager = rampStateManager,
walletManagersFacade = walletManagersFacade,
- marketCryptoCurrencyRepository = marketCryptoCurrencyRepository,
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
networksRepository = networksRepository,
stakingRepository = stakingRepository,
- stakingFeatureToggles = stakingFeatureToggles,
dispatchers = dispatchers,
)
}
diff --git a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt b/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt
index 45cc75e9da..f9e14a3a11 100644
--- a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt
@@ -1,6 +1,7 @@
package com.tangem.tap.domain.card
import com.tangem.blockchain.common.Blockchain
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.common.CompletionResult
import com.tangem.common.card.EllipticCurve
@@ -32,6 +33,7 @@ private typealias DerivedKeys = Map
internal class DefaultDerivationsRepository(
private val tangemSdkManager: TangemSdkManager,
private val userWalletsStore: UserWalletsStore,
+ private val excludedBlockchains: ExcludedBlockchains,
private val dispatchers: CoroutineDispatcherProvider,
) : DerivationsRepository {
@@ -49,6 +51,7 @@ internal class DefaultDerivationsRepository(
blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null,
extraDerivationPath = null,
scanResponse = userWallet.scanResponse,
+ excludedBlockchains = excludedBlockchains,
)
},
)
@@ -85,6 +88,7 @@ internal class DefaultDerivationsRepository(
blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null,
extraDerivationPath = extraDerivationPath,
scanResponse = userWallet.scanResponse,
+ excludedBlockchains = excludedBlockchains,
)
},
)
diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/CardScanningFeatureToggles.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/CardScanningFeatureToggles.kt
index 904cfe1673..59310f93b5 100644
--- a/app/src/main/java/com/tangem/tap/domain/scanCard/CardScanningFeatureToggles.kt
+++ b/app/src/main/java/com/tangem/tap/domain/scanCard/CardScanningFeatureToggles.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.domain.scanCard
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
/**
* Add custom token feature toggles
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt
index 1128c659f5..2885696de1 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt
@@ -7,6 +7,7 @@ import com.tangem.common.authentication.storage.AuthenticatedStorage
import com.tangem.common.json.TangemSdkAdapter
import com.tangem.common.services.secure.SecureStorage
import com.tangem.datasource.local.preferences.AppPreferencesStore
+import com.tangem.domain.models.scan.serialization.*
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.sdk.storage.AndroidSecureStorage
import com.tangem.sdk.storage.createEncryptedSharedPreferences
@@ -19,7 +20,6 @@ import com.tangem.tap.domain.userWalletList.repository.implementation.BiometricU
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultSelectedUserWalletRepository
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsPublicInformationRepository
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsSensitiveInformationRepository
-import com.tangem.tap.domain.userWalletList.utils.json.*
import com.tangem.tap.tangemSdkManager
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/ByteArrayListExtensions.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/ByteArrayListExtensions.kt
deleted file mode 100644
index fa3d2aefba..0000000000
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/ByteArrayListExtensions.kt
+++ /dev/null
@@ -1 +0,0 @@
-package com.tangem.tap.domain.userWalletList.utils
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/DefaultLegacyWalletConnectRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/DefaultLegacyWalletConnectRepository.kt
index 9e980da2ba..bcf6ba147c 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/DefaultLegacyWalletConnectRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/DefaultLegacyWalletConnectRepository.kt
@@ -267,7 +267,7 @@ internal class DefaultLegacyWalletConnectRepository(
)
}
- override fun approve(userNamespaces: Map>) {
+ override fun approve(userNamespaces: Map>, blockchainNames: List) {
val sessionProposal: Wallet.Model.SessionProposal = requireNotNull(this.sessionProposal)
val userChains = userNamespaces.flatMap { namespace ->
@@ -311,6 +311,7 @@ internal class DefaultLegacyWalletConnectRepository(
WalletConnect.NewSessionEstablished(
dAppName = sessionProposal.name,
dAppUrl = sessionProposal.url,
+ blockchainNames = blockchainNames,
),
)
},
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/di/WalletConnectInteractorModule.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/di/WalletConnectInteractorModule.kt
index cc4a3e16c4..9b7a44b10d 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/di/WalletConnectInteractorModule.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/di/WalletConnectInteractorModule.kt
@@ -3,7 +3,7 @@ package com.tangem.tap.domain.walletconnect2.di
import android.app.Application
import com.squareup.moshi.Moshi
import com.tangem.core.analytics.api.AnalyticsEventHandler
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.datasource.di.SdkMoshi
import com.tangem.datasource.files.FileReader
import com.tangem.domain.tokens.repository.CurrenciesRepository
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/LegacyWalletConnectRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/LegacyWalletConnectRepository.kt
index 616643a960..d755da5aea 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/LegacyWalletConnectRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/LegacyWalletConnectRepository.kt
@@ -21,7 +21,7 @@ interface LegacyWalletConnectRepository {
fun disconnect(topic: String)
- fun approve(userNamespaces: Map>)
+ fun approve(userNamespaces: Map>, blockchainNames: List)
fun reject()
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt
index 9d3e956799..e53938eaf6 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt
@@ -1,5 +1,6 @@
package com.tangem.tap.domain.walletconnect2.domain
+import arrow.core.flatten
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.toNetworkId
import com.tangem.domain.tokens.model.CryptoCurrency
@@ -236,8 +237,12 @@ class WalletConnectInteractor(
blockchainHelper.getNamespaceFromFullChainIdOrNull(account.chainId)
?.let { NetworkNamespace(it) }
}.filterNotNull()
+
+ val blockchainNames = blockchainHelper.chainIdsToBlockchains(userNamespaces.values.flatten().map { it.chainId })
+ .map { it.fullName }
walletConnectRepository.approve(
userNamespaces = userNamespaces,
+ blockchainNames = blockchainNames,
)
}
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/toggles/WalletConnectFeatureToggles.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/toggles/WalletConnectFeatureToggles.kt
index 26547d68e8..a6da04800a 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/toggles/WalletConnectFeatureToggles.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/toggles/WalletConnectFeatureToggles.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.domain.walletconnect2.toggles
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
internal class WalletConnectFeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt
index 06591c01b0..476bcd288d 100644
--- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt
@@ -37,5 +37,7 @@ sealed class WalletConnectAction : Action {
data class PerformRequestedAction(val sessionRequest: WcPreparedRequest) : WalletConnectAction()
data class PairConnectErrorAction(val throwable: Throwable) : WalletConnectAction()
+
+ data object UnsupportedDappRequest : WalletConnectAction()
//endregion WalletConnect 2.0
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt
index facfd60eab..fd477038f6 100644
--- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt
@@ -78,6 +78,12 @@ class WalletConnectMiddleware {
val index = action.wcUri.indexOf("@")
when (action.wcUri[index + 1]) {
'2' -> walletConnectRepository.pair(uri = action.wcUri)
+ '1' -> {
+ store.dispatchOnMain(WalletConnectAction.UnsupportedDappRequest)
+ store.dispatchOnMain(
+ GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedWcVersion),
+ )
+ }
}
}
is WalletConnectAction.RejectRequest -> {
diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt
index a7640ed758..1cf6c4da24 100644
--- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt
@@ -15,6 +15,7 @@ object WalletConnectReducer {
is WalletConnectAction.SessionEstablished,
is WalletConnectAction.SessionRejected,
is WalletConnectAction.PairConnectErrorAction,
+ is WalletConnectAction.UnsupportedDappRequest,
-> state.copy(loading = false)
is WalletConnectAction.SessionListUpdated -> state.copy(
wc2Sessions = action.sessions,
diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt
index d1a9368288..d557aa6910 100644
--- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt
@@ -82,6 +82,7 @@ data class WalletForSession(
}
sealed class WalletConnectDialog : StateDialog {
+ data object UnsupportedWcVersion : WalletConnectDialog()
data class ClipboardOrScanQr(val clipboardUri: String) : WalletConnectDialog()
data object UnsupportedCard : WalletConnectDialog()
data class UnsupportedNetwork(val networks: List? = null) : WalletConnectDialog()
diff --git a/app/src/main/java/com/tangem/tap/features/home/featuretoggles/HomeFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/home/featuretoggles/HomeFeatureToggles.kt
index ce8c0bcec3..55ebe3e10d 100644
--- a/app/src/main/java/com/tangem/tap/features/home/featuretoggles/HomeFeatureToggles.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/featuretoggles/HomeFeatureToggles.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.features.home.featuretoggles
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import javax.inject.Inject
class HomeFeatureToggles @Inject constructor(
diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/OnPushClickedIntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/OnPushClickedIntentHandler.kt
new file mode 100644
index 0000000000..e21d25ea54
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/OnPushClickedIntentHandler.kt
@@ -0,0 +1,24 @@
+package com.tangem.tap.features.intentHandler.handlers
+
+import android.content.Intent
+import com.tangem.core.analytics.api.AnalyticsEventHandler
+import com.tangem.tap.common.analytics.events.Push
+import com.tangem.tap.features.intentHandler.IntentHandler
+
+internal class OnPushClickedIntentHandler(val analyticsEventHandler: AnalyticsEventHandler) : IntentHandler {
+
+ override fun handleIntent(intent: Intent?, isFromForeground: Boolean): Boolean {
+ val fromPush = intent?.extras?.getBoolean(IS_OPENED_FROM_PUSH) ?: false
+
+ return if (fromPush) {
+ analyticsEventHandler.send(Push.PushNotificationOpened)
+ true
+ } else {
+ false
+ }
+ }
+
+ companion object {
+ const val IS_OPENED_FROM_PUSH = "IS_OPENED_FROM_PUSH"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt
index 444b2c6f89..d4f05a284a 100644
--- a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt
+++ b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt
@@ -17,7 +17,6 @@ import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
import com.tangem.domain.staking.FetchStakingTokensUseCase
import com.tangem.domain.wallets.legacy.UserWalletsListManager
-import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
import com.tangem.tap.common.extensions.setContext
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
import com.tangem.tap.features.main.model.MainScreenState
@@ -40,7 +39,6 @@ internal class MainViewModel @Inject constructor(
private val blockchainSDKFactory: BlockchainSDKFactory,
private val userWalletsListManager: UserWalletsListManager,
private val dispatchers: CoroutineDispatcherProvider,
- stakingFeatureToggles: StakingFeatureToggles,
private val fetchStakingTokensUseCase: FetchStakingTokensUseCase,
private val apiConfigsManager: ApiConfigsManager,
homeFeatureToggles: HomeFeatureToggles,
@@ -78,9 +76,7 @@ internal class MainViewModel @Inject constructor(
displayBalancesHidingStatusToast()
displayHiddenBalancesModalNotification()
- if (stakingFeatureToggles.isStakingEnabled) {
- fetchStakingTokens()
- }
+ fetchStakingTokens()
deleteDeprecatedLogsUseCase()
}
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt
index 2f18b059ca..5ff29dc0d4 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt
@@ -16,6 +16,7 @@ import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.settings.usercountry.models.UserCountry
import com.tangem.domain.wallets.builder.UserWalletBuilder
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Onboarding
@@ -23,8 +24,8 @@ import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.global.GlobalState
import com.tangem.tap.features.demo.DemoHelper
-import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
+import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction
import com.tangem.tap.features.saveWallet.redux.SaveWalletAction
import com.tangem.tap.mainScope
import com.tangem.tap.proxy.redux.DaggerGraphState
@@ -67,7 +68,10 @@ object OnboardingHelper {
fun whereToNavigate(scanResponse: ScanResponse): AppRoute {
if (store.inject(DaggerGraphState::onboardingV2FeatureToggles).isOnboardingV2Enabled) {
- return AppRoute.Onboarding(scanResponse)
+ return AppRoute.Onboarding(
+ scanResponse = scanResponse,
+ startFromBackup = false,
+ )
}
return when (val type = scanResponse.productType) {
@@ -88,6 +92,7 @@ object OnboardingHelper {
}
fun saveWallet(
+ alreadyCreatedWallet: UserWallet?,
scanResponse: ScanResponse,
accessCode: String? = null,
backupCardsIds: List? = null,
@@ -117,7 +122,7 @@ object OnboardingHelper {
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
// then open save wallet screen
tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen() -> {
- proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError)
+ proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
delay(timeMillis = 1_200)
@@ -131,7 +136,7 @@ object OnboardingHelper {
}
// If device has no biometry and save wallet screen has been shown, then go through old scenario
else -> {
- proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError)
+ proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
}
}
}
@@ -207,7 +212,9 @@ object OnboardingHelper {
fun handleTopUpAction(walletManager: WalletManager, scanResponse: ScanResponse, globalState: GlobalState) {
val blockchain = walletManager.wallet.blockchain
- val cryptoCurrency = CryptoCurrencyFactory().createCoin(
+ val excludedBlockchains = store.inject(DaggerGraphState::excludedBlockchains)
+
+ val cryptoCurrency = CryptoCurrencyFactory(excludedBlockchains).createCoin(
blockchain = blockchain,
extraDerivationPath = null,
scanResponse = scanResponse,
@@ -242,9 +249,10 @@ object OnboardingHelper {
scanResponse: ScanResponse,
backupCardsIds: List?,
hasBackupError: Boolean,
+ alreadyCreatedWallet: UserWallet? = null,
) {
val walletNameGenerateUseCase = store.inject(DaggerGraphState::generateWalletNameUseCase)
- val userWallet = UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
+ val userWallet = alreadyCreatedWallet ?: UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
.hasBackupError(hasBackupError)
.backupCardsIds(backupCardsIds?.toSet())
.build()
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt
index 58d13a9b0e..1c1ea6340e 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt
@@ -197,11 +197,11 @@ private fun handleWalletAction(action: Action) {
}
}
-private fun handleFinishBackup(scanResponse: ScanResponse) {
+private fun handleFinishBackup(scanResponse: ScanResponse, userWallet: UserWallet? = null) {
val backupState = store.state.onboardingWalletState.backupState
val updatedScanResponse = updateScanResponseAfterBackup(scanResponse, backupState)
- val userWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build()
+ val userWalletId = userWallet?.walletId ?: UserWalletIdBuilder.scanResponse(scanResponse).build()
if (backupState.hasRing && userWalletId != null) {
scope.launch {
store.inject(DaggerGraphState::walletsRepository).setHasWalletsWithRing(userWalletId = userWalletId)
@@ -209,6 +209,7 @@ private fun handleFinishBackup(scanResponse: ScanResponse) {
}
OnboardingHelper.saveWallet(
+ alreadyCreatedWallet = userWallet,
scanResponse = updatedScanResponse,
accessCode = backupState.accessCode,
backupCardsIds = backupState.backupCardIds,
@@ -679,7 +680,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
Analytics.send(Onboarding.Finished())
store.state.globalState.onboardingState.onboardingManager?.finishActivation(notActivatedCardIds)
- handleFinishBackup(requireNotNull(scanResponse))
+ handleFinishBackup(requireNotNull(scanResponse), userWallet)
delay(1000)
store.dispatchWithMain(BackupAction.BackupFinished(userWalletId = userWallet?.walletId))
}
@@ -740,6 +741,7 @@ private suspend fun createUserWallet(scanResponse: ScanResponse, backupState: Ba
return requireNotNull(
value = UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
.backupCardsIds(backupState.backupCardIds.toSet())
+ .hasBackupError(backupState.hasBackupError)
.build(),
lazyMessage = { "User wallet not created" },
)
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt
index b80aa53ebb..7f20094f7b 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt
@@ -272,6 +272,7 @@ class OnboardingWalletFragment :
onboardingManageTokensComponent = onboardingManageTokensComponentFactory.create(
context = onboardingComponentContext,
params = OnboardingManageTokensComponent.Params(userWalletId = userWalletId),
+ onDone = {},
)
}
diff --git a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt
index c8e093611d..2c7903ad60 100644
--- a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt
@@ -5,11 +5,11 @@ import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.guard
import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.Analytics
+import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
import com.tangem.domain.wallets.builder.UserWalletBuilder
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
-import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.extensions.dispatchNavigationAction
import com.tangem.tap.common.extensions.dispatchWithMain
@@ -110,7 +110,11 @@ internal class SaveWalletMiddleware {
// TODO: Remove after onboarding refactoring
Analytics.send(Onboarding.EnableBiometrics(AnalyticsParam.OnOffState.On))
} else {
- Analytics.send(MainScreen.EnableBiometrics(AnalyticsParam.OnOffState.On))
+ Analytics.send(
+ MainScreenAnalyticsEvent.EnableBiometrics(
+ state = com.tangem.core.analytics.models.AnalyticsParam.OnOffState.On,
+ ),
+ )
}
/*
@@ -148,7 +152,11 @@ internal class SaveWalletMiddleware {
// TODO: Remove after onboarding refactoring
Analytics.send(Onboarding.EnableBiometrics(AnalyticsParam.OnOffState.Off))
} else {
- Analytics.send(MainScreen.EnableBiometrics(AnalyticsParam.OnOffState.Off))
+ Analytics.send(
+ MainScreenAnalyticsEvent.EnableBiometrics(
+ com.tangem.core.analytics.models.AnalyticsParam.OnOffState.Off,
+ ),
+ )
}
}
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt
index a21351a6b9..be04d0a426 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt
@@ -55,11 +55,15 @@ object TradeCryptoMiddleware {
private fun proceedBuyAction(state: () -> AppState?, action: TradeCryptoAction.Buy) {
val isOnrampEnabled = store.inject(DaggerGraphState::onrampFeatureToggles).isFeatureEnabled
- if (isOnrampEnabled) proceedWithOnramp() else proceedWithLegacyBuyAction(state, action)
+ if (isOnrampEnabled) {
+ proceedWithOnramp(action.userWallet.walletId, action.cryptoCurrencyStatus.currency)
+ } else {
+ proceedWithLegacyBuyAction(state, action)
+ }
}
- private fun proceedWithOnramp() {
- store.dispatchNavigationAction { push(AppRoute.Onramp) }
+ private fun proceedWithOnramp(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency) {
+ store.dispatchNavigationAction { push(AppRoute.Onramp(userWalletId = userWalletId, currency = cryptoCurrency)) }
}
private fun proceedWithLegacyBuyAction(state: () -> AppState?, action: TradeCryptoAction.Buy) {
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt
index 520d262847..8cf25d7f82 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt
@@ -2,6 +2,7 @@ package com.tangem.tap.network.exchangeServices
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.data.common.currency.CryptoCurrencyFactory
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.tap.common.extensions.inject
@@ -10,9 +11,11 @@ import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import com.tangem.utils.converter.TwoWayConverter
-internal class CryptoCurrencyConverter : TwoWayConverter {
+internal class CryptoCurrencyConverter(
+ private val excludedBlockchains: ExcludedBlockchains,
+) : TwoWayConverter {
- private val cryptoCurrencyFactory by lazy { CryptoCurrencyFactory() }
+ private val cryptoCurrencyFactory by lazy { CryptoCurrencyFactory(excludedBlockchains) }
override fun convert(value: Currency): CryptoCurrency {
return when (value) {
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt
index 71c317e080..0e9092a1fa 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt
@@ -8,6 +8,8 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchain.extensions.Result
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
+import com.tangem.domain.core.utils.lceContent
+import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.model.CryptoCurrency
@@ -19,6 +21,8 @@ import com.tangem.tap.domain.model.Currency
import com.tangem.tap.features.demo.isDemoCard
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
import java.math.BigDecimal
/**
@@ -30,9 +34,19 @@ class CurrencyExchangeManager(
private val primaryRules: ExchangeRules,
) : ExchangeService {
+ override val initializationStatus: StateFlow
+ get() = _initializationStatus
+
+ private val _initializationStatus: MutableStateFlow =
+ MutableStateFlow(value = lceLoading())
+
override suspend fun update() {
+ _initializationStatus.value = lceLoading()
+
buyService.update()
sellService.update()
+
+ _initializationStatus.value = lceContent()
}
override fun isBuyAllowed(): Boolean = primaryRules.isBuyAllowed() && buyService.isBuyAllowed()
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt
index 904e22c80e..045c5f948e 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt
@@ -1,22 +1,128 @@
package com.tangem.tap.network.exchangeServices
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
+import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE
+import com.tangem.datasource.exchangeservice.swap.SwapServiceLoader
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
+import com.tangem.domain.tokens.model.CryptoCurrencyStatus
+import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
+import com.tangem.domain.tokens.repository.CurrenciesRepository
+import com.tangem.domain.wallets.models.UserWalletId
+import com.tangem.utils.Provider
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+import com.tangem.utils.isNullOrZero
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.withContext
-class DefaultRampManager(private val exchangeService: ExchangeService?) : RampStateManager {
+@Suppress("LongParameterList")
+internal class DefaultRampManager(
+ private val exchangeService: ExchangeService?,
+ private val buyService: Provider,
+ private val sellService: Provider,
+ private val swapServiceLoader: SwapServiceLoader,
+ private val currenciesRepository: CurrenciesRepository,
+ private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
+ private val dispatchers: CoroutineDispatcherProvider,
+ excludedBlockchains: ExcludedBlockchains,
+) : RampStateManager {
- private val cryptoCurrencyConverter = CryptoCurrencyConverter()
- override fun availableForBuy(scanResponse: ScanResponse, cryptoCurrency: CryptoCurrency): Boolean {
- return exchangeService?.availableForBuy(
- scanResponse,
- currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
- ) ?: false
- }
+ private val cryptoCurrencyConverter = CryptoCurrencyConverter(excludedBlockchains)
- override fun availableForSell(cryptoCurrency: CryptoCurrency): Boolean {
+ override fun isSellSupportedByService(cryptoCurrency: CryptoCurrency): Boolean {
return exchangeService?.availableForSell(
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
) ?: false
}
+
+ override fun availableForBuy(scanResponse: ScanResponse, cryptoCurrency: CryptoCurrency): Boolean {
+ return exchangeService?.availableForBuy(
+ scanResponse = scanResponse,
+ currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
+ ) ?: false
+ }
+
+ override suspend fun availableForSell(userWalletId: UserWalletId, status: CryptoCurrencyStatus): Boolean {
+ val sellSupportedByService = isSellSupportedByService(cryptoCurrency = status.currency)
+
+ if (!sellSupportedByService) return false
+
+ val reason = getSendUnavailabilityReason(userWalletId, status)
+
+ return reason == ScenarioUnavailabilityReason.None
+ }
+
+ override suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {
+ return getExchangeableFlag(userWalletId, cryptoCurrency) && !cryptoCurrency.isCustom
+ }
+
+ override fun getBuyInitializationStatus(): Flow {
+ return buyService.invoke().initializationStatus
+ }
+
+ override suspend fun fetchBuyServiceData() {
+ withContext(dispatchers.io) {
+ buyService.invoke().update()
+ }
+ }
+
+ override fun getSellInitializationStatus(): Flow {
+ return sellService.invoke().initializationStatus
+ }
+
+ override suspend fun fetchSellServiceData() {
+ withContext(dispatchers.io) {
+ sellService.invoke().update()
+ }
+ }
+
+ override fun getSwapInitializationStatus(userWalletId: UserWalletId): Flow {
+ return swapServiceLoader.getInitializationStatus(userWalletId)
+ }
+
+ private suspend fun getExchangeableFlag(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {
+ return withContext(dispatchers.io) {
+ val contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress
+ ?: EMPTY_CONTRACT_ADDRESS_VALUE
+
+ val asset = swapServiceLoader.getInitializationStatus(userWalletId).value.getOrNull()?.find {
+ it.network == cryptoCurrency.network.backendId &&
+ it.contractAddress.equals(contractAddress, ignoreCase = true)
+ }
+
+ asset?.exchangeAvailable ?: false
+ }
+ }
+
+ private suspend fun getSendUnavailabilityReason(
+ userWalletId: UserWalletId,
+ cryptoCurrencyStatus: CryptoCurrencyStatus,
+ ): ScenarioUnavailabilityReason {
+ val coinStatus = getNetworkCoinStatusUseCase.invokeSync(
+ userWalletId = userWalletId,
+ networkId = cryptoCurrencyStatus.currency.network.id,
+ derivationPath = cryptoCurrencyStatus.currency.network.derivationPath,
+ isSingleWalletWithTokens = false,
+ ).getOrNull()
+
+ return when {
+ cryptoCurrencyStatus.value.amount.isNullOrZero() -> {
+ ScenarioUnavailabilityReason.EmptyBalance(ScenarioUnavailabilityReason.WithdrawalScenario.SEND)
+ }
+ currenciesRepository.isSendBlockedByPendingTransactions(
+ cryptoCurrencyStatus = cryptoCurrencyStatus,
+ coinStatus = coinStatus,
+ ) -> {
+ ScenarioUnavailabilityReason.PendingTransaction(
+ withdrawalScenario = ScenarioUnavailabilityReason.WithdrawalScenario.SEND,
+ networkName = coinStatus?.currency?.network?.name.orEmpty(),
+ )
+ }
+ else -> {
+ ScenarioUnavailabilityReason.None
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt
index 495bcec410..e49b386c9d 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt
@@ -1,8 +1,14 @@
package com.tangem.tap.network.exchangeServices
+import com.tangem.domain.core.lce.Lce
+import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.tap.domain.model.Currency
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+typealias ExchangeServiceInitializationStatus = Lce
interface Exchanger {
fun isBuyAllowed(): Boolean
@@ -12,10 +18,17 @@ interface Exchanger {
}
interface ExchangeService : Exchanger, ExchangeUrlBuilder {
+
+ val initializationStatus: StateFlow
+
suspend fun update()
companion object {
fun dummy(): ExchangeService = object : ExchangeService {
+
+ override val initializationStatus: StateFlow =
+ MutableStateFlow(value = lceLoading())
+
override suspend fun update() {}
override fun isBuyAllowed(): Boolean = false
override fun isSellAllowed(): Boolean = false
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoBlockchainMapping.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoBlockchainMapping.kt
index 946d2afce1..9a930fdf76 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoBlockchainMapping.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoBlockchainMapping.kt
@@ -138,6 +138,8 @@ internal val Blockchain.mercuryoNetwork: String?
Blockchain.CasperTestnet -> null
Blockchain.Core -> null
Blockchain.CoreTestnet -> null
+ Blockchain.Chiliz -> null
+ Blockchain.ChilizTestnet -> null
Blockchain.Unknown -> null
Blockchain.Xodex -> null
Blockchain.Canxium -> null
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoService.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoService.kt
index 50b558907b..bd46579044 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoService.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/mercuryo/MercuryoService.kt
@@ -6,12 +6,19 @@ import com.tangem.common.extensions.calculateSha512
import com.tangem.common.extensions.toHexString
import com.tangem.common.services.Result
import com.tangem.common.services.performRequest
+import com.tangem.domain.core.utils.lceContent
+import com.tangem.domain.core.utils.lceError
+import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.tap.domain.model.Currency
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import com.tangem.tap.network.exchangeServices.ExchangeService
+import com.tangem.tap.network.exchangeServices.ExchangeServiceInitializationStatus
import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import timber.log.Timber
import java.util.concurrent.CopyOnWriteArrayList
/**
@@ -19,10 +26,34 @@ import java.util.concurrent.CopyOnWriteArrayList
*/
internal class MercuryoService(private val environment: MercuryoEnvironment) : ExchangeService {
+ override val initializationStatus: StateFlow
+ get() = _initializationStatus
+
+ private val _initializationStatus: MutableStateFlow =
+ MutableStateFlow(value = lceLoading())
+
private val api: MercuryoApi = environment.mercuryoApi
private val availableMercuryoCurrencies = CopyOnWriteArrayList()
+ override suspend fun update() {
+ Timber.i("Start updating")
+ _initializationStatus.value = lceLoading()
+
+ val result = performRequest { api.currencies(environment.apiVersion) }
+ when {
+ result is Result.Success && result.data.status == RESPONSE_SUCCESS_STATUS_CODE -> {
+ handleSuccessfullyUpdatedData(data = result.data.data)
+ }
+ result is Result.Failure -> {
+ availableMercuryoCurrencies.clear()
+
+ Timber.e("Failed to load currencies", result.error)
+ _initializationStatus.value = result.error.lceError()
+ }
+ }
+ }
+
override fun isBuyAllowed(): Boolean = true
override fun isSellAllowed(): Boolean = false
@@ -42,18 +73,6 @@ internal class MercuryoService(private val environment: MercuryoEnvironment) : E
override fun availableForSell(currency: Currency): Boolean = false
- override suspend fun update() {
- val result = performRequest { api.currencies(environment.apiVersion) }
- when {
- result is Result.Success && result.data.status == RESPONSE_SUCCESS_STATUS_CODE -> {
- handleSuccessfullyUpdatedData(data = result.data.data)
- }
- result is Result.Failure -> {
- availableMercuryoCurrencies.clear()
- }
- }
- }
-
override fun getUrl(
action: CurrencyExchangeManager.Action,
cryptoCurrency: CryptoCurrency,
@@ -89,6 +108,9 @@ internal class MercuryoService(private val environment: MercuryoEnvironment) : E
private fun handleSuccessfullyUpdatedData(data: MercuryoCurrenciesResponse.Data) {
availableMercuryoCurrencies.clear()
availableMercuryoCurrencies.addAll(data.config.cryptoCurrencies)
+
+ Timber.i("Successfully updated")
+ _initializationStatus.value = lceContent()
}
private fun signature(address: String) = (address + environment.secret).calculateSha512().toHexString().lowercase()
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt
index 26b26f0b61..90011a2d77 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt
@@ -7,13 +7,20 @@ import com.tangem.common.services.Result
import com.tangem.common.services.performRequest
import com.tangem.datasource.api.common.createRetrofitInstance
import com.tangem.domain.common.extensions.withIOContext
+import com.tangem.domain.core.utils.lceContent
+import com.tangem.domain.core.utils.lceError
+import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.tap.domain.model.Currency
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import com.tangem.tap.network.exchangeServices.ExchangeService
+import com.tangem.tap.network.exchangeServices.ExchangeServiceInitializationStatus
import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder.Companion.SCHEME
import com.tangem.tap.network.exchangeServices.moonpay.models.MoonPayAvailableCurrency
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import timber.log.Timber
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
@@ -23,6 +30,12 @@ class MoonPayService(
private val logEnabled: Boolean,
) : ExchangeService {
+ override val initializationStatus: StateFlow
+ get() = _initializationStatus
+
+ private val _initializationStatus: MutableStateFlow =
+ MutableStateFlow(value = lceLoading())
+
private val api: MoonPayApi by lazy {
createRetrofitInstance(
baseUrl = MoonPayApi.MOOONPAY_BASE_URL,
@@ -34,14 +47,25 @@ class MoonPayService(
override suspend fun update() {
withIOContext {
+ Timber.i("Start updating")
+ _initializationStatus.value = lceLoading()
+
performRequest {
val userStatus = when (val result = performRequest { api.getUserStatus(apiKey) }) {
- is Result.Failure -> return@performRequest
+ is Result.Failure -> {
+ Timber.e("Failed to load user status", result.error)
+ _initializationStatus.value = result.error.lceError()
+ return@performRequest
+ }
is Result.Success -> result.data
}
val currencies = when (val result = performRequest { api.getCurrencies(apiKey) }) {
- is Result.Failure -> return@performRequest
+ is Result.Failure -> {
+ Timber.e("Failed to load currencies", result.error)
+ _initializationStatus.value = result.error.lceError()
+ return@performRequest
+ }
is Result.Success -> result.data
}
@@ -58,6 +82,8 @@ class MoonPayService(
)
}
+ Timber.i("Successfully updated")
+ _initializationStatus.value = lceContent()
status = MoonPayStatus(currenciesToSell, userStatus, currencies)
}
}
diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonpayBlockchainMapping.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonpayBlockchainMapping.kt
index fb01fff927..bce26d7a6a 100644
--- a/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonpayBlockchainMapping.kt
+++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonpayBlockchainMapping.kt
@@ -43,6 +43,7 @@ internal val Blockchain.moonPaySupportedCurrency: MoonPaySupportedCurrency?
Filecoin -> MoonPaySupportedCurrency(networkCode = "filecoin", currencyCode = "fil")
Sui -> MoonPaySupportedCurrency(networkCode = "sui", currencyCode = "sui")
Core -> MoonPaySupportedCurrency(networkCode = "core", currencyCode = "core")
+ Chiliz -> MoonPaySupportedCurrency(networkCode = "ethereum", currencyCode = "chz")
ArbitrumTestnet -> null
AvalancheTestnet -> null
BinanceTestnet -> null
@@ -139,6 +140,7 @@ internal val Blockchain.moonPaySupportedCurrency: MoonPaySupportedCurrency?
Casper -> null
CasperTestnet -> null
CoreTestnet -> null
+ ChilizTestnet -> null
Unknown -> null
Xodex -> null
Canxium -> null
diff --git a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt
index f626aa4238..18c616034a 100644
--- a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt
@@ -1,6 +1,5 @@
package com.tangem.tap.proxy
-import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.redux.StateDialog
@@ -26,10 +25,8 @@ class AppStateHolder @Inject constructor() : ReduxStateHolder {
var mainStore: Store? = null
var tangemSdkManager: TangemSdkManager? = null
var exchangeService: ExchangeService? = null
-
- fun getActualCard(): CardDTO? {
- return scanResponse?.card
- }
+ var buyService: ExchangeService? = null
+ var sellService: ExchangeService? = null
override fun dispatch(action: Action) {
mainStore?.dispatch(action)
diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt
index 075686701f..6827cc546c 100644
--- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt
@@ -2,6 +2,7 @@ package com.tangem.tap.proxy.redux
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.common.routing.AppRouter
import com.tangem.core.navigation.share.ShareManager
import com.tangem.core.navigation.url.UrlOpener
@@ -71,4 +72,5 @@ data class DaggerGraphState(
val onrampFeatureToggles: OnrampFeatureToggles? = null,
val environmentConfigStorage: EnvironmentConfigStorage? = null,
val onboardingV2FeatureToggles: OnboardingV2FeatureToggles? = null,
+ val excludedBlockchains: ExcludedBlockchains? = null,
) : StateType
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/routing/impl/DefaultRoutingComponent.kt b/app/src/main/java/com/tangem/tap/routing/impl/DefaultRoutingComponent.kt
index c3cd524d98..77283b4c75 100644
--- a/app/src/main/java/com/tangem/tap/routing/impl/DefaultRoutingComponent.kt
+++ b/app/src/main/java/com/tangem/tap/routing/impl/DefaultRoutingComponent.kt
@@ -27,7 +27,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
override val stack: Value> = childStack(
source = navigationProvider.getOrCreateTyped(),
- serializer = AppRoute.serializer(),
+ serializer = AppRoute.serializer(), // TODO Maybe set this to null for AppRoute.Onboarding case. Need to check
initialConfiguration = getInitialRoute(),
handleBackButton = false,
childFactory = ::child,
diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt
index b031d03e46..59331b1445 100644
--- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt
+++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt
@@ -11,10 +11,8 @@ import com.tangem.features.disclaimer.api.components.DisclaimerComponent
import com.tangem.features.managetokens.component.ManageTokensComponent
import com.tangem.features.managetokens.component.ManageTokensSource
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
-import com.tangem.features.onramp.component.BuyCryptoComponent
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
-import com.tangem.features.onramp.component.OnrampComponent
-import com.tangem.features.onramp.component.SellCryptoComponent
+import com.tangem.features.onramp.component.*
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.staking.api.navigation.StakingRouter
@@ -51,8 +49,10 @@ internal class ChildFactory @Inject constructor(
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
private val onrampComponentFactory: OnrampComponent.Factory,
+ private val onrampSuccessComponentFactory: OnrampSuccessComponent.Factory,
private val buyCryptoComponentFactory: BuyCryptoComponent.Factory,
private val sellCryptoComponentFactory: SellCryptoComponent.Factory,
+ private val swapSelectTokensComponentFactory: SwapSelectTokensComponent.Factory,
private val onboardingEntryComponentFactory: OnboardingEntryComponent.Factory,
private val sendRouter: SendRouter,
private val tokenDetailsRouter: TokenDetailsRouter,
@@ -197,10 +197,17 @@ internal class ChildFactory @Inject constructor(
is AppRoute.Onramp -> {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),
- params = OnrampComponent.Params(),
+ params = OnrampComponent.Params(userWalletId = route.userWalletId, cryptoCurrency = route.currency),
componentFactory = onrampComponentFactory,
)
}
+ is AppRoute.OnrampSuccess -> {
+ route.asComponentChild(
+ contextProvider = contextProvider(route, contextFactory),
+ params = OnrampSuccessComponent.Params(route.txId),
+ componentFactory = onrampSuccessComponentFactory,
+ )
+ }
is AppRoute.BuyCrypto -> {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),
@@ -215,10 +222,20 @@ internal class ChildFactory @Inject constructor(
componentFactory = sellCryptoComponentFactory,
)
}
+ is AppRoute.SwapCrypto -> {
+ route.asComponentChild(
+ contextProvider = contextProvider(route, contextFactory),
+ params = SwapSelectTokensComponent.Params(userWalletId = route.userWalletId),
+ componentFactory = swapSelectTokensComponentFactory,
+ )
+ }
is AppRoute.Onboarding -> {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),
- params = OnboardingEntryComponent.Params(route.scanResponse),
+ params = OnboardingEntryComponent.Params(
+ scanResponse = route.scanResponse,
+ startBackupFlow = route.startFromBackup,
+ ),
componentFactory = onboardingEntryComponentFactory,
)
}
diff --git a/app/src/test/kotlin/com/tangem/tap/domain/card/CryptoCurrenciesMocks.kt b/app/src/test/kotlin/com/tangem/tap/domain/card/CryptoCurrenciesMocks.kt
index b44074274b..3ff9b7bf0e 100644
--- a/app/src/test/kotlin/com/tangem/tap/domain/card/CryptoCurrenciesMocks.kt
+++ b/app/src/test/kotlin/com/tangem/tap/domain/card/CryptoCurrenciesMocks.kt
@@ -3,6 +3,7 @@ package com.tangem.tap.domain.card
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.FeePaidCurrency
import com.tangem.blockchain.common.Token
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.blockchainsdk.utils.toNetworkId
import com.tangem.data.common.currency.CryptoCurrencyFactory
import com.tangem.data.common.currency.getNetworkDerivationPath
@@ -17,7 +18,7 @@ import com.tangem.domain.tokens.model.Network
*/
internal class CryptoCurrenciesMocks(private val scanResponse: ScanResponse) {
- private val factory = CryptoCurrencyFactory()
+ private val factory = CryptoCurrencyFactory(excludedBlockchains = ExcludedBlockchains())
val cardano by lazy { listOf(createCoin(blockchain = Blockchain.Cardano)) }
val chia by lazy { listOf(element = createCoin(Blockchain.Chia)) }
diff --git a/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt b/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt
index 93a58d5ba5..095156e1c2 100644
--- a/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt
+++ b/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt
@@ -2,6 +2,7 @@ package com.tangem.tap.domain.card
import android.annotation.SuppressLint
import com.google.common.truth.Truth
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.common.CompletionResult
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.card.ScanCardException
@@ -29,6 +30,7 @@ internal class DefaultDerivationsRepositoryTest {
tangemSdkManager = tangemSdkManager,
userWalletsStore = userWalletsStore,
dispatchers = TestingCoroutineDispatcherProvider(),
+ excludedBlockchains = ExcludedBlockchains(),
)
private val defaultUserWalletId = UserWalletId("011")
diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt
index 6744b6c0be..fc52efb20d 100644
--- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt
+++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt
@@ -219,16 +219,24 @@ sealed class AppRoute(val path: String) : Route {
@Serializable
data class Swap(
- val currency: CryptoCurrency,
+ val currencyFrom: CryptoCurrency,
+ val currencyTo: CryptoCurrency? = null,
val userWalletId: UserWalletId,
val isInitialReverseOrder: Boolean = false,
- ) : AppRoute(path = "/swap/${currency.id.value}/${userWalletId.stringValue}/$isInitialReverseOrder"),
+ ) : AppRoute(
+ path = "/swap" +
+ "/${currencyFrom.id.value}" +
+ "/${currencyTo?.id?.value}" +
+ "/${userWalletId.stringValue}" +
+ "/$isInitialReverseOrder",
+ ),
RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
- const val CURRENCY_BUNDLE_KEY = "currency"
+ const val CURRENCY_FROM_KEY = "currencyFrom"
+ const val CURRENCY_TO_KEY = "currencyTo"
const val USER_WALLET_ID_KEY = "userWalletId"
const val IS_INITIAL_REVERSE_ORDER = "isInitialReverseOrder"
}
@@ -287,7 +295,19 @@ sealed class AppRoute(val path: String) : Route {
}
@Serializable
- data object Onramp : AppRoute(path = "/onramp")
+ data class Onramp(
+ val userWalletId: UserWalletId,
+ val currency: CryptoCurrency,
+ ) : AppRoute(path = "/onramp/${userWalletId.stringValue}/${currency.symbol}"), RouteBundleParams {
+ override fun getBundle(): Bundle = bundle(serializer())
+ }
+
+ @Serializable
+ data class OnrampSuccess(
+ val txId: String,
+ ) : AppRoute(path = "/onramp/success/$txId"), RouteBundleParams {
+ override fun getBundle(): Bundle = bundle(serializer())
+ }
@Serializable
data class BuyCrypto(
@@ -299,6 +319,15 @@ sealed class AppRoute(val path: String) : Route {
val userWalletId: UserWalletId,
) : AppRoute(path = "/sell_crypto/${userWalletId.stringValue}")
+ @Serializable
+ data class SwapCrypto(
+ val userWalletId: UserWalletId,
+ ) : AppRoute(path = "/swap_crypto/${userWalletId.stringValue}")
+
// Onboarding V2
- data class Onboarding(val scanResponse: ScanResponse) : AppRoute(path = "/onboarding_v2")
+ @Serializable
+ data class Onboarding(
+ val scanResponse: ScanResponse,
+ val startFromBackup: Boolean,
+ ) : AppRoute(path = "/onboarding_v2${if (startFromBackup) "/backup" else ""}")
}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/bottomsheet/permission/GiveTxPermisssionBottomSheet.kt b/common/ui/src/main/java/com/tangem/common/ui/bottomsheet/permission/GiveTxPermisssionBottomSheet.kt
index 5d8b37fd46..4f4e74d559 100644
--- a/common/ui/src/main/java/com/tangem/common/ui/bottomsheet/permission/GiveTxPermisssionBottomSheet.kt
+++ b/common/ui/src/main/java/com/tangem/common/ui/bottomsheet/permission/GiveTxPermisssionBottomSheet.kt
@@ -31,10 +31,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.containers.FooterContainer
import com.tangem.core.ui.components.inputrow.InputRowDefault
-import com.tangem.core.ui.extensions.TextReference
-import com.tangem.core.ui.extensions.resolveReference
-import com.tangem.core.ui.extensions.resourceReference
-import com.tangem.core.ui.extensions.wrappedList
+import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import kotlinx.collections.immutable.ImmutableList
@@ -118,7 +115,7 @@ private fun GiveTxPermissionBottomSheetContent(content: GiveTxPermissionBottomSh
@Composable
private fun ApprovalBottomSheetInfo(data: GiveTxPermissionState.ReadyForRequest) {
FooterContainer(
- footer = stringResource(id = R.string.give_permission_policy_type_footer),
+ footer = resourceReference(R.string.give_permission_policy_type_footer),
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16),
) {
AmountItem(
@@ -130,7 +127,7 @@ private fun ApprovalBottomSheetInfo(data: GiveTxPermissionState.ReadyForRequest)
}
SpacerH16()
FooterContainer(
- footer = data.footerText.resolveReference(),
+ footer = data.footerText,
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16),
) {
FeeItem(fee = data.fee)
diff --git a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressStatusBlock.kt b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressStatusBlock.kt
new file mode 100644
index 0000000000..cdf3f1f8fb
--- /dev/null
+++ b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressStatusBlock.kt
@@ -0,0 +1,228 @@
+package com.tangem.common.ui.expressStatus
+
+import androidx.annotation.DrawableRes
+import androidx.compose.animation.*
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.common.ui.R
+import com.tangem.common.ui.expressStatus.state.ExpressLinkUM
+import com.tangem.common.ui.expressStatus.state.ExpressStatusItemState
+import com.tangem.common.ui.expressStatus.state.ExpressStatusItemUM
+import com.tangem.common.ui.expressStatus.state.ExpressStatusUM
+import com.tangem.core.ui.components.SpacerWMax
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import kotlinx.collections.immutable.persistentListOf
+
+/**
+ * Block with express statuses
+ *
+ * @param state ui holder
+ * @param modifier modifier
+ * @see [Figma](https://www.figma.com/design/Vs6SkVsFnUPsSCNwlnVf5U/Android-%E2%80%93-UI?node-id=18459-26521&t=4jox7bfqUiXnm2h1-4)
+ */
+@Composable
+fun ExpressStatusBlock(state: ExpressStatusUM, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier
+ .clip(TangemTheme.shapes.roundedCornersXMedium)
+ .background(TangemTheme.colors.background.action)
+ .padding(
+ vertical = TangemTheme.dimens.spacing14,
+ horizontal = TangemTheme.dimens.spacing12,
+ ),
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .padding(bottom = TangemTheme.dimens.spacing16),
+ ) {
+ Text(
+ text = state.title.resolveReference(),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ SpacerWMax()
+ AnimatedVisibility(visible = state.link is ExpressLinkUM.Content) {
+ val link = remember(this) { state.link as ExpressLinkUM.Content }
+ Row(
+ modifier = Modifier.clickable { link.onClick() },
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Icon(
+ painter = painterResource(id = link.icon),
+ contentDescription = null,
+ tint = TangemTheme.colors.icon.informative,
+ modifier = Modifier
+ .size(TangemTheme.dimens.spacing16)
+ .padding(end = TangemTheme.dimens.spacing2),
+ )
+ Text(
+ text = link.text.resolveReference(),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+ }
+ }
+
+ Column {
+ state.statuses.forEachIndexed { index, item ->
+ ExpressStatusStep(item, index == state.statuses.lastIndex)
+ }
+ }
+ }
+}
+
+@Composable
+private fun ExpressStatusStep(status: ExpressStatusItemUM, isLast: Boolean) {
+ AnimatedContent(
+ targetState = status,
+ label = "Exchange Step Change Success",
+ transitionSpec = {
+ fadeIn(tween(durationMillis = 220)) togetherWith
+ fadeOut(tween(durationMillis = 220))
+ },
+ ) { content ->
+ Row {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ when (content.state) {
+ ExpressStatusItemState.Active -> StepInProgress()
+ ExpressStatusItemState.Default -> StepDefault()
+ ExpressStatusItemState.Done -> Step(
+ iconRes = R.drawable.ic_check_24,
+ iconColor = TangemTheme.colors.icon.primary1,
+ borderColor = TangemTheme.colors.field.focused,
+ )
+ ExpressStatusItemState.Error -> Step(
+ iconRes = R.drawable.ic_close_24,
+ iconColor = TangemTheme.colors.icon.warning,
+ )
+ ExpressStatusItemState.Warning -> Step(
+ iconRes = R.drawable.ic_close_24,
+ iconColor = TangemTheme.colors.icon.attention,
+ )
+ }
+ if (!isLast) {
+ StepSeparator()
+ }
+ }
+ val textColor = when (status.state) {
+ ExpressStatusItemState.Active -> TangemTheme.colors.text.primary1
+ ExpressStatusItemState.Default -> TangemTheme.colors.text.disabled
+ ExpressStatusItemState.Done -> TangemTheme.colors.text.primary1
+ ExpressStatusItemState.Error -> TangemTheme.colors.text.warning
+ ExpressStatusItemState.Warning -> TangemTheme.colors.text.attention
+ }
+ Text(
+ text = content.text.resolveReference(),
+ style = TangemTheme.typography.body2,
+ color = textColor,
+ modifier = Modifier
+ .padding(start = TangemTheme.dimens.spacing12),
+ )
+ }
+ }
+}
+
+@Composable
+private fun StepDefault() {
+ Box(
+ modifier = Modifier
+ .size(TangemTheme.dimens.size20)
+ .border(
+ width = TangemTheme.dimens.size1_5,
+ color = TangemTheme.colors.field.focused,
+ shape = CircleShape,
+ )
+ .padding(TangemTheme.dimens.spacing2),
+ )
+}
+
+@Composable
+private fun Step(iconColor: Color, @DrawableRes iconRes: Int, borderColor: Color = iconColor) {
+ Icon(
+ painter = painterResource(id = iconRes),
+ contentDescription = null,
+ tint = iconColor,
+ modifier = Modifier
+ .size(TangemTheme.dimens.size20)
+ .border(
+ width = TangemTheme.dimens.size1_5,
+ color = borderColor,
+ shape = CircleShape,
+ )
+ .padding(TangemTheme.dimens.spacing2),
+ )
+}
+
+@Composable
+private fun StepInProgress() {
+ CircularProgressIndicator(
+ color = TangemTheme.colors.icon.primary1,
+ strokeWidth = TangemTheme.dimens.size2,
+ modifier = Modifier
+ .padding(TangemTheme.dimens.spacing2)
+ .size(TangemTheme.dimens.size14),
+ )
+}
+
+@Composable
+private fun StepSeparator() {
+ Box(
+ modifier = Modifier
+ .padding(vertical = TangemTheme.dimens.spacing2)
+ .size(
+ width = TangemTheme.dimens.size1_5,
+ height = TangemTheme.dimens.size10,
+ )
+ .background(
+ color = TangemTheme.colors.field.focused,
+ shape = CircleShape,
+ ),
+ )
+}
+
+@Preview
+@Composable
+private fun Preview_ExchangeStatusBlock() {
+ val state = ExpressStatusUM(
+ title = resourceReference(R.string.express_exchange_status_title),
+ link = ExpressLinkUM.Content(
+ icon = R.drawable.ic_alert_24,
+ text = resourceReference(R.string.common_go_to_provider),
+ onClick = {},
+ ),
+ statuses = persistentListOf(
+ ExpressStatusItemUM(text = stringReference("Done"), state = ExpressStatusItemState.Done),
+ ExpressStatusItemUM(text = stringReference("Active"), state = ExpressStatusItemState.Active),
+ ExpressStatusItemUM(text = stringReference("Warning"), state = ExpressStatusItemState.Warning),
+ ExpressStatusItemUM(text = stringReference("Error"), state = ExpressStatusItemState.Error),
+ ExpressStatusItemUM(text = stringReference("Default"), state = ExpressStatusItemState.Default),
+ ),
+ )
+
+ TangemThemePreview {
+ ExpressStatusBlock(state = state)
+ }
+}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressStatusNotificationBlock.kt b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressStatusNotificationBlock.kt
new file mode 100644
index 0000000000..58693f2e00
--- /dev/null
+++ b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressStatusNotificationBlock.kt
@@ -0,0 +1,32 @@
+package com.tangem.common.ui.expressStatus
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.tangem.common.ui.notifications.ExpressNotificationsUM
+import com.tangem.common.ui.notifications.NotificationUM
+import com.tangem.core.ui.components.notifications.Notification
+import com.tangem.core.ui.res.TangemTheme
+
+@Composable
+fun ExpressStatusNotificationBlock(state: NotificationUM?) {
+ AnimatedVisibility(
+ visible = state?.config != null,
+ modifier = Modifier.padding(top = 12.dp),
+ label = "Express Status Notification Change",
+ ) {
+ val wrappedNotification = remember(this) { requireNotNull(state?.config) }
+ Notification(
+ config = wrappedNotification,
+ iconTint = when (state) {
+ is ExpressNotificationsUM.NeedVerification -> TangemTheme.colors.icon.attention
+ is ExpressNotificationsUM.FailedByProvider -> TangemTheme.colors.icon.warning
+ else -> null
+ },
+ containerColor = TangemTheme.colors.background.action,
+ )
+ }
+}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/state/ExpressStatusUM.kt b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/state/ExpressStatusUM.kt
new file mode 100644
index 0000000000..6fcb02cc30
--- /dev/null
+++ b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/state/ExpressStatusUM.kt
@@ -0,0 +1,54 @@
+package com.tangem.common.ui.expressStatus.state
+
+import androidx.annotation.DrawableRes
+import androidx.compose.runtime.Stable
+import com.tangem.core.ui.extensions.TextReference
+import kotlinx.collections.immutable.ImmutableList
+
+/**
+ * UI data holder for express status block
+ *
+ * @property title block title
+ * @property link provider web link
+ * @property statuses list of possible and active statuses
+ */
+data class ExpressStatusUM(
+ val title: TextReference,
+ val link: ExpressLinkUM,
+ val statuses: ImmutableList,
+)
+
+/**
+ * Provider web link for express status block.
+ * [Empty] if no link needed
+ * [Content] if link is provided and displayed
+ */
+@Stable
+sealed class ExpressLinkUM {
+ data object Empty : ExpressLinkUM()
+ data class Content(
+ @DrawableRes val icon: Int,
+ val text: TextReference,
+ val onClick: () -> Unit,
+ ) : ExpressLinkUM()
+}
+
+/**
+ * Single status item in express status block
+ */
+data class ExpressStatusItemUM(
+ val text: TextReference,
+ val state: ExpressStatusItemState,
+)
+
+/**
+ * Available status states for express status block
+ */
+enum class ExpressStatusItemState {
+ Active,
+ Default,
+ Done,
+ Warning,
+ Error,
+ ;
+}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/notifications/ExpressNotificationsUM.kt b/common/ui/src/main/java/com/tangem/common/ui/notifications/ExpressNotificationsUM.kt
new file mode 100644
index 0000000000..09c66ed8c8
--- /dev/null
+++ b/common/ui/src/main/java/com/tangem/common/ui/notifications/ExpressNotificationsUM.kt
@@ -0,0 +1,28 @@
+package com.tangem.common.ui.notifications
+
+import com.tangem.common.ui.R
+import com.tangem.core.ui.components.notifications.NotificationConfig
+import com.tangem.core.ui.extensions.resourceReference
+
+object ExpressNotificationsUM {
+
+ data class NeedVerification(val onGoToProviderClick: () -> Unit) : NotificationUM.Warning(
+ title = resourceReference(R.string.express_exchange_notification_verification_title),
+ subtitle = resourceReference(R.string.express_exchange_notification_verification_text),
+ iconResId = R.drawable.ic_alert_triangle_20,
+ buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
+ text = resourceReference(R.string.common_go_to_provider),
+ onClick = onGoToProviderClick,
+ ),
+ )
+
+ data class FailedByProvider(val onGoToProviderClick: () -> Unit) : NotificationUM.Error(
+ title = resourceReference(R.string.express_exchange_notification_failed_title),
+ subtitle = resourceReference(R.string.express_exchange_notification_failed_text),
+ iconResId = R.drawable.ic_alert_circle_24,
+ buttonState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
+ text = resourceReference(R.string.common_go_to_provider),
+ onClick = onGoToProviderClick,
+ ),
+ )
+}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt
index 858fdccb46..83636c2a98 100644
--- a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt
+++ b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt
@@ -9,6 +9,7 @@ import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.format.bigdecimal.shorted
+import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import java.math.BigDecimal
sealed class NotificationUM(val config: NotificationConfig) {
@@ -307,4 +308,17 @@ sealed class NotificationUM(val config: NotificationConfig) {
),
)
}
+
+ sealed interface Solana {
+
+ data class RentInfo(
+ private val rentInfo: CryptoCurrencyWarning.Rent,
+ ) : Info(
+ title = TextReference.Res(R.string.warning_rent_fee_title),
+ subtitle = TextReference.Res(
+ id = R.string.warning_solana_rent_fee_message,
+ formatArgs = wrappedList(rentInfo.rent, rentInfo.exemptionAmount),
+ ),
+ )
+ }
}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt
index ae4993d6ce..62e5cb7ed4 100644
--- a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt
+++ b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt
@@ -5,6 +5,7 @@ import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIco
import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.core.ui.components.marketprice.utils.PriceChangeConverter
import com.tangem.core.ui.components.token.state.TokenItemState
+import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.format.bigdecimal.percent
@@ -39,8 +40,8 @@ class TokenItemStateConverter(
private val fiatAmountStateProvider: (CryptoCurrencyStatus) -> TokenItemState.FiatAmountState? = {
createFiatAmountState(it, appCurrency)
},
- private val onItemClick: (CryptoCurrencyStatus) -> Unit,
- private val onItemLongClick: ((CryptoCurrencyStatus) -> Unit)? = null,
+ private val onItemClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
+ private val onItemLongClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
) : Converter {
override fun convert(value: CryptoCurrencyStatus): TokenItemState {
@@ -75,9 +76,11 @@ class TokenItemStateConverter(
subtitleState = requireNotNull(subtitleStateProvider(this)),
fiatAmountState = requireNotNull(fiatAmountStateProvider(this)),
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = getFormattedAmount()),
- onItemClick = { onItemClick(this) },
- onItemLongClick = onItemLongClick?.let {
- { it(this) }
+ onItemClick = onItemClick?.let { onItemClick ->
+ { onItemClick(it, this) }
+ },
+ onItemLongClick = onItemLongClick?.let { onItemLongClick ->
+ { onItemLongClick(it, this) }
},
)
}
@@ -94,9 +97,11 @@ class TokenItemStateConverter(
iconState = iconStateProvider(this),
titleState = titleStateProvider(this),
subtitleState = subtitleStateProvider(this),
- onItemClick = { onItemClick(this) },
- onItemLongClick = onItemLongClick?.let {
- { it(this) }
+ onItemClick = onItemClick?.let { onItemClick ->
+ { onItemClick(it, this) }
+ },
+ onItemLongClick = onItemLongClick?.let { onItemLongClick ->
+ { onItemLongClick(it, this) }
},
)
}
@@ -107,8 +112,8 @@ class TokenItemStateConverter(
iconState = iconStateProvider(this),
titleState = titleStateProvider(this),
subtitleState = subtitleStateProvider(this),
- onItemLongClick = onItemLongClick?.let {
- { it(this) }
+ onItemLongClick = onItemLongClick?.let { onItemLongClick ->
+ { onItemLongClick(it, this) }
},
)
}
@@ -122,7 +127,7 @@ class TokenItemStateConverter(
is CryptoCurrencyStatus.Unreachable,
is CryptoCurrencyStatus.NoAmount,
-> {
- TokenItemState.TitleState.Content(text = currencyStatus.currency.name)
+ TokenItemState.TitleState.Content(text = stringReference(currencyStatus.currency.name))
}
is CryptoCurrencyStatus.Loaded,
is CryptoCurrencyStatus.Custom,
@@ -130,7 +135,7 @@ class TokenItemStateConverter(
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.TitleState.Content(
- text = currencyStatus.currency.name,
+ text = stringReference(currencyStatus.currency.name),
hasPending = value.hasCurrentNetworkTransactions,
)
}
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 b646142403..ce733b8c51 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
@@ -76,6 +76,9 @@ sealed class AnalyticsParam {
data object MyWallets : ScreensSources("My Wallets")
data object Token : ScreensSources("Token")
data object Stories : ScreensSources("Stories")
+ data object Buy : ScreensSources("Buy")
+ data object Swap : ScreensSources("Swap")
+ data object Sell : ScreensSources("Sell")
}
sealed class TxSentFrom(val value: String) {
@@ -161,6 +164,12 @@ sealed class AnalyticsParam {
}
}
+ enum class Status(val value: String) {
+ Success(value = "Success"),
+ Error(value = "Error"),
+ Pending(value = "Pending"),
+ }
+
companion object Key {
const val BLOCKCHAIN = "blockchain"
const val TOKEN_PARAM = "Token"
diff --git a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/event/MainScreenAnalyticsEvent.kt b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/event/MainScreenAnalyticsEvent.kt
new file mode 100644
index 0000000000..02c1a6d4c0
--- /dev/null
+++ b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/event/MainScreenAnalyticsEvent.kt
@@ -0,0 +1,75 @@
+package com.tangem.core.analytics.models.event
+
+import com.tangem.core.analytics.models.AnalyticsEvent
+import com.tangem.core.analytics.models.AnalyticsParam
+import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
+
+/**
+ * Main screen analytics event
+ *
+ * @param event event name
+ * @param params params
+ */
+sealed class MainScreenAnalyticsEvent(
+ event: String,
+ params: Map = mapOf(),
+) : AnalyticsEvent(category = "Main Screen", event = event, params = params) {
+
+ class EnableBiometrics(state: AnalyticsParam.OnOffState) : MainScreenAnalyticsEvent(
+ event = "Enable Biometric",
+ params = mapOf("State" to state.value),
+ )
+
+ // region Action Buttons feature
+ data class ButtonBuy(val status: AnalyticsParam.Status) : MainScreenAnalyticsEvent(
+ event = "Button - Buy",
+ params = mapOf(AnalyticsParam.STATUS to status.value),
+ )
+
+ data class ButtonSwap(val status: AnalyticsParam.Status) : MainScreenAnalyticsEvent(
+ event = "Button - Swap",
+ params = mapOf(AnalyticsParam.STATUS to status.value),
+ )
+
+ data class ButtonSell(val status: AnalyticsParam.Status) : MainScreenAnalyticsEvent(
+ event = "Button - Sell",
+ params = mapOf(AnalyticsParam.STATUS to status.value),
+ )
+
+ data object BuyScreenOpened : MainScreenAnalyticsEvent(event = "Buy Screen Opened")
+
+ data object SwapScreenOpened : MainScreenAnalyticsEvent(event = "Swap Screen Opened")
+
+ data object SellScreenOpened : MainScreenAnalyticsEvent(event = "Sell Screen Opened")
+
+ data class BuyTokenClicked(val currencySymbol: String) : MainScreenAnalyticsEvent(
+ event = "Buy Token Clicked",
+ params = mapOf(TOKEN_PARAM to currencySymbol),
+ )
+
+ data class SellTokenClicked(val currencySymbol: String) : MainScreenAnalyticsEvent(
+ event = "Sell Token Clicked",
+ params = mapOf(TOKEN_PARAM to currencySymbol),
+ )
+
+ data class SwapTokenClicked(val currencySymbol: String) : MainScreenAnalyticsEvent(
+ event = "Swap Token Clicked",
+ params = mapOf(TOKEN_PARAM to currencySymbol),
+ )
+
+ data class ReceiveTokenClicked(val currencySymbol: String) : MainScreenAnalyticsEvent(
+ event = "Receive Token Clicked",
+ params = mapOf(TOKEN_PARAM to currencySymbol),
+ )
+
+ data class RemoveTokenClicked(val currencySymbol: String) : MainScreenAnalyticsEvent(
+ event = "Remove Button Clicked",
+ params = mapOf(TOKEN_PARAM to currencySymbol),
+ )
+
+ data class ButtonClose(val source: AnalyticsParam.ScreensSources) : MainScreenAnalyticsEvent(
+ event = "Button - Close",
+ params = mapOf(AnalyticsParam.SOURCE to source.value),
+ )
+ // endregion
+}
\ No newline at end of file
diff --git a/core/featuretoggles/.gitignore b/core/config-toggles/.gitignore
similarity index 100%
rename from core/featuretoggles/.gitignore
rename to core/config-toggles/.gitignore
diff --git a/core/featuretoggles/build.gradle.kts b/core/config-toggles/build.gradle.kts
similarity index 94%
rename from core/featuretoggles/build.gradle.kts
rename to core/config-toggles/build.gradle.kts
index 410ef17d0e..0a7bc83fdc 100644
--- a/core/featuretoggles/build.gradle.kts
+++ b/core/config-toggles/build.gradle.kts
@@ -7,7 +7,7 @@ plugins {
}
android {
- namespace = "com.tangem.core.featuretoggles"
+ namespace = "com.tangem.core.configtoggle"
}
dependencies {
diff --git a/core/config-toggles/src/main/assets/configs/excluded_blockchains_config.json b/core/config-toggles/src/main/assets/configs/excluded_blockchains_config.json
new file mode 100644
index 0000000000..4113610e04
--- /dev/null
+++ b/core/config-toggles/src/main/assets/configs/excluded_blockchains_config.json
@@ -0,0 +1,10 @@
+[
+ {
+ "name": "",
+ "version": "undefined"
+ },
+ {
+ "name": "NEXA",
+ "version": "undefined"
+ }
+]
\ No newline at end of file
diff --git a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
similarity index 84%
rename from core/featuretoggles/src/main/assets/configs/feature_toggles_config.json
rename to core/config-toggles/src/main/assets/configs/feature_toggles_config.json
index 2751047561..f7af0b38fc 100644
--- a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json
+++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
@@ -7,10 +7,6 @@
"name": "WC_SOLANA_TX_SIGN_ENABLED",
"version": "5.18.0"
},
- {
- "name": "STAKING_ENABLED",
- "version": "5.15.0"
- },
{
"name": "IS_ETHEREUM_EIP_1559_ENABLED",
"version": "5.17.0"
@@ -25,7 +21,7 @@
},
{
"name": "MAIN_ACTION_BUTTONS_ENABLED",
- "version": "undefined"
+ "version": "5.19.0"
},
{
"name": "ONBOARDING_CODE_REFACTORING_ENABLED",
diff --git a/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/ExcludedBlockchainsManager.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/ExcludedBlockchainsManager.kt
new file mode 100644
index 0000000000..f5db3637b9
--- /dev/null
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/ExcludedBlockchainsManager.kt
@@ -0,0 +1,8 @@
+package com.tangem.core.configtoggle.blockchain
+
+interface ExcludedBlockchainsManager {
+
+ val excludedBlockchainsIds: Set
+
+ suspend fun init()
+}
\ No newline at end of file
diff --git a/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/MutableExcludedBlockchainsManager.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/MutableExcludedBlockchainsManager.kt
new file mode 100644
index 0000000000..1f7fcf4dc0
--- /dev/null
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/MutableExcludedBlockchainsManager.kt
@@ -0,0 +1,10 @@
+package com.tangem.core.configtoggle.blockchain
+
+interface MutableExcludedBlockchainsManager : ExcludedBlockchainsManager {
+
+ suspend fun excludeBlockchain(mainnetId: String, isExcluded: Boolean)
+
+ fun isMatchLocalConfig(): Boolean
+
+ suspend fun recoverLocalConfig()
+}
\ No newline at end of file
diff --git a/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/impl/DefaultExcludedBlockchainsManager.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/impl/DefaultExcludedBlockchainsManager.kt
new file mode 100644
index 0000000000..d0f1dccc44
--- /dev/null
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/blockchain/impl/DefaultExcludedBlockchainsManager.kt
@@ -0,0 +1,74 @@
+package com.tangem.core.configtoggle.blockchain.impl
+
+import com.tangem.core.configtoggle.blockchain.MutableExcludedBlockchainsManager
+import com.tangem.core.configtoggle.storage.TogglesStorage
+import com.tangem.core.configtoggle.utils.associateToggles
+import com.tangem.core.configtoggle.version.VersionProvider
+import com.tangem.datasource.local.preferences.AppPreferencesStore
+import com.tangem.datasource.local.preferences.PreferencesKeys
+import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
+import com.tangem.datasource.local.preferences.utils.store
+
+internal class DefaultExcludedBlockchainsManager(
+ private val localTogglesStorage: TogglesStorage,
+ private val appPreferencesStore: AppPreferencesStore,
+ private val versionProvider: VersionProvider,
+) : MutableExcludedBlockchainsManager {
+
+ private var isInitialized: Boolean = false
+
+ private lateinit var currentExcludedBlockchainsIds: Set
+ private lateinit var localExcludedBlockchainsIds: Set
+
+ override val excludedBlockchainsIds: Set
+ get() {
+ if (!isInitialized) error("ExcludedBlockchainsManager is not initialized")
+
+ return currentExcludedBlockchainsIds
+ }
+
+ override suspend fun init() {
+ localTogglesStorage.populate(path = "configs/excluded_blockchains_config")
+
+ val storedExcludedBlockchainsIds = appPreferencesStore.getSyncOrDefault(
+ key = PreferencesKeys.EXCLUDED_BLOCKCHAINS_KEY,
+ default = emptySet(),
+ )
+
+ localExcludedBlockchainsIds = localTogglesStorage.toggles
+ .associateToggles(currentVersion = versionProvider.get().orEmpty())
+ .filterValues { isIncluded -> !isIncluded }
+ .keys
+
+ currentExcludedBlockchainsIds = localExcludedBlockchainsIds + storedExcludedBlockchainsIds
+
+ isInitialized = true
+ }
+
+ override suspend fun excludeBlockchain(mainnetId: String, isExcluded: Boolean) {
+ if (isExcluded) {
+ currentExcludedBlockchainsIds += mainnetId
+ } else {
+ currentExcludedBlockchainsIds -= mainnetId
+ }
+
+ storeCurrent()
+ }
+
+ override fun isMatchLocalConfig(): Boolean {
+ return currentExcludedBlockchainsIds == localExcludedBlockchainsIds
+ }
+
+ override suspend fun recoverLocalConfig() {
+ currentExcludedBlockchainsIds = localExcludedBlockchainsIds
+
+ storeCurrent()
+ }
+
+ private suspend fun storeCurrent() {
+ appPreferencesStore.store(
+ PreferencesKeys.EXCLUDED_BLOCKCHAINS_KEY,
+ currentExcludedBlockchainsIds,
+ )
+ }
+}
\ No newline at end of file
diff --git a/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/di/ExcludedBlockchainsManagerModule.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/di/ExcludedBlockchainsManagerModule.kt
new file mode 100644
index 0000000000..2e4fcddac5
--- /dev/null
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/di/ExcludedBlockchainsManagerModule.kt
@@ -0,0 +1,49 @@
+package com.tangem.core.configtoggle.di
+
+import android.content.Context
+import com.tangem.core.configtoggle.BuildConfig
+import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
+import com.tangem.core.configtoggle.blockchain.MutableExcludedBlockchainsManager
+import com.tangem.core.configtoggle.blockchain.impl.DefaultExcludedBlockchainsManager
+import com.tangem.core.configtoggle.storage.LocalTogglesStorage
+import com.tangem.core.configtoggle.version.DefaultVersionProvider
+import com.tangem.datasource.asset.loader.AssetLoader
+import com.tangem.datasource.local.preferences.AppPreferencesStore
+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 object ExcludedBlockchainsManagerModule {
+
+ @Provides
+ @Singleton
+ fun provideExcludedBlockchainsManager(
+ @ApplicationContext context: Context,
+ assetLoader: AssetLoader,
+ appPreferencesStore: AppPreferencesStore,
+ ): ExcludedBlockchainsManager {
+ val localTogglesStorage = LocalTogglesStorage(assetLoader)
+ val versionProvider = DefaultVersionProvider(context)
+
+ return DefaultExcludedBlockchainsManager(
+ localTogglesStorage,
+ appPreferencesStore,
+ versionProvider,
+ )
+ }
+
+ @Provides
+ @Singleton
+ fun provideMutableExcludedBlockchainsManager(
+ manager: ExcludedBlockchainsManager,
+ ): MutableExcludedBlockchainsManager? {
+ if (!BuildConfig.TESTER_MENU_ENABLED) return null
+
+ return manager as MutableExcludedBlockchainsManager
+ }
+}
\ No newline at end of file
diff --git a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/di/FeatureTogglesManagerModule.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/di/FeatureTogglesManagerModule.kt
similarity index 62%
rename from core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/di/FeatureTogglesManagerModule.kt
rename to core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/di/FeatureTogglesManagerModule.kt
index ca45c78a6b..8346378b52 100644
--- a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/di/FeatureTogglesManagerModule.kt
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/di/FeatureTogglesManagerModule.kt
@@ -1,12 +1,12 @@
-package com.tangem.core.featuretoggle.di
+package com.tangem.core.configtoggle.di
import android.content.Context
-import com.tangem.core.featuretoggle.manager.DevFeatureTogglesManager
-import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
-import com.tangem.core.featuretoggle.manager.ProdFeatureTogglesManager
-import com.tangem.core.featuretoggle.storage.LocalFeatureTogglesStorage
-import com.tangem.core.featuretoggle.version.DefaultVersionProvider
-import com.tangem.core.featuretoggles.BuildConfig
+import com.tangem.core.configtoggle.BuildConfig
+import com.tangem.core.configtoggle.feature.FeatureTogglesManager
+import com.tangem.core.configtoggle.feature.impl.DevFeatureTogglesManager
+import com.tangem.core.configtoggle.feature.impl.ProdFeatureTogglesManager
+import com.tangem.core.configtoggle.storage.LocalTogglesStorage
+import com.tangem.core.configtoggle.version.DefaultVersionProvider
import com.tangem.datasource.asset.loader.AssetLoader
import com.tangem.datasource.local.preferences.AppPreferencesStore
import dagger.Module
@@ -27,18 +27,18 @@ internal object FeatureTogglesManagerModule {
assetLoader: AssetLoader,
appPreferencesStore: AppPreferencesStore,
): FeatureTogglesManager {
- val localFeatureTogglesStorage = LocalFeatureTogglesStorage(assetLoader)
+ val localTogglesStorage = LocalTogglesStorage(assetLoader)
val versionProvider = DefaultVersionProvider(context)
return if (BuildConfig.TESTER_MENU_ENABLED) {
DevFeatureTogglesManager(
- localFeatureTogglesStorage = localFeatureTogglesStorage,
+ localTogglesStorage = localTogglesStorage,
appPreferencesStore = appPreferencesStore,
versionProvider = versionProvider,
)
} else {
ProdFeatureTogglesManager(
- localFeatureTogglesStorage = localFeatureTogglesStorage,
+ localTogglesStorage = localTogglesStorage,
versionProvider = versionProvider,
)
}
diff --git a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/FeatureTogglesManager.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/FeatureTogglesManager.kt
similarity index 86%
rename from core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/FeatureTogglesManager.kt
rename to core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/FeatureTogglesManager.kt
index 6111e7f73b..86a027924c 100644
--- a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/FeatureTogglesManager.kt
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/FeatureTogglesManager.kt
@@ -1,4 +1,4 @@
-package com.tangem.core.featuretoggle.manager
+package com.tangem.core.configtoggle.feature
/**
* Component for getting information about the availability of feature toggles
diff --git a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/MutableFeatureTogglesManager.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/MutableFeatureTogglesManager.kt
similarity index 92%
rename from core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/MutableFeatureTogglesManager.kt
rename to core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/MutableFeatureTogglesManager.kt
index f04b423f4f..d1d09ced03 100644
--- a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/MutableFeatureTogglesManager.kt
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/MutableFeatureTogglesManager.kt
@@ -1,4 +1,4 @@
-package com.tangem.core.featuretoggle.manager
+package com.tangem.core.configtoggle.feature
/**
* Component for change information about the availability of feature toggles
diff --git a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/DevFeatureTogglesManager.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/impl/DevFeatureTogglesManager.kt
similarity index 81%
rename from core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/DevFeatureTogglesManager.kt
rename to core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/impl/DevFeatureTogglesManager.kt
index 303dce3c7b..750dbada43 100644
--- a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/manager/DevFeatureTogglesManager.kt
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/feature/impl/DevFeatureTogglesManager.kt
@@ -1,9 +1,10 @@
-package com.tangem.core.featuretoggle.manager
+package com.tangem.core.configtoggle.feature.impl
import androidx.annotation.VisibleForTesting
-import com.tangem.core.featuretoggle.storage.FeatureTogglesStorage
-import com.tangem.core.featuretoggle.utils.associateToggles
-import com.tangem.core.featuretoggle.version.VersionProvider
+import com.tangem.core.configtoggle.feature.MutableFeatureTogglesManager
+import com.tangem.core.configtoggle.storage.TogglesStorage
+import com.tangem.core.configtoggle.utils.associateToggles
+import com.tangem.core.configtoggle.version.VersionProvider
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
@@ -13,12 +14,12 @@ import kotlin.properties.Delegates
/**
* Feature toggles manager implementation in DEV build
*
- * @property localFeatureTogglesStorage local feature toggles storage
+ * @property localTogglesStorage local feature toggles storage
* @property appPreferencesStore application local store
* @property versionProvider application version provider
*/
internal class DevFeatureTogglesManager(
- private val localFeatureTogglesStorage: FeatureTogglesStorage,
+ private val localTogglesStorage: TogglesStorage,
private val appPreferencesStore: AppPreferencesStore,
private val versionProvider: VersionProvider,
) : MutableFeatureTogglesManager {
@@ -27,13 +28,13 @@ internal class DevFeatureTogglesManager(
private var localFeatureTogglesMap: Map by Delegates.notNull()
override suspend fun init() {
- localFeatureTogglesStorage.init()
+ localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
val savedFeatureToggles = appPreferencesStore.getObjectSyncOrNull