Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-08 14:33:06 +05:00
parent 04bcb44f76
commit e599995315
18 changed files with 142 additions and 30 deletions

View file

@ -11,6 +11,7 @@ import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.legacy.asLockable import com.tangem.domain.wallets.legacy.asLockable
import com.tangem.domain.core.wallets.UserWalletsListRepository import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase
import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.tap.LockTimerWorker.Companion.TAG import com.tangem.tap.LockTimerWorker.Companion.TAG
import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.tap.common.extensions.dispatchNavigationAction
@ -22,6 +23,7 @@ import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.time.Duration import kotlin.time.Duration
@Suppress("LongParameterList")
internal class LockUserWalletsTimer( internal class LockUserWalletsTimer(
private val context: Context, private val context: Context,
private val settingsRepository: SettingsRepository, private val settingsRepository: SettingsRepository,
@ -30,6 +32,7 @@ internal class LockUserWalletsTimer(
private val userWalletsListRepository: UserWalletsListRepository, private val userWalletsListRepository: UserWalletsListRepository,
private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val hotWalletFeatureToggles: HotWalletFeatureToggles,
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
private val clearAllHotWalletContextualUnlockUseCase: ClearAllHotWalletContextualUnlockUseCase,
) : LifecycleOwner by context as LifecycleOwner, ) : LifecycleOwner by context as LifecycleOwner,
DefaultLifecycleObserver { DefaultLifecycleObserver {
@ -55,6 +58,9 @@ internal class LockUserWalletsTimer(
) )
if (shouldOpenWelcomeScreenOnResume) { if (shouldOpenWelcomeScreenOnResume) {
if (hotWalletFeatureToggles.isHotWalletEnabled) {
clearAllHotWalletContextualUnlockUseCase.invoke()
}
store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) }
settingsRepository.setShouldOpenWelcomeScreenOnResume(value = false) settingsRepository.setShouldOpenWelcomeScreenOnResume(value = false)
} }
@ -120,6 +126,7 @@ internal class LockUserWalletsTimer(
start() start()
} }
.onRight { .onRight {
clearAllHotWalletContextualUnlockUseCase.invoke()
store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) }
} }
} }

View file

@ -50,6 +50,7 @@ import com.tangem.domain.staking.SendUnsubmittedHashesUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.TangemPayFeatureToggles
@ -186,6 +187,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
@Inject @Inject
internal lateinit var hotWalletFeatureToggles: HotWalletFeatureToggles internal lateinit var hotWalletFeatureToggles: HotWalletFeatureToggles
@Inject
internal lateinit var clearAllHotWalletContextualUnlockUseCase: ClearAllHotWalletContextualUnlockUseCase
@Inject @Inject
internal lateinit var tangemPayFeatureToggles: TangemPayFeatureToggles internal lateinit var tangemPayFeatureToggles: TangemPayFeatureToggles
@ -274,6 +278,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
coroutineScope = mainScope, coroutineScope = mainScope,
userWalletsListRepository = userWalletsListRepository, userWalletsListRepository = userWalletsListRepository,
hotWalletFeatureToggles = hotWalletFeatureToggles, hotWalletFeatureToggles = hotWalletFeatureToggles,
clearAllHotWalletContextualUnlockUseCase = clearAllHotWalletContextualUnlockUseCase,
) )
initIntentHandlers() initIntentHandlers()

View file

@ -384,6 +384,16 @@ internal object WalletsDomainModule {
) )
} }
@Provides
@Singleton
fun providesGetHotWalletContextualUnlockUseCase(
hotWalletAccessor: HotWalletAccessor,
): GetHotWalletContextualUnlockUseCase {
return GetHotWalletContextualUnlockUseCase(
hotWalletAccessor = hotWalletAccessor,
)
}
@Provides @Provides
@Singleton @Singleton
fun providesClearHotWalletContextualUnlockUseCase( fun providesClearHotWalletContextualUnlockUseCase(
@ -394,6 +404,16 @@ internal object WalletsDomainModule {
) )
} }
@Provides
@Singleton
fun providesClearAllHotWalletContextualUnlockUseCase(
hotWalletAccessor: HotWalletAccessor,
): ClearAllHotWalletContextualUnlockUseCase {
return ClearAllHotWalletContextualUnlockUseCase(
hotWalletAccessor = hotWalletAccessor,
)
}
@Provides @Provides
@Singleton @Singleton
fun providesExportSeedPhraseUseCase(hotWalletAccessor: HotWalletAccessor): ExportSeedPhraseUseCase { fun providesExportSeedPhraseUseCase(hotWalletAccessor: HotWalletAccessor): ExportSeedPhraseUseCase {

View file

@ -52,6 +52,9 @@ class DefaultHotWalletAccessor @Inject constructor(
} }
} }
override fun getContextualUnlock(hotWalletId: HotWalletId): UnlockHotWallet? =
contextualUnlockHotWallet[hotWalletId]
override fun clearContextualUnlock(hotWalletId: HotWalletId) { override fun clearContextualUnlock(hotWalletId: HotWalletId) {
contextualUnlockHotWallet[hotWalletId] = null contextualUnlockHotWallet[hotWalletId] = null
scope.launch { scope.launch {
@ -59,6 +62,14 @@ class DefaultHotWalletAccessor @Inject constructor(
} }
} }
override fun clearAllContextualUnlock() {
val hotWalletsIds = contextualUnlockHotWallet.keys.toList()
contextualUnlockHotWallet.clear()
scope.launch {
hotWalletsIds.forEach { tangemHotSdk.clearUnlockContext(it) }
}
}
private suspend fun <T> hotSdkRequest(hotWalletId: HotWalletId, block: suspend (unlock: UnlockHotWallet) -> T): T { private suspend fun <T> hotSdkRequest(hotWalletId: HotWalletId, block: suspend (unlock: UnlockHotWallet) -> T): T {
val isAccessCodeRequired = walletsRepository.requireAccessCode() val isAccessCodeRequired = walletsRepository.requireAccessCode()

View file

@ -12,5 +12,9 @@ interface HotWalletAccessor {
suspend fun unlockContextual(hotWalletId: HotWalletId): UnlockHotWallet suspend fun unlockContextual(hotWalletId: HotWalletId): UnlockHotWallet
fun getContextualUnlock(hotWalletId: HotWalletId): UnlockHotWallet?
fun clearContextualUnlock(hotWalletId: HotWalletId) fun clearContextualUnlock(hotWalletId: HotWalletId)
fun clearAllContextualUnlock()
} }

View file

@ -0,0 +1,16 @@
package com.tangem.domain.wallets.usecase
import arrow.core.Either
import com.tangem.domain.wallets.hot.HotWalletAccessor
class ClearAllHotWalletContextualUnlockUseCase(
private val hotWalletAccessor: HotWalletAccessor,
) {
operator fun invoke(): Either<Throwable, Unit> {
return Either.catch {
hotWalletAccessor.clearAllContextualUnlock()
}
}
}

View file

@ -0,0 +1,17 @@
package com.tangem.domain.wallets.usecase
import arrow.core.Either
import com.tangem.domain.wallets.hot.HotWalletAccessor
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.hot.sdk.model.UnlockHotWallet
class GetHotWalletContextualUnlockUseCase(
private val hotWalletAccessor: HotWalletAccessor,
) {
suspend operator fun invoke(hotWalletId: HotWalletId): Either<Throwable, UnlockHotWallet?> {
return Either.catch {
hotWalletAccessor.getContextualUnlock(hotWalletId)
}
}
}

View file

@ -34,12 +34,11 @@ internal class AccessCodeComponent @AssistedInject constructor(
} }
interface ModelCallbacks { interface ModelCallbacks {
fun onAccessCodeSet(userWalletId: UserWalletId, accessCode: String) fun onNewAccessCodeInput(userWalletId: UserWalletId, accessCode: String)
fun onAccessCodeConfirmed(userWalletId: UserWalletId) fun onAccessCodeUpdated(userWalletId: UserWalletId)
} }
data class Params( data class Params(
val isConfirmMode: Boolean,
val accessCodeToConfirm: String? = null, val accessCodeToConfirm: String? = null,
val userWalletId: UserWalletId, val userWalletId: UserWalletId,
val callbacks: ModelCallbacks, val callbacks: ModelCallbacks,

View file

@ -16,11 +16,14 @@ import com.tangem.domain.settings.CanUseBiometryUseCase
import com.tangem.domain.settings.SetAskBiometryShownUseCase import com.tangem.domain.settings.SetAskBiometryShownUseCase
import com.tangem.domain.settings.ShouldShowAskBiometryUseCase import com.tangem.domain.settings.ShouldShowAskBiometryUseCase
import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.ClearHotWalletContextualUnlockUseCase
import com.tangem.domain.wallets.usecase.GetHotWalletContextualUnlockUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.hotwallet.accesscode.entity.AccessCodeUM import com.tangem.features.hotwallet.accesscode.entity.AccessCodeUM
import com.tangem.features.hotwallet.impl.R import com.tangem.features.hotwallet.impl.R
import com.tangem.hot.sdk.TangemHotSdk import com.tangem.hot.sdk.TangemHotSdk
import com.tangem.hot.sdk.model.HotAuth import com.tangem.hot.sdk.model.HotAuth
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.hot.sdk.model.UnlockHotWallet import com.tangem.hot.sdk.model.UnlockHotWallet
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -38,6 +41,8 @@ internal class AccessCodeModel @Inject constructor(
paramsContainer: ParamsContainer, paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider, override val dispatchers: CoroutineDispatcherProvider,
private val getUserWalletUseCase: GetUserWalletUseCase, private val getUserWalletUseCase: GetUserWalletUseCase,
private val getHotWalletContextualUnlockUseCase: GetHotWalletContextualUnlockUseCase,
private val clearHotWalletContextualUnlockUseCase: ClearHotWalletContextualUnlockUseCase,
private val userWalletsListRepository: UserWalletsListRepository, private val userWalletsListRepository: UserWalletsListRepository,
private val walletsRepository: WalletsRepository, private val walletsRepository: WalletsRepository,
private val tangemHotSdk: TangemHotSdk, private val tangemHotSdk: TangemHotSdk,
@ -49,13 +54,15 @@ internal class AccessCodeModel @Inject constructor(
private val params = paramsContainer.require<AccessCodeComponent.Params>() private val params = paramsContainer.require<AccessCodeComponent.Params>()
private var hotWalletId: HotWalletId? = null
internal val uiState: StateFlow<AccessCodeUM> internal val uiState: StateFlow<AccessCodeUM>
field = MutableStateFlow(getInitialState()) field = MutableStateFlow(getInitialState())
private fun getInitialState() = AccessCodeUM( private fun getInitialState() = AccessCodeUM(
accessCode = "", accessCode = "",
onAccessCodeChange = ::onAccessCodeChange, onAccessCodeChange = ::onAccessCodeChange,
isConfirmMode = params.isConfirmMode, isConfirmMode = params.accessCodeToConfirm != null,
buttonEnabled = false, buttonEnabled = false,
buttonInProgress = false, buttonInProgress = false,
onButtonClick = ::onButtonClick, onButtonClick = ::onButtonClick,
@ -65,7 +72,7 @@ internal class AccessCodeModel @Inject constructor(
uiState.update { uiState.update {
it.copy( it.copy(
accessCode = value, accessCode = value,
buttonEnabled = if (params.isConfirmMode) { buttonEnabled = if (params.accessCodeToConfirm != null) {
value == params.accessCodeToConfirm value == params.accessCodeToConfirm
} else { } else {
value.length == uiState.value.accessCodeLength value.length == uiState.value.accessCodeLength
@ -75,12 +82,10 @@ internal class AccessCodeModel @Inject constructor(
} }
private fun onButtonClick() { private fun onButtonClick() {
if (!params.isConfirmMode) { if (params.accessCodeToConfirm == null) {
params.callbacks.onAccessCodeSet(params.userWalletId, uiState.value.accessCode) params.callbacks.onNewAccessCodeInput(params.userWalletId, uiState.value.accessCode)
} else { } else {
params.accessCodeToConfirm?.let { setCode(params.userWalletId, params.accessCodeToConfirm)
setCode(params.userWalletId, it)
}
} }
} }
@ -95,7 +100,9 @@ internal class AccessCodeModel @Inject constructor(
.getOrElse { error("User wallet with id $userWalletId not found") } .getOrElse { error("User wallet with id $userWalletId not found") }
if (userWallet !is UserWallet.Hot) return@launch if (userWallet !is UserWallet.Hot) return@launch
val unlockHotWallet = UnlockHotWallet(userWallet.hotWalletId, HotAuth.NoAuth) val unlockHotWallet = getHotWalletContextualUnlockUseCase(userWallet.hotWalletId)
.getOrNull()
?: UnlockHotWallet(userWallet.hotWalletId, HotAuth.NoAuth)
var updatedHotWalletId = tangemHotSdk.changeAuth( var updatedHotWalletId = tangemHotSdk.changeAuth(
unlockHotWallet = unlockHotWallet, unlockHotWallet = unlockHotWallet,
auth = HotAuth.Password(accessCode.toCharArray()), auth = HotAuth.Password(accessCode.toCharArray()),
@ -133,7 +140,7 @@ internal class AccessCodeModel @Inject constructor(
) )
} }
params.callbacks.onAccessCodeConfirmed(params.userWalletId) params.callbacks.onAccessCodeUpdated(params.userWalletId)
}.onFailure { }.onFailure {
Timber.e(it) Timber.e(it)
@ -188,4 +195,9 @@ internal class AccessCodeModel @Inject constructor(
return canUseBiometry && shouldShowAskBiometry return canUseBiometry && shouldShowAskBiometry
} }
override fun onDestroy() {
hotWalletId?.let { clearHotWalletContextualUnlockUseCase.invoke(it) }
super.onDestroy()
}
} }

View file

@ -127,11 +127,11 @@ internal class AddExistingWalletModel @Inject constructor(
} }
inner class AccessCodeModelCallbacks : AccessCodeComponent.ModelCallbacks { inner class AccessCodeModelCallbacks : AccessCodeComponent.ModelCallbacks {
override fun onAccessCodeSet(userWalletId: UserWalletId, accessCode: String) { override fun onNewAccessCodeInput(userWalletId: UserWalletId, accessCode: String) {
stackNavigation.push(AddExistingWalletRoute.ConfirmAccessCode(userWalletId, accessCode)) stackNavigation.push(AddExistingWalletRoute.ConfirmAccessCode(userWalletId, accessCode))
} }
override fun onAccessCodeConfirmed(userWalletId: UserWalletId) { override fun onAccessCodeUpdated(userWalletId: UserWalletId) {
navigateToPushNotificationsOrNext() navigateToPushNotificationsOrNext()
} }
} }

View file

@ -46,7 +46,6 @@ internal class AddExistingWalletChildFactory @Inject constructor(
is AddExistingWalletRoute.SetAccessCode -> accessCodeComponentFactory.create( is AddExistingWalletRoute.SetAccessCode -> accessCodeComponentFactory.create(
context = childContext, context = childContext,
params = AccessCodeComponent.Params( params = AccessCodeComponent.Params(
isConfirmMode = false,
userWalletId = route.userWalletId, userWalletId = route.userWalletId,
callbacks = model.accessCodeModelCallbacks, callbacks = model.accessCodeModelCallbacks,
), ),
@ -54,7 +53,6 @@ internal class AddExistingWalletChildFactory @Inject constructor(
is AddExistingWalletRoute.ConfirmAccessCode -> accessCodeComponentFactory.create( is AddExistingWalletRoute.ConfirmAccessCode -> accessCodeComponentFactory.create(
context = childContext, context = childContext,
params = AccessCodeComponent.Params( params = AccessCodeComponent.Params(
isConfirmMode = true,
accessCodeToConfirm = route.accessCode, accessCodeToConfirm = route.accessCode,
userWalletId = route.userWalletId, userWalletId = route.userWalletId,
callbacks = model.accessCodeModelCallbacks, callbacks = model.accessCodeModelCallbacks,

View file

@ -35,11 +35,11 @@ internal class UpdateAccessCodeModel @Inject constructor(
} }
} }
override fun onAccessCodeSet(userWalletId: UserWalletId, accessCode: String) { override fun onNewAccessCodeInput(userWalletId: UserWalletId, accessCode: String) {
stackNavigation.push(UpdateAccessCodeRoute.ConfirmAccessCode(userWalletId, accessCode)) stackNavigation.push(UpdateAccessCodeRoute.ConfirmAccessCode(userWalletId, accessCode))
} }
override fun onAccessCodeConfirmed(userWalletId: UserWalletId) { override fun onAccessCodeUpdated(userWalletId: UserWalletId) {
router.pop() router.pop()
} }
} }

View file

@ -19,7 +19,6 @@ internal class UpdateAccessCodeChildFactory @Inject constructor(
is UpdateAccessCodeRoute.SetAccessCode -> accessCodeComponentFactory.create( is UpdateAccessCodeRoute.SetAccessCode -> accessCodeComponentFactory.create(
context = childContext, context = childContext,
params = AccessCodeComponent.Params( params = AccessCodeComponent.Params(
isConfirmMode = false,
userWalletId = route.userWalletId, userWalletId = route.userWalletId,
callbacks = model, callbacks = model,
), ),
@ -27,7 +26,6 @@ internal class UpdateAccessCodeChildFactory @Inject constructor(
is UpdateAccessCodeRoute.ConfirmAccessCode -> accessCodeComponentFactory.create( is UpdateAccessCodeRoute.ConfirmAccessCode -> accessCodeComponentFactory.create(
context = childContext, context = childContext,
params = AccessCodeComponent.Params( params = AccessCodeComponent.Params(
isConfirmMode = true,
accessCodeToConfirm = route.accessCode, accessCodeToConfirm = route.accessCode,
userWalletId = route.userWalletId, userWalletId = route.userWalletId,
callbacks = model, callbacks = model,

View file

@ -7,8 +7,13 @@ import kotlinx.serialization.Serializable
internal sealed class UpdateAccessCodeRoute : Route { internal sealed class UpdateAccessCodeRoute : Route {
@Serializable @Serializable
data class SetAccessCode(val userWalletId: UserWalletId) : UpdateAccessCodeRoute() data class SetAccessCode(
val userWalletId: UserWalletId,
) : UpdateAccessCodeRoute()
@Serializable @Serializable
data class ConfirmAccessCode(val userWalletId: UserWalletId, val accessCode: String) : UpdateAccessCodeRoute() data class ConfirmAccessCode(
val userWalletId: UserWalletId,
val accessCode: String,
) : UpdateAccessCodeRoute()
} }

View file

@ -141,11 +141,11 @@ internal class WalletActivationModel @Inject constructor(
} }
inner class AccessCodeModelCallbacks : AccessCodeComponent.ModelCallbacks { inner class AccessCodeModelCallbacks : AccessCodeComponent.ModelCallbacks {
override fun onAccessCodeSet(userWalletId: UserWalletId, accessCode: String) { override fun onNewAccessCodeInput(userWalletId: UserWalletId, accessCode: String) {
stackNavigation.push(WalletActivationRoute.ConfirmAccessCode(accessCode)) stackNavigation.push(WalletActivationRoute.ConfirmAccessCode(accessCode))
} }
override fun onAccessCodeConfirmed(userWalletId: UserWalletId) { override fun onAccessCodeUpdated(userWalletId: UserWalletId) {
navigateToPushNotificationsOrNext() navigateToPushNotificationsOrNext()
} }
} }

View file

@ -55,7 +55,6 @@ internal class WalletActivationChildFactory @Inject constructor(
is WalletActivationRoute.SetAccessCode -> accessCodeComponentFactory.create( is WalletActivationRoute.SetAccessCode -> accessCodeComponentFactory.create(
context = childContext, context = childContext,
params = AccessCodeComponent.Params( params = AccessCodeComponent.Params(
isConfirmMode = false,
userWalletId = model.params.userWalletId, userWalletId = model.params.userWalletId,
callbacks = model.accessCodeModelCallbacks, callbacks = model.accessCodeModelCallbacks,
), ),
@ -63,7 +62,6 @@ internal class WalletActivationChildFactory @Inject constructor(
is WalletActivationRoute.ConfirmAccessCode -> accessCodeComponentFactory.create( is WalletActivationRoute.ConfirmAccessCode -> accessCodeComponentFactory.create(
context = childContext, context = childContext,
params = AccessCodeComponent.Params( params = AccessCodeComponent.Params(
isConfirmMode = true,
accessCodeToConfirm = route.accessCode, accessCodeToConfirm = route.accessCode,
userWalletId = model.params.userWalletId, userWalletId = model.params.userWalletId,
callbacks = model.accessCodeModelCallbacks, callbacks = model.accessCodeModelCallbacks,

View file

@ -46,6 +46,7 @@ import com.tangem.feature.walletsettings.utils.AccountItemsDelegate
import com.tangem.feature.walletsettings.utils.ItemsBuilder import com.tangem.feature.walletsettings.utils.ItemsBuilder
import com.tangem.feature.walletsettings.utils.WalletCardItemDelegate import com.tangem.feature.walletsettings.utils.WalletCardItemDelegate
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -57,7 +58,6 @@ import javax.inject.Inject
@Suppress("LongParameterList", "LargeClass") @Suppress("LongParameterList", "LargeClass")
@ModelScoped @ModelScoped
internal class WalletSettingsModel @Inject constructor( internal class WalletSettingsModel @Inject constructor(
getWalletUseCase: GetUserWalletUseCase,
paramsContainer: ParamsContainer, paramsContainer: ParamsContainer,
private val router: Router, private val router: Router,
private val messageSender: UiMessageSender, private val messageSender: UiMessageSender,
@ -73,6 +73,7 @@ internal class WalletSettingsModel @Inject constructor(
private val enableWalletNFTUseCase: EnableWalletNFTUseCase, private val enableWalletNFTUseCase: EnableWalletNFTUseCase,
private val disableWalletNFTUseCase: DisableWalletNFTUseCase, private val disableWalletNFTUseCase: DisableWalletNFTUseCase,
getWalletNotificationsEnabledUseCase: GetWalletNotificationsEnabledUseCase, getWalletNotificationsEnabledUseCase: GetWalletNotificationsEnabledUseCase,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase, private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase,
private val settingsManager: SettingsManager, private val settingsManager: SettingsManager,
private val permissionsRepository: PermissionRepository, private val permissionsRepository: PermissionRepository,
@ -80,6 +81,7 @@ internal class WalletSettingsModel @Inject constructor(
private val getIsHuaweiDeviceWithoutGoogleServicesUseCase: GetIsHuaweiDeviceWithoutGoogleServicesUseCase, private val getIsHuaweiDeviceWithoutGoogleServicesUseCase: GetIsHuaweiDeviceWithoutGoogleServicesUseCase,
private val isUpgradeWalletNotificationEnabledUseCase: IsUpgradeWalletNotificationEnabledUseCase, private val isUpgradeWalletNotificationEnabledUseCase: IsUpgradeWalletNotificationEnabledUseCase,
private val dismissUpgradeWalletNotificationUseCase: DismissUpgradeWalletNotificationUseCase, private val dismissUpgradeWalletNotificationUseCase: DismissUpgradeWalletNotificationUseCase,
private val unlockHotWalletContextualUseCase: UnlockHotWalletContextualUseCase,
) : Model() { ) : Model() {
val params: WalletSettingsComponent.Params = paramsContainer.require() val params: WalletSettingsComponent.Params = paramsContainer.require()
@ -144,7 +146,7 @@ internal class WalletSettingsModel @Inject constructor(
) )
} }
} }
getWalletUseCase.invokeFlow(params.userWalletId) getUserWalletUseCase.invokeFlow(params.userWalletId)
.distinctUntilChanged() .distinctUntilChanged()
.filterIsInstance<Either.Right<UserWallet>>() .filterIsInstance<Either.Right<UserWallet>>()
.flatMapLatest { combineUI(it.value) } .flatMapLatest { combineUI(it.value) }
@ -361,7 +363,27 @@ internal class WalletSettingsModel @Inject constructor(
if (!state.value.isWalletBackedUp) { if (!state.value.isWalletBackedUp) {
messageSender.send(makeBackupAtFirstAlertBS) messageSender.send(makeBackupAtFirstAlertBS)
} else { } else {
router.push(AppRoute.UpdateAccessCode(params.userWalletId)) val userWallet = getUserWalletUseCase(params.userWalletId)
.getOrElse { error("User wallet with id ${params.userWalletId} not found") }
if (userWallet is UserWallet.Hot) {
val hotWalletId = userWallet.hotWalletId
when (hotWalletId.authType) {
HotWalletId.AuthType.NoPassword -> {
router.push(AppRoute.UpdateAccessCode(params.userWalletId))
}
HotWalletId.AuthType.Password,
HotWalletId.AuthType.Biometry,
-> modelScope.launch {
unlockHotWalletContextualUseCase.invoke(hotWalletId)
.onLeft {
Timber.e("Unable to unlock wallet with id ${params.userWalletId}")
}
.onRight {
router.push(AppRoute.UpdateAccessCode(params.userWalletId))
}
}
}
}
} }
} }

View file

@ -11,7 +11,7 @@ tangemCardSdk = "develop-561"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
tangemVico = "2.0.0-alpha.25-tangem12" tangemVico = "2.0.0-alpha.25-tangem12"
#tangemVico = "0.0.1" # Keep it! - used for local builds ^ #tangemVico = "0.0.1" # Keep it! - used for local builds ^
tangemHotSdk = "develop-526" tangemHotSdk = "develop-527"
#tangemHotSdk = "0.0.1" # Keep it! - used for local builds ^ #tangemHotSdk = "0.0.1" # Keep it! - used for local builds ^