Protocol resources

Developer Docs

Everything needed to read Aletheia StableChain and to send transactions to it: the public RPC, its REST and JSON-RPC interfaces, how identifiers and amounts are written, and the command-line client. Every example on this page is a real response from a running node.

RESThttps://rpc.stateofaletheia.org/api/v1
JSON-RPChttps://rpc.stateofaletheia.org/rpc/v1
Explorerhttps://aletheiascan.mainnet.stateofaletheia.org

01 Overview

The RPC is the public read interface of the national ledger. It serves finalized data only: every block, transaction and balance it returns is final and will never change. Nothing speculative or pending is ever served, so a result you have read can be relied on and cached.

Read

Blocks, transactions, receipts, accounts, balances, assets, supply and the validator set.

Simulate

Run a signed transaction against the finalized state to see its result and fee before sending it.

Submit

Hand a signed transaction to the network and track it until its block is final, about a second later.

Networks

NetworkPurposeRPCAddress prefix
Mainnet BetaThe national ledger · chain 7770https://rpc.stateofaletheia.orgalt: · checksum al
Private validationMulti-operator rehearsal before mainnetOperators onlychecksum alt
DevnetDevelopment and testinghttp://127.0.0.1:7781checksum ald

An address carries its network inside its checksum, so an address from one network is refused by another. Mainnet Beta runs as chain ID 7770.

02 Quick start

Ask the node where the chain is. The same question works through either interface and gets the same answer.

REST shell
curl https://rpc.stateofaletheia.org/api/v1/network/status
JSON-RPC shell
curl https://rpc.stateofaletheia.org/rpc/v1 \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"getNetworkStatus","params":{}}'
Response · devnet json
{
  "chainId": 7771,
  "finalizedBlock": "alt:Bd8C4db63e9c30f8C00e998d10D118e82aF081C3A4bE5d549310BB7dbE71ae352",
  "finalizedHeight": 120,
  "network": "devnet",
  "peers": null,
  "protocolVersion": 1,
  "syncing": false
}

finalizedHeight is the latest final block; finalizedBlock is its identifier. A new block is produced every 500 ms and becomes final two slots later.

03 Identifiers & amounts

Aletheia writes every identifier in one human-checkable form: a prefix that says what it is, and a hex body whose capital letters are a checksum, the EIP-55 rule Ethereum addresses use, with the network folded in. It catches typing errors and an identifier from another network. Addresses are 20 bytes, so they look like Ethereum addresses after alt:; copy them exactly, capitals included. Aletheia never uses the 0x prefix; the RPC refuses any value that carries it.

WhatFormExample
Account addressalt:…alt:878f580434a9DbF3365b357Aad37F3831719e489
Transactionalt:T…alt:TA1fA8Fc4c07ae7263260407b0004983ad84f12bcB1DA279007aBb3032BcB9ab1
Blockalt:B…alt:B0C953f623C3b9930Bb075d45f978dE04Be2026A3734036108314c210CB2C6562
Hashes and roots64 lowercase hex characters627df554bc4d8c1b83ac2ab8c9e0ca6f211d9f45cbdee23f590ff9956141215f

Amounts are exact

Every amount travels as a decimal string of base units, never as a JSON number: a 64-bit float cannot hold an 18-decimal value and would round it silently. Parse amounts as big integers. Where the node knows an asset's decimals it adds a display field for people; programs should use amount or available.

AEY Aletheian Guilder 18 decimals · 1 AEY = 1018 base units Legal tender; 1 AEY = 1 EUR
ALnT Aletheia Talent 3 decimals · 1 ALnT = 1,000 base units Utility and staking asset; pays fees
GET /accounts/{alt:…}/balances · devnet json
[
  {
    "address": "alt:878f580434a9DbF3365b357Aad37F3831719e489",
    "asset": "AEY",
    "available": "998767690000000000000000",
    "display": "998767.690000000000000000",
    "height": 120,
    "locked": "0"
  },
  {
    "address": "alt:878f580434a9DbF3365b357Aad37F3831719e489",
    "asset": "ALnT",
    "available": "49999984000",
    "display": "49999984.000",
    "height": 120,
    "locked": "0"
  }
]
A 0x-prefixed value is refused json
{
  "error": {
    "code": -32602,
    "data": {
      "detail": "0x-prefixed values are not accepted: use unprefixed lowercase base16 or alt: forms"
    },
    "message": "Invalid params"
  },
  "id": 2,
  "jsonrpc": "2.0"
}

04 REST reference

All paths are below https://rpc.stateofaletheia.org/api/v1. Identifiers go in the path as written. Every REST route has a JSON-RPC method that returns identical data. Select a route to see a real response.

Response · devnet json
{
  "chainId": 7771,
  "finalizedBlock": "alt:Bd8C4db63e9c30f8C00e998d10D118e82aF081C3A4bE5d549310BB7dbE71ae352",
  "finalizedHeight": 120,
  "network": "devnet",
  "peers": null,
  "protocolVersion": 1,
  "syncing": false
}

05 JSON-RPC 2.0

Send POST requests to https://rpc.stateofaletheia.org/rpc/v1 with a JSON-RPC 2.0 envelope. Parameters are always named (an object, never a list), and unknown parameters are refused so a typing mistake cannot pass silently. The method names are listed beside each route above.

Request shell
curl https://rpc.stateofaletheia.org/rpc/v1 \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":7,"method":"getTransaction","params":{"txId":"alt:TA1fA8Fc4c07ae7263260407b0004983ad84f12bcB1DA279007aBb3032BcB9ab1"}}'
Response envelope · devnet json
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "chainId": 7771,
    "finalizedBlock": "alt:Bd8C4db63e9c30f8C00e998d10D118e82aF081C3A4bE5d549310BB7dbE71ae352",
    "finalizedHeight": 120,
    "network": "devnet",
    "peers": null,
    "protocolVersion": 1,
    "syncing": false
  }
}

06 Sending transactions

A transaction is signed by its sender with Ed25519 over a digest that names the chain and network, so a signature made for one network can never be replayed on another. Wallets and the CLI do this for you; the RPC never sees a private key.

  1. 1
    Read the nonce. Each account's transactions are numbered; use /accounts/{alt:…}/nonce.
  2. 2
    Build and sign. Set the fee terms (fee asset, execution-unit limit, maximum fee) and a validity window in slots.
  3. 3
    Simulate. See the result and the exact fee before anything is sent.
  4. 4
    Submit. The answer carries the alt:T… identifier.
  5. 5
    Track. The transaction is served once its block is final, about a second later.
The three calls shell
# 1. Simulate: what the chain would do, and what it would charge
curl -X POST https://rpc.stateofaletheia.org/api/v1/transactions/simulate \
  -H 'content-type: application/json' -d '{"tx":"<signed transaction, base16>"}'

# 2. Submit: admitted to the mempool; the answer carries the alt:T… identifier
curl -X POST https://rpc.stateofaletheia.org/api/v1/transactions \
  -H 'content-type: application/json' -d '{"tx":"<signed transaction, base16>"}'

# 3. Track: 404 until the block holding it is final, then the transaction
curl https://rpc.stateofaletheia.org/api/v1/transactions/alt:T…

Fees

A fee is the execution units a transaction uses multiplied by the published price per unit, in AEY or ALnT. Prices are set by governance and never auctioned, so a busy period never raises them. A simple transfer uses 2,000 units. A transaction that fails still pays for the units it used; nothing else moves.

GET /transactions/{alt:T…} · devnet json
{
  "block": {
    "height": 119,
    "id": "alt:B0C953f623C3b9930Bb075d45f978dE04Be2026A3734036108314c210CB2C6562",
    "index": 0,
    "slot": 119
  },
  "expirySlot": 718,
  "fee": {
    "asset": "ALnT",
    "euLimit": 50000,
    "maxFee": "50000"
  },
  "nonce": 7,
  "receipt": {
    "errorCode": 0,
    "errorName": "",
    "euUsed": 2000,
    "events": 1,
    "feeCharged": "2000",
    "status": "SUCCESS"
  },
  "sender": "alt:878f580434a9DbF3365b357Aad37F3831719e489",
  "status": "FINALIZED",
  "transfer": {
    "amount": "96540000000000000000",
    "asset": "AEY",
    "display": "96.540000000000000000",
    "recipient": "alt:836558540be6169555878CE4CAbCAa9AE4D4cB4C"
  },
  "txId": "alt:TA1fA8Fc4c07ae7263260407b0004983ad84f12bcB1DA279007aBb3032BcB9ab1",
  "txType": 1,
  "type": "Transfer",
  "validFromSlot": 118
}

07 Errors

REST answers with an HTTP status and { error: { code, name, message, details } }. JSON-RPC answers with a standard error object whose data names the protocol error, for example TX_NONCE_TOO_LOW.

JSON-RPCHTTPNameMeaning
-32700400PARSE_ERRORThe body is not valid JSON.
-32600400INVALID_REQUESTNot a JSON-RPC 2.0 request, or an HTTP method the route does not use.
-32601400METHOD_NOT_FOUNDNo method by that name.
-32602400INVALID_PARAMSA parameter is missing, unknown or malformed, including any 0x-prefixed value.
-32001429RATE_LIMITEDToo many requests from this address; slow down and retry.
-32002404NOT_FOUNDNo finalized block, transaction, receipt or record matches.
-32010400TX_REJECTEDThe transaction was refused at admission; data names the protocol error.
-32011400SIMULATION_FAILEDThe transaction would fail on chain; data names the protocol error.
-32603500INTERNALThe node could not answer; nothing was changed.
GET /blocks/height/99999999 · 404 json
{
  "error": {
    "code": -32002,
    "details": {
      "detail": "no finalized block there"
    },
    "message": "Not found",
    "name": "NOT_FOUND"
  }
}

08 Limits & behaviour

Rate limitRequests are budgeted per client address (50 per second by default). Past it the node answers 429 / -32001; wait and retry.
Request sizeBodies are limited to 1 MiB.
FinalityOnly final data is served. A submitted transaction returns 404 until its block is final, then never changes.
CachingFinalized blocks, transactions and receipts never change and can be cached indefinitely. Balances and the head change with every block.
Read-only accessThe RPC is the State's constitutionally authorised read interface. It never holds keys and cannot move funds.

09 Wallet & CLI

aletheia-cli is the State's command-line client for people and scripts. It keeps keys in an encrypted keystore (Argon2id and XChaCha20-Poly1305), asks for the password without echo, and checks that the node is on the network you expect before it signs anything. Every transfer is simulated and summarised before it is signed.

Commands shell
aletheia-cli --rpc 127.0.0.1:7781 status
aletheia-cli keys new  --keystore wallet.json
aletheia-cli keys show --keystore wallet.json
aletheia-cli balance alt:878f580434a9DbF3365b357Aad37F3831719e489 --asset AEY
aletheia-cli transfer --keystore wallet.json --to alt:… --amount 25.50 --asset AEY
aletheia-cli tx show alt:TA1fA8Fc4c07ae7263260407b0004983ad84f12bcB1DA279007aBb3032BcB9ab1
aletheia-cli block show 1200
aletheia-cli --output json --network mainnet status
aletheia-cli status · devnet text
Network          devnet (chain 7771)
Protocol         1
Finalized        #120   alt:B0C953f623C3b9930Bb075d45f978dE04Be2026A3734036108314c210CB2C6562

--output json gives a stable schema for scripts; --network mainnet refuses to talk to a node on any other network. For automation, ALETHEIA_PASSWORD_FILE names a file holding the keystore password.