Add Private Key and Encrypted JSON Keystore Login to Guardian Recovery Portal
- Dominant language
- JavaScript
- Stars
- 2
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Overview
Currently, the Guardian Recovery Portal only supports wallet connection via RainbowKit/Wagmi (MetaMask, WalletConnect, Coinbase Wallet, etc.). This limits accessibility for guardians who may not have these wallets installed or who have their keys stored in other formats.
## Problem
In recovery scenarios, guardians may:
- Not have MetaMask or other wallet extensions installed
- Have their guardian keys backed up as raw private keys
- Have encrypted JSON keystores (exported from MyEtherWallet, Geth, etc.)
- Need emergency access without setting up a full wallet
## Proposed Solution
Add two additional login methods to the Guardian Recovery Portal:
### 1. Private Key Login
- Direct input of raw private key (hex format)
- Create ethers.js Wallet from private key
- Connect to provider and use as signer
### 2. Encrypted JSON Keystore Login
- File upload for JSON keystore
- Password input to decrypt
- Use `ethers.Wallet.fromEncryptedJson()` to decrypt and create signer
## Implementation Details
### UI Changes
**Location:** `frontend/src/screens/GuardianRecoveryPortal.jsx`
Add a tabbed interface with three login options:
1. **Wallet Connect** (current RainbowKit implementation)
2. **Private Key** (new)
3. **JSON Keystore** (new)
### Technical Implementation
#### Private Key Login
```javascript
import { ethers } from 'ethers';
// Create wallet from private key
const wallet = new ethers.Wallet(privateKey, provider);
const signer = wallet;
const address = wallet.address;
```
#### Encrypted JSON Keystore Login
```javascript
import { ethers } from 'ethers';
// Decrypt JSON keystore with password
const wallet = await ethers.Wallet.fromEncryptedJson(jsonKeystore, password);
const signer = wallet.connect(provider);
const address = wallet.address;
```
### New Files to Create
1. **`frontend/src/hooks/useManualWalletLogin.js`**
- Hook to handle private key and JSON keystore imports
- State management for manual login
- Signer creation and cleanup
2. **`frontend/src/components/PrivateKeyLogin.jsx`**
- UI for private key input
- Validation and error handling
- Security warnings
3. **`frontend/src/components/JsonKeystoreLogin.jsx`**
- File upload component
- Password input
- Decryption progress/error handling
4. **`frontend/src/styles/ManualLogin.css`**
- Styling for new login components
### Files to Modify
1. **`frontend/src/screens/GuardianRecoveryPortal.jsx`**
- Add tabbed interface for multiple login methods
- Integrate new login components
- Handle signer from different sources (RainbowKit vs manual)
### Security Considerations
⚠️ **Critical Security Requirements:**
1. **Never store private keys**
- Keep in memory only during session
- Clear on page unload/navigation
2. **Clear security warnings**
- Display prominent warnings about entering private keys
- Recommend using this only on trusted devices
- Warn about phishing risks
3. **HTTPS enforcement**
- Ensure portal is only accessible over HTTPS
- Add check to warn if not on secure connection
4. **Session cleanup**
- Clear all sensitive data on:
- Page unload
- Tab close
- Manual logout
- Session timeout
5. **Input validation**
- Validate private key format (64 hex chars)
- Validate JSON keystore structure
- Handle decryption errors gracefully
6. **No logging**
- Ensure private keys are never logged to console
- Sanitize error messages
### Example Security Warning UI
```
⚠️ Security Warning
You are about to enter your private key directly into this website.
Only proceed if:
✓ You are on a secure HTTPS connection
✓ You trust this website
✓ You are on a secure, private device
✓ You understand the risks
Never share your private key with anyone.
This key will only be stored in memory and will be cleared when you close this page.
```
## User Flow
### Private Key Login Flow
1. User clicks "Private Key" tab
2. Security warning is displayed
3. User acknowledges warning
4. User enters private key (with show/hide toggle)
5. System validates format
6. Wallet is created and address is displayed
7. User can proceed with recovery actions
8. On page close, private key is cleared from memory
### JSON Keystore Login Flow
1. User clicks "JSON Keystore" tab
2. Security warning is displayed
3. User uploads JSON file
4. System validates JSON structure
5. User enters password
6. System attempts decryption (with loading state)
7. On success, wallet is created and address is displayed
8. User can proceed with recovery actions
9. On page close, keystore and password are cleared from memory
## Acceptance Criteria
- [ ] Guardian Recovery Portal has three login methods: Wallet Connect, Private Key, JSON Keystore
- [ ] Private key login accepts valid hex private keys and creates working signer
- [ ] JSON keystore login accepts valid encrypted JSON and decrypts with password
- [ ] Both methods display clear security warnings before use
- [ ] Signers from manual login work with existing `RecoveryInitiator` and `RecoveryApprover` components
- [ ] Private keys/passwords are never stored in localStorage or sessionStorage
- [ ] All sensitive data is cleared on page unload
- [ ] Error handling for invalid inputs, wrong passwords, etc.
- [ ] UI is consistent with existing portal design
- [ ] Works on both desktop and mobile browsers
## Testing Checklist
- [ ] Test private key login with valid key
- [ ] Test private key login with invalid key (wrong format, wrong length)
- [ ] Test JSON keystore login with valid keystore and correct password
- [ ] Test JSON keystore login with wrong password
- [ ] Test JSON keystore login with invalid JSON file
- [ ] Verify signer can initiate recovery
- [ ] Verify signer can approve recovery
- [ ] Verify signer can execute recovery
- [ ] Verify private key is cleared on page refresh
- [ ] Verify private key is cleared on tab close
- [ ] Verify no private keys in console logs
- [ ] Test on different browsers (Chrome, Firefox, Safari)
- [ ] Test on mobile devices
## References
- Ethers.js Wallet documentation: https://docs.ethers.org/v6/api/wallet/#Wallet
- Ethers.js encrypted JSON: https://docs.ethers.org/v6/api/wallet/#Wallet-fromEncryptedJson
- Current Guardian Recovery Portal: `frontend/src/screens/GuardianRecoveryPortal.jsx`
- Existing Web3Auth private key handling: `frontend/src/contexts/Web3AuthContext.jsx` (lines 191-220)
## Priority
**Medium** - This is a nice-to-have feature that improves accessibility but is not critical for core functionality.
## Labels
enhancement, frontend, security, recovery
Contributor guide
Assessment
This issue has not been assessed yet.