CLI Reference
The alw CLI is the command-line interface to Allways. Every on-chain contract action is signed by your Solana keypair; miners' TAO-destination fulfillments are signed by their Bittensor coldkey. See Getting Started for install and key setup.
Command groups:
| Group | Purpose |
|---|---|
alw config | View / set network + wallet + keypair configuration |
alw status | Quick dashboard — balances, active swaps, reservations |
alw view | Read on-chain state (config, miners, rates, reservations, swaps, validators) |
alw swap | Run and manage swaps |
alw collateral | Miner collateral — deposit, withdraw, view |
alw miner | Miner operations — bind, quote, activate, fulfill |
alw admin | Contract-owner operations (config setters, whitelist, treasury, halt) |
alw completion | Print a shell-completion script (bash/zsh/fish) |
All amounts on the CLI are in whole units (SOL, BTC, TAO), not smallest units, unless a command says otherwise. Read-oriented commands (alw view …, alw status, alw swap quote) accept --json for machine consumption.
alw config
View or set persistent configuration (stored at ~/.allways/config.json).
alw config # every settable key: effective value + source (env / config / default)
alw config set env testnet # bundle: bittensor test + every chain's testnet + netuid 19 + router
alw config set env mainnet # bundle: bittensor finney + every chain's mainnet + netuid 7
alw config set router <hotkey> # route reservations through this validator ("" = self-represent)
alw config set wallet <name>
alw config set hotkey <name>| Key | Values | Meaning |
|---|---|---|
env | testnet | mainnet | Sets every chain's network + netuid + the recommended router at once |
network | finney | test | local | ws://… | Bittensor network |
netuid | integer | Subnet UID — 7 (mainnet) / 19 (testnet); env sets it for you |
solana-network | devnet | mainnet | localnet | Solana cluster |
solana-rpc | URL | Custom/keyed Solana RPC (takes precedence over the name) |
solana-keypair | path | Solana signing key (else SOLANA_KEYPAIR_PATH, else ~/.solana/id.json) |
<chain>-network | per chain | One spoke's network — btc-network, eth-network, … alw config set --help lists them all |
router | validator hotkey (ss58) | Route reservations through this validator (stake-weighted entry; it finalizes for you). Empty = self-represent. env sets the recommended Ventura Labs router per network |
wallet / hotkey | name | Local Bittensor wallet/hotkey names |
program-id | pubkey | Solana program id override — dev only; defaults to the baked-in deployed id (same across clusters). ALLWAYS_PROGRAM_ID env wins over this |
alw status
Quick dashboard: network connection, Solana RPC + program health, SOL balance, and your miner status (if you're a miner) or live reservation (if you're mid-swap).
alw status
alw status --miner <miner_pubkey> # look up your reservation on a specific mineralw view
Read on-chain state.
alw view config
The live contract Config — fee, reservation fee, swap/collateral bounds, windows, timeouts, consensus threshold, and halt status. Read this instead of any number quoted in these docs — everything here is admin-tunable.
alw view configalw view miners
Operator view: every miner on-subnet including offline / in-swap / reserved / cooldown, with collateral (SOL), runtime status, posted addresses, and hotkey. For a shopping view of swappable miners only, use alw view rates.
alw view miners
alw view miners --status available --sort capacity --min-capacity 0.5Filters/sorts: --sort uid|rate|capacity|status, --status available|offline|in-swap|reserved|cooldown, --min-capacity <sol>, --search <str>, --full.
alw view rates
Shopping view: only active miners with collateral, so you can compare quotes. Rates always read "destination per 1 source unit". Capacity is the miner's collateral in the quote's backing; the largest single fill it can back is capacity / 1.1.
alw view rates --pair sol-btcFilters/sorts: --pair <from>-<to>, --sort rate|capacity|pair|uid, --min-capacity <sol>, --search <str>, --full.
Direct transfers to a miner's posted address bypass the reservation flow and are not matched to a swap — always go through alw swap now.
alw view reservation
Your active reservation, if any — direction, amounts, addresses, and whether it's live (finalized) or still unfilled (drawn but not yet named). Pass --miner <pubkey> if the CLI's local stash doesn't know which miner you reserved.
alw view reservationalw view swap
A single swap plus its timeline and transaction hashes. --watch polls until the swap reaches a terminal state.
alw view swap <swap_key>
alw view swap <swap_key> --watchalw view active-swaps
Every in-flight swap on the contract. Filter with --status active|fulfilled|pending-attestation.
alw view validators
The whitelisted validator set (Solana pubkeys) and their draw weights.
alw swap
alw swap quote
Preview rates and post-fee receive amounts without committing. Rows whose collateral can't cover your amount, or that fall outside min_swap/max_swap, are flagged.
alw swap quote --from btc --to sol --amount 0.001| Flag | Meaning |
|---|---|
--from | Source asset, by wire id |
--to | Destination asset; one leg must be a hub |
--amount | Source amount (source-chain units) |
alw swap now
Originate a swap: enter the miner's pool → crank and wait out the draw → finalize your reservation at the pinned rate → print where (and exactly how much) to send. With --send it then broadcasts the source funds, relays, and watches to a terminal state; with --no-send you send from your own wallet and relay the hash with alw swap post-tx. Default: --send on an interactive terminal, --no-send in a script. Omitted flags are prompted for on a terminal, and required in a script.
# BTC → SOL (send BTC, receive SOL)
alw swap now --from btc --to sol --amount 0.001 \
--from-address tb1q... --receive-address <your-sol-pubkey> --yes
# SOL → TAO (send SOL, receive TAO) — --receive-address is a TAO ss58
alw swap now --from sol --to tao --amount 0.5 \
--receive-address 5C... --yes
# Pin a specific miner (pubkey from `alw swap quote`); bare --miner opens a picker
alw swap now --from sol --to tao --amount 0.5 \
--receive-address 5C... --miner <miner-pubkey> --yes| Flag | Meaning |
|---|---|
--from | Source asset you spend, by wire id (alw view rates lists every one) |
--to | Destination asset you receive; one leg must be a hub |
--amount | Source amount, in source-chain units |
--receive-address | Destination address — where the miner sends to you (on the --to chain) |
--from-address | Source address — where you broadcast from (required for a non-SOL source); validators reject any source tx whose sender doesn't match |
--from-tx-hash | Source tx hash, if you've already broadcast the send |
--miner | Pin a specific miner by pubkey instead of auto-select; bare --miner lists viable miners and prompts (TTY only). Fails — never falls back — if that miner can't take the swap; warns if it pays far less than the best quote |
--router | Validator hotkey to route through for this swap (overrides the router config) |
--no-router | Self-represent even when a router is configured |
--send / --no-send | Broadcast the source funds from your configured wallet, then relay and watch. Falls back to printed instructions if the credential is missing or your wallet doesn't control the pinned sender |
--btc-fee-rate | Fee rate for a BTC source tx, in sat/vB (default: auto-estimated) |
--yes | Skip the confirmation prompt |
Every direction must include a hub leg, SOL or TAO. Each pool entry pays the reservation fee — base 0.02 SOL, non-refundable, win or lose (the live base is in alw view config); a routed entry is stake-discounted by the router's draw-weight share (up to 95% off, 0.001 SOL floor), while a self-represented entry pays the full base. Before charging it, the CLI surfaces pool contention — entry count, window close, and your odds. Re-running is idempotent: a seat or live reservation you already hold is resumed, not re-bought.
alw swap post-tx
Relay your source-tx hash to the validators for a live reservation. Run it immediately after broadcasting — do not wait for confirmations (deferred confirmation waits them out server-side). If validators haven't seen the tx yet, the CLI retries the relay a few times over a short propagation grace window before giving up.
alw swap post-tx <tx_hash>
alw swap post-tx <tx_hash> --miner <miner_pubkey> # disambiguate if you hold multiple reservationsalw collateral (miners)
alw collateral deposit --amount 2 # deposit SOL collateral
alw collateral withdraw --amount 1.5 # withdraw (after deactivation cooldown)
alw collateral view # your collateral + vault
alw collateral recover-from-hotkey # sweep stray TAO off your hotkey back to the coldkey (--dest, --amount)Collateral must cover 1.1× each swap you accept. Withdrawal is gated: you must be deactivated and past the 2× fulfillment-timeout cooldown, with no active swap and no open pool or held reservation on you.
alw vault (miners — TAO collateral)
The Bittensor side of a TAO-backed quote. Your bond lives in an ink! vault on subtensor; Solana reads a mirror of it that validators maintain, so vault changes take a moment to show up on the swap side.
alw vault post-collateral 1.0 # move TAO from your coldkey into the vault (min 0.25 τ)
alw vault lock # lock the bond so validators can mirror it as backing
alw vault status # your bond, lock state, and what validators have mirrored
alw vault withdraw 0.5 # withdraw from an UNLOCKED bond back to your hotkey
alw vault claim-slash <swap_ref> # claim a reimbursement owed to you as a userThe order matters: post → lock → wait for the mirror → alw miner activate --backing tao. Activation is refused until validators have mirrored a locked bond that clears the minimum, so a quote can never be backed by a bond the network hasn't seen.
Leaving is the reverse and is not unilateral: alw miner deactivate --backing tao first, then validators vote your bond unlocked once you're quiescent — no live swap, timeout windows past, every verdict applied and fee settled. Only then does alw vault withdraw succeed. Deactivating one purse leaves your other purse trading.
alw miner (miners)
alw miner bind-hotkey # bind Solana keypair ↔ Bittensor hotkey (also auto-runs at startup)
alw miner quotes --sol-address <sol> --btc-price <btc-per-sol> --btc-address <btc>
# one price per chain ("X per 1 SOL") → posts both directions of each pair
alw miner quotes ... --dry-run # preview rates + any churn fee
alw miner quotes ... --spread 25 # symmetric margin in bps around the mid (0 = zero-margin mid)
alw miner post # interactive wizard — prompts for chain, addresses, and rates
alw miner post sol <sol-addr> btc <btc-addr> <rate> <counter-rate> --yes # one pair explicitly (both directions)
alw miner post tao <tao-addr> btc <btc-addr> <rate> --backing tao --yes # TAO-backed quote (TAO as the hub leg)
alw miner remove-quote <from> <to> # retract a quote direction
alw miner activate --backing tao # activate ONE purse (sol|tao); omit to infer when only one qualifies
alw miner deactivate --backing tao # drop one purse, leaving your others trading
alw miner deactivate # full exit: every purse goes dark
alw miner status # collateral, quotes, active swaps
alw miner mark-fulfilled --from-tx-hash <src_tx> --to-tx-hash <dest_tx> # manual fulfillment mark (normally automatic)Run bind-hotkey before you register on the subnet: the hotkey→Solana binding is set-once in both directions — a hotkey belongs forever to the first pubkey that binds it (registering first lets someone front-run and squat it), and a bound pubkey can never switch to a different hotkey (re-running with the same hotkey only refreshes the signature; changing hotkeys means a fresh Solana keypair + re-posted collateral). See the Miner Guide for the full onboarding order.
Every quote declares a backing — the purse that answers if you fail to deliver. --backing picks it when you have more than one funded; with a single funded purse it is inferred. The two purses are scored independently, so a swap on one does not cost you the crown on the other (see Incentive).
Quotes are per-direction and floored to 5 significant figures. Re-quoting a direction within 10 minutes pays a churn fee (0.01 SOL < 5 min, 0.001 SOL 5–10 min, free after).
alw admin (contract owner)
Signed by the contract admin keypair. Amount setters take SOL (floats); time setters take seconds (integers). A group-level --yes (or the ALW_ASSUME_YES env) skips confirmations for headless use: alw admin --yes set-….
alw admin add-vali <validator_solana_pubkey> # whitelist a validator (--weight sets its draw weight, default 1)
alw admin remove-vali <validator_solana_pubkey>
alw admin withdraw-treasury --amount 1.5 # drain accumulated fees (recipient is pinned to the admin; omit --amount for all)
alw admin set-min-swap 0.1 alw admin set-max-swap 1
alw admin set-min-collateral 0.1 alw admin set-max-collateral 10
alw admin set-reservation-ttl 480 alw admin set-reservation-fee 0.02
alw admin set-pool-window 60 alw admin set-finalize-window 150
alw admin set-timeout 600 alw admin set-max-extension 8400
alw admin set-threshold 67 alw admin set-weights-interval 3600
alw admin danger halt # emergency: block new deposits/activations/pools
alw admin danger resumeOut-of-range values are rejected with a message rather than a revert. The finalize window is clamped to [15, 300] seconds; the max extension is clamped on-chain to [1800, 8400] seconds (30–140 min — the shipped default is the ceiling, so it can only be lowered); the other setters enforce simple floors (e.g. timeout ≥ 60s, threshold 1–100).
For the system design behind these commands, see How It Works.
