Skip to content

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:

GroupPurpose
alw configView / set network + wallet + keypair configuration
alw statusQuick dashboard — balances, active swaps, reservations
alw viewRead on-chain state (config, miners, rates, reservations, swaps, validators)
alw swapRun and manage swaps
alw collateralMiner collateral — deposit, withdraw, view
alw miner initStep-by-step miner setup: wallet, keys, .env, preflight, go-live (also alw init)
alw doctorPreflight a miner setup — config, keys, RPC, collateral, binding, registration, docker
alw minerMiner operations — bind, quote, activate, fulfill
alw vaultTAO bond vault — miner bonds, the permissionless fee recycle, validator governance
alw adminContract-owner operations (config setters, whitelist, treasury, halt)
alw completionPrint 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).

bash
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>
KeyValuesMeaning
envtestnet | mainnetSets every chain's network + netuid + the recommended router at once
networkfinney | test | local | ws://…Bittensor network
netuidintegerSubnet UID — 7 (mainnet) / 19 (testnet); env sets it for you
solana-networkdevnet | mainnet | localnetSolana cluster
solana-rpcURLCustom/keyed Solana RPC (takes precedence over the name)
solana-keypairpathSolana signing key (else SOLANA_KEYPAIR_PATH, else ~/.solana/id.json)
<chain>-networkper chainOne spoke's network — btc-network, eth-network, … alw config set --help lists them all
routervalidator 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 / hotkeynameLocal Bittensor wallet/hotkey names
program-idpubkeySolana 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).

bash
alw status
alw status --miner <miner_pubkey>   # look up your reservation on a specific miner

alw 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.

bash
alw view config

alw 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.

bash
alw view miners
alw view miners --status available --sort capacity --min-capacity 0.5

Filters/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.

bash
alw view rates --pair sol-btc

Filters/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.

bash
alw view reservation

alw view swap ​

A single swap plus its timeline and transaction hashes. --watch polls until the swap reaches a terminal state.

bash
alw view swap <swap_key>
alw view swap <swap_key> --watch

alw 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.

bash
alw swap quote --from btc --to sol --amount 0.001
FlagMeaning
--fromSource asset, by wire id
--toDestination asset; one leg must be a hub or a subnet alpha
--amountSource 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.

bash
# 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
FlagMeaning
--fromSource asset you spend, by wire id (alw view rates lists every one)
--toDestination asset you receive; one leg must be a hub or a subnet alpha
--amountSource amount, in source-chain units
--receive-addressDestination address — where the miner sends to you (on the --to chain)
--from-addressSource address — where you broadcast from (required for a non-SOL source); validators reject any source tx whose sender doesn't match
--from-tx-hashSource tx hash, if you've already broadcast the send
--minerPin 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
--routerValidator hotkey to route through for this swap (overrides the router config)
--no-routerSelf-represent even when a router is configured
--send / --no-sendBroadcast 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-rateFee rate for a BTC source tx, in sat/vB (default: auto-estimated)
--yesSkip the confirmation prompt

Every direction must include a hub leg (SOL or TAO) or exactly one subnet alpha leg, and not TAO↔alpha. 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. For a TAO or subnet-alpha source, you can pass what btcli prints (<block>-<idx>) or the SDK's data['signed_extrinsic_hash'] — a MEV-shielded send is unwrapped to its inner transfer_stake for you.

bash
alw swap post-tx <tx_hash>
alw swap post-tx 8083554-7   # btcli extrinsic id
alw swap post-tx <tx_hash> --miner <miner_pubkey>   # disambiguate if you hold multiple reservations

alw miner init / alw doctor (miners) ​

The onboarding wizard and its preflight — see the Miner Guide.

alw init is the same command at the top level.

bash
alw miner init                                  # interactive; resumable
alw miner init --configure-only                 # write config + .env, run the preflight, stop
alw miner init --network testnet --wallet w --hotkey h --backing sol --helius-key KEY -y   # unattended
alw doctor                                      # ✓ / ✗ table; exit 1 if anything failed
FlagMeaning
--networktestnet | mainnet — applies the env bundle and the of-record vault-address
--wallet / --hotkeyColdkey / hotkey names; a missing hotkey is created, a missing coldkey only interactively
--backingsol | tao | both
--chainsOptional: key only these spoke families (btc,eth,arb,hype,bnb,avax,base,cro,pol). Default is all of them, with one EVM key shared across every EVM chain
--solana-keypairPath (default ./data/solana/id.json; generated if missing)
--helius-keyHelius API key (free at helius.dev): the wizard writes the cluster's Helius URL and SOLANA_RPC_API_KEY. Interactively it asks for just the key, hidden
--solana-rpcFull Solana RPC URL, for a provider other than Helius
--coldkey-passwordStored as MINER_BITTENSOR_COLDKEY_PASSWORD. The miner unlocks the coldkey at boot to sign TAO payouts, and the container cannot prompt, so an encrypted coldkey needs it
--project-dirCheckout holding .env + docker-compose.miner.yml (default .)
--activate-waitMinutes to keep retrying activation. Default 35 after the wizard just registered you (validators only see a new registration on their next metagraph sync, up to ~30 min), else 0
--yesTake every default and skip confirmations, including the typed ones for bind and lock

alw collateral (miners) ​

bash
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.

bash
alw vault deposit --amount 1.0              # bond TAO into the vault, signed by your hotkey (alias: post-collateral)
alw vault lock                              # lock the bond so validators can mirror it as backing
alw vault status [<hotkey>]                 # vault totals; with a hotkey, that bond's balance, lock state, and settled fees
alw vault withdraw --amount 0.5             # withdraw from an UNLOCKED bond back to your hotkey
alw vault claim-slash <swap_ref>            # claim a parked reimbursement owed to you as a user
alw vault recycle                           # permissionless: stake the vault's fee pot back into the subnet

The 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 vault recycle ​

A permissionless recycle anyone can trigger: it stakes the vault's pot (protocol fees settled out of TAO-backed swaps, plus any TAO sent straight to the vault address) back into the subnet pool. There is no recipient to choose, since the destination is fixed by validator governance, so the caller only pays the ~0.003 τ fee.

bash
alw vault recycle
alw vault recycle --hotkey                  # sign with the hotkey: no password prompt, for cron
alw vault recycle --force                   # submit even if the pot reads empty or unreadable

ALLWAYS_VAULT_SURI overrides the signer for either. Fees only land in the pot at settlement boundaries, miner exits, and slash surpluses, so running it more often than the settle cadence just spends fees. alw vault status shows the current pot and the total recycled so far.

alw vault admin (validators) ​

The vault has no owner and no admin key. Its validator set and config change only by unanimous vote of the current validators, and none of it can move a miner's funds. Each command casts your vote and prints the exact command every other validator must run. With a single-validator set, a vote applies immediately. Signed by the hotkey (--coldkey to sign with the coldkey); a group-level --yes skips confirmation (alw vault admin --yes …).

bash
alw vault admin add-validator <ss58>                 # vote to admit; the candidate then joins with `accept`
alw vault admin accept                               # accept your own pending admission
alw vault admin remove-validator <ss58>              # vote to eject (every OTHER validator; refused below 3)
alw vault admin set-recycle-target <hotkey> <netuid> # where `vault recycle` stakes the pot
alw vault admin set-config --threshold 67           # whole-config vote; omitted flags keep their on-chain value

alw miner (miners) ​

bash
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)

alw bind-hotkey is the same command at the top level (validators bind too). 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). Each wallet's first post pays a one-time 0.02 SOL wallet lock fee.


alw admin (contract owner) ​

Signed by the contract admin keypair. Amount setters take SOL (floats), except the set-tao-* setters, which take TAO; time setters take seconds (integers). A group-level --yes (or the ALW_ASSUME_YES env) skips confirmations for headless use: alw admin --yes set-….

bash
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

# TAO-backed purse (amounts in TAO)
alw admin set-tao-min-swap 0.5    alw admin set-tao-max-swap 25     # 0 = no max
alw admin set-tao-min-collateral 5                                  # attested bond needed to activate the TAO purse
alw admin set-settlement-grace 900                                  # busy window after a non-SOL timeout while the penalty settles (60–7200s)
alw admin set-attest-max-age 86400                                  # attestation dead-man fuse (3600–172800s)
alw admin bump-vault-generation                                     # after replacing the vault, before pointing relayers at it

alw admin danger halt             # emergency: block new deposits/activations/pools
alw admin danger resume

Out-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.

Allways is permissionless, open-source, beta software. Swaps settle directly between counterparty wallets; the protocol never takes custody of user funds, and the protocol fee is charged against miner collateral rather than any user transfer. Validator operators, including those run by the project, verify swap outcomes but cannot redirect or receive any transferred amount. Use at your own risk. No warranty. Not financial advice.
Terms of Service · Privacy Policy