Commands

Every command in the skill: read commands that query protocol state, prepare commands that produce unsigned calldata, and execute commands that sign and broadcast end-to-end.

Common shape

Every command takes --chain base. There's no default chain in v1; the flag is required even though Base is the only supported chain. This is intentional — it forces explicit intent and makes multi-chain expansion straightforward later.

Every command writes a single JSON object to stdout and exits 0 on success or 1 on failure. Errors are reported as JSON on stderr with a structured error field. No partial output, no progress lines, no color codes.

shell
# Generic invocation pattern
npx @robotmoney/cli <command> --chain base [other flags]

Read commands

Read commands query protocol state. None of them require a wallet or signature. They're safe to call frequently; results are always current at the latest block at call time.

health-check

Smoke test: confirms RPC reachability, fetches vault state, and returns ok: true if everything looks healthy.

shell
npx @robotmoney/cli health-check --chain base

Response includes chainId, the RPC endpoint actually used, the current block number, the vault's total assets and share price, paused/shutdown flags, and the active adapter count. See Installation for a worked example.

get-vault

Returns vault-level state: TVL, share price, caps, fee schedule, and adapter breakdown.

shell
npx @robotmoney/cli get-vault --chain base [--verbose]
  • --verbose — include per-adapter balances, oracle freshness, and audit recency metadata.

get-apy

Returns the current effective APY of the vault as a weighted average across active adapters. Excludes the exit fee from the yield calc — the exit fee is reported separately.

shell
npx @robotmoney/cli get-apy --chain base

get-balance

Returns the rmUSDC balance and current USDC value for a given wallet.

shell
npx @robotmoney/cli get-balance --chain base --user-address 0x...
  • --user-address (required) — the wallet to inspect.

Response includes the raw share balance, the share price, the net USDC value after the exit fee (what the user would actually receive if they redeemed right now), and the cost basis if available.

get-basket-holdings

Returns the wallet's holdings across all basket tokens (VIRTUAL, ROBOT, BNKR, JUNO, ZFI, GIZA, PEAQ), with per-token balance and dollar value.

shell
npx @robotmoney/cli get-basket-holdings --chain base --user-address 0x... [--no-pricing]
  • --user-address (required) — the wallet to inspect.
  • --no-pricing — skip dollar-value fetch. Returns token balances only. Useful when you only need quantities.

Prepare commands

Prepare commands return unsigned calldata as JSON. They simulate the transaction at the current block to surface any expected reverts before signing. The CLI never touches keys in this path — the caller signs and broadcasts externally.

Common response shape
Every prepare-* response contains an operation object with a summary, a transactions[] array with one or more unsigned tx objects (target, calldata, value, gas estimate), and a simulation block with allSucceeded, per-tx failures[], and a preview showing the post-state.

prepare-deposit

Prepares the calldata to deposit USDC into the vault and atomically buy the basket leg (95/5 by default).

shell
npx @robotmoney/cli prepare-deposit \
  --chain base \
  --user-address 0x... \
  --amount 100 \
  --receiver 0x... \
  [--no-basket | --basket-only] \
  [--slippage-bps 300]
  • --user-address (required) — who pays the USDC.
  • --amount (required) — USDC amount, decimal. Subject to the per-deposit cap (currently $5,000).
  • --receiver (required) — who receives the rmUSDC shares and basket tokens. Usually the same as user-address.
  • --no-basket — route 100% to vault, skip the basket.
  • --basket-only — route 100% to basket, skip the vault.
  • --slippage-bps — basket leg slippage tolerance in basis points. Default 300 (3%).

Returns two unsigned transactions: the USDC approve and the vault deposit. They must be signed and broadcast in order. The simulation pre-applies the approval via state override so the deposit simulation reflects a fully-approved state.

prepare-redeem

Prepares calldata to redeem rmUSDC shares for USDC. Optionally sells back any subset of basket holdings atomically.

shell
npx @robotmoney/cli prepare-redeem \
  --chain base \
  --user-address 0x... \
  --shares max \
  --receiver 0x... \
  [--sell-all | --sell-percent N | --sell-tokens VIRTUAL,JUNO [--sell-amounts 1.5,200]] \
  [--slippage-bps 300]
  • --shares max — redeem the user's full balance. Reads balanceOf at call time so "max" always means "everything I have right now." Or pass a specific share quantity.
  • --receiver (required) — where the USDC lands.
  • --sell-all — also sell every basket holding back to USDC.
  • --sell-percent N — sell N% of every basket holding.
  • --sell-tokens VIRTUAL,JUNO — sell specific basket tokens. Paired with --sell-amounts for partial sales (otherwise sells full balance of each named token).

Returns one unsigned transaction (a multicall combining the redeem and any basket sells). Simulation reports the expected USDC received, broken down by source (vault redeem vs. each basket sale).

prepare-withdraw

Same as prepare-redeem but specifies the USDC amount the caller wants to receive instead of the share quantity. The skill computes the share burn internally.

shell
npx @robotmoney/cli prepare-withdraw \
  --chain base \
  --user-address 0x... \
  --amount 50 \
  --receiver 0x... \
  [...same basket-sell flags as prepare-redeem...]
When to prefer redeem over withdraw
For full-position exits, prefer prepare-redeem --shares max — it handles adapter liquidity limits gracefully and exits exactly the user's full balance, accounting for fee precision. prepare-withdraw --amount <large> can fail with an ERC4626ExceededMaxWithdraw revert if the requested amount exceeds available adapter liquidity.

Execute commands

Execute commands sign and broadcast end-to-end via an OWS keystore. They take the same flags as their prepare counterparts plus a wallet selector and (optionally) a passphrase. They return confirmed transaction hashes after on-chain confirmation.

create-wallet

Mints a new EVM wallet under the OWS keystore format. Required before any execute-* call if the caller doesn't already have an OWS wallet.

shell
npx @robotmoney/cli create-wallet [--label <string>] [--storage-path <dir>]
  • --label — optional name for the wallet. Defaults to a generated string. Used in --wallet flags below.
  • --storage-path — override the default storage directory (~/.ows/wallets/).

Returns the new address and funding instructions. The wallet needs both USDC and a small amount of ETH on Base before anyexecute-* call works.

execute-deposit

shell
npx @robotmoney/cli execute-deposit \
  --chain base \
  --wallet <name> \
  --amount 100 \
  [--no-basket | --basket-only]

Same semantics as prepare-deposit but signs and broadcasts via the named OWS wallet. The receiver is implicitly the wallet's own address.

execute-redeem

shell
npx @robotmoney/cli execute-redeem \
  --chain base \
  --wallet <name> \
  --shares max \
  [--sell-all]

execute-withdraw

shell
npx @robotmoney/cli execute-withdraw \
  --chain base \
  --wallet <name> \
  --amount 50 \
  [--sell-all]

Wallet selection

  • --wallet <name> explicit → use that OWS wallet
  • Else if exactly one wallet exists in ~/.ows/wallets/ → auto-pick it
  • Else → error with the list of available wallets

Passphrase resolution

In priority order:

  1. --passphrase <string> — highest priority. Note: visible in shell history.
  2. OWS_PASSPHRASE environment variable — cleanest for agent workflows.
  3. Interactive TTY prompt — default for humans.

Simulation reverts

Prepare commands run a simulation and surface any expected reverts. Most reverts have a known cause and a clear fix.

RevertCauseFix
ERC20InsufficientAllowanceUSDC allowance for the vault is below the deposit amountWith prepare-deposit, simulation pre-applies the approval via state override, so this shouldn't appear. If it does, check the caller's approval flow.
ERC20InsufficientBalanceUser lacks USDCFund the wallet with USDC on Base first.
ERC4626ExceededMaxDepositDeposit exceeds vault's max for this receiverReduce amount; check TVL and per-deposit caps.
ERC4626ExceededMaxWithdrawWithdraw amount exceeds the owner's current balanceUse prepare-redeem --shares max to exit the full position.
ERC4626ExceededMaxRedeemRedeem shares exceed the owner's share balanceUse --shares max, which reads balanceOf automatically.
TVLCapExceededDeposit would push total vault assets above the TVL cap ($100,000)Reduce amount or wait for cap raise.
PerDepositCapExceededSingle deposit exceeds the per-deposit cap ($5,000)Split into multiple deposits under the cap.
VaultShutdownVault is permanently shut down — deposits disabledWithdrawals still work; no new deposits accepted.
EnforcedPauseVault is paused (operational emergency)Wait for unpause; withdrawals may still be available.
NoActiveAdaptersNo adapters are activeOperator attention required before any deposit. Not a user- fixable error.
Expected failures
If simulation.failures[i].expected === true, that failure is an artifact of simulating a dependent transaction at latest-block state — not a real error. The allSucceeded field already filters these out, so you only need to inspect failures[] when allSucceeded === false.