From 52bf5cbb58947579ce770d423bddae1c515721b2 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 24 Nov 2025 20:29:26 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../hotwallet/accesscode/AccessCodeModel.kt | 104 +++++++++--------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt index 96fc1b4b46..318bce1dc7 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt @@ -16,6 +16,7 @@ import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.settings.CanUseBiometryUseCase import com.tangem.domain.settings.SetAskBiometryShownUseCase import com.tangem.domain.settings.ShouldShowAskBiometryUseCase +import com.tangem.domain.wallets.hot.HotWalletAccessor import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.ClearHotWalletContextualUnlockUseCase import com.tangem.domain.wallets.usecase.GetHotWalletContextualUnlockUseCase @@ -24,20 +25,20 @@ import com.tangem.features.hotwallet.accesscode.entity.AccessCodeUM import com.tangem.features.hotwallet.impl.R import com.tangem.hot.sdk.TangemHotSdk import com.tangem.hot.sdk.model.HotAuth -import com.tangem.hot.sdk.model.UnlockHotWallet +import com.tangem.hot.sdk.model.HotWalletId import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine -import timber.log.Timber import javax.inject.Inject import kotlin.coroutines.resume -private const val SUCCESS_DISPLAY_DURATION_MS = 200L +private const val SUCCESS_DISPLAY_DURATION_MS = 400L private const val ERROR_DISPLAY_DURATION_MS = 500L @Suppress("LongParameterList") @@ -49,6 +50,7 @@ internal class AccessCodeModel @Inject constructor( private val getUserWalletUseCase: GetUserWalletUseCase, private val getHotWalletContextualUnlockUseCase: GetHotWalletContextualUnlockUseCase, private val clearHotWalletContextualUnlockUseCase: ClearHotWalletContextualUnlockUseCase, + private val hotWalletAccessor: HotWalletAccessor, private val userWalletsListRepository: UserWalletsListRepository, private val walletsRepository: WalletsRepository, private val tangemHotSdk: TangemHotSdk, @@ -101,7 +103,7 @@ internal class AccessCodeModel @Inject constructor( if (isConfirmMode) { modelScope.launch { if (value == params.accessCodeToConfirm) { - showSuccessAndProceed(params.accessCodeToConfirm) + setCode(params.userWalletId, params.accessCodeToConfirm) } else { showErrorAndReset() } @@ -113,23 +115,17 @@ internal class AccessCodeModel @Inject constructor( } private fun onNewCodeSet() { - val accessCode = uiState.value.accessCode - uiState.update { currentState -> - currentState.copy( - accessCode = "", - ) - } - params.callbacks.onNewAccessCodeInput(params.userWalletId, accessCode) - } + modelScope.launch { + delay(timeMillis = SUCCESS_DISPLAY_DURATION_MS) - private suspend fun showSuccessAndProceed(accessCodeToConfirm: String) { - uiState.update { currentState -> - currentState.copy( - accessCodeColor = PinTextColor.Success, - ) + params.callbacks.onNewAccessCodeInput(params.userWalletId, uiState.value.accessCode) + + uiState.update { currentState -> + currentState.copy( + accessCode = "", + ) + } } - delay(timeMillis = SUCCESS_DISPLAY_DURATION_MS) - setCode(params.userWalletId, accessCodeToConfirm) } private suspend fun showErrorAndReset() { @@ -150,27 +146,48 @@ internal class AccessCodeModel @Inject constructor( private fun setCode(userWalletId: UserWalletId, accessCode: String) { modelScope.launch { - runCatching { - val userWallet = getUserWalletUseCase(userWalletId) - .getOrElse { error("User wallet with id $userWalletId not found") } - if (userWallet !is UserWallet.Hot) return@launch + val userWallet = getUserWalletUseCase(userWalletId) + .getOrElse { error("User wallet with id $userWalletId not found") } + if (userWallet !is UserWallet.Hot) return@launch - val unlockHotWallet = getHotWalletContextualUnlockUseCase(userWallet.hotWalletId) - .getOrNull() - ?: UnlockHotWallet(userWallet.hotWalletId, HotAuth.NoAuth) + tryToAskForBiometry() + + userWalletsListRepository.saveWithoutLock( + userWallet.copy(backedUp = true), + canOverride = true, + ) + + userWalletsListRepository.setLock( + userWallet.walletId, + UserWalletsListRepository.LockMethod.AccessCode(accessCode.toCharArray()), + ) + + if (walletsRepository.useBiometricAuthentication()) { + userWalletsListRepository.setLock( + userWallet.walletId, + UserWalletsListRepository.LockMethod.Biometric, + ) + } + + val unlockHotWallet = getHotWalletContextualUnlockUseCase(userWallet.hotWalletId) + .getOrNull() + ?: run { + require(userWallet.hotWalletId.authType == HotWalletId.AuthType.NoPassword) { + "Something went wrong. Hot wallet is locked and cannot be unlocked with NoAuth" + } + + hotWalletAccessor.unlockContextual(userWallet.hotWalletId) + } + + launch(NonCancellable) { var updatedHotWalletId = tangemHotSdk.changeAuth( unlockHotWallet = unlockHotWallet, auth = HotAuth.Password(accessCode.toCharArray()), ) - tryToAskForBiometry() - if (walletsRepository.requireAccessCode().not()) { updatedHotWalletId = tangemHotSdk.changeAuth( - unlockHotWallet = UnlockHotWallet( - walletId = updatedHotWalletId, - auth = HotAuth.Password(accessCode.toCharArray()), - ), + unlockHotWallet = unlockHotWallet, auth = HotAuth.Biometry, ) } @@ -183,22 +200,10 @@ internal class AccessCodeModel @Inject constructor( canOverride = true, ) - userWalletsListRepository.setLock( - userWallet.walletId, - UserWalletsListRepository.LockMethod.AccessCode(accessCode.toCharArray()), - ) - - if (walletsRepository.useBiometricAuthentication()) { - userWalletsListRepository.setLock( - userWallet.walletId, - UserWalletsListRepository.LockMethod.Biometric, - ) - } - - params.callbacks.onAccessCodeUpdated(params.userWalletId) - }.onFailure { - Timber.e(it) + clearHotWalletContextualUnlockUseCase.invoke(params.userWalletId) } + + params.callbacks.onAccessCodeUpdated(params.userWalletId) } } @@ -254,9 +259,4 @@ internal class AccessCodeModel @Inject constructor( return canUseBiometry && shouldShowAskBiometry } - - override fun onDestroy() { - clearHotWalletContextualUnlockUseCase.invoke(params.userWalletId) - super.onDestroy() - } } \ No newline at end of file