diff --git a/app/src/androidTest/kotlin/com/tangem/tests/FeedbackTest.kt b/app/src/androidTest/kotlin/com/tangem/tests/FeedbackTest.kt index 7db589cb4a..528a6535fb 100644 --- a/app/src/androidTest/kotlin/com/tangem/tests/FeedbackTest.kt +++ b/app/src/androidTest/kotlin/com/tangem/tests/FeedbackTest.kt @@ -8,6 +8,7 @@ import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.clickAndWaitFor import com.tangem.common.extensions.clickWithAssertion import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.domain.card.ScanFailsRequester import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import com.tangem.scenarios.checkFailedTransactionDialog @@ -28,16 +29,19 @@ import com.tangem.screens.onStoriesScreen import com.tangem.screens.onTokenDetailsScreen import com.tangem.screens.onMainScreenTopBar import com.tangem.tap.domain.sdk.mocks.MockProvider -import com.tangem.tap.store import dagger.hilt.android.testing.HiltAndroidTest import io.qameta.allure.kotlin.AllureId import io.qameta.allure.kotlin.junit4.DisplayName import org.junit.Ignore import org.junit.Test +import javax.inject.Inject @HiltAndroidTest class FeedbackTest : BaseTestCase() { + @Inject + lateinit var scanFailsRequester: ScanFailsRequester + @AllureId("894") @DisplayName("Send feedback: from details") @Test @@ -177,9 +181,8 @@ class FeedbackTest : BaseTestCase() { } step("Force show 'Scan warning' dialog"){ runOnUiThread { - val requester = store.state.daggerGraphState.scanFailsRequester!! MainScope().launch { - requester.show(AnalyticsParam.ScreensSources.Main) + scanFailsRequester.show(AnalyticsParam.ScreensSources.Main) } } } diff --git a/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt b/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt index 0798bcf8cf..63dcc8eeee 100644 --- a/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt +++ b/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt @@ -7,12 +7,12 @@ import androidx.lifecycle.LifecycleOwner import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager import com.tangem.common.routing.AppRoute +import com.tangem.common.routing.AppRouter import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.wallets.hot.HotWalletPasswordRequester import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase import com.tangem.tap.LockTimerWorker.Companion.TAG -import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.utils.logging.TangemLogger import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job @@ -30,6 +30,7 @@ internal class LockUserWalletsTimer( private val coroutineScope: CoroutineScope, private val clearAllHotWalletContextualUnlockUseCase: ClearAllHotWalletContextualUnlockUseCase, private val passwordRequester: HotWalletPasswordRequester, + private val appRouter: AppRouter, ) : LifecycleOwner by context as LifecycleOwner, DefaultLifecycleObserver { @@ -57,7 +58,7 @@ internal class LockUserWalletsTimer( if (shouldOpenWelcomeScreenOnResume) { passwordRequester.dismiss() clearAllHotWalletContextualUnlockUseCase.invoke() - store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } + appRouter.replaceAll(AppRoute.Welcome()) settingsRepository.setShouldOpenWelcomeScreenOnResume(value = false) } } @@ -121,7 +122,7 @@ internal class LockUserWalletsTimer( .onRight { passwordRequester.dismiss() clearAllHotWalletContextualUnlockUseCase.invoke() - store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } + appRouter.replaceAll(AppRoute.Welcome()) } } } diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 364671d88f..7172772521 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -28,6 +28,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import arrow.core.getOrElse +import com.tangem.common.routing.AppRouter import com.tangem.common.routing.deeplink.DeeplinkConst.WEBLINK_KEY import com.tangem.common.routing.deeplink.PayloadToDeeplinkConverter import com.tangem.core.analytics.api.AnalyticsEventHandler @@ -39,7 +40,6 @@ import com.tangem.core.navigation.url.UrlOpener import com.tangem.data.balancehiding.DefaultDeviceFlipDetector import com.tangem.data.card.sdk.CardSdkOwner import com.tangem.domain.apptheme.model.AppThemeMode -import com.tangem.domain.card.ScanCardUseCase import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.common.wallets.UserWalletsListRepository @@ -61,7 +61,6 @@ import com.tangem.tap.common.analytics.events.Push import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler import com.tangem.tap.features.main.MainViewModel -import com.tangem.tap.proxy.redux.DaggerGraphAction import com.tangem.tap.routing.component.RoutingComponent import com.tangem.tap.routing.configurator.AppRouterConfig import com.tangem.tap.routing.utils.DeepLinkFactory @@ -104,9 +103,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { @Inject lateinit var injectedTangemSdkManager: TangemSdkManager - @Inject - lateinit var scanCardUseCase: ScanCardUseCase - @Inject lateinit var settingsRepository: SettingsRepository @@ -123,6 +119,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { @Inject internal lateinit var appRouterConfig: AppRouterConfig + @Inject + internal lateinit var appRouter: AppRouter + @Inject internal lateinit var routingComponentFactory: RoutingComponent.Factory @@ -269,13 +268,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { userWalletsListRepository = userWalletsListRepository, clearAllHotWalletContextualUnlockUseCase = clearAllHotWalletContextualUnlockUseCase, passwordRequester = passwordRequester, - ) - - store.dispatch( - DaggerGraphAction.SetActivityDependencies( - scanCardUseCase = scanCardUseCase, - cardSdkConfigRepository = cardSdkConfigRepository, - ), + appRouter = appRouter, ) } diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index 46f0aff6cb..ba43027039 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -79,6 +79,8 @@ import org.rekotlin.Store lateinit var store: Store +lateinit var walletsRepository: WalletsRepository + val foregroundActivityObserver = ForegroundActivityObserver open class TangemApplication : Application(), ImageLoaderFactory, Configuration.Provider { @@ -129,9 +131,6 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration. val getAppThemeModeUseCase: GetAppThemeModeUseCase get() = entryPoint.getGetAppThemeModeUseCase() - private val walletsRepository: WalletsRepository - get() = entryPoint.getWalletsRepository() - private val oneTimeEventFilter: OneTimeEventFilter get() = entryPoint.getOneTimeEventFilter() @@ -276,6 +275,8 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration. } fun init() { + walletsRepository = entryPoint.getWalletsRepository() + apiConfigsManager.initialize() store = createReduxStore() 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 5b5902f3cc..24e95b0b93 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 @@ -10,10 +10,8 @@ import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.models.scan.ProductType import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.builder.UserWalletIdBuilder -import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.demo.DemoHelper -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store +import com.tangem.tap.walletsRepository import kotlinx.coroutines.runBlocking /** @@ -23,8 +21,6 @@ class CardContextInterceptor( private val scanResponse: ScanResponse, ) : ParamsInterceptor { - private val walletsRepository = store.inject(DaggerGraphState::walletsRepository) - private val userWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build() override fun id(): String = CardContextInterceptor.id() diff --git a/app/src/main/java/com/tangem/tap/di/TangemSdkManagerModule.kt b/app/src/main/java/com/tangem/tap/di/TangemSdkManagerModule.kt index cca1b670ed..61da4b0ea5 100644 --- a/app/src/main/java/com/tangem/tap/di/TangemSdkManagerModule.kt +++ b/app/src/main/java/com/tangem/tap/di/TangemSdkManagerModule.kt @@ -3,6 +3,7 @@ package com.tangem.tap.di import android.content.Context import com.tangem.core.analytics.api.AnalyticsErrorHandler import com.tangem.domain.card.BuildConfig +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.dynamicaddresses.DynamicAddressesFeatureToggles import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles @@ -36,6 +37,7 @@ internal class TangemSdkManagerModule { dynamicAddressesFeatureToggles: DynamicAddressesFeatureToggles, blockchainToDeriveFinder: BlockchainToDeriveFinder, analyticsErrorHandler: AnalyticsErrorHandler, + cardRepository: CardRepository, ): TangemSdkManager { return if (BuildConfig.MOCK_DATA_SOURCE) { MockTangemSdkManager(resources = context.resources) @@ -50,6 +52,7 @@ internal class TangemSdkManagerModule { dynamicAddressesFeatureToggles = dynamicAddressesFeatureToggles, blockchainToDeriveFinder = blockchainToDeriveFinder, analyticsErrorHandler = analyticsErrorHandler, + cardRepository = cardRepository, ) } } 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 db3b9aa4e2..5a193f32f7 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 @@ -7,6 +7,7 @@ import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles import com.tangem.tap.domain.scanCard.DefaultScanCardProcessor import com.tangem.tap.domain.scanCard.LegacyScanProcessor +import com.tangem.tap.domain.scanCard.UseCaseScanProcessor import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -25,8 +26,16 @@ internal object CardLegacyDomainModule { @Provides @Singleton - fun provideScanCardProcessor(legacyScanProcessor: LegacyScanProcessor): ScanCardProcessor { - return DefaultScanCardProcessor(legacyScanProcessor = legacyScanProcessor) + fun provideScanCardProcessor( + legacyScanProcessor: LegacyScanProcessor, + useCaseScanProcessor: UseCaseScanProcessor, + cardScanningFeatureToggles: CardScanningFeatureToggles, + ): ScanCardProcessor { + return DefaultScanCardProcessor( + legacyScanProcessor = legacyScanProcessor, + useCaseScanProcessor = useCaseScanProcessor, + cardScanningFeatureToggles = cardScanningFeatureToggles, + ) } @Provides diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt index f04b03cef6..c784137e08 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt @@ -5,16 +5,15 @@ import com.tangem.common.core.TangemError import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store // TODO: Remove this object after feature toggle was removed and use ScanCardUseCase instead internal class DefaultScanCardProcessor( private val legacyScanProcessor: LegacyScanProcessor, + private val useCaseScanProcessor: UseCaseScanProcessor, + private val cardScanningFeatureToggles: CardScanningFeatureToggles, ) : ScanCardProcessor { private val isNewCardScanningEnabled: Boolean - get() = store.inject(DaggerGraphState::cardScanningFeatureToggles).isNewCardScanningEnabled + get() = cardScanningFeatureToggles.isNewCardScanningEnabled override suspend fun scan( cardId: String?, @@ -23,7 +22,7 @@ internal class DefaultScanCardProcessor( shouldCheckIsAlreadyActivated: Boolean, ): CompletionResult { return if (isNewCardScanningEnabled) { - UseCaseScanProcessor.scan(cardId, allowsRequestAccessCodeFromRepository) + useCaseScanProcessor.scan(cardId, allowsRequestAccessCodeFromRepository) } else { legacyScanProcessor.scan( analyticsSource = analyticsSource, @@ -47,7 +46,7 @@ internal class DefaultScanCardProcessor( onSuccess: suspend (scanResponse: ScanResponse) -> Unit, ) { if (isNewCardScanningEnabled) { - UseCaseScanProcessor.scan( + useCaseScanProcessor.scan( analyticsSource = analyticsSource, cardId = cardId, onProgressStateChange = onProgressStateChange, diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt index 3c0b311ca7..10dafea284 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt @@ -6,6 +6,7 @@ import com.tangem.common.core.TangemSdkError import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess import com.tangem.common.routing.AppRoute +import com.tangem.common.routing.AppRouter import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsEvent @@ -21,19 +22,18 @@ import com.tangem.core.ui.extensions.toWrappedList import com.tangem.core.ui.message.dialog.Dialogs import com.tangem.domain.card.ScanFailsCounter import com.tangem.domain.card.common.util.twinsIsTwinned +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.common.extensions.withMainContext +import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.sdk.extensions.localizedDescriptionRes import com.tangem.tap.common.analytics.paramsInterceptor.CardContextInterceptor -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.disclaimer.createDisclaimer import com.tangem.tap.features.onboarding.OnboardingHelper import com.tangem.tap.mainScope -import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.scope -import com.tangem.tap.store import com.tangem.tap.tangemSdkManager import com.tangem.utils.extensions.DELAY_SDK_DIALOG_CLOSE import kotlinx.coroutines.Dispatchers @@ -44,11 +44,17 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton +@Suppress("LongParameterList") internal class LegacyScanProcessor @Inject constructor( @GlobalUiMessageSender private val uiMessageSender: UiMessageSender, private val analyticsEventHandler: AnalyticsEventHandler, private val trackingContextProxy: TrackingContextProxy, private val scanFailsCounter: ScanFailsCounter, + private val appRouter: AppRouter, + private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, + private val wasTwinsOnboardingShownUseCase: WasTwinsOnboardingShownUseCase, + private val cardRepository: CardRepository, + private val onboardingHelper: OnboardingHelper, ) { suspend fun scan( @@ -146,7 +152,7 @@ internal class LegacyScanProcessor @Inject constructor( crossinline disclaimerWillShow: () -> Unit = {}, crossinline nextHandler: suspend (ScanResponse) -> Unit, ) { - val disclaimer = scanResponse.card.createDisclaimer() + val disclaimer = scanResponse.card.createDisclaimer(cardRepository) if (disclaimer.isAccepted()) { nextHandler(scanResponse) @@ -157,9 +163,7 @@ internal class LegacyScanProcessor @Inject constructor( withContext(Dispatchers.Main.immediate) { disclaimerWillShow() - store.dispatchNavigationAction { - push(AppRoute.Disclaimer(isTosAccepted = false)) - } + appRouter.push(AppRoute.Disclaimer(isTosAccepted = false)) } } } @@ -189,7 +193,7 @@ internal class LegacyScanProcessor @Inject constructor( mainScope.launch { onCancel() - store.inject(DaggerGraphState::sendFeedbackEmailUseCase).invoke( + sendFeedbackEmailUseCase.invoke( type = FeedbackEmailType.CardAttestationFailed, ) } @@ -209,7 +213,7 @@ internal class LegacyScanProcessor @Inject constructor( crossinline onWalletNotCreated: suspend () -> Unit, crossinline onSuccess: suspend (ScanResponse) -> Unit, ) { - if (OnboardingHelper.isOnboardingCase(scanResponse)) { + if (onboardingHelper.isOnboardingCase(scanResponse)) { trackingContextProxy.addContext(scanResponse) onWalletNotCreated() navigateTo( @@ -221,8 +225,7 @@ internal class LegacyScanProcessor @Inject constructor( } else { trackingContextProxy.setContext(scanResponse) - val wasTwinsOnboardingShown = - store.inject(DaggerGraphState::wasTwinsOnboardingShownUseCase).invokeSync() + val wasTwinsOnboardingShown = wasTwinsOnboardingShownUseCase.invokeSync() if (scanResponse.twinsIsTwinned() && !wasTwinsOnboardingShown) { onWalletNotCreated() @@ -241,7 +244,7 @@ internal class LegacyScanProcessor @Inject constructor( private suspend inline fun navigateTo(route: AppRoute, onProgressStateChange: (showProgress: Boolean) -> Unit) { delay(DELAY_SDK_DIALOG_CLOSE) - store.dispatchNavigationAction { push(route) } + appRouter.push(route) onProgressStateChange(false) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt index d9bbaccdb4..38ee2a3f54 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt @@ -4,33 +4,46 @@ import arrow.fx.coroutines.resourceScope import com.tangem.common.CompletionResult import com.tangem.common.core.TangemError import com.tangem.common.routing.AppRoute +import com.tangem.common.routing.AppRouter import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic import com.tangem.core.analytics.models.ExceptionAnalyticsEvent +import com.tangem.core.analytics.utils.TrackingContextProxy import com.tangem.domain.card.ScanCardException +import com.tangem.domain.card.ScanCardUseCase +import com.tangem.domain.card.ScanFailsRequester +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.tap.common.analytics.events.TangemSdkErrorEvent -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.extensions.inject import com.tangem.tap.domain.scanCard.chains.* import com.tangem.tap.domain.scanCard.utils.ScanCardExceptionConverter -import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.features.onboarding.OnboardingHelper import com.tangem.tap.scope -import com.tangem.tap.store import com.tangem.utils.extensions.DELAY_SDK_DIALOG_CLOSE import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import javax.inject.Inject +import javax.inject.Singleton -internal object UseCaseScanProcessor { +@Singleton +@Suppress("LongParameterList") +internal class UseCaseScanProcessor @Inject constructor( + private val scanCardUseCase: ScanCardUseCase, + private val scanFailsRequester: ScanFailsRequester, + private val appRouter: AppRouter, + private val trackingContextProxy: TrackingContextProxy, + private val wasTwinsOnboardingShownUseCase: WasTwinsOnboardingShownUseCase, + private val cardRepository: CardRepository, + private val onboardingHelper: OnboardingHelper, +) { private val scanCardExceptionConverter = ScanCardExceptionConverter() suspend fun scan( cardId: String? = null, allowsRequestAccessCodeFromRepository: Boolean = false, ): CompletionResult { - val scanCardUseCase = store.inject(DaggerGraphState::scanCardUseCase) - return scanCardUseCase(cardId, allowsRequestAccessCodeFromRepository) .fold( ifLeft = { scanCardException -> @@ -53,7 +66,6 @@ internal object UseCaseScanProcessor { onFailure: suspend (error: TangemError) -> Unit, onSuccess: suspend (scanResponse: ScanResponse) -> Unit, ) = progressScope(onProgressStateChange) { - val scanCardUseCase = store.inject(DaggerGraphState::scanCardUseCase) val chains = buildList { add( FailedScansCounterChain( @@ -61,8 +73,8 @@ internal object UseCaseScanProcessor { ), ) add(AnalyticsChain(Basic.CardWasScanned(analyticsSource))) - add(DisclaimerChain(store, disclaimerWillShow)) - add(CheckForOnboardingChain(store)) + add(DisclaimerChain(appRouter, cardRepository, disclaimerWillShow)) + add(CheckForOnboardingChain(trackingContextProxy, wasTwinsOnboardingShownUseCase, onboardingHelper)) } scanCardUseCase(cardId, afterScanChains = chains).fold( @@ -73,7 +85,7 @@ internal object UseCaseScanProcessor { private fun showScanFailsDialog(source: AnalyticsParam.ScreensSources) { scope.launch { - store.inject(DaggerGraphState::scanFailsRequester).show(source) + scanFailsRequester.show(source) } } @@ -86,7 +98,6 @@ internal object UseCaseScanProcessor { is ScanCardException.ChainException -> proceedWithScanChainException( exception, onWalletNotCreated, - onFailure, ) is ScanCardException.UnknownException, is ScanCardException.UserCancelled, @@ -109,16 +120,12 @@ internal object UseCaseScanProcessor { private suspend fun proceedWithScanChainException( exception: ScanCardException.ChainException, onWalletNotCreated: suspend () -> Unit, - onFailure: suspend (error: TangemError) -> Unit, ) { when (exception) { is ScanChainException.OnboardingNeeded -> { navigateTo(exception.onboardingRoute) onWalletNotCreated() } - is ScanChainException.DisclaimerWasCanceled -> { - onFailure(scanCardExceptionConverter.convertBack(exception)) - } } } @@ -136,6 +143,6 @@ internal object UseCaseScanProcessor { private suspend inline fun navigateTo(route: AppRoute) { delay(DELAY_SDK_DIALOG_CLOSE) - store.dispatchNavigationAction { push(route) } + appRouter.push(route) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt index a3693ba6d2..6576186613 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt @@ -3,18 +3,16 @@ package com.tangem.tap.domain.scanCard.chains import arrow.core.left import arrow.core.right import com.tangem.common.routing.AppRoute +import com.tangem.core.analytics.utils.TrackingContextProxy import com.tangem.domain.card.ScanCardException import com.tangem.domain.card.common.util.twinsIsTwinned import com.tangem.domain.core.chain.Chain import com.tangem.domain.core.chain.ResultChain import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.common.redux.AppState +import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.tap.features.onboarding.OnboardingHelper -import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.utils.extensions.DELAY_SDK_DIALOG_CLOSE import kotlinx.coroutines.delay -import org.rekotlin.Store /** * Handles the verification process to determine if the scanned card requires onboarding. @@ -22,19 +20,17 @@ import org.rekotlin.Store * Returns: * - [ScanChainException.OnboardingNeeded] if onboarding required. * - * @param store the [Store] that holds the state of the app. - * * @see Chain for more information about the Chain interface. */ class CheckForOnboardingChain( - private val store: Store, + private val trackingContextProxy: TrackingContextProxy, + private val wasTwinsOnboardingShownUseCase: WasTwinsOnboardingShownUseCase, + private val onboardingHelper: OnboardingHelper, ) : ResultChain() { override suspend fun launch(previousChainResult: ScanResponse): ScanChainResult { - val trackingContextProxy = store.inject(DaggerGraphState::trackingContextProxy) - return when { - OnboardingHelper.isOnboardingCase(previousChainResult) -> { + onboardingHelper.isOnboardingCase(previousChainResult) -> { trackingContextProxy.addContext(previousChainResult) ScanChainException.OnboardingNeeded( AppRoute.Onboarding( @@ -46,8 +42,7 @@ class CheckForOnboardingChain( else -> { trackingContextProxy.setContext(previousChainResult) - val wasTwinsOnboardingShown = store.inject(DaggerGraphState::wasTwinsOnboardingShownUseCase) - .invokeSync() + val wasTwinsOnboardingShown = wasTwinsOnboardingShownUseCase.invokeSync() // If twins was twinned previously but twins welcome not shown if (previousChainResult.twinsIsTwinned() && !wasTwinsOnboardingShown) { diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt index 7bd4be874c..93a1f9feac 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt @@ -2,33 +2,30 @@ package com.tangem.tap.domain.scanCard.chains import arrow.core.right import com.tangem.common.routing.AppRoute +import com.tangem.common.routing.AppRouter import com.tangem.domain.card.ScanCardException +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.core.chain.Chain import com.tangem.domain.core.chain.ResultChain import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.redux.AppState import com.tangem.tap.features.disclaimer.createDisclaimer -import org.rekotlin.Store /** * Handles disclaimer display after the card scanning operation. * - * Returns [ScanChainException.DisclaimerWasCanceled] if the disclaimer is dismissed by the user. - * - * @param store the [Store] that holds the state of the app, used here to dispatch actions related to disclaimers. * @param disclaimerWillShow an optional function to be invoked when a disclaimer is about to be shown. Default is an * empty function. * * @see Chain for more information about the Chain interface. */ internal class DisclaimerChain( - private val store: Store, + private val appRouter: AppRouter, + private val cardRepository: CardRepository, private val disclaimerWillShow: () -> Unit = {}, ) : ResultChain() { override suspend fun launch(previousChainResult: ScanResponse): ScanChainResult { - val disclaimer = previousChainResult.card.createDisclaimer() + val disclaimer = previousChainResult.card.createDisclaimer(cardRepository) return if (disclaimer.isAccepted()) { previousChainResult.right() @@ -36,9 +33,7 @@ internal class DisclaimerChain( disclaimerWillShow() // TODO: [REDACTED_JIRA] - store.dispatchNavigationAction { - push(route = AppRoute.Disclaimer(isTosAccepted = false)) - } + appRouter.push(route = AppRoute.Disclaimer(isTosAccepted = false)) previousChainResult.right() } diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt index cd7a62cab3..31c35c54de 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt @@ -5,15 +5,6 @@ import com.tangem.domain.card.ScanCardException sealed class ScanChainException : ScanCardException.ChainException() { - /** - * May be returned from [DisclaimerChain] - * */ - class DisclaimerWasCanceled : ScanChainException() { - - @Suppress("UnusedPrivateMember") - private fun readResolve(): Any = DisclaimerWasCanceled() - } - /** * May be returned from [CheckForOnboardingChain] * diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/utils/ScanCardExceptionConverter.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/utils/ScanCardExceptionConverter.kt index a7fd680230..711c8c9e8e 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/utils/ScanCardExceptionConverter.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/utils/ScanCardExceptionConverter.kt @@ -33,7 +33,6 @@ internal class ScanCardExceptionConverter : TwoWayConverter TangemSdkError.UserCancelled() is ScanChainException.OnboardingNeeded, null, -> TangemSdkError.ExceptionError(e?.cause) diff --git a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt index 29a181c404..6211ed6b11 100644 --- a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt @@ -23,6 +23,7 @@ import com.tangem.crypto.bip39.DefaultMnemonic import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey import com.tangem.domain.card.common.util.cardTypesResolver +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse @@ -72,6 +73,7 @@ internal class DefaultTangemSdkManager( private val dynamicAddressesFeatureToggles: DynamicAddressesFeatureToggles, private val blockchainToDeriveFinder: BlockchainToDeriveFinder, private val analyticsErrorHandler: AnalyticsErrorHandler, + private val cardRepository: CardRepository, ) : TangemSdkManager { private val tangemSdk: TangemSdk @@ -146,6 +148,7 @@ internal class DefaultTangemSdkManager( shouldCheckIsAlreadyActivated = shouldCheckIsAlreadyActivated, isDynamicAddressesEnabled = dynamicAddressesFeatureToggles.isDynamicAddressesEnabled, onboardingV2FeatureToggles = onboardingV2FeatureToggles, + cardRepository = cardRepository, ), cardId = cardId, initialMessage = message, @@ -453,6 +456,7 @@ internal class DefaultTangemSdkManager( twinPublicKey = secondCardPublicKey, issuerKeys = issuerKeyPair, isDynamicAddressesEnabled = dynamicAddressesFeatureToggles.isDynamicAddressesEnabled, + cardRepository = cardRepository, ), cardId = cardId, initialMessage = initialMessage, diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt index 266bfaa86b..78d3151844 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt @@ -21,6 +21,7 @@ import com.tangem.domain.card.common.TapWorkarounds.isTangemTwins import com.tangem.domain.card.common.TapWorkarounds.isVisa import com.tangem.domain.card.common.TwinsHelper import com.tangem.domain.card.common.visa.VisaUtilities +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.CardDTO.Companion.RING_BATCH_IDS import com.tangem.domain.models.scan.CardDTO.Companion.RING_BATCH_PREFIX @@ -34,13 +35,10 @@ import com.tangem.operations.backup.StartPrimaryCardLinkingTask import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask import com.tangem.operations.files.ReadFilesTask import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand -import com.tangem.tap.common.extensions.inject import com.tangem.tap.domain.TapSdkError import com.tangem.tap.domain.visa.VisaCardScanHandler import com.tangem.tap.mainScope -import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.scope -import com.tangem.tap.store import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -53,6 +51,7 @@ internal class ScanProductTask( private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles?, private val shouldCheckIsAlreadyActivated: Boolean, private val isDynamicAddressesEnabled: Boolean, + private val cardRepository: CardRepository, override val allowsRequestAccessCodeFromRepository: Boolean = false, ) : CardSessionRunnable { @@ -80,7 +79,11 @@ internal class ScanProductTask( readVisaCard( session = session, cardDto = cardDto, - scanWalletProcessor = ScanWalletProcessor(blockchainToDeriveFinder, isDynamicAddressesEnabled), + scanWalletProcessor = ScanWalletProcessor( + blockchainToDeriveFinder = blockchainToDeriveFinder, + isDynamicAddressesEnabled = isDynamicAddressesEnabled, + cardRepository = cardRepository, + ), callback = callback, ) return @@ -88,7 +91,11 @@ internal class ScanProductTask( val commandProcessor = when { cardDto.isTangemTwins -> ScanTwinProcessor() - else -> ScanWalletProcessor(blockchainToDeriveFinder, isDynamicAddressesEnabled) + else -> ScanWalletProcessor( + blockchainToDeriveFinder = blockchainToDeriveFinder, + isDynamicAddressesEnabled = isDynamicAddressesEnabled, + cardRepository = cardRepository, + ) } commandProcessor.proceed(cardDto, session) { processorResult -> when (processorResult) { @@ -114,7 +121,7 @@ internal class ScanProductTask( return if (shouldCheckIsAlreadyActivated) { PreflightReadMode.FullCardReadWithAccessCodeCheck } else { - return super.preflightReadMode() + super.preflightReadMode() } } @@ -171,6 +178,7 @@ internal class ScanProductTask( private class ScanWalletProcessor( private val blockchainToDeriveFinder: BlockchainToDeriveFinder?, private val isDynamicAddressesEnabled: Boolean, + private val cardRepository: CardRepository, ) : ProductCommandProcessor { var primaryCard: PrimaryCard? = null @@ -262,8 +270,7 @@ private class ScanWalletProcessor( callback: (result: CompletionResult) -> Unit, ) { mainScope.launch { - val isActivationInProgress = store.inject(DaggerGraphState::cardRepository) - .isActivationInProgress(card.cardId) + val isActivationInProgress = cardRepository.isActivationInProgress(card.cardId) @Suppress("ComplexCondition") if (card.backupStatus == CardDTO.BackupStatus.NoBackup && diff --git a/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt b/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt index 548fadc6ad..c2c044dd95 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt @@ -4,6 +4,7 @@ import com.tangem.common.CompletionResult import com.tangem.common.KeyPair import com.tangem.common.core.CardSession import com.tangem.common.core.CardSessionRunnable +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.models.scan.ScanResponse import com.tangem.operations.PreflightReadMode import com.tangem.operations.PreflightReadTask @@ -13,6 +14,7 @@ class FinalizeTwinTask( private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair, private val isDynamicAddressesEnabled: Boolean, + private val cardRepository: CardRepository, ) : CardSessionRunnable { override val allowsRequestAccessCodeFromRepository: Boolean = false @@ -35,6 +37,7 @@ class FinalizeTwinTask( shouldCheckIsAlreadyActivated = false, isDynamicAddressesEnabled = isDynamicAddressesEnabled, onboardingV2FeatureToggles = null, + cardRepository = cardRepository, ).run(session, callback) is CompletionResult.Failure -> callback(CompletionResult.Failure(readResult.error)) diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt index 90f73cb4ad..2f44bf9dd0 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt @@ -1,18 +1,15 @@ package com.tangem.tap.features.disclaimer +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.models.scan.CardDTO -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store import java.util.Locale -fun CardDTO.createDisclaimer(): Disclaimer { - val dataProvider = provideDisclaimerDataProvider(cardId) +fun CardDTO.createDisclaimer(cardRepository: CardRepository): Disclaimer { + val dataProvider = provideDisclaimerDataProvider(cardId, cardRepository) return TangemDisclaimer(dataProvider) } -private fun provideDisclaimerDataProvider(cardId: String): DisclaimerDataProvider { - val cardRepository = store.inject(DaggerGraphState::cardRepository) +private fun provideDisclaimerDataProvider(cardId: String, cardRepository: CardRepository): DisclaimerDataProvider { return object : DisclaimerDataProvider { override fun getLanguage(): String = Locale.getDefault().language override fun getCardId(): String = cardId 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 b90a6fc412..5fb9bba066 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 @@ -40,7 +40,6 @@ import com.tangem.domain.wallets.usecase.UpdateRemoteWalletsInfoUseCase import com.tangem.feature.swap.analytics.StoriesEvents import com.tangem.security.DeviceSecurityInfoProvider import com.tangem.tap.network.exchangeServices.SellService -import com.tangem.tap.proxy.AppStateHolder import com.tangem.tap.routing.configurator.AppRouterConfig import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.logging.TangemLogger @@ -77,7 +76,6 @@ internal class MainViewModel @Inject constructor( private val sendPushTokenUseCase: SendPushTokenUseCase, private val apiConfigsManager: ApiConfigsManager, private val multiQuoteUpdater: MultiQuoteUpdater, - private val appStateHolder: AppStateHolder, private val appRouterConfig: AppRouterConfig, private val sellService: SellService, private val deviceSecurityInfoProvider: DeviceSecurityInfoProvider, @@ -176,8 +174,6 @@ internal class MainViewModel @Inject constructor( private fun initializeOffRamp() { viewModelScope.launch { - appStateHolder.sellService = sellService - sellService.update() } } 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 521d22b51a..757f98522c 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 @@ -2,19 +2,18 @@ package com.tangem.tap.features.onboarding import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.card.common.util.twinsIsTwinned +import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.demo.DemoHelper -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store +import javax.inject.Inject +import javax.inject.Singleton -/** -[REDACTED_AUTHOR] - */ -object OnboardingHelper { +@Singleton +class OnboardingHelper @Inject constructor( + private val cardRepository: CardRepository, +) { suspend fun isOnboardingCase(response: ScanResponse): Boolean { - val cardRepository = store.inject(DaggerGraphState::cardRepository) val cardId = response.card.cardId return when { @@ -22,7 +21,7 @@ object OnboardingHelper { // if (response.visaCardActivationStatus == null) error("Visa card activation status is null") // // response.visaCardActivationStatus !is VisaCardActivationStatus.Activated - return true + true } response.cardTypesResolver.isTangemTwins() -> {