Agent index (llms.txt) — fetch this first, then the page it names.
Global nodes
A global node runs the public Orama chain (oramad) and, optionally, the services beside it: the storage provider, the history archiver, the chain indexer and the repair delegate, or a role of the Orama Tor network (directory authority, relay, exit, validator onion service). It needs no domain, no WireGuard and no cluster. Every command on the node runs as root. None needs raw systemctl.
A machine can also be a cluster node and a global node at once (Sharing a machine).
The chain itself is described in What the chain is and Running a chain node. Remember the status: devnet, stagenet and localnet only.
Hardware
The code does not check hardware. These sizes come from the plan:
| Service | Size |
|---|---|
| Chain (validator) | 4 vCPU, 16 GB RAM, NVMe. State in /var/lib/orama-global/chain |
| Chain (non-validator) | Same disk class |
| Provider | Disk at least the capacity you declare. Piece store /var/lib/orama-global/provider/store |
| Public Kubo | Disk for its StorageMax: the declared capacity plus 10%. Every pinned public piece is stored twice on the host, once in the provider's store and once in Kubo |
| Archiver | Disk for bundles/ (one file per archived range) |
| Repair | Small |
Install
The staged directory is a release's bin/ (/opt/orama/bin once the release archive is extracted on the node): an amd64 release carries oramad, its shielded verifier orama-orchard-verifier with its .sha256 file, orama-global, orama, Kubo's ipfs (v0.43.1) and the official cosmovisor tarball cosmovisor-v1.7.3-linux-amd64.tar.gz. The release's manifest.json (--manifest, /opt/orama/manifest.json by default) lists them. The installer refuses a symlink or a directory another account could change.
What is verified. Every file the install reads must match the release manifest before anything on the host changes, the verifier must match its digest file, and oramad must pin that digest. The installer also verifies the cosmovisor tarball against a pinned SHA-256 and runs ipfs --version as an unprivileged account to require v0.43.1. The manifest is trusted because the archive was verified when it was extracted (a wallet you trust, or the release root). The chain unit runs the staged orama as root before every start, oramad holds the validator key, and orama-global holds hot keys and repair seeds; a directory you assemble yourself makes you the root of trust for it.
sudo orama global install \ --services chain,ipfs,provider \ --public-storage-gb 500 \ --staged-dir /opt/orama/bin \ --persistent-peers <node-id>@<host>:31000,<node-id>@<host>:31000 \ --init-chain --chain-id <chain-id> --moniker <name> --genesis /root/genesis.json \ --enable-firewall --ssh-port 22
- +
--servicesischainplus any ofipfs,provider,archiver,indexer,repair; the Tor rolesdirauth,relay(withexitfor an exit) andonionare described under The Tor network roles. The chain is required: the others reach it only through its RPC on127.0.0.1:31001. Adirauthorrelayhost needs no chain, andonionjoins a chain that is already installed.providerneedsipfsbeside it, since it pins public deals through this host's public Kubo.providerandrepairare never on the same host: a repair delegate holds repair seeds and a provider must not.indexeris optional (loopback 31015, proxied by a gateway). - +Each service gets its own system account (
orama-chain,orama-ipfs-pub,orama-provider,orama-archiver,orama-indexer,orama-repair). Binaries go to/usr/lib/orama-global/bin, root-owned, 0755. - +Units are written to
/etc/systemd/system/orama-global-*.serviceand enabled, not started. None is part oforama-node.service. They start after the chain unit and want it. - +The chain unit runs cosmovisor v1.7.3 with downloads disabled. The chain home must already have a genesis, so use
--init-chainon the first install. The shielded verifier is placed in the cosmovisor layout besideoramad, and the unit passes it tooramadthroughcurrent/bin, so each version runs the verifier it was built with. A second install with the sameoramadchanges nothing; different bytes are refused. To change the chain binary useorama maint global stage-oramad --upgrade <plan> --verifier <file> --verifier-target <name>and let cosmovisor switch at the plan's height. - +The public Kubo is a second daemon, never the private cluster's: its own repo in
/var/lib/orama-global/ipfs(ipfs init --profile=server), no swarm key, the swarm on 31010 tcp and udp, private address ranges filtered and not announced, only pinned content announced. Its RPC is127.0.0.1:31011behind a bearer token that allows onlyadd,cat,pin/add,pin/rm,repo/gcand the read-onlyrepo/stat.--public-storage-gbis the capacity you will declare; Kubo'sStorageMaxis that plus 10%, and a garbage-collection timer runs 20 minutes after start and then every 6 hours. - +With
providerinstalled,PUBLIC_PINandARCHIVEdeals are pinned in the public Kubo before the slot is accepted.PRIVATEdeals never touch it. - +
--init-chainrunsoramad initasorama-chainand puts--genesisin place (itschain_idmust equal--chain-id). The flag is refused when the home already has a genesis. - +
ufw: the chain's 31000 tcp and udp, Kubo's 31010 tcp and udp and the provider's 31013 tcp are allowed with the commentorama-global. An inactiveufwis refused unless--enable-firewallis given; then incoming is denied by default, the SSH port allowed andufwenabled.--ssh-portmust be a portsshd -Tsays sshd listens on. Loopback listeners (31001 to 31004) are not opened. - +
oramad startrefusesquery-gas-limit = "0"on any non-localnet chain id.--init-chainwrites"2000000"; a home from an earlier build must be edited by hand (or given--external-address, which rewrites it), and this release is state-breaking, so such a home cannot be carried over at all: the chain restarts from a new genesis. - +Running the command again with the same flags changes nothing but the binaries' bytes. A service left out of
--servicesis not removed.
The Tor network roles
Orama runs its own anonymity network from unmodified upstream Tor (the node's separate public-Tor client is described in Tor). Its roles are installed with orama global install --services dirauth, relay, relay,exit or onion:
| Role | Installed with | Units | Public ports |
|---|---|---|---|
| Directory authority | dirauth | orama-global-tor-dirauth.service, orama-global-tor-archive.timer | 31020/tcp (ORPort), 31021/tcp (DirPort) |
| Relay | relay | orama-global-tor-relay.service, orama-global-tor-monitor.timer | 31020/tcp |
| Exit (opt-in) | relay,exit | the relay's unit with an exit policy | 31020/tcp |
| Validator onion service | onion | orama-global-tor-onion.service, orama-global-txgate.service | none |
A directory authority is a relay already, so a host runs dirauth or relay, never both. An exit is refused unless the network file says allow_exit.
One network file. tor-network.json is the only network file and tornet.ParseNetwork the only parser. The key ceremony (orama global tor ceremony, run on an offline machine) writes it; you stage it beside the release binaries, and it ships unchanged to clients. It lists at least three directory authorities and the validator onion services that take transaction submissions (validator_onions), and it must say "private": true: the public Orama Tor network is not launched, and every role and client refuses a file that says otherwise. The parser rejects unknown fields. A validator's onion address exists only once its onion role has started, after the ceremony wrote the file, so add it afterwards:
orama global tor onions add --network-file tor-network.json <addr.onion> [<addr.onion>...]
It validates every address, lists none twice, keeps the file's mode and replaces it atomically. Re-install the roles that read the file to pick up the change.
Relay health. On a relay, orama-global-tor-monitor.timer runs orama global tor monitor every five minutes. It writes in_consensus (whether the consensus the relay holds lists it) to /var/lib/orama-global/tor-relay/monitor.json, and leaves it out while the relay has no valid consensus. The node report, the inspector and the health checks follow orama-global-tor-relay.service; orama monitor node --env <env> shows relay active (in the relay set) or (not in the relay set). See Monitoring.
Relay pay. A relay is paid only once it is registered on chain (MsgRegisterRelay, which orama global install does not send) and reported. Each epoch, x/relay pays the median across reporters, with a default reporter quorum of 3. An operator's total goes through the 90/5/5 service split: 90% to the operator's earnings, 5% burned, 5% to the storage archive fund. The bandwidth reporter (orama-global reporter) runs on a directory-authority host and reports epoch e while the chain is in epoch e+1; it drops an epoch whose report window has passed (ErrWindowClosed) or that is already settled (ErrEpochSettled) instead of retrying it. orama global install does not set the reporter up.
Check a client's view. orama vpn check --network tor-network.json joins the network and reads an account through each validator onion service in the file. It passes when at least one answers.
Start, stop, status
sudo orama global start # chain, wait for its RPC, then the rest sudo orama global start provider # needs the chain running sudo orama global stop chain # stops the provider, archiver and repair first sudo orama global restart chain # restarts everything installed, in order sudo orama global status
The chain always starts first and stops last, and the double-sign guard runs before it starts. The other services start only after http://127.0.0.1:31001/status answers (up to five minutes); otherwise they are left stopped and the command fails.
Register and bond
The operator's wallet never touches the node. On your own machine:
- +
orama global bindsigns each service key's binding. - +
orama global registerbuildsMsgRegisterNode: roles, hot key, bindings, endpoints, and--asn, the autonomous system number this node declares (reserved, documentation and private-use numbers are refused; the chain cannot verify the number, and protocol deals go to distinct ASNs, so declare the real one). With--nodethe RootWallet agent signs and it is broadcast. - +
orama global bond --role <role> --amount <norama>bonds each role. - +
orama global capacitydeclares storage bytes for a provider.
Every command that signs a transaction returns only once it is in a block, and prints its hash and height. A transaction the block refuses is reported as a failure with the chain's log, and one that is not in a block within two minutes is reported with its hash so it can be looked up. A role is active only while its bond is at least min_bond: 1 ORAMA for every role, bond_per_gib 1 ORAMA, unbonding 21 days. See Nodes, roles and bonds.
MsgRegisterOperator has no orama command: register needs the operator registered first, and today the stagenet deploy sends it with its own helper.
Validators
The bootstrap committee
The first validators are a bootstrap committee named in genesis (oramad genesis add-bootstrap-validator). A member needs no stake and has an equal share of voting power while lambda is below 1. There is no application or scoring for a seat. Anyone else becomes a validator with a normal MsgCreateValidator, bonded from earnings if needed; the orama CLI does not build that message. See Validators and staking.
Faults
| Fault | Penalty |
|---|---|
| Downtime: fewer than 50% of the last 10,000 blocks signed | 0.01% slash, jailed 10 minutes |
| Double sign | 5% slash, jailed, tombstoned |
A tombstoned validator can never unjail, and x/power gives it no power. Storage: x/storage slashes 10% of a replica's epoch price after two consecutive proof misses.
Unjail and edit
orama global validator unjail --chain-id <id> --operator orama1... --fee <n> --gas <n> [--node http://127.0.0.1:31003] orama global validator edit --chain-id <id> --operator orama1... --moniker <name> --commission-rate 0.05 --fee <n> --gas <n>
Without --node they print the sign document; with it the RootWallet agent signs and the transaction is broadcast. Unjail is refused while the jail runs, without a self-delegation at least the validator's minimum, and for a tombstoned validator. edit sends every field you do not give as [do-not-modify]; one commission change is allowed per 24 hours.
The hot key
The provider and archiver create their own signing key (hot-key, 0600) on first start and log its address. Registering a node needs a binding signed by this key (orama global bind --service hot-key). It pays fees from its own balance, or from a fee-only balance the operator gives it with MsgFundHotKey (out of its earnings, or out of its bank balance with --from-bank; orama setup funds each node's hot key from the bank), which can pay base fees and nothing else.
Back up the consensus key
sudo orama global validator export-key --recipient <your X25519 public key, hex> --to /root/validator-key.orbk
Seals priv_validator_key.json to your public key. The node never holds the private half. Keep the file off the node.
Move a validator without double signing
Never run two copies of one key. The guard is the sign floor: a per-key record of the last state in /var/lib/orama-global/validator-sign-floor.json. The chain unit runs orama global validator check-sign-floor as root before every start, so it applies at boot, on automatic restart and on any manual start. With any floor recorded the chain starts only when a key is present and, when the key has a floor, only when priv_validator_state.json is not behind it.
- +New host:
sudo orama global validator migrate prepareprints a one-time key. The private half stays in/var/lib/orama-global/migrate-recipient.keyuntil an import uses it, ormigrate cancelremoves it. - +Old host:
sudo orama global validator migrate export --recipient <key> --to /root/move.orbk(the--tofile must not exist). It stops the chain and its dependent services, disables the chain unit, writes an in-progress marker that makes the check refuse any start, seals the key and state, records the state as the old host's floor, moves the key out of the chain home, removes the marker and finally writes the bundle. From then on the old host's chain cannot start, andoramadcannot generate a fresh key beside it. - +Copy the bundle to the new host.
- +New host:
sudo orama global validator migrate import --from /root/move.orbk. It refuses while the chain runs, records the old state as the floor first, then installs the key last. - +New host:
sudo orama global start.
This does not cover a copy of the key made any other way (a disk image, a manual copy). The floor exists only on hosts that ran these commands. To abandon a migration on the old host, put both files back owned by orama-chain, mode 0600 (the key as config/priv_validator_key.json, the state as data/priv_validator_state.json under /var/lib/orama-global/chain) and sudo orama global start; do this only if the new host never started the chain with the key. A killed export can leave the marker behind; the chain then refuses to start until root removes it, after checking whether the key is still in the chain home.
The floor, the migration key and the copies are trusted only while /var/lib/orama-global is root's and not writable by its group or others.
Restore from a backup
Only when the old host is gone for good.
- +New host:
sudo orama global validator migrate prepare. - +Your machine:
orama global validator reseal --from validator-key.orbk --identity-file <private key file, 0600> --recipient <key> --to restore.orbk. - +New host:
sudo orama global validator migrate import --from restore.orbk --old-host-destroyed --floor-height <the network's latest committed height>.
A backup carries no sign state, so the import refuses it without both flags. Give the network's latest committed height H, read from a node you trust right before the import: the floor becomes H+1, round 0, and the restored key signs nothing at or below H. If the old host can still start with its copy of the key, the two will double sign; the flag is your statement that it cannot.
Sharing a machine with a cluster node
A machine can be a cluster node and a global node (role: both). The global services run in their own Linux network namespace, orama-global (address 198.18.0.2); the cluster node stays in the root namespace. The two have separate loopbacks and port spaces, separate users and separate state directories.
sudo orama global install --colocated --services chain,ipfs,provider \ --public-storage-gb 500 --staged-dir /opt/orama/bin --enable-firewall --ssh-port 22
Run it on a machine where orama node setup has already installed the cluster node. The namespace cannot reach the WireGuard mesh, so chain peers use public addresses. Removing the layout means restoring net.ipv4.ip_forward from /var/lib/orama-global/netns-prior-ip-forward before deleting /var/lib/orama-global.
Run a faucet
On a test network (a chain id with -stagenet-, -devnet- or -localnet-) a gateway can fund newcomers. They have no account, no node and no SSH access, so the gateway signs the faucet transaction (MsgFaucet) for them with a key of its own, and orama setup asks the network's seeds for it. It is off unless you turn it on, and the gateway signs on no other kind of network. The chain keeps its own limits: a maximum drip, a cooldown per recipient (a day by default) and a cap per epoch.
Do this on each gateway that should serve it, one at a time:
- +As root on the node, make the key:
orama maint faucet init. It creates the key owned by the gateway's account with mode 0600, prints the faucet account, and never replaces a key (running it again prints the same account). - +Fund the account. It pays the fee of every drip and holds nothing else, so a few ORAMA last for the life of the network. It cannot be a genesis account (a genesis starts at zero supply), so fund it like any account, with a drip signed by a node's operator:
orama chain faucet <faucet account> --env <network> --amount 1000000000000. - +In the node's
node.yaml:
chain:
faucet:
enabled: true
# key_file: /opt/orama/.orama/secrets/chain-faucet.key # the default- +
orama node restart.orama node upgradekeeps the block. The gateway fails to start, and says why, if the key file is missing, is not owned by its account or is readable by others.
Check it: curl -sS -X POST https://<gateway>/v1/chain/faucet -H 'Content-Type: application/json' -d '{"recipient":"orama1…"}' answers the transaction hash, the amount and the block. The request, the refusals and the limits are in Reading the chain. A drip is one transaction signed by one account, one at a time, so a gateway serves about one drip a block; a network that expects more gives several of its gateways their own keys. The network's genesis faucet_max_drip has to be at least what one orama setup needs, which is more than the validator's 1,000 ORAMA self-bond (stagenet's is 10,000 ORAMA).
Not built yet
- +
orama node setup --role globalfrom your machine; install runs on the node. - +Signature verification of the staged binaries by the installer; an installed update path for a chain patch that changes no consensus behaviour.
- +An
orama globalcommand forMsgUpdateNode: an ASN is set at registration only. - +An
oramacommand forMsgRegisterOperator. - +Staging the shielded verifier:
orama global installdoes not placeorama-orchard-verifier; a stagenet, testnet or mainnet node without it refuses to start. - +Removing a service, or its firewall rule, that a later install leaves out.
- +An installer for the relay bandwidth reporter (
orama-global reporterruns from a home you prepare), and on-chain relay registration fromorama global install. - +An independent set of directory authorities: Orama runs them all, and the public Tor network is not launched.
- +A remote signer (TMKMS, Horcrux) or a sentry topology.