From b9c1113f8dcf0138e6ef55981bbaf32348351d07 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 30 Mar 2023 10:12:16 +0300 Subject: [PATCH 1/2] Updated on 2026-08-14 --- .../userWalletList/UserWalletsListError.kt | 4 +-- .../BiometricUserWalletsListManager.kt | 8 +++-- .../BiometricUserWalletsKeysRepository.kt | 33 ++++++++++++------- .../ui/WalletSelectorViewModel.kt | 2 +- .../features/welcome/ui/WelcomeViewModel.kt | 2 +- gradle/dependencies.toml | 4 +-- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListError.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListError.kt index 03ec981f62..c73891df83 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListError.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListError.kt @@ -14,8 +14,8 @@ sealed class UserWalletsListError(code: Int) : TangemError(code) { override val messageResId: Int = R.string.user_wallet_list_error_wallet_already_saved } - object InvalidEncryptionKey : UserWalletsListError(code = 60002) { - override var customMessage: String = "Invalid encryption key" + object EncryptionKeyInvalidated : UserWalletsListError(code = 60002) { + override var customMessage: String = "Encryption key invalidated" } data class BiometricsAuthenticationLockout(val isPermanent: Boolean) : UserWalletsListError(code = 60003) { diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt index 72244a8bf8..ad29020162 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt @@ -183,7 +183,11 @@ internal class BiometricUserWalletsListManager( return saveEncryptionKeyIfNotNull(userWallet) .flatMap { sensitiveInformationRepository.save(userWallet, encryptionKey = it) } .flatMap { publicInformationRepository.save(userWallet) } - .map { selectedUserWalletRepository.set(userWallet.walletId) } + .map { + if (changeSelectedUserWallet) { + selectedUserWalletRepository.set(userWallet.walletId) + } + } .flatMap { loadModels() } .doOnSuccess { state.update { prevState -> @@ -259,7 +263,7 @@ internal class BiometricUserWalletsListManager( } } .doOnFailure { error -> - if (error is UserWalletsListError.InvalidEncryptionKey) { + if (error is UserWalletsListError.EncryptionKeyInvalidated) { state.update { prevState -> prevState.copy( hasLockedUserWalletsAfterUnlock = true, diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt index 0307b8b7d4..5d39710ca7 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt @@ -46,7 +46,8 @@ internal class BiometricUserWalletsKeysRepository( UserWalletsListError.BiometricsAuthenticationLockout(isPermanent = false) is TangemSdkError.BiometricsAuthenticationPermanentLockout -> UserWalletsListError.BiometricsAuthenticationLockout(isPermanent = true) - is TangemSdkError.InvalidEncryptionKey -> UserWalletsListError.InvalidEncryptionKey + is TangemSdkError.BiometricCryptographyKeyInvalidated -> + UserWalletsListError.EncryptionKeyInvalidated else -> error } } @@ -91,28 +92,36 @@ internal class BiometricUserWalletsKeysRepository( private suspend fun getAllInternal(): CompletionResult> { return getUserWalletsIds() .map { userWalletId -> - // This is possible because the Card SDK cipher key has an expiration time - // If this operation runs more than that expiration time, the user will have to re-authorize - // to receive all keys + // It is possible to request multiple user wallet keys from biometric storage because + // the biometric cryptography key has an expiration time. + // If this operation runs more than that expiration time, then the user will have to re-authorize + // to receive all user wallets encryption keys getEncryptionKey(userWalletId) .flatMapOnFailure { error -> - // If key decryption failed then skip it - if (error is TangemSdkError.EncryptionOperationFailed) { - CompletionResult.Success(data = null) - } else { - CompletionResult.Failure(error) + when (error) { + is TangemSdkError.InvalidBiometricCryptographyKey, + is TangemSdkError.BiometricCryptographyOperationFailed, + -> { + // These errors can be skipped as the user has the option to re-save their wallets + // in case they occur + CompletionResult.Success(data = null) + } + else -> CompletionResult.Failure(error) } } .doOnFailure { error -> when (error) { is TangemSdkError.UserCanceledBiometricsAuthentication -> { - // If the user cancels biometric authentication, cancel the request for all keys + // If the user cancels biometric authentication, then cancel operation with error return CompletionResult.Failure(error) } - is TangemSdkError.InvalidEncryptionKey -> { - if (error.isKeyRegenerated) { + is TangemSdkError.BiometricCryptographyKeyInvalidated -> { + // If the biometric cryptography key was invalidated, + // then delete all user wallets encryption keys and cancel operation with error + getUserWalletsIds().forEach { userWalletId -> deleteEncryptionKey(userWalletId) } + return CompletionResult.Failure(error) } } } diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt index 0bdae60f69..2637e44e3b 100644 --- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt @@ -196,7 +196,7 @@ internal class WalletSelectorViewModel : ViewModel(), StoreSubscriber WarningModel.KeyInvalidatedWarning( + is UserWalletsListError.EncryptionKeyInvalidated -> WarningModel.KeyInvalidatedWarning( onDismiss = this::dismissWarningDialog, ) else -> currentDialog diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt index 4bbcdf76ea..3687df607c 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt @@ -68,7 +68,7 @@ internal class WelcomeViewModel : ViewModel(), StoreSubscriber { isPermanent = error.isPermanent, onDismiss = this::dismissWarning, ) - is UserWalletsListError.InvalidEncryptionKey -> WarningModel.KeyInvalidatedWarning( + is UserWalletsListError.EncryptionKeyInvalidated -> WarningModel.KeyInvalidatedWarning( onDismiss = this::dismissWarning, ) else -> null diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index b5543ac9e5..556b4d84ca 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -73,8 +73,8 @@ kotlinSerialization = "1.4.1" # region Tangem tangemBlockchainSdk = "develop-204" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "develop-218" -# tangemCardSdk = "0.0.1" # Keep it! - used for local builds +tangemCardSdk = "develop-225" +#tangemCardSdk = "0.0.1" # Keep it! - used for local builds # endregion Tangem # region Tools From f60ac8dcc642e53af2179df411547c48a0782e21 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 24 Apr 2023 15:01:59 +0300 Subject: [PATCH 2/2] Updated on 2026-08-14 --- .../common/analytics/TangemSdkErrorMapper.kt | 129 ------------------ 1 file changed, 129 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/common/analytics/TangemSdkErrorMapper.kt diff --git a/app/src/main/java/com/tangem/tap/common/analytics/TangemSdkErrorMapper.kt b/app/src/main/java/com/tangem/tap/common/analytics/TangemSdkErrorMapper.kt deleted file mode 100644 index a2eecd43e4..0000000000 --- a/app/src/main/java/com/tangem/tap/common/analytics/TangemSdkErrorMapper.kt +++ /dev/null @@ -1,129 +0,0 @@ -package com.tangem.tap.common.analytics - -import com.tangem.common.core.TangemSdkError - -object TangemSdkErrorMapper { - - // This mapping is performed to group errors in FirebaseCrashlytics. - // At the moment, the errors in Crashlytics can only be grouped by their place of creation (class and line). - @Suppress("LongMethod", "ComplexMethod") - fun map(error: TangemSdkError): TangemSdkError { - return when (error) { - is TangemSdkError.TagLost -> TangemSdkError.TagLost() - is TangemSdkError.ExtendedLengthNotSupported -> TangemSdkError.ExtendedLengthNotSupported() - is TangemSdkError.SerializeCommandError -> TangemSdkError.SerializeCommandError() - is TangemSdkError.DeserializeApduFailed -> TangemSdkError.DeserializeApduFailed() - is TangemSdkError.EncodingFailedTypeMismatch -> TangemSdkError.EncodingFailedTypeMismatch( - error.customMessage, - ) - is TangemSdkError.EncodingFailed -> TangemSdkError.EncodingFailed(error.customMessage) - is TangemSdkError.DecodingFailedMissingTag -> TangemSdkError.DecodingFailedMissingTag( - error.customMessage, - ) - is TangemSdkError.DecodingFailedTypeMismatch -> TangemSdkError.DecodingFailedTypeMismatch( - error.customMessage, - ) - is TangemSdkError.DecodingFailed -> TangemSdkError.DecodingFailed(error.customMessage) - is TangemSdkError.InvalidResponse -> TangemSdkError.InvalidResponse() - is TangemSdkError.UnknownStatus -> TangemSdkError.UnknownStatus(error.statusWord) - is TangemSdkError.ErrorProcessingCommand -> TangemSdkError.ErrorProcessingCommand() - is TangemSdkError.InvalidState -> TangemSdkError.InvalidState() - is TangemSdkError.InsNotSupported -> TangemSdkError.InsNotSupported() - is TangemSdkError.InvalidParams -> TangemSdkError.InvalidParams() - is TangemSdkError.NeedEncryption -> TangemSdkError.NeedEncryption() - is TangemSdkError.FileNotFound -> TangemSdkError.FileNotFound() - is TangemSdkError.WalletNotFound -> TangemSdkError.WalletNotFound() - is TangemSdkError.AlreadyPersonalized -> TangemSdkError.AlreadyPersonalized() - is TangemSdkError.CannotBeDepersonalized -> TangemSdkError.CannotBeDepersonalized() - is TangemSdkError.AccessCodeRequired -> TangemSdkError.AccessCodeRequired() - is TangemSdkError.CardReadWrongWallet -> TangemSdkError.CardReadWrongWallet() - is TangemSdkError.CardWithMaxZeroWallets -> TangemSdkError.CardWithMaxZeroWallets() - is TangemSdkError.AlreadyCreated -> TangemSdkError.AlreadyCreated() - is TangemSdkError.MaxNumberOfWalletsCreated -> TangemSdkError.MaxNumberOfWalletsCreated() - is TangemSdkError.PurgeWalletProhibited -> TangemSdkError.PurgeWalletProhibited() - is TangemSdkError.AccessCodeCannotBeChanged -> TangemSdkError.AccessCodeCannotBeChanged() - is TangemSdkError.PasscodeCannotBeChanged -> TangemSdkError.PasscodeCannotBeChanged() - is TangemSdkError.AccessCodeCannotBeDefault -> TangemSdkError.AccessCodeCannotBeDefault() - is TangemSdkError.NoRemainingSignatures -> TangemSdkError.NoRemainingSignatures() - is TangemSdkError.EmptyHashes -> TangemSdkError.EmptyHashes() - is TangemSdkError.HashSizeMustBeEqual -> TangemSdkError.HashSizeMustBeEqual() - is TangemSdkError.WalletIsNotCreated -> TangemSdkError.WalletIsNotCreated() - is TangemSdkError.SignHashesNotAvailable -> TangemSdkError.SignHashesNotAvailable() - is TangemSdkError.TooManyHashesInOneTransaction -> TangemSdkError.TooManyHashesInOneTransaction() - is TangemSdkError.ExtendedDataSizeTooLarge -> TangemSdkError.ExtendedDataSizeTooLarge() - is TangemSdkError.NotPersonalized -> TangemSdkError.NotPersonalized() - is TangemSdkError.NotActivated -> TangemSdkError.NotActivated() - is TangemSdkError.WalletIsPurged -> TangemSdkError.WalletIsPurged() - is TangemSdkError.PasscodeRequired -> TangemSdkError.PasscodeRequired() - is TangemSdkError.VerificationFailed -> TangemSdkError.VerificationFailed() - is TangemSdkError.DataSizeTooLarge -> TangemSdkError.DataSizeTooLarge() - is TangemSdkError.MissingCounter -> TangemSdkError.MissingCounter() - is TangemSdkError.OverwritingDataIsProhibited -> TangemSdkError.OverwritingDataIsProhibited() - is TangemSdkError.DataCannotBeWritten -> TangemSdkError.DataCannotBeWritten() - is TangemSdkError.MissingIssuerPubicKey -> TangemSdkError.MissingIssuerPubicKey() - is TangemSdkError.CardVerificationFailed -> TangemSdkError.CardVerificationFailed() - is TangemSdkError.WrongAccessCode -> TangemSdkError.WrongAccessCode() - is TangemSdkError.WrongPasscode -> TangemSdkError.WrongPasscode() - is TangemSdkError.UnknownError -> TangemSdkError.UnknownError() - is TangemSdkError.UserCancelled -> TangemSdkError.UserCancelled() - is TangemSdkError.Busy -> TangemSdkError.Busy() - is TangemSdkError.MissingPreflightRead -> TangemSdkError.MissingPreflightRead() - is TangemSdkError.WrongCardNumber -> TangemSdkError.WrongCardNumber() - is TangemSdkError.WrongCardType -> TangemSdkError.WrongCardType(null) - is TangemSdkError.CardError -> TangemSdkError.CardError() - is TangemSdkError.NotSupportedFirmwareVersion -> TangemSdkError.NotSupportedFirmwareVersion() - is TangemSdkError.WalletError -> TangemSdkError.WalletError() - is TangemSdkError.WalletCannotBeCreated -> TangemSdkError.WalletCannotBeCreated() - is TangemSdkError.UnsupportedCurve -> TangemSdkError.UnsupportedCurve() - is TangemSdkError.UnsupportedWalletConfig -> TangemSdkError.UnsupportedWalletConfig() - is TangemSdkError.CryptoUtilsError -> TangemSdkError.CryptoUtilsError(error.customMessage) - is TangemSdkError.NetworkError -> TangemSdkError.NetworkError(error.customMessage) - is TangemSdkError.ExceptionError -> TangemSdkError.ExceptionError(error.cause) - is TangemSdkError.TooMuchBackupCards -> TangemSdkError.TooMuchBackupCards() - is TangemSdkError.BackupCardRequired -> TangemSdkError.BackupCardRequired() - is TangemSdkError.CertificateSignatureRequired -> TangemSdkError.CertificateSignatureRequired() - is TangemSdkError.AccessCodeOrPasscodeRequired -> TangemSdkError.AccessCodeOrPasscodeRequired() - is TangemSdkError.ResetPinNoCardsToReset -> TangemSdkError.ResetPinNoCardsToReset() - is TangemSdkError.ResetPinWrongCard -> TangemSdkError.ResetPinWrongCard() - is TangemSdkError.BackupFailedCardNotLinked -> TangemSdkError.BackupFailedCardNotLinked() - is TangemSdkError.BackupNotAllowed -> TangemSdkError.BackupNotAllowed() - is TangemSdkError.BackupCardAlreadyAdded -> TangemSdkError.BackupCardAlreadyAdded() - is TangemSdkError.MissingPrimaryCard -> TangemSdkError.MissingPrimaryCard() - is TangemSdkError.MissingPrimaryAttestSignature -> TangemSdkError.MissingPrimaryAttestSignature() - is TangemSdkError.NoBackupDataForCard -> TangemSdkError.NoBackupDataForCard() - is TangemSdkError.BackupFailedEmptyWallets -> TangemSdkError.BackupFailedEmptyWallets() - is TangemSdkError.BackupFailedNotEmptyWallets -> TangemSdkError.BackupFailedNotEmptyWallets() - is TangemSdkError.NoActiveBackup -> TangemSdkError.NoActiveBackup() - is TangemSdkError.BackupServiceInvalidState -> TangemSdkError.BackupServiceInvalidState() - is TangemSdkError.NoBackupCardForIndex -> TangemSdkError.NoBackupCardForIndex() - is TangemSdkError.EmptyBackupCards -> TangemSdkError.EmptyBackupCards() - is TangemSdkError.BackupFailedWrongIssuer -> TangemSdkError.BackupFailedWrongIssuer() - is TangemSdkError.BackupFailedHDWalletSettings -> TangemSdkError.BackupFailedHDWalletSettings() - is TangemSdkError.BackupFailedNotEnoughCurves -> TangemSdkError.BackupFailedNotEnoughCurves() - is TangemSdkError.BackupFailedNotEnoughWallets -> TangemSdkError.BackupFailedNotEnoughWallets() - is TangemSdkError.FileSettingsUnsupported -> TangemSdkError.FileSettingsUnsupported() - is TangemSdkError.FilesIsEmpty -> TangemSdkError.FilesIsEmpty() - is TangemSdkError.FilesDisabled -> TangemSdkError.FilesDisabled() - is TangemSdkError.HDWalletDisabled -> TangemSdkError.HDWalletDisabled() - is TangemSdkError.WrongInteractionMode -> TangemSdkError.WrongInteractionMode() - is TangemSdkError.IssuerSignatureLoadingFailed -> TangemSdkError.IssuerSignatureLoadingFailed() - is TangemSdkError.BackupFailedFirmware -> TangemSdkError.BackupFailedFirmware() - is TangemSdkError.UserForgotTheCode -> TangemSdkError.UserForgotTheCode() - is TangemSdkError.BackupFailedIncompatibleBatch -> TangemSdkError.BackupFailedIncompatibleBatch() - is TangemSdkError.BiometricsUnavailable -> error - is TangemSdkError.BiometricsAuthenticationFailed -> error - is TangemSdkError.BiometricsAuthenticationLockout -> error - is TangemSdkError.BiometricsAuthenticationPermanentLockout -> error - is TangemSdkError.UserCanceledBiometricsAuthentication -> error - is TangemSdkError.EncryptionOperationFailed -> error - is TangemSdkError.InvalidEncryptionKey -> error - is TangemSdkError.KeyGenerationException -> error - is TangemSdkError.MnemonicException -> error - is TangemSdkError.WalletAlreadyCreated -> error - is TangemSdkError.ResetBackupFailedHasBackedUpWallets -> error - is TangemSdkError.KeysImportDisabled -> error - is TangemSdkError.Underlying -> error - is TangemSdkError.UserCodeRecoveryDisabled -> error - } - } -} \ No newline at end of file