REST API: http://{node_ip}:8001/api/v1 (for Light nodes & external clients)
P2P (QUIC): quic://{node_ip}:10876 (for Full/Super nodes - internal)
Genesis Nodes:
- 154.38.160.39:8001 (REST API) / :10876/udp (QUIC P2P)
- 62.171.157.44:8001 (REST API) / :10876/udp (QUIC P2P)
- 161.97.86.81:8001 (REST API) / :10876/udp (QUIC P2P)
- 5.189.130.160:8001 (REST API) / :10876/udp (QUIC P2P)
- 162.244.25.114:8001 (REST API) / :10876/udp (QUIC P2P)
Note: Light nodes use REST API (HTTP). Full/Super nodes use QUIC for P2P.
Most endpoints are public. Protected endpoints require:
Authorization: Bearer {token}header- Ed25519 signature verification
π Cryptography Details: See CRYPTOGRAPHY_IMPLEMENTATION.md for full cryptographic specifications.
| Context | Algorithm | Notes |
|---|---|---|
| User Transactions | Ed25519 | Standard wallet signatures |
| Node-to-Node (P2P) | Hybrid (Ed25519 + Dilithium) | NIST/Cisco compliant, ephemeral keys per message |
| Block Signatures | Hybrid (Ed25519 + Dilithium) | Quantum-resistant, FIPS 204 |
GET /api/v1/heightResponse:
{
"height": 1234567,
"timestamp": 1700000000
}GET /api/v1/block/latestResponse:
{
"block_height": 1234567,
"hash": "abc123...",
"previous_hash": "def456...",
"timestamp": 1700000000,
"producer": "node_001",
"transaction_count": 150,
"poh_hash": "ghi789...",
"poh_count": 500000000
}GET /api/v1/block/{height}Parameters:
| Name | Type | Description |
|---|---|---|
| height | u64 | Block number |
GET /api/v1/block/hash/{hash}Parameters:
| Name | Type | Description |
|---|---|---|
| hash | string | Block hash (hex) |
GET /api/v1/microblock/{height}GET /api/v1/microblocks?start={start}&end={end}Query Parameters:
| Name | Type | Description |
|---|---|---|
| start | u64 | Start block height |
| end | u64 | End block height (max 100 blocks) |
GET /api/v1/macroblock/{height}GET /api/v1/account/{address}Response:
{
"address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"balance": 1000000000,
"nonce": 42,
"node_type": "Light",
"reputation": 70.0,
"created_at": 1700000000
}GET /api/v1/account/{address}/balanceResponse:
{
"address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"balance": 1000000000,
"balance_formatted": "1.0 QNC"
}GET /api/v1/account/{address}/transactions?page={page}&per_page={per_page}Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
| page | u32 | 1 | Page number |
| per_page | u32 | 20 | Items per page (max 100) |
POST /api/v1/transaction
Content-Type: application/json- Ed25519 signature - REQUIRED for all transactions
- Without signature, transaction will be REJECTED
π OPTIONAL Quantum-Resistant Signatures (v2.25):
- Dilithium3 signature - OPTIONAL for post-quantum security
- When present: +50% gas fee (enterprise quantum protection)
- Both Ed25519 AND Dilithium3 are verified if Dilithium present
Request Body (Standard TX - Ed25519 only):
{
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"to": "b2c3d4e5f6g7h8i9j0keonl1m2n3o4p5q6r7s8t9u0v1w2",
"amount": 1000000000,
"nonce": 42,
"gas_price": 100000,
"gas_limit": 10000,
"signature": "ed25519_signature_hex",
"public_key": "ed25519_pubkey_hex"
}Request Body (Quantum TX - Ed25519 + Dilithium3):
{
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"to": "b2c3d4e5f6g7h8i9j0keonl1m2n3o4p5q6r7s8t9u0v1w2",
"amount": 1000000000,
"nonce": 42,
"gas_price": 100000,
"gas_limit": 10000,
"signature": "ed25519_signature_hex",
"public_key": "ed25519_pubkey_hex",
"dilithium_signature": "dilithium3_signature_hex_6586chars",
"dilithium_public_key": "dilithium3_pubkey_hex_3904chars"
}Note: Quantum TX gas =
gas_price * 1.5 * gas_limit(50% premium for post-quantum security)
Signature Message Format:
transfer:{from}:{to}:{amount}:{nonce}
Address Format: {19 hex}eon{15 hex}{4 hex checksum} (41 characters total)
Gas Limits (QNet-optimized):
| Operation | Gas Limit |
|---|---|
| Transfer | 10,000 |
| Node Activation | 50,000 |
| Reward Claim | 25,000 |
| Contract Deploy | 500,000 |
| Contract Call | 100,000 |
| Ping | 0 (FREE) |
| Batch Operation | 150,000 |
| Max Limit | 1,000,000 |
Min Gas Price: 100,000 nano QNC (0.0001 QNC)
**Response:**
```json
{
"success": true,
"tx_hash": "abc123...",
"message": "Transaction submitted"
}
GET /api/v1/transaction/{hash}Response:
{
"hash": "abc123...",
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"to": "b2c3d4e5f6g7h8i9j0keonl1m2n3o4p5q6r7s8t9u0v1w2",
"amount": 1000000000,
"nonce": 42,
"gas_price": 100000,
"gas_limit": 10000,
"timestamp": 1700000000,
"tx_type": "Transfer"
}GET /api/v1/transactions/history?address={address}&page={page}&per_page={per_page}&tx_type={type}&direction={direction}&start_time={start}&end_time={end}Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | required | Wallet address |
| page | u32 | 1 | Page number |
| per_page | u32 | 20 | Items per page (max 100) |
| tx_type | string | "all" | Filter: "transfer", "activation", "reward", "all" |
| direction | string | "all" | Filter: "sent", "received", "all" |
| start_time | u64 | - | Unix timestamp start |
| end_time | u64 | - | Unix timestamp end |
Response:
{
"success": true,
"transactions": [...],
"total": 150,
"page": 1,
"per_page": 20,
"total_pages": 8
}GET /api/v1/mempool/statusResponse:
{
"pending_count": 1234,
"total_gas": 50000000,
"min_gas_price": 100000,
"max_gas_price": 500000
}GET /api/v1/mempool/transactions?limit={limit}POST /api/v1/bundle/submit
Content-Type: application/jsonRequest Body:
{
"transactions": [...],
"gas_premium": 1.2,
"max_block_number": 1234600,
"signature": "dilithium_signature_hex"
}Response:
{
"success": true,
"bundle_id": "bundle_abc123",
"expires_at": 1700000060
}GET /api/v1/bundle/{id}/statusDELETE /api/v1/bundle/{id}POST /api/v1/generate-activation-code
Content-Type: application/jsonRequest Body:
{
"wallet_address": "Solana_or_EON_address",
"burn_tx_hash": "solana_burn_tx_signature",
"node_type": "light|full|super",
"burn_amount": 1350,
"phase": 1
}Response:
{
"success": true,
"activation_code": "QNET-XXXXXX-XXXXXX-XXXXXX",
"node_type": "light",
"permanent": true
}Note: Activation codes are permanent and never expire. They are cryptographically bound to the burn transaction on Solana blockchain.
Activation Code Format (25 chars):
QNET-{TypeMarker+Timestamp}-{EncryptedWallet1}-{EncryptedWallet2+Entropy}
βββββββ6 charsβββββββ βββββ6 charsβββββ ββββββββββ6 charsββββββββββ
GET /api/v1/activations/by-wallet/{wallet_address}Response:
{
"success": true,
"activations": [
{
"activation_code_hash": "abc123...",
"node_type": "light",
"activated_at": 1700000000,
"is_active": true
}
]
}POST /api/v1/light-node/register
Content-Type: application/jsonRequest Body:
{
"node_id": "light_node_abc123",
"wallet_address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"fcm_token": "firebase_token_here",
"push_type": "fcm|unified_push|polling",
"unified_push_endpoint": "https://ntfy.sh/topic_xyz",
"public_key": "dilithium_pubkey_hex"
}Response:
{
"success": true,
"node_id": "light_node_abc123",
"shard_id": 42,
"next_ping_slot": 1700003600
}POST /api/v1/light-node/ping-response
Content-Type: application/jsonRequest Body:
{
"node_id": "light_node_abc123",
"challenge": "random_challenge_hex",
"signature": "dilithium_signature_hex",
"timestamp": 1700000000
}POST /api/v1/light-node/reactivate
Content-Type: application/jsonRequest Body:
{
"node_id": "light_node_abc123",
"wallet_address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"signature": "ed25519_signature_hex"
}Response:
{
"success": true,
"message": "Node reactivated successfully",
"next_ping_slot": 1700003600
}GET /api/v1/light-node/status?node_id={node_id}Response:
{
"success": true,
"node_id": "light_node_abc123",
"is_active": true,
"consecutive_failures": 0,
"last_seen": 1700000000,
"shard_id": 42,
"total_pings": 150,
"successful_pings": 148
}GET /api/v1/light-node/next-ping?node_id={node_id}Response:
{
"success": true,
"node_id": "light_node_abc123",
"next_ping_time": 1700003600,
"window_number": 42,
"slot_in_window": 127
}Used by F-Droid users without UnifiedPush. Mobile app uses smart wake-up - schedules precise wake ~2 minutes before calculated ping slot (once per 4-hour window), NOT continuous polling.
GET /api/v1/light-node/pending-challenge?node_id={node_id}Response (challenge available):
{
"success": true,
"node_id": "light_node_abc123",
"has_challenge": true,
"challenge": "random_challenge_hex",
"expires_at": 1700000060
}Response (not in ping slot):
{
"success": true,
"node_id": "light_node_abc123",
"has_challenge": false,
"message": "Not your ping slot yet",
"next_ping_time": 1700014400
}Note: App receives
next_ping_timeand schedules next wake-up accordingly. This ensures battery-efficient operation (~1 API call per 4 hours instead of continuous polling).
GET /api/v1/node/status?activation_code={code}&node_id={id}Query Parameters (one required):
| Name | Type | Description |
|---|---|---|
| activation_code | string | QNET-XXXXXX-XXXXXX-XXXXXX |
| node_id | string | Node identifier |
Response:
{
"success": true,
"node_id": "full_node_abc123",
"node_type": "Full",
"is_online": true,
"heartbeat_count": 8,
"reputation": 85.5,
"pending_rewards": 1500000000,
"total_distributed_rewards": 50000000000,
"last_seen": 1700000000,
"uptime_percentage": 99.5
}Reward Rounds (Epochs):
- 1 epoch = 14,400 blocks = 4 hours (at 1 block/second)
- Rewards distributed at blocks 14400, 28800, 43200, etc.
Three Reward Pools:
| Pool | Source | Distribution | Phase |
|---|---|---|---|
| Pool 1 | Base Emission | Equal to ALL eligible nodes | Both |
| Pool 2 | Transaction Fees | Full/Super nodes only (50% each) | Both |
| Pool 3 | Activation Payments | Equal to ALL eligible nodes | Phase 2 only |
Dynamic Emission (Pool 1):
- Initial: ~251,432 QNC per epoch
- Halving: every 4 years
- Sharp drop: 10x reduction at year 20
Eligibility Requirements:
| Node Type | Pings Required | Timing |
|---|---|---|
| Light | 1/1 attestation | Once per 4h window (sharded) |
| Full | 8/10 heartbeats | Every ~24 min (deterministic) |
| Super | 9/10 heartbeats | Every ~24 min (deterministic) |
Ping Window Calculation:
window_start = timestamp - (timestamp % (4 * 60 * 60))
window_end = window_start + (4 * 60 * 60)
Heartbeat included if: timestamp >= window_start && timestamp < window_end
POST /api/v1/rewards/claim
Content-Type: application/jsonRequest Body:
{
"node_id": "node_abc123",
"wallet_address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"quantum_signature": "ed25519_signature_hex",
"public_key": "ed25519_pubkey_hex"
}Response:
{
"success": true,
"claimed_amount": 1500000000,
"tx_hash": "abc123...",
"new_balance": 5000000000
}POST /api/v1/batch/claim-rewards
Content-Type: application/jsonRequest Body:
{
"node_ids": ["node_1", "node_2", "node_3"],
"owner_address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"signature": "ed25519_signature_hex"
}POST /api/v1/batch/transfer
Content-Type: application/json- Ed25519 signature - REQUIRED
- All transfers in batch must be from the SAME sender
Request Body:
{
"transfers": [
{
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"to_address": "b2c3d4e5f6g7h8i9j0keonl1m2n3o4p5q6r7s8t9u0v1w2",
"amount": 1000000000,
"memo": "Payment 1"
},
{
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"to_address": "c3d4e5f6g7h8i9j0k1leon2m3n4o5p6q7r8s9t0u1v2w3",
"amount": 500000000,
"memo": "Payment 2"
}
],
"batch_id": "batch_unique_id_123",
"signature": "ed25519_signature_hex",
"public_key": "ed25519_pubkey_hex"
}Signature Message Format:
batch_transfer:{from}:{total_amount}:{transfer_count}:{batch_id}
Response:
{
"success": true,
"batch_id": "batch_unique_id_123",
"tx_hash": "batch_abc123...",
"total_amount": 1500000000,
"transfer_count": 2,
"from_address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"message": "Batch transfer submitted with 2 transfers"
}GET /api/v1/rewards/pending?node_id={node_id}Response:
{
"success": true,
"node_id": "node_abc123",
"node_type": "Full",
"pending_rewards": 1.5,
"pools": {
"pool1_base_emission": 1.0,
"pool2_tx_fees": 0.5,
"pool3_activation_bonus": 0.0
},
"ping_status": {
"heartbeat_count": 10,
"required_heartbeats": 8,
"is_eligible": true
},
"current_phase": "Phase1",
"current_window_start": 1700000000,
"current_block_height": 14500,
"needs_attention": false
}GET /api/v1/rewards/history/{node_id}?offset={offset}&limit={limit}Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
| offset | u64 | 0 | Number of epochs to skip (for pagination) |
| limit | u64 | 10 | Number of epochs to return (max 100) |
Response:
{
"success": true,
"node_id": "node_abc123",
"current_epoch": 25,
"history": [
{
"epoch": 24,
"status": "claimed",
"total_qnc": 1.5,
"pool1_qnc": 1.0,
"pool2_qnc": 0.5,
"pool3_qnc": 0.0,
"claim_time": 1700100000,
"tx_hash": "abc123..."
},
{
"epoch": 23,
"status": "unclaimed",
"estimated_qnc": 1.4
}
],
"pagination": {
"offset": 0,
"limit": 10,
"has_more": true
}
}GET /api/v1/rewards/pools/{node_id}Description: Returns detailed breakdown of all reward pools for a specific node, including dynamic emission rates with halving schedule.
Response:
{
"success": true,
"node_id": "node_abc123",
"pools": {
"pool1_base_emission": {
"current_epoch_qnc": 1.0,
"description": "Base emission divided equally among all eligible nodes"
},
"pool2_transaction_fees": {
"current_epoch_qnc": 0.5,
"description": "Share of transaction fees (Full/Super only)"
},
"pool3_activation_bonus": {
"current_epoch_qnc": 0.0,
"description": "Share of activation pool (Phase 2 only)"
}
},
"emission_rate": {
"pool1_base_per_epoch_qnc": 251432.34,
"pool1_base_per_year_qnc": 551643145.56,
"current_phase": "Phase1",
"phase_description": "Phase1: 1DEV burn for activation, Pool3 disabled",
"halving_schedule": {
"period_years": 4,
"sharp_drop_year": 20,
"sharp_drop_multiplier": 10
}
},
"eligibility": {
"is_eligible": true,
"heartbeats": 10,
"required": 8,
"node_type": "Full"
},
"cached_at": 1700000000,
"cache_ttl_seconds": 10
}GET /api/v1/rewards/by-wallet/{wallet_address}Description: Returns all nodes owned by a specific wallet address with their pending rewards. Uses inverted index for O(1) lookup.
Response:
{
"success": true,
"wallet_address": "a1b2c3d4e5f6g7h8i9jeon...",
"nodes": [
{
"node_id": "full_node_001",
"node_type": "Full",
"pending_qnc": 1.5,
"is_eligible": true,
"heartbeats": 10
},
{
"node_id": "light_node_002",
"node_type": "Light",
"pending_qnc": 0.5,
"is_eligible": true,
"attestations": 1
}
],
"total_pending_qnc": 2.0,
"node_count": 2
}POST /api/v1/rewards/pending/batch
Content-Type: application/jsonDescription: Get pending rewards for multiple nodes in a single request. Max 100 nodes per batch.
Request Body:
{
"node_ids": ["node_001", "node_002", "node_003"]
}Response:
{
"success": true,
"results": [
{
"node_id": "node_001",
"pending_qnc": 1.5,
"is_eligible": true
},
{
"node_id": "node_002",
"pending_qnc": 0.8,
"is_eligible": true
},
{
"node_id": "node_003",
"error": "Node not found"
}
],
"total_pending_qnc": 2.3,
"successful": 2,
"failed": 1
}GET /api/v1/rewards/network/statsDescription: Returns network-wide reward statistics. Cached for 30 seconds.
Response:
{
"success": true,
"network_stats": {
"total_claims_all_time": 15000,
"total_distributed_qnc": 1500000.0,
"recent_epochs_scanned": 50
},
"current_epoch": 25,
"current_block_height": 360000,
"emission_rate": {
"pool1_base_per_epoch_qnc": "dynamic - use /api/v1/rewards/pools for current value",
"initial_rate_qnc_per_epoch": 251432.34,
"halving_period_years": 4,
"sharp_drop_at_year": 20,
"sharp_drop_multiplier": 10
},
"phases": {
"current": "Phase1",
"phase1_description": "1DEV burn, Pool3=0",
"phase2_description": "QNC activation, Pool3 enabled"
},
"cached_at": 1700000000,
"cache_ttl_seconds": 30
}GET /api/v1/rewards/summary/{node_id}Description: Returns lifetime aggregated reward statistics for a node. Useful for displaying total earnings in wallet UI. Cached for 60 seconds.
Response:
{
"success": true,
"node_id": "node_abc123",
"lifetime_stats": {
"total_claimed_qnc": 150.5,
"total_pool1_qnc": 100.0,
"total_pool2_qnc": 45.0,
"total_pool3_qnc": 5.5,
"epochs_participated": 100,
"epochs_claimed": 95,
"epochs_missed": 5,
"first_claim_epoch": 1,
"last_claim_epoch": 95,
"average_per_epoch_qnc": 1.58
},
"current_pending": {
"pending_qnc": 1.5,
"is_eligible": true,
"current_epoch": 100
},
"cached_at": 1700000000,
"cache_ttl_seconds": 60
}GET /api/v1/peersResponse:
{
"total_peers": 156,
"connected_peers": 42,
"peers": [
{
"node_id": "node_001",
"ip": "154.38.160.39",
"port": 9876,
"node_type": "Super",
"reputation": 95.0,
"latency_ms": 45
}
]
}GET /api/v1/nodes/discoveryGET /api/v1/nodesPOST /api/v1/nodes
Content-Type: application/jsonRequest Body:
{
"node_id": "node_abc123",
"node_type": "Full",
"wallet_address": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"public_key": "dilithium_pubkey_hex",
"api_endpoint": "http://node_ip:8001"
}Response:
{
"success": true,
"node_id": "node_abc123",
"registered_at": 1700000000
}
---
### Node Health Check
```http
GET /api/v1/node/healthResponse:
{
"status": "healthy",
"node_id": "node_abc123",
"node_type": "Full",
"block_height": 1234567,
"peers_connected": 42,
"mempool_size": 150,
"uptime_seconds": 86400
}GET /api/v1/diagnostics/networkGET /api/v1/network/failoversGET /api/v1/statsResponse:
{
"block_height": 1234567,
"total_transactions": 50000000,
"total_accounts": 250000,
"total_nodes": 15000,
"light_nodes": 12000,
"full_nodes": 2500,
"super_nodes": 500,
"tps_current": 1250,
"tps_peak": 424411
}GET /api/v1/blocks/statsGET /api/v1/metrics/performanceThese endpoints are optimized for public consumption (websites, dashboards). Data is cached on the server for 10 minutes to prevent spam and ensure consistent responses.
GET /api/v1/public/statsDescription: Returns cached network statistics. Safe to call frequently - same data for all clients. Server updates cache every 10 minutes.
Response:
{
"active_nodes": 85000,
"light_nodes": 50000,
"full_nodes": 30000,
"super_nodes": 5000,
"height": 1234567,
"phase": 1,
"burn_percentage": 45.5,
"cached_at": "2025-11-28T12:00:00Z",
"cache_ttl_seconds": 600
}| Field | Type | Description |
|---|---|---|
| active_nodes | u64 | Total active nodes (Light + Full + Super) |
| light_nodes | u64 | Active Light nodes |
| full_nodes | u64 | Active Full nodes |
| super_nodes | u64 | Active Super nodes |
| height | u64 | Current blockchain height |
| phase | u8 | Current phase (1 = 1DEV burn, 2 = QNC) |
| burn_percentage | f64 | Percentage of 1DEV supply burned |
| cached_at | string | ISO 8601 timestamp of cache update |
| cache_ttl_seconds | u64 | Cache lifetime in seconds |
GET /api/v1/activation/price?type={node_type}Description: Returns server-calculated activation price. Server knows burn percentage and network size - client cannot manipulate pricing.
Query Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
| type | string | No | Node type: light, full, super. Default: light |
Phase 1 Response (1DEV Burn):
{
"phase": 1,
"node_type": "super",
"cost": 1050,
"currency": "1DEV",
"base_cost": 1500,
"min_cost": 300,
"burn_percentage": 30.0,
"savings": 450,
"savings_percent": 30,
"mechanism": "burn",
"universal_price": true
}Phase 2 Response (QNC Transfer):
{
"phase": 2,
"node_type": "super",
"cost": 5000,
"currency": "QNC",
"base_cost": 10000,
"multiplier": 0.5,
"mechanism": "transfer_to_pool3",
"universal_price": false
}| Field | Type | Description |
|---|---|---|
| phase | u8 | Current activation phase |
| node_type | string | Requested node type |
| cost | u64 | Final activation cost |
| currency | string | Token to use (1DEV or QNC) |
| base_cost | u64 | Base price before discounts |
| multiplier | f64 | Network size multiplier (Phase 2 only) |
| mechanism | string | burn (Phase 1) or transfer_to_pool3 (Phase 2) |
| universal_price | bool | True if same price for all node types |
Phase 1 Pricing Formula:
price = max(1500 - floor(burn% / 10) Γ 150, 300)
Phase 2 Network Multipliers:
| Network Size | Multiplier |
|---|---|
| β€100K nodes | 0.5x (early adopter discount) |
| β€300K nodes | 1.0x (base price) |
| β€1M nodes | 2.0x (high demand) |
| >1M nodes | 3.0x (maximum) |
GET /api/v1/poh/statusResponse:
{
"poh_hash": "abc123...",
"poh_count": 500000000,
"current_slot": 1234567,
"hashes_per_second": 500000,
"last_checkpoint": 499000000,
"is_synchronized": true
}GET /api/v1/shred-protocol/metricsGET /api/v1/parallel-executor/metricsGET /api/v1/pre-execution/statusGET /api/v1/adaptive-bft/timeoutsGET /api/v1/producer/statusGET /api/v1/sync/statusResponse:
{
"is_synced": true,
"current_height": 1234567,
"target_height": 1234567,
"sync_progress": 100.0,
"peers_syncing_from": 5
}GET /api/v1/gas/recommendationsResponse:
{
"slow": 100000,
"standard": 150000,
"fast": 250000,
"instant": 500000,
"base_fee": 100000
}GET /api/v1/reputation/history?node_id={node_id}POST /api/v1/consensus/commitPOST /api/v1/consensus/revealGET /api/v1/consensus/round/{round_number}Parameters:
| Name | Type | Description |
|---|---|---|
| round_number | u64 | Consensus round number |
Response:
{
"round": 12345,
"status": "committed",
"participants": 850,
"threshold_met": true,
"block_hash": "abc123..."
}POST /api/v1/consensus/syncPOST /api/v1/contract/deploy
Content-Type: application/json- Ed25519 signature (NIST FIPS 186-5) - REQUIRED
- Dilithium signature (NIST FIPS 204) - REQUIRED (post-quantum security)
- SHA3-256 hash (NIST FIPS 202) - For code hash
Smart contracts are critical operations. Like node consensus, they require BOTH classical and post-quantum signatures.
Request Body:
{
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"code": "base64_encoded_wasm_bytecode",
"constructor_args": {
"name": "MyToken",
"symbol": "MTK",
"initial_supply": 1000000
},
"gas_limit": 500000,
"gas_price": 150000,
"nonce": 1,
"signature": "ed25519_signature_hex",
"public_key": "ed25519_pubkey_hex",
"dilithium_signature": "dilithium_signature_hex",
"dilithium_public_key": "dilithium_pubkey_hex"
}Signature Message Format:
contract_deploy:{from}:{code_hash}:{nonce}
Response:
{
"success": true,
"contract_address": "c1d2e3f4g5h6i7j8k9leon0m1n2o3p4q5r6s7t8u9v0w1",
"code_hash": "sha3_256_hash_of_wasm",
"code_size": 45678,
"gas_limit": 500000,
"deployer": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"message": "Contract deployment submitted to mempool",
"security": {
"ed25519_verified": true,
"dilithium_verified": true,
"quantum_secure": true,
"nist_standards": {
"signature": "FIPS 186-5 (Ed25519)",
"hash": "FIPS 202 (SHA3-256)",
"post_quantum": "FIPS 204 (Dilithium)"
}
}
}Gas Limits for Deployment:
| Code Size | Recommended Gas |
|---|---|
| < 10 KB | 100,000 |
| 10-50 KB | 250,000 |
| 50-100 KB | 500,000 |
| > 100 KB | 1,000,000 |
POST /api/v1/contract/call
Content-Type: application/json- Ed25519 signature (NIST FIPS 186-5) - REQUIRED
- Dilithium signature (NIST FIPS 204) - REQUIRED
- View calls (read-only) require NO signatures
Request Body (State-Changing Call - BOTH signatures required):
{
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"contract_address": "c1d2e3f4g5h6i7j8k9leon0m1n2o3p4q5r6s7t8u9v0w1",
"method": "transfer",
"args": {
"to": "b2c3d4e5f6g7h8i9j0keonl1m2n3o4p5q6r7s8t9u0v1w2",
"amount": 1000000000
},
"gas_limit": 100000,
"gas_price": 150000,
"nonce": 2,
"signature": "ed25519_signature_hex",
"public_key": "ed25519_pubkey_hex",
"dilithium_signature": "dilithium_signature_hex",
"dilithium_public_key": "dilithium_pubkey_hex",
"is_view": false
}Signature Message Format:
contract_call:{from}:{contract_address}:{method}:{nonce}
Request Body (View Call - No Signatures Required):
{
"from": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"contract_address": "c1d2e3f4g5h6i7j8k9leon0m1n2o3p4q5r6s7t8u9v0w1",
"method": "balanceOf",
"args": {
"account": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2"
},
"gas_limit": 10000,
"gas_price": 100000,
"nonce": 0,
"is_view": true
}Response (State-Changing):
{
"success": true,
"tx_hash": "abc123...",
"contract_address": "c1d2e3f4g5h6i7j8k9leon0m1n2o3p4q5r6s7t8u9v0w1",
"method": "transfer",
"gas_limit": 100000,
"message": "Contract call submitted to mempool",
"security": {
"ed25519_verified": true,
"dilithium_verified": true,
"quantum_secure": true
}
}GET /api/v1/contract/{address}Parameters:
| Name | Type | Description |
|---|---|---|
| address | string | Contract EON address |
Response:
{
"success": true,
"contract": {
"address": "c1d2e3f4g5h6i7j8k9leon0m1n2o3p4q5r6s7t8u9v0w1",
"deployer": "a1b2c3d4e5f6g7h8i9jeon0k1l2m3n4o5p6q7r8s9a1b2",
"deployed_at": 1700000000,
"code_hash": "sha3_256_hash",
"version": "1.0.0",
"total_gas_used": 5000000,
"call_count": 150,
"is_active": true
}
}GET /api/v1/contract/{address}/state?key={key}Query Parameters:
| Name | Type | Description |
|---|---|---|
| key | string | Single state key to query |
| keys | string | Comma-separated list of keys |
Example:
GET /api/v1/contract/c1d2e3f4.../state?key=total_supply
GET /api/v1/contract/c1d2e3f4.../state?keys=name,symbol,decimalsResponse:
{
"success": true,
"contract_address": "c1d2e3f4g5h6i7j8k9leon0m1n2o3p4q5r6s7t8u9v0w1",
"state": {
"total_supply": "1000000000000000000",
"name": "MyToken",
"symbol": "MTK"
}
}POST /api/v1/contract/estimate-gas
Content-Type: application/jsonRequest Body:
{
"operation": "deploy|call|view",
"code_size": 45678,
"args": { "param1": "value1" }
}Response:
{
"success": true,
"operation": "deploy",
"estimated_gas": 150000,
"gas_prices": {
"slow": 100000,
"standard": 150000,
"fast": 250000
},
"estimated_cost": {
"slow": 15000000000,
"standard": 22500000000,
"fast": 37500000000
},
"estimated_cost_qnc": {
"slow": "0.015000000 QNC",
"standard": "0.022500000 QNC",
"fast": "0.037500000 QNC"
}
}Note (v2.19.22): Full/Super nodes use QUIC (UDP 10876) for P2P communication. These HTTP endpoints are for Light nodes and legacy compatibility only.
POST /api/v1/p2p/message
Content-Type: application/jsonRequest Body:
{
"message_type": "BlockAnnouncement|Transaction|PeerDiscovery|...",
"payload": "base64_encoded_data",
"sender_id": "node_abc123",
"signature": "dilithium_signature_hex"
}GET /api/v1/pingResponse:
{
"status": "pong",
"timestamp": 1700000000,
"node_id": "node_abc123"
}GET /api/v1/auth/challenge?address={address}Response:
{
"challenge": "random_challenge_hex",
"expires_at": 1700000060
}POST /api/v1/shutdown
Authorization: Bearer {admin_token}POST /api/v1/failovers
Authorization: Bearer {admin_token}GET /api/v1/node/secure-info
Authorization: Bearer {admin_token}| Code | Description |
|---|---|
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid/missing auth |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource doesn't exist |
| 429 | Too Many Requests - Rate limited |
| 500 | Internal Server Error |
| 503 | Service Unavailable - Node syncing |
| Endpoint Type | Limit | Window | Block Duration |
|---|---|---|---|
| Public Read | 100 req | 1 min | 30 sec |
| Transaction Submit | 30 req | 1 min | 60 sec |
| Bundle Submit | 10 req | 1 min | 120 sec |
| Reward Read | 300 req | 1 min | 30 sec |
| Reward Claim | 60 req | 1 min | 60 sec |
| Admin | 10 req | 1 min | 300 sec |
ws://{node_ip}:8001/ws/subscribe?channels=blocks,account:ADDRESS,contract:ADDRESS
| Limit | Value | Description |
|---|---|---|
| Per IP | 5 connections | Maximum simultaneous WebSocket connections per IP address |
| Total | 10,000 connections | Maximum total WebSocket connections per node |
| Exceeded | HTTP 429 | Returns "Too Many Requests" if limit exceeded |
Note: Connection count is automatically decremented when client disconnects.
| Channel | Format | Description |
|---|---|---|
blocks |
blocks |
All new blocks |
account |
account:EON_ADDRESS |
Balance updates for specific address |
contract |
contract:EON_ADDRESS |
Events from specific contract |
mempool |
mempool |
Pending transactions |
tx |
tx:TX_HASH |
Specific transaction confirmation |
rewards |
rewards:NODE_ID |
Reward updates for specific node (NEW v2.43.1) |
const ws = new WebSocket('ws://154.38.160.39:8001/ws/subscribe?channels=blocks,account:a1b2c3...');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Event:', data.type, data.data);
};NewBlock:
{
"type": "NewBlock",
"data": {
"height": 1234567,
"hash": "abc123...",
"timestamp": 1700000000,
"tx_count": 150,
"producer": "node_001"
}
}BalanceUpdate:
{
"type": "BalanceUpdate",
"data": {
"address": "a1b2c3d4e5f6g7h8i9jeon...",
"new_balance": 1500000000,
"change": 100000000,
"tx_hash": "tx_abc123..."
}
}ContractEvent:
{
"type": "ContractEvent",
"data": {
"contract_address": "c1d2e3f4g5h6i7j8k9leon...",
"event_name": "Transfer",
"data": {"from": "...", "to": "...", "amount": 100},
"block_height": 1234567,
"tx_hash": "tx_xyz789..."
}
}TxConfirmed:
{
"type": "TxConfirmed",
"data": {
"tx_hash": "tx_abc123...",
"block_height": 1234567,
"status": "confirmed"
}
}PendingTx:
{
"type": "PendingTx",
"data": {
"tx_hash": "tx_pending123...",
"from": "a1b2c3...",
"to": "b2c3d4...",
"amount": 1000000000
}
}RewardClaimed (NEW v2.43.1):
{
"type": "RewardClaimed",
"data": {
"node_id": "node_abc123",
"wallet_address": "a1b2c3d4e5f6g7h8i9jeon...",
"amount_qnc": 1.5,
"tx_hash": "abc123...",
"epoch": 25
}
}RewardUpdate (NEW v2.43.1):
{
"type": "RewardUpdate",
"data": {
"node_id": "node_abc123",
"pending_qnc": 1.5,
"pool1_qnc": 1.0,
"pool2_qnc": 0.5,
"pool3_qnc": 0.0,
"is_eligible": true,
"heartbeats": 10
}
}Welcome (on connect):
{
"type": "connected",
"message": "WebSocket connected to QNet node",
"subscribed_channels": 2,
"timestamp": 1700000000
}Warning (if client lags):
{
"type": "warning",
"message": "Missed 5 events due to slow connection"
}POST /api/v1/token/deployRequest Body:
{
"from": "EON_creator_address...",
"name": "MyToken",
"symbol": "MTK",
"decimals": 9,
"initial_supply": 1000000000000000000,
"signature": "base64_ed25519_signature",
"public_key": "base64_ed25519_pubkey"
}Response:
{
"success": true,
"token": {
"contract_address": "EON_contract_abc123...",
"name": "MyToken",
"symbol": "MTK",
"decimals": 9,
"total_supply": 1000000000000000000,
"creator": "EON_creator_address..."
}
}GET /api/v1/token/{contract_address}Response:
{
"success": true,
"token": {
"contract_address": "EON_contract_abc123...",
"name": "MyToken",
"symbol": "MTK",
"decimals": 9,
"total_supply": 1000000000000000000
}
}GET /api/v1/token/{contract_address}/balance/{holder_address}Response:
{
"success": true,
"contract_address": "EON_contract_abc123...",
"holder_address": "EON_holder...",
"balance": 500000000000000000,
"token_name": "MyToken",
"token_symbol": "MTK",
"decimals": 9
}GET /api/v1/account/{address}/tokensResponse:
{
"success": true,
"address": "EON_holder...",
"tokens": [
{
"contract_address": "EON_token1...",
"balance": 500000000000000000,
"name": "MyToken",
"symbol": "MTK",
"decimals": 9
}
],
"token_count": 1
}GET /api/v1/snapshot/latestResponse:
{
"success": true,
"height": 1234500,
"ipfs_cid": "Qm...",
"state_root": "abc123...",
"timestamp": 1732712345
}GET /api/v1/snapshot/{height}Response: Binary snapshot data or redirect to IPFS
π REWARDS API OVERHAUL
- NEW:
GET /api/v1/rewards/history/{node_id}- Paginated reward history by epoch - NEW:
GET /api/v1/rewards/pools/{node_id}- Detailed pool breakdown with dynamic emission - NEW:
GET /api/v1/rewards/by-wallet/{wallet}- All nodes for a wallet (O(1) inverted index) - NEW:
POST /api/v1/rewards/pending/batch- Batch pending rewards (max 100 nodes) - NEW:
GET /api/v1/rewards/network/stats- Network-wide reward statistics - NEW:
GET /api/v1/rewards/summary/{node_id}- Lifetime aggregated stats for node - NEW: WebSocket events:
RewardClaimed,RewardUpdate - NEW: WebSocket channel:
rewards:NODE_ID - IMPROVED: Rate limiting for all reward endpoints (300 req/min read, 60 req/min write)
- IMPROVED: Caching: Pool data (10s), Network stats (30s), Summary (60s)
- FIX: Off-by-one bug in reward window calculation (v2.43.1)
- FIX: Pool 1 dynamic emission with halving schedule
- FIX: Pool 3 correctly shows 0 in Phase 1, enabled in Phase 2
π§ CONSENSUS IMPROVEMENTS
- FIX:
prev_hash_mismatchnow triggersFORK_DETECTEDfor proper reorg - NEW: Height validation in heartbeats (max +100 jump, +50 ahead of local)
- NEW: Backpressure for block broadcasts (max 3 pending, 500ms wait)
- IMPROVED: Heartbeat service now uses
tokio::spawn(wasstd::thread) - IMPROVED:
sign_heartbeat_dilithiumusesspawn_blocking(no runtime panic)
- OPTIMIZATION: Fire-and-forget Shred Protocol broadcast (1 block/sec production guaranteed)
- OPTIMIZATION: 30-second Genesis startup wait (prevents race conditions)
- OPTIMIZATION: Emergency timeout increased to 10s (was 2s)
- RELIABILITY: Pseudo-infinite retries for blocks (never discard critical data)
- RELIABILITY: Exponential backoff: 10s (0-9) β 30s β 60s β 120s β 240s β 300s max
- MEMORY: Adaptive buffer: Full/Super 500 blocks (~50MB), Light 100 blocks (~10MB)
- SYNC: Background re-request every 30s with exponential backoff
- SECURITY: Heartbeat with HYBRID signature (Ed25519 + Dilithium, quantum-resistant)
- OPTIMIZATION: RAW bytes signatures (88% size reduction)
- OPTIMIZATION: Shred Protocol block propagation for ALL network sizes
- OPTIMIZATION: Kademlia K-neighbors for heartbeat routing (K=3)
- OPTIMIZATION: Exponential backoff for failover (3s β 6s β 12s β 24s β 30s max)
- NEW:
gossip_to_k_neighbors()method for DHT-based message propagation - SECURITY: Heartbeat validation via active_full_super_nodes registry (NIST FIPS 204 compliant)
- NEW: QRC-20 Token endpoints:
POST /api/v1/token/deploy- Deploy QRC-20 tokenGET /api/v1/token/{address}- Get token infoGET /api/v1/token/{address}/balance/{holder}- Get token balanceGET /api/v1/account/{address}/tokens- Get all tokens for address
- NEW: Snapshot endpoints for fast sync:
GET /api/v1/snapshot/latest- Latest snapshot infoGET /api/v1/snapshot/{height}- Download snapshot
- FIX: Global token registry (persists across requests)
- FIX: Contract info returns error for non-existent contracts
- FIX: Peer validation logic corrected
- NEW: WebSocket real-time event subscriptions:
ws://node:8001/ws/subscribe- Real-time events- Channels: blocks, account, contract, mempool, tx
- NEW: Smart Contract API endpoints:
POST /api/v1/contract/deploy- Deploy WASM contractsPOST /api/v1/contract/call- Call contract methodsGET /api/v1/contract/{address}- Get contract infoGET /api/v1/contract/{address}/state- Query contract statePOST /api/v1/contract/estimate-gas- Estimate gas costs
- Added IP-based rate limiting for DDoS protection
- Added CORS whitelist for production security
- Added EON address validation with checksum
- Added
/api/v1/transactions/historywith pagination and filtering - Added
/api/v1/light-node/reactivateendpoint - Added
/api/v1/node/statusfor server node monitoring - Updated activation code format to 25 chars (QNET-XXXXXX-XXXXXX-XXXXXX)
- Added UnifiedPush support for F-Droid compatibility
- Added polling fallback for Light nodes without push support
- Added MEV bundle endpoints
- Added VTS status endpoint
- Added Shred Protocol/Parallel Executor metrics
- Initial API release
- Core blockchain endpoints
- Node activation system
- Reward claiming