diff --git a/GEMINI.md b/GEMINI.md index 61bbd27..e900f30 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -2,7 +2,7 @@ ## Project Overview -**SeedPGP v1.4.2**: Client-side BIP39 mnemonic encryption webapp +**SeedPGP v1.4.3**: Client-side BIP39 mnemonic encryption webapp **Stack**: Bun + Vite + React + TypeScript + OpenPGP.js + Tailwind CSS **Deploy**: GitHub Pages (public repo: `seedpgp-web-app`, private source: `seedpgp-web`) **Live URL**: @@ -130,9 +130,23 @@ bun run preview # Preview production build ### Deployment Process -1. **Private repo** (`seedpgp-web`): Source code, development -2. **Public repo** (`seedpgp-web-app`): Built files for GitHub Pages -3. **Deploy script** (`scripts/deploy.sh`): Builds + copies to dist/ + pushes to public repo +**Production:** Cloudflare Pages (auto-deploys from `main` branch) +**Live URL:** + +### Cloudflare Pages Setup + +1. **Repository:** `seedpgp-web` (private repo) +2. **Build command:** `bun run build` +3. **Output directory:** `dist/` +4. **Security headers:** Automatically enforced via `public/_headers` + +### Benefits Over GitHub Pages + +- ✅ Real CSP header enforcement (blocks network requests at browser level) +- ✅ Custom security headers (X-Frame-Options, X-Content-Type-Options) +- ✅ Auto-deploy on push to main +- ✅ Build preview for PRs +- ✅ Better performance (global CDN) ### Git Workflow @@ -141,10 +155,19 @@ bun run preview # Preview production build git add src/ git commit -m "feat(v1.x): description" -# Tag version +# Tag version (triggers auto-deploy to Cloudflare) git tag v1.x.x git push origin main --tags +# **IMPORTANT: Update README.md before tagging** +# Update the following sections in README.md: +# - Current version number in header +# - Recent Changes section with new features +# - Any new usage instructions or screenshots +# Then commit the README update: +git add README.md +git commit -m "docs: update README for v1.x.x" + # Deploy to GitHub Pages ./scripts/deploy.sh v1.x.x ``` @@ -291,7 +314,7 @@ await window.runSessionCryptoTest() --- -## Current Version: v1.4.2 +## Current Version: v1.4.3 *Please update the "Recent Changes", "Known Limitations", and "Next Priorities" sections to reflect the current state of the project.* @@ -353,7 +376,6 @@ Check: Output: ✅ or ❌ for each item + suggest fixes for failures. ``` - --- **Last Updated**: 2026-01-29 diff --git a/README.md b/README.md index f7d8053..f43ef9a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# SeedPGP v1.1.0 +# SeedPGP v1.4.3 **Secure BIP39 mnemonic backup using PGP encryption and QR codes** -A TypeScript/Bun tool for encrypting cryptocurrency seed phrases with OpenPGP and encoding them as QR-friendly Base45 frames with CRC16 integrity checking. +A client-side web app for encrypting cryptocurrency seed phrases with OpenPGP and encoding them as QR-friendly Base45 frames with CRC16 integrity checking. + +**Live App:** ## Features @@ -11,7 +13,11 @@ A TypeScript/Bun tool for encrypting cryptocurrency seed phrases with OpenPGP an - ✅ **Integrity Checking**: CRC16-CCITT-FALSE checksums prevent corruption - 🔑 **BIP39 Support**: Full support for 12/18/24-word mnemonics with passphrase indicator - 🧪 **Battle-Tested**: Validated against official Trezor BIP39 test vectors -- ⚡ **Fast**: Built with Bun runtime for optimal performance +- ⚡ **Fast**: Built with Bun runtime and Vite for optimal performance +- 🔒 **Session-Key Encryption**: Ephemeral AES-GCM-256 encryption for in-memory protection +- 🛡️ **CSP Enforcement**: Real Content Security Policy headers block all network requests +- 📸 **QR Scanner**: Camera and file upload support for scanning encrypted QR codes +- 👁️ **Security Monitoring**: Real-time storage monitoring and clipboard tracking ## Installation @@ -32,7 +38,30 @@ bun run dev ## Usage -### Encrypt a Mnemonic +### Web Interface + +Visit or run locally: + +```bash +bun run dev +# Open http://localhost:5173 +``` + +**Backup Flow:** + +1. Enter your BIP39 mnemonic (12/18/24 words) +2. Import PGP public key or set encryption password +3. Click "Backup" to encrypt and generate QR code +4. Save/print QR code for offline storage + +**Restore Flow:** + +1. Scan QR code or paste encrypted text +2. Import PGP private key or enter password +3. Click "Restore" to decrypt mnemonic +4. Mnemonic auto-clears after 10 seconds + +### API Usage ```typescript import { encryptToSeedPgp, buildPlaintext } from "./lib/seedpgp"; @@ -64,106 +93,42 @@ console.log(decrypted.w); // Recovered mnemonic console.log(decrypted.pp); // BIP39 passphrase indicator (0 or 1) ``` -## Deployment to GitHub Pages (FREE) +## Deployment -This project uses a two-repository setup to keep source code private while hosting the app for free. +**Production:** Cloudflare Pages (auto-deploys from `main` branch) +**Live URL:** -### One-Time Setup +### Cloudflare Pages Setup -#### 1. Create Public Deployment Repo +This project is deployed on Cloudflare Pages for enhanced security features: -Go to https://github.com/new and create: -- **Name**: `seedpgp-web-app` (or any name you prefer) -- **Visibility**: **Public** -- **Don't** initialize with README, .gitignore, or license +1. **Repository:** `seedpgp-web` (private repo) +2. **Build command:** `bun run build` +3. **Output directory:** `dist/` +4. **Security headers:** Automatically enforced via `public/_headers` -#### 2. Configure Vite Base Path +### Benefits Over GitHub Pages -Edit `vite.config.ts`: +- ✅ Real CSP header enforcement (blocks network requests at browser level) +- ✅ Custom security headers (X-Frame-Options, X-Content-Type-Options) +- ✅ Auto-deploy on push to main +- ✅ Build preview for PRs +- ✅ Better performance (global CDN) +- ✅ Cost: $0/month -```typescript -export default defineConfig({ - plugins: [react()], - base: '/seedpgp-web-app/', // Match your public repo name -}) -``` - -#### 3. Build and Deploy +### Deployment Workflow ```bash -# Build the production bundle -bun run build +# Commit feature +git add src/ +git commit -m "feat(v1.x): description" -# Initialize git in dist folder -cd dist -git init -git add . -git commit -m "Deploy seedpgp v1.1.0" - -# Push to your public repo -git remote add origin https://github.com/kccleoc/seedpgp-web-app.git -git branch -M main -git push -u origin main - -# Return to project root -cd .. +# Tag version (triggers auto-deploy to Cloudflare) +git tag v1.x.x +git push origin main --tags ``` -#### 4. Enable GitHub Pages - -1. Go to `https://github.com/kccleoc/seedpgp-web-app/settings/pages` -2. **Source**: Deploy from a branch -3. **Branch**: Select `main` → `/` (root) -4. Click **Save** - -Wait 1-2 minutes, then visit: **https://kccleoc.github.io/seedpgp-web-app/** - ---- - -### Deploying Updates (v1.2.0, v1.3.0, etc.) - -Create `scripts/deploy.sh` in your project root: - -```bash -#!/bin/bash -set -e - -VERSION=$1 - -if [ -z "$VERSION" ]; then - echo "Usage: ./scripts/deploy.sh v1.2.0" - exit 1 -fi - -echo "🔨 Building $VERSION..." -bun run build - -echo "📦 Deploying to GitHub Pages..." -cd dist -git add . -git commit -m "Deploy $VERSION" || echo "No changes to commit" -git push - -cd .. -echo "✅ Deployed to https://kccleoc.github.io/seedpgp-web-app/" -echo "🏷️ Don't forget to tag: git tag $VERSION && git push --tags" -``` - -Make executable and use: - -```bash -chmod +x scripts/deploy.sh -./scripts/deploy.sh v1.2.0 -``` - ---- - -### Repository Structure - -- **seedpgp-web** (Private) - Your source code, active development -- **seedpgp-web-app** (Public) - Built files only, served via GitHub Pages - -**Cost: $0/month** ✅ +**No manual deployment needed!** Cloudflare Pages auto-deploys when you push to `main`. ## Frame Format @@ -183,6 +148,7 @@ BASE45 - Base45-encoded PGP message Creates a SeedPGP plaintext object. **Parameters:** + - `mnemonic` (string): BIP39 mnemonic phrase (12/18/24 words) - `bip39PassphraseUsed` (boolean): Whether a BIP39 passphrase was used - `recipientFingerprints` (string[]): Optional array of recipient key fingerprints @@ -194,6 +160,7 @@ Creates a SeedPGP plaintext object. Encrypts a plaintext object to SeedPGP format. **Parameters:** + ```typescript { plaintext: SeedPgpPlaintext; @@ -203,6 +170,7 @@ Encrypts a plaintext object to SeedPGP format. ``` **Returns:** + ```typescript { framed: string; // SEEDPGP1 frame @@ -216,6 +184,7 @@ Encrypts a plaintext object to SeedPGP format. Decrypts a SeedPGP frame. **Parameters:** + ```typescript { frameText: string; // SEEDPGP1 frame @@ -256,6 +225,8 @@ bun test --watch - **cv25519** provides ~128-bit security level - **CRC16** detects QR scan errors (not cryptographic) - Key fingerprint validation prevents wrong-key usage +- **Session-key encryption**: Ephemeral AES-GCM-256 for in-memory protection +- **CSP headers**: Browser-enforced network blocking via Cloudflare Pages ### ⚠️ Important Notes @@ -267,50 +238,129 @@ bun test --watch ### 🔒 Production Deployment Warning -The GitHub Pages deployment at **https://kccleoc.github.io/seedpgp-web-app/** is for: -- ✅ Testing and demonstration -- ✅ Convenient access for personal use +The Cloudflare Pages deployment at **** is for: + +- ✅ Personal use with enhanced security +- ✅ CSP enforcement blocks all network requests +- ✅ Convenient access from any device - ⚠️ Always verify the URL before use For maximum security with real funds: + - Run locally: `bun run dev` - Or self-host on your own domain with HTTPS +- Use an airgapped device for critical operations + +### Threat Model (Honest) + +**What we protect against:** + +- Accidental persistence to localStorage/sessionStorage +- Plaintext secrets lingering in React state after use +- Clipboard history exposure (with warnings) + +**What we DON'T protect against:** + +- Active XSS or malicious browser extensions +- Memory dumps or browser crash reports +- JavaScript garbage collection timing (non-deterministic) ## Project Structure ``` seedpgp-web/ ├── src/ +│ ├── components/ +│ │ ├── PgpKeyInput.tsx # PGP key import UI +│ │ ├── QrDisplay.tsx # QR code generation +│ │ ├── QrScanner.tsx # Camera + file scanner +│ │ ├── ReadOnly.tsx # Read-only mode toggle +│ │ ├── StorageIndicator.tsx # Storage monitoring +│ │ ├── SecurityWarnings.tsx # Context alerts +│ │ └── ClipboardTracker.tsx # Clipboard monitoring │ ├── lib/ -│ │ ├── seedpgp.ts # Core encryption/decryption -│ │ ├── seedpgp.test.ts # Test vectors -│ │ ├── base45.ts # Base45 codec -│ │ ├── crc16.ts # CRC16-CCITT-FALSE -│ │ └── types.ts # TypeScript definitions -│ └── App.tsx # React UI -├── scripts/ -│ └── deploy.sh # Deployment automation +│ │ ├── seedpgp.ts # Core encryption/decryption +│ │ ├── seedpgp.test.ts # Test vectors +│ │ ├── sessionCrypto.ts # Ephemeral session keys +│ │ ├── base45.ts # Base45 codec +│ │ ├── crc16.ts # CRC16-CCITT-FALSE +│ │ ├── qr.ts # QR utilities +│ │ └── types.ts # TypeScript definitions +│ ├── App.tsx # Main application +│ └── main.tsx # React entry point +├── public/ +│ └── _headers # Cloudflare CSP headers ├── package.json -├── DEVELOPMENT.md # Development guide -└── README.md # This file +├── vite.config.ts # Vite configuration +├── GEMINI.md # AI agent project brief +└── README.md # This file ``` ## Tech Stack - **Runtime**: [Bun](https://bun.sh) v1.3.6+ -- **Language**: TypeScript +- **Language**: TypeScript (strict mode) - **Crypto**: [OpenPGP.js](https://openpgpjs.org) v6.3.0 - **Framework**: React + Vite +- **UI**: Tailwind CSS +- **Icons**: lucide-react +- **QR**: html5-qrcode, qrcode - **Testing**: Bun test runner +- **Deployment**: Cloudflare Pages + +## Version History + +### v1.4.3 (2026-01-30) + +- ✅ Fixed textarea contrast for readability +- ✅ Fixed overlapping floating boxes +- ✅ Polished UI with modern crypto wallet design +- ✅ Updated background color to be lighter + +### v1.4.2 (2026-01-30) + +- ✅ Migrated to Cloudflare Pages for real CSP enforcement +- ✅ Added "Encrypted in memory" badge when mnemonic locked +- ✅ Improved security header configuration +- ✅ Updated deployment documentation + +### v1.4.0 (2026-01-29) + +- ✅ Extended session-key encryption to Restore flow +- ✅ Added 10-second auto-clear timer for restored mnemonic +- ✅ Added manual Hide button for immediate clearing +- ✅ Removed debug console logs from production + +### v1.3.0 (2026-01-28) + +- ✅ Implemented ephemeral session-key encryption (AES-GCM-256) +- ✅ Auto-clear mnemonic after QR generation (Backup flow) +- ✅ Encrypted cache for sensitive state +- ✅ Manual Lock/Clear functionality + +### v1.2.0 (2026-01-27) + +- ✅ Added storage monitoring (StorageIndicator) +- ✅ Added security warnings (context-aware) +- ✅ Added clipboard tracking +- ✅ Implemented read-only mode + +### v1.1.0 (2026-01-26) + +- ✅ Initial public release +- ✅ QR code generation and scanning +- ✅ Full BIP39 mnemonic support +- ✅ Trezor test vector validation +- ✅ Production-ready implementation ## Roadmap -- [ ] QR code generation UI -- [ ] QR code scanner with camera support +- [ ] UI polish (modern crypto wallet design) - [ ] Multi-frame support for larger payloads - [ ] Hardware wallet integration - [ ] Mobile scanning app - [ ] Shamir Secret Sharing support +- [ ] Reproducible builds with git hash verification ## License @@ -320,47 +370,6 @@ MIT License - see LICENSE file for details **kccleoc** - [GitHub](https://github.com/kccleoc) -## Version History - -### v1.1.0 (2026-01-28) -- Initial public release -- Full BIP39 mnemonic support -- Trezor test vector validation -- Production-ready implementation -- GitHub Pages deployment guide - --- ⚠️ **Disclaimer**: This software is provided as-is. Always test thoroughly before trusting with real funds. The author is not responsible for lost funds due to software bugs or user error. - -Now create the deployment script: - -```bash -mkdir -p scripts -cat > scripts/deploy.sh << 'EOF' -#!/bin/bash -set -e - -VERSION=$1 - -if [ -z "$VERSION" ]; then - echo "Usage: ./scripts/deploy.sh v1.2.0" - exit 1 -fi - -echo "🔨 Building $VERSION..." -bun run build - -echo "📦 Deploying to GitHub Pages..." -cd dist -git add . -git commit -m "Deploy $VERSION" || echo "No changes to commit" -git push - -cd .. -echo "✅ Deployed to https://kccleoc.github.io/seedpgp-web-app/" -echo "🏷️ Don't forget to tag: git tag $VERSION && git push --tags" -EOF - -chmod +x scripts/deploy.sh -``` diff --git a/package.json b/package.json index 82f8859..14bcf45 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "seedpgp-web", "private": true, - "version": "1.4.2", + "version": "1.4.3", "type": "module", "scripts": { "dev": "vite",