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.
# 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.
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.
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.
npx @robotmoney/cli get-apy --chain base
get-balance
Returns the rmUSDC balance and current USDC value for a given wallet.
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.
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.
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).
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.
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. ReadsbalanceOfat 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-amountsfor 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.
npx @robotmoney/cli prepare-withdraw \ --chain base \ --user-address 0x... \ --amount 50 \ --receiver 0x... \ [...same basket-sell flags as prepare-redeem...]
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.
npx @robotmoney/cli create-wallet [--label <string>] [--storage-path <dir>]
--label— optional name for the wallet. Defaults to a generated string. Used in--walletflags 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
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
npx @robotmoney/cli execute-redeem \ --chain base \ --wallet <name> \ --shares max \ [--sell-all]
execute-withdraw
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:
--passphrase <string>— highest priority. Note: visible in shell history.OWS_PASSPHRASEenvironment variable — cleanest for agent workflows.- 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.
| Revert | Cause | Fix |
|---|---|---|
ERC20InsufficientAllowance | USDC allowance for the vault is below the deposit amount | With prepare-deposit, simulation pre-applies the approval via state override, so this shouldn't appear. If it does, check the caller's approval flow. |
ERC20InsufficientBalance | User lacks USDC | Fund the wallet with USDC on Base first. |
ERC4626ExceededMaxDeposit | Deposit exceeds vault's max for this receiver | Reduce amount; check TVL and per-deposit caps. |
ERC4626ExceededMaxWithdraw | Withdraw amount exceeds the owner's current balance | Use prepare-redeem --shares max to exit the full position. |
ERC4626ExceededMaxRedeem | Redeem shares exceed the owner's share balance | Use --shares max, which reads balanceOf automatically. |
TVLCapExceeded | Deposit would push total vault assets above the TVL cap ($100,000) | Reduce amount or wait for cap raise. |
PerDepositCapExceeded | Single deposit exceeds the per-deposit cap ($5,000) | Split into multiple deposits under the cap. |
VaultShutdown | Vault is permanently shut down — deposits disabled | Withdrawals still work; no new deposits accepted. |
EnforcedPause | Vault is paused (operational emergency) | Wait for unpause; withdrawals may still be available. |
NoActiveAdapters | No adapters are active | Operator attention required before any deposit. Not a user- fixable error. |
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.