From c849c203b141ff961ba95720ecaceca4fea0e78c Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 28 May 2024 19:05:46 +0800 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/di/domain/CardDomainModule.kt | 7 +++ .../domain/card/DefaultResetCardUseCase.kt | 55 +++++++++++++++++++ .../details/ui/resetcard/ResetCardFragment.kt | 3 +- .../ui/resetcard/ResetCardViewModel.kt | 51 +++++++++++++++-- .../tangem/domain/card/ResetCardUseCase.kt | 15 +++++ .../domain/card/models/ResetCardError.kt | 8 +++ 6 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/domain/card/DefaultResetCardUseCase.kt create mode 100644 domain/card/src/main/kotlin/com/tangem/domain/card/ResetCardUseCase.kt create mode 100644 domain/card/src/main/kotlin/com/tangem/domain/card/models/ResetCardError.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt index f49789df71..1a6c5ff684 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt @@ -9,6 +9,7 @@ import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase +import com.tangem.tap.domain.card.DefaultResetCardUseCase import com.tangem.tap.domain.sdk.TangemSdkManager import dagger.Module import dagger.Provides @@ -77,4 +78,10 @@ internal object CardDomainModule { fun provideDeleteSavedAccessCodesUseCase(tangemSdkManager: TangemSdkManager): DeleteSavedAccessCodesUseCase { return DefaultDeleteSavedAccessCodesUseCase(tangemSdkManager) } + + @Provides + @ViewModelScoped + fun provideResetCardUseCase(tangemSdkManager: TangemSdkManager): ResetCardUseCase { + return DefaultResetCardUseCase(tangemSdkManager) + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/card/DefaultResetCardUseCase.kt b/app/src/main/java/com/tangem/tap/domain/card/DefaultResetCardUseCase.kt new file mode 100644 index 0000000000..6cfd662efd --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/card/DefaultResetCardUseCase.kt @@ -0,0 +1,55 @@ +package com.tangem.tap.domain.card + +import arrow.core.Either +import arrow.core.raise.either +import arrow.core.right +import com.tangem.common.CompletionResult +import com.tangem.common.UserCodeType +import com.tangem.common.core.TangemSdkError +import com.tangem.common.core.UserCodeRequestPolicy +import com.tangem.common.doOnResult +import com.tangem.domain.card.ResetCardUseCase +import com.tangem.domain.card.models.ResetCardError +import com.tangem.domain.models.scan.CardDTO +import com.tangem.tap.domain.sdk.TangemSdkManager + +internal class DefaultResetCardUseCase( + private val tangemSdkManager: TangemSdkManager, +) : ResetCardUseCase { + + override suspend fun invoke(card: CardDTO): Either = either { + val policyBeforeReset = tangemSdkManager.userCodeRequestPolicy + requestMandatoryAccessCodeEntry(card) + + val result = tangemSdkManager.resetToFactorySettings( + cardId = card.cardId, + allowsRequestAccessCodeFromRepository = true, + ) + .doOnResult { tangemSdkManager.setUserCodeRequestPolicy(policyBeforeReset) } + + when (result) { + is CompletionResult.Success -> Unit.right() + is CompletionResult.Failure -> { + if (result.error is TangemSdkError.UserCancelled) { + raise(ResetCardError.UserCanceled) + } else { + raise(ResetCardError.AnotherSdkError) + } + } + } + } + + private fun requestMandatoryAccessCodeEntry(card: CardDTO) { + val type = if (card.isAccessCodeSet) { + UserCodeType.AccessCode + } else if (card.isPasscodeSet == true) { + UserCodeType.Passcode + } else { + null + } + + type?.let { + tangemSdkManager.setUserCodeRequestPolicy(policy = UserCodeRequestPolicy.Always(type)) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt index 1522c07ed3..5affcc7167 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier +import androidx.fragment.app.viewModels import com.tangem.core.navigation.NavigationAction import com.tangem.core.ui.UiDependencies import com.tangem.core.ui.screen.ComposeFragment @@ -19,7 +20,7 @@ internal class ResetCardFragment : ComposeFragment(), StoreSubscriber = mutableStateOf(ResetCardScreenState.InitialState) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt index 02e00914e1..e5cac17cb5 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt @@ -1,13 +1,32 @@ package com.tangem.tap.features.details.ui.resetcard -import com.tangem.tap.common.redux.AppState +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import arrow.core.raise.either +import com.tangem.domain.card.DeleteSavedAccessCodesUseCase +import com.tangem.domain.card.ResetCardUseCase +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.usecase.DeleteWalletUseCase +import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase +import com.tangem.tap.common.extensions.onUserWalletSelected import com.tangem.tap.features.details.redux.CardSettingsState import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.ui.cardsettings.TextReference +import com.tangem.tap.features.details.ui.resetcard.featuretoggles.ResetCardFeatureToggles import com.tangem.tap.features.details.ui.utils.toResetCardDescriptionText -import org.rekotlin.Store +import com.tangem.tap.store +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject -internal class ResetCardViewModel(private val store: Store) { +@HiltViewModel +internal class ResetCardViewModel @Inject constructor( + private val resetCardFeatureToggles: ResetCardFeatureToggles, + private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, + private val resetCardUseCase: ResetCardUseCase, + private val deleteSavedAccessCodesUseCase: DeleteSavedAccessCodesUseCase, + private val deleteWalletUseCase: DeleteWalletUseCase, +) : ViewModel() { fun updateState(state: CardSettingsState?): ResetCardScreenState.ResetCardScreenContent { val descriptionText = state?.cardInfo @@ -45,7 +64,31 @@ internal class ResetCardViewModel(private val store: Store) { private fun onLastWarningDialogResetClicked() { store.dispatch(DetailsAction.ResetToFactory.LastWarningDialogVisibility(isShown = false)) - store.dispatch(DetailsAction.ResetToFactory.Proceed) + + if (resetCardFeatureToggles.isFullResetEnabled) { + makeFullReset() + } else { + store.dispatch(DetailsAction.ResetToFactory.Proceed) + } + } + + private fun makeFullReset() { + val currentUserWallet = getSelectedWalletSyncUseCase().getOrNull() ?: return + + viewModelScope.launch { + resetCurrentCard(userWallet = currentUserWallet).onRight { + val newSelectedWallet = getSelectedWalletSyncUseCase().getOrNull() + if (newSelectedWallet != null) { + store.onUserWalletSelected(newSelectedWallet) + } + } + } + } + + private suspend fun resetCurrentCard(userWallet: UserWallet) = either { + resetCardUseCase(userWallet.scanResponse.card).bind() + deleteSavedAccessCodesUseCase(userWallet.cardId).bind() + deleteWalletUseCase(userWallet.walletId).bind() } private fun onLastWarningDialogDismiss() { diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/ResetCardUseCase.kt b/domain/card/src/main/kotlin/com/tangem/domain/card/ResetCardUseCase.kt new file mode 100644 index 0000000000..85cf78be8a --- /dev/null +++ b/domain/card/src/main/kotlin/com/tangem/domain/card/ResetCardUseCase.kt @@ -0,0 +1,15 @@ +package com.tangem.domain.card + +import arrow.core.Either +import com.tangem.domain.card.models.ResetCardError +import com.tangem.domain.models.scan.CardDTO + +/** + * Use case for resetting card to factory settings + * +[REDACTED_AUTHOR] + */ +interface ResetCardUseCase { + + suspend operator fun invoke(card: CardDTO): Either +} \ No newline at end of file diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/models/ResetCardError.kt b/domain/card/src/main/kotlin/com/tangem/domain/card/models/ResetCardError.kt new file mode 100644 index 0000000000..7db8690e89 --- /dev/null +++ b/domain/card/src/main/kotlin/com/tangem/domain/card/models/ResetCardError.kt @@ -0,0 +1,8 @@ +package com.tangem.domain.card.models + +sealed interface ResetCardError { + + data object UserCanceled : ResetCardError + + data object AnotherSdkError : ResetCardError +} \ No newline at end of file