sendy

command module
v0.1.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2025 License: MIT Imports: 2 Imported by: 0

README ΒΆ

Sendy

Go Version Platform

Sendy is a peer-to-peer encrypted chat application with WebRTC connections and a terminal user interface (TUI). It provides end-to-end encryption for secure messaging and file transfers.

Features

  • πŸ”’ End-to-End Encryption: All messages and files encrypted with NaCl/box (Curve25519 + XSalsa20-Poly1305)
  • πŸ”‘ Ed25519 Authentication: Cryptographic identity for each peer
  • 🌐 P2P WebRTC Connections: Direct peer-to-peer communication after initial handshake
  • πŸ’¬ Persistent Chat History: SQLite database for messages and contacts
  • πŸ” Message Search: Fast full-text search across all conversations
  • πŸ“ File Transfer: Send files up to 200MB with encrypted transit
  • 🎨 Terminal UI: Modern TUI built with Bubbletea
  • πŸš€ High Performance: 1.27 GB/s direct P2P transfer, 63,642 msg/s router throughput
  • πŸ“‘ NAT Traversal: STUN servers for connecting peers behind NAT/firewalls
  • 🚫 Contact Blocking: Block unwanted peers
  • πŸ“Š Online Status: Real-time connection status indicators

Quick Start

Prerequisites
  • Go 1.21 or later
  • fzf (for file picker): brew install fzf (macOS) or sudo apt install fzf (Ubuntu)
Installation
# Clone the repository
git clone https://github.com/udisondev/sendy.git
cd sendy

# Build the unified CLI
go build -o bin/sendy ./cmd/sendy

# Or use Makefile
make build
Running

⚠️ IMPORTANT: Start the router server first, then chat clients!

Step 1: Start the Router Server

./bin/sendy router
# Router starts on port 9090 by default
# Keep this terminal window open!

To use a different port:

./bin/sendy router --addr :7777

Step 2: Start Chat Clients (in new terminal windows)

# First client (default command)
./bin/sendy

# Or explicitly
./bin/sendy chat

# Second client (use different data directory)
./bin/sendy chat --data /tmp/alice

# If router is on different port
./bin/sendy chat --router localhost:7777

On first run, keys are automatically generated and your Peer ID is displayed.

Step 3: Add Contacts and Chat

  1. Copy your Peer ID (64 hex characters) from the startup message
  2. In the other client, press a to add contact
  3. Paste the Peer ID and press Enter
  4. Select the contact and press c to connect
  5. Wait for [Online] status
  6. Press Tab to switch to input field and type your message
  7. Press Enter to send
  8. Press f to send a file (opens fzf file picker)

Usage

Keyboard Shortcuts

General:

  • Tab - Switch between panels (Contacts β†’ Messages β†’ Input)
  • q - Quit (not available when focused on input field)

Contact List Panel (left):

  • ↑/↓ or j/k - Navigate contacts
  • / - Search and filter contacts by name
  • a - Add new contact
  • i - Show your Peer ID
  • d - Delete contact and chat history
  • b - Block/unblock contact
  • c - Connect to selected contact
  • x - Disconnect from selected contact

Message Panel (top right):

  • ↑/↓ or j/k - Scroll messages
  • / - Search messages across all conversations
  • PgUp/PgDown - Page through messages

Input Panel (bottom right):

  • Type your message (multi-line supported)
  • Enter - New line
  • Ctrl+S - Send message
  • f - Send file (opens fzf file picker)
  • Esc - Cancel file selection

Contact Search Mode:

  • / - Open contact search (from contact list panel)
  • Type contact name and press Enter to filter
  • ↑/↓ or j/k - Navigate filtered contacts
  • Enter - Select contact and open chat
  • Esc - Close search and return to main view

Message Search Mode:

  • / - Open message search (from message panel)
  • Type your search query and press Enter to search
  • ↑/↓ or j/k - Navigate search results
  • Enter - Jump to selected message in conversation
  • Esc - Close search and return to main view
Data Directory

By default, all data is stored in ~/.sendy/:

~/.sendy/
β”œβ”€β”€ logs/
β”‚   β”œβ”€β”€ router/
β”‚   β”‚   └── router-*.log      # Router logs
β”‚   └── chat/
β”‚       └── chat-*.log        # Chat logs
└── data/
    β”œβ”€β”€ key                   # Ed25519 private key (protect this!)
    β”œβ”€β”€ chat.db               # SQLite database
    └── files/                # Received files

To use a custom directory:

./bin/sendy --data /path/to/data
Generating New Keys
# Generate and display new keypair without starting chat
./sendy chat --genkey

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Alice   β”‚         β”‚   Bob    β”‚
β”‚ (Client) β”‚         β”‚ (Client) β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
     β”‚                     β”‚
     β”‚  WebRTC Signaling   β”‚
     β”‚    (encrypted)      β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
         β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
         β”‚  Router  β”‚
         β”‚  Server  β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
     After connection:
              β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Direct P2P Connection    β”‚
β”‚  (End-to-End Encrypted)    β”‚
β”‚    Alice ←─────→ Bob       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Components
  1. Router Server (router/)

    • Central signaling server for WebRTC handshake
    • Ed25519 authentication
    • Zero-copy I/O with sync.Pool
    • Does not see message content (only metadata)
  2. P2P Connector (p2p/)

    • WebRTC peer-to-peer connections
    • Perfect negotiation for collision resolution
    • End-to-end encryption for all data
    • Contact blocklist management
  3. Chat (chat/)

    • Message handling and persistence
    • Contact management
    • File transfer coordination
    • SQLite storage
  4. TUI (chat/tui.go)

    • Terminal interface built with Bubbletea
    • Contact list with online status
    • Message history view
    • File picker integration (fzf)

Security

Sendy implements end-to-end encryption for all peer-to-peer communications. For detailed security information, see SECURITY.md.

Highlights
  • Authentication: Ed25519 digital signatures (256-bit security)
  • Encryption: NaCl/box (Curve25519 + XSalsa20-Poly1305)
  • Trust Model: TOFU (Trust On First Use)
  • Protection: Messages, files, and WebRTC signaling are all encrypted
Known Limitations

⚠️ Please read before use:

  • No Perfect Forward Secrecy (PFS) - compromise of private key affects past messages
  • MITM vulnerability on first connection (TOFU model)
  • Router sees connection metadata (not content)
  • No key rotation

See SECURITY.md for complete security documentation.

Performance

Router (Signaling):

  • 63,642 messages/sec (2 peers)
  • 17.73 ns/op
  • 24 B/op, 1 allocs/op

WebRTC P2P Transfer:

  • 1.27 GB/s direct transfer
  • 803.7 ns/op
  • No server involvement after connection

Configuration

Router Server
./bin/sendy router --addr :9090       # Listen address
./bin/sendy router --logdir logs      # Log directory
Chat Client
./bin/sendy --router localhost:9090                          # Router address
./bin/sendy --data ~/.sendy                                  # Data directory
./bin/sendy --genkey                                         # Generate keys only
./bin/sendy --stun-servers "stun:my.server:3478,stun2:port"  # Custom STUN servers
Available Commands
sendy              # Start chat client (default)
sendy chat         # Start chat client
sendy router       # Start router server
sendy --help       # Show help
sendy chat --help  # Show chat options
sendy router --help # Show router options
Environment Variables
  • DEBUG=1 - Enable debug logging
  • SENDY_STUN_SERVERS - Comma-separated list of STUN servers (e.g., stun:stun.l.google.com:19302,stun:stun.cloudflare.com:3478)
STUN Server Configuration

STUN servers are used for NAT traversal to establish P2P connections. Priority order:

  1. --stun-servers flag (highest priority)
  2. SENDY_STUN_SERVERS environment variable
  3. Default servers (Google, Cloudflare, Twilio)

Default STUN servers:

stun:stun.l.google.com:19302       # Google (reliable, ~0.15s)
stun:stun1.l.google.com:19302      # Google backup
stun:stun.cloudflare.com:3478      # Cloudflare (fastest, ~0.05s)
stun:global.stun.twilio.com:3478   # Twilio (production-ready, ~0.17s)

Examples:

# Use custom STUN servers via flag
./bin/sendy --stun-servers "stun:mystun.example.com:3478,stun:backup.example.com:3478"

# Use custom STUN servers via environment
export SENDY_STUN_SERVERS="stun:mystun.example.com:3478,stun:backup.example.com:3478"
./bin/sendy

# Use default servers (no flag or env set)
./bin/sendy

Note: Different peers can use different STUN servers without issues. Each peer uses STUN servers independently to discover their own public IP address.

Limits
MaxFileSize     = 200 MB     // Maximum file transfer size
MaxMessageSize  = 10 MB      // Maximum message size
MaxContactName  = 256 bytes  // Maximum contact name length
MaxContactCount = 10000      // Maximum contacts per user

Project Structure

sendy/
β”œβ”€β”€ cmd/
β”‚   └── sendy/            # Unified CLI application
β”‚       β”œβ”€β”€ main.go       # Entry point
β”‚       └── cmd/          # Cobra commands
β”‚           β”œβ”€β”€ root.go   # Root command
β”‚           β”œβ”€β”€ chat.go   # Chat client command
β”‚           └── router.go # Router server command
β”œβ”€β”€ router/               # Router server and client
β”‚   β”œβ”€β”€ router.go         # Server implementation
β”‚   β”œβ”€β”€ client.go         # Client library
β”‚   β”œβ”€β”€ types.go          # Protocol types
β”‚   └── const.go          # Constants
β”œβ”€β”€ p2p/                  # WebRTC P2P connector
β”‚   β”œβ”€β”€ webrtc.go         # Connection management
β”‚   β”œβ”€β”€ crypto.go         # End-to-end encryption
β”‚   └── *_test.go         # Tests
β”œβ”€β”€ chat/                 # Chat logic
β”‚   β”œβ”€β”€ chat.go           # Core chat logic
β”‚   β”œβ”€β”€ storage.go        # SQLite persistence
β”‚   β”œβ”€β”€ tui.go            # Bubbletea TUI
β”‚   └── filepicker_external.go  # fzf integration
β”œβ”€β”€ SECURITY.md           # Security documentation
β”œβ”€β”€ LICENSE               # MIT License
└── README.md             # This file

Development

Building
# Build unified CLI
go build -o bin/sendy ./cmd/sendy

# Build with debug symbols stripped (smaller binary)
go build -ldflags="-s -w" -o bin/sendy ./cmd/sendy

# Or use Makefile
make build           # Normal build
make build-release   # Optimized build
make clean           # Clean build artifacts
Testing
# Run all tests
go test ./...

# Test specific package
go test ./router
go test ./p2p
go test ./chat

# Run with verbose output
go test -v ./...

# Run benchmarks
go test -bench=. -benchtime=5s ./router
go test -bench=. -benchtime=5s ./p2p
Running Tests with Real Peers
# Terminal 1: Start router
./sendy router

# Terminal 2: Start Alice
./sendy chat --data /tmp/alice

# Terminal 3: Start Bob
./sendy chat --data /tmp/bob

# Add each other as contacts and test messaging/file transfer

Roadmap

Security Improvements:

  • Perfect Forward Secrecy (PFS) implementation
  • Key rotation support
  • Optional key encryption with passphrase
  • Multi-device key synchronization

Features:

  • Message search
  • Group chats
  • Voice/video calls (WebRTC media streams)
  • Message reactions and replies
  • Contact verification (QR codes)
  • Desktop notifications

UX Improvements:

  • File transfer progress bars
  • Image preview in terminal
  • Emoji support
  • Customizable themes
  • Message timestamps in chat view

Operations:

  • Configurable STUN/TURN servers
  • Docker images
  • systemd service files
  • Configuration file support

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Before contributing:

  1. Read SECURITY.md to understand the security model
  2. Ensure all tests pass: go test ./...
  3. Add tests for new features
  4. Follow Go best practices and conventions
  5. Update documentation as needed

Dependencies

License

MIT License - see LICENSE file for details.

Acknowledgments


⚠️ Security Notice: Sendy is experimental software. While it implements strong cryptography, it has not undergone a professional security audit. Use at your own risk. See SECURITY.md for details.

Documentation ΒΆ

The Go Gopher

There is no documentation for this package.

Directories ΒΆ

Path Synopsis
cmd
sendy command
Package p2p прСдоставляСт WebRTC P2P ΠΊΠΎΠ½Π½Π΅ΠΊΡ‚ΠΎΡ€ для прямого ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΈΡ€Π°ΠΌΠΈ.
Package p2p прСдоставляСт WebRTC P2P ΠΊΠΎΠ½Π½Π΅ΠΊΡ‚ΠΎΡ€ для прямого ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΈΡ€Π°ΠΌΠΈ.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL