Codex · Reference · API
REFERENCE

API Reference

Every interface the Liqua binaries expose, in one place — the miner/chain HTTP+SSE API, the Ethash pool, the EVM JSON-RPC, the validator staking API, and the peer control plane. These are local devnet servers: each section names the binary that serves it and the port it listens on.

Conventions

Services & ports

ServiceBinaryDefault portSection
Miner / chainminer/server.mjs (cli.mjs run):8010 HTTPMiner
Ethash poolpool/server.mjs:8030 HTTP · :3333 StratumPool
EVM JSON-RPCpool/server.mjs:8030/rpcJSON-RPC
Validatorminer/validator.mjs:7100 HTTPValidator
Peer node + dashboardnode/server.mjs · liqctl.mjs:8040 HTTP · port +1000 TCPPeer
Exchange · self-mineorderbook-dex/relayer/server.js:8080 HTTPSelf-mine

Miner / chain API :8010

Served by miner/server.mjs. Drives the SOMA-PoW miner and exposes the chain it produces. The mining CLI is a thin client over POST /api/control.

GET/→ dashboard

The live control dashboard (miner/dashboard.html).

GET/explorer→ block explorer

The block explorer UI (miner/explorer.html).

GET/api/state

A full engine snapshot. The shape:

{
  "chainId": 8888, "symbol": "LIQUA", "genesis": "0x…",
  "height": 142, "headRoot": "0x…",
  "running": true, "paused": false,
  "bits": 18, "autoDiff": true, "targetBlockMs": 2500,
  "hashCap": 0, "hps": 14820, "hashes": 1922334,
  "supply": 284.51, "emissionNow": 1.998,
  "posture": 0.2, "marker": "CALM",
  "validators": 4, "mempool": 0, "uptimeMs": 95120,
  "recent": [{ "height", "root", "ts", "nonce", "tries",
               "reward", "witnesses", "K", "blockMs", "hps" }]
}
GET/api/history?limit=300

Recent blocks (newest first). limit caps at 500.

GET/api/block?h= | ?id=

One block by height (?h=142) or by SOMA root (?id=0x…).

SSE/api/stream

Live stream. event: state fires ~every 600 ms with the gauge snapshot; event: log fires per log line ({ t, level, msg }, level ∈ info·ok·warn·mine·block·ctl·err).

POST/api/control

Drive the miner. Body { "action": "<a>", "value": <v> }; replies { ok:true, state } with the fresh snapshot.

actionvalueeffect
speedfactor (def 1.5)multiply the hash cap (faster)
slowfactor (def 1.5)divide the hash cap (slower)
unthrottleremove the cap (CLI max)
capH/s (0 = off)set an exact hashrate ceiling
bitsintegerset PoW difficulty bits
autoboolenable/disable difficulty auto-retarget
targetms (≥250)target block time for auto-retarget
pause · resumehalt / continue production
addtxtx fieldinject a tx into the mempool

Pool API :8030 stratum :3333

Served by pool/server.mjs — HTTP/SSE for the dashboard, a dual-dialect Stratum TCP listener for miners, and an EVM JSON-RPC for wallets.

GET/api/state

Pool stats + payout ledger + L1 bridge + connect info: { …engine.stats(), ledger, l1, connect }. l1 carries the bridged chain height + on-chain balances; ledger carries off-chain PPLNS balances + history.

GET/api/connect

Everything a miner needs to connect, with the pool's detected LAN IP pre-filled:

{
  "url": "stratum+tcp://192.168.1.20:3333",
  "stratumPort": 3333, "httpPort": 8030,
  "hosts": ["192.168.1.20", …], "bestHost": "192.168.1.20",
  "algo": "ethash", "epoch": 0,
  "shareDiff": 6000000, "networkDiff": 500000000,
  "payoutMode": "pplns", "reward": 2, "symbol": "LIQUA",
  "username": "YOUR_LIQUA_ADDRESS.worker",
  "examples": { "sim": "node pool/sim-miner.mjs …",
                 "lolminer": "lolMiner --algo ETHASH …",
                 "teamred": "teamredminer -a ethash …" }
}
GET/api/history?limit= · /api/block?h= | ?id=

Sealed pool blocks — list, or one by height / id. Same shape family as the miner's.

SSE/api/stream

Live pool stream — emits event: state (full pool state) and event: xstate (explorer view) ~every 1 s.

POST/api/control

Operator controls for the pool engine (difficulty, payout mode, etc.).

TCPstratum :3333

Real Stratum, two dialects (auto-detected). The username a miner authorizes with is its payout address. Methods handled:

  • Simple / NiceHashmining.subscribe · mining.authorize · mining.submit · mining.extranonce.subscribe (the server replies mining.set_difficulty + mining.notify).
  • ethproxyeth_submitLogin · eth_getWork · eth_submitWork · eth_submitHashrate.

Each accepted share is verified for real (@ethereumjs/ethash hashimoto-light); a share clearing the network target seals a block, splits PPLNS, and bridges to L1.

EVM JSON-RPC :8030/rpc

A minimal Ethereum JSON-RPC over the L1 bridge world-state, so a standard wallet (e.g. the L8 wallet) can read Liqua balances. POST /rpc (or POST /), standard { jsonrpc, id, method, params }.

MethodReturns
eth_chainIdchain id (hex) — bridge genesis chain
net_versionchain id (decimal string)
web3_clientVersion"liqua-pool-bridge/0.1"
eth_blockNumbercurrent L1 height (hex)
eth_getBalanceon-chain LIQUA balance of the address (hex wei)
eth_getBlockByNumbera minimal block header for the current height
eth_gasPrice · eth_estimateGas1 gwei · 21000 (static devnet values)
eth_getTransactionCount · eth_getCode · eth_call0x0 / 0x (read-only bridge surface)
eth_syncingfalse
Read-only by design

This RPC exposes the bridge's settled balances for wallets to read. It is not a general execution endpoint — eth_call / eth_getCode return empty. Contract interaction happens through the chain's own tx path, not here.

Validator API :7100

Served by miner/validator.mjs. Consumed by the validator connect page. Read endpoints are GET; staking + attestation are POST.

GET/params

Chain + stake parameters that drive the connect UI:

{
  "chainId": 8888, "symbol": "LIQUA", "decimals": 18,
  "veLock": { "dMaxYears": 4, "boostMax": 0.5, … },
  "emission": {…}, "governance": { "quorum": 0.98 }, "reward": {…},
  "policy": { "minStake", "maxLockYears": 4, "boostMax": 0.5, "maxLockSeconds" },
  "height", "somaRoot", "genesis",
  "stake": { "token", "ve", "faucetAmount": 100000 },
  "set": { "count", "totalStaked", "totalVe", "online" }
}
GET/validators

The full validator set, ranked by ve-weight, with per-validator stake, lock, weight, share, online status, and blocks co-signed.

GET/me?address=&pubkey=

Your validator record, if registered: { found, validator }.

GET/stake/params · /stake/of?address=

Staking config (token/ve/min) · your on-chain lock: { balance, locked, stake, veWeight, unlockAt, expired }.

GET/head · /chain · /status

Current head ({ height, somaRoot, … }) · chain summary · node status (also at /api/state): chainId, height, supply, validators, tally, set, miners[].

POST/stake/faucet

Devnet — grant test LIQUA. Body { address }{ ok, granted }.

POST/stake/build/stake/submit

Two-step signed staking. build with { from, action, amount, duration } (action ∈ approve · createLock · withdraw) returns { ok, tx, hash }; sign the hash and submit { tx, from, sig, v }{ ok, … }.

POST/register

Join the set. Body is a signed LIQUA-VALIDATOR-REGISTER message — either { scheme:"native", address, pubkey, stake, lockSeconds, nonce, sig, rec } or { scheme:"eip191", address, stake, lockSeconds, nonce, sig }{ ok, validator }.

POST/attest

Co-sign the live head. Body { pubkey, head, sig, rec } (sign the head's somaRoot) → { ok, blocksCosigned }. This is the §1e proof-of-participation tick.

Peer control plane node port + 1000

A running full node (node/full.mjs) exposes an admin control plane on its node port + 1000 as line-delimited JSON over TCP. The operator handle is liqctl; it sends { cmd, args } and reads back { ok, result }.

cmdargsresult
status{ name, lnode, height, head:{hash}, stateRoot, evmPeers, peersConnected, peersDiscovered, miner }
headthe current canonical head block
chainchain summary
peersdiscovered / connected / EVM peers
produce{ n }produce N blocks (operator-driven)
stopgraceful shutdown
# the CLI adds 1000 to the node port to reach the control socket
node node/liqctl.mjs --port 30303 status      # → control:31303
node node/liqctl.mjs --port 30303 produce '{"n":1}'

Peer dashboard :8040 HTTP

A browser can't reach the raw-TCP control plane, so node/server.mjs boots a full node in-process and bridges it to HTTP/SSE — this is what the peer dashboard talks to.

GET/api/state

The node snapshot:

{
  "name", "id", "lnode", "miner",
  "chainId": 8888, "genesis": "0x…",
  "height": 6, "head": { "number", "hash" }, "stateRoot": "0x…",
  "peersDiscovered", "peersConnected", "evmPeers",
  "peers": [{ "id", "head" }],
  "controlPort", "httpPort", "port", "uptimeMs",
  "recent": [{ "height", "soma", "txs" }]
}
SSE/api/stream

Live stream — event: state (~every 1.5 s) + event: log per event ({ t, level, msg }, level ∈ discover·peer·reject·drop·tx·block·produce·sync·err·sys). GET /api/log returns the buffered log.

POST/api/control

Body { "action": "produce", "n": 1 } produces N blocks locally and gossips them; { "action": "stop" } shuts the node down. Returns { ok, produced, state }.

Self-mine · exchange :8080

The self-mine → locked liquidity feature runs on the orderbook-DEX. Its relayer (orderbook-dex/relayer/server.js, :8080) serves the deploy config + the /self-mine.html UI; the SelfMineLiquidity contract holds positions and is read on-chain (positionOf · page · previewZap · totalLpLocked). The driver that delivers mined emission is orderbook-dex/scripts/self-mine-relayer.jsnpm run self-mine (--demo · --once · --miner/--amount).

Full walkthrough: Self-Mine into Locked Liquidity.

See also

LIQUA · CODEX · API Reference · part of Liqua Chain · 7SLF STUDIOS