@somnia-chain/cli
v0.2.0
Published
The `somnia` command line for Somnia Markets, built with Effect over @somnia-chain/sdk.
Readme
somnia
The command line for Somnia Markets: spot, binary (YES/NO) and perp order books, SomniaLend, oracle prices and the indexer's history, from your terminal or a script.
npx @somnia-chain/cli prices feed BTCIt needs Node 22 or later, and says so on an older one.
BTC/USDC · oracle feed · mainnet
Spot 80,741.675
Mark 80,727.515 (-0.018% vs spot)
Updated 20:00:17 (1s ago) · block 449,768,411At a terminal, results read as text: amounts in token units, prices at the market's precision, times on your clock. Piped, redirected or run by an agent, every command prints JSON instead, so its output goes straight into jq, a script or an agent. --json asks for JSON at a terminal too.
Install
somnia needs Node.js 22 or newer. Run it once with npx:
npx @somnia-chain/cli --helpOr install it to get a somnia command on your path:
npm install -g @somnia-chain/cli
somnia --helpThe package is one self-contained file with no runtime dependencies, plus the front-end template somnia venue init copies. The only optional one is @napi-rs/keyring, which stores keys in your system keychain. If your platform has no prebuilt binary for it, everything except somnia keys still works.
Quick start
Reads need no account and no configuration. They go to mainnet unless you say otherwise:
# Spot pools, then one pool's order book
somnia catalog markets --type SPOT
somnia spot book --pool 0x...
# BTC binary markets trading now, soonest expiry first
somnia binary markets --asset BTC --limit 5
# Perp markets live on Somnia Tokyo (and on the testnets)
somnia perp markets --network tokyo
# Is the indexer keeping up with the chain?
somnia health sync
# Follow every oracle update for ETH
somnia watch price ETHTo send a transaction, give the CLI a key and pick testnet while you try things out. A key in the system keychain stays out of your shell history:
somnia keys generate testnet
export SOMNIA_SIGNER=keychain:testnet
somnia signer show --network testnet
# 10,000 tUSDC (the testnet binary collateral) to the signer, which needs some STT for gas.
# Get STT from the testnet faucet: https://testnet.somnia.network
somnia binary faucet --network testnet
# Buy 10 YES at 0.55 on a binary market
somnia binary place --market $MARKET --side buy-yes --price 0.55 --quantity 10 --network testnetPerp margin is USDso, which testnet has no faucet for: get STT from the testnet faucet, sell it on the SOMI/USDso spot pool, check the USDso it brought with somnia wallet $ADDRESS --network testnet, then deposit at most that: somnia perp deposit --amount 15 --network testnet. somnia perp --help walks through it. tUSDC is binary collateral only.
Where there is no keychain (a CI runner or a headless server), set SOMNIA_PRIVATE_KEY=0x... from a secret instead. A write approves the token it spends when the allowance is short, waits for the receipt and prints the transaction's hash, status and block number.
Your own venue
somnia venue sets up a venue for event markets in a few commands, on testnet first:
somnia venue init my-venue --network testnet # a front end: wallet connection, your markets, order entry
somnia venue create --network testnet --fee 0.5 # an operator, a market policy and the venue, saved to ./somnia-venue.json
somnia venue markets add --from question.json --network testnetA question file holds one market or an array of them. A price market resolves YES when the asset's USDC price at expiry is at or above the strike, read from six exchanges:
{ "type": "price", "asset": "BTC", "strike": 100000, "expiry": "+1d" }A custom market reads any number a public JSON API reports:
{
"type": "custom",
"question": "Will ETH/USDC on Binance be at or above 3,000 at noon UTC on 1 December?",
"strike": 3000,
"decimals": 2,
"expiry": "2026-12-01T12:00:00Z",
"sources": [{ "url": "https://data-api.binance.vision/api/v3/ticker/price?symbol=ETHUSDC", "path": "price" }]
}--policy says who may create markets: operator (you), allowlist (you and the accounts you add with somnia venue policy allow) or open (anyone). somnia venue fee set changes the fee for new markets, and somnia venue status and somnia venue markets list read the venue back.
Every command explains itself
--help on any command lists its flags, what each one means and working examples. It is written to be enough to use the command without other docs, for people and for coding agents alike.
somnia --help
somnia perp --help
somnia perp place --helpCommands
| Command | What it does |
| ----------- | ----------------------------------------------------------------------------------------- |
| spot | Spot order books: pools, orders, vaults; place, amend, cancel and stop orders |
| binary | Binary (YES/NO) markets: find markets, books, positions and PnL; trade, mint, redeem |
| perp | Perpetual futures (tokyo and the testnets): cross-margin accounts, orders, stops, funding |
| wallet | One account across every market: balances, orders, positions and claimable payouts |
| lending | SomniaLend (Aave v3): reserves and accounts; supply, withdraw, borrow, repay |
| tokens | ERC-20, ERC-6909 and native SOMI balances, allowances and metadata |
| catalog | Markets and pools of every kind: listings, counts, bindings, fees |
| prices | Oracle prices: latest feeds, ticks and candles |
| watch | Live data as it happens: blocks, logs, markets, order flow, prices, balances, positions |
| fills | The executed-trade tape of every market |
| candles | A pool's OHLCV candles |
| venue | Your own venue: a front end, the venue on chain, its markets, fee and policy |
| venues | Operators and venues on MarketsCore, and the builder fees routed through their markets |
| activity | The venue's indexed timeline, per market, transaction or block |
| fees | Protocol, builder and settlement fee history |
| health | Indexer lag behind the chain, and an overall venue grade |
| system | Deployed contract wiring, and transaction summaries |
| explorer | Explorer lookups (Blockscout API): address, transaction, block, token, logs, search |
| signer | The account writes sign as, and plain transfers from it |
| keys | Signing keys in the system keychain |
| tx | Sign and send transactions built elsewhere |
| lookup | Say what an address, hash, block, id or text names, and how to read it |
| read | An RPC endpoint's chain id and latest block: a connectivity check |
| feedback | Tell the Somnia team what is wrong, missing or confusing, with the CLI version attached |
| telemetry | Anonymous usage telemetry: off until you opt in; what it shares, on or off |
| mcp | An MCP server for AI agents: quick read tools, and a guide to every command |
Networks
| Flag | Network | Native token |
| ----------------------------- | ----------------------------------- | ------------ |
| --network mainnet (default) | Somnia mainnet, chain 5031 | SOMI |
| --network testnet | Shannon testnet, chain 50312 | STT |
| --network tokyo | Somnia Tokyo, chain 50321 | SOMI |
| --network tokyo-testnet | Hideki (Tokyo testnet), chain 50383 | STT |
SOMNIA_NETWORK sets the default for a whole shell. --rpc-url, --indexer-url, --oracle-url and --explorer-url point a command at other endpoints than the preset's. somnia system endpoints --network tokyo prints the URLs a preset stands for.
Perp markets are on tokyo (sixteen markets), testnet and tokyo-testnet; Somnia mainnet has none. Stop orders for perps are not deployed on tokyo yet. SomniaLend is on mainnet and testnet. binary faucet is for the testnets. The Tokyo chains have no CollateralRouter, so the native-SOMI and Permit2 binary flows are not available there.
Units and output
Amounts and prices are in token units: --price 81500, --quantity 0.001, --amount 100. The command reads the token's decimals, and order commands refuse a price or size off the market's tick and lot, naming the nearest valid values. --raw takes raw on-chain integers instead (1.5 of a 6-decimal token is 1500000). Flags typed uint (ids, bps, blocks) are always raw integers. A write first checks that the wallet can pay its gas: each transaction reserves its gas limit at 60 gwei, 0.6 STT at the default 10,000,000 gas. Times are unix seconds unless a flag says otherwise. A binary market id can be given in full or without its leading zeros: 0xd5d7 is 0x00…0d5d7.
At a terminal, a command prints text: tables and labelled fields, amounts scaled by their token's decimals, prices at the market's tick size, times on the local clock (TZ applies) and how long ago they were, and a write's transaction with its explorer link. Anywhere else (a pipe, a file, an agent's shell) it prints JSON on stdout, with big integers as decimal strings so nothing loses precision, exactly as the raw on-chain values come. Every command uses the same shapes: addresses are checksummed, an order's side is a side string (buy, sell, buy-yes…, or takerSide for a fill), and a read that can fail on its own prints its value or { "error": … } in place.
| Want | Use |
| --------------------------------- | ----------------------------------------------------- |
| JSON at a terminal | --json, or SOMNIA_FORMAT=json for the whole shell |
| Text when piped, e.g. into less | --format text, or SOMNIA_FORMAT=text |
| No color | --no-color, or NO_COLOR=1 |
watch commands run until you stop them. At a terminal each prints a timestamped line per update, with the change since the last one; anywhere else it prints one compact JSON object per line (watch logs and watch reactivity always do). A document from SOMNIA_SIGNER=build (and tx sign) is always JSON, since the next step reads it. A failure prints one error: <message> line to stderr and exits with status 1; at a terminal a hint: line may follow.
somnia binary markets --asset BTC --limit 5 | jq -r '.[].question'Signing
The signer always comes from the environment, never from a flag, so keys stay out of shell history and process lists.
| Variable | Signs with |
| --------------------------------- | ------------------------------------------------------------------ |
| SOMNIA_PRIVATE_KEY=0x<64 hex> | A local key. The default source |
| SOMNIA_SIGNER=keychain[:<name>] | A key stored with somnia keys (the name defaults to default) |
| SOMNIA_SIGNER=build:<address> | Nothing: prints the unsigned transactions from <address> instead |
| SOMNIA_SESSION_SEED=0x<64 hex> | A session account the node signs for |
| SOMNIA_SMART_ACCOUNT=<address> | Acts as this smart account, owned by the key, which pays the gas |
somnia signer show prints the account in use and its SOMI balance.
Keys in the system keychain
somnia keys keeps keys in the macOS Keychain, Windows Credential Manager or the Secret Service on Linux, so they never sit in a dotfile:
somnia keys generate trading
SOMNIA_SIGNER=keychain:trading somnia signer showOffline signing
Build a transaction on one machine, sign it where the key lives and broadcast it from anywhere:
SOMNIA_SIGNER=build:$ADDRESS somnia spot cancel --pool $POOL --order-id 42 > built.json
somnia tx sign < built.json > signed.json
somnia tx submit < signed.jsonAI agents (MCP)
somnia mcp is a Model Context Protocol server on stdio. Add it to an agent:
claude mcp add somnia -- npx -y @somnia-chain/cli mcp # Claude Code
codex mcp add somnia -- npx -y @somnia-chain/cli mcp # CodexIts read tools answer quick questions: markets, spot_book, spot_portfolio, binary_markets, binary_market, binary_positions, perp_markets, perp_account, token_balance, price, fills, venue_health, and the Explorer lookups explorer_address, explorer_transaction, explorer_block, explorer_token, explorer_logs and explorer_search. Each runs the matching command and returns its JSON along with the command line, so the agent learns the CLI as it goes. somnia_find finds the command for a task, somnia_help shows any command's --help, and somnia_feedback sends the Somnia team feedback, as somnia feedback does.
For everything else, including every transaction, the server points the agent to the CLI itself. The server never signs or sends anything. --network (or SOMNIA_NETWORK) and the endpoint flags set the network the read tools use when a call names none. Every read tool takes a network of mainnet, testnet, tokyo or tokyo-testnet, so somnia mcp --network tokyo serves Somnia Tokyo by default and a call can still name another.
Feedback
Found a bug, or something missing or confusing? Tell the team from the terminal:
somnia feedback "perp place should say which tick sizes are valid" --context "placing a BTC order on testnet"It sends your message with the CLI version, Node and OS and, if a command failed in the last 24 hours, that command's name and error (never its flag values). --message-only sends your words alone. Agents can use it too, or the somnia_feedback tool of somnia mcp (messageOnly: true there).
Usage telemetry
Telemetry is off unless you turn it on. The first time you run a command at a terminal, somnia asks once whether to share anonymous usage data. The default answer is no, and the question never appears in a pipe, in CI or under somnia mcp. With it on, each command sends one event: the command's name, the names of its flags (never their values), the network, whether it worked and the kind of error, how long it took, the CLI version, OS, CPU architecture and Node, whether it ran in CI, and when. It never sends keys, addresses, amounts, hashes, arguments or error messages. The team uses it to see which commands people use and where they get stuck.
somnia telemetry status # what is on, and exactly what is shared
somnia telemetry enable # no prompt: for scripts, and for agents once their user says yes
somnia telemetry disableDO_NOT_TRACK=1 always turns it off, and SOMNIA_TELEMETRY=1 or 0 overrides the saved choice. Agents should ask their user before running somnia telemetry enable, and tell them what would be shared and why.
Shell completions
somnia --completions zsh > "${fpath[1]}/_somnia"
somnia --completions bash >> ~/.bashrcfish, powershell and sh work too.
Development
The CLI lives in the somnia-markets pnpm workspace and is built on @somnia-chain/sdk (packages/unified-sdk), the Effect SDK. esbuild bundles both, with every npm dependency, into dist/somnia.mjs, which plain Node runs.
pnpm install # once, at the repo root
pnpm --filter @somnia-chain/cli build # writes dist/somnia.mjs
pnpm --filter @somnia-chain/cli somnia --help
pnpm --filter @somnia-chain/cli testReleasing
Releases go through changesets, like the rest of the repo, but the CLI releases on its own schedule, independently of the SDK:
- A pull request that changes what users see adds a changeset:
pnpm changeset, pick@somnia-chain/cli, choose the bump and describe the change for the changelog. A changeset names the CLI alone, never the CLI and the SDK together. - A release pull request runs
pnpm version-cli, which bumpspackage.jsonand writesCHANGELOG.mdfrom the CLI's changesets only. Pending SDK changesets stay queued for the SDK's own release (pnpm version-packages). - Merging it runs the Release CLI workflow, which builds the bundle, stages the npm package (
pnpm --filter @somnia-chain/cli stage, intodist/npm) and publishes that version.
For a canary of what is on main, run the Release CLI workflow from the Actions tab on main with canary checked. It publishes <version>-canary.<timestamp>.g<sha> under the npm canary dist-tag, without committing a version or touching changesets. Try it with npx @somnia-chain/cli@canary --help.
To check what would be published, without publishing:
pnpm --filter @somnia-chain/cli build
pnpm --filter @somnia-chain/cli stage
npm pack ./packages/cli/dist/npm --dry-runLicense
MIT
