{"id":49171703,"url":"https://github.com/krushndayshmookh/whisp","last_synced_at":"2026-04-22T19:04:21.877Z","repository":{"id":313850056,"uuid":"1053133140","full_name":"krushndayshmookh/whisp","owner":"krushndayshmookh","description":"A privacy-first messaging app with zero server storage. Messages exist only while both peers are online, then vanish completely.","archived":false,"fork":false,"pushed_at":"2025-09-09T04:48:44.000Z","size":88,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-09T06:44:15.470Z","etag":null,"topics":["android","anonymous","dcode-2025","hacktoberfest","ios","javascript","messaging","nodejs","react-native","vue"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/krushndayshmookh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-09T03:23:07.000Z","updated_at":"2025-09-09T06:09:02.000Z","dependencies_parsed_at":"2025-09-10T05:02:43.864Z","dependency_job_id":null,"html_url":"https://github.com/krushndayshmookh/whisp","commit_stats":null,"previous_names":["krushndayshmookh/whisp"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/krushndayshmookh/whisp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krushndayshmookh%2Fwhisp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krushndayshmookh%2Fwhisp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krushndayshmookh%2Fwhisp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krushndayshmookh%2Fwhisp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krushndayshmookh","download_url":"https://codeload.github.com/krushndayshmookh/whisp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krushndayshmookh%2Fwhisp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32150399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T17:06:48.269Z","status":"ssl_error","status_checked_at":"2026-04-22T17:06:19.037Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","anonymous","dcode-2025","hacktoberfest","ios","javascript","messaging","nodejs","react-native","vue"],"created_at":"2026-04-22T19:04:18.979Z","updated_at":"2026-04-22T19:04:21.849Z","avatar_url":"https://github.com/krushndayshmookh.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Whisp - Ephemeral Messaging\n\nA privacy-first messaging app with zero server storage. Messages exist only while both peers are online, then vanish completely.\n\n## Core Principles\n\n- **No content on servers**: Server only handles discovery + signaling; never sees message payloads\n- **Ephemeral sessions**: Chats exist only while both peers are online; session keys die when either leaves\n- **Identity = keys, not PII**: Usernames are public aliases; trust is anchored in device/account keys\n- **Metadata minimization**: Store only what's essential for reachability; aggressively rotate/expire the rest\n\n## Architecture\n\n### System Components\n\n- **Directory/Signaling Server**: Maps usernames to online devices (volatile in-memory store)\n- **TURN/STUN**: NAT traversal for P2P; fallback to TURN relay (still E2E-encrypted)\n- **Clients**: Hold keys, contact list, and minimal logs locally; establish WebRTC data channels\n\n### Key Management\n\n- **Account Keypair (AK)**: Ed25519 for identity (long-term, per user)\n- **Device Keypair (DK)**: Ed25519 + Curve25519 for device auth and ECDH\n- **Pre-keys**: Short-lived X25519 bundles advertised only while online\n- **Session Keys**: Derived via X3DH → Double Ratchet for continuous PFS\n\n## User Flow\n\n### Account Setup\n\n1. Generate AK, DK, and initial pre-key bundle\n2. Choose username (check availability)\n3. Server records: username, AK_pub, deviceID, DK_pub (no private keys, no PII)\n4. Device stores private keys locally (Secure Enclave/KeyStore)\n\n### Multi-Device Support\n\n- **QR Handoff**: Old device displays enrollment token (signed with AK_priv)\n- **OTP Handoff**: Remote device addition with signed token\n\n### Contacting Someone\n\n1. Enter username → server returns online status + safety number\n2. If online, request session → server forwards connection request\n3. Both sides fetch pre-keys and run X3DH/Noise key exchange\n4. Switch to Double Ratchet on P2P channel\n\n## Messaging\n\n- **Transport**: WebRTC DataChannel or QUIC\n- **Encryption**: Double Ratchet with PFS + post-compromise security\n- **Storage**: Messages only in memory (ring buffer), cleared on disconnect\n- **No persistence**: App close/OS kill/lock → buffer cleared\n\n## Privacy \u0026 Security\n\n### What Server Stores\n\n- **Persistent**: username, AK_pub, deviceID, DK_pub, push tokens\n- **Ephemeral**: Online presence, pre-key bundles, session offers\n- **Never**: Messages, contact lists, safety numbers, IP logs\n\n### Threat Mitigations\n\n- **Server compromise**: Only public keys leak—no content or history\n- **MITM prevention**: Authenticated AKE + safety number verification\n- **Metadata protection**: TURN-only mode to hide peer IPs\n- **Spam prevention**: Rate limits + proof-of-work for first contact\n- **Device loss**: Revoke device with signed revocation from another device\n\n## Tech Stack\n\n- **Mobile**:\n  - **Android**: Kotlin + Jetpack Compose + Retrofit + OkHttp\n  - **iOS**: Swift + SwiftUI + Combine + URLSession\n  - **Cross-platform**: React Native + Expo\n- **Web**: Vue.js 3 + Axios\n- **Transport**: WebSocket + HTTP REST API\n- **Crypto**: Android Keystore + iOS Keychain + JWT\n- **Server**: Node.js + Express + SQLite\n- **Push**: APNs / FCM with opaque tokens\n\n## MVP Features\n\n- ✅ **Cross-platform clients**: Android, iOS, Expo, Vue web\n- ✅ **Account creation and username claim**\n- ✅ **Device key generation and secure storage**\n- ✅ **Real-time ephemeral messaging via WebSocket**\n- ✅ **In-memory ephemeral sessions**\n- ✅ **Friend management system**\n- ✅ **Environment-based configuration**\n- ✅ **Secure credential storage**\n- 🔄 Multi-device support via QR handoff\n- 🔄 Friend requests with safety number verification\n- 🔄 WebRTC messaging with Double Ratchet encryption\n- 🔄 TURN fallback and push notifications\n- 🔄 Device revocation and panic close\n\n## Discovery Modes\n\n### Privacy Levels\n\n1. **Public**: Directory shows username + online/offline status\n2. **Default**: Username-only lookup, no public directory  \n3. **Strict**: Username + Friend Verification Code (FVC) required\n\n### Friend Verification Code (FVC)\n\n- **TOTP-based**: Time-based codes (60-120s windows)\n- **Static**: One-time printed codes\n- **Privacy-first**: Server verifies without storing secrets\n\n## Competitor Analysis\n\n### Key Players\n\n- **Wickr Me**: Zero-knowledge logs, millisecond ephemeral chats\n- **Confide**: Screenshot-proof, self-destructing messages  \n- **Snapchat**: Mainstream ephemeral messaging\n- **Telegram Secret Chats**: E2EE with self-destruct timers\n- **Session**: Decentralized, no PII required\n\n### Our Differentiation\n\n- Live ephemeral messaging with zero storage anywhere\n- Strict control over presence \u0026 history\n- Flexible discovery modes with FVC\n- Real-time camera capture without disk storage\n\n## Development Roadmap\n\n### Phase 1: Core MVP\n\n- Account creation and device management\n- WebRTC messaging with Double Ratchet\n- In-memory ephemeral sessions\n- Basic friend system\n\n### Phase 2: Privacy Basics\n\n- Auto-delete timers (5s, 1m, 1h, 1d)\n- Server minimalism (presence only)\n- Panic close functionality\n\n### Phase 3: Trust \u0026 Control\n\n- Screenshot protection\n- Safety number verification\n- Friend Verification Codes\n\n### Phase 4: Feature Parity\n\n- Self-destructing media\n- Presence controls\n- Multi-device support\n\n### Phase 5: Differentiators\n\n- Custom discovery modes\n- Metadata hiding (TURN-only)\n- Group ephemeral chats\n\n### Phase 6: Advanced Privacy\n\n- E2E encryption implementation\n- Chunked file transfer\n- Decentralized relays\n\n## Environment Configuration\n\nThe Whisp application supports multiple environments with flexible configuration:\n\n### Quick Start (Development)\n\n```bash\n# Start all services for local development\n./start-dev.sh\n```\n\n### Environment-Specific Configuration\n\n- **Development**: Localhost URLs, debug logging, relaxed CORS\n- **Staging**: Pre-production testing with staging URLs\n- **Production**: Optimized performance, secure configuration\n\n### Client Configuration\n\n- **Expo**: Environment-specific `app.json` files\n- **Vue**: Automatic hostname detection with fallbacks\n- **iOS**: Build configurations and Info.plist settings\n- **Android**: Build variants and environment-specific URLs\n\n### Server Configuration\n\n- **Environment Variables**: `NODE_ENV`, `PORT`, `JWT_SECRET`, `CORS_ORIGIN`\n- **Environment Files**: `env.development`, `env.production`\n- **Scripts**: `npm run dev:env`, `npm run prod:env`\n\nFor detailed configuration instructions, see [ENVIRONMENT_CONFIG.md](./ENVIRONMENT_CONFIG.md).\n\n## Deployment\n\n### Development\n\n```bash\n# Start all services for local development\n./start-dev.sh\n```\n\n### Production\n\n```bash\n# Set required environment variables\nexport JWT_SECRET=\"your-super-secure-jwt-secret\"\nexport CORS_ORIGIN=\"https://yourdomain.com\"\n\n# Deploy all clients and server\n./deploy-prod.sh\n```\n\n## 📱 Client Applications\n\n### Android\n\n- **Technology**: Kotlin + Jetpack Compose\n- **Build**: `cd clients/android \u0026\u0026 ./gradlew assembleDebug`\n- **Run**: Open in Android Studio or `./gradlew installDebug`\n\n### iOS\n\n- **Technology**: Swift + SwiftUI\n- **Build**: Open `clients/ios/Whisp/Whisp.xcodeproj` in Xcode\n- **Run**: Build and run on device/simulator\n\n### Expo (Cross-platform)\n\n- **Technology**: React Native + Expo\n- **Build**: `cd clients/expo \u0026\u0026 npm run start:dev`\n- **Run**: Scan QR code with Expo Go app\n\n### Vue (Web)\n\n- **Technology**: Vue.js 3 + Axios\n- **Build**: Open `clients/vue/index.html` in browser\n- **Run**: Serve from any web server\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrushndayshmookh%2Fwhisp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrushndayshmookh%2Fwhisp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrushndayshmookh%2Fwhisp/lists"}