fix: allow isAuthenticating updates on frozen SecureKeychain#33406
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
PR template — items to address before "Ready for review"Warnings — informational, address before merging:
See docs/readme/ready-for-review.md for the full Definition of Ready for Review. |
🧪 Flaky unit test detectionRun history flaky detectionHistorical failure rate is a hint, not proof — review each suggestion in context. See the flaky-test-detection skill for the full pattern reference and manual audit workflow. Failures / runs sampled per window:
AI-detected flaky patterns
|
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
The test file adds one new test case verifying the refactored SecureKeychain is used in authentication/login flows, onboarding, and account security. Since this is a refactoring of the authentication keychain module, SmokeAccounts is the most relevant tag to verify that account security flows (SRP reveal, account management) still work correctly after the refactoring. The login/unlock path is also exercised as part of account tests. No other tags are needed because:
Performance Test Selection: |
|
⚡ Performance Test Results
❌ 1 test failed · 5 tests · 1 device 📱 Devices tested (1)Android: Google Pixel 8 Pro (v14.0) ❌ Failed Tests (1)@metamask-mobile-platform
✅ Passed Tests (4)
Branch: |



Description
Biometric / fingerprint unlock fails on the Login screen with:
TypeError: Cannot assign to read-only property 'isAuthenticating'
Root cause: SecureKeychain.init() calls Object.freeze(instance) on the singleton. During unlock, getGenericPassword() / getSecureItem() set instance.isAuthenticating = true|false so LockManagerService does not auto-lock mid-auth. That write mutates a frozen object. After the React Native 0.81 → 0.83 / Hermes upgrade (shipped with the 8.4 line), this assignment throws instead of failing silently, so Login surfaces the error and unlock cannot complete.
Solution: Keep Object.freeze(instance) (salt / instance integrity), but move isAuthenticating into the existing WeakMap-backed private state and expose it via getter/setter. Callers keep the same API; the flag can change without mutating frozen own-data properties.
Changelog
CHANGELOG entry: ixed fingerprint and biometric unlock failing with a read-only isAuthenticating error after the React Native 0.83 upgrade
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
screen-20260716-102617-1784190357463.mp4
After
fingerprint.mp4
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Note
Medium Risk
Touches login/unlock and auto-lock coordination during keychain auth; behavior is intended to be unchanged but failures would block wallet access.
Overview
Fixes biometric/fingerprint unlock failing on Login with
Cannot assign to read-only property 'isAuthenticating'after the RN 0.83 / Hermes upgrade, where writes to frozen objects now throw.SecureKeychain.init()stillObject.freezes the singleton, butisAuthenticatingis no longer an own property onSecureKeychainEncryptor. It lives in the existingWeakMapprivate state (alongsidecode) and is exposed through a getter/setter, sogetGenericPassword/getSecureItemcan flip the flag during auth without mutating the frozen instance.LockManagerServiceand other callers keep the sameinstance.isAuthenticatingAPI.Adds a unit test that
getSecureItemresetsisAuthenticatingto false on the frozen singleton after a mocked keychain read.Reviewed by Cursor Bugbot for commit 9c67f54. Configure here.