Overview
Medusa Wallet implements a multi-layered authentication system combining PIN codes, biometric authentication, and secure storage. The system protects sensitive data like API keys, access tokens, and user credentials.Authentication Architecture
The authentication system consists of three main components:- PIN Authentication: Primary security layer
- Biometric Authentication: Optional convenience layer (Face ID, Touch ID, fingerprint)
- Secure Storage: Encrypted storage for sensitive data
Storage Layers
MMKV Storage
MMKV Storage
Medusa uses react-native-mmkv for fast, unencrypted data storage:Use Cases:
- App state persistence (Zustand stores)
- User preferences and settings
- Last background timestamp for lock timing
- Non-sensitive application data
~/workspace/source/storage/mmkv.ts:1-31Encrypted Storage
Encrypted Storage
Sensitive data is stored using Expo’s SecureStore with hardware-backed encryption:Key Features:
- Hardware-backed encryption on supported devices
- Automatic key versioning for migrations
- Used exclusively for PIN storage
- Data persists across app updates
- iOS: Keychain Services
- Android: EncryptedSharedPreferences with AES256
~/workspace/source/storage/encrypted.ts:1-21PIN Authentication
PIN Storage and Validation
PIN Storage and Validation
PINs are stored in encrypted storage and validated through the auth store:Configuration:PIN Retry Logic:
- User has 3 attempts to enter correct PIN
- Each failed attempt decrements retry counter
- After 3 failed attempts, user is logged out
- Successful authentication resets retry counter
~/workspace/source/store/auth.ts:1-96App Lock Mechanism
App Lock Mechanism
The app automatically locks based on background time:Lock Behavior:
- Lock triggers after 1 minute in background
- 5-second grace period for quick app switches
- Grace period preserves route for camera/send/receive screens
- No lock when user is logged out
- Lock state persists across app restarts
~/workspace/source/hooks/useAppAuthentication.ts:65-148Biometric Authentication
Biometric Setup
Biometric Setup
Biometric authentication uses Expo’s LocalAuthentication:Security Requirements:
- Device must have biometric hardware
- User must be enrolled (Face ID/Touch ID configured)
- Enrolled level must be
BIOMETRIC_STRONGor higher - Device fallback (passcode) is disabled for security
~/workspace/source/hooks/useBiometric.ts:1-39Biometric Authentication Flow
Biometric Authentication Flow
Biometric takes precedence over PIN when enabled and available:Authentication Priority:
- Biometric (if enabled and available)
- PIN fallback (if biometric fails or unavailable)
- Logout (if PIN attempts exhausted)
~/workspace/source/hooks/useAppAuthentication.ts:100-134Privacy Screen
Inactive State Privacy
Inactive State Privacy
The app displays a privacy screen when inactive to protect sensitive information:Behavior:
- Triggers on
inactivestate (iOS) - Triggers on
backgroundstate (Android, due to app switcher behavior) - Replaces current screen to hide sensitive data
- Prevents screenshots in app switcher
- Automatically dismissed when app becomes active
~/workspace/source/hooks/useAppAuthentication.ts:73-78Auth Store State
State Management
State Management
The auth store manages authentication state across the app:Persistence:
- State persists to MMKV storage
- PIN stored separately in encrypted storage
- Access token cleared on logout
- Retry counter resets on successful auth
~/workspace/source/store/auth.ts:8-32Security Best Practices
- Layered Security: PIN required, biometric optional enhancement
- Hardware Encryption: Leverage device secure storage
- No Password Storage: Only store encrypted PINs
- Automatic Locking: Time-based app locks
- Retry Limits: Forced logout after failed attempts
- Privacy Screen: Hide data in app switcher
- No Screenshot Logging: Sensitive screens protected