mirror of
https://github.com/kccleoc/seedpgp-web.git
synced 2026-03-07 09:57:50 +08:00
Update and rename _GPT-Suggestion.md to DEVELOPMENT.md
This commit is contained in:
291
DEVELOPMENT.md
Normal file
291
DEVELOPMENT.md
Normal file
@@ -0,0 +1,291 @@
|
||||
Here's your `DEVELOPMENT.md`:
|
||||
|
||||
```markdown
|
||||
# Development Guide - SeedPGP v1.1.0
|
||||
|
||||
## Architecture Quick Reference
|
||||
|
||||
### Core Types
|
||||
|
||||
```typescript
|
||||
// src/lib/types.ts
|
||||
interface SeedPgpPlaintext {
|
||||
v: number; // Version (always 1)
|
||||
t: string; // Type ("bip39")
|
||||
w: string; // Mnemonic words (normalized)
|
||||
l: string; // Language ("en")
|
||||
pp: number; // BIP39 passphrase used? (0 or 1)
|
||||
fpr?: string[]; // Optional recipient fingerprints
|
||||
}
|
||||
|
||||
interface ParsedSeedPgpFrame {
|
||||
kind: "single"; // Frame type
|
||||
crc16: string; // 4-digit hex checksum
|
||||
b45: string; // Base45 payload
|
||||
}
|
||||
```
|
||||
|
||||
### Frame Format
|
||||
|
||||
```
|
||||
SEEDPGP1:0:ABCD:BASE45DATA
|
||||
|
||||
SEEDPGP1 - Protocol identifier + version
|
||||
0 - Frame number (single frame)
|
||||
ABCD - CRC16-CCITT-FALSE checksum (4 hex digits)
|
||||
BASE45 - Base45-encoded PGP binary message
|
||||
```
|
||||
|
||||
### Key Functions
|
||||
|
||||
#### Encryption Flow
|
||||
```typescript
|
||||
buildPlaintext(mnemonic, bip39PassphraseUsed, recipientFingerprints?)
|
||||
→ SeedPgpPlaintext
|
||||
|
||||
encryptToSeedPgp({ plaintext, publicKeyArmored?, messagePassword? })
|
||||
→ { framed: string, pgpBytes: Uint8Array, recipientFingerprint?: string }
|
||||
```
|
||||
|
||||
#### Decryption Flow
|
||||
```typescript
|
||||
decryptSeedPgp({ frameText, privateKeyArmored?, privateKeyPassphrase?, messagePassword? })
|
||||
→ SeedPgpPlaintext
|
||||
|
||||
frameDecodeToPgpBytes(frameText)
|
||||
→ Uint8Array (with CRC16 validation)
|
||||
```
|
||||
|
||||
#### Encoding/Decoding
|
||||
```typescript
|
||||
frameEncode(pgpBinary: Uint8Array) → "SEEDPGP1:0:CRC16:BASE45"
|
||||
frameParse(text: string) → ParsedSeedPgpFrame
|
||||
frameDecodeToPgpBytes(frameText: string) → Uint8Array
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
```json
|
||||
{
|
||||
"openpgp": "^6.3.0", // PGP encryption (curve25519Legacy)
|
||||
"bun-types": "latest", // Bun runtime types
|
||||
"react": "^18.x", // UI framework
|
||||
"vite": "^5.x" // Build tool
|
||||
}
|
||||
```
|
||||
|
||||
### OpenPGP.js v6 Quirks
|
||||
|
||||
⚠️ **Important compatibility notes:**
|
||||
|
||||
1. **Empty password array bug**: Never pass `passwords: []` to `decrypt()`. Only include if non-empty:
|
||||
```typescript
|
||||
if (msgPw) {
|
||||
decryptOptions.passwords = [msgPw];
|
||||
}
|
||||
```
|
||||
|
||||
2. **Curve naming**: Use `curve25519Legacy` (not `curve25519`) in `generateKey()`
|
||||
|
||||
3. **Key validation**: Always call `getEncryptionKey()` to verify public key has usable subkeys
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
seedpgp-web/
|
||||
├── src/
|
||||
│ ├── lib/
|
||||
│ │ ├── seedpgp.ts # Core encrypt/decrypt logic
|
||||
│ │ ├── seedpgp.test.ts # Test vectors (15 tests)
|
||||
│ │ ├── base45.ts # Base45 encoder/decoder
|
||||
│ │ ├── crc16.ts # CRC16-CCITT-FALSE
|
||||
│ │ └── types.ts # TypeScript interfaces
|
||||
│ ├── App.tsx # React UI entry
|
||||
│ └── main.tsx # Vite bootstrap
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── vite.config.ts
|
||||
├── README.md
|
||||
└── DEVELOPMENT.md # This file
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# All tests
|
||||
bun test
|
||||
|
||||
# Watch mode
|
||||
bun test --watch
|
||||
|
||||
# Verbose output
|
||||
bun test --verbose
|
||||
```
|
||||
|
||||
### Development Server
|
||||
|
||||
```bash
|
||||
bun run dev # Start Vite dev server
|
||||
bun run build # Production build
|
||||
bun run preview # Preview production build
|
||||
```
|
||||
|
||||
### Adding Features
|
||||
|
||||
1. **Write tests first** in `seedpgp.test.ts`
|
||||
2. **Implement in** `src/lib/seedpgp.ts`
|
||||
3. **Update types** in `types.ts` if needed
|
||||
4. **Run full test suite**: `bun test`
|
||||
5. **Commit with conventional commits**: `feat: add QR generation`
|
||||
|
||||
## Feature Agenda
|
||||
|
||||
### 🚧 v1.2.0 - QR Code Round-Trip
|
||||
|
||||
**Goal**: Read back QR code and decrypt with user-provided credentials
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Add QR code generation from `encrypted.framed`
|
||||
- Library: `qrcode` or `qr-code-styling`
|
||||
- Input: SEEDPGP1 frame string
|
||||
- Output: QR code image/canvas/SVG
|
||||
|
||||
- [ ] Add QR code scanner UI
|
||||
- Library: `html5-qrcode` or `jsqr`
|
||||
- Camera/file upload input
|
||||
- Parse scanned text → `frameText`
|
||||
|
||||
- [ ] Build decrypt UI form
|
||||
- Input fields:
|
||||
- Scanned QR text (auto-filled)
|
||||
- Private key (file upload or paste)
|
||||
- Key passphrase (password input)
|
||||
- OR message password (alternative)
|
||||
- Call `decryptSeedPgp()`
|
||||
- Display recovered mnemonic + metadata
|
||||
|
||||
- [ ] Add visual feedback
|
||||
- CRC16 validation status
|
||||
- Key fingerprint match indicator
|
||||
- Decryption success/error states
|
||||
|
||||
**API Usage**:
|
||||
```typescript
|
||||
// Generate QR
|
||||
import QRCode from 'qrcode';
|
||||
const { framed } = await encryptToSeedPgp({ ... });
|
||||
const qrDataUrl = await QRCode.toDataURL(framed);
|
||||
|
||||
// Scan and decrypt
|
||||
const scannedText = "SEEDPGP1:0:ABCD:..."; // from scanner
|
||||
const decrypted = await decryptSeedPgp({
|
||||
frameText: scannedText,
|
||||
privateKeyArmored: userKey,
|
||||
privateKeyPassphrase: userPassword,
|
||||
});
|
||||
console.log(decrypted.w); // Recovered mnemonic
|
||||
```
|
||||
|
||||
**Security Notes**:
|
||||
- Never log decrypted mnemonics in production
|
||||
- Clear sensitive data from memory after use
|
||||
- Validate CRC16 before attempting decrypt
|
||||
- Show key fingerprint for user verification
|
||||
|
||||
---
|
||||
|
||||
### 🔮 Future Ideas (v1.3+)
|
||||
|
||||
- [ ] Multi-frame support (for larger payloads)
|
||||
- [ ] Password-only (SKESK) encryption flow
|
||||
- [ ] Shamir Secret Sharing integration
|
||||
- [ ] Hardware wallet key generation
|
||||
- [ ] Mobile companion app (React Native)
|
||||
- [ ] Printable paper backup templates
|
||||
- [ ] Encrypted cloud backup with PBKDF2
|
||||
- [ ] BIP85 child mnemonic derivation
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
### Enable verbose PGP logging
|
||||
|
||||
Uncomment in `seedpgp.ts`:
|
||||
```typescript
|
||||
console.log("Raw PGP hex:", Array.from(pgpBytes).map(...));
|
||||
console.log("SeedPGP: message packets:", ...);
|
||||
console.log("SeedPGP: encryption key IDs:", ...);
|
||||
```
|
||||
|
||||
### Test with known vectors
|
||||
|
||||
Use Trezor vectors from test file:
|
||||
```bash
|
||||
bun test "Trezor" # Run only Trezor tests
|
||||
```
|
||||
|
||||
### Validate frame manually
|
||||
|
||||
```typescript
|
||||
import { frameParse } from "./lib/seedpgp";
|
||||
const parsed = frameParse("SEEDPGP1:0:ABCD:...");
|
||||
console.log(parsed); // Check structure
|
||||
```
|
||||
|
||||
## Code Style
|
||||
|
||||
- **Functions**: Async by default, explicit return types
|
||||
- **Errors**: Throw descriptive Error objects with context
|
||||
- **Naming**: `camelCase` for functions, `PascalCase` for types
|
||||
- **Comments**: Only for non-obvious crypto/encoding logic
|
||||
- **Testing**: One test per edge case, descriptive names
|
||||
|
||||
## Git Workflow
|
||||
|
||||
```bash
|
||||
# Feature branch
|
||||
git checkout -b feat/qr-generation
|
||||
|
||||
# Conventional commits
|
||||
git commit -m "feat(qr): add QR code generation"
|
||||
git commit -m "test(qr): add QR round-trip test"
|
||||
|
||||
# Tag releases
|
||||
git tag -a v1.2.0 -m "Release v1.2.0 - QR round-trip"
|
||||
git push origin main --tags
|
||||
```
|
||||
|
||||
## Questions for Next Session
|
||||
|
||||
When continuing development, provide:
|
||||
|
||||
1. **Feature context**: "Adding QR code generation for v1.2.0"
|
||||
2. **Current code**: Paste relevant files you're modifying
|
||||
3. **Specific question**: "How should I structure the QR scanner component?"
|
||||
|
||||
Example starter prompt:
|
||||
```
|
||||
I'm working on seedpgp-web v1.1.0 (BIP39 PGP encryption tool).
|
||||
|
||||
[Paste this DEVELOPMENT.md section]
|
||||
[Paste relevant source files]
|
||||
|
||||
I want to add QR code generation. Here's my current seedpgp.ts...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-01-28
|
||||
**Maintainer**: @kccleoc
|
||||
```
|
||||
|
||||
Now commit it:
|
||||
|
||||
```bash
|
||||
git add DEVELOPMENT.md
|
||||
git commit -m "docs: add development guide with v1.2.0 QR agenda"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
Ready for your next feature sprint! 🚀📋
|
||||
@@ -1,10 +0,0 @@
|
||||
Next steps (optional):
|
||||
QR code generation - Add library to generate QR codes from encrypted.framed
|
||||
|
||||
UI integration - Connect to your React components
|
||||
|
||||
Multi-frame support - If you need to handle larger payloads (though mnemonics fit in single frame)
|
||||
|
||||
Password-only mode - Test SKESK-only encryption for backup scenarios
|
||||
|
||||
Your crypto wallet backup tool has a solid foundation! 🔐✨
|
||||
Reference in New Issue
Block a user