Updated on 2026-08-14
This commit is contained in:
parent
77f097766d
commit
bf9dbc3535
4 changed files with 25 additions and 67 deletions
|
|
@ -14,10 +14,13 @@ import com.tangem.tap.domain.userWalletList.repository.implementation.BiometricU
|
|||
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultSelectedUserWalletRepository
|
||||
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsPublicInformationRepository
|
||||
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsSensitiveInformationRepository
|
||||
import com.tangem.tap.domain.userWalletList.utils.json.*
|
||||
import com.tangem.tap.domain.userWalletList.utils.json.ByteArrayKeyAdapter
|
||||
import com.tangem.tap.domain.userWalletList.utils.json.CardBackupStatusAdapter
|
||||
import com.tangem.tap.domain.userWalletList.utils.json.ExtendedPublicKeysMapAdapter
|
||||
import com.tangem.tap.domain.userWalletList.utils.json.ScanResponseDerivedKeysMapAdapter
|
||||
import com.tangem.tap.domain.userWalletList.utils.json.WalletDerivedKeysMapAdapter
|
||||
|
||||
const val USER_WALLETS_STORAGE_NAME = "user_wallets_storage"
|
||||
const val USER_WALLETS_BIOMETRIC_KEY_NAME = "user_wallets"
|
||||
private const val USER_WALLETS_STORAGE_NAME = "user_wallets_storage"
|
||||
|
||||
fun UserWalletsListManager.Companion.provideBiometricImplementation(
|
||||
context: Context,
|
||||
|
|
@ -43,7 +46,6 @@ fun UserWalletsListManager.Companion.provideBiometricImplementation(
|
|||
)
|
||||
|
||||
val keysRepository = BiometricUserWalletsKeysRepository(
|
||||
biometricKeyName = USER_WALLETS_BIOMETRIC_KEY_NAME,
|
||||
moshi = moshi,
|
||||
secureStorage = secureStorage,
|
||||
biometricManager = tangemSdkManager.biometricManager,
|
||||
|
|
@ -61,7 +63,6 @@ fun UserWalletsListManager.Companion.provideBiometricImplementation(
|
|||
)
|
||||
|
||||
return BiometricUserWalletsListManager(
|
||||
tangemSdkManager = tangemSdkManager,
|
||||
keysRepository = keysRepository,
|
||||
publicInformationRepository = publicInformationRepository,
|
||||
sensitiveInformationRepository = sensitiveInformationRepository,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.tap.domain.userWalletList.implementation
|
|||
import com.tangem.common.*
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.domain.common.util.encryptionKey
|
||||
import com.tangem.tap.domain.TangemSdkManager
|
||||
import com.tangem.tap.domain.model.UserWallet
|
||||
import com.tangem.tap.domain.userWalletList.UserWalletListError
|
||||
import com.tangem.tap.domain.userWalletList.UserWalletsListManager
|
||||
|
|
@ -20,7 +19,6 @@ import timber.log.Timber
|
|||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class BiometricUserWalletsListManager(
|
||||
private val tangemSdkManager: TangemSdkManager,
|
||||
private val keysRepository: UserWalletsKeysRepository,
|
||||
private val publicInformationRepository: UserWalletsPublicInformationRepository,
|
||||
private val sensitiveInformationRepository: UserWalletsSensitiveInformationRepository,
|
||||
|
|
@ -83,7 +81,6 @@ internal class BiometricUserWalletsListManager(
|
|||
}
|
||||
|
||||
override fun lock() {
|
||||
tangemSdkManager.biometricManager.unauthenticate()
|
||||
state.update { prevState ->
|
||||
prevState.copy(
|
||||
encryptionKeys = emptyList(),
|
||||
|
|
@ -122,14 +119,15 @@ internal class BiometricUserWalletsListManager(
|
|||
if (isWalletSaved && !canOverride) {
|
||||
CompletionResult.Failure(UserWalletListError.WalletAlreadySaved)
|
||||
} else {
|
||||
keysRepository.save(
|
||||
walletId = userWallet.walletId,
|
||||
encryptionKey = userWallet.scanResponse.card.encryptionKey,
|
||||
)
|
||||
.doOnSuccess { keys ->
|
||||
val newEncryptionKeys = state.value.encryptionKeys
|
||||
.plus(UserWalletEncryptionKey(userWallet.walletId, userWallet.scanResponse.card.encryptionKey))
|
||||
.distinctBy { it.walletId }
|
||||
|
||||
keysRepository.store(newEncryptionKeys)
|
||||
.doOnSuccess {
|
||||
state.update { prevState ->
|
||||
prevState.copy(
|
||||
encryptionKeys = (keys + prevState.encryptionKeys).distinctBy { it.walletId },
|
||||
encryptionKeys = newEncryptionKeys,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -146,21 +144,22 @@ internal class BiometricUserWalletsListManager(
|
|||
val walletIdsToRemove = state.value.wallets
|
||||
.map { it.walletId }
|
||||
.filter { it in walletIds }
|
||||
val remainingEncryptionKeys = state.value.encryptionKeys
|
||||
.filter { it.walletId !in walletIdsToRemove }
|
||||
|
||||
changeSelectedWalletIfNeeded(walletIdsToRemove)
|
||||
|
||||
return sensitiveInformationRepository.delete(walletIdsToRemove)
|
||||
.flatMap { publicInformationRepository.delete(walletIdsToRemove) }
|
||||
.flatMap { keysRepository.delete(walletIdsToRemove) }
|
||||
.map { keys ->
|
||||
.flatMap { keysRepository.store(remainingEncryptionKeys) }
|
||||
.map {
|
||||
state.update { prevState ->
|
||||
prevState.copy(
|
||||
encryptionKeys = keys,
|
||||
encryptionKeys = remainingEncryptionKeys,
|
||||
wallets = prevState.wallets.filter { it.walletId !in walletIdsToRemove },
|
||||
)
|
||||
}
|
||||
}
|
||||
.flatMap { loadModels() }
|
||||
}
|
||||
|
||||
override suspend fun clear(): CompletionResult<Unit> {
|
||||
|
|
@ -171,12 +170,11 @@ internal class BiometricUserWalletsListManager(
|
|||
.flatMap { keysRepository.clear() }
|
||||
.map {
|
||||
selectedUserWalletRepository.set(null)
|
||||
tangemSdkManager.biometricManager.unauthenticate()
|
||||
state.update { State() }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun get(walletId: UserWalletId): CompletionResult<UserWallet> = withUnlock {
|
||||
override suspend fun get(walletId: UserWalletId): CompletionResult<UserWallet> {
|
||||
return catching {
|
||||
state.value.wallets.first { it.walletId == walletId }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
package com.tangem.tap.domain.userWalletList.repository
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||
|
||||
internal interface UserWalletsKeysRepository {
|
||||
suspend fun getAll(): CompletionResult<List<UserWalletEncryptionKey>>
|
||||
suspend fun save(walletId: UserWalletId, encryptionKey: ByteArray): CompletionResult<List<UserWalletEncryptionKey>>
|
||||
suspend fun delete(walletIds: List<UserWalletId>): CompletionResult<List<UserWalletEncryptionKey>>
|
||||
suspend fun store(encryptionKeys: List<UserWalletEncryptionKey>): CompletionResult<Unit>
|
||||
suspend fun clear(): CompletionResult<Unit>
|
||||
}
|
||||
|
|
@ -6,24 +6,19 @@ import com.squareup.moshi.Types
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.biometric.BiometricManager
|
||||
import com.tangem.common.biometric.BiometricStorage
|
||||
import com.tangem.common.flatMap
|
||||
import com.tangem.common.map
|
||||
import com.tangem.common.mapFailure
|
||||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.tap.common.extensions.replaceByOrAdd
|
||||
import com.tangem.tap.domain.userWalletList.UserWalletListError
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||
import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository
|
||||
|
||||
internal class BiometricUserWalletsKeysRepository(
|
||||
biometricKeyName: String,
|
||||
moshi: Moshi,
|
||||
secureStorage: SecureStorage,
|
||||
biometricManager: BiometricManager,
|
||||
) : UserWalletsKeysRepository {
|
||||
private val biometricStorage = BiometricStorage(
|
||||
biometricKeyName = biometricKeyName,
|
||||
biometricManager = biometricManager,
|
||||
secureStorage = secureStorage,
|
||||
)
|
||||
|
|
@ -41,50 +36,16 @@ internal class BiometricUserWalletsKeysRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun save(
|
||||
walletId: UserWalletId,
|
||||
encryptionKey: ByteArray,
|
||||
): CompletionResult<List<UserWalletEncryptionKey>> {
|
||||
return getAll()
|
||||
.flatMap { keys ->
|
||||
if (keys.any { it.walletId == walletId }) {
|
||||
return@flatMap CompletionResult.Success(Unit)
|
||||
}
|
||||
|
||||
val encodedKeys = keys.toMutableList()
|
||||
.apply {
|
||||
replaceByOrAdd(UserWalletEncryptionKey(walletId, encryptionKey)) {
|
||||
it.walletId == walletId
|
||||
}
|
||||
}
|
||||
.encode()
|
||||
|
||||
biometricStorage.store(
|
||||
key = StorageKey.WalletEncryptionKeys.name,
|
||||
data = encodedKeys,
|
||||
)
|
||||
}
|
||||
.flatMap { getAll() }
|
||||
override suspend fun store(encryptionKeys: List<UserWalletEncryptionKey>): CompletionResult<Unit> {
|
||||
return biometricStorage.store(
|
||||
key = StorageKey.WalletEncryptionKeys.name,
|
||||
data = encryptionKeys.encode(),
|
||||
)
|
||||
.mapFailure { error ->
|
||||
UserWalletListError.SaveEncryptionKeysError(error.cause ?: error)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun delete(walletIds: List<UserWalletId>): CompletionResult<List<UserWalletEncryptionKey>> {
|
||||
return getAll()
|
||||
.map { keys ->
|
||||
val keysToRemove = keys.filter { it.walletId in walletIds }.toSet()
|
||||
(keys - keysToRemove).encode()
|
||||
}
|
||||
.flatMap { encodedKeys ->
|
||||
biometricStorage.store(
|
||||
key = StorageKey.WalletEncryptionKeys.name,
|
||||
data = encodedKeys,
|
||||
)
|
||||
}
|
||||
.flatMap { getAll() }
|
||||
}
|
||||
|
||||
override suspend fun clear(): CompletionResult<Unit> {
|
||||
return biometricStorage.delete(key = StorageKey.WalletEncryptionKeys.name)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue