A genuinely decentralized exchange with NO central servers required.
✅ Distributed Orderbook - Each client has its own orderbook instance ✅ Order Distribution - Orders distributed to all peer instances via Grenache ✅ Match & Remainder - Matched order remainders added to orderbook ✅ Grenache Communication - Uses Grenache DHT for inter-node communication ✅ Embedded Grape - Each node runs its own Grape DHT server ✅ No Central Servers - Fully distributed Kademlia DHT network
Built to spec: Uses Grenache for communication between nodes, with each client maintaining its own orderbook instance.
Read ARCHITECTURE.md for detailed explanation.
Before getting started, ensure you have the following:
- Node.js: >= 20.19.5 (check with
node --version) - npm: >= 8.0.0 (check with
npm --version) - Memory: Minimum 512MB RAM per node (recommended 1GB for development)
- Operating Systems: Linux, macOS, Windows (WSL recommended for Windows)
Default ports (can be customized via environment variables):
- P2P Port: 3000 (for peer-to-peer connections)
- Grape DHT Port: 20001 (for Kademlia DHT)
- Grape API Port: 30001 (for Grape HTTP API)
Firewall: Ensure these ports are accessible if running across different machines/networks.
# Clone the repository
git clone https://github.com/RadW2020/bitfitech.git
cd bitfitech
# Install dependencies
npm installNote: If you see dependency vulnerabilities, you can safely ignore them for development or run npm audit fix to address them.
Get started in 3 simple steps:
Step 1: Ensure you've installed dependencies (see Prerequisites above)
npm installStep 2: Start your first node
npm startStep 3: Done! Your node is now running and will automatically discover peers.
What happens:
- Starts embedded Grape DHT server (Kademlia)
- Starts P2P server on port 3000
- Discovers peers via Grenache DHT + mDNS
- Initializes local orderbook
- Distributes orders via Grenache to all peers
Test with multiple nodes on your machine:
# Terminal 1 - First node (becomes bootstrap for others)
P2P_PORT=3001 npm start
# Terminal 2 - Second node
P2P_PORT=3002 npm start
# Terminal 3 - Third node
P2P_PORT=3003 npm startWhat happens:
- Nodes discover each other via mDNS
- Direct TCP connections established
- Orderbook synchronized automatically
- Orders propagate peer-to-peer
No configuration needed! Defaults fulfill original requirements:
{
"embeddedGrape": {
"enabled": true, // Each node runs Grape DHT
"dhtPort": 20001, // Kademlia DHT port
"apiPort": 30001 // Grape HTTP API port
},
"p2p": {
"enabled": true, // Always on
"port": 3000, // P2P listening port
"enableMDNS": true, // Local network discovery
"enableGrenache": true, // Grenache DHT (REQUIRED per spec)
"enablePeerExchange": true, // Peers share peer lists
"useWellKnownNodes": true // Use community bootstrap nodes
}
}Customize if needed:
# P2P Network
P2P_PORT=3000 # P2P listening port
P2P_HOST=0.0.0.0 # Bind address (0.0.0.0 = all interfaces)
# Discovery (all optional)
DISCOVERY_MDNS=true # Local network discovery
DISCOVERY_PEER_EXCHANGE=true # Peer list sharing
USE_WELL_KNOWN_NODES=true # Use community bootstrap nodes
# Custom Bootstrap Peers
BOOTSTRAP_PEERS=peer1.com:3000,peer2.com:3000
# Peer Management
PEER_STORAGE_PATH=.peers.json # Persistent peer storage
MAX_PEERS=50 # Maximum connections
# Exchange
EXCHANGE_PAIR=BTC/USD # Trading pairUses Grenache for communication - Fulfills original requirements.
npm startFeatures:
- Embedded Grape DHT (Kademlia) in each node
- Grenache for order distribution between nodes
- Direct TCP peer connections
- mDNS local discovery
- Peer exchange protocol
- Well-known bootstrap nodes
Perfect for:
- Production deployments
- Meets "Use Grenache" requirement
- Distributed Kademlia DHT
- No external infrastructure
Is this TRUE P2P? ✅ YES (distributed DHT, no central servers)
For simple local testing only - Disables Grenache (not per spec).
EMBEDDED_GRAPE=false \
DISCOVERY_GRENACHE=false \
P2P_PORT=3001 \
npm startFeatures:
- Direct TCP connections only
- mDNS local discovery
- Peer exchange
- No DHT
Note: Does NOT fulfill "Use Grenache" requirement. Use only for local testing.
Requires manual Grape servers - Not recommended (centralized).
See EMBEDDED_GRAPE_DHT.md for details.
┌────────────────────────────────────┐
│ Start P2P Node │
│ 1. Load persisted peers │
│ 2. Start TCP server │
│ 3. Start discovery │
└────────────────────────────────────┘
┌─────────────────┐
│ Discovery │
│ Strategies: │
│ │
│ ✓ Persisted │──► Reconnect to known peers
│ ✓ mDNS │──► Find local network peers
│ ✓ Bootstrap │──► Connect to well-known nodes
│ ✓ Peer Exchange │──► Get peers from peers
└─────────────────┘
Node A ──TCP──► Node B
│ │
└──TCP──►──────┘
Node C
1. User places order on Node A
2. Node A adds to local orderbook
3. Node A broadcasts to connected peers
4. Peers receive, deduplicate, add to orderbook
5. Peers rebroadcast to their peers
6. Order reaches entire network
Each node independently:
1. Receives orders from network
2. Matches against local orderbook
3. Broadcasts trade to network
4. Vector clocks ensure consistency
# Connect only to specific peers
BOOTSTRAP_PEERS=friend1.example.com:3000,friend2.example.com:3000 \
USE_WELL_KNOWN_NODES=false \
npm start# Only connect to specified peers
DISCOVERY_MDNS=false \
DISCOVERY_PEER_EXCHANGE=false \
USE_WELL_KNOWN_NODES=false \
BOOTSTRAP_PEERS=specific.peer.com:3000 \
npm start# Recommended production settings
NODE_ENV=production \
P2P_PORT=3000 \
P2P_HOST=0.0.0.0 \
MAX_PEERS=100 \
LOG_LEVEL=info \
npm start# Run test suite
npm test
# Run with coverage
npm run test:coverage
# Integration tests
npm run test:integration
# Pure P2P integration test
npm run test -- test/integration/pure-p2p.test.js- No central servers - Each node is independent
- No coordinator - Self-organizing network
- No single point of failure - Network survives node failures
- TCP connections - Direct socket-to-socket
- Message routing - Intelligent broadcast with deduplication
- Gossip protocol - Efficient message propagation
- mDNS - Zero-config local network discovery
- Bootstrap nodes - Well-known entry points
- Peer exchange - Exponential peer discovery
- Persistent peers - Remember connections across restarts
- Decimal precision - Accurate financial calculations
- Price-time priority - Fair FIFO matching
- Vector clocks - Distributed event ordering
- Circuit breaker - Fault tolerance
- Comprehensive logging - Structured logging system
- Health monitoring - Heartbeat and peer health
- Rate limiting - Protection against abuse
- Error handling - Graceful degradation
src/
├── p2p/ # 🔥 Core P2P Components
│ ├── direct-connection-service.js # Direct TCP connections
│ ├── peer-manager.js # Peer lifecycle management
│ ├── peer-discovery.js # Multi-strategy discovery
│ ├── message-router.js # Intelligent routing
│ ├── peer-protocol.js # P2P message protocol
│ ├── peer-storage.js # Persistent peer storage
│ └── well-known-nodes.js # Bootstrap node registry
│
├── core/
│ └── orderbook.js # Order matching engine
│
├── clients/
│ ├── exchange-client.js # Main exchange interface
│ └── example-client.js # Demo implementation
│
├── services/
│ ├── grenache-service.js # Optional: DHT service
│ └── embedded-grape-server.js # Optional: Embedded DHT
│
└── utils/
├── config.js # Configuration management
├── logger.js # Logging system
├── vector-clock.js # Distributed ordering
├── circuit-breaker.js # Fault tolerance
└── ...
✅ Peer verification - Handshake protocol
✅ Message validation - Schema validation
✅ Rate limiting - Prevent abuse
✅ Circuit breaker - Fault isolation
This is a permissionless network:
- Any node can join
- Nodes maintain local orderbooks
- Consensus via vector clocks
- No Byzantine fault tolerance (yet)
For production: Consider adding:
- Message signing
- Peer whitelisting
- Network access control
- Byzantine fault tolerance
Error: EADDRINUSE: address already in use 0.0.0.0:3000
Solution: Another process is using the default port. Change the port using environment variables:
# Change P2P port
P2P_PORT=3001 npm start
# For multiple nodes on same machine
P2P_PORT=3001 GRAPE_DHT_PORT=20002 GRAPE_API_PORT=30002 npm startAlternative: Find and stop the process using the port:
# Linux/macOS
lsof -ti:3000 | xargs kill -9
# Windows
netstat -ano | findstr :3000
taskkill /PID <PID> /FSymptoms: Node starts but doesn't connect to peers
Solutions:
-
Check firewall settings: Ensure ports are not blocked
# Linux: Allow ports through firewall sudo ufw allow 3000/tcp sudo ufw allow 20001/tcp sudo ufw allow 30001/tcp -
Verify mDNS is enabled (for local network discovery):
# Check environment variable echo $DISCOVERY_MDNS # Should be 'true' or empty
-
Use manual bootstrap peers:
# Connect to specific peer BOOTSTRAP_PEERS=192.168.1.100:3000 npm start -
Check if Grenache is running (if using embedded mode):
- Look for "Grape DHT server started" in logs
- Verify ports 20001 and 30001 are listening
Error: The engine "node" is incompatible with this module
Solution: Update Node.js to version 20.19.5 or higher:
# Using nvm (recommended)
nvm install 20.19.5
nvm use 20.19.5
# Verify version
node --versionSymptoms: Slow performance, high memory usage
Solutions:
-
Reduce maximum peers:
MAX_PEERS=25 npm start
-
Increase Node.js memory limit:
NODE_OPTIONS="--max-old-space-size=2048" npm start -
Disable verbose logging in production:
LOG_LEVEL=warn NODE_ENV=production npm start
Common causes:
-
Port conflicts: Other tests or processes using ports
# Kill all node processes pkill -9 node # Run tests again npm test
-
Timeout issues: Increase test timeout
# Edit vitest.config.js to increase timeout -
Clean start: Remove generated files
rm -f .peers*.json npm test
Error: Connection timeout or Socket closed before connection
Solutions:
-
Increase timeout values in
.env:PEER_RECONNECT_INTERVAL=60000 # 60 seconds -
Check network connectivity:
# Test connection to peer nc -zv 127.0.0.1 3000 # Or using telnet telnet 127.0.0.1 3000
-
Disable rate limiting during development:
ENABLE_RATE_LIMIT=false npm start
Symptoms: Different orderbook states across nodes
Solutions:
-
Wait for synchronization: Give nodes time to sync (2-5 seconds)
-
Check peer connections:
- Verify all nodes are connected to each other
- Check logs for "Peer connected" messages
-
Restart all nodes for clean state:
# Stop all nodes pkill -9 node # Clean peer storage rm -f .peers*.json # Start nodes again
If you encounter issues not covered here:
- Check logs: Set
LOG_LEVEL=debugfor detailed information - Search existing issues: GitHub Issues
- Open a new issue: Include logs, environment details, and steps to reproduce
- Join discussions: GitHub Discussions
A: NO external servers needed! Each node runs its own embedded Grape DHT server. It's fully distributed - no central Grape infrastructure required.
A: Project requirement. The original spec requires "Use Grenache for communication between nodes". We fulfill this with embedded Grape (distributed DHT) in each node.
A: No. They're entry points for DHT discovery. After first connection:
- Your node joins the Kademlia DHT
- You discover more peers via DHT
- Peers remembered in
.peers.json - Any node can be a bootstrap node
Like Bitcoin's DNS seeds or BitTorrent DHT bootstrap.
A: On local network, YES! mDNS discovery works without internet.
A: Just run a stable node! Anyone can add your node to src/p2p/well-known-nodes.js via PR.
A: No problem! You can:
- Use mDNS (works on LAN)
- Connect to any peer manually
- Wait for persisted peers to come online
A: YES! Similar architecture:
- Direct peer connections
- Gossip protocol
- Optional DHT (Kademlia)
- Decentralized discovery
A: Thousands. Each node maintains ~50-100 connections. Network grows exponentially via peer exchange.
- ARCHITECTURE.md - Deep dive into P2P architecture
- EMBEDDED_GRAPE_DHT.md - DHT mode documentation
- API Documentation - Run
npm run docs
We welcome contributions! Especially:
- Adding well-known bootstrap nodes
- Improving discovery algorithms
- Byzantine fault tolerance
- Message encryption
- Performance optimization
See CONTRIBUTING.md for guidelines.
- Direct TCP connections
- Decentralized discovery
- Distributed orderbook
- Production ready
- TLS encryption for peer connections
- Message signing and verification
- Byzantine fault tolerance
- NAT traversal (UPnP/STUN/TURN)
- IPv6 support
- Performance metrics and monitoring
- Web UI for node management
MIT License - See LICENSE file
"True P2P means peers talk directly. No servers. No middlemen. No single point of failure."
This system embodies that philosophy completely.
- Decentralization is not optional - It's the core design principle
- Simplicity over features - Easy to run, hard to break
- Community over corporation - Anyone can contribute
- Transparency over obscurity - Open source, readable code
Inspired by:
- BitTorrent - Gossip protocol and peer exchange
- Bitcoin - Decentralized consensus and bootstrap nodes
- Kademlia - Distributed hash table design
- Grenache - DHT implementation (optional component)
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: raul@bitfitech.network
Built with ❤️ for a truly decentralized future.
No servers. No middlemen. Just peers.