Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-13 22:51:18 +08:00
parent 312740cd64
commit 5f95ba532e
4 changed files with 43 additions and 23 deletions

View file

@ -57,21 +57,11 @@ internal class BiometricUserWalletsListManager(
get() = state.value.userWallets.size
override suspend fun unlock(): CompletionResult<UserWallet> {
return unlockWithBiometryInternal()
.mapFailure { error ->
if (error is UserWalletsListError) {
error
} else {
UserWalletsListError.UnableToUnlockUserWallets(cause = error)
}
}
.map {
selectedUserWalletSync.guard {
throw UserWalletsListError.UnableToUnlockUserWallets(
cause = IllegalStateException("No user wallet selected"),
)
}
}
return unlockWithBiometryInternal().mapUnlockResult()
}
override suspend fun unlockAndSelect(selectedWalletId: UserWalletId): CompletionResult<UserWallet> {
return unlockWithBiometryInternal(selectedWalletId = selectedWalletId).mapUnlockResult()
}
override fun lock() {
@ -198,7 +188,7 @@ internal class BiometricUserWalletsListManager(
}
}
private suspend fun unlockWithBiometryInternal(): CompletionResult<Unit> {
private suspend fun unlockWithBiometryInternal(selectedWalletId: UserWalletId? = null): CompletionResult<Unit> {
return keysRepository.getAll()
.map { keys ->
state.update { prevState ->
@ -207,7 +197,7 @@ internal class BiometricUserWalletsListManager(
)
}
}
.flatMap { loadModels() }
.flatMap { loadModels(selectedWalletId = selectedWalletId) }
.map {
state.update { prevState ->
val hasLockedUserWallets = prevState.userWallets.any { it.isLocked }
@ -216,6 +206,24 @@ internal class BiometricUserWalletsListManager(
}
}
private fun CompletionResult<Unit>.mapUnlockResult(): CompletionResult<UserWallet> {
return this
.mapFailure { error ->
if (error is UserWalletsListError) {
error
} else {
UserWalletsListError.UnableToUnlockUserWallets(cause = error)
}
}
.map {
selectedUserWalletSync.guard {
throw UserWalletsListError.UnableToUnlockUserWallets(
cause = IllegalStateException("No user wallet selected"),
)
}
}
}
private suspend fun saveEncryptionKeyIfNotNull(userWallet: UserWallet): CompletionResult<ByteArray?> {
val encryptionKey = userWallet.scanResponse.card.encryptionKey
?.let { UserWalletEncryptionKey(userWallet.walletId, it) }
@ -237,7 +245,7 @@ internal class BiometricUserWalletsListManager(
}
}
private suspend fun loadModels(): CompletionResult<Unit> {
private suspend fun loadModels(selectedWalletId: UserWalletId? = null): CompletionResult<Unit> {
return getSavedUserWallets()
.map { userWallets ->
if (userWallets.isNotEmpty()) {
@ -247,7 +255,7 @@ internal class BiometricUserWalletsListManager(
prevState.copy(
userWallets = wallets,
selectedUserWalletId = findOrSetSelectedUserWalletId(
prevSelectedWalletId = prevState.selectedUserWalletId,
prevSelectedWalletId = selectedWalletId ?: prevState.selectedUserWalletId,
userWallets = wallets,
),
)

View file

@ -110,6 +110,13 @@ interface UserWalletsListManager {
*/
suspend fun unlock(): CompletionResult<UserWallet>
/**
* Unlock all [UserWallet]s and select passed [UserWalletId]
*
* @param selectedWalletId [UserWalletId] of [UserWallet] which must be selected
*/
suspend fun unlockAndSelect(selectedWalletId: UserWalletId): CompletionResult<UserWallet>
/** Remove [UserWallet]s from [userWallets] and set [isLocked] as true */
fun lock()
}

View file

@ -8,6 +8,7 @@ import com.tangem.common.doOnSuccess
import com.tangem.domain.wallets.legacy.WalletsStateHolder
import com.tangem.domain.wallets.legacy.asLockable
import com.tangem.domain.wallets.models.UnlockWalletError
import com.tangem.domain.wallets.models.UserWalletId
/**
* Unlock wallets use case
@ -18,11 +19,11 @@ import com.tangem.domain.wallets.models.UnlockWalletError
*/
class UnlockWalletsUseCase(private val walletsStateHolder: WalletsStateHolder) {
suspend operator fun invoke(): Either<UnlockWalletError, Unit> {
suspend operator fun invoke(selectedWalletId: UserWalletId): Either<UnlockWalletError, Unit> {
val userWalletsListManager = walletsStateHolder.userWalletsListManager?.asLockable()
?: return UnlockWalletError.CommonError.left()
userWalletsListManager.unlock()
userWalletsListManager.unlockAndSelect(selectedWalletId = selectedWalletId)
.doOnSuccess { return Unit.right() }
.doOnFailure { return UnlockWalletError.CommonError.left() }

View file

@ -763,10 +763,14 @@ internal class WalletViewModel @Inject constructor(
}
override fun onUnlockWalletClick() {
val state = uiState as? WalletState.ContentState ?: return
analyticsEventsHandler.send(WalletScreenAnalyticsEvent.NoticeWalletLocked)
viewModelScope.launch(dispatchers.io) {
unlockWalletsUseCase()
viewModelScope.launch(dispatchers.main) {
unlockWalletsUseCase(
selectedWalletId = state.walletsListConfig.wallets[state.walletsListConfig.selectedWalletIndex].id,
)
}
}