RustChain Read-Only API Contract
September 5, 2026 ยท View on GitHub
Canonical compatibility contract for the stable public RustChain health, epoch, active-miner, and wallet-balance reads. It reflects the production Flask handlers and intentionally excludes unregistered or write-capable routes.
The canonical machine-readable source is compatibility_lab/read_only_api.openapi.json. This reference is checked in for review and must be regenerated whenever the contract changes.
Safety Boundary
The compatibility surface is public and read-only. The lab sends only GET, never sends a request body or credentials, keeps TLS verification enabled, and is never pointed at a live node by CI.
Endpoints
| Method | Path | Operation | Implementation |
|---|---|---|---|
GET | /health | Read node health | api_health |
GET | /epoch | Read current epoch state | get_epoch |
GET | /api/miners | List recently attested miners | api_miners |
GET | /wallet/balance | Read a miner wallet balance | api_wallet_balance |
GET /health
Returns process uptime, database availability, backup age, and tip freshness. An unhealthy node returns the same body schema with HTTP 503.
Query parameters: none.
Responses
| Status | Schema | Meaning |
|---|---|---|
200 | HealthResponse | The node reports healthy. |
503 | HealthResponse | The database or backup freshness check reports unhealthy. |
Offline fixtures:
GET /epoch
Returns the current absolute slot and epoch plus the configured reward pot, epoch size, enrollment count, and fixed RTC supply.
Query parameters: none.
Responses
| Status | Schema | Meaning |
|---|---|---|
200 | EpochResponse | Current epoch state. |
Offline fixtures:
GET /api/miners
Returns miners whose latest accepted attestation is less than one hour old, with bounded pagination and current-epoch enrollment metadata.
Query Parameters
| Name | Required | Type | Constraints | Description |
|---|---|---|---|---|
limit | no | integer | >= 1; <= 1000; default 100 | Maximum miners returned. |
offset | no | integer | >= 0; default 0 | Zero-based result offset. |
Responses
| Status | Schema | Meaning |
|---|---|---|
200 | MinersResponse | A page of active miners and pagination metadata. |
400 | ValidationErrorResponse | A pagination parameter is malformed or outside its accepted range. |
429 | RateLimitResponse | The per-client miner-list rate limit has been reached. |
Offline fixtures:
GET /wallet/balance
Returns a valid miner identifier and its balance in integer micro-RTC and decimal RTC. A valid unknown identifier returns a zero balance.
Query Parameters
| Name | Required | Type | Constraints | Description |
|---|---|---|---|---|
miner_id | yes | string | min length 1; max length 80; pattern ^[A-Za-z0-9._:-]+$ | Canonical miner or wallet identifier. The endpoint also implements address as a legacy alias, but this contract standardizes miner_id. |
Responses
| Status | Schema | Meaning |
|---|---|---|
200 | WalletBalanceResponse | The wallet balance, including zero for a valid unknown identifier. |
400 | ValidationErrorResponse | The miner identifier is missing, malformed, or conflicts with the legacy address alias. |
Offline fixtures:
Schemas
HealthResponse
Health body returned for both healthy and unhealthy status codes.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
ok | boolean | yes | - | Combined database and backup-freshness result. |
version | string | yes | min length 1 | Running node application version. |
uptime_s | integer | yes | >= 0 | Whole seconds since this process started. |
db_rw | boolean | yes | - | Whether the node database quick check completed. |
backup_age_hours | number or null | yes | >= 0 | Age of the newest known backup, or null when no backup timestamp is available. |
tip_age_slots | integer or null | yes | >= 0 | Tip freshness indicator, or null when no header can be read. The current implementation reports zero when a header exists. |
EpochResponse
Current epoch and immutable/configured emission values.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
epoch | integer | yes | - | Current epoch number derived from the absolute slot. |
slot | integer | yes | - | Absolute slot number derived from genesis time. |
epoch_pot | number | yes | >= 0 | RTC distributed across an epoch. |
enrolled_miners | integer | yes | >= 0 | Rows enrolled for the current epoch. |
blocks_per_epoch | integer | yes | >= 1 | Configured slots per epoch. |
total_supply_rtc | number | yes | >= 0 | Fixed total RTC supply configured by the node. |
MinerInfo
One miner with an accepted attestation in the active one-hour window.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
miner | string | yes | min length 1 | Miner wallet identifier. |
last_attest | integer | yes | >= 0 | Unix timestamp of the latest accepted attestation. |
first_attest | integer or null | yes | >= 0 | Unix timestamp of the first retained attestation, or null when absent. |
device_family | string or null | yes | - | Attested device family as stored by the node. |
device_arch | string or null | yes | - | Attested device architecture as stored by the node. |
hardware_type | string | yes | min length 1 | Display classification derived by the node. |
entropy_score | number | yes | - | Stored hardware entropy score, defaulting to zero when falsey. |
antiquity_multiplier | number | yes | >= 0 | Reward multiplier selected from the hardware weight table. |
MinersPagination
Pagination and enrollment metadata for an active-miner page.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
total | integer | yes | >= 0 | Total miners in the active one-hour window. |
total_enrolled | integer | yes | >= 0 | Miner enrollments in the current epoch. |
limit | integer | yes | >= 1; <= 1000 | Applied page size. |
offset | integer | yes | >= 0 | Applied zero-based offset. |
count | integer | yes | >= 0; <= 1000 | Number of miners in this response page. |
MinersResponse
Paginated active-miner response envelope.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
miners | MinerInfo[] | yes | - | Miners ordered by latest attestation descending. |
pagination | MinersPagination | yes | - | Page and epoch-enrollment metadata. |
WalletBalanceResponse
Balance for a canonical miner identifier. Success intentionally has no ok field.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
miner_id | string | yes | min length 1; max length 80; pattern ^[A-Za-z0-9._:-]+$ | The validated identifier supplied by the caller. |
amount_i64 | integer | yes | - | Balance in integer micro-RTC. |
amount_rtc | number | yes | - | Balance expressed in RTC. |
ValidationErrorResponse
Public input-validation error used by miner pagination and wallet lookup.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
ok | boolean | yes | constant false | Always false for this error body. |
error | string | yes | min length 1 | Stable human-readable validation reason. |
RateLimitResponse
Rate-limit body returned by the active-miner endpoint.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
ok | boolean | yes | constant false | Always false for this error body. |
error | string | yes | constant "rate_limited" | Stable rate-limit error code. |
limit | string | yes | pattern ^[0-9]+/[0-9]+s$ | Configured request count and window, such as 30/60s. |
Verification
From the repository root:
python3 -m compatibility_lab validate
python3 -m compatibility_lab generate-docs --check
python3 -m compatibility_lab check-links
A live compatibility probe is explicit and optional:
python3 -m compatibility_lab probe https://node.example --miner-id compatibility-probe