p2p-chat-example
v1.0.0
Published
P2P chat with CRDT synchronization
Downloads
5
Readme
P2P Chat Example
A fully decentralized peer-to-peer chat application demonstrating the complete toolkit-p2p stack.
Features
- 🔐 Cryptographic Identity - Each user has a unique Ed25519 keypair
- 🌐 WebRTC Transport - Direct peer-to-peer connections
- 📦 Content-Addressed Storage - SHA-256 based message storage
- 🔄 CRDT Synchronization - Conflict-free message ordering with LWW-Map
- 🎨 Beautiful UI - Modern, responsive chat interface
Architecture
User A User B
├─ Identity (Ed25519) ├─ Identity (Ed25519)
├─ WebRTC Transport ├─ WebRTC Transport
├─ Mesh Cache (SHA-256) ├─ Mesh Cache (SHA-256)
└─ LWW-Map CRDT └─ LWW-Map CRDT
│ │
└──────── Sync via Merkle Trees ──────┘How It Works
1. Identity Management
Each peer generates an Ed25519 keypair for signing messages and establishing trust.
2. Message Storage
Messages are stored in a Last-Writer-Wins Map (LWW-Map) CRDT:
- Each message has a vector clock timestamp
- Concurrent edits are resolved deterministically
- Deletions use tombstones
3. Synchronization
- Merkle trees detect differences between peers
- Only changed messages are transmitted
- Efficient bandwidth usage
4. Conflict Resolution
When two peers send messages simultaneously:
- Vector clocks detect the concurrent write
- Peer IDs provide deterministic tie-breaking
- Both messages are preserved in correct order
Running the Example
# Install dependencies
pnpm install
# Start dev server
pnpm dev
# Open http://localhost:3000Usage
- Enter your name - This becomes your display name
- Enter room code (optional) - Leave empty to create a new room
- Click "Join Chat" - Connects to peers in the same room
- Start chatting - Messages sync automatically via CRDTs
Code Structure
src/
└── main.ts # Main application logic
├── Identity setup
├── CRDT initialization
├── Transport setup
├── Message handling
└── UI renderingIntegration Points
@toolkit-p2p/identity
const identity = await generateIdentity();
// Used for: signing messages, peer authentication@toolkit-p2p/sync
// Create message store
const messages = createLWWMap<string, Message>();
// Add message with vector clock
let clock = increment(clock, peerId);
messages = set(messages, msgId, message, clock, peerId);
// Merge with remote peer
messages = merge(localMessages, remoteMessages);@toolkit-p2p/mesh-cache
const cache = new MeshCache({ transport });
await cache.init();
// Store message content
const cid = await cache.put(messageData);
// Retrieve from peers
const data = await cache.get(cid);@toolkit-p2p/transport
const transport = createTransport({
identity,
signalingUrl: 'ws://localhost:8080',
roomCode,
});
// Send to all peers
transport.broadcast(message);
// Receive from peers
transport.onMessage((peerId, data) => {
// Handle incoming message
});CRDT Guarantees
This chat application guarantees:
✅ Eventual Consistency - All peers converge to the same message history ✅ Commutativity - Message order is deterministic regardless of delivery order ✅ Idempotency - Receiving the same message multiple times has no effect ✅ Partition Tolerance - Works offline, syncs when reconnected
Performance
| Operation | Complexity | Notes | |-----------|------------|-------| | Send message | O(1) | Instant local update | | Receive message | O(1) | CRDT merge operation | | Sync messages | O(log n) | Merkle tree comparison | | Full sync | O(n) | Only on first connect |
Extending
Want to add more features? Try:
- Typing indicators - Using G-Counter CRDT
- Read receipts - Using LWW-Map per message
- File sharing - Using content-addressed storage
- Reactions - Using OR-Set CRDT
- Channels - Multiple LWW-Map instances
Learn More
License
MIT
