POST
/node/register
Register or update a node
โผ
Request Body
{
"node_id": "node-abc-001", // 3โ128 alphanumeric chars
"public_key": "-----BEGIN PUBLIC KEY-----\n...",
"ip_address": "192.168.1.100", // IPv4 or IPv6
"node_type": "raspberry", // see valid types below
"location": "US-East"
}
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| node_id | string | required | Unique node identifier (3โ128 chars, alphanumeric + -_:.) |
| public_key | string | required | PEM, hex (64+ chars), or base64 public key |
| ip_address | string | required | Valid IPv4 or IPv6 address |
| node_type | enum | required | raspberry | server | supernode | edge | validator | storage |
| location | string | required | Geographic location or region identifier |
Response 200
{
"status": "success",
"node_id": "node-abc-001"
}
POST
/node/heartbeat
Update metrics & mark online
โผ
Request Body
{
"node_id": "node-abc-001", // required
"cpu": 45.2, // 0โ100 (percentage)
"memory": 67.8, // 0โ100 (percentage)
"bandwidth": 120.5, // Mbps
"storage": 30.1, // 0โ100 (percentage used)
"uptime": 86400 // seconds
}
Response 200
{
"status": "updated",
"node_id": "node-abc-001"
}
โ If no heartbeat is received for 120 seconds, node is auto-marked offline
GET
/nodes
List all nodes with pagination & filters
โผ
Query Parameters
page
integer
Page number (default: 1)
limit
integer
Items per page (default: 50, max: 200)
node_type
string
Filter by type (exact match)
location
string
Filter by location (partial match)
status
online | offline
Filter by status
Example Request
GET /nodes?page=1&limit=20&node_type=raspberry&status=online
X-API-Key: your-api-key
Response 200
{
"nodes": [...],
"total": 42,
"page": 1,
"limit": 20,
"pages": 3
}
GET
/nodes/active
Online nodes only (last seen < 2 min)
โผ
Response 200
{
"count": 5,
"nodes": [
{
"node_id": "node-abc-001",
"status": "online",
"node_type": "raspberry",
"cpu": 45.2,
"last_seen": "2024-01-15T10:30:00.000Z"
}
]
}
GET
/nodes/:node_id
Full detail for a single node
โผ
Response 200
{
"node_id": "node-abc-001",
"public_key": "-----BEGIN PUBLIC KEY-----...",
"ip_address": "192.168.1.100",
"node_type": "raspberry",
"location": "US-East",
"cpu": 45.2,
"memory": 67.8,
"bandwidth": 120.5,
"storage": 30.1,
"uptime": 86400,
"last_seen": "2024-01-15T10:30:00.000Z",
"status": "online",
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z"
}
Error โ 404 Not Found
{ "error": "Node 'node-xyz' not found" }
GET
/health
Public health check โ no auth required
โผ
Response 200
{
"status": "healthy",
"service": "zukga-node-registry",
"version": "1.0.0",
"timestamp": "2024-01-15T10:30:00.000Z",
"uptime": 3600,
"db": { "status": "ok", "latency_ms": 2 }
}
๐ Database Schema โ nodes
node_id
VARCHAR(128) PK
Primary key, unique node identifier
public_key
TEXT NOT NULL
PEM / hex / base64 public key
ip_address
VARCHAR(45)
IPv4 or IPv6 address
node_type
VARCHAR(50)
raspberry / server / supernode / โฆ
location
VARCHAR(255)
Geographic region
cpu
FLOAT
CPU usage percentage 0โ100
memory
FLOAT
Memory usage percentage 0โ100
bandwidth
FLOAT
Bandwidth in Mbps
storage
FLOAT
Storage usage percentage 0โ100
uptime
FLOAT
Uptime in seconds
last_seen
TIMESTAMPTZ
Last heartbeat timestamp
status
VARCHAR(20)
"online" or "offline"
created_at
TIMESTAMPTZ
Auto-set on insert
updated_at
TIMESTAMPTZ
Auto-updated on change
Deploy with Docker
1
Configure environment
cp .env.example .env
# Edit .env โ set API_KEY and JWT_SECRET
2
Start services (registry + postgres)
docker compose up --build
3
Optional: Launch pgAdmin (dev)
docker compose --profile dev up
# pgAdmin at http://localhost:5050
4
Verify health
curl http://localhost:4010/health
๐ก WebSocket โ Real-time Node Events
Connect to ws://localhost:4010/ws/nodes for live event streaming.
Event Types
// Node registered or re-registered
{ "event": "registered", "data": { "node_id": "..." }, "timestamp": "..." }
// Heartbeat received
{ "event": "heartbeat", "data": { "node_id": "...", "cpu": 45 }, "timestamp": "..." }
// Nodes went offline
{ "event": "offline", "data": { "node_ids": ["..."] }, "timestamp": "..." }
Browser Example
const ws = new WebSocket('ws://localhost:4010/ws/nodes');
ws.onmessage = (e) => console.log(JSON.parse(e.data));
ZUKGA Service Integrations
Trust Score Service
:5000
Evaluates node reliability based on uptime, heartbeat consistency, and performance metrics
Rewards Engine
:5001
Distributes ZUKGA token rewards to nodes based on contribution and uptime statistics
ZUKGA Wallet
:5002
Links node public keys to wallet addresses for on-chain reward distribution
# Set in .env to enable integrations
TRUST_SCORE_SERVICE_URL=http://trust-score-service:5000
REWARDS_ENGINE_URL=http://rewards-engine:5001
WALLET_SERVICE_URL=http://wallet-service:5002