105 lines
3.7 KiB
Markdown
105 lines
3.7 KiB
Markdown
# BridgeSwarm Advanced Chat
|
|
|
|
A production-polished P2P chat demo on BridgeSwarm: rooms (channels), presence, markdown, emoji, and peer file transfer — all over one Hyperswarm topic with no central server.
|
|
|
|
## Features
|
|
|
|
### Messaging
|
|
- Real-time P2P messages between tabs/browsers (Unicode / emoji safe)
|
|
- Markdown (sanitized with DOMPurify) + formatting toolbar
|
|
- Emoji picker
|
|
- Timestamps and system join/leave messages
|
|
- Typing indicators (scoped to the current room)
|
|
|
|
### Rooms
|
|
- Multiple **channels** on a single Hyperswarm topic (not separate DHT topics)
|
|
- Create rooms; peers learn about new rooms over the wire
|
|
- Full **state sync** on connect (rooms, recent history, file metadata, nicknames)
|
|
- Per-room message history (in-memory for the session)
|
|
|
|
### Users
|
|
- Nicknames + online peer list
|
|
- Deterministic avatar colors from public key / nickname
|
|
- Presence handshake on connect
|
|
|
|
### File sharing
|
|
- Announce file metadata to the room
|
|
- Peers request bytes with `file-request` / `file-data` (targeted)
|
|
- Soft size cap: **1.5 MB** per file
|
|
- Does **not** require Hyperdrive replication
|
|
|
|
### App chrome
|
|
- Leave / rejoin, host-disconnect recovery
|
|
- **Session restore** on reload (same `swarmId` + seed identity, rooms/history, reattached peers)
|
|
- Toast alerts + optional sounds
|
|
- Mobile drawers for rooms/users and settings/files
|
|
- Examples back link
|
|
|
|
## How to run
|
|
|
|
1. Load the BridgeSwarm extension and native host.
|
|
2. Enable **Examples server** in extension Settings (or from the repo: `npm run examples`).
|
|
3. Open **http://127.0.0.1:4173/chat-advanced/** in **two tabs**.
|
|
|
|
Do **not** open via `file://`.
|
|
|
|
## Usage
|
|
|
|
### Joining
|
|
1. Enter a topic (default `bridge-swarm-advanced-v1`) and nickname.
|
|
2. Click **Join**. Join stays open until the connection succeeds.
|
|
3. Open the same topic in a second tab to chat.
|
|
|
|
### Messaging
|
|
- Type in the compose box; Enter sends (Shift+Enter for newline).
|
|
- Use the toolbar for markdown shortcuts, or the emoji picker.
|
|
- Toggle **Markdown** in Settings to switch between sanitized rich HTML and simple formatting.
|
|
|
|
### Rooms
|
|
- Click **+** to create a channel name (letters, numbers, `.` `_` `-`).
|
|
- Peers receive a `room` announce plus a `state-sync` snapshot so late joiners get the full room list and recent history.
|
|
- Room counts show local message counts for that channel.
|
|
|
|
### Files
|
|
1. Click the paperclip and pick a file under 1.5 MB.
|
|
2. Peers see a share bubble and automatically request the bytes.
|
|
3. Click the file in the sidebar or **Download** on the bubble when ready.
|
|
|
|
### Leave
|
|
- Use **Leave** in the left sidebar to destroy the swarm and return to the join modal.
|
|
- If the native host drops, the UI resets so you can rejoin.
|
|
|
|
## Protocol (overview)
|
|
|
|
| Type | Purpose |
|
|
|------|---------|
|
|
| `handshake` / `presence` | Nickname + public key exchange |
|
|
| `state-sync` | Snapshot: rooms, recent messages, file metadata, users |
|
|
| `state-request` | Ask peer to send a fresh `state-sync` |
|
|
| `chat` | Room-scoped text message |
|
|
| `system` | Join/leave style notices |
|
|
| `typing` | Room-scoped typing flag |
|
|
| `room` | Announce a new channel |
|
|
| `file` | Metadata announce (no payload) |
|
|
| `file-request` | Ask peer for bytes (`requesterKey`) |
|
|
| `file-data` | Targeted base64 response |
|
|
|
|
All writes use `TextEncoder` → `conn.write(Uint8Array)`.
|
|
|
|
## Security notes
|
|
|
|
- Markdown is passed through **DOMPurify** before `innerHTML`.
|
|
- Anyone on the topic can read messages and request shared files — treat the topic like a shared room password.
|
|
- File bytes stay in memory for the session; nothing is durable across reloads.
|
|
|
|
## Architecture
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
TabA[Tab A] -->|Hyperswarm topic| TabB[Tab B]
|
|
TabA -->|chat room presence typing| TabB
|
|
TabA -->|file announce| TabB
|
|
TabB -->|file-request| TabA
|
|
TabA -->|file-data| TabB
|
|
```
|