Skip to content

Operator CLI

lattice is the declarative front door for one host. It reads one lattice.json, owns no resident state, and reconciles one lattice-node process that hosts the configured Nexus-rooted tree.

Every command accepts --root <directory>. The current directory is the default.

{
"listen": 4001,
"rpc": 8080,
"webSocket": 4002,
"peers": ["<public-key>@node.example:4001"],
"externalAddress": "192.0.2.10",
"publicRead": 8081,
"publicReadRate": 25,
"publicReadExpensiveRate": 1,
"publicReadMaxRate": 200,
"publicReadURL": "https://reads.example.org",
"publicSubmit": false,
"hostedChains": [
"Nexus/Alpha",
"Nexus/Alpha/Beta"
],
"mine": {
"worker": "cpu",
"workers": 2,
"batchSize": 2000000,
"recipients": {
"Nexus": "<address>",
"Nexus/Alpha": "<address>",
"Nexus/Alpha/Beta": "<address>"
},
"minBlockIntervalSeconds": 10
}
}

This is intentionally one schema:

  • listen, rpc, public-read policy, and identity apply once to the process;
  • peers is a list per chain, keyed by absolute path; an array is Nexus’s list (see “Configured peers” in operations.md);
  • hostedChains lists child paths parent before child;
  • mining maps are keyed by hosted absolute path;
  • ports must be nonzero and unique, except that webSocket may be 0, which turns the browser listener off (see “Network surfaces” in operations.md);
  • rates must be finite and nonnegative;
  • blockBodies, when set, is all or none and is passed as --block-bodies (see “What a node keeps” in operations.md);
  • state, when set, is all, tip or none and is passed as --state (same section);
  • finalityWindow, when set, is a number of blocks and is passed as --finality-window N for every hosted chain; absent or 0 is off (see Node-local finality);
  • finalityWindows, when set, maps a chain path to blocks ({"Nexus/Alpha": 500}) over that default and is passed as --finality-window path=N; 0 turns it off for that chain;
  • announceLifetime, when set, is 1 to 86400 and is passed as --announce-lifetime (see “Discovery and peer health” in operations.md);
  • publicReadURL, when set, is an absolute https:// (or http://) URL with a host and no credentials, query or fragment; it is passed as --public-read-url and declared for every hosted level (see Listing a chain on an explorer);
  • publicReadFetches, when set, is nonnegative and is passed as --public-read-fetches: how many Volumes the public listener reads from peers at once for readers when the node does not hold them (see GET /volumes/:cid); 0 serves only what the node holds;
  • publicSubmit, when true, passes --public-submit and requires publicRead: the public listener also accepts POST /transactions (see Running a public submit endpoint); absent or false is off;
  • unknown paths in mining policy are rejected.
Command Effect
lattice init Create lattice.json and the process identity, refusing to overwrite a topology.
lattice up Start the one node process in the background. Restart it when the configured hosted path set changed.
lattice up --foreground Supervise the node for container or init-system use.
lattice status Read every hosted level from the one loopback RPC.
lattice down Stop the node process under the spawn lock.
lattice wipe Remove the complete stopped tree storage. Preserve identity, specs, and topology.
lattice identity Print the process public key and peer string.

Examples:

Terminal window
lattice init --root /var/lib/lattice
lattice up --root /var/lib/lattice
lattice status --root /var/lib/lattice
lattice down --root /var/lib/lattice

The PID file names the executable as well as the PID, so a recycled PID is not signalled. Start, stop, restart, child creation, and wipe share one spawn lock. Storage also has its own writer lock; wipe refuses if any node still owns it.

Terminal window
lattice child create Nexus/Alpha \
--root /var/lib/lattice \
--block-time 10000 \
--reward 1000 \
--premine 0

Or provide a complete ChainSpec JSON:

Terminal window
lattice child create Nexus/Alpha \
--root /var/lib/lattice \
--spec alpha-spec.json

A spec names each WASM policy module by CID in wasmPolicies. Give the file for every module it names:

Terminal window
lattice child create Nexus/Alpha \
--root /var/lib/lattice \
--spec alpha-spec.json \
--policy-module transfer-rules.wasm \
--policy-module action-rules.wasm

Each file is matched to the spec by its CID and checked against the policy ABI; creation is refused if a file is one the spec does not name, or a named module has no file. The modules are kept beside the spec, and the node stores them at start, so it can store and serve the genesis it mines.

A spec with a premine needs the account the genesis pays it to:

Terminal window
lattice child create Nexus/Alpha \
--root /var/lib/lattice \
--spec alpha-spec.json \
--premine-to <address>

premine counts blocks of the reward schedule; the genesis pays their rewards to that account in one unsigned credit, as Nexus’s genesis pays its own, and genesis validation bounds the credit by the premine. Creation is refused for a premine with no account, an account that is not an address, or a genesis one of the spec’s transaction policies refuses. The account is kept beside the spec and passed to the node as --premine-to <path>=<address>, which the node checks the same way at start.

A chain can also start with state its creator writes, such as names the creator holds from the first block, as signed transactions the genesis carries after its premine:

Terminal window
lattice child create Nexus/Alpha \
--root /var/lib/lattice \
--spec alpha-spec.json \
--genesis-transactions genesis.json

The file is a JSON array of what POST /transactions takes. Genesis validation does not check signatures, so creation does: each transaction must be signed by exactly its signers, be for this chain, carry no coin, deposit, receipt or withdrawal actions (a genesis pays only its premine), and pass the spec’s transaction policies; with the premine they must fit one block. The file is kept beside the spec and passed to the node as --genesis-transactions <path>=<file>, which the node checks the same way at start. A signer’s later transactions continue from the nonces its genesis transactions used.

Creation writes one immutable spec and adds the path to hostedChains. The node builds the genesis candidate from that spec when the parent has an executed state it can commit, and ordinary merged mining secures it. There is no child-deploy command or parent authorization transaction.

For a nested child, create the parent first. Its genesis is not eligible until the parent has executed a block. Give a chain positive rewards before relying on it as a parent; a reward-free, transaction-free chain never changes state.

Command Effect
lattice mine start Start the background coordinator loop.
lattice mine status Show its PID and configured recipients.
lattice mine stop Finish or bound the active round, then stop.

mine.worker is cpu for the bundled worker or an executable path implementing the worker contract. mine.recipients controls each chain’s reward and fee recipient; an omitted path burns that payout. mine.minWork is a local search filter, not a committed consensus target. mine.minBlockIntervalSeconds is a floor on template spacing and releases itself when rounds run longer.

The mining loop probes the node for the template expiry and places a deadline around each coordinator process group. A timeout is logged loudly and the next round retries.

Terminal window
lattice key generate --out ./wallet.json

Key files are created mode 0600, and transaction commands refuse a group/other-readable key.

Terminal window
lattice tx send \
--root /var/lib/lattice \
--chain Nexus/Alpha \
--key ./wallet.json \
--to <address> \
--amount 25 \
--fee 1

tx deposit, tx receipt, and tx withdraw expose the three cross-level exchange actions. All submissions use the one RPC listener and carry their absolute chain path. The CLI rejects a path this host does not serve; the node also returns 404 for an unhosted path.

Generate foreground units from the configured topology:

Terminal window
lattice emit-systemd --root /var/lib/lattice \
> /etc/systemd/system/lattice.generated.units

The checked-in examples are deploy/lattice-node.service and deploy/lattice-mining-coordinator.service. The coordinator unit requires a nonempty RECIPIENT_ARGS in /etc/lattice/mining.env so production mining cannot silently burn all rewards.

<root>/
lattice.json
identity/Nexus.key
specs/Nexus%2FAlpha.json
chains/Nexus/
state.db
volumes.db
volume-bundles.db
storage.lock
run/
log/

There is no per-chain process, port, key, or child state.db. The path in specs/ identifies a level; runtime facts for every level share the one tree journal.


Source: lattice-node/docs/operator-cli.md at 9abd15b1bb05