How to Get Chain Statistics from the Amadeus Protocol RPC API

The Amadeus Protocol exposes chain statistics through the GET /api/chain/stats HTTP RPC endpoint, which returns a comprehensive JSON payload containing block height, supply metrics, validator data, epoch information, and network performance indicators.

The Amadeus Protocol node provides a RESTful RPC interface for querying blockchain state. Understanding how to retrieve chain statistics is essential for building monitoring dashboards, explorer applications, and automated tooling that tracks network health. The primary endpoint aggregates data from multiple internal subsystems and caches frequently-changing values for optimal performance.

Chain Statistics Endpoint Overview

The canonical endpoint for chain statistics is /api/chain/stats. When invoked, the HTTP server defined in ex/lib/http/multiserver.ex routes this request to API.Chain.stats/0 lines 92-95.

This function orchestrates data collection from five distinct sources before assembling the final response.

Data Sources and Implementation

Chain Tip and Basic Metrics

The endpoint retrieves the canonical chain tip from DB.Chain and formats it using format_entry_for_client/1 in ex/lib/api/api_chain.ex lines 62-74.

This provides:

  • Current height and rooted height
  • Tip hash (Base58-encoded)
  • Current validator and next validator public keys
  • Segment VR hash

Supply and Circulating Amounts

Supply metrics come from NodeStatsGen.supply/0, defined in ex/lib/node/node_stats_gen.ex lines 12-16. This GenServer maintains a cached snapshot refreshed every 6 hours to avoid expensive recalculation.

Available supply fields:

  • circulating — coins in active circulation
  • total_supply — maximum supply at current height
  • total_locked — coins locked in contracts or staking
  • supply_computed_at_height — block height of last calculation
  • total_supply_y3 and total_supply_y30 — projected supplies at year 3 and year 30

Validator Set and SOL Counters

Active validator data is served by NodeStatsGen.validators/0 lines 22-27. This reads from an ETS table refreshed every second, providing near-real-time stake weights, SOL counts, and commission rates.

Epoch-Specific Performance Data

Current epoch metrics are assembled in ex/lib/api/api_chain.ex lines 78-90:

Metric Source Function
emission_for_epoch RDB.protocol_epoch_emission/1
diff_bits API.Epoch.get_diff_bits/0
pflops Calculated protocol floating-point operations
txs_per_sec Derived from recent block timing

Burned Fees

Total AMA burned (proxy for fees paid) comes from API.Contract.total_burned/0 lines 86-87, implemented in ex/lib/api/api_contract.ex.

Response Format

All values are encoded in human-readable formats: Base58 for hashes, floating-point decimals for coin amounts. The JSON structure follows this schema:

{
  "error": "ok",
  "stats": {
    "height": 123456,
    "rooted_height": 123450,
    "tip_hash": "3vZK...",
    "tip": {},
    "tx_pool_size": 12,
    "cur_validator": "5KQ9...",
    "next_validator": "9fA...",
    "emission_for_epoch": 2500000,
    "circulating": 12345678,
    "total_supply": 200000000,
    "total_locked": 3000000,
    "validators": {},
    "supply_computed_at_height": 123400,
    "total_supply_y3": 804065972,
    "total_supply_y30": 1000000000,
    "burned": 12345.67,
    "diff_bits": 24,
    "pflops": 1.23e+03,
    "txs_per_sec": 5.6,
    "segment_vr_hash": "7bL..."
  }
}

Code Examples for Querying Chain Statistics

cURL (Command Line)

The fastest way to test the endpoint:

curl -s https://nodes.amadeus.bot/api/chain/stats | jq .

JavaScript / Fetch

For browser or Node.js applications:

const getChainStats = async () => {
  const response = await fetch('https://nodes.amadeus.bot/api/chain/stats');
  const data = await response.json();
  
  if (data.error === 'ok') {
    const { height, total_supply, txs_per_sec } = data.stats;
    console.log(`Block ${height}: ${total_supply} total supply, ${txs_per_sec} TX/s`);
    return data.stats;
  }
  throw new Error(`RPC error: ${data.error}`);
};

Python / requests

import requests

def fetch_chain_stats():
    url = "https://nodes.amadeus.bot/api/chain/stats"
    response = requests.get(url, timeout=10)
    response.raise_for_status()
    
    data = response.json()
    if data.get("error") != "ok":
        raise RuntimeError(f"Node returned error: {data['error']}")
    
    return data["stats"]

# Usage

stats = fetch_chain_stats()
print(f"Height: {stats['height']}, Validators: {len(stats['validators'])}")

Elixir (Internal Module Call)

For node operators building internal tooling, call the implementation directly:


# Direct module invocation bypasses HTTP overhead

stats = API.Chain.stats()
IO.inspect(stats, pretty: true)

# Access specific fields

%{height: height, circulating: circ} = stats

Key Implementation Files

Understanding the source structure helps when debugging or extending functionality:

Performance and Caching Characteristics

The endpoint balances freshness with efficiency through tiered caching:

  1. Supply data — 6-hour refresh cycle (expensive recalculation)
  2. Validator sets — 1-second ETS cache (frequent but lightweight)
  3. Tip data — Real-time database read (authoritative source)
  4. Epoch metrics — Computed on request using cached epoch state

This design ensures sub-100ms response times under normal load while maintaining data consistency for critical consensus values.

Summary

  • The Amadeus Protocol RPC exposes chain statistics via GET /api/chain/stats
  • Data aggregates from API.Chain.stats/0 with contributions from NodeStatsGen for cached values
  • Response includes height, supply metrics, validator sets, epoch performance, and burned fees
  • Supply snapshots refresh every 6 hours; validator data updates every second
  • Implementation spans ex/lib/api/api_chain.ex, ex/lib/node/node_stats_gen.ex, and ex/lib/http/multiserver.ex

Frequently Asked Questions

What is the rate limit for the chain statistics endpoint?

The Amadeus Protocol node does not implement explicit rate limiting on /api/chain/stats, but validator data refreshes every second and supply data every six hours. Caching responses client-side for 5-10 seconds is recommended to avoid unnecessary load.

Why does circulating supply differ from total supply minus locked?

Circulating supply excludes protocol-reserved emissions, timelocked allocations, and coins in unclaimed staking rewards that have not yet entered active circulation. The total_locked field represents only contract-locked amounts, not the full non-circulating balance.

Can I run this query against a local node?

Yes. Replace https://nodes.amadeus.bot with your local node's HTTP endpoint (typically http://localhost:8080 or as configured in multiserver.ex). Local queries bypass network latency and return identical data structures.

How accurate is the txs_per_sec metric?

The value represents a rolling average over recent blocks, typically 60 seconds of chain history. It reflects successfully processed transactions, not submitted or pending mempool entries. For mempool size, reference tx_pool_size in the same response.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →