A real-time, cryptographically secured chat application with client-side key generation, digital signature verification, and zero-trust architecture.
| Feature | Description |
|---|---|
| ** Client-Side Key Generation** | BIP39 mnemonic phrase generates an ECC keypair entirely in the browser — no secrets ever leave your device |
| ** Digital Signature Verification** | Every action (register, add friend, send message, upload file) is signed client-side and verified server-side using ethers.js |
| ** Real-Time Messaging** | Instant message delivery via Socket.IO with WebSocket transport |
| ** Presence System** | Live online/offline indicators and "last seen" timestamps for all connections |
| ** Read Receipts** | Triple-state delivery tracking: sent → delivered → seen |
| ** Typing Indicators** | Real-time "typing…" status with auto-timeout |
| ** File & Image Sharing** | Upload and share images/files (up to 5 MB) with cryptographic upload authorization |
| ** Username System** | Human-readable usernames mapped to cryptographic addresses |
| ** Zero-Trust Backend** | The server never stores private keys and verifies every request via signature recovery |
┌─────────────────────────────────────────────────────────────┐
│ CLIENT (React + Vite) │
│ │
│ ┌──────────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐ │
│ │ Landing │ │ Login │ │ Chat │ │ Crypto │ │
│ │ Page │ │ Page │ │ Page │ │ Utils │ │
│ └──────────┘ └───────────┘ └───────────┘ └──────────┘ │
│ │ │ │ │ │
│ └──────────────┴──────────────┴──────────────┘ │
│ │ │
│ ethers.js Wallet │
│ (BIP39 · ECC · Signatures) │
└──────────────────────────┬──────────────────────────────────┘
│ HTTP REST + WebSocket (Socket.IO)
┌──────────────────────────┴──────────────────────────────────┐
│ SERVER (Node.js + Express) │
│ │
│ ┌─────────────┐ ┌───────────────┐ ┌──────────────────┐ │
│ │ REST API │ │ Socket.IO │ │ Multer Upload │ │
│ │ Routes │ │ Events │ │ Pipeline │ │
│ └──────┬──────┘ └───────┬───────┘ └────────┬─────────┘ │
│ │ │ │ │
│ └─────────────────┴────────────────────┘ │
│ │ │
│ ethers.verifyMessage() │
│ (Signature Recovery on ALL ops) │
└──────────────────────────┬──────────────────────────────────┘
│
┌──────┴──────┐
│ MongoDB │
│ Atlas │
└─────────────┘
- Node.js ≥ 18
- npm ≥ 9
- A MongoDB instance (local or MongoDB Atlas)
git clone https://github.com/yadavayush834/chat_app.git
cd chat_appcd backend
npm installCreate a .env file in the backend/ directory:
MONGO_URI=mongodb+srv://<user>:<password>@<cluster>.mongodb.net/<dbname>
PORT=5000Start the server:
node server.jscd ../client
npm install
npm run devThe client will start on http://localhost:5173 by default.
chat_app/
├── backend/
│ ├── models/
│ │ ├── User.js # User schema (username, address, friends, presence)
│ │ └── Message.js # Message schema (sender, receiver, content, media, status)
│ ├── uploads/ # Multer file storage directory
│ ├── db.js # MongoDB connection handler
│ ├── server.js # Express server, REST API, Socket.IO events
│ ├── package.json
│ └── .env # Environment variables (MONGO_URI)
│
├── client/
│ ├── src/
│ │ ├── pages/
│ │ │ ├── LandingPage.jsx # Registration + wallet generation
│ │ │ ├── LoginPage.jsx # Mnemonic-based login
│ │ │ └── ChatPage.jsx # Main chat interface
│ │ ├── utils/
│ │ │ └── crypto.js # Wallet generation, restoration, signing
│ │ ├── App.jsx # React Router setup
│ │ ├── App.css # Component styles
│ │ ├── index.css # Global styles & design system
│ │ └── main.jsx # Entry point
│ ├── index.html
│ ├── vite.config.js
│ └── package.json
│
├── .gitignore
└── README.md
-
Registration — User picks a username. A BIP39 mnemonic phrase and ECC keypair are generated client-side. The registration request is signed and the server verifies ownership via
ethers.verifyMessage(). -
Login — User enters their 12-word mnemonic phrase. The wallet is reconstructed in-browser and the derived address is checked against the database.
-
Messaging — Every outgoing message is signed with the sender's private key. The server recovers the signer's address and rejects any message where the recovered address doesn't match the claimed sender.
-
Friend Requests — Adding a friend requires a signed payload to prevent impersonation.
-
File Uploads — Each upload includes a timestamped signature. Expired or invalid signatures cause the uploaded file to be immediately deleted.
-
Socket Authentication — WebSocket connections are authenticated with a timestamped signature (5-minute expiry window) to prevent replay attacks.
| Data | Stored? |
|---|---|
| Private keys | ❌ Never |
| Mnemonic phrases | ❌ Never |
| Raw passwords | ❌ N/A (passwordless) |
| Public addresses | ✅ As user identifier |
| Message content | ✅ Stored in DB |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/api/users/register |
Register a new username + address | Signature |
POST |
/api/users/me |
Fetch user profile & friends list | Address |
POST |
/api/users/friend |
Add a friend by username | Signature |
GET |
/api/messages/:addr/:friendAddr |
Get message history between two users | — |
POST |
/api/upload |
Upload a file attachment | Signature + Timestamp |
| Event | Direction | Description |
|---|---|---|
authenticate |
Client → Server | Authenticate socket connection with signed timestamp |
send_message |
Client → Server | Send a signed message |
receive_message |
Server → Client | Deliver incoming message |
message_sent |
Server → Client | Confirm message was saved |
typing / stop_typing |
Bidirectional | Typing indicator events |
update_message_status |
Client → Server | Mark messages as delivered/seen |
message_status_updated |
Server → Client | Notify sender of read receipts |
presence_update |
Server → Client | Online/offline status changes |
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite 8, React Router 7 |
| Backend | Node.js, Express 5 |
| Real-Time | Socket.IO 4 |
| Database | MongoDB (Mongoose 9) |
| Cryptography | ethers.js 6 (ECC / BIP39 / ECDSA) |
| File Uploads | Multer 2 |
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the ISC License.
Built with ❤️ using React, Node.js, and ethers.js