Secure HTTP/WebSocket API server for decentralized messaging applications
Production-ready REST API and WebSocket server for building secure, decentralized messaging applications. Built with Go, featuring end-to-end encryption, wallet-based authentication, and real-time communication over the Zentalk network.
- Go 1.24 or higher
- SQLite3
- Running zentalk-node instance
git clone https://github.com/ZentaChain/zentalk-api.git
cd zentalk-api
# Install dependencies
make deps
# Build binary
make build# Option 1: Using Makefile (recommended)
make dev
# Option 2: Using startup script
./start-api.sh
# Option 3: Manual
export ZENTALK_ENV=development
go run cmd/api-server/main.gomake help # Show all available commands
make build # Build API server binary
make dev # Run development server
make test # Run tests
make check # Run all checks (fmt, vet, lint, test)
make swagger # Generate Swagger/OpenAPI documentation
# Environment setup
make env-dev # Create .env from development template
make env-prod # Create .env from production template
make generate-jwt-secret # Generate secure JWT secret
# Database
make db-backup # Backup database
make db-restore # Restore database from backup
# Database Migrations
make migrate-up # Apply all pending migrations
make migrate-down # Rollback last migration
make migrate-version # Show current migration version
make migrate-goto # Migrate to specific version (requires VERSION=N)
make migrate-create # Create new migration files (requires NAME=xxx)
# Server control
make start # Start server with script
make stop # Stop server
make restart # Restart serverThe API server uses environment-based configuration for security and flexibility.
Development:
# Uses defaults (localhost CORS, auto-generated JWT)
export ZENTALK_ENV=development
make devProduction:
# 1. Create environment file
make env-prod
# 2. Generate JWT secret
make generate-jwt-secret
# 3. Edit .env file
nano .env
# Required settings:
# ZENTALK_ENV=production
# ZENTALK_JWT_SECRET=<your-generated-secret>
# ZENTALK_CORS_ORIGINS=https://app.zentalk.chat
# 4. Run server
make runEnvironment Variables:
| Variable | Description | Default | Required |
|---|---|---|---|
ZENTALK_ENV |
Environment (development/production) | development | No |
ZENTALK_HOST |
Server host | localhost | No |
ZENTALK_PORT |
Server port | 3001 | No |
ZENTALK_JWT_SECRET |
JWT signing secret | auto-generated | Yes (production) |
ZENTALK_CORS_ORIGINS |
Allowed CORS origins | localhost:3000 | No |
ZENTALK_RATE_DEFAULT_RPM |
Default rate limit (req/min) | 100 | No |
ZENTALK_RATE_REGISTER_RPH |
Registration rate limit (req/hour) | 5-10 | No |
ZENTALK_DB_PATH |
Database file path | data/messages.db | No |
ZENTALK_BACKUP_ENABLED |
Enable automated backups | false (true in prod) | No |
See .env.example (development) or .env.production.example (production) for complete list
The API comes with interactive Swagger/OpenAPI documentation that you can use to explore and test all endpoints directly in your browser.
Access Swagger UI:
http://localhost:3001/swagger/index.html
Generate/Update Documentation:
make swagger # Generate Swagger docs from code annotationsThe Swagger UI provides:
- Complete API reference with request/response examples
- Interactive testing - try endpoints directly from the browser
- Authentication configuration (JWT, Wallet signature)
- Schema definitions for all request/response types
OpenAPI Spec Files:
- JSON:
docs/swagger.json - YAML:
docs/swagger.yaml
POST /api/initialize
Content-Type: application/json
{
"wallet_address": "0x1234...",
"username": "alice",
"signature": "0xabcdef..."
}All authenticated endpoints require JWT token:
Authorization: Bearer {session_token}
Messaging
POST /api/send # Send message
GET /api/messages/{chatId} # Get messages
POST /api/edit-message # Edit message
POST /api/delete-message # Delete message
POST /api/mark-as-read # Mark as readContacts
POST /api/discover # Discover contact
POST /api/peer-info # Get peer info
POST /api/block-contact # Block contact
POST /api/unblock-contact # Unblock contactMedia
POST /api/upload-media # Upload file
GET /api/media/{mediaId} # Download fileUser Profile
POST /api/update-profile # Update profile
POST /api/update-status # Update status
POST /api/update-username # Update usernameChannels
POST /api/create-channel # Create channel
POST /api/send-channel-message # Send to channelconst ws = new WebSocket("ws://localhost:3001/ws?token={session_token}");
ws.onmessage = (event) => {
const { type, payload } = JSON.parse(event.data);
// Handle: message, typing, read_receipt, message_deleted, message_edited, reaction_added
};// Initialize session
const res = await fetch("http://localhost:3001/api/initialize", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
wallet_address: "0x1234...",
username: "alice",
signature: "0xabcdef...",
}),
});
const { session_token } = await res.json();
// Send message
await fetch("http://localhost:3001/api/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session_token}`,
},
body: JSON.stringify({
to: "0x5678...",
content: "Hello!",
type: "text",
}),
});- End-to-End Encryption - Double Ratchet algorithm via zentalk-node
- X3DH Key Exchange - Perfect forward secrecy
- Zero-Knowledge Server - API cannot decrypt message content
- Wallet Authentication - ECDSA signature verification
- Local Storage - Messages stored locally, not in the cloud
zentalk-api/
├── cmd/api-server/ # Main entry point
├── pkg/api/
│ ├── database/ # SQLite layer
│ └── server/ # HTTP/WebSocket handlers
├── data/ # Runtime data
└── bin/ # Compiled binaries
The API includes comprehensive automated tests covering unit, integration, and functional testing.
Running Tests:
# Run all tests
make test
# Run tests with coverage report
make test-coverage
# Run only unit tests
make test-unit
# Run only integration tests
make test-integration
# Run tests with verbose output
make test-verbose
# Run short tests (skip long-running tests)
make test-short
# Get coverage summary
make test-coverage-summaryTest Structure:
zentalk-api/
├── pkg/
│ ├── api/database/
│ │ └── users_test.go # Database layer unit tests
│ ├── api/server/
│ │ └── health_test.go # Server handler unit tests
│ └── testutil/
│ └── helpers.go # Test utilities and helpers
└── tests/
└── integration/
└── api_test.go # API integration tests
Writing Tests:
Use the test helpers from pkg/testutil:
import (
"testing"
"github.com/ZentaChain/zentalk-api/pkg/testutil"
)
func TestMyFeature(t *testing.T) {
// Setup test database
db, cleanup := testutil.SetupTestDB(t)
defer cleanup()
// Get test config
cfg := testutil.GetTestConfig()
// Use assertion helpers
testutil.AssertNoError(t, err, "operation failed")
testutil.AssertEqual(t, got, want, "values don't match")
testutil.AssertTrue(t, condition, "condition failed")
}Coverage Goals:
- Unit Tests: >80% coverage of business logic
- Integration Tests: All API endpoints
- Database Tests: All CRUD operations
CI/CD Integration:
Tests run automatically on:
- Every push to main/develop branches
- Every pull request
- Pre-deployment checks
View test results in GitHub Actions or run locally before committing.
The API includes comprehensive performance testing tools for benchmarking and load testing.
Go Benchmarks:
# Run all benchmarks
make benchmark
# Run database benchmarks only
make benchmark-db
# Run server benchmarks only
make benchmark-server
# Run with CPU profiling
make benchmark-cpu
# Run with memory profiling
make benchmark-memLoad Testing with k6:
# Smoke test (1 minute, 1 user)
make load-test-smoke
# Load test (4 minutes, 20-50 users)
make load-test
# Stress test (30 minutes, 100-400 users)
make stress-testInstalling k6:
# macOS
brew install k6
# Linux
sudo apt-get install k6
# Windows
choco install k6Performance Baselines:
- API Endpoints: p95 < 500ms
- Database Operations: < 5ms average
- Concurrent Users: 50-100 (normal), 200+ (peak)
- Error Rate: < 1%
See benchmarks/README.md for detailed documentation on performance testing.
The API uses a migration system for managing database schema changes. This ensures safe, versioned updates to the database structure.
Running Migrations:
# Apply all pending migrations
make migrate-up
# Check current migration version
make migrate-version
# Rollback last migration
make migrate-down
# Migrate to specific version
make migrate-goto VERSION=1Creating New Migrations:
# Create new migration files
make migrate-create NAME=add_feature_table
# This creates:
# - migrations/{timestamp}_add_feature_table.up.sql
# - migrations/{timestamp}_add_feature_table.down.sqlMigration Files:
Migrations are stored in migrations/ directory with naming format {version}_{description}.{up|down}.sql:
.up.sql- Forward migration (apply changes).down.sql- Reverse migration (rollback changes)
Example Migration:
-- migrations/000001_initial_schema.up.sql
CREATE TABLE users (
id TEXT PRIMARY KEY,
username TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- migrations/000001_initial_schema.down.sql
DROP TABLE IF EXISTS users;Best Practices:
- Always test migrations on a copy of production data before applying
- Create a database backup before running migrations:
make db-backup - Each migration should be atomic and reversible
- Use meaningful names for migration files
- Never modify existing migration files after they've been applied
Direct Migration Commands:
For advanced use cases, you can run migrations directly:
# Run migrations
go run cmd/migrate/main.go -cmd up
# Check version
go run cmd/migrate/main.go -cmd version
# Rollback
go run cmd/migrate/main.go -cmd down
# Goto specific version
go run cmd/migrate/main.go -cmd goto -target 1The API exposes Prometheus metrics for comprehensive monitoring and observability.
Metrics Endpoint:
http://localhost:3001/metrics
Available Metrics:
-
HTTP Metrics
zentalk_http_requests_total- Total HTTP requests by method, endpoint, statuszentalk_http_request_duration_seconds- Request duration histogramzentalk_http_request_size_bytes- Request size histogramzentalk_http_response_size_bytes- Response size histogramzentalk_http_in_flight_requests- Current in-flight requests
-
WebSocket Metrics
zentalk_websocket_connections_total- Total WebSocket connectionszentalk_websocket_active_connections- Active WebSocket connectionszentalk_websocket_messages_total- WebSocket messages by direction and typezentalk_websocket_message_size_bytes- Message size histogram
-
Session Metrics
zentalk_active_sessions- Current active sessionszentalk_session_creations_total- Total sessions createdzentalk_session_destructions_total- Total sessions destroyed
-
Message Metrics
zentalk_messages_total- Total messages by type and statuszentalk_messages_sent_total- Total messages sentzentalk_messages_received_total- Total messages receivedzentalk_message_size_bytes- Message size histogram
-
Database Metrics
zentalk_db_queries_total- Database queries by operation and tablezentalk_db_query_duration_seconds- Query duration histogramzentalk_db_connections_active- Active database connections
-
Error Metrics
zentalk_errors_total- Total errors by type and endpoint
Quick Setup with Docker:
The monitoring/ directory contains ready-to-use Prometheus and Grafana configurations:
cd monitoring
docker-compose up -dThis starts:
- Prometheus on http://localhost:9090
- Grafana on http://localhost:3000 (admin/zentalk123)
Manual Prometheus Setup:
# prometheus.yml
scrape_configs:
- job_name: 'zentalk-api'
static_configs:
- targets: ['localhost:3001']
metrics_path: '/metrics'
scrape_interval: 10sGrafana Dashboard:
Import the pre-built dashboard from monitoring/grafana-dashboard.json or create custom visualizations using the exposed metrics.
Key Panels to Monitor:
- Active sessions and WebSocket connections
- HTTP request rate and latency (p95, p99)
- Error rates by endpoint
- Database query performance
- Message throughput
Alerting (Recommended):
Set up alerts for:
- High error rates (> 5% of requests)
- Slow requests (p99 > 1s)
- Database connection pool exhaustion
- WebSocket connection spikes
server {
listen 443 ssl http2;
server_name api.zentalk.chat;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
location /api/ {
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
}
location /ws {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}- 1000+ HTTP req/s
- 1000+ concurrent WebSocket connections
- 500+ msg/s throughput
- <10ms latency
✅ Environment-Based Configuration
- Separate development and production configs
- Production requires explicit JWT secret
- Environment-specific CORS origins
✅ Secure WebSocket Authentication
- Tokens sent via
Sec-WebSocket-Protocolheader (not URL) - Prevents token leakage in logs and browser history
- Backward compatible with legacy auth methods
✅ Rate Limiting
- Default: 100 requests/minute per IP
- Registration: 5-10 requests/hour (configurable)
- Prevents spam and abuse
✅ CORS Protection
- Configurable allowed origins
- Development: localhost only
- Production: your domain(s) only
✅ HTTPS/TLS Support
- Nginx reverse proxy configuration included
- SSL/TLS termination
- Security headers (HSTS, CSP, X-Frame-Options)
1. Set Up Environment
# Generate JWT secret
make generate-jwt-secret
# Create production config
make env-prod
# Edit .env file
nano .envRequired .env settings:
ZENTALK_ENV=production
ZENTALK_JWT_SECRET=<generated-secret>
ZENTALK_CORS_ORIGINS=https://app.zentalk.chat
ZENTALK_HOST=127.0.0.1 # Bind to localhost (nginx handles public)2. Set Up Nginx
# Copy nginx configuration
sudo cp nginx.conf.example /etc/nginx/sites-available/zentalk
sudo ln -s /etc/nginx/sites-available/zentalk /etc/nginx/sites-enabled/
# Update domain in config
sudo nano /etc/nginx/sites-available/zentalk
# Obtain SSL certificate
sudo certbot --nginx -d app.zentalk.chat
# Test and reload
sudo nginx -t
sudo systemctl reload nginx3. Set Up Systemd Service
Create /etc/systemd/system/zentalk-api.service:
[Unit]
Description=Zentalk API Server
After=network.target
[Service]
Type=simple
User=zentalk
WorkingDirectory=/opt/zentalk/zentalk-api
EnvironmentFile=/opt/zentalk/zentalk-api/.env
ExecStart=/opt/zentalk/zentalk-api/bin/api-server
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable zentalk-api
sudo systemctl start zentalk-api
sudo systemctl status zentalk-api4. Verify Deployment
# Check logs
sudo journalctl -u zentalk-api -f
# Verify HTTPS
curl -I https://app.zentalk.chat/health
# Test WebSocket (with token)
wscat -c "wss://app.zentalk.chat/ws" --header "Sec-WebSocket-Protocol: token.<your-jwt>"# Server logs
sudo journalctl -u zentalk-api -f
# Nginx logs
sudo tail -f /var/log/nginx/zentalk-access.log
sudo tail -f /var/log/nginx/zentalk-error.log
# Database backup
make db-backup# Allow nginx
sudo ufw allow 'Nginx Full'
# Allow SSH (if not already)
sudo ufw allow OpenSSH
# Enable firewall
sudo ufw enablePriority areas:
- Testing - Unit and integration tests
- Documentation - API docs and guides
- Features - Rate limiting, metrics
- Security - Audits and testing
Guidelines:
- Fork the repository
- Create a feature branch
- Write tests
- Run
go test ./...andgo fmt ./... - Submit a pull request
- Zentalk Node - Relay and mesh storage
- ZentaChain Website
- Block Explorer
- Issues: GitHub Issues
- Security: security@zentachain.io
Build secure, decentralized messaging applications with Zentalk API 🚀
MIT License - see LICENSE for details.