DocsAPI Reference
API Reference

JSON-RPC API

Complete reference for the QuanChain RPC surface. Native qc_* namespaces, eth_* compatibility, and a websocket subscription model.

Intermediate20 min read
Where to call

Endpoints

text
Testnet RPC:   https://rpc-testnet.quanchain.ai
Testnet WS:    wss://ws-testnet.quanchain.ai

Mainnet:       (published at launch)

All POST bodies follow the standard JSON-RPC 2.0 shape:

json
{ "jsonrpc": "2.0", "method": "qc_chainHead", "params": [1], "id": 1 }
Access

Authentication

The public RPC is open and rate-limited per IP. For higher quotas, dedicated endpoints, or write-mempool priority, request an API key from the developer portal and pass it as a header:

bash
curl https://rpc-testnet.quanchain.ai \
  -H "X-QuanChain-Key: qc_live_..." \
  -X POST -d '{ "jsonrpc": "2.0", "method": "qc_chainHead", "params": [1], "id": 1 }'
Namespace

qc_chain · chain state

qc_chainHeadRPC

Head block of the requested channel.

Params
[channel: 1|2|3]
Returns
{ height, hash, ts }
qc_blockByHeightRPC

Full block at the given channel + height.

Params
[channel, height]
Returns
Block
qc_blockByHashRPC

Full block by its hash. Channel inferred.

Params
[hash]
Returns
Block
qc_chainConfigRPC

Network config: chain id, channel finalities, current epoch.

Params
[]
Returns
ChainConfig
Namespace

qc_wallet · wallet introspection

qc_walletInfoRPC

Resolve any wallet address (parent or child) to its current state.

Params
[address]
Returns
{ level, parent, activeChild, ... }
qc_parentTreeRPC

Snapshot of the parent's Merkle tree: root, depth, used indices.

Params
[parentAddr]
Returns
MerkleSnapshot
qc_resolveAddressRPC

Forward-resolve a retired child to the currently active child of its parent.

Params
[oldChild]
Returns
address
Namespace

qc_tx · transactions

qc_sendRawTransactionRPC

Broadcast a pre-signed SpendAndRotate envelope.

Params
[hex]
Returns
txHash
qc_getTransactionRPC

Confirmed transaction including its rotation child.

Params
[hash]
Returns
Tx | null
qc_getReceiptRPC

Receipt with logs, gas used, and new active child.

Params
[hash]
Returns
Receipt | null
qc_recentTransactionsRPC

Recent transactions across all channels (chain caps at 50).

Params
[limit?]
Returns
Tx[]
Namespace

qc_spend · SpendAndRotate helpers

qc_prepareSpendRPC

Build an unsigned SpendAndRotate envelope. Caller signs offline.

Params
[from, to, amount]
Returns
UnsignedEnvelope
qc_estimateFeeRPC

Estimate the channel fee at current congestion.

Params
[channel, payloadSize]
Returns
feeQCH
Composite signing is local
The RPC never sees a private key. Signing happens client-side in the SDK or wallet. RPC methods named qc_prepare* exist solely to assemble envelopes; the caller signs and resubmits via qc_sendRawTransaction.
Namespace

qc_recovery · parent operations

qc_prepareRecoveryRPC

Build a recovery envelope. Requires composite signature from parent.

Params
[parent, reason, newLevel?]
Returns
UnsignedRecovery
qc_recoveryStatusRPC

Pending and historical recoveries for a parent identity.

Params
[parent]
Returns
RecoveryStatus
Live data

Websocket subscriptions

typescript
import { QuanChain } from '@quanchain/sdk';

const ws = new QuanChain.Ws('wss://ws-testnet.quanchain.ai');

ws.subscribe('newBlocks', { channel: 1 }, (block) => {
  console.log('C1 head:', block.height, block.hash);
});

ws.subscribe('walletEvents', { parent: 'QC20_...' }, (ev) => {
  // 'rotate' | 'recovery' | 'inboundTransfer'
});

Subscriptions are filtered server-side. Channel-1 newBlocks fires roughly every 200 ms; walletEvents only fires for the parent address(es) in the filter.

Codes

Error codes

text
-32600  Invalid JSON-RPC request
-32601  Method not found
-32602  Invalid params (validation failure)
-32000  Server error (generic)
-32010  Wallet rotation conflict — child already spent
-32011  Composite signature failed verification
-32012  Merkle proof failed verification
-32013  Channel capacity exceeded — retry on different channel
-32020  Rate-limit hit (HTTP 429 also returned)
Quotas

Rate limits

Public RPC is limited to 100 requests per minute per IP. Authenticated keys lift the limit to 6,000 rpm by default and can be raised further via the developer portal. Websocket connections have no per-message ceiling; subscriptions are capped at 32 per socket.

SDK-friendly examples for every method are in the SDKs reference.

Want help?

Join the developer Discord, open a GitHub issue, or read the whitepaper.