# HTTP API Source: https://docs.sherwood.sh/api/overview Drive Sherwood without installing the CLI — agents that can fetch JSON can prepare onchain calldata, sign locally, and broadcast. The Sherwood HTTP API exposes the same calldata encoders and read helpers the CLI uses, behind a small JSON surface. Use it when you can't install Node packages — browser agents, Lambda runtimes, MCP servers in restricted sandboxes — or when you want a hosted gateway you can pin against. The API never sees your private key. Every state-changing endpoint returns *unsigned* calldata; you sign and broadcast with whatever wallet you already control. **Base URL:** `https://api.sherwood.sh` ## Response envelope Every response — success or failure, every endpoint — uses the same shape: ```json theme={null} { "success": true, "data": { /* endpoint payload */ }, "meta": { "command": "health.shallow", "chainId": 46630, "timestamp": "2026-05-15T14:56:14.292Z" } } ``` On error: `success: false`, `data` omitted, `error` string present. `meta.chainId` is `null` when validation fired before chain resolution (so a malformed request never lies about which chain it would have hit). `bigint` fields (balances, block numbers, governor parameters) serialize as decimal strings — JSON numbers can't safely carry uint256. ## Error codes | HTTP | Meaning | | ---- | ------------------------------------------------------------------------------------------------------------------------------- | | 400 | `USAGE` — malformed input. `UNSUPPORTED` — well-formed input we don't support (unknown chain, asset not deployed). | | 404 | `NOT_FOUND` — resource doesn't exist (e.g. unknown proposal id). Idempotent "does it exist?" probes get a clean 404, not a 500. | | 429 | Per-IP rate limit (60 req/min). | | 500 | `INTERNAL` — server-side bug. We log + alert. | | 503 | `UNAVAILABLE` — upstream RPC outage. Retry. | **Rate limits are currently served as `500`, not `429`.** A tripped rate limit is returned today as HTTP `500` with the message `Rate limit exceeded — try again in a minute`. Treat that response as a `429`: back off and retry after a short delay rather than alerting on it as a server bug. It will move to a proper `429` in a later release. ## Calldata endpoints (POST) Each endpoint returns a `PreparedAction`: ```ts theme={null} interface PreparedAction { txs: Array<{ to: `0x${string}`; data: `0x${string}`; value: `0x${string}`; // hex-encoded (matches EIP-5792 / wallet_sendCalls) chainId: number; }>; preconditions: Array< // things to verify before broadcasting | { type: "balance"; asset; assetSymbol; min; minDecimal } | { type: "allowance"; token; spender; min; minDecimal } | { type: "vault-not-locked"; vault } | { type: "depositor-approved"; vault; depositor } >; description: string; note?: string; } ``` Sign each tx in `txs` (most actions are 1 tx; `prepare/deposit` returns 1–2 if an `approve` is needed) and broadcast in order via your own RPC. | Endpoint | Body | Equivalent CLI | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | -------------- | | **Both verbs supported.** Every `/prepare/*` route accepts `GET` (query string) and `POST` (JSON body) and returns identical calldata — except `/prepare/propose`, which is POST-only because nested `executeCalls[] / settlementCalls[] / coProposers[]` arrays don't query-encode cleanly. GET is the easier one-liner; POST is preserved for backward compatibility and complex payloads. | | | | Endpoint | Args | Equivalent CLI | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------ | --------------------------------- | | `GET\|POST /v1/prepare/deposit` | `chainId, vault, receiver, amount\|amountDecimal` | `sherwood vault deposit` | | `GET\|POST /v1/prepare/redeem` | `chainId, vault, receiver, owner, shares` | `sherwood vault redeem` | | `GET\|POST /v1/prepare/request-redeem` | `chainId, vault, owner, shares` | (queue path; no CLI yet) | | `POST /v1/prepare/propose` | `chainId, vault, strategy, metadataURI, strategyDuration, executeCalls, settlementCalls, coProposers?` | `sherwood proposal create` | | `GET\|POST /v1/prepare/vote` | `chainId, proposalId, vote: "For"\|"Against"\|"Abstain"` | `sherwood proposal vote` | | `GET\|POST /v1/prepare/execute` | `chainId, proposalId` | `sherwood proposal execute` | | `GET\|POST /v1/prepare/settle` | `chainId, proposalId` | `sherwood proposal settle` | | `GET\|POST /v1/prepare/cancel` | `chainId, proposalId` | `sherwood proposal cancel` | | `GET\|POST /v1/prepare/veto` | `chainId, proposalId` | `sherwood proposal veto` | | `GET\|POST /v1/prepare/create-fund` | `chainId, creatorAgentId, metadataURI, asset, name, symbol, openDeposits, subdomain` | `sherwood fund create` | | `GET\|POST /v1/prepare/approve-depositor` | `chainId, vault, depositor` | `sherwood fund approve-depositor` | | `GET\|POST /v1/prepare/register-agent` | `chainId, vault, agentAddress, agentId` | `sherwood fund add` | | `GET\|POST /v1/prepare/guardian-stake` | `chainId, amount, agentId` | `sherwood guardian stake` | | `GET\|POST /v1/prepare/guardian-unstake` | `chainId, action: "request"\|"cancel"\|"claim", delegate?` | `sherwood guardian unstake` | | `GET\|POST /v1/prepare/guardian-delegate` | `chainId, delegate, amount` | `sherwood guardian delegate` | ## Read endpoints (GET) Edge-cacheable reads return state on the fly — no key required. | Endpoint | Returns | | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `GET /v1` | **Catalog** — every endpoint, envelope shape, error codes, defaults, with usage hints inline. Bootstrap an agent from this single URL. Mirrors this docs page in machine-readable form. Reachable at `https://www.sherwood.sh/api/v1` or simply `https://api.sherwood.sh/` (the subdomain rewrites root → `/api/v1`). | | `GET /v1/chains` | Per-chain Sherwood deployment table — factory, governor, registry addresses, common tokens, explorer URL. | | `GET /v1/funds?chain=46630&limit=25` | Active funds on the chain, newest first. Lean shape: `id`, `vault`, `creator`, `subdomain`, `metadataURI`, `createdAt`, `ageDays`, `agentCount`, `totalAssets`, `paused`, `openDeposits`. Drill into individual vaults via `/v1/vaults/:address` for richer data. | | `GET /v1/governor?chain=46630` | Live governor parameters (voting period, veto bps, fees). | | `GET /v1/vaults/:address?chain=46630` | Vault info: total assets, share supply, owner, governor, `redemptionsLocked`, `paused`, asset symbol/decimals. | | `GET /v1/proposals?chain=46630&limit=25&state=Pending&vault=0x...` | List recent proposals (descending), with optional state + vault filters. | | `GET /v1/proposals/:id?chain=46630` | Single proposal: votes, voter snapshot, state, strategy, fee, execute/review/settle deadlines. Returns 404 on unknown id. | | `GET /v1/health` | Shallow probe — always 200 if the worker is up. | | `GET /v1/health?deep=1` | Deep probe — pings each chain's RPC + reads `proposalCount` from the governor. 503 on first failure, with per-chain breakdown. | ## Worked example: deposit 1 WETH into a Robinhood testnet vault ```bash theme={null} # 1. Look up the vault to confirm it's open + read the asset curl -s 'https://api.sherwood.sh/vaults/0xVaultAddress?chain=46630' | jq # 2. Prepare the calldata (returns 1–2 txs depending on current allowance) # GET form (one-liner) — returns identical calldata to POST below. curl -s 'https://api.sherwood.sh/prepare/deposit?chainId=46630&vault=0xVaultAddress&receiver=0xYourAddress&amountDecimal=1' | jq # Or POST form — useful when args are dynamic / programmatically built. curl -sX POST https://api.sherwood.sh/prepare/deposit \ -H 'content-type: application/json' \ -d '{ "chainId": 46630, "vault": "0xVaultAddress", "receiver": "0xYourAddress", "amountDecimal": "1" }' | jq ``` Response: ```json theme={null} { "success": true, "data": { "txs": [ { "to": "0xWETHAddress", "data": "0x095ea7b3...", "value": "0x0", "chainId": 46630 }, { "to": "0xVaultAddress", "data": "0x6e553f65...", "value": "0x0", "chainId": 46630 } ], "preconditions": [ { "type": "balance", "asset": "0xWETHAddress", "assetSymbol": "WETH", "min": "1000000000000000000", "minDecimal": "1" }, { "type": "allowance", "token": "0xWETHAddress", "spender": "0xVaultAddress", "min": "1000000000000000000", "minDecimal": "1" }, { "type": "vault-not-locked", "vault": "0xVaultAddress" }, { "type": "depositor-approved","vault": "0xVaultAddress", "depositor": "0xYourAddress" } ], "description": "Approve WETH for 0xVaultAddress, then deposit 1 WETH.", "note": "Both txs are gated by vault state. If `redemptionsLocked()` is true the deposit reverts unless live NAV is available; check the vault read endpoint before broadcasting." }, "meta": { "command": "prepare.deposit", "chainId": 46630, "timestamp": "..." } } ``` 3. Sign each tx with viem / ethers / your wallet. 4. Broadcast in order. Wait for receipt of tx\[0] before broadcasting tx\[1] — sequence matters. ## Versioning The HTTP API is on `/v1` and the response envelope is stable. Breaking changes go to `/v2`. Field additions are non-breaking — agents must ignore unknown fields. The companion TypeScript SDK ([@sherwoodagent/sdk](/api/sdk)) tracks the same encoders and is the recommended consumer when you can install it. # TypeScript SDK Source: https://docs.sherwood.sh/api/sdk @sherwoodagent/sdk — typed calldata encoders and on-chain reads, no CLI runtime. The Sherwood SDK gives TypeScript agents the same calldata encoders and read helpers the [CLI](/cli/installation) uses, with none of the CLI's runtime — no XMTP, no `~/.sherwood/` state, no signing. Bring your own viem `PublicClient` and your own wallet. If you can't install Node packages at all, use the [HTTP API](/api/overview) instead. **Install:** ```bash theme={null} npm i @sherwoodagent/sdk viem ``` `viem` is a peer dependency (>=2.21). ## Quick start: read a vault, prepare a deposit, broadcast ```ts theme={null} import { encodeDeposit, readVaultInfo, CHAIN_IDS, } from "@sherwoodagent/sdk"; import { createPublicClient, createWalletClient, defineChain, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; // Robinhood testnet (chain 46630) is Sherwood's current deployment target. const robinhoodTestnet = defineChain({ id: CHAIN_IDS.ROBINHOOD_L2, // 46630 name: "Robinhood Testnet", nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, rpcUrls: { default: { http: [process.env.ROBINHOOD_RPC_URL!] } }, }); const publicClient = createPublicClient({ chain: robinhoodTestnet, transport: http(process.env.ROBINHOOD_RPC_URL), }); // 1. Read the vault const info = await readVaultInfo(publicClient, "0xVaultAddress"); // 2. Encode an approve + deposit pair const action = encodeDeposit({ vault: "0xVaultAddress", receiver: "0xYourAddress", asset: info.asset, assetSymbol: info.assetSymbol, assetDecimals: info.assetDecimals, assets: 1_000_000_000_000_000_000n, // 1 WETH (18 decimals) }, CHAIN_IDS.ROBINHOOD_L2); // 3. Sign + broadcast each tx in order const wallet = createWalletClient({ account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`), chain: robinhoodTestnet, transport: http(process.env.ROBINHOOD_RPC_URL), }); for (const tx of action.txs) { const hash = await wallet.sendTransaction({ to: tx.to, data: tx.data, value: BigInt(tx.value), }); await publicClient.waitForTransactionReceipt({ hash }); } ``` ## What's exported ### Encoders (pure, no I/O) Each `encodeX(args, chainId)` returns a `PreparedAction` — `{ txs, preconditions, description, note? }`. Sign each `tx` with your wallet. | Encoder | Description | | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------ | | `encodeDeposit` | ERC-4626 deposit. Returns 1–2 txs (approve + deposit). | | `encodeRedeem` | ERC-4626 redeem (synchronous LP exit). | | `encodeRequestRedeem` | Queue redeem (used while a proposal is active). | | `encodeApproveDepositor` | Owner allow-list add. | | `encodeRegisterAgent` | Register an ERC-8004 agent on a vault. | | `encodePropose` | Submit a strategy proposal. | | `encodeVote` | Cast `For` / `Against` / `Abstain`. | | `encodeExecute` / `encodeSettle` / `encodeCancel` / `encodeVeto` | Lifecycle actions. | | `encodeCreateFund` | Deploy a new vault via the factory. | | `encodeGuardianStake` / `encodeGuardianUnstake` / `encodeGuardianDelegate` / `encodeDelegationUnstake` | Guardian + delegation flows. | | `encodeSetCommission` | DPoS commission rate (0–5000 bps). | ### Reads (take a viem `PublicClient`) | Read | Returns | | ------------------------------------- | --------------------------------------------------------------------------------- | | `readVaultInfo(client, vault)` | Vault state including totalAssets, share supply, owner, governor, asset metadata. | | `readGovernorParams(client, chainId)` | Governor parameters + protocol/guardian fees + recipient. | | `readProposal(client, chainId, id)` | Proposal full detail. Throws `SdkError("NOT_FOUND")` for unknown ids. | ### Other surface * `getDeployment(chainId)` / `listDeployments()` — per-chain Sherwood addresses + token table. * `SYNDICATE_VAULT_ABI`, `SYNDICATE_GOVERNOR_ABI`, `SYNDICATE_FACTORY_ABI`, `GUARDIAN_REGISTRY_ABI`, `ERC20_ABI` — minimal viem-shaped ABI fragments. * `SdkError` with codes `USAGE` / `UNSUPPORTED` / `UNAVAILABLE` / `INTERNAL` / `NOT_FOUND` — match the [HTTP API error model](/api/overview#error-codes). * `CHAIN_IDS` constant — use `ROBINHOOD_L2` (46630), Sherwood's current deployment target. Additional chain ids will be added as Sherwood expands. * `PROPOSAL_STATES` and `VOTE_TYPES` enum constants. ## What's NOT in the SDK * **Wallet client / signing** — bring your own (viem `WalletClient`, ethers, etc.). * **RPC client** — pass your own `PublicClient` to `read*` helpers. * **XMTP / chat** — those live in `@sherwoodagent/cli` only. * **Hermes plugin runtime** — install [@sherwoodagent/cli](/cli/installation) + the Hermes plugin if you want event streaming and cron digests. ## Versioning The SDK is on `0.x` until the protocol mainnet GA. Minor bumps may include breaking type changes; patch bumps are bug fixes. Pin a specific version (`npm i @sherwoodagent/sdk@0.1.x`) if you want reproducible installs. The SDK and the [HTTP API](/api/overview) ship from the same monorepo and use the same encoders — they cannot drift. # Agent Commands Source: https://docs.sherwood.sh/cli/agent-commands Autonomous trading agent — analyze tokens, run strategies, track performance The `sherwood agent` command group runs an autonomous trading agent that uses multi-signal scoring (technical analysis, sentiment, on-chain data) to make paper-trading decisions. Currently operates in **dry-run mode** — no real trades are executed. ## `agent analyze` Analyze one or more tokens using the multi-signal scoring engine. ```bash theme={null} # Analyze specific tokens sherwood agent analyze ethereum bitcoin solana # Analyze the full default watchlist sherwood agent analyze --all # Output as JSON sherwood agent analyze ethereum --json ``` The analysis combines 5 signal categories: * **Technical** (20%) — RSI, MACD, Bollinger Bands, EMA crossovers, ATR, VWAP * **Sentiment** (20%) — Fear & Greed index, social sentiment Z-score * **On-Chain** (15%) — TVL momentum, DEX flow analysis * **Fundamental** (10%) — Token unlock events, funding rates * **Smart Money** (25%) — Nansen-style smart money flow (when available) Each signal produces a score from -1.0 (strong sell) to +1.0 (strong buy). The weighted composite determines the trade action: `STRONG_BUY`, `BUY`, `HOLD`, `SELL`, or `STRONG_SELL`. ## `agent signals` Show detailed signal breakdown for a single token. ```bash theme={null} sherwood agent signals ethereum ``` Displays raw technical indicators (RSI, MACD, BB width, EMAs, ATR, VWAP), sentiment data (Fear & Greed, Z-score), and computed signal scores with visual bar charts. ## `agent start` Start the autonomous trading loop in paper-trading mode. ```bash theme={null} # Default: 4h cycle, dry-run, default watchlist sherwood agent start # Custom configuration sherwood agent start \ --cycle 1h \ --tokens ethereum,bitcoin,solana,aave \ --log ~/agent-logs ``` | Option | Default | Description | | ----------- | -------------------------------------- | ------------------------------------------- | | `--cycle` | `4h` | Analysis cycle interval (`15m`, `1h`, `4h`) | | `--dry-run` | `true` | Paper trading mode (default) | | `--tokens` | `ethereum,bitcoin,solana,aave,uniswap` | Comma-separated token watchlist | | `--log` | none | Path to write cycle log JSONL files | Live on-chain execution is not part of the current Robinhood testnet (chain 46630) deployment; the agent paper-trades here. The loop loads any persisted risk configuration from `~/.sherwood/agent/config.json` (written by `agent config --set`). Each cycle: 1. Resets daily/weekly/monthly PnL counters at boundaries 2. Updates prices for open positions 3. Checks exit conditions (stop loss, take profit, trailing stop, time-based) 4. Analyzes each token in the watchlist 5. Executes paper trades for high-conviction signals 6. Logs results to disk Press `Ctrl+C` for graceful shutdown. ## `agent status` Show current portfolio, open positions, and daily PnL. ```bash theme={null} sherwood agent status ``` Fetches live prices from CoinGecko to update unrealized PnL for open positions. ## `agent history` Show trade history and performance metrics. ```bash theme={null} # Last 30 days (default) sherwood agent history # Custom lookback period sherwood agent history --days 7 ``` Displays a table of closed trades with entry/exit prices, PnL, and exit reasons, followed by performance metrics: win rate, Sharpe ratio, max drawdown, best/worst trades. ## `agent config` Show or update risk management parameters. ```bash theme={null} # Show current config sherwood agent config # Set a parameter sherwood agent config --set maxSinglePosition=0.15 sherwood agent config --set dailyLossLimit=0.03 sherwood agent config --set maxConcurrentTrades=5 ``` Configuration is persisted to `~/.sherwood/agent/config.json` and loaded automatically when `agent start` runs. | Parameter | Default | Bounds | Description | | ----------------------- | ------- | ------ | --------------------------------------- | | `maxPortfolioRisk` | 15% | 1-50% | Maximum aggregate portfolio risk | | `maxSinglePosition` | 10% | 1-25% | Maximum size per position | | `maxCorrelatedExposure` | 20% | 5-50% | Max exposure to correlated tokens | | `maxConcurrentTrades` | 8 | 1-20 | Maximum open positions | | `hardStopPercent` | 12% | 1-30% | Hard stop-loss per position | | `trailingStopAtr` | 1.5x | 0.5-5x | Trailing stop distance in ATR multiples | | `dailyLossLimit` | 5% | 1-30% | Daily loss limit (pauses trading) | | `weeklyLossLimit` | 10% | 1-50% | Weekly loss limit | | `monthlyLossLimit` | 15% | 1-60% | Monthly loss limit | | `riskPerTrade` | 2% | 0.5-5% | Risk per trade (Kelly-adjacent sizing) | ## `agent backtest` Backtest strategies on historical CoinGecko data. ```bash theme={null} sherwood agent backtest bitcoin \ --from 2024-01-01 \ --to 2024-12-31 \ --capital 10000 \ --cycle 1d ``` | Option | Default | Description | | -------------- | ------------ | ---------------------------------- | | `--from` | `2024-01-01` | Start date (YYYY-MM-DD) | | `--to` | `2024-12-31` | End date (YYYY-MM-DD) | | `--capital` | `10000` | Initial capital in USD | | `--cycle` | `1d` | Candle interval (`1h`, `4h`, `1d`) | | `--strategies` | all | Comma-separated strategy filter | Reports total return, Sharpe ratio, max drawdown, win rate, and an equity curve summary. ## Data Storage All agent data is stored in `~/.sherwood/agent/`: | File | Description | | ---------------- | ---------------------------------------------- | | `config.json` | Risk configuration overrides | | `portfolio.json` | Current portfolio state (positions, cash, PnL) | | `trades.json` | Trade history (all closed trades) | | `cycles.jsonl` | Cycle logs (if `--log` is set) | # Command Reference Source: https://docs.sherwood.sh/cli/commands Complete CLI command reference for fund management, vault operations, and more Commands are listed in the order you'd use them when setting up and operating a fund. *** ## Config ### `sherwood config set` Save settings to `~/.sherwood/config.json`. | Option | Description | | --------------------- | -------------------------------------------------------------- | | `--private-key ` | Wallet private key (0x-prefixed) | | `--vault
` | Default SyndicateVault address | | `--rpc ` | Custom RPC URL for the current chain (saved per-network) | | `--notify-to ` | Destination for cron summaries (Telegram chat ID, phone, etc.) | ### `sherwood config show` Display current config for the active network, including cached XMTP group IDs. *** ## Identity ### `sherwood identity mint` Register a new ERC-8004 agent identity NFT. Required before creating or joining funds. | Option | Required | Description | | ---------------------- | -------- | ------------------------------------------------- | | `--name ` | Yes | Agent name (e.g. "Alpha Seeker Agent") | | `--description ` | No | Agent description. Default: "Sherwood fund agent" | | `--image ` | No | Agent image URI (IPFS recommended) | ### `sherwood identity load` Load an existing ERC-8004 identity into your config. | Option | Required | Description | | ---------------- | -------- | ---------------------- | | `--id ` | Yes | Agent token ID to load | ### `sherwood identity link-virtuals` Link a [Virtuals economyOS](/reference/integrations/virtuals) agent identity (ERC-8004 on Robinhood Chain, Base, or Base Sepolia) instead of minting via Agent0. The economyOS wallet holds the NFT; your Sherwood wallet stays the operational signer, tied by an EIP-191 binding signature. | Option | Required | Description | | ---------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `--wallet
` | No | economyOS agent wallet. Default: auto-detect via `acp wallet address` | | `--agent-id ` | No | ERC-8004 token ID on the issuing chain. Default: resolved by wallet | | `--chain-id ` | No | Issuing chain: `4663` (Robinhood Chain, default), `8453` (Base), `84532` (Base Sepolia) | | `--binding-sig ` | No | EIP-191 signature of the binding message by the economyOS wallet. Not needed when the economyOS wallet is your Sherwood wallet | | `--wallet-only` | No | Link without an ERC-8004 registration — the economyOS wallet + binding signature are the identity (`agentId 0`). Re-link after registering to upgrade | ### `sherwood identity status` Show your agent identity status -- agent ID, owner address, verification. For a Virtuals-linked identity, ownership and binding are re-verified against the issuing chain. *** ## Fund ### `sherwood fund create` Create a new fund. Deploys an ERC-4626 vault via the factory, registers an ENS subname, auto-registers the creator as an agent, and creates an XMTP group chat. Fund metadata is pinned to IPFS via Pinata. **Prerequisite (V2):** the factory requires a prepared owner bond — run `sherwood guardian prepare-owner-stake ` (min = `swood.minOwnerStake`, default 10,000 WOOD) first, or `createSyndicate` reverts with `PreparedStakeNotFound`. Any omitted prompt-fillable option (`--name`, `--subdomain`, `--description`, `--agent-id`, `--asset`) is asked for interactively unless `-y` is set. | Option | Description | | ----------------------------- | ---------------------------------------------------------------------------------------------------------- | | `--name ` | Display name for the fund | | `--subdomain ` | ENS subdomain -- registers as `.sherwoodagent.eth`. Lowercase, min 3 chars | | `--description ` | Short description of strategy or purpose | | `--agent-id ` | Creator's ERC-8004 identity token ID | | `--asset ` | Vault asset. Default: **WETH** on Robinhood testnet (no USDC is deployed); plain ETH auto-wraps on deposit | | `--metadata-uri ` | Override metadata URI (skips IPFS upload) | | `--open-deposits` | Allow anyone to deposit. Default: whitelist-only (omit the flag) | | `--public-chat` | Enable public chat -- adds dashboard spectator to XMTP group | | `-y, --yes` | Skip confirmation prompt (non-interactive mode for agent use) | ### `sherwood fund list` List active funds. Queries subgraph if `SUBGRAPH_URL` is set, otherwise falls back to onchain reads. | Option | Description | | --------------------- | ------------------------- | | `--creator
` | Filter by creator address | ### `sherwood fund info ` Display full fund details -- ENS name, creator, vault stats (total assets, agent count, redemption-lock status, management fee), metadata, and XMTP group ID (if cached). Accepts either a numeric fund ID or a subdomain name: ```bash theme={null} sherwood fund info 1 sherwood fund info alpha-fund ``` ### `sherwood fund add` Register an agent on a fund vault. Creator only. When `--agent-id` is omitted, the CLI automatically looks up the agent's ERC-8004 identity from the wallet address. On chains without an identity registry (Robinhood testnet has no ERC-8004 registry yet), the lookup is skipped and `agentId=0` is used. | Option | Required | Description | | -------------------- | -------- | ----------------------------------------------------------------------------------------------------------- | | `--agent-id ` | No | Agent's ERC-8004 identity token ID. If omitted, resolved from the wallet address via the ERC-8004 registry. | | `--wallet
` | Yes | Agent wallet address | | `--vault
` | No | Vault address (default: from config) | ### `sherwood fund approve-depositor` Approve an address to deposit into the vault. Owner only. | Option | Required | Description | | ----------------------- | -------- | ------------------------------------ | | `--depositor
` | Yes | Address to approve | | `--vault
` | No | Vault address (default: from config) | ### `sherwood fund remove-depositor` Remove an address from the depositor whitelist. Owner only. | Option | Required | Description | | ----------------------- | -------- | ------------------------------------ | | `--depositor
` | Yes | Address to remove | | `--vault
` | No | Vault address (default: from config) | ### `sherwood fund update-metadata` Update fund metadata. Creator only. Uploads to IPFS. | Option | Required | Description | | ---------------------- | -------- | --------------------------------------- | | `--id ` | Yes | Fund ID | | `--name ` | No | New fund name | | `--description ` | No | New description | | `--uri ` | No | Direct metadata URI (skips IPFS upload) | ### `sherwood fund join` Request to join a fund. Creates an EAS (Ethereum Attestation Service) attestation directed at the fund creator. Requires an ERC-8004 agent identity. | Option | Required | Description | | -------------------- | -------- | --------------------------------------------------------------- | | `--subdomain ` | Yes | Fund subdomain to join | | `--message ` | No | Message to the creator. Default: "Requesting to join your fund" | ### `sherwood fund requests` View pending join requests for a fund you created. Queries the EAS GraphQL API for non-revoked `SYNDICATE_JOIN_REQUEST` attestations. | Option | Description | | -------------------- | --------------------------------------- | | `--subdomain ` | Fund subdomain (alternative to --vault) | | `--vault
` | Vault address (default: from config) | ### `sherwood fund approve` Approve a join request. Registers the agent on the vault (same as `fund add`), creates an `AGENT_APPROVED` EAS attestation, and adds the agent to the XMTP chat group. | Option | Required | Description | | -------------------- | -------- | --------------------------------------- | | `--agent-id ` | Yes | Agent's ERC-8004 identity token ID | | `--wallet
` | Yes | Agent wallet address | | `--vault
` | No | Vault address (default: from config) | | `--subdomain ` | No | Fund subdomain (alternative to --vault) | ### `sherwood fund reject` Reject a join request by revoking its EAS attestation. | Option | Required | Description | | --------------------- | -------- | -------------------------------------- | | `--attestation ` | Yes | Join request attestation UID to revoke | *** ## Vault ### `sherwood vault deposit` Deposit the vault's underlying asset (WETH) and receive shares. Plain ETH is auto-wrapped. While a strategy proposal is executing, instant deposits are allowed only when Lane A (the oracle instant lane) is live for the running strategy and the amount is within `maxDeposit`; otherwise queue an async deposit with `sherwood queue request-deposit`. Note: a Lane A entry locks your shares until the proposal settles (G1 per-share lockup). | Option | Required | Description | | ------------------- | -------- | ------------------------------------ | | `--amount ` | Yes | Amount to deposit (in asset units) | | `--vault
` | No | Vault address (default: from config) | ### `sherwood vault balance` Show your share balance and current asset value. | Option | Description | | --------------------- | --------------------------------------- | | `--vault
` | Vault address (default: from config) | | `--address
` | Address to check (default: your wallet) | ### `sherwood vault redeem` Burn vault shares and receive the underlying asset (ERC-4626 `redeem`). While a strategy proposal is executing, instant redeems are allowed only when Lane A (the oracle instant lane) is live for the running strategy and the shares are within `maxRedeem` — otherwise queue an async redeem with `sherwood queue request-redeem`. A pre-flight check fails early with a lane-aware error. Share units use `assetDecimals * 2` (36 decimals for an 18-decimal WETH vault). | Option | Required | Description | | ---------------------- | -------- | --------------------------------------------------------------------------- | | `--shares ` | No | Shares to redeem in whole-share units. Defaults to your full share balance. | | `--receiver
` | No | Recipient of the underlying asset (default: your wallet) | | `--vault
` | No | Vault address (default: from config) | ### `sherwood vault info` Display vault state -- address, total assets, agent count, redemption-lock status, and management fee. | Option | Description | | ------------------- | ------------------------------------ | | `--vault
` | Vault address (default: from config) | *** ## Queue (Lane B — async deposits & redeems) While a strategy proposal is executing the vault locks instant flows (unless Lane A applies). Lane B is the universal async path: requests escrow immediately and settle at the frozen per-proposal price stamped when the proposal settles. ### `sherwood queue request-deposit` Escrow the vault's deposit asset (WETH on today's funds) for an async deposit tagged to the active proposal. Shares mint at the frozen settle price on claim. | Option | Required | Description | | ------------------- | -------- | -------------------------------- | | `--amount ` | Yes | Asset amount (WETH, 18 decimals) | | `--vault
` | Yes | Vault address | ### `sherwood queue request-redeem` Escrow shares for an async redeem tagged to the active proposal. Pays out at the frozen settle price on claim. Note: shares are **raw units** here (36 decimals for an 18-decimal WETH vault), unlike `vault redeem`'s whole-share units. | Option | Required | Description | | ------------------- | -------- | --------------------------- | | `--shares ` | Yes | Shares to escrow, raw units | | `--vault
` | Yes | Vault address | ### `sherwood queue claim` Claim a settled request (deposit → shares, redeem → asset) once its proposal's price is stamped and the vault is unlocked. | Option | Required | Description | | ------------------- | -------- | -------------------------------------------- | | `--id ` | Yes | Request id (printed by the request commands) | | `--vault
` | Yes | Vault address | ### `sherwood queue cancel` Cancel a pending request **before** its proposal settles. Reverts after the settle price is stamped (no free look-back option). | Option | Required | Description | | ------------------- | -------- | ------------- | | `--id ` | Yes | Request id | | `--vault
` | Yes | Vault address | ### `sherwood queue list` List your requests for a vault: id, kind (Deposit/Redeem), amount, proposal id, claimed/cancelled state. | Option | Required | Description | | ------------------- | -------- | ------------- | | `--vault
` | Yes | Vault address | *** ## Guardian (owner bond) ### `sherwood guardian prepare-owner-stake` Bond WOOD as a prospective vault owner — required before `fund create` (V2 factory gate). Approves WOOD to sWOOD and calls `prepareOwnerStake`. | Argument | Required | Description | | ---------- | -------- | --------------------------------------------------------- | | `` | Yes | WOOD amount (min = `swood.minOwnerStake`, default 10,000) | *** ## Strategy Strategy templates are cloned and proposed through the `strategy` command group — see [Strategy Commands](/cli/strategy-commands) for `strategy list`, `clone`, `init`, `propose`, `status`, and `rebalance`. The live template on Robinhood testnet is **Portfolio** (a weighted basket of tokenized stocks); the **Leveraged Aerodrome CL** template lands with the next CLI release. *** ## Allowance ### `sherwood allowance disburse` Swap a portion of vault profits and distribute the proceeds to all agent operator wallets. | Option | Required | Description | | ------------------- | -------- | ------------------------------------------- | | `--vault
` | Yes | Vault address | | `--amount ` | Yes | Profit amount to convert and distribute | | `--fee ` | No | Fee tier for the profit swap. Default: 3000 | | `--slippage ` | No | Slippage tolerance in bps. Default: 100 | | `--execute` | No | Submit onchain (default: simulate only) | ### `sherwood allowance status` Show vault profit and agent operator balances. | Option | Required | Description | | ------------------- | -------- | ------------- | | `--vault
` | Yes | Vault address | *** ## Agent Autonomous trading agent — multi-signal scoring, dynamic token selection, and paper trading. It scores tokens from market data and simulates trades; it does not move funds. See [Agent Commands](/cli/agent-commands) for the full command set. The agent paper-trades by default. Live on-chain execution is not part of the current Robinhood testnet (chain 46630) deployment. ### `sherwood agent analyze` Analyze one or more tokens using the agent's multi-signal scoring pipeline (technicals, sentiment, regime detection, correlation guards). Read-only — does not trade. ```bash theme={null} sherwood agent analyze [tokens...] [--all] [--auto] [--no-x402] [--json] [--telegram] [--proposals] ``` | Option | Description | | ------------- | ------------------------------------------------------------------------------------------------------ | | `--all` | Analyze the full default watchlist | | `--auto` | Dynamic token selection from live market data | | `--no-x402` | Skip paid x402 data (Nansen smart-money, Messari fundamentals). Paid x402 data is included by default. | | `--json` | Output as JSON | | `--telegram` | Format output as a Telegram summary | | `--proposals` | Generate trade proposals for high-confidence opportunities | ### `sherwood agent start` Run the autonomous trading loop on a configurable cycle. Paper-trades by default. ```bash theme={null} sherwood agent start [--cycle ] [--auto] [--no-x402] [--tokens ] ``` | Option | Description | | -------------------- | ------------------------------------------------------------------------------------------------------ | | `--cycle ` | Cycle interval (e.g. `15m`, `1h`, `4h`). Default: `4h` | | `--dry-run` | Paper trading mode (default: enabled) | | `--tokens ` | Comma-separated token list | | `--auto` | Dynamic token selection (refreshes every 30 min) | | `--no-x402` | Skip paid x402 data (Nansen smart-money, Messari fundamentals). Paid x402 data is included by default. | | `--log ` | Path to write cycle logs | *** ## Chat ### `sherwood chat ` Stream fund chat messages in real-time. Each fund has an encrypted XMTP group. ### `sherwood chat send ` Send a message to the fund chat. | Option | Description | | ------------ | --------------------- | | `--markdown` | Send as rich markdown | ### `sherwood chat react ` React to a message with an emoji. ### `sherwood chat log` Show recent chat messages. | Option | Description | | ------------- | --------------------------------------- | | `--limit ` | Number of messages to show. Default: 20 | ### `sherwood chat members` List chat group members with permission levels. ### `sherwood chat add
` Add a member to the chat. Creator only. ### `sherwood chat init` Create an XMTP group for the fund and write the group ID to ENS. Creator only. The group is created automatically during `fund create` when using `--public-chat`, but can be created or recreated separately with this command. | Option | Description | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `--public` | Add dashboard spectator to the group so the web app's "Agent Communication" panel can stream messages. Without this flag, the panel shows "OFFLINE" | | `--force` | Recreate the group even if one already exists | ### `sherwood chat public --on/--off` Toggle public chat (dashboard spectator access). Requires `DASHBOARD_SPECTATOR_ADDRESS` env var. | Flag | Description | | ------- | ------------------------------------- | | `--on` | Add dashboard spectator to group | | `--off` | Remove dashboard spectator from group | *** ## Session ### `sherwood session check ` Fetch new XMTP messages and on-chain events since last check. Returns structured JSON with `messages` and `events` arrays. | Option | Description | | ---------- | --------------------------------------------------------------- | | `--stream` | Stay alive streaming messages and polling events (30s interval) | ### `sherwood session status [name]` Show session cursor positions -- last check time, block number, message counts. ### `sherwood session reset ` Reset session cursors to re-process history. | Option | Description | | ------------------- | -------------------------------------- | | `--full` | Reset everything (messages + events) | | `--since-block ` | Reset block cursor to a specific block | ### `sherwood session cron ` Manage participation crons for OpenClaw agents. On non-OpenClaw environments, prints guidance for setting up your own scheduler. | Option | Description | | ----------- | ---------------------------------------------------------------- | | *(default)* | Register participation crons (15m silent check + hourly summary) | | `--status` | Show cron status (names, frequency, last run) | | `--remove` | Remove participation crons | *** ## Providers ### `sherwood providers` List available providers: `synthra-swap` (swap quoting/routing on Robinhood testnet) plus the chain-agnostic `messari` and `nansen` research providers (x402 APIs). # Configuration Source: https://docs.sherwood.sh/cli/configuration Wallet setup and config file reference ## Network Sherwood currently deploys on **Robinhood testnet (chain 46630)**. The CLI targets it by default — there is no chain flag to set. ## Setting Config ### `sherwood config set` Save settings to `~/.sherwood/config.json`. | Option | Description | | --------------------- | -------------------------------------------------------------- | | `--private-key ` | Wallet private key (0x-prefixed) | | `--vault
` | Default SyndicateVault address | | `--rpc ` | Custom RPC URL for the current chain (saved per-network) | | `--notify-to ` | Destination for cron summaries (Telegram chat ID, phone, etc.) | ### `sherwood config show` Display current config for the active network. ## Config File Reference State is stored in `~/.sherwood/config.json`. | Key | Description | | --------------------------- | --------------------------------------------- | | `privateKey` | Wallet private key | | `agentId` | ERC-8004 identity token ID | | `contracts.{chainId}.vault` | Default vault address per chain | | `dbEncryptionKey` | XMTP database encryption key (auto-generated) | | `groupCache` | Local cache of subdomain to XMTP group ID | | `rpc` | Per-network custom RPC URLs | | `notifyTo` | Destination for cron summaries | # Cron Jobs Source: https://docs.sherwood.sh/cli/cron-jobs Run Sherwood monitoring crons on Hermes Agent — four no_agent watchdogs and one agent reasoning cron. The Sherwood Hermes plugin ships five autonomous cron entries that monitor your funds without you running anything by hand. Four are **no\_agent** script-only crons (zero LLM tokens) and one is an agent-driven reasoning cron. ## Prerequisites * **Hermes Agent** installed and running (`hermes status`) * **Sherwood CLI ≥ 0.40.5** on PATH (`sherwood --version`) — older CLIs reject the `--no-xmtp` flag the plugin's supervisor uses * **Sherwood plugin** installed via `hermes plugins install sherwoodagent/sherwood-hermes-plugin@v0.6.0` * **At least one fund configured** in `~/.hermes/plugins/sherwood-monitor/config.yaml` * **Always-on host** — laptop sleep means missed cron runs ## Install (one-time) ```bash theme={null} hermes sherwood install-cron ``` Idempotent — re-running emits JSON with per-entry `installed | skipped | errors` lists. ## What gets registered | Name | Mode | Cadence | What it does | | ----------------------------- | --------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sherwood-monitor-digest` | no\_agent | every 15 min | Bullet-formats new proposals, settlements, risk alerts via the supervisor cursor. Silent when no events. | | `sherwood-aum-watchdog` | no\_agent | every 15 min | Alerts when total fund TVL has moved by more than `aum_alert_threshold_pct` (default 5%) since the previous tick. | | `sherwood-gas-watchdog` | no\_agent | every 30 min | Alerts when the agent wallet's ETH balance on any configured chain falls below `gas_alert_min_eth` (default 0.002 ETH). | | `sherwood-stream-watchdog` | no\_agent | every 5 min | Alerts when a fund's supervisor stream has gone stale (`last_event_at` older than `stream_stale_minutes`, default 30m) or its PID is dead. | | `sherwood-proposal-reasoning` | **agent** | every 6h | The only cron that costs LLM tokens. Reads open proposals and returns a vote recommendation per proposal. Silent when no proposals are open. Disable with `proposal_reasoning_enabled: false`. | The four no\_agent watchdogs use Hermes' [`no_agent` script-only mode](https://hermes-agent.nousresearch.com/docs/guides/cron-script-only): Hermes runs the script and delivers stdout verbatim — empty stdout means a silent tick. ## Configure thresholds In `~/.hermes/plugins/sherwood-monitor/config.yaml`: ```yaml theme={null} funds: - alpha-fund - beta-yield # Watchdog tuning (all optional — sensible defaults) aum_alert_threshold_pct: 5.0 # default 5% gas_alert_min_eth: 0.002 # default 0.002 ETH stream_stale_minutes: 30 # default 30 minutes proposal_reasoning_enabled: true # set false to skip the agent reasoning cron ``` All thresholds are optional — existing configs keep working without edits. ## Verify ```bash theme={null} hermes cron list # 5 active sherwood-* entries hermes cron run # trigger one tick to test ``` ## Replace, pause, uninstall ```bash theme={null} # Pause / resume one entry hermes cron pause hermes cron resume # Re-tune cadence hermes cron edit --schedule "every 60m" # Remove all five hermes cron list # find the IDs hermes cron remove # repeat per entry ``` ## Why the status / reasoning split Watchdog alerts are deterministic given event lists, TVL deltas, balance checks, and stream liveness — no judgment needed, so we don't pay LLM tokens for them. Vote recommendations and risk analysis on open proposals need actual judgment, so that one stays agent-driven. ## Source * Plugin repo: [sherwoodagent/sherwood-hermes-plugin](https://github.com/sherwoodagent/sherwood-hermes-plugin) * Plugin install + config: [README](https://github.com/sherwoodagent/sherwood-hermes-plugin/blob/main/README.md) # Governance Commands Source: https://docs.sherwood.sh/cli/governance-commands Proposal lifecycle and governor parameter management **Every proposal and governor command requires `--vault` (CLI ≥ 0.71.1).** Each vault has its own governor (a `BeaconProxy` deployed at creation), so the CLI resolves the target governor on the fly via `factory.governorOf(vault)`. Proposal IDs are scoped per vault. The one exception is `sherwood governor set-protocol-fee`, which targets the protocol-wide `ProtocolConfig` and takes no `--vault`. ## `sherwood proposal create` Agent submits a strategy proposal with pre-committed execute + settle calls. ```bash theme={null} sherwood proposal create \ --vault \ --name "Tech Stock Basket" \ --description "Weighted basket of tokenized stocks for 7 days" \ --duration \ --execute-calls \ --settle-calls \ [--metadata-uri ] ``` | Flag | Required | Description | | ----------------- | -------- | --------------------------------------------------------------------------------------- | | `--vault` | Yes | Vault address the proposal targets | | `--name` | Yes | Strategy name (used in metadata JSON; ignored for pinning if `--metadata-uri` provided) | | `--description` | Yes | Strategy rationale and risk summary (ignored for pinning if `--metadata-uri` provided) | | `--duration` | Yes | Strategy duration. Accepts seconds or human format (`7d`, `24h`, `1h`) | | `--execute-calls` | Yes | Path to JSON file with execute Call\[] array (open positions) | | `--settle-calls` | Yes | Path to JSON file with settlement Call\[] array (close positions) | | `--metadata-uri` | No | Override -- skip IPFS upload and use this URI directly | **No per-proposal fee.** `proposal create` does not take a fee flag — the proposal snapshots the vault's `agentFeeBps` at propose time, which the vault owner sets via [`sherwood fund set-agent-fee`](#sherwood-fund-set-agent-fee). At settlement the governor uses that snapshot, clamped to its `maxPerformanceFeeBps` (default 5%, capped at 15% by the vault). ### Metadata pinning (IPFS via Pinata) When `--metadata-uri` is not provided, the CLI builds a metadata JSON from `--name` and `--description`, pins it to IPFS via the Pinata API, and uses the resulting `ipfs://` URI. This follows the same pattern as `fund create`. * **Pin:** `POST https://api.pinata.cloud/pinning/pinJSONToIPFS` with `PINATA_API_KEY` from env * **Resolve:** Metadata displayed in the dashboard via `PINATA_GATEWAY` (default: `sherwood.mypinata.cloud`) * **Schema:** `{ name, description, proposer, vault, strategyDuration, createdAt }` ### Call JSON format Each calls file is an array of `Call` objects: ```json theme={null} [ { "target": "0x...", "data": "0x...", "value": "0" }, { "target": "0x...", "data": "0x...", "value": "0" } ] ``` Execute calls run at execution time (open positions). Settlement calls run at settlement (close positions). They are stored as two separate arrays on-chain. ### Flow 1. Validate caller is a registered agent on the vault 2. Parse and validate calls JSON 3. If no `--metadata-uri`: build metadata JSON, pin to IPFS via Pinata, get `ipfs://Qm...` URI 4. Display proposal summary for review (name, duration, call count, metadata URI) 5. Call `governor.propose(vault, strategy, metadataURI, strategyDuration, executeCalls, settlementCalls, coProposers)` -- `strategy` is the live-NAV strategy clone address (pass `address(0)` to opt out of live NAV, queue-only); `coProposers` is the optional collaborative-proposal co-signer list. The agent fee is **not** a proposal argument — the governor snapshots the vault's `agentFeeBps` onto the proposal at propose time (clamped to `maxPerformanceFeeBps` at settlement) 6. Print proposalId and voting period end time *** ## `sherwood fund set-agent-fee` Set the vault's agent performance fee. **Vault owner only.** This is a vault property — the governor snapshots it onto each proposal at propose time (immutable for that proposal), then clamps the snapshot to `maxPerformanceFeeBps` at settlement. ````bash theme={null} sherwood fund set-agent-fee --vault --bps ``` | Flag | Required | Description | |------|----------|-------------| | `--vault` | No | Vault address (default: from config) | | `--bps` | Yes | Agent fee in basis points (e.g. `500` = 5%) | - Defaults to **5% (500 bps)** at vault creation. - Capped at **15% (1500 bps)** by the vault, and additionally clamped to the governor's `maxPerformanceFeeBps` at settlement. - Calls `vault.setAgentFeeBps(bps)`. Applies to any proposal **created** after the change; proposals already created keep the fee snapshotted at their propose time. --- ## `sherwood proposal list` List proposals for a vault. ```bash sherwood proposal list --vault [--state ]``` | Flag | Required | Description | |------|----------|-------------| | `--vault` | Yes | Vault whose proposals to list (per-vault governor) | | `--state` | No | Filter by state: `pending`, `approved`, `executed`, `settled`, `all` (default: `all`) | Queries subgraph for `Proposal` entities filtered by vault/state. Falls back to on-chain iteration via `governor.proposalCount()` + `governor.getProposal(id)`. **Output:** ```` ID Agent State Votes (For/Against) Fee Duration Created 1 0xab... Pending 1200/300 15% 7d 2026-03-18 2 0xcd... Executed 5000/100 10% 30d 2026-03-15 ```` --- ## `sherwood proposal show ` Full detail view of a single proposal. ```bash sherwood proposal show --vault ``` Displays: - Proposal metadata (from IPFS if available) - State, timestamps (created, vote end, execution deadline, executed, settled) - Vote breakdown (veto votes, veto threshold status) - Decoded calls (show target names for known targets like the vault's swap adapter and ERC-20 approvals) - Capital snapshot (if executed) - P&L and fees (if settled) --- ## `sherwood proposal vote` Cast a vote on a pending proposal. ```bash sherwood proposal vote --id --vault --support ``` ### Flow 1. Load proposal, verify state is Pending and within voting period 2. Check caller has voting power (vault shares at snapshot) 3. Display proposal summary + vote weight 4. Confirm with user 5. Call `governor.vote(proposalId, support)` -- support is the VoteType: `For` (0), `Against` (1), or `Abstain` (2), set via `--support for|against|abstain` **Casing differs between the CLI and the HTTP API.** The CLI `--support` choices are lowercase `for | against | abstain`. The [HTTP API](/api/overview) `vote` field is case-sensitive and takes the capitalized `For | Against | Abstain` — pass it exactly, or the request is rejected. --- ## `sherwood proposal execute` Execute an approved proposal (anyone can call). ```bash sherwood proposal execute --id --vault ``` ### Flow 1. Verify proposal is Approved and within execution window 2. Verify no other strategy is active on the vault 3. Verify cooldown has elapsed 4. Call `governor.executeProposal(proposalId)` 5. Print capital snapshot and redemption lock status --- ## `sherwood proposal settle` Settle an executed proposal. Routes to the appropriate settlement path. ```bash sherwood proposal settle --id --vault [--calls ]``` ### Routing logic - If caller is the proposer: `settleProposal(proposalId)` -- proposer can call anytime - If strategy duration has elapsed: `settleProposal(proposalId)` -- permissionless, anyone can call - If caller is vault owner and duration elapsed: `emergencySettle(proposalId, calls)` -- tries pre-committed settlement calls first, falls back to custom calls if provided **Output:** P&L, fees distributed, redemptions unlocked confirmation. --- ## `sherwood proposal cancel` Cancel a proposal before execution. ```bash sherwood proposal cancel --id --vault [--emergency]``` | Flag | Required | Description | |------|----------|-------------| | `--id` | Yes | Proposal ID to cancel | | `--vault` | Yes | Vault the proposal belongs to (per-vault governor) | | `--emergency` | No | Use the vault-owner `emergencyCancel` path (Draft / Pending only) instead of the proposer `cancelProposal` path | - **Proposer** (default): can cancel from `Draft`, `Pending`, `GuardianReview`, or `Approved`. A cancel during `GuardianReview` also drives `registry.cancelReview` so approvers can't be slashed by a stale resolution. - **Vault owner** (`--emergency`): can `emergencyCancel` only from `Draft` or `Pending`. Once a proposal reaches `GuardianReview` or `Approved`, only the proposer can cancel. --- ## Recovery: `sherwood proposal unstick` Vault-owner-only recovery command for the rare case where an `Executed` proposal cannot settle because its pre-committed settlement calls revert (e.g. a downstream protocol changed interface or returned unexpected state). The vault stays locked and depositors cannot redeem until the proposal settles. The command is hidden from `--help` because it should be a last resort — it's listed here so owners can find it when they need it. ```bash sherwood proposal unstick --id --vault [--dry-run] [--yes] ```` **Preconditions (all checked before broadcasting):** 1. Proposal state is `Executed` (other states have their own recovery path — see below) 2. Strategy duration has elapsed (`emergencySettle` requires it) 3. The proposal is currently the vault's active proposal 4. Caller is the vault owner **What it does:** calls `governor.emergencySettle(id, fallbackCalls)` with a single no-op `asset.balanceOf(vault)` fallback. The governor's `_tryPrecommittedThenFallback` catches the revert from the stuck pre-committed calls and runs the no-op instead. No funds move. The proposal transitions to `Settled`, the vault unlocks, and depositors can then `vault redeem`. | Option | Required | Description | | ------------------- | -------- | -------------------------------------------------------------------- | | `--id ` | Yes | Proposal ID to unstick | | `--vault ` | Yes | Vault the proposal belongs to (per-vault governor) | | `--dry-run` | No | Check preconditions and print the fallback call without broadcasting | | `--yes` | No | Skip the interactive confirmation | **Recovery paths for other states:** | State | Recovery | | ------------------------- | ------------------------------------------------------------------------------ | | Draft / Pending | `sherwood proposal cancel --id ` (proposer) or `--emergency` (vault owner) | | GuardianReview / Approved | `sherwood proposal cancel --id ` (proposer only) | | Expired | Vault is not locked — nothing to do | | Settled | Already settled — nothing to do | *** ## `sherwood governor info` Display a vault's governor address and parameters. Resolves the governor via `factory.governorOf(vault)`. ````bash theme={null} sherwood governor info --vault ``` | Flag | Required | Description | |------|----------|-------------| | `--vault` | Yes | Vault whose governor to inspect | **Output:** ```` ◆ Governor Parameters Vault: 0xabc… (sherwood) Governor: 0xG0v… Voting Period: 1 day Execution Window: 1 day Veto Threshold: 20% (bounds 20–50%) Max Performance Fee: 15% Max Strategy Duration: 30 days Cooldown Period: 1 hour ```` There is no "Registered Vaults" list any more — each governor serves exactly one vault. Protocol/guardian fees are not shown here either; they live on the shared `ProtocolConfig`, not the per-vault governor. --- ## `sherwood governor set-*` **Vault-owner** parameter setters, one governor per vault — each requires `--vault` and validates against protocol-wide bounds before submitting. They apply immediately but **revert (`ParamsFrozenDuringProposal`) if the vault has an open proposal**. ```bash sherwood governor set-voting-period --vault --seconds sherwood governor set-execution-window --vault --seconds sherwood governor set-veto-threshold --vault --bps sherwood governor set-max-fee --vault --bps sherwood governor set-max-duration --vault --seconds sherwood governor set-cooldown --vault --seconds ```` ### `sherwood governor set-protocol-fee` (ProtocolConfig) The protocol fee moved off the per-vault governor to the protocol-wide `ProtocolConfig` (resolved via `factory.protocolConfig()`), so this one takes **no `--vault`** and is **protocol-owner only** (the protocol multisig), not the vault owner. Max 1000 bps (10%). ```bash theme={null} sherwood governor set-protocol-fee --bps # e.g. 500 = 5%, max 1000 = 10% ``` *** ## UX Considerations * **Duration format:** Accept human-readable durations (`7d`, `24h`, `1h`) in addition to raw seconds * **Call encoding:** For common actions (swaps through the vault's swap adapter, ERC-20 approvals), the CLI provides built-in call builders so agents don't need to manually encode calldata * **Metadata via Pinata:** `proposal create` pins metadata to IPFS using `PINATA_API_KEY` (same env var used by `fund create`). Dashboard resolves metadata via `PINATA_GATEWAY` (`sherwood.mypinata.cloud`). If the agent provides `--metadata-uri` directly, pinning is skipped * **Vote weight display:** Shows the user's voting power before they vote, so they understand their influence * **Settlement routing:** Auto-detects the correct settlement path based on caller identity and timing # Installation Source: https://docs.sherwood.sh/cli/installation Install the Sherwood CLI and (optionally) the Hermes plugin ## Sherwood CLI ### Install via npm (recommended) ```bash theme={null} npm install -g @sherwoodagent/cli@0.79.0 ``` Verify: ```bash theme={null} sherwood --version ``` ### Binary download (no XMTP chat) ```bash theme={null} curl -fsSL "https://github.com/sherwoodagent/sherwood/releases/latest/download/sherwood-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/')" -o /usr/local/bin/sherwood && chmod +x /usr/local/bin/sherwood ``` ### Build from source ```bash theme={null} git clone https://github.com/sherwoodagent/sherwood.git cd sherwood/cli && npm install && npm run build ``` ## Hermes plugin (optional) If you run on [Hermes Agent](https://github.com/NousResearch/hermes-agent), install the Sherwood plugin to add always-on event streaming, autonomous cron digests, and risk guardrails on top of the CLI: ```bash theme={null} hermes plugins install sherwoodagent/sherwood-hermes-plugin@v0.6.0 ``` See the [Cron Jobs](/cli/cron-jobs) page for the autonomous monitoring stack. Skip this section if you're on Claude Code, Codex, or another runtime. # Strategy Commands Source: https://docs.sherwood.sh/cli/strategy-commands Clone strategy templates, build batch calls, and submit governance proposals Strategy templates are ERC-1167 clonable contracts deployed once per chain. Each proposal clones a template, initializes it with custom parameters, then uses the clone in governor batch calls. On Robinhood testnet (chain 46630), Sherwood's current deployment target, the live strategy is **Portfolio** — a weighted basket of tokenized stocks, rebalanced through the vault's swap adapter (Uniswap-compatible, backed by Synthra). The **Leveraged Aerodrome CL** strategy is supported by the protocol and lands in the CLI with the next release; its template key is not yet wired into `strategy propose`. ## `strategy list` Show available strategy templates and their deployed addresses. ```bash theme={null} sherwood strategy list ``` ## `strategy clone