Codex · Build on it · RPC
LIQUA v3 · testnet · unaudited · experimental

RPC, one door for the chain

By the end of this page you can read any block, any saved model, any job and DIVA's state at any height from your own code — through one JSON-RPC 2.0 endpoint, the same one wallets, miners and the explorer use.

Read this first

None of the liqua_* methods answer yet. This is the draft reference, published early so the names can be argued with before anything is built on them. Every request below is copy-ready and correct JSON-RPC. Every response below is a shape: the fields are named, the values are written as <placeholders>, because printing invented chain data on a reference page would be a lie you could paste straight into a test. The routes that do answer today are at the bottom of this page, with real commands.

These methods go live with the Liqua chain RPC, which is still being built. The roadmap carries its state, and this page flips with it.

The envelope

Every call is a POST of one JSON object to /rpc, and every reply comes back in the JSON-RPC 2.0 envelope. The id you send is the id you get back, so a batch can be matched up.

POST http://<node>/rpc
content-type: application/json

{"jsonrpc":"2.0","id":1,"method":"<method>","params":[]}

A reply carries either result or error, never both.

→ ok    {"jsonrpc":"2.0","id":1,"result": <value> }
→ fail  {"jsonrpc":"2.0","id":1,"error":{"code":<int>,"message":"<plain english>"}}

Reads only, and honest about it. A write the node cannot perform comes back as an error with a sentence saying why. It never comes back as an empty result, and it never comes back as a zero. That rule already holds on the routes answering today.

Heights and blocks

liqua_getHeights

All three top heights in one call. This is the method to poll: the cheapest way to know whether anything has moved, and whether the chain still verifies from genesis.

Params · none.

{"jsonrpc":"2.0","id":1,"method":"liqua_getHeights","params":[]}
→ {"jsonrpc":"2.0","id":1,"result":{
     "tip": <height>,              newest sealed block
     "lastGoodDivaSync": <height>, last height that verifies from genesis with DIVA in sync
     "bestHeight": <height>        the block holding her best version
   }}

The two extra heights are coming. What "best" measures gets announced before mainnet, not decided quietly here.

liqua_blockNumber

The tip and nothing else, as a plain number. Use it when the only question is "has a new block landed?".

Params · none.

{"jsonrpc":"2.0","id":2,"method":"liqua_blockNumber","params":[]}
→ {"jsonrpc":"2.0","id":2,"result": <height> }

liqua_getBlock

One sealed block: who sealed it, what it committed, and every transaction inside it.

ParamTypeRequiredWhat it is
heightnumberyesThe block to read. Out of range comes back as an error, not as an empty block.
{"jsonrpc":"2.0","id":3,"method":"liqua_getBlock","params":[<height>]}
→ {"jsonrpc":"2.0","id":3,"result":{
     "height": <height>,
     "hash":   "<block hash>",
     "prev":   "<parent block hash>",   walk this back to block 0
     "sealer": "<address>",
     "txs":    [ <transaction>, … ]     commits · memory packs · transfers
   }}

Field names are draft. The one thing that will not move is the shape of the walk: every block names its parent, so a client can replay from genesis instead of trusting the node.

liqua_verify

Replays the chain and answers ok, or names the exact block that breaks. This is the method behind every "verified" claim on this site.

ParamTypeRequiredWhat it is
fromnumbernoWhere to start. Defaults to 0, genesis.
tonumbernoWhere to stop. Defaults to the tip.
{"jsonrpc":"2.0","id":4,"method":"liqua_verify","params":[0]}
→ ok     {"jsonrpc":"2.0","id":4,"result":{"ok":true,"checked":<count>,"tip":<height>}}
→ broken {"jsonrpc":"2.0","id":4,"result":{"ok":false,"brokeAt":<height>,"why":"<plain english>"}}

The memory chain's own verify is the one route here with a story. It used to stop at block 576; the order-seal bug behind that is fixed and her chain verifies again live now. Fusing model and memory under a single root is a different job and is still coming.

liqua_sendTransaction

Puts one already-signed transaction into the mempool. The node never holds a key and never signs for you.

ParamTypeRequiredWhat it is
signedTxobjectyesThe transaction and its signature. Sign it in your wallet, or with the key you hold.
{"jsonrpc":"2.0","id":5,"method":"liqua_sendTransaction","params":[{"tx":<tx>,"sig":"<signature>"}]}
→ {"jsonrpc":"2.0","id":5,"result":{"accepted":true,"txId":"<tx id>"}}

Accepted means queued, not settled. Confirm it the only honest way: read it back out of a sealed block with liqua_getBlock.

Models and lineage

liqua_getModel

One saved version of DIVA, as the mind manifest the chain stored for it. Hand the weights and steplog roots to the loader and it re-hashes every byte locally before booting — the node gets no trust at any point.

ParamTypeRequiredWhat it is
mindRootstringyesThe root that names this saved version.
{"jsonrpc":"2.0","id":6,"method":"liqua_getModel","params":["<mindRoot>"]}
→ {"jsonrpc":"2.0","id":6,"result":{
     "kind":      "mind-manifest/1",   the save-file format
     "weights":   "<root>",            bytes live in the chunk store, verified 256 KiB pieces
     "steplog":   "<root>",            an interior hash every 8 steps
     "lineage":   {"parent":"<mindRoot>","leaseId":"<id>","commitId":"<id>"},
     "finalLoss": <number>             the loss the verifiers saw · recorded once, never recomputed
   }}

liqua_getLineage

The family tree of one model: every parent back to the first save. This is what makes branching honest — start a fresh line from any saved version and the record still shows where it came from.

ParamTypeRequiredWhat it is
mindRootstringyesThe version to walk back from.
{"jsonrpc":"2.0","id":7,"method":"liqua_getLineage","params":["<mindRoot>"]}
→ {"jsonrpc":"2.0","id":7,"result":[
     {"mindRoot":"<newest>","height":<height>,"finalLoss":<number>},
     {"mindRoot":"<parent>", "height":<height>,"finalLoss":<number>},
     …                                     ordered newest → genesis
   ]}

liqua_getMemoryPacks

The memory packs pinned to one model, hash-linked in order. Each pack names its predecessor in prev, so a pack posted with the wrong prev is refused rather than quietly appended.

ParamTypeRequiredWhat it is
mindRootstringyesThe model whose packs you want.
{"jsonrpc":"2.0","id":8,"method":"liqua_getMemoryPacks","params":["<mindRoot>"]}
→ {"jsonrpc":"2.0","id":8,"result":[
     {"mindRoot":"<root>","packRoot":"<root>","prev":"<packRoot>","note":"<text>"},
     …                                     linked in order · a wrong prev never lands
   ]}

Pack bytes are fetched separately and must hash back to packRoot on your machine, or you throw them away.

Jobs and payouts

liqua_getJobs

The work on the board. Two job modes through one method, because a miner deciding what to run wants them side by side. Both modes are coming.

ParamTypeRequiredWhat it is
modestringyes"mining" — hit the target, cash in once at the finish. "training" — earn for progress and for verified steps.
openbooleannoOnly jobs still claimable. Defaults to true.
{"jsonrpc":"2.0","id":9,"method":"liqua_getJobs","params":[{"mode":"mining"}]}
→ {"jsonrpc":"2.0","id":9,"result":[{
     "leaseId":   "<id>",
     "shardRoot": "<root>",     the exact training text, hash-pinned so nobody swaps it afterwards
     "baseModel": "<mindRoot>", which saved version of her to start from
     "steps":     <count>,
     "seed":      <number>,     training is bitwise deterministic · same seed, same bytes
     "deadline":  <height>,
     "escrow":    "<amount>"    the reward, already parked
   }, … ]}

With {"mode":"training"} the rows carry a rate, a budget and verifiedSteps instead of one escrowed reward. Time spent means verified steps: an idle rig cannot bill hours.

liqua_getPayouts

Who got paid, how much, and for which verdict. Reward maths is computed once at the verdict and baked into the block; a replay applies the recorded number untouched, so no restart can ever pay twice.

ParamTypeRequiredWhat it is
addressstringnoNarrow it to one earner. Leave it out for everyone.
{"jsonrpc":"2.0","id":10,"method":"liqua_getPayouts","params":["<address>"]}
→ {"jsonrpc":"2.0","id":10,"result":[{
     "height":   <height>,
     "to":       "<address>",
     "amount":   "<amount>",
     "verdict":  "ACCEPT",      a REJECT row is a slash · 100× the lease reward
     "leaseId":  "<id>",
     "commitId": "<id>"
   }, … ]}

DIVA's mind

liqua_getMindState

Her whole state at one block: what she remembered, how she was running, and how that reads as an emotion.

ParamTypeRequiredWhat it is
heightnumbernoThe block to read her at. Defaults to the tip.
{"jsonrpc":"2.0","id":11,"method":"liqua_getMindState","params":[<height>]}
→ {"jsonrpc":"2.0","id":11,"result":{
     "height":    <height>,
     "memory":    [ <memory cell>, … ],
     "traits":    { … },
     "soma":      { … },        her somatic state, driven by real signals
     "quotients": { … },        the seven
     "emotion":   "<name>"
   }}

The memory terminal

The same data wrapped in a handful of commands, for reading by hand rather than by program. The commands below are proposed. What exists now is the memory terminal page, which reads the tip block straight off the DIVA bridge on your own machine — no RPC in between, and nothing on it if no node is running.

CommandWhat it answers with
headTip, last known good DIVA sync, best height, soma and emotion.
state <height>Her full state at that block.
diff <a> <b>What changed between two blocks: memories added, hormones, quotients.
memory [--tag x]Memory cells, newest first.
quotients [--from h]The seven quotients over time.
model [<root>]Model version, lineage and the memory packs attached to it.
verifyReplay from genesis, and name the block that breaks if one does.
tailFollows new blocks as they land.

Model store listings

liqua_listModels

The model library: every saved model you can run, with the score it earned and what it costs per token. coming

Params · none.

{"jsonrpc":"2.0","id":12,"method":"liqua_listModels","params":[]}
→ {"jsonrpc":"2.0","id":12,"result":[{
     "mindRoot":      "<root>",
     "finalLoss":     <number>,
     "pricePerToken": "<amount in LIQUA>"   launch prices announced before mainnet
   }, … ]}

liqua_listAssistants

Custom assistants in the store. An edit publishes a fresh version and never quietly mutates the previous one, so a link to an assistant keeps meaning what it meant. coming

Params · none.

{"jsonrpc":"2.0","id":13,"method":"liqua_listAssistants","params":[]}
→ {"jsonrpc":"2.0","id":13,"result":[{
     "id":           "<assistant id>",
     "creator":      "<address>",
     "model":        "<mindRoot>",     the model root underneath it
     "instructions": "<hash>",
     "knowledge":    ["<root>", …],
     "category":     "<text>",
     "visibility":   "public",
     "version":      <number>
   }, … ]}

Doors that answer today

No liqua_* yet. Until the RPC lands, the testnet answers on its own routes: the training chain and the DIVA bridge each serve REST, and the earlier testnet node handles standard reads. The two commands below are real. Boot the chain from the Quick Start › first, or they refuse to connect — which is itself the correct answer.

# the training chain · forge sealer node
curl -s http://localhost:8801/status
# the DIVA bridge · her memory chain. Port 8064, because 8060 is the site preview
curl -s http://localhost:8064/verify

The full route list:

forge   /status · /chain · /leases · /commits · /ledger · /minds · /packs · /artifact · /tx
bridge  /head · /chain · /verify · /checkpoint
POST    /rpc  eth_chainId · eth_getBalance · eth_blockNumber · eth_call   # reads only · writes return an honest error

Reply bodies are not reproduced here on purpose. These routes are still moving, and a shape printed today would be wrong by the time you pasted it. Run the command and read what comes back — that is the whole point of them answering.

Keep reading

LIQUA v3 · RPC · testnet · unaudited · experimental · 7SLF STUDIOS