尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證NodeX web app: decentralized, peer-to-peer chat in the browser (Next.js, libp2p)
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A decentralized, peer-to-peer chat app that runs in your browser.
Your identity lives on your device, not on a server.
The backend runs on Render's free plan, so after a quiet spell the first visit can take about a minute while it wakes up; the app connects by itself once it does. To try chat, open the app in a normal and a private window, create two identities, and search for one from the other by its handle.檢視完整 README ↗| Live | Address |
|---|---|
| App (Vercel) | https://node-x-frontend-red.vercel.app |
| Email verifier (Render) | https://nodex-verifier.onrender.com |
| P2P node (Render) | /dns4/nodex-node.onrender.com/tcp/443/wss/p2p/12D3KooWPXJbYpESjgy7rxyTgS6szXv373DHJBjidVRbzgSRAfr3 |
The backend runs on Render's free plan, so after a quiet spell the first visit can take about a minute while it wakes up; the app connects by itself once it does. To try chat, open the app in a normal and a private window, create two identities, and search for one from the other by its handle.
This repository is the NodeX web app (Next.js). It needs two small services from the NodeX-backend repository: a P2P node that browsers join the network through, and an email verifier used once at sign-up.
NodeX is a messaging app built on a simple principle: no central server owns your account.
Rahul#7K3M9X.| Feature | Details | |
|---|---|---|
| ✅ | Email verification | A 6-digit code sent to your email during sign-up |
| ✅ | Cryptographic identity | Ed25519 key pair and libp2p Peer ID, generated on your device |
| ✅ | Handle | DisplayName#TAG, e.g. Rahul#7K3M9X, case-insensitive. It's your only username. |
| ✅ | 12-word recovery phrase | BIP39; restores the exact same identity on any device |
| ✅ | Passwordless local login | Email + handle + recovery phrase, checked on your device |
| ✅ | Secure key storage | Private key encrypted with a non-exportable browser key |
| ✅ | Find people by handle (P2P) | Signed records in a libp2p DHT, verified on your device |
| ✅ | Real-time P2P chat | Browser to browser over WebRTC, end-to-end encrypted |
| ✅ | Ticks and read receipts | 🕓 waiting · ✓ delivered · ✓✓ read; unread counts |
| ✅ | Offline queue | Messages to an offline friend wait on your device and go out when they're back |
| ✅ | Disappearing messages | Deleted from both devices 48 hours after being read |
| ✅ | Photos, videos, documents | Photos compressed on device; files up to 50 MB with progress, cancel and resume |
| ✅ | Emoji picker | Built in; emoji-only messages shown large |
| ✅ | Reply, forward, edit, delete | Quote replies, forward to another chat, edit your messages, delete for me / for everyone |
| ✅ | Typing indicator and last seen | "typing…" and "last seen today at 11:05", from your own device's connections |
| ✅ | Profile photo (P2P) | Shared device to device; visible to everyone or "My contacts only" |
| ✅ |
Everything below runs in your browser:
12-word recovery phrase ──BIP39──► Ed25519 private key ──► Peer ID (12D3KooW…)
email + Peer ID ──PBKDF2 (200k)──► email commitment
display name + Peer ID + commitment ──PBKDF2 (600k)──► 6-character tag
handle = DisplayName # TAG → Rahul#7K3M9X
0-9 A-Z without I L O U); I/L are read as 1 and O as 0.You (browser) ──publish signed record──► NodeX DHT ◄──lookup "rahul#7k3m9x"── Someone else (browser)
key = /nodex/<lowercase handle>, value = { handle, peer_id, email_commitment, seq, sig }), and republishes it every 6 hours while the app is open.Search is by exact handle (a DHT can't do partial search) and sends no HTTP requests.
Asha's browser ──WebRTC (direct, encrypted)──► Bob's browser
│ │
└──── handshake only, via a NodeX node ───┘
| Protocol | Used for |
|---|---|
/nodex/chat/1.0.0 | Messages, photos (60 KB chunks), acks, read receipts, typing, edits, deletions |
/nodex/file/1.0.0 | Videos and documents: the receiver pulls the bytes, with resume and SHA-256 check |
/nodex/profile/1.0.0 | Profile photos: fetch and live updates |
Both people need the app open at the same time for a message to move. There's no server to hold messages for offline users.
| Data | Where it lives | Sent to a server? |
|---|---|---|
| 12-word recovery phrase | Only with you (written down) | ❌ Never |
| Private key | Your device, encrypted with a non-exportable device key | ❌ Never |
| Not stored; the verifier sees it only to send the code | Only during sign-up | |
| Handle record | The P2P network's DHT, so others can find you | Public by design |
| Contacts, messages, block list | Your device | ❌ Never |
| Profile photo | Your device, and devices of people allowed to see it | ❌ Never |
The email commitment in your public handle record is a slow, salted hash of your email, needed so anyone can check your handle belongs to your key. Someone who already suspects your exact email could test that guess, so treat your handle as linked to your email.
git clone https://github.com/noobdivya/NodeX-frontend.git
cd NodeX-frontend
cp .env.example .env.local # paste the P2P node address into it
npm install
npm run dev
Open http://localhost:3000 and create your identity. The home screen shows Online · discoverable on the NodeX network once your handle is published. To try chat, create a second identity in a private/InPrivate window and look it up by its handle.
.env.local)| Variable | Default | Description |
|---|---|---|
NEXT_PUBLIC_API_URL | http://localhost:8080 | Address of the email verifier |
NEXT_PUBLIC_BOOTSTRAP_PEERS | – | P2P node address(es) to join the network through, as printed by the node (comma-separated) |
NEXT_PUBLIC_STUN_SERVERS | – | Optional STUN servers (e.g. stun:stun.l.google.com:19302) so browsers on different networks can connect directly. STUN never sees messages. |
NEXT_PUBLIC_BOOTSTRAP_PEERS value from its logs.NEXT_PUBLIC_BOOTSTRAP_PEERS = the node's /dns4/…/tcp/443/wss/p2p/… addressNEXT_PUBLIC_API_URL = the verifier's address, e.g. https://nodex-verifier.onrender.comCORS_ORIGINS to your Vercel address.Every page is static, so the app is served from Vercel's CDN; all networking happens in the browser.
app/ Pages: /, /register, /login, /home
components/
├── register/ Email → code → name → phrase → identity
├── login/ Log in / recover
└── home/ Chat list, chat screen, search, profile, menu
lib/
├── identity.ts Keys, recovery phrase, handle derivation
├── handle.ts Handle parsing, case-insensitive comparison
├── keystore.ts Encrypted identity vault (IndexedDB)
├── contacts.ts Local contacts, last seen, block flag
├── messages.ts Local message storage (IndexedDB)
├── profile.ts Profile photos and photo privacy
├── image.ts Photo crop, resize and compression
├── notifications.ts Background notifications
├── api.ts Email verifier calls
└── p2p/
├── node.ts Browser libp2p node: join, publish, look up, WebRTC
├── record.ts Create/validate handle records (mirrors the node's record.go)
├── chat.ts Chat protocol: messages, acks, receipts, edits, deletes, typing
├── file-transfer.ts Video/document transfer with resume
├── profile-share.ts Profile photo sharing
└── blocklist.ts Blocked people, enforced on this device
| Layer | Technology |
|---|---|
| App | Next.js 16, React 19, TypeScript |
| Cryptography | @libp2p/crypto, @libp2p/peer-id, @scure/bip39, Web Crypto (PBKDF2, AES-GCM, SHA-256) |
| P2P | libp2p, @libp2p/kad-dht, @libp2p/websockets, @libp2p/webrtc, @libp2p/circuit-relay-v2, Noise, Yamux |
| Storage | IndexedDB |
End-to-end tests run in real browsers (Playwright, two or three users at once) against a local P2P node. They cover sign-up, recovery and case-insensitive login; P2P search including a forged record being rejected; real-time chat over a confirmed direct WebRTC connection; offline delivery; read receipts and disappearing messages; photos, videos and documents arriving byte-for-byte identical (including cancel and resume); reply, forward, edit and delete; last seen, typing, notifications, blocking and photo privacy; and that none of this makes HTTP requests to any server.
npx tsc --noEmit # type-check
npm run build # production build
Issues and pull requests are welcome. Please open an issue first to discuss larger changes.
No license has been chosen yet. Until one is added, all rights are reserved by the author.
| Notifications |
| While NodeX is open in the background; unread count in the tab title |
| ✅ | Block a user | Your device refuses their connections and requests; they aren't told |