From fb75978c4600528dfa9d99fb1f147b27e9a00079 Mon Sep 17 00:00:00 2001 From: Yashovardhan Agrawal <21066442+yashovardhan@users.noreply.github.com> Date: Thu, 9 Jul 2026 20:10:58 +0400 Subject: [PATCH] Rewrite metamask-agent-wallet skill for weak-LLM execution (v6.0.0) Full template rewrite of SKILL.md and all references/ and workflows/, verified against @metamask/agentic-cli 4.0.1 (--help flag schemas + live read-only runs + compiled-source inspection): - One canonical syntax per command (flag form wherever both exist); removed phantom positionals (predict quote/place/markets get, wallet requests watch) - Required/optional flag tables with value formats; captured real output blocks with Capture -> placeholder lines; explicit confirm-before-executing checklists; per-file error/recovery tables - SKILL.md: placeholder legend, global-flags table, preflight checklist with real mm doctor output, explicit routing rows (added mm tx, price/token subcommands) - Split predict.md into predict-account/data/trade; market-data.md into price/token; renamed chain.md->chains.md, polling.md->wallet-requests.md; new concepts.md and aave.md - New scripts/encode_approve.py for exact-amount ERC-20 approvals - Fixed: QR login works on prod (COMING_SOON guard is dead code); --to-address rejected same-chain (INVALID_SWAP_PARAMS); perps --venue optional; --wallet-timeout + walletTimeoutSeconds documented; perps --dry-run/--yes coverage; transfer --token semantics; Aave ERC-20 vs native value branch Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 53 ++ README.md | 4 +- skills/metamask-agent-wallet/SKILL.md | 431 +++++------ .../metamask-agent-wallet/references/aave.md | 128 +++ .../metamask-agent-wallet/references/auth.md | 315 ++++---- .../metamask-agent-wallet/references/chain.md | 30 - .../references/chains.md | 58 ++ .../references/concepts.md | 115 +++ .../references/decode.md | 61 +- .../references/doctor.md | 74 +- .../references/errors.md | 281 +++---- .../references/market-data.md | 188 ----- .../metamask-agent-wallet/references/perps.md | 563 ++++++++------ .../references/polling.md | 52 -- .../references/predict-account.md | 354 +++++++++ .../references/predict-data.md | 330 ++++++++ .../references/predict-trade.md | 369 +++++++++ .../references/predict.md | 730 ------------------ .../metamask-agent-wallet/references/price.md | 178 +++++ .../references/signing.md | 143 +++- .../metamask-agent-wallet/references/swap.md | 240 ++++-- .../metamask-agent-wallet/references/token.md | 183 +++++ .../references/transaction.md | 106 ++- .../references/transfer.md | 76 +- .../references/tx-history.md | 113 ++- .../references/wallet-requests.md | 96 +++ .../references/wallet.md | 327 ++++---- .../metamask-agent-wallet/references/x402.md | 237 ++++-- .../scripts/encode_approve.py | 32 + .../workflows/aave-borrow.md | 104 +-- .../workflows/aave-collateral.md | 99 ++- .../workflows/aave-markets.md | 59 +- .../workflows/aave-positions.md | 81 +- .../workflows/aave-repay.md | 136 ++-- .../workflows/aave-supply.md | 120 ++- .../workflows/aave-withdraw.md | 98 +-- .../metamask-agent-wallet/workflows/bridge.md | 96 ++- .../metamask-agent-wallet/workflows/login.md | 62 +- .../workflows/market-data.md | 79 +- .../workflows/onboarding.md | 119 ++- .../workflows/perps-close-position.md | 70 +- .../workflows/perps-modify-position.md | 68 +- .../workflows/perps-open-position.md | 118 ++- .../workflows/predict-funding.md | 108 +-- .../workflows/predict-manage-orders.md | 78 +- .../workflows/predict-markets.md | 66 +- .../workflows/predict-place-order.md | 93 +-- .../workflows/predict-portfolio.md | 68 +- .../workflows/predict-setup.md | 82 +- .../metamask-agent-wallet/workflows/swap.md | 67 +- .../workflows/troubleshooting.md | 86 ++- .../workflows/x402-pay.md | 107 ++- 52 files changed, 4758 insertions(+), 3173 deletions(-) create mode 100644 skills/metamask-agent-wallet/references/aave.md delete mode 100644 skills/metamask-agent-wallet/references/chain.md create mode 100644 skills/metamask-agent-wallet/references/chains.md create mode 100644 skills/metamask-agent-wallet/references/concepts.md delete mode 100644 skills/metamask-agent-wallet/references/market-data.md delete mode 100644 skills/metamask-agent-wallet/references/polling.md create mode 100644 skills/metamask-agent-wallet/references/predict-account.md create mode 100644 skills/metamask-agent-wallet/references/predict-data.md create mode 100644 skills/metamask-agent-wallet/references/predict-trade.md delete mode 100644 skills/metamask-agent-wallet/references/predict.md create mode 100644 skills/metamask-agent-wallet/references/price.md create mode 100644 skills/metamask-agent-wallet/references/token.md create mode 100644 skills/metamask-agent-wallet/references/wallet-requests.md create mode 100644 skills/metamask-agent-wallet/scripts/encode_approve.py diff --git a/CHANGELOG.md b/CHANGELOG.md index ad8cea6..b872a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,59 @@ catch up if you are on an older skill version — apply the entries above yours The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and the skills follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [6.0.0] — targets CLI v4.0.1 + +### Changed (breaking) + +- **Full rewrite of `SKILL.md` and every file in `references/` and `workflows/`** to fixed, + weak-LLM-friendly templates: one canonical syntax per command (flag form wherever both + positional and flag forms exist), required/optional flag tables with value-format columns, + captured real output blocks with `Capture: field → ` lines, explicit + "Confirm before executing" field checklists, per-file error/recovery tables, and a + placeholder legend + global-flags table centralized in `SKILL.md`. Every documented flag was + verified against `mm --help` JSON on CLI v4.0.1. Incremental catch-up from ≤5.x + does not apply to this entry — re-read the whole skill. +- Split `references/predict.md` → `predict-account.md`, `predict-data.md`, `predict-trade.md`; + split `references/market-data.md` → `price.md`, `token.md`; renamed `references/chain.md` → + `chains.md` and `references/polling.md` → `wallet-requests.md`. + +### Added + +- `references/concepts.md` — shared concepts: wallet/trading modes, async job model + (`pollingId`, `--wait`, `intent`), secrets via `MM_PASSWORD`/`MM_MNEMONIC`, `$SKILL_DIR`, + CAIP-2/CAIP-19 construction, amount/decimals conversion, suspicious-payload checklist. +- `references/aave.md` — canonical home for the Aave V3 GraphQL machinery (endpoint, market + discovery, amount formats per operation, the three response types, approval security rule). +- `scripts/encode_approve.py` — deterministic ERC-20 `approve(address,uint256)` calldata for + exact-amount allowances (replaces the old hand-encoding instruction in the supply workflow). + +### Fixed + +- Removed phantom positional syntax: `predict quote`/`place`/`markets get` and + `wallet requests watch` are flag-only (`--token-id`, `--market`, `--polling-id`). +- `predict redeem`: exactly one of `` | `--all` (previously shown as both optional). +- `predict markets search` takes a positional query (`mm predict markets search `). +- Documented `--wallet-timeout` on all wallet-job commands and the `walletTimeoutSeconds` + config key; `MM_PASSWORD` env applies to every command that accepts `--password`. +- perps: `--venue` is optional (defaults to `hyperliquid`); `--dry-run`/`--yes` documented on + cancel/transfer/deposit/withdraw (the old "`--yes` has no effect" claim was false). +- `transfer --token`: ERC-20 transfers use the contract address; symbols only for native. +- QR login (`mm login qr`) works on all environments including production — the + `COMING_SOON`-on-prod claim in the onboarding workflow was stale (verified against CLI source). +- `--to-address` is rejected for same-chain swaps (`INVALID_SWAP_PARAMS`) — documented with the + verbatim error; `--to-address`/`--refuel` are cross-chain only. +- Aave supply: explicit ERC-20 (`"value":"0x0"`) vs native (hex from `amount_to_hex.py`) + branch; per-operation amount formats consolidated in `references/aave.md`. +- SKILL.md routing: added `mm tx` (lookup by hash); replaced the vague `mm price ...` / + `mm token ...` rows with one row per subcommand. + +### Notes + +- The CLI's own `--help` *usage strings* are unreliable in places (e.g. + `mm wallet trading-mode get --help` prints `mm mode get`, which does not exist, and + advertises `--chain-namespace`/`--address` flags that are rejected). The docs trust the + `flags` arrays and empirical runs instead; upstream bug to file against MetaMask/agentic. + ## [5.0.1] — targets CLI v4.0.1 ### Removed diff --git a/README.md b/README.md index 82d69d8..48196ab 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,14 @@ SKILLs for the MetaMask Agent CLI (`@metamask/agentic-cli` v4.0.1). These skills | Skill | Description | | --- | --- | -| [`metamask-agent-wallet`](./skills/metamask-agent-wallet/SKILL.md) | Full CLI skill that routes the agent to topic-specific reference docs (`references/`) for all MetaMask Agent CLI commands — auth, wallets, transfers, signing, swaps, bridges, perps, prediction markets, Aave V3, market data, x402 payments, and calldata decoding — plus multistep workflow templates (`workflows/`) for onboarding, swaps, bridges, perps, prediction markets, and Aave. | +| [`metamask-agent-wallet`](./skills/metamask-agent-wallet/SKILL.md) | Full CLI skill that routes the agent to topic-specific reference docs (`references/`) for all MetaMask Agent CLI commands — auth, wallets, transfers, signing, swaps, bridges, perps, prediction markets, Aave V3, market data, x402 payments, and calldata decoding — plus multistep workflow templates (`workflows/`) for onboarding, swaps, bridges, perps, prediction markets, and Aave. Every doc follows a fixed template (one canonical syntax per command, flag tables verified against `mm --help`, captured outputs, confirmation checklists) so that even small models can execute commands by string substitution. Runtime helper scripts: `amount_to_hex.py`, `encode_approve.py`, `x402_pay.py`. | ## Installation Install with [Vercel's Skills CLI](https://skills.sh): ```bash -npx skills add metaMask/agent-skills +npx skills add metamask/agent-skills ``` ## Changelog diff --git a/skills/metamask-agent-wallet/SKILL.md b/skills/metamask-agent-wallet/SKILL.md index 3aca389..54c4246 100644 --- a/skills/metamask-agent-wallet/SKILL.md +++ b/skills/metamask-agent-wallet/SKILL.md @@ -4,278 +4,229 @@ description: Use when the user asks anything about blockchain wallets, transacti license: MIT metadata: author: metamask - version: "5.0.1" + version: "6.0.0" cliVersion: "4.0.1" --- # MetaMask Agentic CLI Skill -This skill documents the `mm` CLI surface for MetaMask Agent Wallet authentication, wallet lifecycle, balance queries, token transfers, message and typed-data signing, raw transactions, chain discovery, market data, token discovery, perpetual futures trading, prediction market trading, token swaps, and cross-chain bridges. +This skill documents the `mm` CLI. The loop for every request is: +**route → read the reference → validate inputs → confirm with the user → execute**. -Use the routing table to select the relevant reference file. CLI behavior lives in `references/`. Repeatable operational patterns live in `workflows/`. +## How to use this skill -## Command Routing +1. Match the user's intent to a row in the Command Routing table below. +2. Read the listed reference file BEFORE constructing any command. +3. If the request is a multi-step pattern (a row in the Workflows table), read that workflow too. +4. Build the command by replacing placeholders per the legend below. Change nothing else. +5. For state-changing commands, show the user the fields listed in the reference's + "Confirm before executing" section and wait for approval, then execute with `--toon`. -Match the user's intent to a command and reference file, then read the reference before constructing a command. If intent spans multiple domains, load them sequentially in dependency order. +## Placeholder legend -| User Intent | Command | Reference | +In syntax lines, `` tokens are placeholders: replace the whole token, brackets +included, with a real value. Everything else is literal. Never copy a value that contains `...` +or `…`. Addresses are always the full `0x` + 40 hex characters. + +| Placeholder | Format | Example | +| --- | --- | --- | +| `
` | `^0x[0-9a-fA-F]{40}$` | `0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48` | +| ``, `` | positive decimal `^\d+\.?\d*$` | `0.5` | +| `` | positive integer | `1` (Ethereum), `137` (Polygon) | +| `` | `eip155:` | `eip155:1` | +| `` | see references/concepts.md | `eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48` | +| `` | symbol or `
` | `ETH`, `USDC` | +| `` | market symbol | `BTC` | +| `` | string from `mm swap quote` output | — | +| `` | string from a state-changing command's output | — | +| `` | Predict outcome token ID string | — | +| `` | Predict/perps order ID | — | +| `` | Predict market condition ID (`0x` + 64 hex) | — | +| `` | valid JSON, single-quoted in shell | `'{"to":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","value":"0x0","data":"0x095ea7b3"}'` | +| ``, `` | `^0x[0-9a-fA-F]+$` | — | +| `` | `^0x[0-9a-fA-F]{64}$` | — | +| `` | `https://` URL | — | +| `` | Unix timestamp in seconds (`date +%s`) | `1783600000` | +| `` | perps venue | `hyperliquid` | +| `` | `mainnet` or `testnet` | `mainnet` | +| `` | perps: `long`/`short`; predict: `buy`/`sell` | `long` | +| ``, `` | positive decimal; predict prices in `(0, 1]` | `0.65` | +| `` | predict: `GTC`, `GTD`, `FOK`, `FAK` | `GTC` | +| `` | free-text search string | `bitcoin` | +| `` | URL-style identifier from a listing | — | +| `` | pagination cursor from a previous response | — | +| `` | Aave pool contract, `^0x[0-9a-fA-F]{40}$` | — | + +A reference may define additional placeholders where it uses them; the same rules apply. + +## Global flags + +Valid on every command. They are deliberately NOT repeated in reference flag tables. + +| Flag | Short | Description | +| --- | --- | --- | +| `--format` | `-f` | Output format: `text`, `json`, or `toon` (default: `text` in TTY, `json` when piped) | +| `--json` | | Shorthand for `--format=json` | +| `--toon` | | Shorthand for `--format=toon` | +| `--verbose` | `-v` | Debug logs on stderr, for troubleshooting | + +Always use `--toon` unless the user explicitly requests another format. Commands that create +wallet jobs also accept `--wallet-timeout ` (max 600) — see references/concepts.md. + +## Preflight (run once per session, before the first mm command) + +1. Run `mm --version`. If the `major.minor` (first two numbers) differs from `cliVersion` in + this file's frontmatter, warn once: "Version mismatch: installed ``, skill pinned + to `4.0.1`. Update with `npm install -g @metamask/agentic-cli@latest`, then re-install skills + with `npx skills add metamask/agent-skills`." Then continue. +2. Run `mm doctor`. Real output shape: + +```json +{ + "ok": true, + "data": { + "cli": "4.0.1", + "env": "prod", + "authenticated": true, + "initialized": true, + "hints": [] + } +} +``` + +3. If `authenticated` is `false` → follow workflows/login.md. +4. If `initialized` is `false` → follow workflows/onboarding.md. +5. Re-run `mm doctor` after remediation. Do not run any other command until both are `true`. +6. Never use `mm init show` as the readiness check — it throws `NOT_INITIALIZED` on an + uninitialized project instead of reporting state. + +## Safety invariants + +These apply to every operation. + +1. **Secrets.** Never store, log, or display private keys, mnemonics, passwords, or auth + tokens. Secrets travel only via the `MM_PASSWORD` / `MM_MNEMONIC` environment variables — + never as `--password` or `--mnemonic` flags (references/concepts.md). +2. **Confirmation.** Before any state-changing command, show the user the exact fields listed + in that command's "Confirm before executing" section and wait for explicit approval. + +| Operation class | Rule | +| --- | --- | +| On-chain writes (transfer, send-transaction, swap/bridge execute, perps orders and fund moves, predict orders/deposit/withdraw/redeem, x402 pay, Aave) | Confirm the reference's field list first | +| Signing (sign-message, sign-typed-data) | Show the exact message/domain summary first | +| Cancel-all / redeem-all / `mm reset` | Confirm the exact destructive scope first | +| Read-only queries, auth, wallet management | No confirmation needed | + +3. **Input hygiene.** Validate every user-provided value against the placeholder legend and the + reference's "Value format" column. Reject values containing shell metacharacters + (`; | & $ \` >`). Wrap JSON payloads in single quotes. +4. **Unfamiliar calldata.** If a payload was not constructed by you, run + `mm decode --payload ` and confirm the decoded intent with the user before + signing or sending. Apply the suspicious-payload checklist in references/concepts.md. + +## Command routing + +Match intent → read the reference → construct the command. + +| User intent | Command | Reference | | --- | --- | --- | +| Check CLI + session health | `mm doctor` | [doctor.md](references/doctor.md) | | Check authentication status | `mm auth status` | [auth.md](references/auth.md) | -| Login in MetaMask Agentic CLI | `mm login` | [auth.md](references/auth.md) | -| Choose a wallet mode and set up policies | `mm init` | [auth.md](references/auth.md) | -| Show current init settings | `mm init show` | [auth.md](references/auth.md) | -| Sign in via QR code with MetaMask Mobile | `mm login qr` | [auth.md](references/auth.md) | -| Sign in via browser (Google or Email) | `mm login browser` | [auth.md](references/auth.md) | +| Sign in (browser: Google/email) | `mm login browser` | [auth.md](references/auth.md) | +| Sign in (QR with MetaMask Mobile) | `mm login qr` | [auth.md](references/auth.md) | | Sign out | `mm logout` | [auth.md](references/auth.md) | -| Reset CLI session | `mm reset` | [auth.md](references/auth.md) | -| Show CLI configuration | `mm config get` | [auth.md](references/auth.md) | -| Set CLI configuration | `mm config set` | [auth.md](references/auth.md) | -| Set BYOK mnemonic encryption password | `mm wallet password set` | [auth.md](references/auth.md) | -| Change BYOK mnemonic encryption password | `mm wallet password change` | [auth.md](references/auth.md) | -| Remove BYOK mnemonic encryption password | `mm wallet password remove` | [auth.md](references/auth.md) | -| Interpret raw CLI error codes | `AuthError`, `ValidationError`, `WALLET_ERROR` | [errors.md](references/errors.md) | -| Inspect CLI, skills, environment, and session health | `mm doctor` | [doctor.md](references/doctor.md) | -| Decode EVM calldata into a human-readable intent | `mm decode` | [decode.md](references/decode.md) | +| Wipe the local CLI session | `mm reset` | [auth.md](references/auth.md) | +| Set up wallet mode + trading mode | `mm init` | [auth.md](references/auth.md) | +| Show current init settings | `mm init show` | [auth.md](references/auth.md) | +| Show / set CLI configuration | `mm config get` / `mm config set` | [auth.md](references/auth.md) | +| Set / change / remove BYOK password | `mm wallet password set\|change\|remove` | [auth.md](references/auth.md) | | Create a wallet | `mm wallet create` | [wallet.md](references/wallet.md) | -| List all wallets | `mm wallet list` | [wallet.md](references/wallet.md) | +| List wallets | `mm wallet list` | [wallet.md](references/wallet.md) | | Switch active wallet | `mm wallet select` | [wallet.md](references/wallet.md) | -| Show active wallet details | `mm wallet show` | [wallet.md](references/wallet.md) | +| Show wallet details | `mm wallet show` | [wallet.md](references/wallet.md) | | Show active wallet address | `mm wallet address` | [wallet.md](references/wallet.md) | -| Check the active wallet balance | `mm wallet balance` | [wallet.md](references/wallet.md) | -| Show a QR code and address to fund the active wallet | `mm wallet add-fund` | [wallet.md](references/wallet.md) | -| Show current trading mode | `mm wallet trading-mode get` | [wallet.md](references/wallet.md) | -| Set trading mode (guard or beast) | `mm wallet trading-mode set` | [wallet.md](references/wallet.md) | -| View wallet policy | `mm wallet policy get` | [wallet.md](references/wallet.md) | -| Set wallet policy | `mm wallet policy set` | [wallet.md](references/wallet.md) | -| Show project policy template | `mm wallet policy template` | [wallet.md](references/wallet.md) | +| Check balances | `mm wallet balance` | [wallet.md](references/wallet.md) | +| Show funding QR + address | `mm wallet add-fund` | [wallet.md](references/wallet.md) | +| Show / set trading mode | `mm wallet trading-mode get\|set` | [wallet.md](references/wallet.md) | +| View / set / template wallet policy | `mm wallet policy get\|set\|template` | [wallet.md](references/wallet.md) | +| List pending wallet requests | `mm wallet requests list` | [wallet-requests.md](references/wallet-requests.md) | +| Watch a polling id | `mm wallet requests watch` | [wallet-requests.md](references/wallet-requests.md) | | Sign a plaintext message | `mm wallet sign-message` | [signing.md](references/signing.md) | | Sign EIP-712 typed data | `mm wallet sign-typed-data` | [signing.md](references/signing.md) | | Send a raw EVM transaction | `mm wallet send-transaction` | [transaction.md](references/transaction.md) | -| Transfer native tokens or ERC-20 tokens | `mm transfer` | [transfer.md](references/transfer.md) | -| List supported chains by the CLI | `mm chains list` | [chain.md](references/chain.md) | -| List pending wallet requests | `mm wallet requests list` | [polling.md](references/polling.md) | -| Watch a wallet polling id | `mm wallet requests watch` | [polling.md](references/polling.md) | -| Query spot or historical prices | `mm price ...` | [market-data.md](references/market-data.md) | -| Discover tokens, token networks, or token metadata | `mm token ...` | [market-data.md](references/market-data.md) | -| List perpetual markets | `mm perps markets` | [perps.md](references/perps.md) | -| Check perps account balance | `mm perps balance` | [perps.md](references/perps.md) | -| List open perpetual positions | `mm perps positions` | [perps.md](references/perps.md) | -| Get a quote for a perpetual order | `mm perps quote` | [perps.md](references/perps.md) | -| List resting perpetual orders | `mm perps orders` | [perps.md](references/perps.md) | -| Open a perpetual position | `mm perps open` | [perps.md](references/perps.md) | -| Close a perpetual position | `mm perps close` | [perps.md](references/perps.md) | -| Modify leverage, take-profit, or stop-loss | `mm perps modify` | [perps.md](references/perps.md) | -| Cancel a resting perps order | `mm perps cancel` | [perps.md](references/perps.md) | -| Deposit USDC into a perps venue | `mm perps deposit` | [perps.md](references/perps.md) | -| Withdraw USDC from a perps venue | `mm perps withdraw` | [perps.md](references/perps.md) | -| Transfer USDC between spot and perp accounts | `mm perps transfer` | [perps.md](references/perps.md) | -| List perpetual futures venues | `mm perps list-venues` | [perps.md](references/perps.md) | -| List available DEXs for a venue | `mm perps dexs` | [perps.md](references/perps.md) | -| Set Predict trading mode | `mm predict mode` | [predict.md](references/predict.md) | -| One-time Predict setup | `mm predict setup` | [predict.md](references/predict.md) | -| Create or refresh Predict credentials | `mm predict auth` | [predict.md](references/predict.md) | -| Repair Predict approvals | `mm predict approve` | [predict.md](references/predict.md) | -| Check Predict back-end status and account setup | `mm predict status` | [predict.md](references/predict.md) | -| Check if Polymarket is geoblocked for your IP | `mm predict geoblock` | [predict.md](references/predict.md) | -| List prediction markets | `mm predict markets list` | [predict.md](references/predict.md) | -| Search prediction markets | `mm predict markets search` | [predict.md](references/predict.md) | -| Inspect a prediction market | `mm predict markets get` | [predict.md](references/predict.md) | -| List Polymarket events | `mm predict events list` | [predict.md](references/predict.md) | -| Inspect a Polymarket event | `mm predict events get` | [predict.md](references/predict.md) | -| List Polymarket event series | `mm predict series list` | [predict.md](references/predict.md) | -| Inspect a Polymarket event series | `mm predict series get` | [predict.md](references/predict.md) | -| List Polymarket tags | `mm predict tags list` | [predict.md](references/predict.md) | -| Inspect a Polymarket tag | `mm predict tags get` | [predict.md](references/predict.md) | -| Preview a prediction order cost | `mm predict quote` | [predict.md](references/predict.md) | -| Place a prediction market order | `mm predict place` | [predict.md](references/predict.md) | -| Cancel prediction orders | `mm predict cancel` | [predict.md](references/predict.md) | -| View prediction market positions | `mm predict positions` | [predict.md](references/predict.md) | -| View open prediction orders | `mm predict orders` | [predict.md](references/predict.md) | -| Show full Predict portfolio snapshot | `mm predict portfolio` | [predict.md](references/predict.md) | -| List redeemable (winning) positions | `mm predict redeem list` | [predict.md](references/predict.md) | -| Redeem winning positions | `mm predict redeem` | [predict.md](references/predict.md) | -| Check Predict deposit wallet balance | `mm predict balance` | [predict.md](references/predict.md) | -| Fund Predict deposit wallet | `mm predict deposit` | [predict.md](references/predict.md) | -| Withdraw pUSD from Predict deposit wallet | `mm predict withdraw` | [predict.md](references/predict.md) | -| Fetch prediction order book | `mm predict book` | [predict.md](references/predict.md) | -| Watch a Predict job | `mm predict watch` | [predict.md](references/predict.md) | -| List recent transactions for the active wallet | `mm tx history` | [tx-history.md](references/tx-history.md) | +| Transfer native / ERC-20 tokens | `mm transfer` | [transfer.md](references/transfer.md) | +| List supported chains | `mm chains list` | [chains.md](references/chains.md) | +| Decode EVM calldata | `mm decode` | [decode.md](references/decode.md) | +| Look up a transaction by hash | `mm tx` | [tx-history.md](references/tx-history.md) | +| List recent transactions | `mm tx history` | [tx-history.md](references/tx-history.md) | +| Spot prices | `mm price spot` | [price.md](references/price.md) | +| Historical prices | `mm price history` | [price.md](references/price.md) | +| Supported price currencies / networks | `mm price currencies` / `mm price networks` | [price.md](references/price.md) | +| Token metadata by CAIP-19 | `mm token assets` | [token.md](references/token.md) | +| Popular / trending / top-gainer tokens | `mm token list popular\|trending\|top-gainer` | [token.md](references/token.md) | +| Search tokens by name or symbol | `mm token list search` | [token.md](references/token.md) | +| Token API networks | `mm token networks` | [token.md](references/token.md) | +| List perps venues / DEXs | `mm perps list-venues` / `mm perps dexs` | [perps.md](references/perps.md) | +| List perp markets | `mm perps markets` | [perps.md](references/perps.md) | +| Perps balance / positions / orders | `mm perps balance\|positions\|orders` | [perps.md](references/perps.md) | +| Quote a perp order | `mm perps quote` | [perps.md](references/perps.md) | +| Open / close / modify a position | `mm perps open\|close\|modify` | [perps.md](references/perps.md) | +| Cancel a perps order | `mm perps cancel` | [perps.md](references/perps.md) | +| Perps deposit / withdraw / transfer | `mm perps deposit\|withdraw\|transfer` | [perps.md](references/perps.md) | +| Predict mode / one-time setup | `mm predict mode` / `mm predict setup` | [predict-account.md](references/predict-account.md) | +| Predict credentials / approvals | `mm predict auth` / `mm predict approve` | [predict-account.md](references/predict-account.md) | +| Predict backend status / geoblock | `mm predict status` / `mm predict geoblock` | [predict-account.md](references/predict-account.md) | +| Predict wallet balance / deposit / withdraw | `mm predict balance\|deposit\|withdraw` | [predict-account.md](references/predict-account.md) | +| Browse / search prediction markets | `mm predict markets list\|search\|get` | [predict-data.md](references/predict-data.md) | +| Polymarket events / series / tags | `mm predict events\|series\|tags list\|get` | [predict-data.md](references/predict-data.md) | +| Fetch a Predict order book | `mm predict book` | [predict-data.md](references/predict-data.md) | +| Quote / place a prediction order | `mm predict quote` / `mm predict place` | [predict-trade.md](references/predict-trade.md) | +| Cancel prediction orders | `mm predict cancel` | [predict-trade.md](references/predict-trade.md) | +| Predict positions / orders / portfolio | `mm predict positions\|orders\|portfolio` | [predict-trade.md](references/predict-trade.md) | +| Redeem winning positions | `mm predict redeem` / `mm predict redeem list` | [predict-trade.md](references/predict-trade.md) | +| Watch a Predict job | `mm predict watch` | [predict-trade.md](references/predict-trade.md) | | Get a swap or bridge quote | `mm swap quote` | [swap.md](references/swap.md) | -| Execute a token swap or bridge | `mm swap execute` | [swap.md](references/swap.md) | -| Check swap or bridge status | `mm swap status` | [swap.md](references/swap.md) | -| Bridge tokens to another chain | `mm swap execute` | [swap.md](references/swap.md) | -| Pay an HTTP `402` / x402 paywalled request | `python3 scripts/x402_pay.py` | [x402.md](references/x402.md) | +| Execute a swap or bridge | `mm swap execute` | [swap.md](references/swap.md) | +| Check swap / bridge status | `mm swap status` | [swap.md](references/swap.md) | +| Aave V3 lend / borrow / positions | `mm wallet send-transaction` + Aave API | [aave.md](references/aave.md) | +| Pay an HTTP 402 (x402) paywall | `python3 "$SKILL_DIR/scripts/x402_pay.py"` | [x402.md](references/x402.md) | +| Interpret a CLI error code | — | [errors.md](references/errors.md) | +| Term you don't recognize | — | [concepts.md](references/concepts.md) | ## Workflows -CLI behavior lives in `references/`. Repeatable patterns live in `workflows/`. Load a workflow file when the user's request is a pattern, not a single command. +Load a workflow when the user's request is a multi-step pattern, not a single command. | Pattern | Workflow | | --- | --- | -| First time setup and onboarding | [onboarding.md](workflows/onboarding.md) | +| First-time setup and onboarding | [onboarding.md](workflows/onboarding.md) | | Login flow | [login.md](workflows/login.md) | | Troubleshooting decision tree | [troubleshooting.md](workflows/troubleshooting.md) | -| Swap quote-review-execute flow | [swap.md](workflows/swap.md) | -| Bridge quote-review-execute flow | [bridge.md](workflows/bridge.md) | -| Open a perpetual position flow | [perps-open-position.md](workflows/perps-open-position.md) | -| Close a perpetual position flow | [perps-close-position.md](workflows/perps-close-position.md) | -| Modify a perpetual position flow | [perps-modify-position.md](workflows/perps-modify-position.md) | -| Predict first-time setup and credentials | [predict-setup.md](workflows/predict-setup.md) | -| Deposit or withdraw pUSD from Predict wallet | [predict-funding.md](workflows/predict-funding.md) | -| Search and browse prediction markets | [predict-markets.md](workflows/predict-markets.md) | +| Same-chain swap (quote → confirm → execute) | [swap.md](workflows/swap.md) | +| Cross-chain bridge (quote → confirm → execute) | [bridge.md](workflows/bridge.md) | +| Open a perp position | [perps-open-position.md](workflows/perps-open-position.md) | +| Close a perp position | [perps-close-position.md](workflows/perps-close-position.md) | +| Modify a perp position | [perps-modify-position.md](workflows/perps-modify-position.md) | +| Predict first-time setup | [predict-setup.md](workflows/predict-setup.md) | +| Predict deposit / withdraw pUSD | [predict-funding.md](workflows/predict-funding.md) | +| Browse prediction markets | [predict-markets.md](workflows/predict-markets.md) | | Quote and place a prediction order | [predict-place-order.md](workflows/predict-place-order.md) | -| View or cancel Predict orders and positions | [predict-manage-orders.md](workflows/predict-manage-orders.md) | -| View Predict portfolio and redeem winnings | [predict-portfolio.md](workflows/predict-portfolio.md) | -| Token discovery, prices, and market data | [market-data.md](workflows/market-data.md) | +| View / cancel Predict orders and positions | [predict-manage-orders.md](workflows/predict-manage-orders.md) | +| Predict portfolio and redeem winnings | [predict-portfolio.md](workflows/predict-portfolio.md) | +| Token discovery, prices, market data | [market-data.md](workflows/market-data.md) | | Supply assets to Aave V3 | [aave-supply.md](workflows/aave-supply.md) | | Withdraw assets from Aave V3 | [aave-withdraw.md](workflows/aave-withdraw.md) | | Borrow from Aave V3 | [aave-borrow.md](workflows/aave-borrow.md) | | Repay Aave V3 debt | [aave-repay.md](workflows/aave-repay.md) | | Toggle Aave V3 collateral | [aave-collateral.md](workflows/aave-collateral.md) | -| Check Aave V3 positions and health factor | [aave-positions.md](workflows/aave-positions.md) | -| Discover Aave V3 tokens, rates, and liquidity | [aave-markets.md](workflows/aave-markets.md) | -| Pay an HTTP `402` (x402) paywalled request | [x402-pay.md](workflows/x402-pay.md) | - -## Global Flags - -Every `mm` command accepts these flags: - -| Flag | Short | Description | -| --- | --- | --- | -| `--format` | `-f` | Output format: `text`, `json`, or `toon` (defaults to `text` in TTY, `json` when piped) | -| `--json` | | Shorthand for `--format=json` | -| `--toon` | | Shorthand for `--format=toon` | -| `--verbose` | `-v` | Show debug logs on stderr. Use for troubleshooting | - -Always use `--toon` for command output unless the user explicitly requests a different format. - -## Preflight - -Run these checks before the first CLI operation in a session, in order. - -### 1. Version compatibility - -This skill is written for `@metamask/agentic-cli` **v4.0.1** (see `cliVersion` in the frontmatter). Check the installed version: - -```bash -mm --version -``` - -The installed version is the value after `@metamask/agentic-cli/` (e.g. `@metamask/agentic-cli/2.0.0 darwin-arm64 node-v22.18.0`). Compare its `major.minor` against the pinned `cliVersion`. Optionally check the latest published version (best-effort; skip silently on network failure): - -```bash -npm view @metamask/agentic-cli version -``` - -If the installed `major.minor` differs from the pinned `cliVersion`, or the installed version is behind the latest release, warn the user once and continue: - -> Version mismatch: installed CLI ``, this skill is pinned to `4.0.1`, latest release is ``. Command syntax in this skill may be inaccurate until they are aligned. Update the CLI with `npm install -g @metamask/agentic-cli@latest`, then re-install the skills with `npx skills add metaMask/agent-skills`. - -Run this check once per session. Do not block operations on it. - -### 2. Readiness gate (authentication + initialization) - -`mm doctor` is the single readiness check. Run it before the first CLI operation in a session: - -```bash -mm doctor -``` - -It reports an `authenticated` boolean, an `initialized` boolean, and a list of `hints`. **Do not run any other command until `mm doctor` reports both `authenticated: true` and `initialized: true`.** Authentication and initialization are independent gates: a session can be authenticated while the project has no wallet mode selected, in which case any command that needs a wallet aborts before running with `NOT_INITIALIZED` — "Project not initialized." (hint: Run `mm init` to set up wallet and trading modes.). - -A project counts as initialized only when a wallet mode is set — and, for `server-wallet`, a trading mode is set as well (`byok` needs only the wallet mode). Do not use `mm init show` as the check: it requires an initialized project and throws `NOT_INITIALIZED` on an uninitialized one rather than reporting state. - -Remediate, then **re-run `mm doctor` and confirm a clean result before doing anything else**: - -- `authenticated: false` → follow `workflows/login.md` (or `workflows/onboarding.md` for first-time setup) to run `mm login`. -- `authenticated: true` and `initialized: false` → follow `workflows/onboarding.md` to run `mm init` and select a wallet mode (and a trading mode for server-wallet). - -## Safety Rules - -These rules apply to every operation, regardless of which reference or workflow is active. - -### Input Validation - -Before constructing any command, validate all user-provided values: - -| Flag | Validation rule | -| --- | --- | -| `--to`, `--address` | Must match `^0x[0-9a-fA-F]{40}$` | -| `--amount` | Human-readable decimal (e.g. 0.5, 100). Must match `^\d+\.?\d*$`. Reject spaces, semicolons, pipes, backticks, or shell metacharacters | -| `--chain-id` | Must be a positive integer (`^\d+$`) | -| `--payload` (send-transaction) | Must be valid JSON. No unescaped shell metacharacters outside the JSON structure | -| `--payload` (decode) | Must be 0x-prefixed hex calldata, matching `^0x[0-9a-fA-F]+$` | -| `--token` | Must be a valid hex address or known symbol | -| `--leverage` | Must be a positive integer (`^\d+$`) | -| `--size` | Human-readable decimal (e.g. 0.01, 1). Must match `^\d+\.?\d*$` and be positive | -| `--venue` | Must be `hyperliquid` | -| `--side` (perps) | Must be `long` or `short` | -| `--order-id` | Must be a positive integer (`^\d+$`) | -| `--token-id` | Must be a non-empty outcome token ID string | -| `--price`, `--limit-price` | Must be a positive number in range `(0, 1]` | -| `--order-type` | Must be one of `GTC`, `GTD`, `FOK`, `FAK` | -| `--side` (predict) | Must be `buy` or `sell` | -| `--slippage` | Must be a number between 0 and 100 | -| `--from-chain`, `--to-chain` | Must be a positive integer EVM chain ID | -| `--to-address` | Must match `^0x[0-9a-fA-F]{40}$`. Only valid for cross-chain swaps (`--to-chain` differs from `--from-chain`); rejected for same-chain swaps | -| `--refuel` | Boolean flag (no value). Only meaningful for cross-chain swaps (`--to-chain` differs from `--from-chain`); no effect on same-chain swaps | -| `--password` | Must be a non-empty string. Never log, display, or store the value. | -| x402 `asset` | Must be a valid contract address on a network returned by `mm chains list`. The currency choice is the server's offer confirmed by the user; the script keeps no currency allowlist. | -| x402 `payTo` / authorization `to` | Must match `^0x[0-9a-fA-F]{40}$` and equal the recipient in the `402` | -| x402 `value` | Atomic-unit integer that exactly equals the offered amount (the `exact` scheme is not a maximum) | -| x402 resource URL | Must be `https://`. Reject a `402` reached via an unexpected cross-host redirect | - -Do not pass unvalidated user input into any command. - -### Confirmation Requirements - -| Operation type | Confirmation rule | -| --- | --- | -| Transfers | Always confirm recipient, amount, token, and chain before executing | -| Raw transactions | Always confirm transaction payload, chain, recipient, value, and calldata summary before executing | -| Message signing | Always show exact message and chain before signing | -| Typed-data signing | Always show domain, primary type, chain, verifying contract, and message summary before signing | -| Swaps / bridges | Always confirm from/to tokens, amount, source/destination chain, slippage, quoted output, recipient address (if `--to-address` is set), and the destination gas top-up (if `--refuel` is set) before executing | -| x402 payments | Always confirm asset, decimals-correct amount, network, `payTo`, and resource URL before signing the authorization. One payment attempt per resource, never auto-retry a payment. Autonomous auto-pay is not supported. | -| Perps trading | Always confirm symbol, side, size, leverage, venue, order type, and limit price if present before executing | -| Perps deposit/withdraw | Always confirm amount, asset, venue, network, and destination where applicable before executing | -| Predict trading | Always confirm token ID, side, size, price, order type, market, and outcome before executing | -| Predict deposit | Always confirm amount before executing | -| Predict withdraw | Always confirm amount and recipient (`--to` defaults to owner EOA) before executing | -| Predict redeem | Always confirm the target (condition ID or `--all`) before executing; `--all` redeems every winning position | -| Cancel-all operations | Always confirm scope and exact destructive effect before executing | -| Auth / wallet management | May execute without confirmation, except `reset` which requires explicit user confirmation | -| Read-only queries | May execute without confirmation | - -### Credential Safety - -- Never store, log, or display private keys, mnemonics, passwords, or auth tokens. -- Never pass `--password` or `--mnemonic` as inline flags. Always instruct the user to set the `MM_PASSWORD` and `MM_MNEMONIC` environment variables instead to avoid exposing secrets in shell history. - -### Suspicious Content Warnings - -Flag to the user before proceeding if a signing payload or transaction contains: - -- URLs or contract addresses the user did not provide -- `permit`, `approve`, `setApprovalForAll`, or allowance-like fields -- Unusually large values or unfamiliar contract interactions - -When raw calldata is unfamiliar or was not constructed by you, run `mm decode --payload <0x-calldata>` first and confirm the decoded intent with the user before signing or sending. See [decode.md](references/decode.md). - -## Async Model - -In both server-wallet and BYOK mode, signing and transaction commands go through a job-polling loop and return a `pollingId`. Handle this consistently: - -1. Prefer `--wait` to block until complete. -2. If not using `--wait`, inform the user of the `pollingId` and how to track it: - - `mm wallet requests list` - - `mm wallet requests watch --polling-id ` -3. In BYOK mode, the local key signs locally but the operation still produces a pending job and a `pollingId`. If the mnemonic is password-encrypted, the user must set `MM_PASSWORD` environment variable to unlock it for the operation. - -Transfers, swaps, perps, predict orders, and predict withdraws attach a human-readable `intent` summary to their wallet request (e.g. `Transfer 0.5 ETH to 0x...`, `Withdraw 10 pUSD to 0x...`). When surfacing a pending request from `wallet requests list` or `wallet requests watch`, show the `intent` summary so the user can confirm what they are approving. +| Aave V3 positions and health factor | [aave-positions.md](workflows/aave-positions.md) | +| Aave V3 markets, rates, liquidity | [aave-markets.md](workflows/aave-markets.md) | +| Pay an HTTP 402 (x402) request | [x402-pay.md](workflows/x402-pay.md) | -## Output Rules +## Output rules -- Route silently. Do not announce which reference you are loading. -- Surface errors from commands verbatim. Do not mask or reword them. -- If a command fails, check `mm --help` and guide from there. +1. Route silently — do not announce which reference you are loading. +2. Surface CLI errors verbatim; do not mask or reword them. +3. If a command fails unexpectedly, run `mm --help` and follow its `flags` list. + Trust the `flags` descriptions over the `usage` string — some usage strings are inaccurate. +4. Async model (`pollingId`, `--wait`, `intent`): references/concepts.md. diff --git a/skills/metamask-agent-wallet/references/aave.md b/skills/metamask-agent-wallet/references/aave.md new file mode 100644 index 0000000..cf4adad --- /dev/null +++ b/skills/metamask-agent-wallet/references/aave.md @@ -0,0 +1,128 @@ +# Aave V3 (GraphQL API + mm wallet send-transaction) + +The `mm` CLI has no Aave commands. Aave flows query the Aave V3 GraphQL API for a ready-made +transaction, then execute it with `mm wallet send-transaction`. This file is the shared +machinery; per-operation steps live in workflows/aave-supply.md, aave-withdraw.md, +aave-borrow.md, aave-repay.md, aave-collateral.md, aave-positions.md, aave-markets.md. + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- If the user did not name a chain, ask — do not guess. Chain IDs: `mm chains list`. +- Sender address comes from `mm wallet address --toon` (capture `address` → `
`). +- Asset symbols resolve to contract addresses with `mm token list search --query --chain ` (references/token.md). + +## Endpoint + +All queries are POSTs to `https://api.v3.aave.com/graphql`: + +```bash +curl -s -X POST https://api.v3.aave.com/graphql \ + -H 'Content-Type: application/json' \ + -d '{"query":""}' +``` + +## Market discovery (run first in every flow) + +```bash +curl -s -X POST https://api.v3.aave.com/graphql \ + -H 'Content-Type: application/json' \ + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address reserves { underlyingToken { symbol } } } }"}' +``` + +### Output + +```json +{"data":{"markets":[{"address":"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5", +"reserves":[{"underlyingToken":{"symbol":"USDC"}},{"underlyingToken":{"symbol":"WETH"}}, +{"underlyingToken":{"symbol":"cbBTC"}}]}]}} +``` + +Capture: `markets[].address` → ``. + +1. One market returned → use its `address` as ``. +2. Multiple markets returned → show the user each `address` with up to 5 of its reserve + symbols and ask which market to use. + +## Amount format per operation + +The GraphQL `amount` field format differs by operation. Use exactly: + +| Operation | `amount` value format | +| --- | --- | +| `supply` | `value: ""` (plain decimal string, e.g. `"0.5"`) | +| `borrow` | `value: ""` (plain decimal string) | +| `withdraw` | `value: { exact: "" }`, or `value: { max: true }` for the full balance | +| `repay` | `value: { exact: "" }`, or `value: { max: true }` for the full debt (not allowed with `onBehalfOf`) | +| `healthFactorPreview` | same format as the wrapped operation | + +Amounts are human-readable decimals; the API converts to atomic units. ERC-20 asset: +`amount: { erc20: { currency: "
", value: ... } }`. Native token (only where the +reserve accepts it): use `native` in place of `erc20` (no `currency` field). + +## Response types (supply / withdraw / borrow / repay) + +Every operation query returns one of three `__typename`s. Handle in order: + +1. `TransactionRequest` (`{to, from, data, value, chainId}`) → confirm with the user, then + execute it (see "Executing" below). +2. `ApprovalRequired` → an ERC-20 allowance is needed first. It contains `approval` + (a TransactionRequest) and `originalTransaction` (the operation itself). Apply the + approval security rule below, confirm with the user, send the approval, wait for it to + complete, then send `originalTransaction`. +3. `InsufficientBalanceError` (`{required, available}`) → show both amounts to the user and + stop. + +## Executing a returned transaction + +```bash +mm wallet send-transaction --chain-id --payload '{"to":"
","value":"","data":""}' --wait --intent "" --toon +``` + +`--payload` fields come from the API response, except `value`, which must be `0x`-prefixed hex: + +- ERC-20 operation (supply/withdraw/borrow/repay/approval of a token) → `"value":"0x0"`. +- Native-token supply → `"value":""` from: + +```bash +python3 "$SKILL_DIR/scripts/amount_to_hex.py" 0.5 18 +# -> 0x6f05b59d3b20000 +``` + +Always pass `--wait` and a human-readable `--intent`. Global flags and `--wallet-timeout` +apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set `MM_PASSWORD` +first (references/concepts.md). Async model and pollingId tracking: references/concepts.md. + +## Approval security rule + +The API's default `approval` transaction grants an UNLIMITED allowance (max uint256). + +1. Tell the user the API default is an unlimited approval. +2. Offer the exact-amount alternative — encode the calldata yourself: + +```bash +python3 "$SKILL_DIR/scripts/encode_approve.py" 0xA238Dd80C259a72e81d7e4664a9801593F98d1c5 100 6 +# -> 0x095ea7b3000000000000000000000000a238dd80c259a72e81d7e4664a9801593f98d1c50000000000000000000000000000000000000000000000000000000005f5e100 +``` + +Arguments: spender (``), amount, token decimals. Use the printed calldata as +`"data"` and the TOKEN CONTRACT address as `"to"` (`"value":"0x0"`). Exact-amount approvals +are consumed by the operation; a repeat operation needs a fresh approval. + +## Confirm before executing + +Show the user ALL of: operation, asset symbol + contract address, amount (or "full +balance"/"full debt"), chain, pool address, and — for approvals — the spender and whether +the allowance is unlimited or exact. Do not run until the user approves. + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `InsufficientBalanceError` (API) | Not enough tokens for the operation | Show `required` vs `available`; offer a swap (workflows/swap.md) or bridge (workflows/bridge.md) | +| GraphQL `errors[]` in response | Malformed query or unsupported market/asset | Re-check pool address, asset address, chain ID, and the amount format table above | +| Revert `0x6679996d` | Full withdrawal attempted with outstanding debt | Repay all debt first (workflows/aave-repay.md) | +| `WALLET_ERROR` | Insufficient gas at execution | `mm wallet balance --chain `; top up the native token | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/auth.md b/skills/metamask-agent-wallet/references/auth.md index 6126991..2fb177b 100644 --- a/skills/metamask-agent-wallet/references/auth.md +++ b/skills/metamask-agent-wallet/references/auth.md @@ -1,122 +1,92 @@ -# Authentication Commands +# mm auth / login / init / config -Use these commands to initialize wallet mode, sign in, inspect authentication status, and clear local session state. +Sign in and out, initialize wallet + trading mode, and manage CLI configuration and the BYOK password. -## `init` Command +## Prerequisites -Initialize the project by selecting wallet mode and trading mode. Requires an authenticated session. Run `mm login` first. +- `mm doctor` runs without auth — use it first (references/doctor.md). +- `mm login`, `mm logout`, `mm reset`, `mm config get|set` need no prior auth. `mm init` requires an authenticated session. +- Canonical login is always an explicit subcommand (`mm login browser`, `mm login qr`). Bare `mm login` opens a TTY-only method picker and fails without a TTY — never use it from a script or agent. +- Secrets travel only via `MM_MNEMONIC` (read ONLY by `mm init`) and `MM_PASSWORD` — never as flags (references/concepts.md). + +## mm auth status + +Show whether the CLI session is authenticated and how. Read-only. ### Syntax ```bash -mm init [--wallet ] [--mode ] [--mnemonic ] [--password ] +mm auth status ``` -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--wallet` | No | Wallet mode: `server-wallet` or `byok` | -| `--mode` | No | Trading mode: `guard` or `beast` | -| `--mnemonic` | No | BIP-39 mnemonic phrase for BYOK wallet. Never pass inline. Set `MM_MNEMONIC` env var instead. | -| `--password` | No | Password to encrypt the BYOK mnemonic at rest. Never pass inline. Set `MM_PASSWORD` env var instead. If omitted in interactive mode, the CLI prompts. If omitted in non-interactive mode, mnemonic is stored unencrypted. | +No non-global flags. Global flags apply — see SKILL.md § Global flags. -### Example +### Output -```bash -mm init -mm init --wallet server-wallet --mode beast -export MM_MNEMONIC="word1 word2 ..." -mm init --wallet byok --mode guard - -export MM_MNEMONIC="word1 word2 ..." -export MM_PASSWORD="mypassword" -mm init --wallet byok --mode guard +``` +ok: true +data: + authenticated: true + summary: + mode: session + signedInAs: BFr2FRheqx_PUMcyhj6… + method: Stored session ``` -### Note - -- In server-wallet mode, if the account already has a remote EVM wallet, `mm init` syncs it and loads the existing trading mode instead of prompting for a new trading mode or creating a wallet. Use `mm wallet policy get` to view the wallet policy. -- In BYOK mode, `mm init` registers the wallet server-side and prompts for trading mode (`guard` or `beast`). If a trading mode is already set server-side, it is loaded without prompting. The `--mode` flag skips the prompt in non-interactive/scripted use. - -## `init show` Command +## mm login browser -Display the current initialization settings (wallet mode, trading mode). Use `mm wallet policy get` to view the wallet policy separately. +Sign in via the browser (Google or Email — the user picks in the browser). State-changing (local session only; no wallet job). ### Syntax ```bash -mm init show +mm login browser [--no-wait] ``` -### Supported Flags +### Optional flags -This command does not support additional flags beyond output format options. +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--no-wait` | off | boolean flag | Print the sign-in URL and exit without waiting. Complete later with `mm login --token` (below). | +| `--timeout` | CLI default | integer seconds | Seconds to wait for the browser callback | -### Example - -```bash -mm init show -``` +Global flags apply — see SKILL.md § Global flags. -## `login` Command - -Sign in to the CLI. On a TTY, bare `mm login` shows a method picker (MetaMask Mobile QR or browser). QR is recommended but not auto-selected. `mm login browser` covers both Google and Email — the user picks interactively in the browser. - -### Syntax +### Examples ```bash -mm login [qr | browser] [--token ] [--timeout ] [--no-wait] +mm login browser --no-wait --toon ``` -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--token` | No | Pre-minted CLI token in `cliToken:cliRefreshToken` format [env: `MM_CLI_TOKEN`] | -| `--timeout` | No | Seconds to wait for QR or browser callback | -| `--no-wait` | No | Print the sign-in URL and exit without waiting (for non-interactive/CI use). Not supported with QR login. Complete later with `mm login --token` | - -### Example +If `--no-wait` was used, after the user finishes in the browser complete the session with the token they receive: ```bash -mm login browser --no-wait -mm login --token "cliToken:cliRefreshToken" +mm login --token --toon ``` -### Note +`--token` takes a pre-minted CLI token in `cliToken:cliRefreshToken` format (env: `MM_CLI_TOKEN`). Never log it. -- If already authenticated, the CLI returns `ALREADY_AUTHENTICATED`. Run `mm logout` first, then log in again. -- `mm login qr` (scan with MetaMask Mobile) is available on all environments, including production. -- Pairing codes tolerate `-` and whitespace separators (e.g. `608-225` is equivalent to `608225`). -- Use `mm login browser --no-wait` for non-interactive/CI flows. The command prints a sign-in URL; the user completes login in the browser (Google or Email). Bare `mm login --no-wait` fails without a TTY because no method is selected. -- `--no-wait` is not supported with QR login. Complete authentication later with `mm login --token`. -- After a successful login in server-wallet mode, the CLI automatically syncs existing wallets from the server. Run `mm wallet list` immediately — no need to re-run `mm init`. In BYOK mode, no sync occurs; run `mm init` to configure the wallet. +## mm login qr -## `auth status` Command - -Show the current authentication status. +Sign in by scanning a QR code with MetaMask Mobile. Works on ALL environments, including production. State-changing (local session only). Requires an interactive terminal to display the QR; `--no-wait` is NOT supported. ### Syntax ```bash -mm auth status [--toon] +mm login qr ``` -### Supported Flags - -This command does not support additional flags beyond output format options. +### Optional flags -### Example +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--timeout` | CLI default | integer seconds | Seconds to wait for the mobile pairing | -```bash -mm auth status -mm auth status --toon -``` +Global flags apply — see SKILL.md § Global flags. Pairing codes tolerate `-` and whitespace (`608-225` = `608225`). -## `logout` Command +## mm logout -Sign out and clear auth credentials plus local init state, wallet selection, and stored BYOK mnemonic. Prompts for confirmation before signing out. +Sign out: clears auth credentials plus local init state. State-changing (local session only). ### Syntax @@ -124,184 +94,169 @@ Sign out and clear auth credentials plus local init state, wallet selection, and mm logout [--yes] ``` -### Supported Flags +### Optional flags -| Name | Required | Description | -| --- | --- | --- | -| `--yes` | No | Skip the confirmation prompt (for non-interactive/scripted use) | +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--yes` | off | boolean flag | Skip the confirmation prompt (non-interactive use) | -### Example +Global flags apply — see SKILL.md § Global flags. + +### Confirm before executing + +Show the user: "Sign out and clear the local session (auth credentials and init state)?" Only after explicit approval, run: ```bash -mm logout -mm logout --yes +mm logout --yes --toon ``` -## `config get` Command +## mm reset -Show persisted CLI configuration. Does not require authentication. +Clear the local CLI session entirely (logout plus wipe saved credentials). Destructive — last-resort troubleshooting only (workflows/troubleshooting.md). ### Syntax ```bash -mm config get [env|verbose|format] +mm reset [--yes] ``` -### Supported Keys +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--yes` | off | boolean flag | Skip the confirmation prompt (non-interactive use) | -| Key | Description | -| --- | --- | -| `env` | Target API environment: `prod`, `dev`, or `uat` (defaults to `prod` when unset) | -| `verbose` | Whether verbose logging is persisted (`true` or `false`) | -| `format` | Default output format: `json`, `text`, or `toon` | +Global flags apply — see SKILL.md § Global flags. -Omit the key to return all values. +### Confirm before executing -### Example +Show the user the exact scope: "Reset wipes the entire local CLI session — you will need to log in and run `mm init` again." Require explicit approval (SKILL.md § Safety invariants). Only then run: ```bash -mm config get -mm config get env +mm reset --yes --toon ``` -## `config set` Command +## mm init -Persist a CLI configuration value in `~/.metamask/config.json`. Does not require authentication. +Initialize the project: choose wallet mode (`server-wallet` or `byok`) and trading mode (`guard` or `beast`). Requires an authenticated session. State-changing (local + server-side registration; no on-chain write). -### Syntax +Choose the sub-block by wallet mode. If the user has their own mnemonic → BYOK; otherwise → server-wallet (recommended). + +### Server-wallet ```bash -mm config set +mm init --wallet server-wallet --mode guard ``` -### Supported Keys - -| Key | Values | -| --- | --- | -| `env` | `prod`, `dev`, or `uat` | -| `verbose` | `true` or `false` | -| `format` | `json`, `text`, or `toon` | - -### Overrides - -Persisted values can be overridden per invocation without changing `~/.metamask/config.json`: +If the account already has a remote EVM wallet, `mm init` syncs it and reuses the existing trading mode instead of prompting or creating a new wallet. -| Key | Override | -| --- | --- | -| `env` | `MM_ENV` environment variable | -| `verbose` | `--verbose` / `-v` flag | -| `format` | `--format`, `--json`, `--toon`, etc. | - -### Example +### BYOK ```bash -mm config set env prod -mm config set env dev -mm config set env uat -mm config set format toon +export MM_MNEMONIC="word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12" +mm init --wallet byok --mode guard ``` -### Note +To encrypt the mnemonic at rest, also `export MM_PASSWORD` before running. Without it in non-interactive mode the mnemonic is stored unencrypted — offer `mm wallet password set` afterward. `MM_MNEMONIC` is read ONLY by `mm init`. -- Switch environments at any time with `mm config set env `. -- Non-prod sessions are stored in env-scoped files under `~/.metamask/` (e.g. `session.dev.json`, `session.uat.json`); prod uses `session.json`. +### Optional flags -## `reset` Command +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wallet` | interactive prompt | `server-wallet` or `byok` | Wallet mode | +| `--mode` | interactive prompt / server value | `guard` or `beast` | Trading mode (references/concepts.md § Trading modes) | -Clear the local CLI session entirely, including auth credentials, wallet state, mnemonic, swap quotes, and persisted config. Prompts for confirmation before resetting. +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). The CLI also accepts `--mnemonic`/`--password`; NEVER use them — set `MM_MNEMONIC`/`MM_PASSWORD` instead. -### Syntax +### Confirm before executing -```bash -mm reset [--yes] -``` +Show the user: wallet mode, trading mode, and (BYOK) whether the mnemonic will be password-encrypted. Wait for approval. -### Supported Flags +## mm init show -| Name | Required | Description | -| --- | --- | --- | -| `--yes` | No | Skip the confirmation prompt (for non-interactive/scripted use) | +Show current init settings (wallet mode, trading mode). Read-only. Throws `NOT_INITIALIZED` on an uninitialized project — never use it as a readiness check; use `mm doctor` (references/doctor.md). -### Example +### Syntax ```bash -mm reset -mm reset --yes +mm init show ``` -## `wallet password set` Command +No non-global flags. Global flags apply — see SKILL.md § Global flags. + +## mm config get -Set a password to encrypt the BYOK mnemonic at rest. Only available in BYOK mode when the mnemonic is currently unencrypted. +Show persisted CLI configuration (`~/.metamask/config.json`). Read-only. No auth required. ### Syntax ```bash -mm wallet password set [--new ] +mm config get [] ``` -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--new` | No | New password. If omitted, the CLI prompts interactively. | +`` is one of `env`, `verbose`, `format`, `walletTimeoutSeconds`. Omit it to show all values. No non-global flags. Global flags apply — see SKILL.md § Global flags. -### Example +### Examples ```bash -mm wallet password set -mm wallet password set --new "mypassword" +mm config get env --toon ``` -## `wallet password change` Command +## mm config set -Change the BYOK mnemonic encryption password. Only available when the mnemonic is currently encrypted. +Persist a CLI configuration value. State-changing (local file only). Positional-only — there are no key/value flags. ### Syntax ```bash -mm wallet password change [--current ] [--new ] +mm config set ``` -### Supported Flags - -| Name | Required | Description | +| Key | Values | Per-invocation override | | --- | --- | --- | -| `--current` | No | Current password. If omitted, the CLI prompts interactively. | -| `--new` | No | New password. If omitted, the CLI prompts interactively. | - -### Example - -```bash -mm wallet password change -mm wallet password change --current "oldpassword" --new "newpassword" -``` - -## `wallet password remove` Command +| `env` | `prod`, `dev`, `uat` | `MM_ENV` env var | +| `verbose` | `true`, `false` | `--verbose` | +| `format` | `text`, `json`, `toon` | `--format` / `--json` / `--toon` | +| `walletTimeoutSeconds` | integer ≤ 600 | `--wallet-timeout` | -Remove the BYOK mnemonic encryption password, storing the mnemonic as plaintext. Only available when the mnemonic is currently encrypted. +Global flags apply — see SKILL.md § Global flags. Non-prod sessions live in env-scoped files under `~/.metamask/` (`session.dev.json`, `session.uat.json`); prod uses `session.json`. -### Syntax +### Examples ```bash -mm wallet password remove [--current ] +mm config set walletTimeoutSeconds 300 --toon ``` -### Supported Flags +## mm wallet password set | change | remove -| Name | Required | Description | -| --- | --- | --- | -| `--current` | No | Current password. If omitted, the CLI prompts interactively. | +Manage the password encrypting the BYOK mnemonic at rest. State-changing (local file only). ALWAYS run these in an interactive TTY and let the CLI prompt — never pass `--new` or `--current` inline (they exist but would leak the secret into shell history). -### Example +If the mnemonic is unencrypted → `set`. If already encrypted → `change` or `remove`. + +### Syntax ```bash +mm wallet password set +mm wallet password change mm wallet password remove -mm wallet password remove --current "mypassword" ``` -## Wallet Modes +Global flags apply — see SKILL.md § Global flags. After encryption, every signing command needs `MM_PASSWORD` set (references/concepts.md). -| Mode | Behavior | -| --- | --- | -| `server-wallet` | Keys hosted by MetaMask infrastructure. Signing and transaction operations return async job handles with a `pollingId`. | -| `byok` | Bring your own local mnemonic. Keys are held locally and signing is done on-device, but operations still go through a job-polling loop and return a `pollingId`. If the mnemonic is encrypted with a password, the CLI requires `MM_PASSWORD` to unlock before any operation that needs the private key. | +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `ALREADY_AUTHENTICATED` | `mm login` while a valid session exists | Run `mm logout` first, then log in again | +| `AUTH_FAILED` / `TOKEN_INVALID` | Sign-in or token verification failed | Retry `mm login browser`; check the token was pasted whole | +| `PAIRING_TIMEOUT` / `PAIRING_EXPIRED` / `MWP_TIMEOUT` / `MWP_CANCELLED` | QR pairing timed out or was cancelled on mobile | Re-run `mm login qr` and scan promptly | +| `NO_TTY` | Bare `mm login`, or a password prompt, without a terminal | Use `mm login browser --no-wait`; run password commands in a TTY | +| `NOT_INITIALIZED` | `mm init show` (or another command) before `mm init` | Follow workflows/onboarding.md | +| `INVALID_MNEMONIC` | Bad BIP-39 phrase in `MM_MNEMONIC` | Ask the user to re-check the phrase; never echo it | +| `INVALID_CONFIG_KEY` / `INVALID_CONFIG_VALUE` | Unknown config key or bad value | Use only the keys/values in the `mm config set` table | +| `ALREADY_ENCRYPTED` | `password set` on an encrypted mnemonic | Use `mm wallet password change` | +| `NOT_ENCRYPTED` | `password change`/`remove` on an unencrypted mnemonic | Use `mm wallet password set` | +| `WRONG_PASSWORD` | Wrong current password | Re-prompt the user interactively | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/chain.md b/skills/metamask-agent-wallet/references/chain.md deleted file mode 100644 index a09e4a6..0000000 --- a/skills/metamask-agent-wallet/references/chain.md +++ /dev/null @@ -1,30 +0,0 @@ -# Chain Commands - -Use `chains` commands to discover supported blockchain networks. - -## `chains list` Command - -List all supported EVM blockchain networks (EIP-155). - -### Syntax - -```bash -mm chains list [--toon] -``` - -### Supported Flags - -This command does not support additional flags beyond output format options. - -### Example - -```bash -mm chains list -mm chains list --toon -``` - -## Supported Namespaces - -| Namespace | Notes | -| --- | --- | -| `eip155` | Major EVM chains, such as Ethereum, Polygon, Arbitrum, Optimism, and BSC | diff --git a/skills/metamask-agent-wallet/references/chains.md b/skills/metamask-agent-wallet/references/chains.md new file mode 100644 index 0000000..c544d6c --- /dev/null +++ b/skills/metamask-agent-wallet/references/chains.md @@ -0,0 +1,58 @@ +# mm chains + +Discover the blockchain networks the CLI supports and their chain IDs. + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Only the `eip155` (EVM) namespace is currently listed: Ethereum, Polygon, BSC, Avalanche, + Optimism, Celo, Arbitrum, Base, Linea, plus their common testnets. + +## mm chains list + +List all supported blockchain networks across all namespaces. Read-only. No flags beyond +global flags. + +### Syntax + +```bash +mm chains list +``` + +Global flags apply — see SKILL.md § Global flags. + +### Output + +``` +ok: true +data: + chains[17]{key,chainNamespace,caip2,chainId,name,selected}: + ethereum,eip155,"eip155:1",1,Ethereum,false + polygon,eip155,"eip155:137",137,Polygon,false + bsc,eip155,"eip155:56",56,Binance Smart Chain (BSC),false + avalanche,eip155,"eip155:43114",43114,Avalanche,false + optimism,eip155,"eip155:10",10,Optimism,false + arbitrum,eip155,"eip155:42161",42161,Arbitrum One,false + base,eip155,"eip155:8453",8453,Base,false + linea,eip155,"eip155:59144",59144,Linea,false + sepolia,eip155,"eip155:11155111",11155111,Sepolia Test Network,false + arbitrum-sepolia,eip155,"eip155:421614",421614,Arbitrum Sepolia,false + base-sepolia,eip155,"eip155:84532",84532,Base Sepolia,false +``` + +Capture: `chainId` → use as ``; `caip2` → use as `` in other commands. + +### Examples + +```bash +mm chains list --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `NETWORK_UNREACHABLE` | No network connectivity | Check the connection, retry | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/concepts.md b/skills/metamask-agent-wallet/references/concepts.md new file mode 100644 index 0000000..6c6c62c --- /dev/null +++ b/skills/metamask-agent-wallet/references/concepts.md @@ -0,0 +1,115 @@ +# Shared concepts + +Definitions used by every reference and workflow in this skill. Load this file when a term +below is unclear. + +## Wallet modes + +Set once per project with `mm init` (see references/auth.md). + +| Mode | Meaning | +| --- | --- | +| `server-wallet` | Keys hosted by MetaMask infrastructure. Signing returns an async job with a `pollingId`. | +| `byok` | Bring your own local mnemonic. Keys held locally, signing on-device, but operations still return a `pollingId`. If the mnemonic is password-encrypted, set `MM_PASSWORD` before any signing operation. | + +## Trading modes + +Set with `mm init --mode ` or `mm wallet trading-mode set `. + +| Mode | Meaning | +| --- | --- | +| `guard` | Enforces outflow/whitelist policies and blocks malicious transactions. | +| `beast` | Skips policy checks but still blocks malicious transactions. | + +## Async job model (`pollingId`) + +Every state-changing command (transfer, send-transaction, sign, swap execute, perps trading, +predict orders/deposits/withdraws) creates a wallet job. + +1. With `--wait`: the command blocks until the job completes. Prefer this. +2. Without `--wait`: the command returns immediately with `{"pollingId": "..."}`. Track it: + +```bash +mm wallet requests list +mm wallet requests watch --polling-id +``` + +3. Jobs carry a human-readable `intent` string (e.g. `Transfer 0.5 ETH to 0x1234...`). Always + show the `intent` to the user when surfacing a pending request. +4. `--wallet-timeout ` (max 600) sets how long the CLI waits per wallet job + (MFA/signing). Persistent default: `mm config set walletTimeoutSeconds `. + +## Secrets (`MM_PASSWORD`, `MM_MNEMONIC`) + +Never pass secrets as command-line flags and never print, log, or store them. Set environment +variables instead: + +```bash +export MM_MNEMONIC="word1 word2 word3 ..." # read only by: mm init (BYOK setup) +export MM_PASSWORD="the-password" # read by every command that accepts --password (BYOK unlock) +``` + +`--password` unlocks an already-encrypted BYOK mnemonic. To set, change, or remove that +password, use `mm wallet password set | change | remove` (interactive prompt — do not pass +`--new`/`--current` inline). + +## `$SKILL_DIR` + +The directory containing this skill's `SKILL.md`. Resolve it once, then call helper scripts +with absolute paths: + +```bash +python3 "$SKILL_DIR/scripts/amount_to_hex.py" 0.5 18 +``` + +## TTY vs non-interactive + +In an interactive terminal the CLI may show pickers and confirmation prompts. In scripts and +agent harnesses there is no TTY, so: + +1. Always pass the subcommand and flags explicitly (e.g. `mm login browser`, never bare `mm login`). +2. `mm logout` and `mm reset` prompt for confirmation; pass `--yes` only after the user + explicitly approved. +3. Output defaults to JSON when piped, text in a TTY. Pass `--toon` explicitly. + +## CAIP identifiers + +Some price/token commands take CAIP IDs. Build them by string substitution: + +| Kind | Pattern | Example | +| --- | --- | --- | +| CAIP-2 network | `eip155:` | `eip155:1` (Ethereum), `eip155:137` (Polygon) | +| CAIP-19 native asset | `eip155:/slip44:` | `eip155:1/slip44:60` (ETH), `eip155:137/slip44:966` (POL) | +| CAIP-19 ERC-20 asset | `eip155:/erc20:
` | `eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48` (USDC on Ethereum) | + +Discover valid networks with `mm price networks` or `mm token networks`; chain IDs with +`mm chains list`. + +## Amounts and decimals + +CLI `--amount` flags take human-readable decimals (`0.5`, `100`) — never wei. When a raw +transaction payload needs an atomic-unit hex `value` (e.g. Aave native supplies), convert +mechanically: + +```bash +python3 "$SKILL_DIR/scripts/amount_to_hex.py" +# example: python3 "$SKILL_DIR/scripts/amount_to_hex.py" 0.5 18 -> 0x6f05b59d3b20000 +``` + +Unix timestamps (e.g. `mm price history --from/--to`, `mm predict place --expiration`): + +```bash +date +%s +``` + +## Suspicious payload checklist + +Before signing or sending anything you did not construct yourself, flag to the user if the +payload contains any of: + +1. URLs or contract addresses the user did not provide. +2. `permit`, `approve`, `setApprovalForAll`, or allowance-like fields. +3. Unusually large values or unfamiliar contract interactions. + +For unfamiliar calldata, run `mm decode --payload ` first and confirm the decoded +intent with the user (references/decode.md). diff --git a/skills/metamask-agent-wallet/references/decode.md b/skills/metamask-agent-wallet/references/decode.md index 5a36084..717b497 100644 --- a/skills/metamask-agent-wallet/references/decode.md +++ b/skills/metamask-agent-wallet/references/decode.md @@ -1,38 +1,63 @@ -# Decode Commands +# mm decode -Use `decode` to turn raw EVM calldata into a human-readable intent before signing or sending a transaction. Requires authentication and a completed `init`. +Turn raw EVM calldata into a human-readable intent before signing or sending. Run this on any +calldata you did not construct yourself (SKILL.md § Safety invariants). -## `decode` Command +## Prerequisites -Decode hex-encoded EVM calldata into its function name, parameters, and a plain-language summary. +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). + +## mm decode + +Decode hex calldata into function name, parameters, and a plain-language `intent`. Read-only. ### Syntax ```bash -mm decode --payload <0x-calldata> [--toon] +mm decode --payload ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--payload` | Yes | Hex-encoded EVM calldata to decode (e.g. `0x095ea7b3...`). | +| `--payload` | `^0x[0-9a-fA-F]+$` | Hex-encoded EVM calldata to decode | + +### Optional flags + +None beyond global flags. + +Global flags apply — see SKILL.md § Global flags. ### Output -| Field | Description | -| --- | --- | -| `functionName` | Decoded function name, when the selector is recognized | -| `params` | Array of decoded parameters, each with `name` and `value` | -| `intent` | Plain-language summary of the call (e.g. `Call approve(spender: 0x..., amount: ...)`) | +``` +ok: true +data: + functionName: transfer + params[2]{name,type,value}: + param0,address,0x742d35Cc6634C0532925a3b844Bc454e4438f44e + param1,uint256,"1000000" + intent: "Call transfer(param0: 0x742d35Cc6634C0532925a3b844Bc454e4438f44e, param1: 1000000)" +``` + +Capture: `intent` → show to the user verbatim when confirming a transaction or signature. -### Example +### Examples ```bash -mm decode --payload 0x095ea7b3000000000000000000000000... --toon +# ERC-20 transfer(to, amount) calldata — 1 USDC (6 decimals) to 0x742d… +mm decode --payload 0xa9059cbb000000000000000000000000742d35cc6634c0532925a3b844bc454e4438f44e00000000000000000000000000000000000000000000000000000000000f4240 --toon ``` -## Notes +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `INVALID_DATA` | Payload is not valid hex calldata | Re-check the `0x` prefix and hex characters | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | + +If the selector is not recognized, `intent` falls back to `Call unknown function`. Treat +unrecognized calldata as higher risk and warn the user before proceeding. -- Use this before `mm wallet send-transaction` whenever the calldata is unfamiliar or was not constructed by you, to confirm what the transaction actually does. -- If the selector is not recognized, `intent` falls back to `Call unknown function`. Treat unrecognized calldata as higher risk and warn the user before proceeding. +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/doctor.md b/skills/metamask-agent-wallet/references/doctor.md index 32443b1..715de3e 100644 --- a/skills/metamask-agent-wallet/references/doctor.md +++ b/skills/metamask-agent-wallet/references/doctor.md @@ -1,8 +1,14 @@ -# Doctor command +# mm doctor -Use `mm doctor` to inspect CLI version, AI skills, environment, and session health. This command does not require authentication or initialization. +One-shot health check: CLI version, environment, authentication, initialization, and installed MetaMask AI skills. Requires neither auth nor init — it is always the first command to run. -## `doctor` command +## Prerequisites + +- None. `mm doctor` works on a fresh, logged-out install. + +## mm doctor + +Inspect CLI, skills, environment, and session health. Read-only. ### Syntax @@ -10,37 +16,57 @@ Use `mm doctor` to inspect CLI version, AI skills, environment, and session heal mm doctor ``` -### Supported flags - -This command does not support additional flags beyond output format options. +No non-global flags. Global flags apply — see SKILL.md § Global flags. ### Output -| Field | Type | Description | -| --- | --- | --- | -| `cli` | string | Installed CLI version | -| `env` | string | Current environment (`prod`, `dev`, or `uat`) | -| `authenticated` | boolean | Whether the CLI session is valid | -| `initialized` | boolean | Whether you have run `mm init` (wallet mode and trading mode are set for server wallets) | -| `recommendedSkills` | object | Installed MetaMask AI skill status for `metamask-agent-wallet` and `metamask-agent-workflows` | -| `compatible` | boolean or null | Whether the installed CLI version is compatible with the installed skills. `null` if no skills are detected | -| `hints` | string[] | Actionable guidance, for example missing skills, auth issues, init needed, or version mismatch | +``` +ok: true +data: + cli: 4.0.1 + env: prod + authenticated: true + initialized: true + recommendedSkills: + "metamask-agent-wallet": + found: false + name: metamask-agent-wallet + "metamask-agent-workflows": + found: false + name: metamask-agent-workflows + compatible: null + hints[1]: No MetaMask AI skills found. Install with `npx skills add metamask/agent-skills`. +``` -### Skill detection +| Field | Meaning | +| --- | --- | +| `cli` | Installed CLI version | +| `env` | Active environment: `prod`, `dev`, or `uat` | +| `authenticated` | Session is valid. `false` → workflows/login.md | +| `initialized` | `mm init` has been completed. `false` → workflows/onboarding.md | +| `recommendedSkills` | Detected MetaMask AI skills (global lock file, falling back to the project directory) | +| `compatible` | CLI `major.minor` matches the installed skill's pinned `cliVersion`; `null` when no skills detected | +| `hints` | Actionable next steps (missing skills, auth needed, init needed, version mismatch) | -`mm doctor` detects installed skills from the global skills lock file (`~/.agents/.skill-lock.json` or `$XDG_STATE_HOME/skills/.skill-lock.json`). It parses `SKILL.md` frontmatter for the skill `version` and `cliVersion` metadata, then checks the CLI `major.minor` against the skill `cliVersion` requirement. +### Gates and readiness -As of CLI v4.0.1, `mm doctor` also detects **project-local** MetaMask AI skills: when the global skill lock file exists but contains no MetaMask entries, the command falls back to scanning the current project for installed `metamask-agent-wallet` / `metamask-agent-workflows` skills so locally-installed skills are still reported. +1. If `authenticated: false` → every wallet/trading command will fail with an auth error. Fix first (workflows/login.md). +2. If `initialized: false` → wallet operations fail with `NOT_INITIALIZED`. Fix second (workflows/onboarding.md). +3. Only when BOTH are `true` and no blocking `hints` remain is the session ready. +4. Follow any `hints` verbatim — they are the CLI's own remediation guidance. +5. NEVER use `mm init show` as a readiness check: it throws `NOT_INITIALIZED` on an uninitialized project instead of reporting state. `mm auth status` reports only authentication, not initialization. -### Example +### Examples ```bash -mm doctor mm doctor --toon ``` -### Notes +### Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `mm: command not found` (shell) | CLI not installed or not on `PATH` | `npm install -g @metamask/agentic-cli@latest`, then re-run | +| `NETWORK_UNREACHABLE` | No network to backend | Check connectivity; retry | -- Use as the first step in troubleshooting to check if CLI, auth, init, and skills are healthy. -- Run after a CLI upgrade to verify skill compatibility. -- Use in CI or scripting to confirm environment and session state. +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/errors.md b/skills/metamask-agent-wallet/references/errors.md index 16426a7..f704b31 100644 --- a/skills/metamask-agent-wallet/references/errors.md +++ b/skills/metamask-agent-wallet/references/errors.md @@ -1,164 +1,117 @@ -# Error Codes - -This reference lists error codes the CLI actually emits. SDK-only or remapped codes are noted where relevant. Workflows for diagnosing failures live in `../workflows/troubleshooting.md`. - -## Auth Errors - -| Code | Meaning | -| --- | --- | -| `ALREADY_AUTHENTICATED` | Valid session already exists; run `mm logout` before logging in again | -| `AUTH_FAILED` | Authentication failed (includes missing refresh token cases) | -| `AUTH_ERROR` | Generic authentication error (includes missing auth token cases) | -| `TOKEN_INVALID` | Invalid CLI token, token pair, or project ID | -| `TOKEN_REFRESH_FAILED` | Failed to refresh token | -| `PAIRING_TIMEOUT` | Login pairing timed out | -| `PAIRING_EXPIRED` | Pairing session expired | -| `INVALID_OTP` | Invalid one-time password | -| `MWP_TIMEOUT` | Mobile Wallet Protocol timeout | -| `MWP_CANCELLED` | Mobile Wallet Protocol cancelled (pairing aborted) | -| `LOGOUT_FAILED` | Logout operation failed (includes token revoke failures) | - -## Validation Errors - -| Code | Meaning | -| --- | --- | -| `MISSING_FLAG` | Required flag is missing in headless mode | -| `MISSING_INPUT` | Required input is missing | -| `MISSING_CHAIN` | Chain value is missing | -| `MISSING_CHAIN_ID` | Chain ID is missing | -| `INVALID_CHAIN` | Chain value is invalid | -| `MISSING_TO` | Recipient address is missing | -| `INVALID_TO` | Recipient address is invalid | -| `INVALID_DATA` | Transaction data is invalid | -| `INVALID_INPUT` | Invalid user input | -| `INVALID_QUANTITY` | EVM quantity is invalid | -| `INVALID_LIMIT` | Invalid limit value | -| `INVALID_INTERVAL` | Invalid time interval | -| `INVALID_TIMESTAMP` | Invalid timestamp | -| `INVALID_ASSET_ID` | Invalid asset identifier | -| `MISSING_ASSET_IDS` | Missing asset IDs | -| `MISSING_ASSET_TYPE` | Missing asset type | -| `MISSING_QUERY` | Missing search query | -| `MISSING_WALLET_REF` | Missing wallet reference | -| `MISSING_TRANSACTION_PAYLOAD` | Transaction payload is missing | -| `INVALID_TRANSACTION_PAYLOAD` | Transaction payload is invalid | -| `MISSING_TYPED_DATA` | EIP-712 typed data payload is missing | -| `INVALID_TYPED_DATA` | EIP-712 typed data payload is invalid | -| `CHAIN_ID_MISMATCH` | Typed-data domain chain ID differs from `--chain-id` | -| `INVALID_MNEMONIC` | BYOK mnemonic is invalid | - -## Wallet Errors - -| Code | Meaning | -| --- | --- | -| `MISSING_MNEMONIC` | BYOK wallet mode is missing a mnemonic | -| `MNEMONIC_LOCKED` | Mnemonic unlock failed after maximum attempts | -| `WRONG_PASSWORD` | Current password is incorrect | -| `ALREADY_ENCRYPTED` | Mnemonic is already password-encrypted (use `wallet password change` instead) | -| `NOT_ENCRYPTED` | Mnemonic is not encrypted (use `wallet password set` instead) | -| `PASSWORD_MISMATCH` | Password confirmation does not match | -| `EMPTY_PASSWORD` | Empty password provided | -| `WALLET_NOT_FOUND` | Wallet not found | -| `WALLET_ERROR` | Wallet provider or wallet operation error (includes on-chain reverts and network failures from wallet paths) | -| `WALLET_METADATA` | Wallet metadata error | -| `WRONG_NAMESPACE` | Wrong namespace for wallet | -| `UNSUPPORTED_NAMESPACE` | Unsupported wallet namespace | -| `NO_AUTH_TOKEN` | Missing authentication token for wallet operations | -| `NO_PROJECT_ID` | Project ID not configured for wallet | -| `MISSING_PROJECT_ID` | Project ID is not configured | -| `INVALID_TRADING_MODE` | Invalid trading mode; use `guard` or `beast` | -| `ALREADY_SET_TRADING_MODE` | Trading mode is already set to the requested value | - -## Command Errors - -| Code | Meaning | -| --- | --- | -| `ABORTED` | Operation aborted by user | -| `NOT_INITIALIZED` | Project not initialized. Run `mm init` | -| `NO_MNEMONIC` | Mnemonic not stored | -| `NO_TTY` | No TTY available for interactive prompts | -| `MISSING_ID` | Missing ID parameter | -| `MISSING_QUOTE_ID` | Missing quote ID | -| `MISSING_SWAP_PARAMS` | Missing swap parameters | -| `COMING_SOON` | Feature not yet available (e.g. `mm login qr` on production) | -| `INVALID_CONFIG_KEY` | Unknown config key passed to `mm config get` or `mm config set` | -| `INVALID_CONFIG_VALUE` | Invalid value for a config key (e.g. env not in `prod|dev|uat`) | - -## Swap & Bridge Errors - -| Code | Meaning | -| --- | --- | -| `NO_QUOTES` | No swap or bridge quotes available | -| `BRIDGE_API_ERROR` | Bridge API error | -| `TOKEN_NOT_FOUND` | Token not found | -| `INVALID_SWAP_PARAMS` | Invalid swap parameters | -| `NATIVE_ASSET_UNSUPPORTED` | Native asset not supported for this swap route | -| `QUOTE_PERSIST_FAILED` | Failed to persist quote | -| `QUOTE_NOT_FOUND` | Quote not found | -| `EXECUTE_FAILED` | Swap execution failed | -| `NO_TRADE_DATA` | No trade data available | -| `STATUS_UNAVAILABLE` | Swap status unavailable | -| `SWAP_ERROR` | Generic swap error | - -## Perps Errors - -| Code | Meaning | -| --- | --- | -| `UNSUPPORTED_VENUE` | Unsupported perpetual venue | -| `UNSUPPORTED_NETWORK` | Unsupported network for perps | -| `UNSUPPORTED_ROUTE` | Unsupported deposit or withdraw route | -| `UNSUPPORTED_ASSET` | Unsupported asset | -| `UNSUPPORTED_SOURCE_CHAIN` | Unsupported source chain for perps deposit | -| `INVALID_SYMBOL` | Unknown perpetual market symbol | -| `INVALID_AMOUNT` | Invalid amount | -| `INVALID_SIZE` | Invalid position size | -| `INVALID_LEVERAGE` | Invalid leverage value | -| `INVALID_PRICE` | Invalid price | -| `INVALID_SLIPPAGE` | Invalid slippage value | -| `INVALID_ADDRESS` | Invalid address | -| `INSUFFICIENT_BALANCE` | Insufficient balance | -| `POSITION_NOT_FOUND` | Position not found | -| `QUOTE_FAILED` | Quote generation failed | -| `ORDER_REJECTED` | Order rejected | -| `CANCEL_FAILED` | Order cancellation failed | -| `SIGNING_FAILED` | Signing operation failed | -| `WITHDRAW_FAILED` | Withdrawal failed | -| `DEPOSIT_FAILED` | Deposit failed | -| `HYPERLIQUID_ERROR` | Hyperliquid protocol error | -| `PERPS_ERROR` | Generic perpetuals error | - -## Predict Errors - -| Code | Meaning | -| --- | --- | -| `PREDICT_SETUP_REQUIRED` | Predict setup required before operation | -| `PREDICT_AUTH_REQUIRED` | Predict authentication required | -| `PREDICT_AUTH_INVALID` | Predict credentials invalid or incomplete | -| `PREDICT_RELAYER_CONFIG_REQUIRED` | Relayer configuration required | -| `PREDICT_INVALID_DEPOSIT_AMOUNT` | Invalid deposit amount | -| `PREDICT_WITHDRAW_ZERO` | Withdraw amount must be greater than zero | -| `PREDICT_WITHDRAW_INSUFFICIENT_BALANCE` | Withdraw amount exceeds deposit wallet pUSD balance | -| `PREDICT_FUNDING_CHAIN_UNSUPPORTED` | Funding chain not supported | -| `PREDICT_INSUFFICIENT_BALANCE` | Insufficient Predict balance | -| `PREDICT_INSUFFICIENT_ALLOWANCE` | Insufficient Predict allowance | -| `PREDICT_INSUFFICIENT_FUNDING_BALANCE` | Insufficient funding balance for Predict deposit | -| `PREDICT_CANCEL_TARGET_REQUIRED` | Cancel target not specified | -| `PREDICT_WALLET_STATE_REQUIRED` | Wallet state required for Predict | -| `PREDICT_METHOD_UNAVAILABLE` | Predict method not available | -| `PREDICT_DEPOSIT_FAILED` | Predict deposit failed | -| `PREDICT_ERROR` | Generic Predict error | -| `PREDICT_GEOBLOCKED` | Polymarket is not available in your region; Predict features cannot be used from this location. Emitted by `mm predict setup` (region guard) and surfaced by `mm predict geoblock` | -| `UNSUPPORTED_PREDICT_CHAIN` | Predict chain not supported | - -## Transaction History Errors - -| Code | Meaning | -| --- | --- | -| `NO_HISTORY_WALLETS` | No EVM wallets found in roster for transaction history | - -## Network & Filesystem Errors - -| Code | Meaning | -| --- | --- | -| `NETWORK_UNREACHABLE` | Network unreachable | -| `RESET_FAILED` | Failed to reset CLI session | +# Error codes (master list) + +Every error code the CLI emits, with recovery. Per-command tables in the other reference files +are scoped subsets; this file is the single master list. Diagnosis flow: workflows/troubleshooting.md. +Always surface the CLI's own `message` and `hint` verbatim before explaining. + +## Auth + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `ALREADY_AUTHENTICATED` | Valid session already exists | `mm logout`, then log in again | +| `AUTH_FAILED` | Authentication failed (incl. missing refresh token) | Re-run `mm login browser` or `mm login qr` | +| `AUTH_ERROR` | Generic auth error (incl. missing auth token) | `mm auth status`; if not authenticated, workflows/login.md | +| `TOKEN_INVALID` | Invalid CLI token, token pair, or project ID | Re-run login; paste the full `cliToken:cliRefreshToken` | +| `TOKEN_REFRESH_FAILED` | Failed to refresh token | Re-run login (workflows/login.md) | +| `PAIRING_TIMEOUT` / `PAIRING_EXPIRED` | QR/login pairing timed out or expired | Re-run `mm login qr`; scan promptly | +| `INVALID_OTP` | Invalid one-time password | Re-enter the code; separators `-`/space are tolerated | +| `MWP_TIMEOUT` / `MWP_CANCELLED` | Mobile Wallet Protocol timed out or was cancelled | Re-run `mm login qr`; approve on the phone | +| `LOGOUT_FAILED` | Logout failed (incl. token revoke failure) | Retry `mm logout`; last resort `mm reset` after user approval | + +## Validation + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `MISSING_FLAG` / `MISSING_INPUT` | Required flag/input absent in headless mode | Re-read the command's Required flags table; add the flag | +| `MISSING_CHAIN` / `MISSING_CHAIN_ID` / `INVALID_CHAIN` | Chain absent or invalid | `mm chains list --toon`; pass a valid `--chain-id` | +| `MISSING_TO` / `INVALID_TO` | Recipient absent or malformed | Ask the user for the full `0x` + 40-hex address | +| `INVALID_DATA` / `INVALID_QUANTITY` / `INVALID_INPUT` | Malformed transaction data / EVM quantity / input | Re-validate against the reference's Value format column | +| `INVALID_LIMIT` | Limit out of range (e.g. `mm tx history --limit`: 1-500) | Follow the CLI hint; pass an in-range integer | +| `INVALID_INTERVAL` / `INVALID_TIMESTAMP` | Bad time interval or timestamp | Use Unix seconds (`date +%s`); see references/price.md | +| `INVALID_ASSET_ID` / `MISSING_ASSET_IDS` / `MISSING_ASSET_TYPE` | CAIP asset ID absent or malformed | Build per references/concepts.md § CAIP identifiers | +| `MISSING_QUERY` | Search query absent | Pass the query (e.g. `--query` for token search) | +| `MISSING_WALLET_REF` | Wallet reference absent | Pass `--id`, `--address`, or `--name` (references/wallet.md) | +| `MISSING_TRANSACTION_PAYLOAD` / `INVALID_TRANSACTION_PAYLOAD` | Tx payload absent or invalid JSON | Single-quote the JSON; see references/transaction.md | +| `MISSING_TYPED_DATA` / `INVALID_TYPED_DATA` | EIP-712 payload absent or invalid | See references/signing.md | +| `CHAIN_ID_MISMATCH` | Typed-data `domain.chainId` ≠ `--chain-id` | Align both to the same chain ID | +| `INVALID_MNEMONIC` | BYOK mnemonic invalid | Re-check `MM_MNEMONIC`; never echo it | + +## Wallet + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `MISSING_MNEMONIC` / `NO_MNEMONIC` | BYOK mode without a stored mnemonic | Re-run `mm init` with `MM_MNEMONIC` set (references/auth.md) | +| `MNEMONIC_LOCKED` | Unlock failed after max attempts | Set the correct `MM_PASSWORD` env var; retry | +| `WRONG_PASSWORD` | Wrong current password | Set the correct `MM_PASSWORD`; for password commands, re-prompt interactively | +| `ALREADY_ENCRYPTED` | Mnemonic already encrypted | Use `mm wallet password change` | +| `NOT_ENCRYPTED` | Mnemonic not encrypted | Use `mm wallet password set` | +| `PASSWORD_MISMATCH` / `EMPTY_PASSWORD` | Confirmation mismatch or empty password | Re-run the password command in a TTY | +| `WALLET_NOT_FOUND` | Wallet not found | `mm wallet list --toon`; select an existing wallet | +| `WALLET_ERROR` | Wallet/provider error (incl. reverts, insufficient funds, network failures) | `mm wallet balance --toon`; check funds/gas; retry | +| `WALLET_METADATA` | Wallet metadata error | `mm wallet show --toon`; retry | +| `WRONG_NAMESPACE` / `UNSUPPORTED_NAMESPACE` | Bad wallet namespace | Use a supported `--chain-namespace` (references/wallet.md) | +| `NO_AUTH_TOKEN` / `NO_PROJECT_ID` / `MISSING_PROJECT_ID` | Session missing token or project ID | `mm doctor`; re-login (workflows/login.md) | +| `INVALID_TRADING_MODE` | Trading mode not `guard`/`beast` | `mm wallet trading-mode set guard` or `beast` | +| `ALREADY_SET_TRADING_MODE` | Mode already set to that value | Nothing to do; inform the user | + +## Command / session + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `ABORTED` | User aborted at a prompt | Nothing to do; confirm and retry if intended | +| `NOT_INITIALIZED` | `mm init` not run | workflows/onboarding.md | +| `NO_TTY` | Interactive prompt without a terminal | Pass explicit subcommand/flags; run password prompts in a TTY | +| `MISSING_ID` / `MISSING_QUOTE_ID` / `MISSING_SWAP_PARAMS` | Required ID or swap params absent | Capture the ID from the previous command's output; re-run | +| `COMING_SOON` | Feature not available in this environment | Use an alternative method or environment | +| `INVALID_CONFIG_KEY` / `INVALID_CONFIG_VALUE` | Bad `mm config` key or value | Keys: `env`,`verbose`,`format`,`walletTimeoutSeconds` (references/auth.md) | +| `RESET_FAILED` | Session reset failed | Retry `mm reset`; check `~/.metamask/` permissions | +| `NETWORK_UNREACHABLE` | Network unreachable | Check connectivity; retry | + +## Swap & bridge + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `NO_QUOTES` | No route for pair/amount | Try another amount/pair; verify the token via `mm token list search` | +| `BRIDGE_API_ERROR` / `SWAP_ERROR` | Backend swap/bridge error | Retry; if persistent, re-quote | +| `TOKEN_NOT_FOUND` | Token unknown on that chain | `mm token list search --query --chain ` | +| `INVALID_SWAP_PARAMS` | Invalid parameter combination (e.g. `--to-address` on a same-chain swap) | Follow the CLI hint; see references/swap.md | +| `NATIVE_ASSET_UNSUPPORTED` | Native asset unsupported on this route | Use the wrapped token or a different route | +| `QUOTE_PERSIST_FAILED` / `QUOTE_NOT_FOUND` | Quote not saved or expired | Re-run `mm swap quote`; execute promptly by `--quote-id` | +| `EXECUTE_FAILED` / `NO_TRADE_DATA` | Execution failed / no trade data | `mm swap status --quote-id `; re-quote if terminal | +| `STATUS_UNAVAILABLE` | Status not yet available | Wait and re-run `mm swap status` | + +## Perps + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `UNSUPPORTED_VENUE` / `UNSUPPORTED_NETWORK` / `UNSUPPORTED_ROUTE` / `UNSUPPORTED_ASSET` / `UNSUPPORTED_SOURCE_CHAIN` | Unsupported venue/network/route/asset/chain | `mm perps list-venues --toon`; use supported values (references/perps.md) | +| `INVALID_SYMBOL` | Unknown market symbol | `mm perps markets --toon`; pick a listed symbol | +| `INVALID_AMOUNT` / `INVALID_SIZE` / `INVALID_LEVERAGE` / `INVALID_PRICE` / `INVALID_SLIPPAGE` / `INVALID_ADDRESS` | Malformed numeric/address input | Re-validate against references/perps.md flag tables | +| `INSUFFICIENT_BALANCE` | Not enough margin/balance | `mm perps balance --toon`; offer `mm perps deposit` | +| `POSITION_NOT_FOUND` | No such position | `mm perps positions --toon` | +| `QUOTE_FAILED` / `ORDER_REJECTED` / `CANCEL_FAILED` | Quote/order/cancel rejected | Surface the message; re-quote and retry with user approval | +| `SIGNING_FAILED` | Signing failed | BYOK: set `MM_PASSWORD`; check `mm wallet requests list` | +| `DEPOSIT_FAILED` / `WITHDRAW_FAILED` | Fund move failed | Check balances on both sides; retry | +| `HYPERLIQUID_ERROR` / `PERPS_ERROR` | Venue/generic perps error | Surface verbatim; retry once | + +## Predict + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `PREDICT_SETUP_REQUIRED` | One-time setup not done | workflows/predict-setup.md | +| `PREDICT_AUTH_REQUIRED` / `PREDICT_AUTH_INVALID` | Predict credentials missing/invalid | `mm predict auth --refresh` (references/predict-account.md) | +| `PREDICT_RELAYER_CONFIG_REQUIRED` | Relayer config required | Re-run `mm predict setup` | +| `PREDICT_INVALID_DEPOSIT_AMOUNT` / `PREDICT_WITHDRAW_ZERO` | Bad deposit/withdraw amount | Ask the user for a positive amount | +| `PREDICT_WITHDRAW_INSUFFICIENT_BALANCE` / `PREDICT_INSUFFICIENT_BALANCE` / `PREDICT_INSUFFICIENT_FUNDING_BALANCE` | Balance too low | `mm predict balance --toon`; offer a deposit (workflows/predict-funding.md) | +| `PREDICT_INSUFFICIENT_ALLOWANCE` | Allowance too low | `mm predict approve` (references/predict-account.md) | +| `PREDICT_FUNDING_CHAIN_UNSUPPORTED` / `UNSUPPORTED_PREDICT_CHAIN` | Chain unsupported for Predict | Use the supported funding chain (references/predict-account.md) | +| `PREDICT_CANCEL_TARGET_REQUIRED` | No cancel target given | Pass `--order-id`, `--market`, `--asset`, or `--all` | +| `PREDICT_WALLET_STATE_REQUIRED` / `PREDICT_METHOD_UNAVAILABLE` | Wallet state missing / method unavailable | `mm predict status --toon`; re-run setup if hinted | +| `PREDICT_DEPOSIT_FAILED` / `PREDICT_ERROR` | Deposit/generic Predict failure | Surface verbatim; check `mm predict status` | +| `PREDICT_GEOBLOCKED` | Region not supported by Polymarket | Confirm with `mm predict geoblock`; Predict is unusable from this location | + +## History + +| Code | Meaning | Recovery | +| --- | --- | --- | +| `NO_HISTORY_WALLETS` | No EVM wallets in roster | `mm wallet list --toon`; create/select a wallet first | diff --git a/skills/metamask-agent-wallet/references/market-data.md b/skills/metamask-agent-wallet/references/market-data.md deleted file mode 100644 index ef83b4e..0000000 --- a/skills/metamask-agent-wallet/references/market-data.md +++ /dev/null @@ -1,188 +0,0 @@ -# Market Data Commands - -Use `price` and `token` commands for read-only token metadata, token discovery, and price data. - -## `price spot` Command - -Fetch spot prices for one or more CAIP-19 assets. - -### Syntax - -```bash -mm price spot --asset-ids [--vs ] [--market-data] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--asset-ids` | Yes | Comma-separated CAIP-19 asset IDs | -| `--vs` | No | Quote currency; defaults to `usd` | -| `--market-data` | No | Include market cap, supply, and change percent | - -### Example - -```bash -mm price spot --asset-ids "eip155:1/slip44:60,eip155:137/slip44:966" -mm price spot --asset-ids "eip155:1/slip44:60" --vs eur -mm price spot --asset-ids "eip155:1/slip44:60" --market-data -``` - -## `price history` Command - -Fetch historical prices for an asset. - -### Syntax - -```bash -mm price history --chain-id --asset-type [--time-period ] [--interval ] [--from ] [--to ] [--vs ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--chain-id` | Yes | CAIP-2 chain ID (e.g. `eip155:1`). Run `mm price networks` to see supported chains | -| `--asset-type` | Yes | CAIP-19 asset type (e.g. `slip44:60` for ETH, `erc20:0x...` for ERC-20 tokens) | -| `--time-period` | No | Time period (e.g. `1d`, `7d`, `30d`, `2M`, `1y`, `3y`) | -| `--interval` | No | Sampling interval: `5m`, `hourly`, or `daily` | -| `--from` | No | Start time as a Unix timestamp in seconds. Use with `--to` instead of `--time-period` for custom ranges | -| `--to` | No | End time as a Unix timestamp in seconds. Use with `--from` instead of `--time-period` for custom ranges | -| `--vs` | No | Quote currency code (defaults to `usd`). Run `mm price currencies` to see options | - -### Example - -```bash -mm price history --chain-id eip155:1 --asset-type slip44:60 --time-period 7d --interval daily -``` - -## `price currencies` Command - -List supported quote currencies. - -### Syntax - -```bash -mm price currencies -``` - -### Example - -```bash -mm price currencies -``` - -## `price networks` Command - -List CAIP-2 networks supported by the price API. - -### Syntax - -```bash -mm price networks -``` - -### Example - -```bash -mm price networks -``` - -## `token list` Commands - -List popular, trending, or top-gainer tokens. - -### Syntax - -```bash -mm token list popular [--chain ] -mm token list trending [--chain ] -mm token list top-gainer [--chain ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--chain` | No | Chain id, CAIP-2 id, or configured chain key. Defaults to the active wallet chain, or `eip155:1` if none is selected | - -### Example - -```bash -mm token list popular --chain 1 -mm token list trending --chain 1 -mm token list top-gainer --chain 1 -``` - -## `token list search` Command - -Search tokens by query. - -### Syntax - -```bash -mm token list search --query [--chain ] [--limit ] [--after ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--query` | Yes | Search query by symbol or name (e.g. USDC, Wrapped Ether) | -| `--chain` | No | Comma-separated chain IDs, CAIP-2 IDs, or configured chain keys. Defaults to the active wallet chain, or `eip155:1` if none is selected | -| `--limit` | No | Maximum results (defaults to 10; 1-500) | -| `--after` | No | Pagination cursor | - -### Example - -```bash -mm token list search --query USDC --chain 1,137 --limit 25 -mm token list search --query WETH --chain eip155:8453 -``` - -## `token networks` Command - -List networks supported by token APIs. - -### Syntax - -```bash -mm token networks -``` - -### Example - -```bash -mm token networks -``` - -## `token assets` Command - -Fetch asset metadata for one or more CAIP-19 assets. - -### Syntax - -```bash -mm token assets --asset-ids [--include-market-data] [--include-token-security-data] [--include-labels] [--include-aggregators] [--include-coingecko-id] [--include-occurrences] [--include-rwa-data] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--asset-ids` | Yes | Comma-separated CAIP-19 asset IDs (e.g. `eip155:1/erc20:0xa0b8...`). Run `mm token networks` to see supported chains | -| `--include-market-data` | No | Include market cap, volume, and price data | -| `--include-token-security-data` | No | Include token security signals (scam risk, honeypot detection) | -| `--include-labels` | No | Include token labels and categories | -| `--include-aggregators` | No | Include aggregator sources that list this token | -| `--include-coingecko-id` | No | Include the CoinGecko identifier for cross-referencing | -| `--include-occurrences` | No | Include occurrence count across chains | -| `--include-rwa-data` | No | Include real-world asset (RWA) data | - -### Example - -```bash -mm token assets --asset-ids "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48,eip155:137/slip44:966" -mm token assets --asset-ids "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" --include-market-data --include-token-security-data --include-labels -mm token assets --asset-ids "eip155:1/slip44:60" --include-aggregators --include-coingecko-id --include-rwa-data -``` diff --git a/skills/metamask-agent-wallet/references/perps.md b/skills/metamask-agent-wallet/references/perps.md index 5861111..34c3190 100644 --- a/skills/metamask-agent-wallet/references/perps.md +++ b/skills/metamask-agent-wallet/references/perps.md @@ -1,399 +1,520 @@ -# Perpetual Trading Commands +# mm perps -Use `perps` commands to trade perpetual futures on supported venues. Currently supported venue: `hyperliquid`. +Trade perpetual futures. Only venue: `hyperliquid`. Funds live in a venue account (deposit +USDC from Arbitrum first), separate from the wallet's on-chain balances. -## Common Flags +## Prerequisites -Most `perps` commands accept these flags (`list-venues` does not): +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Shared optional flags, valid on every command below and omitted from the per-command tables: + `--venue ` (default `hyperliquid`, only allowed value `hyperliquid`) and `--network + ` (default `mainnet`, allowed `mainnet` | `testnet`). Exception: `list-venues` takes + neither. Include `--venue hyperliquid` in commands anyway for explicitness. +- The seven state-changing commands (`open`, `close`, `modify`, `cancel`, `deposit`, + `withdraw`, `transfer`) additionally share these optional flags (also omitted from tables): + `--dry-run` (preview without signing or submitting) and `--yes` (skip the interactive + confirmation prompt — pass only after the user approved). +- Async model for the state-changing commands: the wallet job runs synchronously — no `--wait` + flag, no `pollingId`. Global flags and `--wallet-timeout` apply — see SKILL.md § Global + flags. BYOK with an encrypted mnemonic: set `MM_PASSWORD` first (references/concepts.md). +- Read-only commands (`list-venues`, `dexs`, `markets`, `balance`, `positions`, `orders`, + `quote`): global flags apply — see SKILL.md § Global flags. +- `--size` is in the base asset (`0.01` = 0.01 BTC); deposit/withdraw/transfer amounts are USDC. -| Name | Required | Description | -| --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) | - -The `--yes` flag skips interactive confirmation on `open`, `close`, `modify`, and `cancel` only. On `deposit`, `transfer`, and `withdraw`, `--yes` is accepted but has no effect because those commands do not prompt. Perps commands do not use `--wait`. In BYOK mode with an encrypted mnemonic, state-changing commands also accept `--password` to unlock the mnemonic [env: `MM_PASSWORD`]. +## mm perps list-venues -## `perps markets` Command - -List perpetual markets for a venue. +List available perpetual venues. Read-only. No flags beyond global. ### Syntax ```bash -mm perps markets [--venue ] [--network ] [--symbol ] [--symbols ] [--dex ] +mm perps list-venues ``` -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`). Run `mm perps list-venues` to see options (allowed: `hyperliquid`) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) (allowed: `mainnet`, `testnet`) | -| `--symbol` | No | Filter to a single market symbol (e.g. BTC) | -| `--symbols` | No | Comma-separated market symbols to filter (e.g. BTC,ETH,SOL) | -| `--dex` | No | HIP-3 DEX name; omit for the main Hyperliquid DEX. Run `mm perps dexs` to see options | - -### Example +### Output -```bash -mm perps markets --venue hyperliquid -mm perps markets --venue hyperliquid --symbol BTC -mm perps markets --venue hyperliquid --symbols BTC,ETH,SOL --network testnet -mm perps markets --venue hyperliquid --dex myDex +``` +ok: true +data: + venues[1]: + - id: hyperliquid + label: Hyperliquid + networks[2]: mainnet,testnet ``` -## `perps balance` Command +## mm perps dexs -Show the connected wallet's perpetual account balances for a venue. +List DEX identifiers a venue exposes (main Hyperliquid DEX is the empty string, plus HIP-3 +DEXs). Read-only. No flags beyond the shared `--venue`/`--network`. ### Syntax ```bash -mm perps balance [--venue ] [--network ] +mm perps dexs --venue hyperliquid ``` -### Example +### Output -```bash -mm perps balance --venue hyperliquid -mm perps balance --venue hyperliquid --network testnet +``` +ok: true +data: + dexs[10]: "",xyz,flx,vntl,hyna,km,abcd,cash,para,mkts ``` -## `perps positions` Command +## mm perps markets -List open positions for the connected wallet on a venue. +List perpetual markets for a venue. Read-only. ### Syntax ```bash -mm perps positions [--venue ] [--network ] +mm perps markets --venue hyperliquid [--symbol ] ``` -### Example +### Required flags -```bash -mm perps positions --venue hyperliquid -mm perps positions --venue hyperliquid --network testnet -``` +None. -## `perps quote` Command +### Optional flags -Estimate entry price, notional, fees, and liquidation price without placing an order. +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--symbol` | all markets | market symbol | Filter to a single market (e.g. `BTC`) | +| `--symbols` | all markets | comma-separated symbols | Filter to several markets (e.g. `BTC,ETH,SOL`) | +| `--dex` | main DEX | name from `mm perps dexs` | HIP-3 DEX name; omit for the main Hyperliquid DEX | -### Syntax +### Output -```bash -mm perps quote [--venue ] --symbol --side --size --leverage [--type ] [--limit-px ] [--network ] +``` +ok: true +data[1]{venue,symbol,maxLeverage,sizeDecimals,markPrice,oraclePrice,fundingRate,openInterest,volume24h}: + hyperliquid,BTC,40,5,"62944.0","62961.0","0.0000125","37908.9644999999","1770767064.72…" ``` -### Supported Flags +Capture: `symbol` → ``; check `maxLeverage` before choosing `--leverage`. -| Name | Required | Description | -| --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`) | -| `--symbol` | Yes | Market symbol (e.g. BTC, ETH, SOL) | -| `--side` | Yes | Position direction (allowed: `long`, `short`) | -| `--size` | Yes | Size in base asset, human-readable (e.g. 0.01, 1) | -| `--leverage` | Yes | Leverage multiplier as a positive integer (e.g. 5, 10) | -| `--type` | No | Order type (allowed: `market`, `limit`). Default is `market` | -| `--limit-px` | If `--type limit` | Limit price, human-readable (e.g. 60000 for BTC) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) | +## mm perps balance + +Show the venue account's balances. Read-only. No flags beyond the shared `--venue`/`--network`. -### Example +### Syntax ```bash -mm perps quote --venue hyperliquid --symbol BTC --side long --size 0.01 --leverage 5 -mm perps quote --venue hyperliquid --symbol ETH --side short --size 1 --leverage 10 --type limit --limit-px 2500 +mm perps balance --venue hyperliquid ``` -## `perps open` Command +### Output -Open a new perpetual position by placing an order. +``` +ok: true +data: + venue: hyperliquid + totalBalance: "0.000042" + spendableBalance: "0.000042" + withdrawableBalance: "0.000042" + marginUsed: "0" + unrealizedPnl: "0.00" + returnOnEquity: "0" + subAccounts: + main: … +``` + +## mm perps positions + +List open positions. Read-only. No flags beyond the shared `--venue`/`--network`. ### Syntax ```bash -mm perps open [--venue ] --symbol --side --size --leverage [--type ] [--limit-px ] [--max-slippage-bps ] [--network ] [--dry-run] [--yes] [--password ] +mm perps positions --venue hyperliquid ``` -### Supported Flags +### Output -| Name | Required | Description | -| --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`) | -| `--symbol` | Yes | Market symbol (e.g. BTC, ETH, SOL) | -| `--side` | Yes | Position direction (allowed: `long`, `short`) | -| `--size` | Yes | Size in base asset, human-readable (e.g. 0.01, 1) | -| `--leverage` | Yes | Leverage multiplier as a positive integer (e.g. 5, 10) | -| `--type` | No | Order type (allowed: `market`, `limit`; defaults to `market`) | -| `--limit-px` | If `--type limit` | Limit price; required when `--type` is `limit` (e.g. 60000 for BTC) | -| `--max-slippage-bps` | No | Slippage cap in basis points for IOC market pricing (e.g. 50) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) | -| `--dry-run` | No | Validate and preview the order without signing or submitting | -| `--yes` | No | Skip interactive confirmation | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm perps open --venue hyperliquid --symbol BTC --side long --size 0.01 --leverage 5 -mm perps open --venue hyperliquid --symbol ETH --side short --size 1 --leverage 10 --type limit --limit-px 2500 -mm perps open --venue hyperliquid --symbol BTC --side long --size 0.05 --leverage 3 --dry-run ``` +ok: true +data: [] +``` + +Non-empty: one row per position (symbol, side, size, entry price, leverage, liquidation +price, unrealized PnL). Capture: `symbol` → `` for `mm perps close` / `mm perps modify`. -## `perps orders` Command +## mm perps orders -List resting orders for the connected wallet on a venue. +List resting (unfilled) orders. Read-only. No flags beyond the shared `--venue`/`--network`. ### Syntax ```bash -mm perps orders [--venue ] [--network ] +mm perps orders --venue hyperliquid ``` -### Example +### Output -```bash -mm perps orders --venue hyperliquid -mm perps orders --venue hyperliquid --network testnet +``` +ok: true +data: [] ``` -## `perps close` Command +Non-empty rows include the venue order ID. Capture: order ID → `` for `mm perps cancel`. -Close one position, part of a position, or all open positions. +## mm perps quote + +Estimate entry price, notional, fees, and liquidation price without placing an order. Read-only. ### Syntax ```bash -mm perps close [--venue ] [--symbol ] [--size ] [--all] [--max-slippage-bps ] [--network ] [--dry-run] [--yes] [--password ] +mm perps quote --venue hyperliquid --symbol --side --size --leverage ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`) | -| `--symbol` | Yes, unless `--all` | Market symbol to close (e.g. BTC, ETH) | -| `--size` | No | Partial close size in base asset (e.g. 0.5); omit for full close. Not allowed with `--all` | -| `--all` | No | Close all open positions; mutually exclusive with `--symbol` | -| `--max-slippage-bps` | No | Slippage cap in basis points for IOC pricing (e.g. 50) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) | -| `--dry-run` | No | Preview the close action without signing or submitting | -| `--yes` | No | Skip interactive confirmation | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--symbol` | market symbol | Market symbol (e.g. `BTC`, `ETH`, `SOL`) | +| `--side` | `long` or `short` | Position direction | +| `--size` | decimal `^\d+\.?\d*$`, > 0 | Size in base asset (e.g. `0.01`) | +| `--leverage` | positive integer | Leverage multiplier (e.g. `5`); ≤ market `maxLeverage` | -### Validation Rules +### Optional flags -- `--size` is not allowed with `--all`. +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--type` | `market` | `market` or `limit` | Order type | +| `--limit-px` | — | decimal price | Limit price; required when `--type limit` | -### Example +### Output -```bash -mm perps close --venue hyperliquid --symbol BTC -mm perps close --venue hyperliquid --symbol ETH --size 0.5 -mm perps close --venue hyperliquid --all -mm perps close --venue hyperliquid --symbol BTC --dry-run +``` +ok: true +data: + venue: hyperliquid + symbol: BTC + side: long + orderType: market + entryPrice: "62948" + size: "0.001" + notional: "62.95" + estimatedFee: "0.0283" + estimatedLiquidationPrice: "31474" + feeRate: "0.00045" + warnings[1]: Liquidation price is an estimate and does not include all venue-specific margin rules. ``` -## `perps modify` Command +Capture: `entryPrice`, `notional`, `estimatedFee`, `estimatedLiquidationPrice` → show in the +confirmation before `mm perps open`. -Modify leverage, take-profit, or stop-loss for an existing position. +## mm perps open + +Open a new perpetual position by placing an order. State-changing. ### Syntax ```bash -mm perps modify [--venue ] --symbol [--leverage ] [--tp ] [--sl ] [--network ] [--dry-run] [--yes] [--password ] +mm perps open --venue hyperliquid --symbol --side --size --leverage [--type ] [--limit-px ] [--dry-run] [--yes] ``` -### Supported Flags +### Required flags -| Name | Required | Description | -| --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`) | -| `--symbol` | Yes | Market symbol (e.g. BTC, ETH, SOL) | -| `--leverage` | No | New leverage multiplier as a positive integer (e.g. 5, 10) | -| `--tp` | No | Take-profit trigger price, human-readable (e.g. 3000, 2500.50) | -| `--sl` | No | Stop-loss trigger price, human-readable (e.g. 2000, 1800.75) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) | -| `--dry-run` | No | Preview the modify action without signing or submitting | -| `--yes` | No | Skip interactive confirmation | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +Same four as `mm perps quote`: `--symbol`, `--side`, `--size`, `--leverage` (same formats). + +### Optional flags -### Validation Rules +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--type` | `market` | `market` or `limit` | Order type | +| `--limit-px` | — | decimal price | Limit price; required when `--type limit` | +| `--max-slippage-bps` | venue default | positive integer | Slippage cap in basis points for IOC market pricing (e.g. `50`) | -- At least one of `--leverage`, `--tp`, or `--sl` must be provided. +### Output -### Example +```json +{"ok": true, "data": {"status": "filled", "symbol": "BTC", "size": "0.001"}} +``` + + +### Confirm before executing + +Show ALL of: symbol, side, size, leverage, venue, order type, limit price (if limit), and the +quoted `entryPrice`, `notional`, `estimatedFee`, `estimatedLiquidationPrice` from +`mm perps quote`. Do not run until the user approves. + +### Examples ```bash -mm perps modify --venue hyperliquid --symbol BTC --leverage 10 -mm perps modify --venue hyperliquid --symbol ETH --tp 3000 --sl 2000 -mm perps modify --venue hyperliquid --symbol BTC --leverage 3 --dry-run +mm perps open --venue hyperliquid --symbol BTC --side long --size 0.001 --leverage 2 --dry-run --toon +mm perps open --venue hyperliquid --symbol BTC --side long --size 0.001 --leverage 2 --yes --toon +mm perps open --venue hyperliquid --symbol ETH --side short --size 1 --leverage 10 --type limit --limit-px 2500 --yes --toon ``` -## `perps cancel` Command +## mm perps close -Cancel a resting perps order. +Close one position, part of one, or all open positions. State-changing. ### Syntax +Two disjoint modes — if closing one symbol use the first form; if closing everything, the second: + ```bash -mm perps cancel [--venue ] --order-id [--symbol ] [--network ] [--dry-run] [--yes] [--password ] +mm perps close --venue hyperliquid --symbol [--size ] [--dry-run] [--yes] +mm perps close --venue hyperliquid --all [--dry-run] [--yes] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`). Run `mm perps list-venues` to see options (allowed: `hyperliquid`) | -| `--order-id` | Yes | Venue order ID to cancel (positive integer) | -| `--symbol` | No | Market symbol; speeds up cancel by avoiding an open-order lookup (e.g. BTC, ETH) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) (allowed: `mainnet`, `testnet`) | -| `--dry-run` | No | Preview the cancel action without signing or submitting | -| `--yes` | No | Skip interactive confirmation | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--symbol` XOR `--all` | market symbol / boolean flag | `--symbol` closes one market; `--all` closes every open position. Mutually exclusive; exactly one required. | + +### Optional flags -### Example +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--size` | full close | decimal, > 0 | Partial close size in base asset. Not allowed with `--all`. | +| `--max-slippage-bps` | venue default | positive integer | Slippage cap in basis points for IOC pricing | + +### Output + +```json +{"ok": true, "data": {"status": "filled", "symbol": "BTC", "closedSize": "0.001"}} +``` + + +### Confirm before executing + +Show ALL of: symbol (or "ALL open positions" for `--all`), size (full or partial), the +position's unrealized PnL from `mm perps positions`, venue. Do not run until the user approves. + +### Examples ```bash -mm perps cancel --venue hyperliquid --order-id 12345 -mm perps cancel --venue hyperliquid --order-id 12345 --symbol BTC -mm perps cancel --venue hyperliquid --order-id 12345 --dry-run -mm perps cancel --venue hyperliquid --order-id 12345 --yes +mm perps close --venue hyperliquid --symbol BTC --yes --toon +mm perps close --venue hyperliquid --symbol BTC --size 0.0005 --yes --toon +mm perps close --venue hyperliquid --all --dry-run --toon ``` -## `perps deposit` Command +## mm perps modify -Deposit USDC into a perpetual venue. +Modify leverage, take-profit, or stop-loss on an existing position. State-changing. ### Syntax ```bash -mm perps deposit [--venue ] --amount [--asset ] [--source-chain ] [--network ] [--dry-run] [--password ] +mm perps modify --venue hyperliquid --symbol [--leverage ] [--tp ] [--sl ] [--dry-run] [--yes] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`). Run `mm perps list-venues` to see options (allowed: `hyperliquid`) | -| `--amount` | Yes | Human-readable USDC amount to deposit (e.g. 100, 50.5) | -| `--asset` | No | Deposit asset (defaults to `USDC`) (allowed: `USDC`) | -| `--source-chain` | No | Source chain as a CAIP-2 ID or decimal chain ID (defaults to Arbitrum for the selected network: `eip155:42161` on mainnet, `eip155:421614` on testnet) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) (allowed: `mainnet`, `testnet`) | -| `--dry-run` | No | Preview the transaction without signing or submitting | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--symbol` | market symbol | Market symbol of the open position | + +At least one of `--leverage`, `--tp`, `--sl` is also required. + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--leverage` | unchanged | positive integer | New leverage multiplier | +| `--tp` | unchanged | decimal price | Take-profit trigger price | +| `--sl` | unchanged | decimal price | Stop-loss trigger price | + +### Output + +```json +{"ok": true, "data": {"symbol": "BTC", "leverage": 10}} +``` + + +### Confirm before executing -### Example +Show ALL of: symbol, venue, and each field being changed as old → new (leverage, TP, SL). Do +not run until the user approves. + +### Examples ```bash -mm perps deposit --venue hyperliquid --amount 100 --asset USDC -mm perps deposit --venue hyperliquid --amount 100 --asset USDC --dry-run +mm perps modify --venue hyperliquid --symbol BTC --leverage 10 --yes --toon +mm perps modify --venue hyperliquid --symbol ETH --tp 3000 --sl 2000 --yes --toon ``` -## `perps withdraw` Command +## mm perps cancel -Withdraw USDC from a perpetual venue. +Cancel a resting perpetual order by venue order ID. State-changing. ### Syntax ```bash -mm perps withdraw [--venue ] --amount [--asset ] [--destination
] [--network ] [--dry-run] [--include-spot] [--password ] +mm perps cancel --venue hyperliquid --order-id [--symbol ] [--dry-run] [--yes] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`). Run `mm perps list-venues` to see options (allowed: `hyperliquid`) | -| `--amount` | Yes | Human-readable USDC amount to withdraw (e.g. 50, 25.5) | -| `--asset` | No | Withdrawal asset (defaults to `USDC`) (allowed: `USDC`) | -| `--destination` | No | EVM destination address (defaults to your connected wallet) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) (allowed: `mainnet`, `testnet`) | -| `--dry-run` | No | Preview the withdrawal without signing or submitting | -| `--include-spot` | No | Move free spot USDC to perp before withdrawing if needed | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--order-id` | positive integer | Venue order ID from `mm perps orders` | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--symbol` | looked up | market symbol | Speeds up cancel by avoiding the open-order lookup | + +### Output + +```json +{"ok": true, "data": {"orderId": 12345, "status": "cancelled"}} +``` + -### Example +### Confirm before executing + +Show ALL of: order ID, plus that order's symbol, side, size, and price from `mm perps orders`. +Do not run until the user approves. + +### Examples ```bash -mm perps withdraw --venue hyperliquid --amount 50 --asset USDC -mm perps withdraw --venue hyperliquid --amount 50 --asset USDC --include-spot -mm perps withdraw --venue hyperliquid --amount 50 --asset USDC --destination 0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18 +mm perps cancel --venue hyperliquid --order-id 12345 --symbol BTC --yes --toon ``` -## `perps transfer` Command +## mm perps deposit -Transfer USDC between spot and perp accounts on a perpetual venue. +Deposit USDC from the wallet's on-chain balance into a perpetual venue. State-changing. ### Syntax ```bash -mm perps transfer [--venue ] --amount --direction [--asset ] [--network ] [--dry-run] [--password ] +mm perps deposit --venue hyperliquid --amount [--dry-run] [--yes] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`) | -| `--amount` | Yes | Human-readable USDC amount to transfer (e.g. 100, 50.5) | -| `--direction` | Yes | Transfer direction (allowed: `spot-to-perp`, `perp-to-spot`) | -| `--asset` | No | Transfer asset (defaults to `USDC`) (allowed: `USDC`) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) | -| `--dry-run` | No | Preview the transfer without signing or submitting | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--amount` | decimal, > 0 | Human-readable USDC amount (e.g. `100`) | + +### Optional flags -### Example +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--asset` | `USDC` | `USDC` | Deposit asset (only USDC allowed) | +| `--source-chain` | Arbitrum for the network (`eip155:42161` on mainnet) | `` | Source chain of the funds | + +### Output + +```json +{"ok": true, "data": {"amount": "100", "asset": "USDC", "status": "submitted"}} +``` + + +Venue credit can take a few minutes; verify with `mm perps balance`. + +### Confirm before executing + +Show ALL of: amount, asset (USDC), source chain, venue. Verify the wallet holds the USDC plus +gas on the source chain first (`mm wallet balance --chain 42161`). Do not run until the user +approves. + +### Examples ```bash -mm perps transfer --venue hyperliquid --amount 100 --direction spot-to-perp --asset USDC -mm perps transfer --venue hyperliquid --amount 50 --direction perp-to-spot --asset USDC +mm perps deposit --venue hyperliquid --amount 100 --yes --toon ``` -## `perps list-venues` Command +## mm perps withdraw -List available perpetual futures venues. +Withdraw USDC from a perpetual venue to an EVM address. State-changing. ### Syntax ```bash -mm perps list-venues +mm perps withdraw --venue hyperliquid --amount [--destination
] [--include-spot] [--dry-run] [--yes] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--amount` | decimal, > 0 | Human-readable USDC amount (e.g. `50`) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--asset` | `USDC` | `USDC` | Withdrawal asset (only USDC allowed) | +| `--destination` | connected wallet | `^0x[0-9a-fA-F]{40}$` | EVM destination address | +| `--include-spot` | off | boolean flag | Move free spot USDC to perp first if needed to cover the amount | + +### Output + +```json +{"ok": true, "data": {"amount": "50", "asset": "USDC", "status": "submitted"}} ``` + -### Supported Flags +### Confirm before executing -This command does not support additional flags beyond output format options. +Show ALL of: amount, destination address (explicit or "connected wallet"), venue, whether +`--include-spot` is set. Verify `withdrawableBalance` covers the amount (`mm perps balance`). +Do not run until the user approves. -### Example +### Examples ```bash -mm perps list-venues +mm perps withdraw --venue hyperliquid --amount 50 --yes --toon +mm perps withdraw --venue hyperliquid --amount 50 --destination 0x7c2b3e65ef2b18235e2d24266f92854a70207483 --include-spot --yes --toon ``` -## `perps dexs` Command +## mm perps transfer -List available DEX identifiers a venue exposes. For Hyperliquid, this includes the main DEX and any HIP-3 builder-deployed DEXs. +Move USDC between spot and perp accounts inside the venue. State-changing. ### Syntax ```bash -mm perps dexs [--venue ] [--network ] +mm perps transfer --venue hyperliquid --amount --direction [--dry-run] [--yes] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--venue` | No | Perpetual venue (defaults to `hyperliquid`) | -| `--network` | No | Target network: `mainnet` or `testnet` (defaults to `mainnet`) | +| `--amount` | decimal, > 0 | Human-readable USDC amount | +| `--direction` | `spot-to-perp` or `perp-to-spot` | Transfer direction | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--asset` | `USDC` | `USDC` | Transfer asset (only USDC allowed) | + +### Output + +```json +{"ok": true, "data": {"amount": "100", "direction": "spot-to-perp", "status": "submitted"}} +``` + + +### Confirm before executing + +Show ALL of: amount, direction, venue. Do not run until the user approves. -### Example +### Examples ```bash -mm perps dexs --venue hyperliquid +mm perps transfer --venue hyperliquid --amount 100 --direction spot-to-perp --yes --toon ``` -## Notes +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `ValidationError` | Malformed flag value, unknown symbol, `--limit-px` missing with `--type limit`, or both/neither of `--symbol`/`--all` on close | Re-check values against the tables above; list markets with `mm perps markets --venue hyperliquid --toon` | +| Insufficient margin / balance | Venue account cannot cover the notional at the requested size | `mm perps balance --venue hyperliquid --toon`; offer `mm perps deposit` or a smaller size, after user approval | +| Leverage above market max | `--leverage` exceeds the market's `maxLeverage` | Read `maxLeverage` from `mm perps markets --symbol ` and re-quote | +| Order or position not found | Wrong ``, or no open position for `` | Re-list with `mm perps orders` / `mm perps positions` | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | -- If the user does not mention a token symbol, use `mm perps markets` to list available markets and confirm the symbol with the user before proceeding. +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/polling.md b/skills/metamask-agent-wallet/references/polling.md deleted file mode 100644 index 3b0fec4..0000000 --- a/skills/metamask-agent-wallet/references/polling.md +++ /dev/null @@ -1,52 +0,0 @@ -# Polling Commands - -In server wallet mode, signing and transaction commands return a `pollingId` instead of an immediate result. Use these commands to track and wait for results. Both commands are server-wallet mode only. - -Transfers, swaps, perps, predict orders, and predict withdraws attach a human-readable `intent` summary to their request (e.g. `Transfer 0.5 ETH to 0x...`, `Withdraw 10 pUSD to 0x...`). When listing or watching requests, surface the `intent` so the user can confirm what they are approving. - -## `wallet requests list` Command - -List all pending wallet requests. - -### Syntax - -```bash -mm wallet requests list [--sync] [--toon] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--sync` | No | Refresh pending requests before listing (defaults to true; use `--no-sync` to skip) | - -### Example - -```bash -mm wallet requests list -mm wallet requests list --no-sync --toon -``` - -## `wallet requests watch` Command - -Wait for a specific wallet request to complete by its polling ID. MFA prompts are surfaced once when a job enters the `AWAITING_MFA` state. - -### Syntax - -```bash -mm wallet requests watch [--polling-id ] [--toon] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Request polling ID returned by a previous command (positional) | -| `--polling-id` | No | Same as positional `` | - -### Example - -```bash -mm wallet requests watch abc-123 -mm wallet requests watch --polling-id abc-123 --toon -``` diff --git a/skills/metamask-agent-wallet/references/predict-account.md b/skills/metamask-agent-wallet/references/predict-account.md new file mode 100644 index 0000000..e0c319a --- /dev/null +++ b/skills/metamask-agent-wallet/references/predict-account.md @@ -0,0 +1,354 @@ +# mm predict (account & funding) + +Set up, fund, and inspect the Predict (Polymarket) trading account: mode, one-time setup, +credentials, approvals, status, geoblock, balance, deposit, withdraw. + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Setup gate: `mm predict status` must show `setupComplete: true` before any trading command + (references/predict-trade.md). If `false`, run `mm predict setup --wait` first. +- Deposits convert USDC.e held by the owner EOA on Polygon (chain 137) into pUSD in the + Predict deposit wallet; withdrawals convert pUSD back out. +- Market/token discovery: references/predict-data.md. Orders: references/predict-trade.md. +- Async job IDs from setup/approve/deposit/withdraw are tracked with + `mm predict watch --id --wait` (references/predict-trade.md). + +## mm predict mode + +Show or switch the Predict trading mode (local setting). Read-only when bare. Positional-only — +there is no flag form. + +### Syntax + +```bash +mm predict mode [mainnet|testnet] +``` + +Bare form shows the current mode; with an argument it switches. No command-specific flags. +Global flags apply — see SKILL.md § Global flags. + +### Output + +`{"ok": true, "data": {command: mode, result: {mode: mainnet}}}` + +### Examples + +```bash +mm predict mode --toon +mm predict mode mainnet --toon +``` + +## mm predict setup + +One-time setup: creates trading credentials, deploys the deposit wallet, sets approvals. State-changing. + +### Syntax + +```bash +mm predict setup [--wait] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the setup job completes (prefer this) | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {result: {pollingId: "..."}}}` + +Capture: `pollingId` → use as `` in `mm predict watch --id --wait`. + +### Async + +Without `--wait` a job ID is returned; track it with `mm predict watch --id --wait`. + +### Confirm before executing + +Show the user: that setup deploys a deposit wallet and grants token approvals on Polygon, and +the active Predict mode (`mm predict mode`). Do not run until the user approves. + +### Examples + +```bash +mm predict setup --wait --toon +``` + +## mm predict auth + +Create or refresh Predict trading credentials (API key + CLOB signing). State-changing +(local credentials only; no on-chain effect, no confirmation needed). + +### Syntax + +```bash +mm predict auth [--refresh] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--refresh` | off | boolean flag | Force-create or refresh trading credentials | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {result: {credentials: true}}}` + +### Async + +Completes inline; no `pollingId`. + +### Confirm before executing + +None required — no on-chain effect. Mention that credentials will be (re)created. + +### Examples + +```bash +mm predict auth --refresh --toon +``` + +## mm predict approve + +Repair missing deposit-wallet approvals. State-changing. + +### Syntax + +```bash +mm predict approve [--wait] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the approval job completes | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {result: {pollingId: "..."}}}` + +Capture: `pollingId` → use as `` in `mm predict watch --id --wait`. + +### Async + +Without `--wait`, track the job with `mm predict watch --id --wait`. + +### Confirm before executing + +Show the user: that this grants token approvals from the Predict deposit wallet on Polygon. + +### Examples + +```bash +mm predict approve --wait --toon +``` + +## mm predict status + +Probe Predict back-end reachability (Gamma + CLOB) and report account setup state. Read-only. + +### Syntax + +```bash +mm predict status +``` + +No command-specific flags. Global flags apply — see SKILL.md § Global flags. + +### Output + +```yaml +ok: true +data: + command: status + result: + chainId: 137 + gamma: ok + clob: ok + account: + ownerAddress: 0x7c2b3e65ef2b18235e2d24266f92854a70207483 + depositWalletAddress: 0xb5B5A96FD0AfdC6ba006D8a04f2F3f20a8B6f982 + deployed: false + credentials: false + setupComplete: false +``` + +Capture: `account.setupComplete` → if `false`, run `mm predict setup --wait` before trading. + +### Examples + +```bash +mm predict status --toon +``` + +## mm predict geoblock + +Check whether Polymarket access is geoblocked for the current IP. Read-only. Cheaper than +letting `mm predict setup` abort with `PREDICT_GEOBLOCKED`. + +### Syntax + +```bash +mm predict geoblock +``` + +No command-specific flags. Global flags apply — see SKILL.md § Global flags. + +### Output + +`{"ok": true, "data": {result: {blocked: false, ip: "203.0.113.7", country: "DE", region: ""}}}` + +### Examples + +```bash +mm predict geoblock --toon +``` + +## mm predict balance + +Check deposit-wallet funds (pUSD), approvals, and setup status. Read-only. + +### Syntax + +```bash +mm predict balance [--token-id ] [--sync] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--token-id` | omitted | outcome token ID string | Also report the holding of one outcome token (from `mm predict markets get`) | +| `--sync` | off | boolean flag | Refresh balances and allowances before reading | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {result: {pusd: "25.00", approvals: true, setupComplete: true}}}` + +### Examples + +```bash +mm predict balance --sync --toon +``` + +## mm predict deposit + +Convert USDC.e from the owner EOA into pUSD in the Predict deposit wallet. State-changing. + +### Syntax + +```bash +mm predict deposit --amount [--wait] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--amount` | decimal `^\d+\.?\d*$`, > 0 | pUSD amount, human-readable (`5`, `100`). Not atomic units. | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the deposit job completes | + +Global flags and `--wallet-timeout` apply — see SKILL.md § Global flags. BYOK with an encrypted +mnemonic: set `MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {result: {pollingId: "..."}}}` + +Capture: `pollingId` → use as `` in `mm predict watch --id --wait`. + +### Async + +Without `--wait`, track the job with `mm predict watch --id --wait`. + +### Confirm before executing + +Show the user ALL of: amount, source (owner EOA USDC.e on Polygon), destination (Predict +deposit wallet, as pUSD). Do not run until the user approves. + +### Examples + +```bash +mm predict deposit --amount 5 --wait --toon +``` + +## mm predict withdraw + +Withdraw pUSD from the Predict deposit wallet to the owner EOA or another address. Validates +the amount against the on-chain deposit-wallet balance before signing. State-changing. + +### Syntax + +```bash +mm predict withdraw --amount [--to
] [--wait] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--amount` | decimal `^\d+\.?\d*$`, > 0 | pUSD amount, human-readable (`5`, `100`) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--to` | owner EOA | `^0x[0-9a-fA-F]{40}$` | Recipient address | +| `--wait` | off | boolean flag | Block until the withdraw job completes | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {result: {pollingId: "..."}}}` + +Capture: `pollingId` → use as `` in `mm predict watch --id --wait`. + +### Async + +Without `--wait`, track the job with `mm predict watch --id --wait`. + +### Confirm before executing + +Show the user ALL of: amount, recipient address (say "owner EOA" explicitly when `--to` is +omitted). Do not run until the user approves. + +### Examples + +```bash +mm predict withdraw --amount 10 --wait --toon +mm predict withdraw --amount 5 --to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e --wait --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `PREDICT_GEOBLOCKED` | IP resolves to a restricted region (checked before any wallet interaction) | Confirm with `mm predict geoblock`; Predict is unavailable from this region | +| `PREDICT_SETUP_REQUIRED` | Account command run before setup completed | Run `mm predict setup --wait`, verify with `mm predict status` | +| `UNKNOWN` (`fetch failed`) | Transient network failure to the Predict back end | Retry; check reachability with `mm predict status` | +| `WALLET_ERROR` | Insufficient USDC.e (deposit) or pUSD (withdraw) | Check `mm wallet balance --chain 137` or `mm predict balance --sync`; adjust amount | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/predict-data.md b/skills/metamask-agent-wallet/references/predict-data.md new file mode 100644 index 0000000..428f2ab --- /dev/null +++ b/skills/metamask-agent-wallet/references/predict-data.md @@ -0,0 +1,330 @@ +# mm predict (market data) + +Browse Polymarket data: markets, events, series, tags, and order books. All commands in this +file are read-only and need no confirmation. + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- No Predict setup needed to browse. Setup gate applies only to trading + (references/predict-trade.md) and funding (references/predict-account.md). +- Flow: find a market (`markets search` or `markets list`) → `markets get` to read outcome + token IDs → `book` / references/predict-trade.md with those `` values. +- Tag slugs/IDs from `tags list` feed the `--tag`/`--tag-slug`/`--tag-id` filters below. + +## mm predict markets list + +List tradeable Predict markets with Gamma-style filters. Read-only. + +### Syntax + +```bash +mm predict markets list [--limit ] [--tag ] [--active] [--closed] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--slug` | omitted | market slug string | Filter by market slug | +| `--limit` | server default | integer 1-500 | Maximum markets to return | +| `--offset` | `0` | integer ≥ 0 | Result offset for pagination | +| `--order` | omitted | comma-separated field names | Market fields to order by | +| `--ascending` | off | boolean flag | Sort ascending (default descending) | +| `--tag` | omitted | tag slug string | Market tag or category (e.g. `sports`, `politics`) | +| `--liquidity-num-min` | omitted | decimal | Minimum market liquidity | +| `--liquidity-num-max` | omitted | decimal | Maximum market liquidity | +| `--volume-num-min` | omitted | decimal | Minimum market volume | +| `--volume-num-max` | omitted | decimal | Maximum market volume | +| `--start-date-min` | omitted | ISO 8601 date-time | Minimum market start date-time | +| `--start-date-max` | omitted | ISO 8601 date-time | Maximum market start date-time | +| `--end-date-min` | omitted | ISO 8601 date-time | Minimum market end date-time | +| `--end-date-max` | omitted | ISO 8601 date-time | Maximum market end date-time | +| `--active` | off | boolean flag | Only include active markets | +| `--closed` | off | boolean flag | Include closed markets | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +List of market objects with `id`, `question`, `conditionId`, `slug`, `outcomes`, +`outcomePrices`, `liquidity`, `volume`, `active`, `closed` (same shape as the captured +`markets search` output below). + + +Capture: `slug` or `conditionId` → use in `mm predict markets get --market `. + +### Examples + +```bash +mm predict markets list --tag sports --liquidity-num-min 10000 --limit 10 --toon +mm predict markets list --active --limit 50 --toon +``` + +## mm predict markets search + +Free-text search via Polymarket public search. Read-only. The query is POSITIONAL — there is +no query flag. + +### Syntax + +```bash +mm predict markets search [--limit ] +``` + +`` is a search string; quote it if it contains spaces. (New placeholder: ``.) + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--limit` | `10` | integer | Results per type | +| `--page` | `1` | integer | Search result page | +| `--sort` | omitted | field name | Search sort field | +| `--ascending` | off | boolean flag | Sort ascending | +| `--search-tags` | on | boolean flag | Include tag matches (`--no-search-tags` to disable) | +| `--events-status` | active | boolean flag | Restrict to active events (`--no-events-status` for all) | +| `--recurrence` | omitted | `annual`\|`daily`\|`weekly`\|`monthly` | Filter by series recurrence | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```yaml +ok: true +data: + command: "market:search" + params: {query: bitcoin, limit: 1, searchTags: true, eventsStatus: active} + result: + markets[11]: + - id: "2769746" + question: "Will the price of Bitcoin be above $52,000 on July 9?" + conditionId: 0x5179f59617e32ce893c4ecc0ee1e4916c65f7a85eb3774c87cdc3430cb1d0d73 + slug: bitcoin-above-52k-on-july-9-2026 + outcomes: "[\"Yes\", \"No\"]" + outcomePrices: "[\"0.9995\", \"0.0005\"]" + liquidity: "210307.34108" + active: true + closed: false + orderPriceMinTickSize: 0.001 + orderMinSize: 5 +``` + +Capture: `slug` or `conditionId` → use in `mm predict markets get --market `. + +### Examples + +```bash +mm predict markets search bitcoin --limit 1 --toon +mm predict markets search "Knicks NBA Finals" --limit 5 --toon +``` + +## mm predict markets get + +Inspect one market and read the outcome token IDs required by quote/place/book/balance. Read-only. + +### Syntax + +```bash +mm predict markets get --market +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--market` | market slug, ID, or `` | The market to inspect (find via `markets search`/`markets list`) | + +Global flags apply — see SKILL.md § Global flags. (New placeholder: ``.) + +### Output + +Market object with `question`, `conditionId`, per-outcome token IDs, prices, tick size, and +minimum order size. + + +Capture: outcome token ID → use as `` in `mm predict book --token-id ` and +references/predict-trade.md; `conditionId` → `` for cancel/redeem. + +### Examples + +```bash +mm predict markets get --market bitcoin-above-52k-on-july-9-2026 --toon +mm predict markets get --market 0x5179f59617e32ce893c4ecc0ee1e4916c65f7a85eb3774c87cdc3430cb1d0d73 --toon +``` + +## mm predict events list / events get + +List Polymarket events (groupings of related markets), or inspect one. Read-only. +`events get` is positional-only. + +### Syntax + +```bash +mm predict events list [--tag-slug ] [--active] [--limit ] +mm predict events get +``` + +`` is an event slug or ID. (New placeholder: ``.) + +### Optional flags (events list only; events get has none) + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--tag-slug` | omitted | tag slug string | Filter by tag slug (e.g. `sports`) | +| `--tag-id` | omitted | integer | Filter by tag ID (from `mm predict tags list`) | +| `--active` | off | boolean flag | Active events only | +| `--closed` | off | boolean flag | Include closed/resolved events | +| `--featured` | off | boolean flag | Only featured/trending events | +| `--order` | omitted | `volume_24hr`\|`volume`\|`liquidity`\|`start_date`\|`end_date` | Sort field | +| `--ascending` | off | boolean flag | Sort ascending (default descending) | +| `--liquidity-min` | omitted | decimal | Minimum event liquidity | +| `--start-date-min` / `--start-date-max` | omitted | ISO 8601 | Event start date bounds | +| `--end-date-min` / `--end-date-max` | omitted | ISO 8601 | Event end date bounds | +| `--limit` | server default | integer | Max results | +| `--offset` | `0` | integer ≥ 0 | Result offset for pagination | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +Event objects with `id`, `slug`, `title`, and nested market summaries. + + +### Examples + +```bash +mm predict events list --tag-slug sports --limit 10 --toon +mm predict events get us-recession-in-2026 --toon +``` + +## mm predict series list / series get + +List recurring Polymarket event series, or inspect one by ID. Read-only. `series get` is +positional-only. + +### Syntax + +```bash +mm predict series list [--recurrence ] [--limit ] +mm predict series get +``` + +(New placeholders: ``, ``.) + +### Optional flags (series list only; series get has none) + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--recurrence` | omitted | `annual`\|`daily`\|`weekly`\|`monthly` | Filter by recurrence | +| `--active` | off | boolean flag | Active series only | +| `--featured` | off | boolean flag | Only featured series | +| `--tag-slug` | omitted | tag slug string | Filter by tag slug | +| `--limit` | server default | integer | Max results | +| `--offset` | `0` | integer ≥ 0 | Result offset for pagination | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +Series objects with `id`, `slug`, `title`, `recurrence`. + + +### Examples + +```bash +mm predict series list --recurrence weekly --limit 10 --toon +mm predict series get 12345 --toon +``` + +## mm predict tags list / tags get + +List Polymarket tags (feed `--tag`/`--tag-slug`/`--tag-id` filters), or fetch one by ID or +slug. Read-only. `tags get` is positional-only. + +### Syntax + +```bash +mm predict tags list [--limit ] +mm predict tags get +``` + +`` for `tags get` may also be a numeric tag ID. (New placeholder: ``.) + +### Optional flags (tags list only; tags get has none) + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--limit` | server default | integer | Max results | +| `--offset` | `0` | integer ≥ 0 | Result offset for pagination | +| `--is-carousel` | off | boolean flag | Only carousel tags | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```yaml +ok: true +data: + command: tags + params: {limit: 3} + result: + tags[3]: + - id: "101867" + label: product marekt fit + slug: product-marekt-fit + - id: "1512" + label: caitlin clark + slug: caitlin-clark + - id: "100601" + label: virgins + slug: virgins +``` + +Capture: `slug` → `--tag-slug`/`--tag`; `id` → `--tag-id`. + +### Examples + +```bash +mm predict tags list --limit 3 --toon +mm predict tags get sports --toon +``` + +## mm predict book + +Fetch the raw order book for an outcome token. Read-only. + +### Syntax + +```bash +mm predict book --token-id +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--token-id` | outcome token ID string | From `mm predict markets get --market ` | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +Bids and asks as `{price, size}` levels; prices are per-share in the range (0, 1]. + + +### Examples + +```bash +mm predict book --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `ValidationError` | Malformed flag value or missing positional argument | Re-check values against the tables above | +| `NOT_FOUND` | Unknown slug, ID, condition ID, or token ID | Re-discover via `mm predict markets search ` or `mm predict tags list` | +| `UNKNOWN` (`fetch failed`) | Transient network failure to Gamma/CLOB | Retry; check reachability with `mm predict status` (references/predict-account.md) | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/predict-trade.md b/skills/metamask-agent-wallet/references/predict-trade.md new file mode 100644 index 0000000..5540f36 --- /dev/null +++ b/skills/metamask-agent-wallet/references/predict-trade.md @@ -0,0 +1,369 @@ +# mm predict (trading) + +Quote, place, cancel, and track Predict (Polymarket) orders; view positions, portfolio, and +redeem winnings. + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Setup gate: `mm predict status` shows `account.setupComplete: true` + (references/predict-account.md). Otherwise every command here fails `PREDICT_SETUP_REQUIRED`. +- pUSD funds the orders: check `mm predict balance --sync`, top up with `mm predict deposit` + (references/predict-account.md). +- `` and `` come from `mm predict markets get --market ` + (references/predict-data.md). +- Prices are per-share, in the range (0, 1]. Sides are `buy` or `sell`. Order types: `GTC` + (limit, default), `GTD` (limit with `--expiration`), `FOK`/`FAK` (market-style). + +## mm predict quote + +Preview order cost and fill before placing. Read-only. + +### Syntax + +```bash +mm predict quote --token-id --side --size [--limit-price ] +``` + +(New placeholders: `` = `buy`|`sell`, `` = shares decimal, `` = decimal in (0, 1].) + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--token-id` | outcome token ID string | From `mm predict markets get` | +| `--side` | `buy` \| `sell` | Order side | +| `--size` | decimal `^\d+\.?\d*$`, > 0 | Order size in shares (`1`, `100`) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--limit-price` | market price | decimal in (0, 1] | Execution price per share | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +Estimated cost, average fill price, and fillable size for the requested order. + + +### Examples + +```bash +mm predict quote --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --side buy --size 10 --toon +mm predict quote --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --side sell --size 5 --limit-price 0.60 --toon +``` + +## mm predict place + +Place a Predict order (GTC/GTD limit, FOK/FAK market). State-changing. + +### Syntax + +```bash +mm predict place --token-id --side --size --price [--order-type ] [--post-only] [--expiration ] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--token-id` | outcome token ID string | From `mm predict markets get` | +| `--side` | `buy` \| `sell` | Order side | +| `--size` | decimal `^\d+\.?\d*$`, > 0 | Order size in shares | +| `--price` | decimal in (0, 1] | Worst price per share: limit price for GTC/GTD, worst fill for FOK/FAK | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--order-type` | `GTC` | `GTC` \| `GTD` \| `FOK` \| `FAK` | Order type | +| `--post-only` | off | boolean flag | Reject if the order would cross the book. Not valid with FOK/FAK | +| `--expiration` | none | `` seconds (`date +%s`) | Required for GTD; invalid for other types | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +Order record with `orderId` and status, or a job ID for asynchronous submission. + + +Capture: `orderId` → use as `` in `mm predict cancel --order-id `; a job +ID → `` in `mm predict watch --id --wait`. + +### Async + +If a job ID is returned, track it with `mm predict watch --id --wait`. + +### Confirm before executing + +Show the user ALL of: market question, outcome, side, size (shares), price per share, +order type, total cost (size × price for buys), expiration if GTD. Do not run until the +user approves. Quote first with `mm predict quote`. + +### Examples + +```bash +mm predict place --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --side buy --size 10 --price 0.55 --toon +mm predict place --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --side sell --size 2 --price 0.70 --order-type GTD --expiration 1783600000 --toon +``` + +## mm predict cancel + +Cancel open Predict orders. State-changing. Pass EXACTLY ONE targeting flag: + +- If the user names one order → `--order-id `. +- If the user wants everything cancelled → `--all` (destructive scope — confirm explicitly). +- If the user wants one market cleared → `--market `. +- If the user wants one outcome token cleared → `--asset `. + +### Syntax + +```bash +mm predict cancel --order-id +``` + +### Optional flags (exactly one required) + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--order-id` | — | order ID string | Cancel a single order | +| `--all` | — | boolean flag | Cancel ALL open orders | +| `--market` | — | `` (`0x` + 64 hex) | Cancel all orders in one market | +| `--asset` | — | outcome token ID string | Cancel all orders on one outcome token | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +List of cancelled order IDs. + + +### Async + +Completes inline; no `pollingId`. + +### Confirm before executing + +Show the user the exact scope: the order ID, or "ALL open orders", or the market/asset being +cleared plus how many open orders match (`mm predict orders`). Do not run until approved. + +### Examples + +```bash +mm predict cancel --order-id 0x1f9090aae28b8a3dceadf281b0f12828e676c326 --toon +mm predict cancel --market 0x5179f59617e32ce893c4ecc0ee1e4916c65f7a85eb3774c87cdc3430cb1d0d73 --toon +``` + +## mm predict orders + +View open Predict orders. Read-only. + +### Syntax + +```bash +mm predict orders [--market ] [--cursor ] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--market` | all markets | market slug, ID, or `` | Filter to one market | +| `--cursor` | first page | cursor string from a previous response | Pagination | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +Open orders with `orderId`, token, side, size, price, and a pagination `cursor`. + + +Capture: `orderId` → `` for `mm predict cancel --order-id `. + +### Examples + +```bash +mm predict orders --toon +``` + +## mm predict positions + +View Predict positions. Read-only. + +### Syntax + +```bash +mm predict positions [--market ] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--market` | all markets | market slug, ID, or `` | Filter to one market | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +Positions with market question, outcome, size, and estimated value. + + +### Examples + +```bash +mm predict positions --toon +``` + +## mm predict portfolio + +Full snapshot: pUSD balance, open positions with estimated value, redeemable winnings. Read-only. +No command-specific flags besides the pointer line below. + +### Syntax + +```bash +mm predict portfolio +``` + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {"result": {"balance": "...", "positions": [], "redeemable": []}}}` + + +### Examples + +```bash +mm predict portfolio --toon +``` + +## mm predict redeem list + +List all redeemable (winning) positions with size and market question. Read-only. +No command-specific flags. + +### Syntax + +```bash +mm predict redeem list +``` + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +Redeemable positions with `conditionId`, market question, and size. + + +Capture: `conditionId` → `` for `mm predict redeem --wait`. + +### Examples + +```bash +mm predict redeem list --toon +``` + +## mm predict redeem + +Redeem winning tokens after market resolution. State-changing. Choose EXACTLY ONE form: + +- If the user names one market → positional: `mm predict redeem [--wait]`. +- If the user wants everything → `mm predict redeem --all [--wait]` (destructive scope — confirm explicitly). + +### Syntax + +```bash +mm predict redeem [--wait] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--all` | off | boolean flag | Redeem all redeemable positions (replaces the positional) | +| `--wait` | off | boolean flag | Block until the redemption transaction is confirmed | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +`{"ok": true, "data": {"result": {"pollingId": "..."}}}` + + +Capture: `pollingId` → `` for `mm predict watch --id --wait`. + +### Async + +Without `--wait`, track the job with `mm predict watch --id --wait`. + +### Confirm before executing + +Show the user: the market(s) being redeemed (from `mm predict redeem list`) and the expected +pUSD proceeds; for `--all`, list every affected market. Do not run until approved. + +### Examples + +```bash +mm predict redeem 0x5179f59617e32ce893c4ecc0ee1e4916c65f7a85eb3774c87cdc3430cb1d0d73 --wait --toon +mm predict redeem --all --wait --toon +``` + +## mm predict watch + +Watch a setup, approval, deposit, withdraw, or order job until it completes. Read-only tracker. + +### Syntax + +```bash +mm predict watch --id [--wait] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--id` | job or transaction ID string | The `pollingId` returned by a Predict state-changing command | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the job completes (prefer this) | + +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). + +### Output + +Job status record; terminal states report success/failure and any transaction hash. + + +### Examples + +```bash +mm predict watch --id 018f9a2b-4c6d-7e8f-9a0b-1c2d3e4f5a6b --wait --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `PREDICT_SETUP_REQUIRED` | Setup incomplete for the owner EOA | `mm predict setup --wait`, verify with `mm predict status` (references/predict-account.md) | +| `PREDICT_GEOBLOCKED` | Restricted region | `mm predict geoblock`; Predict unavailable from this IP | +| `ValidationError` | Price outside (0, 1], `--post-only` with FOK/FAK, `--expiration` without GTD, or multiple/zero cancel targets | Fix the flag combination per the tables above | +| `WALLET_ERROR` | Insufficient pUSD for the order | `mm predict balance --sync`; deposit via references/predict-account.md | +| `UNKNOWN` (`fetch failed`) | Transient CLOB/Gamma network failure | Retry; check `mm predict status` | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/predict.md b/skills/metamask-agent-wallet/references/predict.md deleted file mode 100644 index 9f57f50..0000000 --- a/skills/metamask-agent-wallet/references/predict.md +++ /dev/null @@ -1,730 +0,0 @@ -# Predict Commands - -Use the `predict` commands to trade on prediction markets (Polymarket via the CLOB). - -## `predict mode` Command - -Choose or display the current Predict trading mode. - -### Syntax - -```bash -mm predict mode [mainnet|testnet] -``` - -### Example - -```bash -mm predict mode mainnet -mm predict mode testnet -mm predict mode -``` - -## `predict setup` Command - -One-time Predict setup: creates trading credentials, deploys the deposit wallet, and sets approvals. - -### Syntax - -```bash -mm predict setup [--wait] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--wait` | No | Block until the job completes | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict setup --wait -``` - -## `predict auth` Command - -Create or refresh Predict trading credentials (API key + CLOB signing). - -### Syntax - -```bash -mm predict auth [--refresh] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--refresh` | No | Force-create or refresh trading credentials | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict auth -mm predict auth --refresh -``` - -## `predict approve` Command - -Repair missing deposit-wallet approvals. - -### Syntax - -```bash -mm predict approve [--wait] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--wait` | No | Block until the job completes | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict approve --wait -``` - -## `predict status` Command - -Probe Predict back-end reachability (Gamma + CLOB) and report account setup status: deposit wallet address, on-chain deployment, stored CLOB credentials, and a `setupComplete` flag. - -### Syntax - -```bash -mm predict status -``` - -### Example - -```bash -mm predict status -``` - -## `predict geoblock` Command - -Check whether Polymarket access is geoblocked for your current IP. Returns `blocked`, `ip`, `country`, and `region`. - -### Syntax - -```bash -mm predict geoblock -``` - -### Example - -```bash -mm predict geoblock -``` - -## `predict markets list` Command - -List tradeable Predict markets with Gamma-style filters. - -### Syntax - -```bash -mm predict markets list [--slug ] [--limit ] [--offset ] [--order ] [--ascending] [--tag ] [--liquidity-num-min ] [--liquidity-num-max ] [--volume-num-min ] [--volume-num-max ] [--start-date-min ] [--start-date-max ] [--end-date-min ] [--end-date-max ] [--active] [--closed] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--slug` | No | Market slug to filter by | -| `--limit` | No | Maximum markets to return, 1-500 | -| `--offset` | No | Market result offset (0-based) | -| `--order` | No | Comma-separated market fields to order by | -| `--ascending` | No | Sort markets in ascending order | -| `--tag` | No | Market tag or category (e.g. sports, politics) | -| `--liquidity-num-min` | No | Minimum market liquidity | -| `--liquidity-num-max` | No | Maximum market liquidity | -| `--volume-num-min` | No | Minimum market volume | -| `--volume-num-max` | No | Maximum market volume | -| `--start-date-min` | No | Minimum market start date-time | -| `--start-date-max` | No | Maximum market start date-time | -| `--end-date-min` | No | Minimum market end date-time | -| `--end-date-max` | No | Maximum market end date-time | -| `--active` | No | Only include active markets | -| `--closed` | No | Include closed markets | - -### Example - -```bash -mm predict markets list --slug will-this-work --limit 5 -mm predict markets list --tag sports --liquidity-num-min 10000 --limit 10 -mm predict markets list --active --limit 50 -``` - -## `predict markets search` Command - -Search Predict markets with Polymarket public search. - -### Syntax - -```bash -mm predict markets search [--limit ] [--page ] [--sort ] [--ascending] [--search-tags] [--events-status] [--recurrence ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Search string (positional) | -| `--limit` | No | Results per type (defaults to 10) | -| `--page` | No | Search result page | -| `--sort` | No | Search sort field | -| `--ascending` | No | Sort search results in ascending order | -| `--search-tags` | No | Include tag matches in search results (defaults to true; use `--no-search-tags` to disable) | -| `--events-status` | No | Restrict to active events (defaults to true; use `--no-events-status` for all) | -| `--recurrence` | No | Filter by series recurrence: `daily`, `weekly`, or `monthly` | - -### Example - -```bash -mm predict markets search "Knicks NBA Finals" --limit 5 -mm predict markets search "election" --limit 5 -``` - -## `predict markets get` Command - -Inspect a specific market and show outcome token IDs needed for quoting and placing orders. - -### Syntax - -```bash -mm predict markets get [--market ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Market slug, ID, or condition ID (positional). Run `mm predict markets search` or `mm predict markets list` to find markets | -| `--market` | No | Same as positional `` | - -### Example - -```bash -mm predict markets get will-the-new-york-knicks-win-the-2026-nba-finals -mm predict markets get 0x713641f745d71f6ec61f906237ffca3c8583f251e49384429a63ceb0ccdb2d37 -``` - -## `predict events list` Command - -List Polymarket events (groupings of related markets) with Gamma-style filters. - -### Syntax - -```bash -mm predict events list [--tag-slug ] [--tag-id ] [--active] [--closed] [--featured] [--order ] [--ascending] [--liquidity-min ] [--start-date-min ] [--start-date-max ] [--end-date-min ] [--end-date-max ] [--limit ] [--offset ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--tag-slug` | No | Filter by tag slug (e.g. sports, politics) | -| `--tag-id` | No | Filter by tag ID (from `mm predict tags list`) | -| `--active` | No | Active events only | -| `--closed` | No | Include closed/resolved events | -| `--featured` | No | Only featured/trending events | -| `--order` | No | Sort field: `volume_24hr`, `volume`, `liquidity`, `start_date`, `end_date` | -| `--ascending` | No | Sort ascending (defaults to descending) | -| `--liquidity-min` | No | Minimum event liquidity | -| `--start-date-min` | No | Minimum event start date-time | -| `--start-date-max` | No | Maximum event start date-time | -| `--end-date-min` | No | Minimum event end date-time | -| `--end-date-max` | No | Maximum event end date-time | -| `--limit` | No | Maximum events to return, 1-500 | -| `--offset` | No | Result offset (0-based) | - -### Example - -```bash -mm predict events list --tag-slug sports --limit 10 -mm predict events list --active --featured -``` - -## `predict events get` Command - -Inspect a single Polymarket event by slug or ID. - -### Syntax - -```bash -mm predict events get -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Event slug or ID (positional) | - -### Example - -```bash -mm predict events get some-event-slug -``` - -## `predict series list` Command - -List Polymarket event series (recurring groupings of events). - -### Syntax - -```bash -mm predict series list [--recurrence ] [--active] [--featured] [--tag-slug ] [--limit ] [--offset ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--recurrence` | No | Filter by recurrence: `annual`, `daily`, `weekly`, or `monthly` | -| `--active` | No | Active series only | -| `--featured` | No | Only featured series | -| `--tag-slug` | No | Filter by tag slug | -| `--limit` | No | Maximum series to return, 1-500 | -| `--offset` | No | Result offset (0-based) | - -### Example - -```bash -mm predict series list --recurrence weekly --limit 10 -``` - -## `predict series get` Command - -Inspect a single event series by ID. - -### Syntax - -```bash -mm predict series get -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Series ID (positional) | - -### Example - -```bash -mm predict series get 12345 -``` - -## `predict tags list` Command - -List Polymarket tags, useful for `--tag-slug` / `--tag-id` filters on events and markets. - -### Syntax - -```bash -mm predict tags list [--limit ] [--offset ] [--is-carousel] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--limit` | No | Maximum tags to return, 1-500 | -| `--offset` | No | Result offset (0-based) | -| `--is-carousel` | No | Only carousel tags | - -### Example - -```bash -mm predict tags list --limit 50 -``` - -## `predict tags get` Command - -Fetch a single Polymarket tag by numeric ID or slug. - -### Syntax - -```bash -mm predict tags get -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Tag ID (integer) or slug string (positional) | - -### Example - -```bash -mm predict tags get sports -mm predict tags get 100 -``` - -## `predict quote` Command - -Preview order cost and fill before placing. - -### Syntax - -```bash -mm predict quote [--token-id ] --side --size [--limit-price ] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Outcome token ID (positional). Run `mm predict markets get ` to get token IDs | -| `--token-id` | No | Same as positional `` | -| `--side` | Yes | Order side: `buy` or `sell` | -| `--size` | Yes | Order size in shares, human-readable (e.g. 1, 100) | -| `--limit-price` | No | Execution price per share, between 0 and 1 | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict quote --token-id --side buy --size 1 -mm predict quote --token-id --side sell --size 5 --limit-price 0.60 -``` - -## `predict place` Command - -Place a Predict order (GTC/GTD limit, FOK/FAK market). - -### Syntax - -```bash -mm predict place [--token-id ] --side --size --price [--order-type ] [--post-only] [--expiration ] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Outcome token ID (positional). Run `mm predict markets get ` to get token IDs | -| `--token-id` | No | Same as positional `` | -| `--side` | Yes | Order side: `buy` or `sell` | -| `--size` | Yes | Order size in shares, human-readable (e.g. 1, 100) | -| `--price` | Yes | Worst price per share (0-1); limit price for GTC/GTD, worst fill for FOK/FAK | -| `--order-type` | No | Order type: `GTC`, `GTD`, `FOK`, or `FAK` (defaults to `GTC`) | -| `--post-only` | No | Reject if the order would cross the book. Not supported with FOK/FAK orders | -| `--expiration` | If `GTD` | Expiration as a Unix timestamp in seconds (only valid for GTD orders) | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Validation Rules - -- `--post-only` cannot be used with FOK or FAK orders. -- `--expiration` is only valid for GTD orders. - -### Example - -```bash -mm predict place --token-id --side buy --size 1 --price 0.80 -mm predict place --token-id --side buy --size 5 --price 1 --order-type FOK -mm predict place --token-id --side sell --size 2 --price 0.7 --order-type GTD --expiration 1735689600 -``` - -## `predict cancel` Command - -Cancel Predict orders by ID, market, asset, or all open orders. - -### Syntax - -```bash -mm predict cancel [] [--order-id ] [--all] [--market ] [--asset ] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes (unless `--all`/`--market`/`--asset`) | Order ID to cancel (positional) | -| `--order-id` | No | Same as positional `` | -| `--all` | No | Cancel all open orders | -| `--market` | No | Cancel orders for a given market condition ID | -| `--asset` | No | Cancel orders for a specific outcome token ID | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Validation Rules - -- Use only one of `--order-id`, `--all`, or `--market`/`--asset` (market and asset can be combined as one target). - -### Example - -```bash -mm predict cancel -mm predict cancel --order-id -mm predict cancel --all -mm predict cancel --market -mm predict cancel --asset -``` - -## `predict positions` Command - -View your Predict positions. - -### Syntax - -```bash -mm predict positions [--market ] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--market` | No | Market slug, ID, or condition ID. Run `mm predict markets search` or `mm predict markets list` to find markets | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict positions -mm predict positions --market -``` - -## `predict portfolio` Command - -Full portfolio snapshot: deposit wallet pUSD balance, open positions with estimated value, and outstanding redeemable winnings. - -### Syntax - -```bash -mm predict portfolio [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict portfolio -``` - -## `predict redeem list` Command - -List all redeemable (winning) positions in your deposit wallet, with position size and market question. - -### Syntax - -```bash -mm predict redeem list [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict redeem list -``` - -## `predict redeem` Command - -Redeem winning tokens after market resolution. Redeem one position by condition ID, or all redeemable positions with `--all`. With `--wait`, polls for the transaction receipt. - -### Syntax - -```bash -mm predict redeem [] [--all] [--wait] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes (unless `--all`) | Market condition ID to redeem (positional) | -| `--all` | No | Redeem all redeemable positions | -| `--wait` | No | Block until the redemption transaction is confirmed | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Validation Rules - -- Provide either a `` or `--all`, not both. - -### Example - -```bash -mm predict redeem 0xABC123... --wait -mm predict redeem --all --wait -``` - -## `predict orders` Command - -View open Predict orders. - -### Syntax - -```bash -mm predict orders [--market ] [--cursor ] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--market` | No | Market slug, ID, or condition ID. Run `mm predict markets search` or `mm predict markets list` to find markets | -| `--cursor` | No | Pagination cursor from a previous response | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict orders -mm predict orders --market -``` - -## `predict balance` Command - -Check deposit wallet funds, approvals, and setup status. - -### Syntax - -```bash -mm predict balance [--token-id ] [--sync] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--token-id` | No | Outcome token ID. Run `mm predict markets get ` to get token IDs | -| `--sync` | No | Refresh balances and allowances before reading | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict balance --sync -mm predict balance --token-id --sync -``` - -## `predict withdraw` Command - -Withdraw pUSD from your Predict deposit wallet to your owner EOA or another address. Validates the amount against the on-chain deposit wallet balance before signing. Uses the Polymarket Relayer batch mechanism. - -### Syntax - -```bash -mm predict withdraw --amount [--to
] [--wait] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--amount` | Yes | pUSD amount to withdraw, human-readable (e.g. 0.1, 5, 100) | -| `--to` | No | Recipient address. Defaults to your owner EOA | -| `--wait` | No | Block until the job completes | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict withdraw --amount 10 --wait -mm predict withdraw --amount 5 --to 0xAbc... --wait -``` - -## `predict deposit` Command - -Convert USDC.e from your EOA to pUSD in your Predict deposit wallet. - -### Syntax - -```bash -mm predict deposit --amount [--wait] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--amount` | Yes | pUSD amount to deposit, human-readable (e.g. 5, 100) | -| `--wait` | No | Block until the job completes | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict deposit --amount 5 --wait -``` - -## `predict book` Command - -Fetch the raw order book for an outcome token. - -### Syntax - -```bash -mm predict book [--token-id ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Outcome token ID (positional). Run `mm predict markets get ` to get token IDs | -| `--token-id` | No | Same as positional `` | - -### Example - -```bash -mm predict book --token-id -``` - -## `predict watch` Command - -Watch a setup, approval, deposit, withdraw, or order job until it completes. - -### Syntax - -```bash -mm predict watch [--id ] [--wait] [--password ] -``` - -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | Job or transaction ID to watch (positional) | -| `--id` | No | Same as positional `` | -| `--wait` | No | Block until the job completes | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | - -### Example - -```bash -mm predict watch --wait -mm predict watch --id --wait -``` - -## Notes - -- Before trading, run `mm predict setup --wait` to initialize credentials, deploy the deposit wallet, and set approvals. -- `mm predict setup` aborts early with `PREDICT_GEOBLOCKED` if your IP resolves to a restricted region, before any wallet interaction. Use `mm predict geoblock` to check region status without running setup. -- Use `mm predict markets get ` to get outcome token IDs required by `quote`, `place`, `book`, and `balance --token-id`. -- Use `mm predict events`, `mm predict series`, and `mm predict tags` to browse Polymarket content; tag slugs/IDs from `mm predict tags list` feed the `--tag-slug` / `--tag-id` filters on `events` and `markets`. -- After a market resolves, use `mm predict redeem list` to see winnings and `mm predict redeem --wait` (or `--all`) to claim them. `mm predict portfolio` shows balance, open positions, and redeemable winnings in one snapshot. -- Prices are per-share and must be in the range [0, 1]. -- Side must be `buy` or `sell`. -- The `predict mode` command switches between `mainnet` and `testnet`. -- If the user does not specify a mode, the CLI uses the previously set mode. -- Setup, approve, deposit, withdraw, redeem, and order flows can return job IDs. Track them with `mm predict watch --wait`. diff --git a/skills/metamask-agent-wallet/references/price.md b/skills/metamask-agent-wallet/references/price.md new file mode 100644 index 0000000..aaa1055 --- /dev/null +++ b/skills/metamask-agent-wallet/references/price.md @@ -0,0 +1,178 @@ +# mm price + +Read-only spot prices, historical prices, and price-API capability lists for CAIP-19 assets. + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Build CAIP-2 / CAIP-19 identifiers by string substitution — see references/concepts.md § CAIP identifiers. +- Unknown token contract address? Resolve it first with `mm token list search` (references/token.md). + +## mm price spot + +Fetch current prices for one or more CAIP-19 assets. Read-only. + +### Syntax + +```bash +mm price spot --asset-ids [--vs ] [--market-data] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--asset-ids` | one or more ``, comma-separated, no spaces | Assets to price (e.g. `eip155:1/slip44:60,eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--vs` | `usd` | currency code from `mm price currencies` | Quote currency | +| `--market-data` | off | boolean flag | Include market cap, supply, and 24h change | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + vsCurrency: usd + includeMarketData: false + prices[1]{assetId,vsCurrency,price}: + "eip155:1/slip44:60",usd,1741.75 +``` + +### Examples + +```bash +# ETH and POL native prices in USD +mm price spot --asset-ids eip155:1/slip44:60,eip155:137/slip44:966 --toon +# USDC on Ethereum with market data, in EUR +mm price spot --asset-ids eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --vs eur --market-data --toon +``` + +## mm price history + +Fetch historical prices for one CAIP-19 asset. Read-only. The asset is split across two flags: +`--chain-id` takes the CAIP-2 part, `--asset-type` takes the part after the `/`. + +### Syntax + +```bash +mm price history --chain-id --asset-type [--time-period ] [--interval ] [--from ] [--to ] [--vs ] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--chain-id` | `` (e.g. `eip155:1`) | Chain. Supported chains: `mm price networks` | +| `--asset-type` | `slip44:` or `erc20:
` | The CAIP-19 asset type (the part after `/`) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--time-period` | API default | `1d`, `7d`, `30d`, `2M`, `1y`, `3y` | Lookback window. Do not combine with `--from`/`--to` | +| `--from` | — | `` seconds | Custom range start; use together with `--to` | +| `--to` | — | `` seconds | Custom range end; use together with `--from` | +| `--interval` | API default | `5m`, `hourly`, `daily` | Sampling interval | +| `--vs` | `usd` | currency code from `mm price currencies` | Quote currency | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + chainId: "eip155:1" + assetType: "slip44:60" + vsCurrency: usd + timePeriod: 1d + interval: daily + prices[2]: + - [2]: 1783555200000,1742.5277253393804 + - [2]: 1783609607000,1739.5050996130065 + marketCaps[2]: … + totalVolumes[2]: … +``` + +`prices` rows are `[millisecond-timestamp, price]` pairs. + +### Examples + +```bash +# ETH daily prices over the last 7 days +mm price history --chain-id eip155:1 --asset-type slip44:60 --time-period 7d --interval daily --toon +# USDC on Ethereum for a custom Unix range +mm price history --chain-id eip155:1 --asset-type erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --from 1783000000 --to 1783600000 --interval hourly --toon +``` + +## mm price currencies + +List supported quote currencies for `--vs`. Read-only. + +### Syntax + +```bash +mm price currencies +``` + +No required or optional flags. Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + currencies[94]: btc,eth,ltc,bch,bnb,eos,xrp,xlm,link,dot,yfi,usd,aed,ars,aud,… +``` + +### Examples + +```bash +mm price currencies --toon +``` + +## mm price networks + +List CAIP-2 networks supported by the price API. Read-only. + +### Syntax + +```bash +mm price networks +``` + +No required or optional flags. Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + fullSupport[11]: "eip155:1","eip155:10","eip155:56","eip155:100","eip155:137","eip155:250","eip155:324","eip155:8453","eip155:42161","eip155:43114","eip155:59144" + partialSupport: + spotPricesV2[68]: "eip155:25","eip155:30",… + spotPricesV3[72]: "eip155:25","eip155:30",… +``` + +### Examples + +```bash +mm price networks --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `INVALID_ASSET_ID` | Malformed `--asset-ids` value | Rebuild the CAIP-19 per references/concepts.md; resolve contract addresses with `mm token list search` | +| `INVALID_CHAIN` | Chain not supported by the price API | Run `mm price networks` and pick a listed CAIP-2 ID | +| `INVALID_INTERVAL` | `--interval` not one of `5m`, `hourly`, `daily` | Re-run with a listed interval | +| `INVALID_TIMESTAMP` | `--from`/`--to` not Unix seconds, or from > to | Regenerate with `date +%s`; ensure `--from` < `--to` | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/signing.md b/skills/metamask-agent-wallet/references/signing.md index 460296f..6178b2f 100644 --- a/skills/metamask-agent-wallet/references/signing.md +++ b/skills/metamask-agent-wallet/references/signing.md @@ -1,70 +1,137 @@ -# Signing Commands +# mm wallet sign-message / sign-typed-data -Use `wallet sign-message` and `wallet sign-typed-data` to produce -cryptographic signatures with the active wallet. +Produce cryptographic signatures with the active wallet. Both commands release a signature — +treat them as state-changing and always confirm first. -## `wallet sign-message` Command +## Prerequisites -Sign a plaintext message with the active wallet. +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- If the user did not name a chain, ask — do not guess. Discover chain IDs with `mm chains list`. +- If any part of the payload was not constructed by you, apply the suspicious-payload + checklist in references/concepts.md before signing. + +## mm wallet sign-message + +Sign a plaintext message with the active wallet. State-changing (signature release). ### Syntax ```bash -mm wallet sign-message --message --chain-id [--wait] [--password ] +mm wallet sign-message --message --chain-id [--wait] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--chain-id` | Yes | EVM chain ID as a positive integer (e.g. 1, 137). If not mentioned, ask the user. | -| `--message` | Yes | Plain-text message to sign | -| `--wait` | No | Block until the signature request completes (server-wallet mode only; BYOK returns immediately) | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--message` | plain text, quoted | The exact message to sign | +| `--chain-id` | integer `^\d+$` | EVM chain ID (`1` = Ethereum, `137` = Polygon) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the signature request completes (server-wallet mode only; BYOK returns immediately) | + +Global flags and `--wallet-timeout` apply — see SKILL.md § Global flags. BYOK with an encrypted +mnemonic: set `MM_PASSWORD` first (references/concepts.md). + +### Output + +```json +{"ok": true, "data": {"pollingId": "..."}} +``` + + +Capture: `pollingId` → use as `` in `mm wallet requests watch --polling-id `. + +### Async + +Without `--wait` the command returns a `pollingId` immediately. Track it via +references/wallet-requests.md and show the request's `intent` string to the user. -### Example +### Confirm before executing + +Show the user ALL of: the exact message text, the chain, the signing wallet address. +Do not run until the user approves. + +### Examples ```bash -mm wallet sign-message --message "Hello, world!" --chain-id 1 -mm wallet sign-message --message "Hello" --chain-id 1 --wait +mm wallet sign-message --message "I agree to the terms of service v2" --chain-id 1 --wait --toon ``` -## `wallet sign-typed-data` Command +## mm wallet sign-typed-data -Sign EIP-712 typed data with the active wallet. +Sign EIP-712 typed data with the active wallet. State-changing (signature release). ### Syntax ```bash -mm wallet sign-typed-data --chain-id --payload '' [--wait] [--password ] +mm wallet sign-typed-data --chain-id --payload [--wait] [--intent ""] ``` -### Supported Flags +`` must be valid JSON, single-quoted in shell, with ALL of these top-level keys: + +| Key | Content | +| --- | --- | +| `types` | Type definitions, including `EIP712Domain` | +| `primaryType` | Name of the main type being signed | +| `domain` | Domain separator: `name`, `version`, `chainId`, `verifyingContract` | +| `message` | The actual data to sign | -| Name | Required | Description | +### Required flags + +| Flag | Value format | Description | | --- | --- | --- | -| `--chain-id` | Yes | EVM chain ID as a positive integer (e.g. 1, 137) | -| `--payload` | Yes | EIP-712 typed data as a JSON string with `domain`, `types`, `primaryType`, and `message` | -| `--wait` | No | Block until the signature request completes (server-wallet mode only; BYOK returns immediately) | -| `--intent` | No | Human-readable summary of what is being signed, forwarded with the request | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--chain-id` | integer `^\d+$` | EVM chain ID. Must match `domain.chainId` in the payload | +| `--payload` | JSON string, single-quoted | EIP-712 typed data (schema above) | -### Example +### Optional flags -```bash -mm wallet sign-typed-data --chain-id 1 --payload '{"types":...,"primaryType":...,"domain":...,"message":...}' -mm wallet sign-typed-data --chain-id 137 --payload '{"types":...}' --wait --intent "Approve 10 USDC" +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the signature request completes (server-wallet mode only; BYOK returns immediately) | +| `--intent` | none | quoted text | Human-readable summary of what is being signed, forwarded with the request | + +Global flags and `--wallet-timeout` apply — see SKILL.md § Global flags. BYOK with an encrypted +mnemonic: set `MM_PASSWORD` first (references/concepts.md). + +### Output + +```json +{"ok": true, "data": {"pollingId": "..."}} ``` + + +Capture: `pollingId` → use as `` in `mm wallet requests watch --polling-id `. + +### Async -## EIP-712 Typed Data +Without `--wait` the command returns a `pollingId` immediately. Track it via +references/wallet-requests.md and show the request's `intent` string to the user. -The `--payload` must be valid JSON with these required fields: -- `types` -- type definitions -- `primaryType` -- the main type being signed -- `domain` -- domain separator (name, version, chainId, verifyingContract) -- `message` -- the actual data to sign +### Confirm before executing -## Notes +Show the user ALL of: `domain.name`, `domain.verifyingContract`, chain, `primaryType`, and a +summary of `message` (flag any `permit`/`approve`/allowance-like fields per +references/concepts.md). Do not run until the user approves. -- If the Chain is not mentioned by the user, ask for the chain. -- In server-wallet mode, signing returns a `pollingId` when `--wait` is omitted. See `references/polling.md` to track requests. +### Examples + +```bash +mm wallet sign-typed-data --chain-id 1 --payload '{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Order":[{"name":"trader","type":"address"},{"name":"amount","type":"uint256"}]},"primaryType":"Order","domain":{"name":"Example DEX","version":"1","chainId":1,"verifyingContract":"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"},"message":{"trader":"0x7c2b3e65ef2b18235e2d24266f92854a70207483","amount":"1000000"}}' --wait --intent "Sign Example DEX order for 1 USDC" --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `MISSING_TYPED_DATA` | `--payload` missing | Provide the full EIP-712 JSON | +| `INVALID_TYPED_DATA` | Payload not valid EIP-712 JSON | Re-check the four required keys and JSON syntax | +| `CHAIN_ID_MISMATCH` | `domain.chainId` differs from `--chain-id` | Make them identical, re-confirm with the user | +| `MISSING_CHAIN_ID` | `--chain-id` missing | Ask the user for the chain, then retry | +| `MNEMONIC_LOCKED` / `WRONG_PASSWORD` | BYOK mnemonic locked or wrong `MM_PASSWORD` | Ask the user to set the correct `MM_PASSWORD` env var, then retry | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/swap.md b/skills/metamask-agent-wallet/references/swap.md index 0520e35..b2973b6 100644 --- a/skills/metamask-agent-wallet/references/swap.md +++ b/skills/metamask-agent-wallet/references/swap.md @@ -1,128 +1,208 @@ -# Swap & Bridge Commands +# mm swap -Use the `swap` commands to perform same-chain token swaps or cross-chain bridges. When `--from-chain` and `--to-chain` differ, the CLI automatically routes through a bridge. +Same-chain token swaps and cross-chain bridges. Same commands for both: when `--from-chain` +and `--to-chain` differ, the CLI routes through a bridge. -## `swap quote` Command +## Prerequisites -Get a swap or bridge quote showing expected output, fees, and route. +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- If the user did not name a chain, ask — do not guess. Discover chain IDs with `mm chains list`. +- Amounts in quote output (`srcAssetAmount`, `destAssetAmount`, `minDestAssetAmount`, fee + `amount`) are ATOMIC units — divide by `10^decimals` of the matching asset before showing + them to the user. The `--amount` input flag stays human-readable. +- Multi-step patterns: workflows/swap.md (same-chain), workflows/bridge.md (cross-chain). + +## mm swap quote + +Get a swap or bridge quote showing expected output, fees, and route. Read-only. ### Syntax ```bash -mm swap quote --from --to --amount --from-chain [--to-chain ] [--to-address
] [--slippage ] [--refuel] +mm swap quote --from --to --amount --from-chain [--to-chain ] [--slippage ] [--to-address
] [--refuel] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--from` | Yes | Source token symbol (e.g. ETH, POL, USDC) | -| `--to` | Yes | Destination token symbol (e.g. USDC, USDT) | -| `--amount` | Yes | Human-readable amount to swap (e.g. 0.5, 100) | -| `--from-chain` | Yes | Source EVM chain ID (e.g. 1 for Ethereum, 137 for Polygon) | -| `--to-chain` | No | Destination EVM chain ID. Defaults to `--from-chain` for same-chain swaps | -| `--to-address` | No | Recipient address for bridged output tokens. Only valid for cross-chain swaps. Defaults to the signer's wallet | -| `--slippage` | No | Maximum slippage as a percentage, 0-100 (defaults to 0.5) | -| `--refuel` | No | Bundle a small destination native-gas top-up into a cross-chain quote. Only valid when `--to-chain` differs from `--from-chain`. See [Refuel](#refuel) | +| `--from` | token symbol | Source token symbol (`ETH`, `POL`, `USDC`) | +| `--to` | token symbol | Destination token symbol (`USDC`, `USDT`) | +| `--amount` | decimal `^\d+\.?\d*$`, > 0 | Human-readable amount to swap (`0.5`, `100`). Not wei. | +| `--from-chain` | integer `^\d+$` | Source EVM chain ID (`1` = Ethereum, `137` = Polygon) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--to-chain` | same as `--from-chain` | integer `^\d+$` | Destination chain ID. Different value = cross-chain bridge | +| `--slippage` | `0.5` | decimal 0–100 | Maximum slippage percent. Warn the user above 1% | +| `--to-address` | active wallet | `^0x[0-9a-fA-F]{40}$` | Recipient of bridged output. Cross-chain only — rejected same-chain | +| `--refuel` | off | boolean flag | Bundle a destination native-gas top-up. Cross-chain only; best-effort (falls back to a regular quote if no aggregator offers it). Do not use when `--to` is the destination chain's native gas asset — that route returns `NO_QUOTES` | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```json +{ + "ok": true, + "data": { + "quoteId": "0x20a57409b6f9702cd1919983ec7a480b6e20e70d22e9af051c9622f7ab50f2e4", + "request": { + "walletAddress": "0x7c2b3e65ef2b18235e2d24266f92854a70207483", + "srcChainId": 1, "destChainId": 1, + "srcAsset": {"symbol": "ETH", "decimals": 18}, + "destAsset": {"symbol": "USDC", "decimals": 6}, + "srcAssetAmount": "1000000000000000000", + "slippage": 0.5 + }, + "quote": { + "bridgeId": "okx", + "srcAssetAmount": "991250000000000000", + "destAssetAmount": "1724960864", + "minDestAssetAmount": "1716336059", + "feeData": {"metabridge": {"amount": "8750000000000000", "usd": "15.24…"}} + } + } +} +``` + +All `*AssetAmount` and fee `amount` values are atomic units — scale by each asset's +`decimals` before display (here `destAssetAmount` 1724960864 / 10^6 = 1724.96 USDC). +When a refuel-bearing quote is selected, the quote includes a `refuel` step and the +resolved request shows `refuel: true`. + +Capture: `quoteId` → use as `` in `mm swap execute` and `mm swap status`. -### Example +### Examples ```bash -mm swap quote --from ETH --to USDC --amount 0.5 --from-chain 1 -mm swap quote --from USDC --to USDT --amount 100 --from-chain 137 -mm swap quote --from ETH --to USDC --amount 1 --from-chain 1 --to-chain 137 -mm swap quote --from ETH --to USDC --amount 0.5 --from-chain 1 --slippage 1 -mm swap quote --from ETH --to pUSD --amount 0.5 --from-chain 1 --to-chain 137 --to-address 0x742d...f2bD18 -mm swap quote --from ETH --to USDC --amount 1 --from-chain 1 --to-chain 42161 --refuel +# Same-chain swap quote: 1 ETH -> USDC on Ethereum +mm swap quote --from ETH --to USDC --amount 1 --from-chain 1 --toon +# Cross-chain bridge quote: 100 USDC Ethereum -> Polygon, 1% slippage +mm swap quote --from USDC --to USDC --amount 100 --from-chain 1 --to-chain 137 --slippage 1 --toon +# Bridge to another recipient with destination gas top-up +mm swap quote --from USDC --to USDC --amount 50 --from-chain 1 --to-chain 42161 --to-address 0x742d35Cc6634C0532925a3b844Bc454e4438f44e --refuel --toon ``` -## `swap execute` Command +## mm swap execute -Execute a swap or bridge, either by referencing a previous quote ID or by providing parameters for an automatic re-quote and execute. +Execute a swap or bridge. State-changing. -### Syntax +Two disjoint modes — choose exactly one: + +- If the user reviewed a quote from `mm swap quote` → use mode A (`--quote-id`). Always prefer this. +- If the user explicitly waived quote review and asked for immediate execution → mode B (re-quote and execute). Otherwise never use mode B: it executes a price the user never saw. + +### Mode A: execute a reviewed quote (preferred) + +#### Syntax ```bash -mm swap execute --quote-id [--password ] -mm swap execute --from --to --amount --from-chain [--to-chain ] [--to-address
] [--slippage ] [--refuel] [--password ] +mm swap execute --quote-id ``` -### Supported Flags - -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--quote-id` | Yes (unless re-quote args given) | Quote ID returned by `mm swap quote`. If omitted, provide `--from`, `--to`, `--amount`, and `--from-chain` to re-quote | -| `--from` | Yes (unless `--quote-id`) | Source token symbol | -| `--to` | Yes (unless `--quote-id`) | Destination token symbol | -| `--amount` | Yes (unless `--quote-id`) | Amount to swap | -| `--from-chain` | Yes (unless `--quote-id`) | Source EVM chain ID | -| `--to-chain` | No | Destination EVM chain ID. Defaults to `--from-chain` for same-chain swaps | -| `--to-address` | No | Recipient address for bridged output tokens. Only valid for cross-chain swaps. Defaults to the signer's wallet. Persisted quotes retain the recipient for `--quote-id` execution | -| `--slippage` | No | Maximum slippage as a percentage, 0-100 (defaults to 0.5) | -| `--refuel` | No | Bundle a destination native-gas top-up into a cross-chain re-quote. Only valid when `--to-chain` differs from `--from-chain`; ignored when executing by `--quote-id` (the persisted quote already carries the flag). See [Refuel](#refuel) | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--quote-id` | string from `mm swap quote` | The reviewed quote to execute. A persisted quote retains its recipient and refuel setting | -### Validation Rules +When `--quote-id` is given, all re-quote flags are ignored. -- Either `--quote-id` OR the full set of re-quote flags (`--from`, `--to`, `--amount`, `--from-chain`) must be provided. -- When `--quote-id` is given, re-quote flags are ignored. +### Mode B: re-quote and execute (only on explicit user request) -### Example +#### Syntax ```bash -mm swap execute --quote-id -mm swap execute --from ETH --to USDC --amount 0.5 --from-chain 1 -mm swap execute --from USDC --to USDT --amount 100 --from-chain 137 --to-chain 137 --slippage 1 +mm swap execute --from --to --amount --from-chain [--to-chain ] [--slippage ] [--to-address
] [--refuel] ``` -## `swap status` Command +Required: `--from`, `--to`, `--amount`, `--from-chain`. Optional: `--to-chain`, `--slippage`, +`--to-address`, `--refuel` — same formats and same cross-chain-only rules as `mm swap quote`. -Check the status of a previously executed swap or bridge by its quote ID. +Global flags and `--wallet-timeout` apply — see SKILL.md § Global flags. BYOK with an encrypted +mnemonic: set `MM_PASSWORD` first (references/concepts.md). -### Syntax +### Output + +```json +{"ok": true, "data": {"pollingId": "...", "quoteId": "...", "txHash": "..."}} +``` + + +Capture: `quoteId` → use as `` in `mm swap status --quote-id `. + +### Async + +Execution creates a wallet job (`pollingId`) — track via references/wallet-requests.md and show the +job's `intent` to the user. Then poll `mm swap status --quote-id ` until terminal. + +### Confirm before executing + +Show the user ALL of: from token, to token, amount, source chain, destination chain (if +cross-chain), slippage, expected output (`destAssetAmount` scaled by decimals), minimum +received (`minDestAssetAmount` scaled), fees, recipient (if `--to-address`), destination gas +top-up (if `--refuel`). Do not run until the user approves. + +### Examples ```bash -mm swap status --quote-id [--tx-hash ] +# Mode A: execute the reviewed quote +mm swap execute --quote-id 0x20a57409b6f9702cd1919983ec7a480b6e20e70d22e9af051c9622f7ab50f2e4 --toon +# Mode B (user explicitly waived quote review): swap 0.5 ETH -> USDC on Ethereum +mm swap execute --from ETH --to USDC --amount 0.5 --from-chain 1 --toon ``` -### Supported Flags +## mm swap status -| Name | Required | Description | -| --- | --- | --- | -| `--quote-id` | Yes | Quote ID returned by `mm swap quote` | -| `--tx-hash` | No | Source transaction hash. Overrides the stored hash from execute | +Check the status of a previously executed swap or bridge by its quote ID. Read-only. -### Example +### Syntax ```bash -mm swap status --quote-id -mm swap status --quote-id --tx-hash 0xabc...123 +mm swap status --quote-id [--tx-hash ] ``` -## Refuel +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--quote-id` | string from `mm swap quote` | Quote that was executed | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--tx-hash` | stored hash from execute | `^0x[0-9a-fA-F]{64}$` | Source transaction hash override | + +Global flags apply — see SKILL.md § Global flags. + +### Output -Refuel bundles a small amount of the **destination chain's native gas token** into a cross-chain quote, so the recipient lands with gas to spend even if they arrive with a zero native balance. This is useful when bridging to a chain where the recipient holds none of the gas token (e.g. bridging USDC to Arbitrum with no ETH there). +```json +{"ok": true, "data": {"status": "...", "srcTxHash": "...", "destTxHash": "..."}} +``` + + +Repeat until the status is terminal (completed or failed). Bridges: the destination side can +lag well behind the source transaction. -- **Opt-in only.** Refuel is never enabled automatically — pass `--refuel` to request it. -- **Cross-chain only.** `--refuel` is only meaningful when `--to-chain` differs from `--from-chain`. It has no effect on same-chain swaps. -- **Not for native-asset destinations.** Do not use `--refuel` when the destination token is the destination chain's native gas asset (e.g. bridging ETH from Base into ETH on Arbitrum). There is nothing to top up, and the backend returns **0 quotes** for the route — surfaced as a `NO_QUOTES` error. Only use `--refuel` when bridging into a non-native token (e.g. USDC). -- **Best-effort.** Only some bridge aggregators offer a gas top-up. When `--refuel` is set, the CLI prefers a quote that includes the top-up; if no aggregator offers one for that route, it falls back to the best regular quote (no error). -- **Output.** When a refuel-bearing quote is selected, the quote includes a `refuel` step describing the native-gas top-up (source amount spent and destination native amount received), and the resolved request shows `refuel: true`. +### Examples ```bash -# Bridge USDC to Arbitrum and top up ETH for gas on arrival -mm swap quote --from USDC --to USDC --amount 50 --from-chain 1 --to-chain 42161 --refuel +mm swap status --quote-id 0x20a57409b6f9702cd1919983ec7a480b6e20e70d22e9af051c9622f7ab50f2e4 --toon ``` -## Notes - -- If the chain is not mentioned by the user, ask for the chain. -- Use `mm chains list` to discover supported chain IDs. -- Same-chain swap: omit `--to-chain` (it defaults to `--from-chain`). -- Cross-chain bridge: set `--to-chain` to a different chain than `--from-chain`. The CLI automatically routes through a bridge. -- The typical flow is: `mm swap quote` to preview, then `mm swap execute --quote-id ` to submit. -- You can skip the quote step by passing all swap parameters directly to `mm swap execute`. -- Use `mm swap status --quote-id ` to track progress after execution. -- If the user asks to "bridge" tokens, use the `swap` commands with different `--from-chain` and `--to-chain` values. -- If the user is bridging to a chain where they hold no native gas token, suggest `--refuel` to top up gas on the destination (cross-chain only). See [Refuel](#refuel). -- After execution, track swap progress with `mm swap status --quote-id `. +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `NO_QUOTES` | No route for this pair/amount; or `--refuel` used with a native-gas destination token | Try another amount/pair; verify the token exists on the chain (`mm token list search`); if `--refuel` was set, re-quote without it | +| `INVALID_SWAP_PARAMS` | `--to-address is not supported for same-chain swaps; output always goes to your wallet.` | Omit `--to-address`, or use a cross-chain swap (different `--from-chain` and `--to-chain`) to redirect output | +| `MISSING_QUOTE_ID` / `MISSING_SWAP_PARAMS` | Neither `--quote-id` nor the full re-quote flag set was provided | Provide `--quote-id`, or all of `--from --to --amount --from-chain` | +| `QUOTE_NOT_FOUND` | Quote ID expired or unknown | Re-run `mm swap quote`, re-confirm with the user, execute the new ID | +| `NATIVE_ASSET_UNSUPPORTED` | Native asset not supported for this swap route | Use the wrapped token or another pair | +| `EXECUTE_FAILED` | Swap execution failed (e.g. insufficient balance or gas) | Check `mm wallet balance --chain `; re-quote and retry | +| `STATUS_UNAVAILABLE` | Status backend temporarily unavailable | Retry `mm swap status` after a short delay | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/token.md b/skills/metamask-agent-wallet/references/token.md new file mode 100644 index 0000000..f10cd8b --- /dev/null +++ b/skills/metamask-agent-wallet/references/token.md @@ -0,0 +1,183 @@ +# mm token + +Read-only token discovery and metadata: search by symbol/name, curated lists, and CAIP-19 +asset metadata (including security signals). + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Build CAIP-19 identifiers by string substitution — see references/concepts.md § CAIP identifiers. +- Multi-step discovery pattern (symbol → CAIP-19 → price): workflows/market-data.md. + +## mm token list search + +Search tokens by symbol or name across one or more chains. Read-only. This is the standard +way to resolve a symbol to a contract address. + +### Syntax + +```bash +mm token list search --query [--chain ] [--limit ] [--after ] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--query` | symbol or name string | e.g. `USDC`, `Wrapped Ether` | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--chain` | active wallet chain, else `eip155:1` | comma-separated chain IDs or CAIP-2 IDs, no spaces (`1,137`) | Chains to search. Options: `mm token networks` | +| `--limit` | `10` | integer 1-500 | Maximum results | +| `--after` | — | cursor string | Pagination cursor: `nextCursor` from a previous response | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + query: USDC + networks[1]: "eip155:1" + tokens[2]{symbol,name,address,decimals,chainId,price,priceChangePct24h,marketCap,volume24hUsd}: + USDC,USDC,0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48,6,"eip155:1",1.000022769440105,null,73203337961,11222199505 + AUSDC,Aave USDC,0xbcca60bb61934080951369a648fb03df4f96263c,6,"eip155:1",1.003,null,0,19337.26 + nextCursor: MQ== + hasNextPage: true +``` + +Capture: `address` + `chainId` → build `` as `/erc20:
` for +`mm token assets`, `mm price spot`, and `mm price history`. + +### Examples + +```bash +mm token list search --query USDC --chain 1 --limit 2 --toon +mm token list search --query "Wrapped Ether" --chain 1,8453 --limit 5 --toon +``` + +## mm token list popular | trending | top-gainer + +Curated token lists for one chain. Read-only. Three sibling commands with identical flags. + +### Syntax + +```bash +mm token list popular [--chain ] +mm token list trending [--chain ] +mm token list top-gainer [--chain ] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--chain` | active wallet chain, else `eip155:1` | chain ID or CAIP-2 ID (`1` or `eip155:1`) | Chain to list. Options: `mm token networks` | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + tokens[N]{symbol,name,address,decimals,chainId,price,priceChangePct24h,marketCap,volume24hUsd}: … +``` + + +### Examples + +```bash +mm token list popular --chain 1 --toon +mm token list trending --chain 137 --toon +mm token list top-gainer --chain 8453 --toon +``` + +## mm token assets + +Fetch metadata for one or more CAIP-19 asset IDs. Read-only. Use `--include-token-security-data` +to surface scam/risk signals before the user trades an unfamiliar token. + +### Syntax + +```bash +mm token assets --asset-ids [--include-market-data] [--include-token-security-data] [--include-labels] [--include-aggregators] [--include-coingecko-id] [--include-occurrences] [--include-rwa-data] +``` + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--asset-ids` | one or more ``, comma-separated, no spaces | Assets to describe (e.g. `eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`) | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--include-market-data` | off | boolean flag | Market cap, volume, price data | +| `--include-token-security-data` | off | boolean flag | Security signals (scam risk, honeypot detection) | +| `--include-labels` | off | boolean flag | Token labels and categories | +| `--include-aggregators` | off | boolean flag | Aggregator sources listing the token | +| `--include-coingecko-id` | off | boolean flag | CoinGecko identifier | +| `--include-occurrences` | off | boolean flag | Occurrence count across chains | +| `--include-rwa-data` | off | boolean flag | Real-world asset data | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + assets[N]{assetId,symbol,name,decimals,…}: one row per requested asset ID +``` + + +### Examples + +```bash +mm token assets --asset-ids eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --include-market-data --include-token-security-data --toon +mm token assets --asset-ids eip155:1/slip44:60,eip155:137/erc20:0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 --include-labels --toon +``` + +## mm token networks + +List CAIP-2 networks supported by the Token API. Read-only. + +### Syntax + +```bash +mm token networks +``` + +No required or optional flags. Global flags apply — see SKILL.md § Global flags. + +### Output + +```text +ok: true +data: + networks[N]: "eip155:1","eip155:10","eip155:56",… +``` + + +### Examples + +```bash +mm token networks --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `INVALID_ASSET_ID` | Malformed `--asset-ids` value | Rebuild the CAIP-19 per references/concepts.md; get the address from `mm token list search` | +| `INVALID_CHAIN` | Chain not supported by the Token API | Run `mm token networks` and pick a listed chain | +| `INVALID_LIMIT` | `--limit` outside 1-500 | Re-run with an integer between 1 and 500 | +| `TOKEN_NOT_FOUND` | No token matches the query or asset ID | Broaden `--chain`, try an alternate symbol/name, or ask the user for the contract address | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/transaction.md b/skills/metamask-agent-wallet/references/transaction.md index 69d0cfa..0ac540c 100644 --- a/skills/metamask-agent-wallet/references/transaction.md +++ b/skills/metamask-agent-wallet/references/transaction.md @@ -1,51 +1,97 @@ -# Transaction Commands +# mm wallet send-transaction -Use `wallet send-transaction` to send raw EVM transactions with the active wallet. +Send a raw EVM transaction from the active wallet. State-changing. -## `wallet send-transaction` Command +## Prerequisites -Send a raw EVM transaction using the active wallet. +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- If the user did not name a chain, ask — do not guess. Discover chain IDs with `mm chains list`. +- If the calldata was not constructed by you, decode it FIRST with + `mm decode --payload ` (references/decode.md) and confirm the decoded intent with + the user before sending. Apply the suspicious-payload checklist in references/concepts.md. +- For simple native/ERC-20 transfers prefer `mm transfer` (references/transfer.md). + +## mm wallet send-transaction ### Syntax ```bash -mm wallet send-transaction --chain-id --payload '' [--wait] [--password ] +mm wallet send-transaction --chain-id --payload [--wait] [--intent ""] +``` + +`` is a JSON string, single-quoted in shell: + +```json +{ + "to": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", + "value": "0xde0b6b3a7640000", + "data": "0x" +} ``` -### Supported Flags +| Key | Required | Format | Description | +| --- | --- | --- | --- | +| `to` | Yes | `^0x[0-9a-fA-F]{40}$` | Destination address | +| `value` | No | `0x`-prefixed hex wei, NOT decimal | Native amount. Convert decimals with `python3 "$SKILL_DIR/scripts/amount_to_hex.py" 18` | +| `data` | No | `^0x[0-9a-fA-F]*$` | Calldata (`0x` for plain sends) | + +Optional payload keys: `gas`, `nonce`, `maxFeePerGas`, `maxPriorityFeePerGas`. + +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--chain-id` | Yes | EVM chain ID as a positive integer (e.g. 1, 137) | -| `--payload` | Yes | Transaction as a JSON string with at least a `to` address (e.g. `'{"to":"0x...","value":"0x0"}'}`) | -| `--wait` | No | Block until the transaction completes (server-wallet mode only; BYOK returns immediately) | -| `--intent` | No | Human-readable summary of what the transaction does, forwarded with the request | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--chain-id` | integer `^\d+$` | EVM chain ID (`1` = Ethereum, `137` = Polygon) | +| `--payload` | JSON string, single-quoted | Transaction payload (schema above) | -### Example +### Optional flags -```bash -mm wallet send-transaction --chain-id 1 --payload '{"to":"0x742d...","value":"0xde0b6b3a7640000","data":"0x"}' --intent "Send 1 ETH to 0x742d...f2bD18" -mm wallet send-transaction --chain-id 1 --payload '{"to":"0x...","value":"0x0","data":"0xabcdef"}' --wait -mm wallet send-transaction --chain-id 1 --payload '...' --toon -``` +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the transaction completes (server-wallet mode only; BYOK returns immediately) | +| `--intent` | none | quoted text | Human-readable summary of what the transaction does, forwarded with the request | -## Transaction Payload +Global flags and `--wallet-timeout` apply — see SKILL.md § Global flags. BYOK with an encrypted +mnemonic: set `MM_PASSWORD` first (references/concepts.md). -The `--payload` flag takes a JSON string with transaction fields: +### Output ```json -{ - "to": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18", - "value": "0xde0b6b3a7640000", - "data": "0x" -} +{"ok": true, "data": {"pollingId": "..."}} ``` + + +Capture: `pollingId` → use as `` in `mm wallet requests watch --polling-id `. + +### Async + +Without `--wait` the command returns a `pollingId` immediately. Track it via +references/wallet-requests.md and show the request's `intent` string to the user. + +### Confirm before executing -Optional fields: `gas`, `nonce`, `maxFeePerGas`, `maxPriorityFeePerGas`. The `value` field must be 0x-prefixed hex, not a decimal wei string. +Show the user ALL of: `to` address, native `value` in human units, decoded meaning of `data` +(via `mm decode` when non-empty), chain, and the `--intent` text. Do not run until the user +approves. -## Notes +### Examples + +```bash +# Send 1 ETH on Ethereum mainnet +mm wallet send-transaction --chain-id 1 --payload '{"to":"0x742d35Cc6634C0532925a3b844Bc454e4438f44e","value":"0xde0b6b3a7640000","data":"0x"}' --intent "Send 1 ETH to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e" --wait --toon +# ERC-20 transfer of 1 USDC on Ethereum via calldata (decode-confirmed first) +mm wallet send-transaction --chain-id 1 --payload '{"to":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","value":"0x0","data":"0xa9059cbb000000000000000000000000742d35cc6634c0532925a3b844bc454e4438f44e00000000000000000000000000000000000000000000000000000000000f4240"}' --intent "Transfer 1 USDC to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e" --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `MISSING_TRANSACTION_PAYLOAD` | `--payload` missing | Provide the JSON payload | +| `INVALID_TRANSACTION_PAYLOAD` | Payload not valid JSON or missing `to` | Re-check the schema above; `value` must be hex, not decimal | +| `INVALID_TO` | `to` is not a valid address | Ask the user for the full 40-hex address | +| `INVALID_QUANTITY` | `value` not `0x`-prefixed hex | Convert with `scripts/amount_to_hex.py` | +| `WALLET_ERROR` | Insufficient balance/gas or on-chain revert | Run `mm wallet balance --chain `; inspect with `mm decode`; retry after funding | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | -- If the chain is not mentioned by the user, ask for the chain. -- When the `data`/calldata is unfamiliar or was not constructed by you, decode it first with `mm decode --payload <0x-calldata>` and confirm the intent before sending. See `references/decode.md`. -- In server-wallet mode, send-transaction returns a `pollingId` when `--wait` is omitted. See `references/polling.md` to track requests. +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/transfer.md b/skills/metamask-agent-wallet/references/transfer.md index 4286708..60ec06c 100644 --- a/skills/metamask-agent-wallet/references/transfer.md +++ b/skills/metamask-agent-wallet/references/transfer.md @@ -1,38 +1,72 @@ -# Transfer Commands +# mm transfer -Use `transfer` to send native token or ERC-20 tokens from the active wallet. +Send native or ERC-20 tokens from the active wallet to a recipient address. State-changing. -## `transfer` Command +## Prerequisites -Transfer native currency or ERC-20 tokens to a recipient address. +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Recipient is a full `0x` + 40-hex address. ENS names are not supported. +- If the user did not name a chain, ask — do not guess. Discover chain IDs with `mm chains list`. + +## mm transfer ### Syntax ```bash -mm transfer --to
--amount --chain-id --token [--wait] [--password ] +mm transfer --to
--amount --chain-id --token [--wait] ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--to` | Yes | Recipient hex address (e.g. 0x742d...f2bD18). ENS is not supported. | -| `--amount` | Yes | Human-readable amount to transfer (e.g. 0.5, 100) | -| `--chain-id` | Yes | EVM chain ID as a positive integer (e.g. 1, 137) | -| `--token` | Yes | Token symbol or ERC-20 contract address (e.g. ETH, USDC, 0xa0b8...) | -| `--wait` | No | Block until the transfer completes (server-wallet mode only; BYOK returns immediately) | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +| `--to` | `^0x[0-9a-fA-F]{40}$` | Recipient address | +| `--amount` | decimal `^\d+\.?\d*$`, > 0 | Human-readable amount (`0.5`, `100`). Not wei. | +| `--chain-id` | integer `^\d+$` | EVM chain ID (`1` = Ethereum, `137` = Polygon) | +| `--token` | symbol or `
` | Native token: symbol (`ETH`, `POL`). ERC-20: the contract address, not the symbol. | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--wait` | off | boolean flag | Block until the transfer completes (server-wallet mode only; BYOK returns immediately) | + +Global flags and `--wallet-timeout` apply — see SKILL.md § Global flags. BYOK with an encrypted +mnemonic: set `MM_PASSWORD` first (references/concepts.md). + +### Output + +```json +{"ok": true, "data": {"pollingId": "..."}} +``` + -### Example +Capture: `pollingId` → use as `` in `mm wallet requests watch --polling-id `. + +### Async + +Without `--wait` the command returns a `pollingId` immediately. Track it via +references/wallet-requests.md and show the request's `intent` string to the user. + +### Confirm before executing + +Show the user ALL of: recipient, amount, token, chain. Do not run until the user approves. + +### Examples ```bash -mm transfer --to 0x742d...f2bD18 --amount 0.5 --chain-id 1 --token ETH -mm transfer --to 0x742d...f2bD18 --amount 100 --chain-id 137 --token USDC -mm transfer --to 0x742d...f2bD18 --amount 1.0 --chain-id 1 --token ETH --toon +# 0.5 ETH on Ethereum mainnet, wait for completion +mm transfer --to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e --amount 0.5 --chain-id 1 --token ETH --wait --toon +# 100 USDC on Polygon, by contract address +mm transfer --to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e --amount 100 --chain-id 137 --token 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 --toon ``` -## Notes +### Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `ValidationError` | Malformed flag value | Re-check each value against the table above; ask the user for the full value | +| `WALLET_ERROR` | Insufficient balance or gas | Run `mm wallet balance --chain `; offer a swap or bridge, then retry | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | -- If the chain is not mentioned by the user, ask for the chain. -- Use `mm chains list` to discover supported chain IDs. -- In server-wallet mode, transfer returns a `pollingId` when `--wait` is omitted. See `references/polling.md` to track requests. +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/tx-history.md b/skills/metamask-agent-wallet/references/tx-history.md index a4f5d2d..edb94fc 100644 --- a/skills/metamask-agent-wallet/references/tx-history.md +++ b/skills/metamask-agent-wallet/references/tx-history.md @@ -1,37 +1,110 @@ -# Transaction history command +# mm tx -Use `mm tx history` to list recent transactions for the active wallet or specific addresses. +Look up a transaction by hash and list recent transactions for your wallets. -## `tx history` command +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- History covers EVM wallets in your account roster only. + +## mm tx + +Look up a single transaction by hash. Read-only. ### Syntax ```bash -mm tx history [--addresses ] [--chain ] [--type ] [--limit ] +mm tx --hash [--chain ] ``` -### Supported flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--addresses` | No | Comma-separated EVM wallet addresses to include. Defaults to all EVM wallets for your account | -| `--chain` | No | Comma-separated chain filters (e.g. `1,137` or `eip155:1`). Run `mm chains list` to see options | -| `--type` | No | Filter by direction (`in`, `out`, `self`) or transaction category/type | -| `--limit` | No | Maximum number of transactions to return (1-500, default 50) | +| `--hash` | `^0x[0-9a-fA-F]{64}$` | Transaction hash | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--chain` | probe common EVM chains | `` or `` (`1` or `eip155:1`) | Chain to query; pass it when known — probing is slower | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +``` +ok: true +data: + status: success + receipt: + hash: 0x21333b4f532bbc967275c03c21664cc753cbd527e234d17a39134cbc19497bfa + timestamp: "2026-06-17T15:11:47.000Z" + chainId: 1 + blockNumber: 25338081 + gasUsed: 21000 + effectiveGasPrice: "2502497925" + value: "4340000000000000" + to: 0xae92af9d910e7df9914caa34936dd27beaf4220b + from: 0x7c2b3e65ef2b18235e2d24266f92854a70207483 + isError: false +``` -### Example +### Examples + +```bash +mm tx --hash 0x21333b4f532bbc967275c03c21664cc753cbd527e234d17a39134cbc19497bfa --chain 1 --toon +``` + +## mm tx history + +List recent transactions for the active wallet (or specific addresses). Read-only. + +### Syntax + +```bash +mm tx history [--chain ] [--type ] [--limit ] [--addresses
] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--addresses` | all EVM wallets in roster | comma-separated `
` | Wallet addresses to include | +| `--chain` | all | comma-separated `` or `` (`1,137` or `eip155:1`) | Chain filter; discover with `mm chains list` | +| `--type` | all | `in`, `out`, `self`, or a category/type | Filter by direction or transaction type | +| `--limit` | 50 | integer 1-500 | Maximum number of transactions to return | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +``` +ok: true +data: + items[3]{txHash,type,status,summary,ts}: + 0xc777ff9dcde0f2958f15d156a9695f3277121f656e16438957d93e897297fc82,TRANSFER,success,Received 1 TWT from 0x8b7e…6447,"2026-06-24T09:24:43.000Z" + 0x21333b4f532bbc967275c03c21664cc753cbd527e234d17a39134cbc19497bfa,STANDARD,success,Sent 0.00434 ETH to 0xae92…220b,"2026-06-17T15:11:47.000Z" + unprocessedNetworks: [] + warnings: [] +``` + +Capture: `txHash` → use as `` in `mm tx --hash `. + +### Examples ```bash -mm tx history mm tx history --limit 10 --toon -mm tx history --chain 1,8453 -mm tx history --type out -mm tx history --addresses 0x742d...f2bD18 --chain 137 --limit 100 +mm tx history --chain 1,8453 --type out --toon +mm tx history --addresses 0x7c2b3e65ef2b18235e2d24266f92854a70207483 --chain 137 --limit 100 --toon ``` -### Notes +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `INVALID_LIMIT` | `--limit` outside 1-500 (e.g. `0`) | Pass an integer between 1 and 500 | +| `NO_HISTORY_WALLETS` | Account has no EVM wallets in roster | Create one via references/wallet.md, then retry | +| `INVALID_CHAIN` | Unknown chain filter | Run `mm chains list` and use a listed `chainId` or `caip2` | -- If you omit `--addresses`, the command queries all EVM wallets for your account. -- Addresses must be 0x-prefixed EVM addresses. -- `--limit` must be between 1 and 500. Values outside this range return an `INVALID_LIMIT` error. -- If your account has no EVM wallets, the command returns a `NO_HISTORY_WALLETS` error. +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/wallet-requests.md b/skills/metamask-agent-wallet/references/wallet-requests.md new file mode 100644 index 0000000..c874474 --- /dev/null +++ b/skills/metamask-agent-wallet/references/wallet-requests.md @@ -0,0 +1,96 @@ +# mm wallet requests + +Track asynchronous wallet jobs by `pollingId`. In server-wallet mode, signing and transaction +commands return a `pollingId` instead of an immediate result (references/concepts.md § Async +job model). Both commands are server-wallet mode only. + +## Prerequisites + +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Requests carry a human-readable `intent` string (e.g. `Transfer 0.5 ETH to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e`). + Always surface the `intent` so the user can see what they are approving. + +## mm wallet requests list + +List all pending wallet requests. Read-only. + +### Syntax + +```bash +mm wallet requests list [--no-sync] +``` + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--sync` | on | boolean flag | Refetch live status for non-terminal entries; pass `--no-sync` to skip the refresh | + +Global flags apply — see SKILL.md § Global flags. + +### Output + +``` +ok: true +data: + requests: [] +``` + +When requests are pending, each entry includes `pollingId`, `status`, and `intent`. +Capture: `pollingId` → use as `` in `mm wallet requests watch --polling-id `. + +### Examples + +```bash +mm wallet requests list --toon +mm wallet requests list --no-sync --toon +``` + +## mm wallet requests watch + +Wait for a specific wallet request to complete. Read-only (it only observes the job). MFA +prompts are surfaced once when a job enters the `AWAITING_MFA` state. + +### Syntax + +```bash +mm wallet requests watch --polling-id +``` + +There is no positional form — `--polling-id` is required. + +### Required flags + +| Flag | Value format | Description | +| --- | --- | --- | +| `--polling-id` | string from a prior command's output | Polling ID to wait on; list pending IDs with `mm wallet requests list` | + +### Optional flags + +None beyond global flags. + +Global flags and `--wallet-timeout` apply — see SKILL.md § Global flags. + +### Output + +```json +{"ok": true, "data": {"pollingId": "...", "status": "COMPLETED", "intent": "Transfer 0.5 ETH to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e"}} +``` + + +### Examples + +```bash +mm wallet requests watch --polling-id 7f3c2a9e-1b4d-4e8a-9c6f-2d5b8a1e4c7f --toon +mm wallet requests watch --polling-id 7f3c2a9e-1b4d-4e8a-9c6f-2d5b8a1e4c7f --wallet-timeout 300 --toon +``` + +## Errors + +| Code | Cause | Recovery | +| --- | --- | --- | +| `MISSING_ID` | `--polling-id` missing | Run `mm wallet requests list`, pick the ID, retry | +| `MISSING_FLAG` | Required flag omitted in headless mode | Pass `--polling-id` explicitly | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/wallet.md b/skills/metamask-agent-wallet/references/wallet.md index 84d0cf1..6c4da15 100644 --- a/skills/metamask-agent-wallet/references/wallet.md +++ b/skills/metamask-agent-wallet/references/wallet.md @@ -1,158 +1,188 @@ -# Wallet Commands +# mm wallet -Use the `wallet` commands to create, list, select, inspect wallets, and check balances. +Create, list, select, and inspect wallets; check balances; manage trading mode and policy. -## `wallet create` Command +## Prerequisites -Create a new wallet under the authenticated account. +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Trading-mode and policy commands apply to the active server wallet (server-wallet mode only). +- `--chain-namespace` accepts only the literal value `evm`. +- Wallet selector flags (used by select/show): `--address
` (preferred), `--id `, `--name `, `--chain-namespace evm`. Pass exactly one selector. + +## mm wallet create + +Create a new wallet under the authenticated account. State-changing. Synchronous — no +`pollingId` is created. ### Syntax ```bash -mm wallet create [--chain-namespace ] [--name ] [--trading-mode ] [--password ] +mm wallet create --chain-namespace evm --name --trading-mode ``` -### Supported Flags +### Required flags -| Name | Required | Description | -| --- | --- | --- | -| `--chain-namespace` | No | Wallet chain namespace: `evm` (EIP-155) (allowed: `evm`) | -| `--name` | No | Display name for the wallet | -| `--trading-mode` | No | `guard` enforces outflow/whitelist policies and blocks malicious transactions. `beast` skips policy checks but still blocks malicious transactions (allowed: `guard`, `beast`) | -| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] | +None — but always pass flags explicitly in scripts (a TTY may otherwise prompt). -### Example +### Optional flags -```bash -mm wallet create --chain-namespace evm -mm wallet create --chain-namespace evm --name "Trading" -mm wallet create --chain-namespace evm --name "Fast Trading" --trading-mode beast -``` +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--chain-namespace` | `evm` | literal `evm` | Wallet chain namespace (EIP-155) | +| `--name` | auto | string | Display name for the wallet | +| `--trading-mode` | `guard` | `guard` or `beast` | Server wallets only. `guard` enforces outflow/whitelist policies and blocks malicious transactions; `beast` skips policy checks but still blocks malicious transactions | -## `wallet list` Command +Global flags apply — see SKILL.md § Global flags. BYOK with an encrypted mnemonic: set +`MM_PASSWORD` first (references/concepts.md). BYOK with an +encrypted mnemonic: set `MM_PASSWORD` first (references/concepts.md). -List all wallets associated with the authenticated account. +### Confirm before executing -### Syntax +Only if `--trading-mode beast`: warn that policy checks will be skipped for this wallet and +wait for approval. Otherwise no confirmation needed (wallet management). + +### Examples ```bash -mm wallet list [--chain-namespace ] [--toon] +mm wallet create --chain-namespace evm --name "Trading" --trading-mode guard --toon +mm wallet create --chain-namespace evm --name "Fast Trading" --trading-mode beast --toon ``` -### Supported Flags +## mm wallet list -| Name | Required | Description | -| --- | --- | --- | -| `--chain-namespace` | No | Filter by namespace: `evm` (EIP-155) (allowed: `evm`) | +List all wallets for the authenticated account. Read-only. +Optional flags: `--chain-namespace evm` (namespace filter; default all). +Global flags apply — see SKILL.md § Global flags. -### Example +### Syntax ```bash -mm wallet list -mm wallet list --chain-namespace evm --toon +mm wallet list --toon ``` -## `wallet select` Command +### Output + +``` +ok: true +data: + mode: server + chainNamespace: null + wallets[1]{walletId,address,name,chainNamespace,tradingMode}: + null,0x7c2b3e65ef2b18235e2d24266f92854a70207483,Server EVM Wallet 1,evm,beast +``` -Switch the active wallet used for subsequent commands. +Capture: `address` → use as `
` in `mm wallet select --address
`. + +## mm wallet select + +Switch the active wallet for subsequent commands. State-changing (local session only; +synchronous, no `pollingId`, no user confirmation needed — state the new active address after). +Optional flags: one selector from Prerequisites. Global flags apply — see SKILL.md § Global flags. ### Syntax ```bash -mm wallet select [--chain-namespace ] [--id ] [--address
] [--name ] +mm wallet select --address
``` -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--chain-namespace` | No | Filter by namespace: `evm` (EIP-155) (allowed: `evm`) | -| `--id` | No | Wallet ID | -| `--address` | No | Wallet address (0x-prefixed hex) | -| `--name` | No | Wallet display name | - -### Example +### Examples ```bash -mm wallet select --address 0x742d...f2bD18 -mm wallet select --name "Trading" +mm wallet select --address 0x7c2b3e65ef2b18235e2d24266f92854a70207483 --toon ``` -## `wallet show` Command +## mm wallet show -Display details for a specific wallet or the currently active wallet. +Show details for a specific wallet, or the active wallet when no selector is passed. Read-only. +Optional flags: one selector from Prerequisites. Global flags apply — see SKILL.md § Global flags. ### Syntax ```bash -mm wallet show [--chain-namespace ] [--id ] [--address
] [--name ] +mm wallet show [--address
] ``` -### Supported Flags - -| Name | Required | Description | -| --- | --- | --- | -| `--chain-namespace` | No | Filter by namespace: `evm` (EIP-155) (allowed: `evm`) | -| `--id` | No | Wallet ID | -| `--address` | No | Wallet address (0x-prefixed hex) | -| `--name` | No | Wallet display name | - -### Example +### Examples ```bash -mm wallet show -mm wallet show --address 0x742d...f2bD18 +mm wallet show --toon ``` -## `wallet address` Command +## mm wallet address -Print the address of the currently active wallet. +Print the active wallet address. Read-only. +Optional flags: `--chain-namespace evm`. Global flags apply — see SKILL.md § Global flags. ### Syntax ```bash -mm wallet address [--chain-namespace ] +mm wallet address --toon ``` -### Supported Flags +## mm wallet balance -| Name | Required | Description | -| --- | --- | --- | -| `--chain-namespace` | No | Wallet chain namespace: `evm` (EIP-155) (allowed: `evm`) | +Show native and token balances for the active wallet. Read-only. -### Example +### Syntax ```bash -mm wallet address -mm wallet address --chain-namespace evm +mm wallet balance [--chain ] [--token ] [--currency ] ``` -## `wallet add-fund` Command +### Optional flags -Show a QR code and address to fund the currently active wallet. In interactive mode (TTY or REPL), renders an ASCII QR code plus the address. In headless mode (`--json`, piped stdout), outputs the address only. +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--chain` | all chains | comma-separated `` or `` (`1,137` or `eip155:1`) | Chain filter; discover with `mm chains list` | +| `--token` | all tokens | symbol, `
`, or `` | Token filter (`USDC`, contract address, or CAIP-19 ID) | +| `--currency` | `usd` | fiat code (`usd`, `eur`) | Fiat currency for price conversion | +| `--address` | active wallet | `^0x[0-9a-fA-F]{40}$` | Read balances for a different wallet address | +| `--testnet` | off | boolean flag | Read balances via RPC on Arbitrum Sepolia, Amoy, and Sepolia | +| `--testnet-chain-id` | — | comma-separated `` (`421614,80002`) | EVM testnet chain IDs for on-chain RPC balance reads | +| `--token-contracts` | — | comma-separated `
` | ERC-20 contracts to read on testnet RPC chains; use with `--testnet-chain-id` | -### Syntax +Global flags apply — see SKILL.md § Global flags. + +### Output + +``` +ok: true +data: + currency: usd + totalValue: "0.28095449727443748075" + chains[2]: + - chain: "eip155:1" + name: Ethereum + totalValue: "0.27363681086398687225" + tokens[1]{token,amount,usdValue,assetId,name,type}: + ETH,"0.000157104527552167","0.27363681086398687225","eip155:1/slip44:60",Ether,native +``` + +### Examples ```bash -mm wallet add-fund [--chain-namespace ] +mm wallet balance --toon +mm wallet balance --chain 8453 --token USDC --toon +mm wallet balance --testnet-chain-id 421614 --token-contracts 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 --toon ``` -### Supported Flags +## mm wallet add-fund -| Name | Required | Description | -| --- | --- | --- | -| `--chain-namespace` | No | Wallet chain namespace: `evm` (EIP-155) (allowed: `evm`) | +Show a QR code and address to fund the active wallet. Read-only. TTY: ASCII QR plus address; +headless (`--json`/piped): address only. +Optional flags: `--chain-namespace evm`. Global flags apply — see SKILL.md § Global flags. -### Example +### Syntax ```bash -mm wallet add-fund mm wallet add-fund --toon ``` -## `wallet trading-mode get` Command +## mm wallet trading-mode get -Show the current trading mode and active server-wallet address for the selected wallet. Server-wallet mode only. +Show the trading mode of the active server wallet. Read-only. Takes NO flags beyond global +flags — the CLI's usage string for this command is wrong; never add `--chain-namespace` or +`--address` (rejected as nonexistent). Global flags apply — see SKILL.md § Global flags. ### Syntax @@ -160,38 +190,46 @@ Show the current trading mode and active server-wallet address for the selected mm wallet trading-mode get ``` -### Example +### Output -```bash -mm wallet trading-mode get +``` +ok: true +data: + mode: beast + address: 0x7c2b3e65ef2b18235e2d24266f92854a70207483 ``` -## `wallet trading-mode set` Command +## mm wallet trading-mode set -Set the trading mode for the active server wallet. Prompts for confirmation when switching to Beast mode. Rejects if the mode is already set or the session isn't in server-wallet mode. +Set the trading mode of the active server wallet. State-changing (synchronous, no `pollingId`). +The mode is a POSITIONAL argument — no flag form exists, and `--chain-namespace`/`--address` +are rejected. Global flags apply — see SKILL.md § Global flags. ### Syntax ```bash -mm wallet trading-mode set +mm wallet trading-mode set ``` -### Supported Flags +`` is `guard` or `beast` (definitions: references/concepts.md § Trading modes). -| Name | Required | Description | -| --- | --- | --- | -| `` | Yes | `guard` enforces outflow/whitelist policies and blocks malicious transactions. `beast` skips policy checks but still blocks malicious transactions | +### Confirm before executing + +Show the user: current mode (from `mm wallet trading-mode get`), requested mode. For `beast`, +warn that policy checks will be skipped. Do not run until the user approves. -### Example +### Examples ```bash -mm wallet trading-mode set guard -mm wallet trading-mode set beast +mm wallet trading-mode set guard --toon +mm wallet trading-mode set beast --toon ``` -## `wallet policy get` Command +## mm wallet policy get -Show the policy for the active server wallet. Server-wallet mode only. +Show the policy YAML for the active server wallet. Read-only. Takes NO flags beyond global +flags (its usage string is wrong; never add `--chain-namespace` or `--address`). +Global flags apply — see SKILL.md § Global flags. ### Syntax @@ -199,89 +237,72 @@ Show the policy for the active server wallet. Server-wallet mode only. mm wallet policy get ``` -### Supported Flags - -This command does not support additional flags beyond output format options. +### Output -### Example - -```bash -mm wallet policy get -mm wallet policy get --toon +``` +ok: true +data: + policy: "# Mimir Wallet Policy\nschema_version: 1\nwallet_address: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\"\n\naddresses:\n allowlist: []\n blocklist: []\n\nevm:\n allowed_chains:\n - 1\n - 8453\n outflow_limits_usd:\n rolling_24h: 0\n" + address: 0x7c2b3e65ef2b18235e2d24266f92854a70207483 ``` -## `wallet policy set` Command +Capture: `policy` → edit and reuse as `` in `mm wallet policy set --policy `. -Set the policy for the active server wallet. Server-wallet mode only. +## mm wallet policy set + +Set the policy YAML for the active server wallet. State-changing (synchronous, no `pollingId`). ### Syntax ```bash -mm wallet policy set --policy +mm wallet policy set --policy ``` -### Supported Flags +### Required flags -| Name | Required | Description | +| Flag | Value format | Description | | --- | --- | --- | -| `--policy` | Yes | Policy string to apply | - -### Example - -```bash -mm wallet policy set --policy "maxDailyOutflow: 1000" -``` - -## `wallet policy template` Command - -Show the project policy template. Server-wallet mode only. +| `--policy` | YAML string, single-quoted in shell | Full policy YAML to apply. Start from `mm wallet policy get` or `mm wallet policy template`, never from scratch | -### Syntax - -```bash -mm wallet policy template -``` +Global flags apply — see SKILL.md § Global flags. -### Supported Flags +### Confirm before executing -This command does not support additional flags beyond output format options. +Show the user the full policy YAML being applied and a summary of what changed versus the +current policy. Do not run until the user approves. -### Example +### Examples ```bash -mm wallet policy template -mm wallet policy template --toon +mm wallet policy set --policy 'schema_version: 1 +evm: + allowed_chains: + - 1 + - 8453 + outflow_limits_usd: + rolling_24h: 1000' --toon ``` -## `wallet balance` Command +## mm wallet policy template -Show native and token balances for the active wallet. +Show the project policy template YAML. Read-only. No flags beyond global flags. +Global flags apply — see SKILL.md § Global flags. ### Syntax ```bash -mm wallet balance [--currency ] [--chain ] [--token ] [--address
] [--testnet] [--testnet-chain-id ] [--token-contracts ] +mm wallet policy template --toon ``` -### Supported Flags +## Errors -| Name | Required | Description | +| Code | Cause | Recovery | | --- | --- | --- | -| `--currency` | No | Fiat currency code for price conversion (e.g. usd, eur) | -| `--chain` | No | Comma-separated chain filters (e.g. `1,137` or `eip155:1`). Run `mm chains list` to see options | -| `--token` | No | Filter by token symbol, contract address, or CAIP-19 asset ID (e.g. USDC, 0xa0b8...) | -| `--address` | No | Wallet address (0x-prefixed hex) | -| `--testnet` | No | Read balances via RPC on Arbitrum Sepolia, Amoy, and Sepolia testnets | -| `--testnet-chain-id` | No | Comma-separated EVM testnet chain IDs for on-chain RPC balance reads (e.g. `421614,80002`) | -| `--token-contracts` | No | Comma-separated ERC-20 contract addresses for testnet RPC chains (0x-prefixed hex). Use with `--testnet-chain-id` to read specific token balances on testnets | - -### Example - -```bash -mm wallet balance -mm wallet balance --chain 8453 -mm wallet balance --token USDC -mm wallet balance --currency eur -mm wallet balance --testnet -mm wallet balance --testnet-chain-id 421614 --token-contracts 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 -``` +| `WALLET_NOT_FOUND` | Selector matched no wallet | Run `mm wallet list` and retry with an exact `--address` | +| `INVALID_TRADING_MODE` | Mode not `guard` or `beast` | Retry with exactly `guard` or `beast` | +| `ALREADY_SET_TRADING_MODE` | Requested mode already active | Nothing to do; report the current mode | +| `UNSUPPORTED_NAMESPACE` | `--chain-namespace` value not `evm` | Use `evm` | +| `NOT_INITIALIZED` | Project has no wallet mode | Follow workflows/onboarding.md, then retry | +| `NO_TTY` | Interactive prompt in headless mode | Pass all flags explicitly | + +Full code list: references/errors.md. diff --git a/skills/metamask-agent-wallet/references/x402.md b/skills/metamask-agent-wallet/references/x402.md index 2c93049..dd2753d 100644 --- a/skills/metamask-agent-wallet/references/x402.md +++ b/skills/metamask-agent-wallet/references/x402.md @@ -1,114 +1,189 @@ -# x402 Payments (buyer / payer) +# x402 payments (buyer) -Use this when an HTTP request returns **`402 Payment Required`** following the -[x402 protocol](https://docs.x402.org), or when the user asks to pay for / fetch a paywalled API, -endpoint, file, or resource over HTTP. +Pay an HTTP `402 Payment Required` (x402 protocol) paywall with the active wallet, via the +helper script `scripts/x402_pay.py`. Not an `mm` subcommand. -`scripts/x402_pay.py` performs the payment: it fetches the URL, reads the server's payment -requirements, signs an EIP-3009 authorization with `mm wallet sign-typed-data`, retries with the -payment header, and reports the settlement. Signing is delegated to `mm`, so the private key stays -in the wallet. The script is pure Python standard library (run with `python3`). +## Prerequisites -## How x402 works (exact scheme, EVM) +- `mm doctor` reports `authenticated: true` and `initialized: true` (SKILL.md § Preflight). +- Resolve `$SKILL_DIR` (references/concepts.md) and invoke the script by absolute path: + `python3 "$SKILL_DIR/scripts/x402_pay.py" ...`. A bare `scripts/x402_pay.py` will not be found. +- Do NOT pass `--toon`/`--json`/`--format`; the script always prints JSON (it silently ignores + these flags if passed). +- BYOK with an encrypted mnemonic: set `MM_PASSWORD` first so signing is non-interactive + (references/concepts.md). +- Autonomous auto-pay is unsupported: every payment requires explicit user confirmation. -1. The client requests a resource. The server replies `402` with one or more **payment options** - (scheme, network, amount, asset, `payTo`, validity window). -2. The client signs an EIP-3009 `TransferWithAuthorization` for one option. This is a gasless, - off-chain authorization (no on-chain tx from the payer) permitting a pull of exactly the amount - to `payTo`. -3. The client retries with the payment header. The server's facilitator settles on-chain and - returns the resource plus a settlement header (tx hash). +## How x402 works (exact scheme, EVM) -The script handles both protocol versions: v1 (requirements in the `402` body, retry header -`X-PAYMENT`) and v2 (requirements in the `PAYMENT-REQUIRED` header, retry header -`PAYMENT-SIGNATURE`). The payload envelope also differs: v1 puts `scheme`/`network` at the top -level, while v2 nests the chosen requirements under `accepted` and forwards the top-level -`resource` (see the x402 v2 spec, PaymentPayload schema). The script builds the correct envelope -per version. +1. Client requests a resource; server replies `402` with payment options (scheme, network, + amount, asset, `payTo`). +2. Client signs an EIP-3009 `TransferWithAuthorization` for one option — a gasless off-chain + authorization permitting a pull of EXACTLY the stated amount (the `exact` scheme is an exact + amount, not a maximum) to `payTo`. +3. Client retries the request with the payment header; the server's facilitator settles + on-chain and returns the resource plus a settlement receipt (tx hash). -### Supported +The script handles v1 (requirements in the 402 body; retry header `X-PAYMENT`) and v2 +(requirements in the `PAYMENT-REQUIRED` header; retry header `PAYMENT-SIGNATURE`) and builds the +correct payload envelope per version. It signs via `mm wallet sign-typed-data --wait`, so the +private key stays in the wallet and wallet spend policy applies. -- The `exact` scheme on EVM networks (`eip155:*`) using EIP-3009 - `transferWithAuthorization`, protocol v1 and v2. +Supported: `exact` scheme, EIP-3009, EVM networks `mm` supports (resolved from `mm chains list`). +Not supported (rejected with a clear error): permit2 asset transfer method, other schemes +(e.g. `upto`), non-EVM networks, offers missing EIP-712 domain `name`/`version` in `extra`. -### Not supported (rejected with a clear error) +## Safety rules -- The Permit2 asset transfer method (`extra.assetTransferMethod: "permit2"`) and its gas-sponsoring - extensions. An EIP-3009 option on the same asset is preferred when offered; a Permit2-only offer - is reported as unsupported. Signing a Permit2 authorization is a separate flow. -- Other schemes such as `upto`, and non-EVM networks (e.g. Solana). -- Offers that omit the EIP-712 domain `name`/`version` in `extra`. The reference client falls back - to reading them on-chain; this script does not, so it asks for an offer that includes them rather - than risk signing the wrong domain. +1. HTTPS only. Plain `http` is allowed only on loopback (`localhost`/`127.0.0.1`) for testing. +2. Redirects are never followed — a 3xx on a payment request is surfaced as an error. +3. ONE payment attempt per resource. Never auto-retry `pay`; rerunning makes a NEW payment. +4. Before `pay --confirm`, confirm asset, amount, network, `payTo`, and resource URL with the + user from the `inspect` output. -## Usage +## inspect -`scripts/x402_pay.py` is a helper script (not an `mm` subcommand). Two things follow from that: -call it by its **full path inside this skill's directory**, since the shell's working directory is -not stable between commands and a bare `scripts/x402_pay.py` will not be found; and **do not pass -the global `--toon`/`--format` flags** to it, as it always prints JSON (it accepts and ignores them -if passed). Let `SKILL_DIR` be this skill's base directory (the folder containing `SKILL.md`). +Fetch the URL and print the parsed payment requirement(s). Read-only: no signing, no spending. -Inspect first (read-only: no signing, no spending), show the result to the user, then pay. +### Syntax ```bash -python3 "$SKILL_DIR/scripts/x402_pay.py" inspect [--method M] [--data BODY] -python3 "$SKILL_DIR/scripts/x402_pay.py" pay --confirm [--method M] [--data BODY] [--asset ] [--network ] +python3 "$SKILL_DIR/scripts/x402_pay.py" inspect [--method ] [--data ] [--content-type ] ``` -`inspect` prints the payment requirement(s) as JSON, including the human-readable amount, asset -symbol, network, `payTo`, and resource. `pay` runs the payment for a single eligible option and -prints the settlement (`transaction`) and the resource body. It requires `--confirm`. When the -`402` offers more than one eligible option, choose one with `--asset` or `--network`. +### Required arguments + +| Argument | Value format | Description | +| --- | --- | --- | +| `` (positional) | `https://` URL | The paywalled resource | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--method` | `GET` | HTTP method | Method to request the resource with | +| `--data` | none | string | Request body (replayed identically on the paid retry) | +| `--content-type` | `application/json` | MIME type | Content-Type for `--data` | -The resource may use any HTTP method. For a non-GET endpoint pass `--method` (and `--data` for a -request body); the same request is replayed with the payment attached, so a paid `POST` works the -same as a `GET`. `--data` defaults to a JSON content type, overridable with `--content-type`. +### Output -### Example +`{"status": "payment_required", "x402Version": 1|2, "resource": , +"options": [...]}` on stdout. Each entry in `options[]`: + +| Field | Description | +| --- | --- | +| `scheme` | Payment scheme; only `exact` is payable | +| `network` | x402 network id (v1 name like `base-sepolia`, or CAIP-2 like `eip155:8453`) | +| `amount` | Atomic-unit integer string — the EXACT amount that will be signed | +| `payTo` | Recipient address | +| `asset` | ERC-20 contract address | +| `maxTimeoutSeconds` | Settlement window (default 3600) | +| `extra` | Scheme extras, incl. EIP-712 domain `name`/`version` | +| `resource` | Per-option resource (v1) | +| `chainId` | EVM chain id resolved via `mm chains list`, or `null` if unsupported | +| `assetTransferMethod` | `eip3009` (default) or `permit2` | +| `eligible` | `true` only if scheme `exact` + EIP-3009 + supported network | +| `symbol`, `decimals`, `humanAmount` | Present only when `mm token assets` resolves the asset; display metadata | + + +Capture: `asset`, `humanAmount` (or `amount`), `network`, `payTo` → show to the user before `pay`. + +### Examples ```bash python3 "$SKILL_DIR/scripts/x402_pay.py" inspect https://api.example.com/premium -# review the amount / payTo / resource with the user, then: -python3 "$SKILL_DIR/scripts/x402_pay.py" pay https://api.example.com/premium --confirm +python3 "$SKILL_DIR/scripts/x402_pay.py" inspect https://api.example.com/report --method POST --data '{"query":"eth"}' ``` -## What the script checks +## pay -It pays an option whose `scheme` is `exact` on a network `mm` supports (resolved from -`mm chains list`). Before signing it verifies the amount is a positive atomic-unit integer, the -asset and `payTo` are valid addresses, the EIP-712 domain (`name`/`version`) is present, and the -URL is `https://` (plain `http` is allowed only on loopback for local testing). It does not follow -redirects, so a cross-host redirect cannot divert payment. After paying it makes a single retry -and reports settlement; it never retries a payment. +Run the payment for a single eligible option and print settlement + resource body. State-changing. -These are protocol-correctness checks. Which currencies and amounts are allowed is the wallet's -decision: the asset comes from the server's offer, the user confirms it, and `mm` signs (and is -where spend policy applies). The script does not keep its own currency allowlist. +### Syntax -## Assets and decimals +```bash +python3 "$SKILL_DIR/scripts/x402_pay.py" pay --confirm [--method ] [--data ] [--content-type ] [--asset
] [--network ] +``` + +### Required arguments + +| Argument | Value format | Description | +| --- | --- | --- | +| `` (positional) | `https://` URL | The paywalled resource | +| `--confirm` | boolean flag | Mandatory attestation of explicit user approval; without it the script refuses and exits 1 | + +### Optional flags + +| Flag | Default | Value format | Description | +| --- | --- | --- | --- | +| `--method` | `GET` | HTTP method | Method to request the resource with | +| `--data` | none | string | Request body (replayed identically on the paid retry) | +| `--content-type` | `application/json` | MIME type | Content-Type for `--data` | +| `--asset` | none | `^0x[0-9a-fA-F]{40}$` | Pick one option by asset contract when several are eligible | +| `--network` | none | x402 network id | Pick one option by network when several are eligible | + +### Output + +```json +{ + "status": "settled", + "asset": "USDC", + "amount": "0.01", + "network": "eip155:8453", + "payTo": "0x7c2b3e65ef2b18235e2d24266f92854a70207483", + "transaction": "0x9f2ac1...", + "settlement": {"transaction": "0x9f2ac1..."}, + "resource": {"data": "..."} +} +``` + -The server chooses which assets it accepts; the client can only pay one the server offered. The -script reads the asset's symbol and decimals from `mm token assets` for display. When `mm` cannot -resolve them (for example on testnets the Token API does not index), it shows the raw atomic -amount; the signed value is the server's atomic amount either way. +`asset`/`amount` fall back to the raw contract address / atomic amount when token metadata is +unresolvable. `transaction`/`settlement` may be `null` if the server returned no receipt. -## Wallet modes +### Async -- **Server-wallet:** signing runs synchronously via `--wait` (guard mode permits EIP-712 signing). - The x402 window is short, so if a signature needs manual approval and is slow, the authorization - can expire; rerun `pay` to sign again with fresh values. -- **BYOK:** signing returns immediately. Set `MM_PASSWORD` for an encrypted mnemonic so signing is - non-interactive. +Synchronous. Internally it runs `mm wallet sign-typed-data --chain-id --wait` with an +intent like `x402: 0.01 USDC to
for `. Slow manual signing can outlive the 402 +window — if so, rerun `pay` only with fresh user approval (it is a new payment). -## Confirmation +### Confirm before executing -Run `inspect` and show the user the asset, amount, network, `payTo`, and resource URL. Run -`pay ... --confirm` only after the user approves. A signature authorizes a real token debit. +Show the user ALL of (from `inspect`): asset (symbol + contract), amount (`humanAmount` if +present, else atomic `amount`), network, `payTo`, resource URL. A signature authorizes a real +token debit. Do not run until the user approves. -## Idempotency +### Examples + +```bash +python3 "$SKILL_DIR/scripts/x402_pay.py" pay https://api.example.com/premium --confirm +python3 "$SKILL_DIR/scripts/x402_pay.py" pay https://api.example.com/premium --confirm --network eip155:8453 --asset 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 +``` -The script is stateless. The EIP-3009 nonce prevents the same signed authorization from settling -twice, and each run makes one payment, but rerunning `pay` for the same resource makes a new -payment. Guard repeated calls at the caller. A local idempotency ledger (a caller-supplied key -mapped to prior settlements) is a possible future improvement. +## Exit codes + +| Code | Meaning | +| --- | --- | +| `0` | Success — result JSON on stdout | +| `1` | Expected failure — `{"status": "error", "error": ""}` on stderr | +| `2` | Argument error (argparse usage message on stderr) | + +## Errors + +All script errors are exit 1 with `{"status": "error", "error": ...}` on stderr. + +| Error contains | Cause | Recovery | +| --- | --- | --- | +| `refusing to pay without --confirm` | `--confirm` omitted | Run `inspect`, get user approval, rerun with `--confirm` | +| `resource URL must be https://` | Plain-http non-loopback URL | Ask the user for the https URL; never downgrade | +| `expected HTTP 402, got ` | Resource is not paywalled (or already paid) | If 200, return the resource; otherwise surface the status | +| `not a standard x402 challenge` | 402 uses a different paywall scheme | Unsupported; tell the user, do not attempt payment | +| `no eligible option` | No `exact` + EIP-3009 offer on a network `mm` supports | Show the `Offered:` list to the user; unsupported | +| `permit2 asset transfer method` | Only permit2 offers | Unsupported; tell the user | +| `multiple eligible options` | Several payable offers | Rerun `pay` with `--asset` or `--network` after user picks | +| `network '' is not supported by mm` | Unknown network id | Check `mm chains list` (references/chains.md) | +| `signing failed` | `mm wallet sign-typed-data` returned no signature | Check `mm doctor`; BYOK: set `MM_PASSWORD`; see references/signing.md | +| `payment not accepted (HTTP )` | Facilitator/server rejected the paid retry | Surface verbatim. NEVER rerun automatically — a rerun is a new payment | +| `mm produced no JSON` | `mm` not installed or errored | Run `mm doctor`; workflows/troubleshooting.md | + +Full mm code list: references/errors.md. Workflow: workflows/x402-pay.md. diff --git a/skills/metamask-agent-wallet/scripts/encode_approve.py b/skills/metamask-agent-wallet/scripts/encode_approve.py new file mode 100644 index 0000000..d5de3f1 --- /dev/null +++ b/skills/metamask-agent-wallet/scripts/encode_approve.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +"""Encode ERC-20 approve(address,uint256) calldata for an exact-amount allowance. + +Usage: + python3 encode_approve.py + +Examples: + python3 encode_approve.py 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2 100 6 + # approve 100 USDC (6 decimals) -> 0x095ea7b3000...0005f5e100 +""" + +import re +import sys +from decimal import Decimal + +if len(sys.argv) != 4: + print(f"Usage: {sys.argv[0]} ", file=sys.stderr) + sys.exit(1) + +spender = sys.argv[1] +if not re.fullmatch(r"0x[0-9a-fA-F]{40}", spender): + print("error: spender must be a 0x-prefixed 40-hex-character address", file=sys.stderr) + sys.exit(1) + +decimals = int(sys.argv[3]) +value = int(Decimal(sys.argv[2]) * 10 ** decimals) +if value < 0 or value >= 2 ** 256: + print("error: amount out of uint256 range", file=sys.stderr) + sys.exit(1) + +selector = "095ea7b3" # approve(address,uint256) +print("0x" + selector + spender[2:].lower().rjust(64, "0") + format(value, "x").rjust(64, "0")) diff --git a/skills/metamask-agent-wallet/workflows/aave-borrow.md b/skills/metamask-agent-wallet/workflows/aave-borrow.md index 40ff6cc..41d2279 100644 --- a/skills/metamask-agent-wallet/workflows/aave-borrow.md +++ b/skills/metamask-agent-wallet/workflows/aave-borrow.md @@ -1,83 +1,87 @@ -# Aave V3 borrow workflow +# Aave V3 borrow -Use this workflow to borrow assets from Aave V3 against supplied collateral. +Use when the user wants to borrow assets from Aave V3 against supplied collateral. +Supplying collateral: workflows/aave-supply.md. Repaying: workflows/aave-repay.md. +Shared machinery (endpoint, response types, executing): references/aave.md. -## Flow +## Preconditions -1. Resolve chain, asset address, and pool address. -2. Check collateral and borrow capacity. -3. Preview health factor impact. -4. Query the Aave API for the borrow transaction and execute. +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: chain, asset, amount. If the chain was not named, ask — do not guess. +3. The user has supplied collateral with `isCollateral: true` on at least one asset — verify + via workflows/aave-positions.md. No collateral → workflows/aave-supply.md; collateral + disabled → workflows/aave-collateral.md. +4. The asset is borrowable: `borrowCapReached` is `false` and the reserve is not frozen or + paused — check via workflows/aave-markets.md. -## Resolve chain and addresses +## Steps -If the user doesn't specify a chain, ask. Fetch the available markets for the chain from the Aave API to get pool addresses: +### 1. Discover the market (pool address) ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{"query":"{ markets(request: { chainIds: [] }) { address reserves { underlyingToken { symbol } } } }"}' + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address reserves { underlyingToken { symbol } } } }"}' ``` -Each entry in the response is a separate Aave V3 market. Extract `address` from each — this is the pool contract address. +Expected output: `data.markets[]` with `address` and reserve symbols. Multiple markets → ask +the user which one (references/aave.md § Market discovery). +Capture: `markets[].address` → ``. -- If one market is returned, use its `address` as ``. -- If multiple markets are returned, present them to the user (showing the `address` and up to 5 representative token symbols from `reserves[].underlyingToken.symbol`) and ask which market they want to interact with. - -## Check collateral - -Before borrowing, check the user's positions using `aave-positions.md`. Verify the following. - -1. The user has supplied collateral. If not, follow `aave-supply.md` to supply assets first. -2. Collateral is enabled on at least one supplied asset (`isCollateral` is `true`). If not, follow `aave-collateral.md` to enable it. -3. Available borrow capacity covers the requested amount. - -Query available markets to check the target asset's borrow APY and whether `borrowCapReached` is `true`. See `aave-markets.md`. - -## Preview health factor - -Preview the health factor impact before borrowing: +### 2. Preview health factor ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ healthFactorPreview(request: { action: { borrow: { market: \"\", sender: \"\", chainId: , amount: { erc20: { currency: \"\", value: \"\" } } } } }) { before after } }" - }' + -d '{"query":"{ healthFactorPreview(request: { action: { borrow: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", sender: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453, amount: { erc20: { currency: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", value: \"100\" } } } } }) { before after } }"}' ``` -Show the health factor before and after. If the projected health factor (`after`) drops below 1.5, warn about liquidation risk. If it drops below 1.0, stop and tell the user to reduce the borrow amount or repay existing debt. - -## Query borrow transaction +Expected output: `data.healthFactorPreview.before` and `.after`. Sender comes from +`mm wallet address --toon`. +If `after` < 1.5 → warn about liquidation risk. If `after` < 1.0 → stop; suggest a smaller +amount or repaying existing debt. -Get the wallet address and query the Aave V3 GraphQL API. Don't include `onBehalfOf` when borrowing for the user's own account. It triggers a credit delegation requirement even for self-borrows. - -```bash -mm wallet address -``` +### 3. Query the borrow transaction ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ borrow(request: { market: \"\", amount: { erc20: { currency: \"\", value: \"\" } }, sender: \"\", chainId: }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }" - }' + -d '{"query":"{ borrow(request: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", amount: { erc20: { currency: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", value: \"100\" } }, sender: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453 }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }"}' ``` -The `value` in the amount is a human-readable decimal string (e.g., `"2"`, `"100"`). The API handles conversion. +Borrow amount is a plain decimal string (references/aave.md § Amount format). Do NOT include +`onBehalfOf` for a self-borrow — it triggers a credit-delegation requirement. +Expected output: `__typename` — handle per references/aave.md § Response types. +Capture: `to` and `data` → step 5 payload. -## Execute borrow +### 4. Confirm with the user -Confirm the asset, amount, chain, and projected health factor with the user. The `value` field must be `0x`-prefixed hex (typically `"0x0"` for ERC-20 borrows). +Show: asset symbol + contract address, amount, chain, pool address, borrow APY (from +workflows/aave-markets.md if known), and the projected health factor from step 2. Remind +that debt accrues interest. Do not continue until the user explicitly approves. + +### 5. Execute ```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Borrow from Aave V3 on " +mm wallet send-transaction --chain-id 8453 --payload '{"to":"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5","value":"0x0","data":"0xa415bcad000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913"}' --wait --intent "Borrow 100 USDC from Aave V3 on Base" --toon ``` -If the response is `InsufficientBalanceError`, show the required and available amounts and stop. +`"value"` is `"0x0"` for borrows; `to`/`data` come from step 3. +Expected output: transaction completion (with `--wait`) or a `pollingId` +(references/concepts.md § Async job model). + +## Decision points + +- User rejects at step 4 → stop. Do not execute. +- Projected health factor below 1.0 at step 2 → stop; offer a smaller amount or more collateral. +- `borrowCapReached` is `true` for the asset → borrowing unavailable; suggest another asset. +- After completion → verify debt and health factor via workflows/aave-positions.md; repayment + via workflows/aave-repay.md. -## Notes +## Errors -- After the transaction confirms, use `aave-positions.md` to verify the updated position and health factor. -- The borrowed amount accrues interest over time. Check debt at any time using `aave-positions.md`. -- To repay the borrow, see `aave-repay.md`. +| Error / symptom | Recovery | +| --- | --- | +| `InsufficientBalanceError` | Borrow capacity too low; show `required` vs `available`, suggest more collateral or a smaller amount | +| GraphQL `errors[]` in response | Re-check pool address, asset address, chain ID, amount format (references/aave.md); ensure no `onBehalfOf` | +| `WALLET_ERROR` (gas) | `mm wallet balance --chain `; top up the native token | diff --git a/skills/metamask-agent-wallet/workflows/aave-collateral.md b/skills/metamask-agent-wallet/workflows/aave-collateral.md index afa968e..6a45219 100644 --- a/skills/metamask-agent-wallet/workflows/aave-collateral.md +++ b/skills/metamask-agent-wallet/workflows/aave-collateral.md @@ -1,66 +1,89 @@ -# Aave V3 collateral workflow +# Aave V3 collateral toggle -Use this workflow to enable or disable an asset as collateral on Aave V3. +Use when the user wants to enable or disable a supplied asset as collateral on Aave V3. +Supplying: workflows/aave-supply.md. Repaying debt first: workflows/aave-repay.md. +Shared machinery (endpoint, executing, confirm rule): references/aave.md. -## Flow +## Preconditions -1. Resolve chain, asset address, and pool address. -2. Check current collateral status and health factor. -3. Query the Aave API for the collateral toggle transaction. -4. Execute toggle. +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: chain and asset. If the chain was not named, ask — do not guess. + Resolve a symbol to a contract address: `mm token list search --query USDC --chain 8453 --toon`. +3. The wallet has a non-zero supply of the asset on Aave (check via workflows/aave-positions.md); + toggling collateral on an unsupplied asset reverts. -## Resolve chain and addresses +## Steps -If the user doesn't specify a chain, ask. Fetch the available markets for the chain from the Aave API to get pool addresses: +### 1. Discover the market (pool address) ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{"query":"{ markets(request: { chainIds: [] }) { address reserves { underlyingToken { symbol } } } }"}' + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address reserves { underlyingToken { symbol } } } }"}' ``` -Each entry in the response is a separate Aave V3 market. Extract `address` from each — this is the pool contract address. +Expected output: `data.markets[]` with `address` and reserve symbols. Multiple markets → ask +the user which one (references/aave.md § Market discovery). +Capture: `markets[].address` → ``. -- If one market is returned, use its `address` as ``. -- If multiple markets are returned, present them to the user (showing the `address` and up to 5 representative token symbols from `reserves[].underlyingToken.symbol`) and ask which market they want to interact with. - -## Check status - -Query the user's positions using `aave-positions.md`. For the target asset, check whether collateral is enabled or disabled (`isCollateral`). - -The user must have a non-zero supply of the asset to toggle collateral. - -When disabling collateral, check the health factor. If the user has outstanding borrows, disabling collateral lowers the health factor. Show the impact. If the health factor would drop below 1.0, stop and tell the user to repay debt first via `aave-repay.md`. - -## Query collateral toggle transaction - -Get the wallet address and query the Aave V3 GraphQL API: +### 2. Get the sender address and current status ```bash -mm wallet address +mm wallet address --toon ``` +Expected output: the active wallet address. +Capture: `address` → `
` in step 3. +Then run the positions query (workflows/aave-positions.md § Steps 3) and read the target +asset's `isCollateral` field — this tells you which direction the toggle will take. + +### 3. Query the collateral toggle transaction + ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ collateralToggle(request: { market: \"\", underlyingToken: \"\", user: \"\", chainId: }) { to from data value chainId } }" - }' + -d '{"query":"{ collateralToggle(request: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", underlyingToken: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", user: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453 }) { to from data value chainId } }"}' ``` -The API returns a `TransactionRequest` with `{to, from, data, value, chainId}`. The toggle direction is determined automatically based on the current collateral state. +The toggle direction is decided by the API from the current on-chain state. +Expected output: a `TransactionRequest` `{to, from, data, value, chainId}`. +Capture: `to` and `data` → step 5 payload. + +### 4. Confirm with the user -## Execute toggle +Show: asset symbol + contract address, chain, pool address, and the toggle direction +(enabling or disabling, from step 2's `isCollateral`). If DISABLING and the user has any +borrows: show the current health factor and warn that disabling lowers it; if it would drop +below 1.0, stop and point to workflows/aave-repay.md. Do not continue until the user +explicitly approves. -Confirm the asset, toggle direction (enabling or disabling), and chain with the user. The `value` field must be `0x`-prefixed hex. +### 5. Execute the toggle ```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Toggle as collateral on Aave V3 on " +mm wallet send-transaction --chain-id 8453 --payload '{"to":"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5","value":"0x0","data":"0x5a3b74b9000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda029130000000000000000000000000000000000000000000000000000000000000001"}' --wait --intent "Enable USDC as collateral on Aave V3 on Base" --toon ``` -## Notes +Use the `to`/`data` captured in step 3 (`"value"` is always `"0x0"` for a toggle). +Expected output: transaction completion (with `--wait`) or a `pollingId` +(references/concepts.md § Async job model). + +### 6. Verify + +Re-run the positions query (workflows/aave-positions.md) and confirm the asset's +`isCollateral` flipped as expected. + +## Decision points + +- User rejects at step 4 → stop. Do not execute. +- Asset has zero supplied balance → offer workflows/aave-supply.md first. +- Disabling would push the health factor below 1.0 → stop; offer workflows/aave-repay.md. +- Transaction reverts → the reserve may not be collateral-eligible; check the market's + reserves via workflows/aave-markets.md. + +## Errors -- Enabling collateral lets the asset back borrows, increasing borrow capacity. -- Disabling collateral removes it from the borrow calculation. This may trigger liquidation if remaining collateral can't cover existing debt. -- Not all assets support collateral usage. If the transaction reverts, the reserve may not be eligible. -- After the transaction confirms, verify the updated status using `aave-positions.md`. +| Error / symptom | Recovery | +| --- | --- | +| GraphQL `errors[]` in response | Re-check pool address, asset address, chain ID (references/aave.md) | +| On-chain revert | Asset not supplied, or reserve not collateral-eligible; verify via workflows/aave-positions.md and workflows/aave-markets.md | +| `WALLET_ERROR` (gas) | `mm wallet balance --chain `; top up the native token | diff --git a/skills/metamask-agent-wallet/workflows/aave-markets.md b/skills/metamask-agent-wallet/workflows/aave-markets.md index 0b4705a..305734e 100644 --- a/skills/metamask-agent-wallet/workflows/aave-markets.md +++ b/skills/metamask-agent-wallet/workflows/aave-markets.md @@ -1,39 +1,52 @@ -# Aave V3 markets workflow +# Aave V3 markets and rates -Use this workflow to discover available Aave V3 tokens, supply/borrow rates, and borrowing capacity on a chain. +Use when the user wants to discover which assets Aave V3 supports on a chain, their supply +and borrow APYs, or available borrow liquidity. Read-only — no transaction is sent. Feeds +workflows/aave-supply.md and workflows/aave-borrow.md. The user's own positions: +workflows/aave-positions.md. Shared machinery (endpoint): references/aave.md. -## Flow +## Preconditions -1. Resolve chain. -2. Query available markets. -3. Present results. +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know the chain. If the chain was not named, ask — do not guess. Chain IDs: `mm chains list`. -## Resolve chain +## Steps -If the user doesn't specify a chain, ask. - -## Query available markets +### 1. Query markets with reserve details ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ markets(request: { chainIds: [] }) { address reserves { underlyingToken { symbol decimals } supplyInfo { apy { formatted } } borrowInfo { apy { formatted } availableLiquidity { amount { value } usd } borrowCapReached } isFrozen isPaused } } }" - }' + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address reserves { underlyingToken { symbol decimals } supplyInfo { apy { formatted } } borrowInfo { apy { formatted } availableLiquidity { amount { value } usd } borrowCapReached } isFrozen isPaused } } }"}' ``` -The response returns one entry per market. Each entry has an `address` (the pool contract address) and a `reserves` array. +Expected output: `data.markets[]`, one entry per market, each with `address` (the pool +contract) and a `reserves[]` array. +Capture: `markets[].address` → `` for a follow-up supply/borrow workflow. + +### 2. Present the results -## Present results +1. Group reserves by market `address`; label each group with its pool address. +2. Drop reserves where `isFrozen` or `isPaused` is `true`. +3. For each remaining reserve show: + - Symbol and decimals (`underlyingToken.symbol`, `underlyingToken.decimals`) + - Supply APY (`supplyInfo.apy.formatted`) + - Borrow APY (`borrowInfo.apy.formatted`) + - Available liquidity (`borrowInfo.availableLiquidity.amount.value` and `.usd`) + - Borrow cap reached (`borrowInfo.borrowCapReached`) +4. `apy.formatted` is already a percentage (`"2.12"` = 2.12%) — do not convert. -Group reserves by market `address`. Within each market, filter out reserves where `isFrozen` or `isPaused` is `true`. For each active reserve, show: +## Decision points -- Token symbol and decimals (`underlyingToken.symbol`, `underlyingToken.decimals`) -- Supply APY (`supplyInfo.apy.formatted`) -- Borrow APY (`borrowInfo.apy.formatted`) -- Available liquidity (`borrowInfo.availableLiquidity.amount.value`, `borrowInfo.availableLiquidity.usd`) -- Borrow cap reached (`borrowInfo.borrowCapReached`) +- `borrowCapReached` is `true` for an asset → tell the user borrowing that asset is + unavailable; supplying may still work. +- User picks an asset to supply → workflows/aave-supply.md (reuse the captured ``). +- User picks an asset to borrow → workflows/aave-borrow.md (reuse the captured ``). +- Empty `markets[]` → Aave V3 not deployed on this chain; ask the user for another chain. -The `apy.formatted` field returns a percentage directly (e.g., `"2.12"` means 2.12%). No conversion is needed. +## Errors -If `borrowCapReached` is `true`, tell the user that borrowing isn't available for that asset. +| Error / symptom | Recovery | +| --- | --- | +| GraphQL `errors[]` in response | Re-check the chain ID and query syntax against references/aave.md § Endpoint | +| Asset the user wants is missing or frozen/paused | Offer another asset from the list or another chain | diff --git a/skills/metamask-agent-wallet/workflows/aave-positions.md b/skills/metamask-agent-wallet/workflows/aave-positions.md index d65a5bb..8ff3bbd 100644 --- a/skills/metamask-agent-wallet/workflows/aave-positions.md +++ b/skills/metamask-agent-wallet/workflows/aave-positions.md @@ -1,71 +1,80 @@ -# Aave V3 positions workflow +# Aave V3 positions and health factor -Use this workflow to check Aave V3 positions, health factor, interest rates, or reserve data. +Use when the user wants to see their Aave V3 supplies, borrows, collateral status, or health +factor, or to preview the health-factor impact of a planned operation. Read-only — no +transaction is sent. Rates and available assets: workflows/aave-markets.md. +Shared machinery (endpoint, market discovery): references/aave.md. -## Flow +## Preconditions -1. Get wallet address and chain. -2. Query supply and borrow positions via GraphQL. -3. Present summary. +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know the chain. If the chain was not named, ask — do not guess. Chain IDs: `mm chains list`. -## Resolve chain +## Steps -Get the wallet address: +### 1. Get the wallet address ```bash -mm wallet address +mm wallet address --toon ``` -If the user doesn't specify a chain, ask. Fetch all markets for the chain to get pool addresses: +Expected output: the active wallet address. +Capture: `address` → `
` in step 3. + +### 2. Discover the markets (pool addresses) ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{"query":"{ markets(request: { chainIds: [] }) { address } }"}' + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address } }"}' ``` -Collect all returned `address` values as ``. - -## Query positions +Expected output: `data.markets[]` with one `address` per market. +Capture: ALL `markets[].address` values → the `markets` array entries in step 3. -Query supply and borrow positions across all markets in a single request. Build the `markets` array from all addresses returned above: +### 3. Query supplies and borrows across all markets ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ userSupplies(request: { markets: [{ address: \"\", chainId: }, { address: \"\", chainId: }], user: \"\" }) { currency { symbol decimals } balance { amount { value } usd } apy { formatted } isCollateral marketAddress } userBorrows(request: { markets: [{ address: \"\", chainId: }, { address: \"\", chainId: }], user: \"\" }) { currency { symbol decimals } debt { amount { value } usd } apy { formatted } marketAddress } }" - }' + -d '{"query":"{ userSupplies(request: { markets: [{ address: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", chainId: 8453 }], user: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\" }) { currency { symbol decimals } balance { amount { value } usd } apy { formatted } isCollateral marketAddress } userBorrows(request: { markets: [{ address: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", chainId: 8453 }], user: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\" }) { currency { symbol decimals } debt { amount { value } usd } apy { formatted } marketAddress } }"}' ``` -Include one `{ address, chainId }` entry per market returned by the previous query. The response contains both `userSupplies` and `userBorrows` arrays spanning all markets. - -## Health factor preview +Include one `{ address, chainId }` entry per market captured in step 2. +Expected output: `userSupplies[]` and `userBorrows[]` arrays spanning all markets. -Preview the health factor impact of a planned operation: +### 4. (Only if the user is planning an operation) Preview the health factor ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ healthFactorPreview(request: { action: { : { market: \"\", sender: \"\", chainId: , amount: { erc20: { currency: \"\", value: \"\" } } } } }) { before after } }" - }' + -d '{"query":"{ healthFactorPreview(request: { action: { borrow: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", sender: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453, amount: { erc20: { currency: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", value: \"100\" } } } } }) { before after } }"}' ``` -Replace `` with `supply`, `borrow`, `withdraw`, or `repay`. All action types require `market`, `sender`, and `chainId`. +The action key is one of `supply`, `borrow`, `withdraw`, `repay`; its `amount` uses the same +format as the wrapped operation (references/aave.md § Amount format). +Expected output: `healthFactorPreview` with `before` and `after`. -## Present summary +### 5. Present the summary -Format the data into three sections: +1. Supplied assets: symbol, `balance.amount.value`, `balance.usd`, `apy.formatted`, `isCollateral`. +2. Borrowed assets: symbol, `debt.amount.value`, `debt.usd`, `apy.formatted`. +3. Health factor with a risk label (see Decision points). `apy.formatted` is already a + percentage (`"2.12"` = 2.12%) — do not convert. -Supplied assets: -- Symbol, balance (`balance.amount.value`), USD value (`balance.usd`), supply APY (`apy.formatted`), used as collateral (`isCollateral`) +## Decision points -Borrowed assets: -- Symbol, debt amount (`debt.amount.value`), USD value (`debt.usd`), borrow APY (`apy.formatted`) +- Health factor above 2.0 → safe; no warning needed. +- 1.5–2.0 → moderate; mention it when the user plans to borrow or withdraw more. +- 1.0–1.5 → risky, approaching liquidation; warn and offer workflows/aave-repay.md or + workflows/aave-supply.md (more collateral). +- Below 1.0 → position is liquidatable; warn urgently and recommend immediate repay/supply. +- No supplies and no borrows returned → tell the user they have no Aave position on this + chain; offer workflows/aave-markets.md and workflows/aave-supply.md. -Account summary: -- Total collateral value, total debt value, available borrows, health factor -- Health factor guidance: above 2.0 is safe, 1.5–2.0 is moderate, 1.0–1.5 is risky and approaching liquidation, below 1.0 is liquidatable +## Errors -The `apy.formatted` field returns a percentage directly (e.g., `"2.12"` means 2.12%). No conversion is needed. \ No newline at end of file +| Error / symptom | Recovery | +| --- | --- | +| GraphQL `errors[]` in response | Re-check pool addresses, chain ID, and wallet address; re-run step 2 | +| Empty `markets[]` in step 2 | Aave V3 not deployed on this chain; ask the user for another chain | diff --git a/skills/metamask-agent-wallet/workflows/aave-repay.md b/skills/metamask-agent-wallet/workflows/aave-repay.md index 11a830c..4a8c683 100644 --- a/skills/metamask-agent-wallet/workflows/aave-repay.md +++ b/skills/metamask-agent-wallet/workflows/aave-repay.md @@ -1,103 +1,83 @@ -# Aave V3 repay workflow +# Aave V3 repay -Use this workflow to repay borrowed assets on Aave V3. +Use when the user wants to repay borrowed assets on Aave V3. +Borrowing: workflows/aave-borrow.md. Withdrawing collateral: workflows/aave-withdraw.md. +Shared machinery (endpoint, response types, approval rule): references/aave.md. -## Flow +## Preconditions -1. Resolve chain, asset address, and pool address. -2. Check outstanding debt. -3. Query the Aave API for the repay transaction. -4. Handle approval if required, then repay. +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: chain, asset, amount (or "full debt"). If the chain was not named, ask. +3. Outstanding debt exists — check `userBorrows` via workflows/aave-positions.md and show the + user the debt amount (`debt.amount.value`) and borrow APY (`apy.formatted`). +4. Wallet balance covers the repayment plus gas: `mm wallet balance --chain `. -## Resolve chain and addresses +## Steps -If the user doesn't specify a chain, ask. Fetch the available markets for the chain from the Aave API to get pool addresses: +### 1. Discover the market (pool address) ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{"query":"{ markets(request: { chainIds: [] }) { address reserves { underlyingToken { symbol } } } }"}' + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address reserves { underlyingToken { symbol } } } }"}' ``` -Each entry in the response is a separate Aave V3 market. Extract `address` from each — this is the pool contract address. +Expected output: `data.markets[]` with `address` and reserve symbols. Multiple markets → ask +the user which one (references/aave.md § Market discovery). +Capture: `markets[].address` → ``. -- If one market is returned, use its `address` as ``. -- If multiple markets are returned, present them to the user (showing the `address` and up to 5 representative token symbols from `reserves[].underlyingToken.symbol`) and ask which market they want to interact with. - -## Check debt - -Query the user's outstanding debt using `userBorrows` from `aave-positions.md`. Identify the following. - -- The asset being repaid and its contract address -- Current debt amount (`debt.amount.value`) -- Current borrow APY (`apy.formatted`) - -Show the debt amount and current rate. - -## Query repay transaction - -Get the wallet address and query the Aave V3 GraphQL API: - -```bash -mm wallet address -``` - -For a specific repayment amount: +### 2. Query the repay transaction ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ repay(request: { market: \"\", amount: { erc20: { currency: \"\", value: { exact: \"\" } } }, sender: \"\", chainId: }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { reason requiredAmount { value decimals } currentAllowance { value decimals } approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }" - }' -``` - -To repay the full debt, use `{ max: true }` instead of `{ exact: \"\" }` in the value field. This lets the contract calculate the exact outstanding debt at execution time, including accrued interest. - -You can't use `{ max: true }` when `onBehalfOf` is set in the request. If repaying on behalf of another address, specify the exact repayment amount. Query the current debt via `userBorrows` and add a small buffer (e.g., 0.5%) to account for interest accrued between query and execution. - -## Handle response - -The API returns one of three response types: - -### `TransactionRequest` - -The transaction is ready to send. Confirm with the user, then send. The `value` field must be `0x`-prefixed hex (typically `"0x0"` for ERC-20 repayments). - -```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Repay on Aave V3 on " + -d '{"query":"{ repay(request: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", amount: { erc20: { currency: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", value: { exact: \"100\" } } }, sender: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453 }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { reason requiredAmount { value decimals } currentAllowance { value decimals } approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }"}' ``` -### `ApprovalRequired` +Full debt: use `value: { max: true }` instead of `value: { exact: \"100\" }` — the contract +computes the exact debt (including accrued interest) at execution time. `{ max: true }` is +NOT allowed with `onBehalfOf`; when repaying for another address, use `exact` with the +current debt plus a small buffer (about 0.5%) — the contract refunds the excess. +Sender comes from `mm wallet address --toon`. +Expected output: `__typename` — handle per references/aave.md § Response types. +Capture: `to` and `data` (from `approval` and/or the transaction) → step 4 payload. -An ERC-20 approval is needed before repayment. Confirm the token being approved, the spender, and the amount with the user. Then send the approval. +### 3. Confirm with the user -```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Approve for Aave V3 Pool on " -``` +Show: asset symbol + contract address, amount (or "full debt"), chain, pool address; if +`ApprovalRequired`, also the spender and that the API default allowance is UNLIMITED, +offering the exact-amount alternative (references/aave.md § Approval security rule). +Do not continue until the user explicitly approves. If `InsufficientBalanceError`: show +`required` vs `available` and stop. -After the approval confirms, send the original repay transaction. +### 4. Execute ```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Repay on Aave V3 on " +mm wallet send-transaction --chain-id 8453 --payload '{"to":"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5","value":"0x0","data":"0x573ade81000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913"}' --wait --intent "Repay 100 USDC on Aave V3 on Base" --toon ``` -ERC-20 approvals are consumed by the repay transaction. If the user approved an exact amount and needs to repay again (e.g., for remaining dust debt), a new approval is required. Consider approving slightly more than the debt amount to avoid this. - -### `InsufficientBalanceError` - -The user doesn't have enough tokens to repay. Show the required and available amounts, then stop. - -## Handling dust debt - -Interest accrues continuously between borrow and repay transactions. When repaying an exact amount equal to the original borrow, a small "dust" debt remains. - -To handle this: -1. Use `{ max: true }` (only works without `onBehalfOf`) to let the contract calculate the exact outstanding debt at execution time. -2. Over-repay slightly: query the current debt via `userBorrows`, then repay with the debt amount plus a small buffer (e.g., 0.5%). The contract only deducts the actual debt and refunds the excess. -3. Acquire more tokens: if the wallet balance equals the exact original borrow amount, acquire slightly more of the token to cover interest. - -## Notes - -- After the transaction confirms, use `aave-positions.md` to verify the debt is cleared or reduced. -- All debt (including dust amounts) must be cleared before a full collateral withdrawal. See `aave-withdraw.md`. +`"value"` is `"0x0"` for ERC-20 repayments; `to`/`data` come from step 2. If step 2 returned +`ApprovalRequired`: send the APPROVAL's `to`/`data` first (`"value":"0x0"`, intent +"Approve 100 USDC for Aave V3 Pool on Base"), wait for completion, then send +`originalTransaction`'s `to`/`data`. +Expected output: transaction completion (with `--wait`) or a `pollingId` +(references/concepts.md § Async job model). + +## Decision points + +- User rejects at step 3 → stop. Do not execute. +- User wants the debt fully cleared → prefer `{ max: true }`; repaying the exact original + borrow amount leaves interest "dust" that blocks full collateral withdrawal. +- Dust debt remains after an exact repay → re-run with `{ max: true }`, or over-repay with a + 0.5% buffer; if the wallet holds only the exact original amount, acquire slightly more first. +- Exact-amount approval already consumed by a prior repay → a new approval is required for + the next repay. +- After completion → verify the debt is cleared or reduced via workflows/aave-positions.md. + +## Errors + +| Error / symptom | Recovery | +| --- | --- | +| `InsufficientBalanceError` | Show `required` vs `available`; offer a swap (workflows/swap.md) or bridge (workflows/bridge.md), then restart at step 2 | +| GraphQL `errors[]` in response | Re-check pool address, asset address, chain ID, amount format (references/aave.md); `{ max: true }` with `onBehalfOf` is invalid | +| `WALLET_ERROR` (gas) | `mm wallet balance --chain `; top up the native token | diff --git a/skills/metamask-agent-wallet/workflows/aave-supply.md b/skills/metamask-agent-wallet/workflows/aave-supply.md index 7a1f749..7b1f166 100644 --- a/skills/metamask-agent-wallet/workflows/aave-supply.md +++ b/skills/metamask-agent-wallet/workflows/aave-supply.md @@ -1,102 +1,96 @@ -# Aave V3 supply workflow +# Aave V3 supply -Use this workflow to supply (deposit) assets into Aave V3 and earn interest. +Use when the user wants to supply (deposit) an asset into Aave V3 to earn interest. +Withdrawing: workflows/aave-withdraw.md. Borrowing: workflows/aave-borrow.md. +Shared machinery (endpoint, response types, approval rule): references/aave.md. -## Flow +## Preconditions -1. Resolve chain, asset address, and pool address. -2. Check wallet balance. -3. Query the Aave API for the supply transaction. -4. Handle approval if required, then supply. +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: chain, asset, amount. If the chain was not named, ask — do not guess. + Resolve a symbol to a contract address: `mm token list search --query USDC --chain 8453 --toon`. +3. Balance covers the amount plus gas: `mm wallet balance --chain `. If not: offer a + swap (workflows/swap.md) or bridge (workflows/bridge.md) first. -## Resolve chain and addresses +## Steps -If the user doesn't specify a chain, ask. Fetch the available markets for the chain from the Aave API to get pool addresses: +### 1. Discover the market (pool address) ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{"query":"{ markets(request: { chainIds: [] }) { address reserves { underlyingToken { symbol } } } }"}' + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address reserves { underlyingToken { symbol } } } }"}' ``` -Each entry in the response is a separate Aave V3 market. Extract `address` from each — this is the pool contract address. +Expected output: `data.markets[]` with `address` and reserve symbols. Multiple markets → ask +the user which one (references/aave.md § Market discovery). +Capture: `markets[].address` → ``. -- If one market is returned, use its `address` as ``. -- If multiple markets are returned, present them to the user (showing the `address` and up to 5 representative token symbols from `reserves[].underlyingToken.symbol`) and ask which market they want to interact with. - -Resolve the asset's contract address on the target chain. If the user provides a symbol instead of an address, run `mm token list search --query --chain `. - -Aave V3 doesn't accept native ETH on most markets. If the reserve accepts native tokens, use `native` instead of `erc20` in the GraphQL request. - -## Check balance - -Check that the user has sufficient funds: +### 2. Get the sender address ```bash -mm wallet balance --chain +mm wallet address --toon ``` -If the user doesn't have enough of the supply token or native gas token, check balances on other chains. If the user has assets on the same chain, prompt them to swap. If the user has assets on another chain, prompt them to bridge to the target chain before proceeding. - -## Query supply transaction +Expected output: the active wallet address. +Capture: `address` → `
` (sender) in step 3. -Get the wallet address and query the Aave V3 GraphQL API for the supply execution plan: - -```bash -mm wallet address -``` +### 3. Query the supply transaction ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ supply(request: { market: \"\", amount: { erc20: { currency: \"\", value: \"\" } }, sender: \"\", chainId: }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { reason requiredAmount { value decimals } currentAllowance { value decimals } approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }" - }' + -d '{"query":"{ supply(request: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", amount: { erc20: { currency: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", value: \"100\" } }, sender: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453 }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { reason requiredAmount { value decimals } currentAllowance { value decimals } approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }"}' ``` -The `value` in the amount is a human-readable decimal string (e.g., `"42"`, `"0.5"`). The API handles decimal-to-wei conversion. - -## Handle response +Supply amount is a plain decimal string (references/aave.md § Amount format). Native-token +supply (only where the reserve accepts it): replace `erc20: { currency: ..., value: \"100\" }` +with `native: \"100\"`. +Expected output: `__typename` of `TransactionRequest`, `ApprovalRequired`, or +`InsufficientBalanceError` — handle per references/aave.md § Response types. +Capture: `to` and `data` (from `approval` and/or the transaction) → step 5 payload. -The API returns one of three response types: +### 4. Confirm with the user -### `TransactionRequest` - -The transaction is ready to send. Confirm with the user, then send. - -The `value` field in the transaction payload must be `0x`-prefixed hex. For ERC-20 supplies, this is `"0x0"`. For native token supplies, convert the amount to hex using the helper script: - -```bash -python3 scripts/amount_to_hex.py -``` - -If python3 isn't available, multiply the amount by `10^decimals` manually and convert the result to hex. - -```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Supply to Aave V3 on " -``` +Show: asset symbol + contract address, amount, chain, pool address; if `ApprovalRequired`, +also the spender and that the API default allowance is UNLIMITED, offering the exact-amount +alternative (references/aave.md § Approval security rule). Do not continue until the user +explicitly approves. If `InsufficientBalanceError`: show `required` vs `available` and stop. -### `ApprovalRequired` +### 5. Execute — pick ONE branch for `value` -An ERC-20 approval is needed before supply. Confirm the token being approved, the spender, and the amount with the user. Then send the approval. +If the supplied asset is an ERC-20 → `"value":"0x0"` (`to`/`data` from step 3): ```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Approve for Aave V3 Pool on " +mm wallet send-transaction --chain-id 8453 --payload '{"to":"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5","value":"0x0","data":"0x617ba037000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913"}' --wait --intent "Supply 100 USDC to Aave V3 on Base" --toon ``` -After the approval confirms, send the original supply transaction. +If the supplied asset is the NATIVE token → `"value"` is the hex printed by +`python3 "$SKILL_DIR/scripts/amount_to_hex.py" 0.5 18` (→ `0x6f05b59d3b20000`): ```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Supply to Aave V3 on " +mm wallet send-transaction --chain-id 8453 --payload '{"to":"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5","value":"0x6f05b59d3b20000","data":"0x617ba0370000000000000000000000004200000000000000000000000000000000000006"}' --wait --intent "Supply 0.5 ETH to Aave V3 on Base" --toon ``` -Security note: The Aave API returns `max uint256` (unlimited) as the default approval amount. Tell the user. For better security, construct a limited approval by encoding `approve(address,uint256)` calldata (selector `0x095ea7b3`) with the exact supply amount instead of using the API-provided approval transaction. +If step 3 returned `ApprovalRequired`: run this command first with the APPROVAL's `to`/`data` +(`"value":"0x0"`, intent "Approve 100 USDC for Aave V3 Pool on Base"), wait for completion, +then run it again with `originalTransaction`'s `to`/`data`. +Expected output: transaction completion (with `--wait`) or a `pollingId` +(references/concepts.md § Async job model). -### `InsufficientBalanceError` +## Decision points -The user doesn't have enough tokens. Show the required and available amounts, then stop. +- User rejects at step 4 → stop. Do not execute. +- User declines the unlimited approval → build exact-amount calldata with + `scripts/encode_approve.py` (references/aave.md § Approval security rule). +- Asset missing from the market's reserves → offer workflows/aave-markets.md to pick a + supported asset. +- After completion → verify the new aToken position via workflows/aave-positions.md. -## Notes +## Errors -- After the transaction confirms, the user receives aTokens representing their deposit. Use `aave-positions.md` to verify the updated position. -- To check current supply rates before supplying, see `aave-positions.md`. +| Error / symptom | Recovery | +| --- | --- | +| `InsufficientBalanceError` | Show `required` vs `available`; offer swap/bridge, then restart at step 3 | +| GraphQL `errors[]` in response | Re-check pool address, asset address, chain ID, amount format (references/aave.md) | +| `WALLET_ERROR` (gas) | `mm wallet balance --chain `; top up the native token | diff --git a/skills/metamask-agent-wallet/workflows/aave-withdraw.md b/skills/metamask-agent-wallet/workflows/aave-withdraw.md index 6c4dd11..e508b95 100644 --- a/skills/metamask-agent-wallet/workflows/aave-withdraw.md +++ b/skills/metamask-agent-wallet/workflows/aave-withdraw.md @@ -1,78 +1,86 @@ -# Aave V3 withdraw workflow +# Aave V3 withdraw -Use this workflow to withdraw supplied assets from Aave V3. +Use when the user wants to withdraw supplied assets from Aave V3. +Supplying: workflows/aave-supply.md. Repaying debt: workflows/aave-repay.md. +Shared machinery (endpoint, response types, executing): references/aave.md. -## Flow +## Preconditions -1. Resolve chain, asset address, and pool address. -2. Check positions and health factor. -3. Query the Aave API for the withdraw transaction. -4. Execute withdrawal. +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: chain, asset, amount (or "full balance"). If the chain was not named, ask. +3. The user has a supply position in the asset — verify via workflows/aave-positions.md. +4. Full withdrawal only: `userBorrows` shows NO outstanding debt (even dust). If debt exists, + the transaction reverts with `0x6679996d` — repay first via workflows/aave-repay.md. -## Resolve chain and addresses +## Steps -If the user doesn't specify a chain, ask. Fetch the available markets for the chain from the Aave API to get pool addresses: +### 1. Discover the market (pool address) ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{"query":"{ markets(request: { chainIds: [] }) { address reserves { underlyingToken { symbol } } } }"}' + -d '{"query":"{ markets(request: { chainIds: [8453] }) { address reserves { underlyingToken { symbol } } } }"}' ``` -Each entry in the response is a separate Aave V3 market. Extract `address` from each — this is the pool contract address. +Expected output: `data.markets[]` with `address` and reserve symbols. Multiple markets → ask +the user which one (references/aave.md § Market discovery). +Capture: `markets[].address` → ``. -- If one market is returned, use its `address` as ``. -- If multiple markets are returned, present them to the user (showing the `address` and up to 5 representative token symbols from `reserves[].underlyingToken.symbol`) and ask which market they want to interact with. - -## Check positions - -Check the user's current positions using `aave-positions.md`. Confirm the asset and available balance. - -Before a full withdrawal, query `userBorrows` and verify there's no outstanding debt. A full collateral withdrawal fails if any debt exists, even tiny "dust" amounts. The transaction reverts with error `0x6679996d`. Follow `aave-repay.md` to clear all debt first. - -For a partial withdrawal with outstanding borrows, preview the health factor impact: +### 2. Preview health factor (only if the user has outstanding borrows) ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ healthFactorPreview(request: { action: { withdraw: { market: \"\", sender: \"\", chainId: , amount: { erc20: { currency: \"\", value: { exact: \"\" } } } } } }) { before after } }" - }' + -d '{"query":"{ healthFactorPreview(request: { action: { withdraw: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", sender: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453, amount: { erc20: { currency: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", value: { exact: \"100\" } } } } } }) { before after } }"}' ``` -If the projected health factor (`after`) drops below 1.5, warn about liquidation risk. If it drops below 1.0, stop and tell the user to repay debt first. - -## Query withdraw transaction - -Get the wallet address and query the Aave V3 GraphQL API: +Expected output: `data.healthFactorPreview.before` and `.after`. +If `after` < 1.5 → warn about liquidation risk. If `after` < 1.0 → stop; the user must repay +debt first. Sender comes from `mm wallet address --toon`. -```bash -mm wallet address -``` - -For a specific amount: +### 3. Query the withdraw transaction ```bash curl -s -X POST https://api.v3.aave.com/graphql \ -H 'Content-Type: application/json' \ - -d '{ - "query": "{ withdraw(request: { market: \"\", amount: { erc20: { currency: \"\", value: { exact: \"\" } } }, sender: \"\", chainId: }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }" - }' + -d '{"query":"{ withdraw(request: { market: \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\", amount: { erc20: { currency: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", value: { exact: \"100\" } } }, sender: \"0x7c2b3e65ef2b18235e2d24266f92854a70207483\", chainId: 8453 }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }"}' ``` -To withdraw the full balance, use `{ max: true }` instead of `{ exact: \"\" }` in the value field. +Full balance: use `value: { max: true }` instead of `value: { exact: \"100\" }`. +To send funds to a different address, add `recipient: \"
\"` to the request. +Expected output: `__typename` — handle per references/aave.md § Response types. +Capture: `to` and `data` → step 5 payload. -## Execute withdrawal +### 4. Confirm with the user -Confirm the asset, amount (or "full balance"), destination, and chain with the user. The `value` field must be `0x`-prefixed hex (typically `"0x0"` for ERC-20 withdrawals). +Show: asset symbol + contract address, amount (or "full balance"), destination (default: +sender), chain, pool address, and the health-factor impact from step 2 if computed. Do not +continue until the user explicitly approves. + +### 5. Execute ```bash -mm wallet send-transaction --chain-id --payload '{"to":"","value":"0x0","data":""}' --wait --intent "Withdraw from Aave V3 on " +mm wallet send-transaction --chain-id 8453 --payload '{"to":"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5","value":"0x0","data":"0x69328dec000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913"}' --wait --intent "Withdraw 100 USDC from Aave V3 on Base" --toon ``` -If the response is `ApprovalRequired`, send the approval transaction first, then the withdrawal transaction (same pattern as `aave-supply.md`). +`"value"` is `"0x0"` for withdrawals; `to`/`data` come from step 3. If step 3 returned +`ApprovalRequired`, send `approval` first, then `originalTransaction` +(references/aave.md § Response types). +Expected output: transaction completion (with `--wait`) or a `pollingId` +(references/concepts.md § Async job model). + +## Decision points + +- User rejects at step 4 → stop. Do not execute. +- Full withdrawal requested but debt exists → repay via workflows/aave-repay.md, then restart. +- Projected health factor below 1.0 at step 2 → stop; suggest a smaller amount or repaying debt. +- After completion → verify the reduced position via workflows/aave-positions.md. -## Notes +## Errors -- After the transaction confirms, use `aave-positions.md` to verify the updated position. -- Add a `recipient` field to the request to withdraw to a different address than the sender. +| Error / symptom | Recovery | +| --- | --- | +| Revert `0x6679996d` | Outstanding debt blocks full withdrawal; clear ALL debt (workflows/aave-repay.md), then retry | +| `InsufficientBalanceError` | Requested more than supplied; show `required` vs `available`, ask for a smaller amount | +| GraphQL `errors[]` in response | Re-check pool address, asset address, chain ID, amount format (references/aave.md) | +| `WALLET_ERROR` (gas) | `mm wallet balance --chain `; top up the native token | diff --git a/skills/metamask-agent-wallet/workflows/bridge.md b/skills/metamask-agent-wallet/workflows/bridge.md index 857583f..47710f9 100644 --- a/skills/metamask-agent-wallet/workflows/bridge.md +++ b/skills/metamask-agent-wallet/workflows/bridge.md @@ -1,62 +1,76 @@ -# Bridge workflow +# Cross-chain bridge -Use this workflow when the user wants to bridge tokens across chains. +Use when the user wants to move tokens from one chain to another. +Same-chain: use workflows/swap.md instead. Command details: references/swap.md. -Reference command syntax in `references/swap.md`. The CLI uses the same `swap` commands for bridging. Set `--to-chain` to a different chain than `--from-chain`. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: source token, destination token, amount, source chain, destination chain. If a + chain was not named, ask — do not guess. List chains with `mm chains list`. +3. Source-chain balance covers the amount plus gas: `mm wallet balance --chain `. -1. Quote. -2. Confirm with the user. -3. Execute and track status. +## Steps -Don't skip the quote review step. The user needs to see output amount, fees, route, and slippage before executing. - -## Quote - -```bash -mm swap quote --from ETH --to USDC --amount 1 --from-chain 1 --to-chain 137 --slippage 0.5 -``` - -Required flags: `--from`, `--to`, `--amount`, `--from-chain`, and `--to-chain`. - -If the user wants the bridged tokens sent to a different wallet on the destination chain, add `--to-address`: +### 1. Get a bridge quote ```bash -mm swap quote --from ETH --to USDC --amount 1 --from-chain 1 --to-chain 137 --to-address 0x742d...f2bD18 +mm swap quote --from USDC --to USDC --amount 100 --from-chain 1 --to-chain 137 --toon ``` -If the recipient may have no native gas on the destination chain, add `--refuel` to bundle a destination gas top-up into the quote (cross-chain only, opt-in, best-effort — see `references/swap.md`). Do **not** add `--refuel` when the destination token is the destination chain's native gas asset (e.g. bridging into ETH on Arbitrum) — the backend returns 0 quotes in that case: +Cross-chain only, add as needed: `--to-address
` to send output to another wallet; +`--refuel` to bundle a destination native-gas top-up (skip it when the destination token IS +the destination chain's native gas asset — that route returns `NO_QUOTES`). +Expected output: `data.quoteId` plus a `quote` object with `destAssetAmount`, +`minDestAssetAmount`, `bridgeId`, and `feeData`. +Capture: `quoteId` → used as `` in steps 3 and 4. -```bash -mm swap quote --from USDC --to USDC --amount 50 --from-chain 1 --to-chain 42161 --refuel -``` +### 2. Confirm with the user -Persist the quote id for execution. Show the quote to the user before execution. -Confirm source token, destination token, amount, source chain, destination chain, slippage, expected output, fees, route, recipient address (if `--to-address` was set), and the destination gas top-up (if `--refuel` was set). +Show: from token, to token, amount, source chain, destination chain, slippage (default 0.5%), +expected output (`destAssetAmount` scaled by the destination token's `decimals`), minimum +received (`minDestAssetAmount` scaled), fees, bridge route (`bridgeId`), recipient address +(only if `--to-address` was set), destination gas top-up (only if `--refuel` was set). +Do not continue until the user explicitly approves. -## Execute +### 3. Execute by quote id ```bash -mm swap execute --quote-id "QUOTE_ID" +mm swap execute --quote-id --toon ``` -Prefer executing by quote ID. Re-quote-and-execute flags exist, but quote ID execution keeps the reviewed quote tied to the submitted action. +Always execute the reviewed quote by id. Never pass token/amount flags here — that re-quotes +and executes a price the user never reviewed. The persisted quote already carries the +recipient and refuel settings. +Expected output: a wallet job (`pollingId`) — show its `intent` to the user. -## Status +### 4. Track status until terminal ```bash -mm swap status --quote-id "QUOTE_ID" -mm swap status --quote-id "QUOTE_ID" --tx-hash 0xabc123 +mm swap status --quote-id --toon ``` -Use status polling for bridges where the destination side can lag behind the source transaction. - -## Edge cases - -- Quote expired: re-quote and ask the user to review the new quote. -- Insufficient balance: surface the error verbatim. -- Slippage exceeded: only increase `--slippage` if the user explicitly accepts more slippage. Always warn the user if slippage - is increased above 1% that it will affect the minimum received. -- Missing chain: use `mm chains list` before guessing a chain ID. -- Refuel into a native asset: if `--refuel` is set and the destination token is the destination chain's native gas asset, the backend returns 0 quotes (`NO_QUOTES`). Re-quote without `--refuel`. +Repeat until the status is terminal (completed or failed). The destination-chain side can lag +minutes behind the source transaction — keep polling; do not re-execute. Then report both +source and destination results. + +## Decision points + +- User rejects at step 2 → stop. Do not execute. +- Quote expired or `QUOTE_NOT_FOUND` at step 3 → return to step 1, then re-confirm at step 2. +- `NO_QUOTES` with `--refuel` → the destination token is likely the native gas asset; retry + step 1 without `--refuel`. +- User wants output at a different address → valid only cross-chain via `--to-address` + (same-chain it is rejected with `INVALID_SWAP_PARAMS`). +- Recipient may have no gas on the destination chain and destination token is non-native → + offer `--refuel` before quoting. + +## Errors + +| Error / symptom | Recovery | +| --- | --- | +| `NO_QUOTES` | No route for this pair/amount/chains. Drop `--refuel` if set; try a different amount or token; verify the token exists on both chains with `mm token list search --query USDC --chain 137` | +| `INVALID_SWAP_PARAMS` (`--to-address` same-chain) | Ensure `--to-chain` differs from `--from-chain`, or omit `--to-address` | +| Insufficient balance | `mm wallet balance --chain `; fund the source chain first, then re-quote | +| Slippage exceeded / user asks for higher slippage | Re-quote with `--slippage ` only after explicit user approval; warn above 1% | +| Status stuck non-terminal | Keep polling `mm swap status`; destination settlement can take minutes. Do not re-execute | diff --git a/skills/metamask-agent-wallet/workflows/login.md b/skills/metamask-agent-wallet/workflows/login.md index 05f7541..ab114d1 100644 --- a/skills/metamask-agent-wallet/workflows/login.md +++ b/skills/metamask-agent-wallet/workflows/login.md @@ -1,39 +1,61 @@ -# Login Workflow +# Login -Use this workflow when the user needs to log in to the CLI. +Use when the user needs to sign in (or `mm doctor` reports `authenticated: false`) on an +already-initialized project. Full first-time setup: workflows/onboarding.md. +Command details: references/auth.md. -Reference command syntax in `references/auth.md`. +## Preconditions -## Flow +1. CLI installed: `mm --version` prints a version. If not: `npm install -g @metamask/agentic-cli@latest`. +2. Not already signed in: `mm auth status --toon` shows `authenticated: false`. If `true`, stop — nothing to do (to switch accounts, `mm logout` first with user approval). -1. Ask the user which login method they want: MetaMask Mobile QR or browser (Google / Email). -2. Execute login. -3. Verify with token. +## Steps -## Login +### 1. Choose a method -For non-interactive/CI flows, use `mm login browser --no-wait`: +Ask the user: MetaMask Mobile QR or browser (Google/Email)? Both work on all environments, +including production. -```bash -mm login browser --no-wait -``` +- QR and interactive terminal → `mm login qr` (shows a QR; `--no-wait` not supported) +- Browser or non-interactive → `mm login browser --no-wait` -The command prints a sign-in URL. The user opens it in a browser and chooses Google or Email to complete sign-in. +### 2. Log in -`mm login qr` (scan with MetaMask Mobile) is available on all environments, including production. QR login keeps the CLI attached to the relay, so it does not support `--no-wait`. +```bash +mm login browser --no-wait --toon +``` -## Verify +Expected output: a sign-in URL. The user opens it and completes Google or Email sign-in. +Capture: the token the user receives → `` in step 3. -Once the user completes sign-in, verify with: +### 3. Complete the session (only if `--no-wait` was used) ```bash -mm login --token "" +mm login --token --toon ``` -## Confirm +Expected output: `ok: true` with authenticated session. Never log or store the token. -Run `mm doctor` to verify the session is ready. It reports `authenticated` and `initialized` booleans. Do not proceed until both are `true`. If `initialized` is `false`, follow `workflows/onboarding.md` to run `mm init`. +### 4. Verify ```bash -mm doctor +mm doctor --toon ``` + +Expected output: `authenticated: true`. If `initialized: false`, continue with +workflows/onboarding.md step 4 before running any wallet command. + +## Decision points + +- Server-wallet mode → login auto-syncs existing wallets; `mm wallet list` works immediately, no re-init needed. +- BYOK mode → no sync on login; if `initialized: false`, run `mm init` (workflows/onboarding.md). +- User cannot open a browser and has MetaMask Mobile → use `mm login qr` in a TTY. + +## Errors + +| Error / symptom | Recovery | +| --- | --- | +| `ALREADY_AUTHENTICATED` | Already signed in; `mm logout` first only if the user wants to switch accounts | +| `TOKEN_INVALID` | Re-paste the full `cliToken:cliRefreshToken`; re-run step 2 if expired | +| `PAIRING_TIMEOUT` / `PAIRING_EXPIRED` | Re-run `mm login qr`; scan promptly | +| Login succeeds but commands still fail | workflows/troubleshooting.md | diff --git a/skills/metamask-agent-wallet/workflows/market-data.md b/skills/metamask-agent-wallet/workflows/market-data.md index 872563a..ff839a9 100644 --- a/skills/metamask-agent-wallet/workflows/market-data.md +++ b/skills/metamask-agent-wallet/workflows/market-data.md @@ -1,62 +1,69 @@ -# Market Data Workflow +# Token discovery and market data -Use this workflow when the user wants to look up token prices, discover tokens, or explore market data. +Use when the user asks for a token's price, price history, or metadata and you do not yet have +its CAIP-19 asset ID. Already have the CAIP-19 (or it is a native asset like ETH)? Skip to +step 3. Command details: references/price.md and references/token.md. -Reference command syntax in `references/market-data.md`. +## Preconditions -## Find a Token +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know the chain. If the user did not name one, ask — do not guess. Chain IDs: + `mm chains list`; token-API coverage: `mm token networks`. -If the user mentions a token by name or symbol, search for it first to get the correct asset ID: +## Steps -```bash -mm token list search --query "USDC" --chain 1 -``` +### 1. Resolve the token to a contract address -To browse popular, trending, or top-gainer tokens on a chain: +Native assets (ETH, POL) need no search — build `eip155:/slip44:` directly +(references/concepts.md § CAIP identifiers) and skip to step 3. For any other symbol or name: ```bash -mm token list popular --chain 1 -mm token list trending --chain 1 -mm token list top-gainer --chain 1 +mm token list search --query USDC --chain 1 --limit 5 --toon ``` -Use `mm token networks` to discover which chains support token data. +Expected output: `data.tokens` rows with `symbol`, `name`, `address`, `decimals`, `chainId`. +Capture: `address` + `chainId` → build `` as `/erc20:
`, e.g. +`eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`. -## Get Token Metadata +### 2. Disambiguate -Once you have the CAIP-19 asset ID, fetch detailed metadata: +If more than one row plausibly matches the user's request (same or similar symbol), show the +user the candidates (symbol, name, address, market cap) and ask which one they mean. Do not +pick silently. -```bash -mm token assets --asset-ids "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" --include-market-data --include-token-security-data -``` - -## Get Spot Price - -Fetch the current price for one or more tokens: +### 3. Get the spot price ```bash -mm price spot --asset-ids "eip155:1/slip44:60" -mm price spot --asset-ids "eip155:1/slip44:60,eip155:137/slip44:966" --vs eur --market-data +mm price spot --asset-ids eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --market-data --toon ``` -Use `mm price networks` to discover supported CAIP-2 chain IDs and `mm price currencies` to list quote currencies. +Expected output: `data.prices` rows with `assetId`, `vsCurrency`, `price`. -## Get Historical Price +### 4. Get historical prices (only if the user asked for a trend or range) -Fetch historical price data for an asset: +Split the CAIP-19: the part before `/` goes to `--chain-id`, the part after to `--asset-type`. ```bash -mm price history --chain-id eip155:1 --asset-type slip44:60 --time-period 7d --interval daily +mm price history --chain-id eip155:1 --asset-type erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --time-period 7d --interval daily --toon ``` -Common time periods: `1d`, `7d`, `30d`, `2M`, `1y`, `3y`. Intervals: `5m`, `hourly`, `daily`. +Expected output: `data.prices` rows of `[millisecond-timestamp, price]` pairs. + +## Decision points -For a custom date range, use `--from` and `--to` with Unix timestamps instead of `--time-period`. +- Search returns zero rows → retry with more chains (`--chain 1,137,8453`) or an alternate + name; still nothing → ask the user for the contract address. +- Multiple plausible matches → ask the user (step 2). Never assume the first row. +- User wants a curated browse instead of a specific token → `mm token list popular|trending|top-gainer --chain ` (references/token.md). +- User wants safety/metadata detail → `mm token assets --asset-ids --include-token-security-data --include-market-data`. +- User names a non-USD currency → check it exists via `mm price currencies`, then add `--vs `. +- Custom date range → replace `--time-period` with `--from --to ` (`date +%s`). -## Edge Cases +## Errors -- If the chain is not mentioned by the user, ask for the chain. -- Use `mm chains list` to discover supported chain IDs. -- If a token search returns no results, try broader chains or alternate names. -- CAIP-19 asset IDs follow the format `eip155:/slip44:` for native tokens or `eip155:/erc20:` for ERC-20s. -- Use `--include-token-security-data` on `token assets` to surface scam or risk signals before the user trades an unfamiliar token. +| Error / symptom | Recovery | +| --- | --- | +| `INVALID_ASSET_ID` | Rebuild the CAIP-19 per references/concepts.md; re-check the address from step 1 | +| `INVALID_CHAIN` | Chain not covered by the API; run `mm price networks` / `mm token networks` and pick a listed chain | +| `TOKEN_NOT_FOUND` | Broaden the search chains or ask the user for the contract address | +| Price looks stale or null | Retry with `--market-data`; for thin tokens warn the user that pricing may be unreliable | diff --git a/skills/metamask-agent-wallet/workflows/onboarding.md b/skills/metamask-agent-wallet/workflows/onboarding.md index 94d8041..20a4c12 100644 --- a/skills/metamask-agent-wallet/workflows/onboarding.md +++ b/skills/metamask-agent-wallet/workflows/onboarding.md @@ -1,108 +1,99 @@ -# Onboarding Workflow +# First-time setup (onboarding) -Use this workflow when the user is setting up the MetaMask Agentic CLI for the first time. +Use when the user has never used the `mm` CLI in this project, or `mm doctor` reports +`authenticated: false` or `initialized: false`. Already authenticated but not initialized: +skip to step 4. Command details: references/auth.md, references/doctor.md. -Reference command syntax in `references/auth.md` and `references/wallet.md`. +## Preconditions -## Flow +1. CLI installed: `mm --version` prints a version. If it fails: `npm install -g @metamask/agentic-cli@latest`. +2. Version check per SKILL.md § Preflight (warn on `major.minor` mismatch, then continue). -1. Check CLI installation. -2. Login. -3. Initialize wallet mode. -4. Verify readiness. -5. Show wallet address. +## Steps -## Check CLI Installation +### 1. Check current state ```bash -mm --version +mm doctor --toon ``` -If this fails, the CLI is not installed. Guide the user to install it with `npm install -g @metamask/agentic-cli@latest` before proceeding. +Expected output: `authenticated` and `initialized` booleans plus `hints`. +Capture: `authenticated` → decides step 2; `initialized` → decides step 4. -Then run the version compatibility check from the skill `Preflight` section: compare the installed `major.minor` against the pinned `cliVersion` and the latest published release, and warn the user if they are out of sync. +### 2. Choose a login method (skip if `authenticated: true`) -## Login Flow +Ask the user: MetaMask Mobile QR or browser (Google/Email)? Both work on all environments, +including production. -Ask the user which login method they want to use: MetaMask Mobile QR or browser (Google or Email). QR (`mm login qr`) is available on non-production builds (dev/uat); on production it returns `COMING_SOON`, so fall back to browser login there. +- QR and interactive terminal available → `mm login qr` +- Otherwise (or user prefers browser) → `mm login browser --no-wait` -### Login +### 3. Log in ```bash -mm login browser --no-wait +mm login browser --no-wait --toon ``` -Use `--no-wait` for non-interactive environments. The command prints a sign-in URL; the user completes sign-in in the browser using Google or Email. +Expected output: a sign-in URL. The user opens it and completes Google or Email sign-in. +If `--no-wait` was used, complete the session: `mm login --token --toon`. -### Verify +### 4. Choose wallet mode and trading mode (skip if `initialized: true`) -Once the user completes sign-in, verify with: +Ask the user: -```bash -mm login --token "" -``` +- Wallet mode: `server-wallet` (recommended; MetaMask hosts the keys) or `byok` (user's own mnemonic). +- Trading mode: `guard` (policy checks enforced) or `beast` (skips policy checks; still blocks malicious transactions). -## Initialize Project +Confirm both choices explicitly before running init. -First check whether the project is already initialized with `mm doctor` (read its `initialized` boolean): +### 5. Initialize + +If server-wallet: ```bash -mm doctor +mm init --wallet server-wallet --mode guard --toon ``` -If `initialized` is `true`, skip this step. - -For server-wallet mode, if the account already has a remote wallet, `mm init` syncs it and reuses the existing trading mode — no trading-mode prompt. For BYOK mode, if a trading mode is already set server-side for the wallet, it is loaded without prompting. - -Otherwise, ask the user which wallet mode they want: -- `server-wallet` (recommended) — keys are hosted by MetaMask infrastructure. No need to manage private keys or mnemonics. -- `byok` — bring your own mnemonic. The user manages their own keys locally. - -Ask the user which trading mode they want (applies to both server-wallet and BYOK): -- `guard` — enforces outflow and whitelist policies. When a policy is violated, the CLI requires MFA confirmation before proceeding. -- `beast` — skips all policy checks and confirmations. Useful for scripting or experienced users who want faster execution. - -Server wallet: +If BYOK: instruct the user to set env vars (never inline flags), then run: ```bash -mm init --wallet server-wallet --mode guard +export MM_MNEMONIC="word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12" +export MM_PASSWORD="chosen-password" +mm init --wallet byok --mode guard --toon ``` -BYOK: +Expected output: `ok: true`. `MM_PASSWORD` is optional here; without it the mnemonic is stored +unencrypted — offer `mm wallet password set` (interactive TTY) afterward. -Never pass `--mnemonic` or `--password` as inline flags. Always instruct the user to set environment variables instead. +### 6. Verify readiness ```bash -export MM_MNEMONIC="word1 word2 ..." -mm init --wallet byok --mode guard +mm doctor --toon ``` -If the user wants to encrypt their mnemonic with a password during init: +Expected output: `authenticated: true` AND `initialized: true`, no blocking hints. Do not run +other commands until both are true. Never use `mm init show` as this check. -```bash -export MM_MNEMONIC="word1 word2 ..." -export MM_PASSWORD="mypassword" -mm init --wallet byok --mode guard -``` - -If the mnemonic was stored unencrypted, suggest setting a password afterward: +### 7. Report the wallet address ```bash -mm wallet password set +mm wallet address --toon ``` -Once the mnemonic is encrypted, all subsequent operations that need the private key require the `MM_PASSWORD` environment variable to be set. Never instruct the user to pass `--password` inline. +Expected output: the active wallet address. Show it to the user; setup is complete. -## Verify Readiness +## Decision points -```bash -mm doctor -``` +- `mm doctor` already all-true → nothing to do; report ready. +- Server-wallet account already has a remote wallet → `mm init` syncs it and reuses the existing trading mode (no prompt). +- After login in server-wallet mode, wallets auto-sync — `mm wallet list` works immediately. +- User declines to share a mnemonic → use `server-wallet`. -Confirm `mm doctor` reports both `authenticated: true` and `initialized: true` with no blocking hints before proceeding. (`mm auth status` reports only authentication and does not reflect initialization, so it cannot confirm readiness on its own.) +## Errors -## Show Wallet Address - -```bash -mm wallet address -``` +| Error / symptom | Recovery | +| --- | --- | +| `ALREADY_AUTHENTICATED` at step 3 | Skip to step 4 (or `mm logout` first to switch accounts) | +| `PAIRING_TIMEOUT` / `MWP_CANCELLED` on QR | Re-run `mm login qr`; scan promptly | +| `INVALID_MNEMONIC` at step 5 | Ask the user to re-check `MM_MNEMONIC`; never echo it | +| `NOT_INITIALIZED` after step 5 | Re-run step 5; check step 3 succeeded first | diff --git a/skills/metamask-agent-wallet/workflows/perps-close-position.md b/skills/metamask-agent-wallet/workflows/perps-close-position.md index 8aa26ec..4adb019 100644 --- a/skills/metamask-agent-wallet/workflows/perps-close-position.md +++ b/skills/metamask-agent-wallet/workflows/perps-close-position.md @@ -1,54 +1,64 @@ -# Perps Close Position Workflow +# Close a perp position -Use this workflow when the user wants to close a perpetual position. +Use when the user wants to close a perpetual position (fully, partially, or all positions). +Cancelling a resting order instead: `mm perps cancel` (references/perps.md). +Command details: references/perps.md. -Reference command syntax in `references/perps.md`. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. An open position exists: `mm perps positions --venue hyperliquid --toon` returns a + non-empty list. If empty: tell the user there is nothing to close and stop. -1. Check open positions. -2. Dry run the close. -3. Confirm with the user and close. +## Steps -## Confirm Symbol - -If the user does not mention a token symbol, list open positions and confirm with the user: +### 1. List open positions ```bash -mm perps positions +mm perps positions --venue hyperliquid --toon ``` -## Check Positions - -`--venue` defaults to `hyperliquid`. It can be omitted. +Expected output: one row per position with symbol, side, size, entry price, unrealized PnL. +Capture: `symbol` → `` in step 3; size and unrealized PnL → shown in step 2. -```bash -mm perps positions -``` +### 2. Confirm with the user -## Dry Run +Show: symbol (or "ALL open positions" if the user asked to close everything), current size, +close size (full, or the partial `--size`), side, current unrealized PnL (estimated impact of +closing now), venue. Do not continue until the user explicitly approves. -Preview the close before executing: +### 3. Close ```bash -mm perps close --symbol BTC --dry-run +mm perps close --venue hyperliquid --symbol BTC --yes --toon ``` -For partial close, include `--size `. +Variants (exactly one form): +- Partial close: append `--size 0.0005` to the command above. +- Close everything: `mm perps close --venue hyperliquid --all --yes --toon` (no `--symbol`, no `--size`). -## Close +Expected output: `ok: true` with the close/fill result. -Remove `--dry-run` only after explicit user confirmation: +### 4. Verify ```bash -mm perps close --symbol BTC -mm perps close --symbol BTC --size 0.005 +mm perps positions --venue hyperliquid --toon ``` -`--all` closes every open position. Require explicit confirmation that the user wants all positions closed. +Expected output: the position is gone (full close / `--all`) or shows the reduced size +(partial). Report realized outcome to the user. -```bash -mm perps close --all -``` +## Decision points + +- User rejects at step 2 → stop. Do not close. +- User wants to close several but not all symbols → run step 3 once per symbol, confirming each. +- Partial `--size` ≥ position size → treat as a full close; omit `--size`. +- Uncertain market conditions → run step 3 with `--dry-run` instead of `--yes` first, review, re-run. + +## Errors -Do not add `--yes` unless the user explicitly asked for unattended execution. +| Error / symptom | Recovery | +| --- | --- | +| `ValidationError` (`--symbol` with `--all`, or `--size` with `--all`) | Use exactly one form from step 3 | +| Position not found | Re-run step 1; the symbol may already be closed or misspelled | +| Position still listed after full close | Wait a few seconds and re-run step 4; venue settlement can lag | diff --git a/skills/metamask-agent-wallet/workflows/perps-modify-position.md b/skills/metamask-agent-wallet/workflows/perps-modify-position.md index 3f28f06..0aa8311 100644 --- a/skills/metamask-agent-wallet/workflows/perps-modify-position.md +++ b/skills/metamask-agent-wallet/workflows/perps-modify-position.md @@ -1,49 +1,65 @@ -# Perps Modify Position Workflow +# Modify a perp position -Use this workflow when the user wants to modify leverage, take-profit, or stop-loss on an existing position. +Use when the user wants to change leverage, take-profit (TP), or stop-loss (SL) on an +existing perpetual position. Changing size: close partially (workflows/perps-close-position.md) +or open more (workflows/perps-open-position.md). Command details: references/perps.md. -Reference command syntax in `references/perps.md`. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. An open position exists for the symbol: `mm perps positions --venue hyperliquid --toon`. +3. At least one change is specified: new leverage, TP price, or SL price. If none, ask — + `mm perps modify` requires at least one of `--leverage`, `--tp`, `--sl`. -1. Check open positions. -2. Dry run the modification. -3. Confirm with the user and modify. +## Steps -## Confirm Symbol - -If the user does not mention a token symbol, list open positions and confirm with the user: +### 1. Read the current position ```bash -mm perps positions +mm perps positions --venue hyperliquid --toon ``` -## Check Positions +Expected output: a row for the symbol with current side, size, leverage, liquidation price. +Capture: `symbol` → `` in step 3; current leverage/TP/SL → the "old" values in step 2. + +### 2. Confirm with the user + +Show: symbol, venue, and each changed field as old → new (leverage, TP price, SL price). +Sanity-check against the position's side: for a long, TP above and SL below the current mark +price; inverted for a short — warn if not. Warn that raising leverage moves the liquidation +price closer. Do not continue until the user explicitly approves. -`--venue` defaults to `hyperliquid`. It can be omitted. +### 3. Modify ```bash -mm perps positions +mm perps modify --venue hyperliquid --symbol BTC --leverage 10 --yes --toon ``` -## Dry Run +Include only the flags being changed, e.g. TP/SL only: +`mm perps modify --venue hyperliquid --symbol ETH --tp 3000 --sl 2000 --yes --toon`. +Expected output: `ok: true` with the updated values. -Preview the modification before executing: +### 4. Verify ```bash -mm perps modify --symbol BTC --leverage 10 --dry-run -mm perps modify --symbol ETH --tp 3000 --sl 2000 --dry-run +mm perps positions --venue hyperliquid --toon ``` -At least one of `--leverage`, `--tp`, or `--sl` must be provided. +Expected output: the position row reflects the new leverage and/or trigger prices. Report the +new liquidation price to the user if leverage changed. -## Modify +## Decision points -Remove `--dry-run` only after explicit user confirmation: +- User rejects at step 2 → stop. Do not modify. +- New leverage exceeds the market's max → check `maxLeverage` via + `mm perps markets --venue hyperliquid --symbol BTC --toon`; ask for a valid value. +- TP/SL on the wrong side of the mark price → warn and re-confirm before running. +- Uncertain → run step 3 with `--dry-run` instead of `--yes` first, review, re-run. -```bash -mm perps modify --symbol BTC --leverage 10 -mm perps modify --symbol ETH --tp 3000 --sl 2000 -``` +## Errors -Do not add `--yes` unless the user explicitly asked for unattended execution. +| Error / symptom | Recovery | +| --- | --- | +| `ValidationError` (none of `--leverage`/`--tp`/`--sl` given) | Ask the user which field to change; pass at least one | +| Position not found | Re-run step 1; confirm the exact symbol | +| Leverage above market max | Read `maxLeverage` from `mm perps markets --symbol `; re-confirm a valid value | diff --git a/skills/metamask-agent-wallet/workflows/perps-open-position.md b/skills/metamask-agent-wallet/workflows/perps-open-position.md index 2712341..e93f082 100644 --- a/skills/metamask-agent-wallet/workflows/perps-open-position.md +++ b/skills/metamask-agent-wallet/workflows/perps-open-position.md @@ -1,102 +1,76 @@ -# Perps open position workflow +# Open a perp position -Use this workflow when the user wants to open a new perpetual position. +Use when the user wants to open a new perpetual futures position (long or short). +Closing or changing an existing position: workflows/perps-close-position.md / +workflows/perps-modify-position.md. Command details: references/perps.md. -Reference command syntax in `references/perps.md`. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: symbol, side (long/short), size (base asset), leverage. If any is missing, ask — + do not guess. Symbols: `mm perps markets --venue hyperliquid --toon`. +3. Venue margin covers the position: `mm perps balance --venue hyperliquid --toon` — + `spendableBalance` ≥ quoted notional / leverage. If not, deposit first + (`mm perps deposit`, references/perps.md) from Arbitrum USDC. -1. Check balance and deposit if needed. -2. Quote the position. -3. Dry run. -4. Confirm with the user and open. +## Steps -## Confirm symbol - -If the user doesn't mention a token symbol, list available markets and confirm with the user: - -```bash -mm perps markets -``` - -## Check balance - -`--venue` defaults to `hyperliquid`. You can omit it. - -```bash -mm perps balance -``` - -If available margin is zero or insufficient, deposit USDC before proceeding. Hyperliquid only supports deposits from Arbitrum mainnet (`eip155:42161`). - -Check the user's Arbitrum balance for USDC and ETH (for gas). - -```bash -mm wallet balance --chain 42161 -``` - -### No ETH and no USDC on Arbitrum - -Inform the user that ETH on Arbitrum is required for gas. Without ETH, no on-chain transaction is possible. Bridge from another chain. +### 1. Verify the market and max leverage ```bash -mm swap quote --from --to ETH --amount 0.001 --from-chain --to-chain 42161 -mm swap execute --quote-id "$QUOTE_ID" # quote ID from the swap quote command +mm perps markets --venue hyperliquid --symbol BTC --toon ``` -Once the user has ETH for gas, swap or bridge to get USDC on Arbitrum. +Expected output: one row with `symbol`, `maxLeverage`, `markPrice`. +Capture: `maxLeverage` → reject the request if the desired leverage exceeds it. -```bash -mm swap quote --from --to USDC --amount --from-chain --to-chain 42161 -mm swap execute --quote-id "$QUOTE_ID" # quote ID from the swap quote command -``` - -### Has ETH or another token on Arbitrum (but no USDC) - -Swap to USDC on Arbitrum. +### 2. Quote the order ```bash -mm swap quote --from --to USDC --amount --from-chain 42161 -mm swap execute --quote-id "$QUOTE_ID" # quote ID from the swap quote command +mm perps quote --venue hyperliquid --symbol BTC --side long --size 0.001 --leverage 2 --toon ``` -### Has ETH and USDC on Arbitrum - -Deposit USDC directly into Hyperliquid. +For a limit order append `--type limit --limit-px 60000`. +Expected output: `entryPrice`, `notional`, `estimatedFee`, `estimatedLiquidationPrice`, `warnings`. +Capture: those four fields → shown in step 3. -```bash -mm perps deposit --amount --asset USDC -``` +### 3. Confirm with the user +Show: symbol, side, size, leverage, venue, order type (market/limit), limit price if set, +quoted entry price, notional, estimated fee, estimated liquidation price (note it is an +estimate). Do not continue until the user explicitly approves. -## Quote - -Always quote before opening: +### 4. Open the position ```bash -mm perps quote --symbol BTC --side long --size 0.01 --leverage 5 +mm perps open --venue hyperliquid --symbol BTC --side long --size 0.001 --leverage 2 --yes --toon ``` -Show the user estimated entry, notional, fees, liquidation price, side, size, leverage, and venue before proceeding. - -## Dry run +If anything is uncertain (first trade, near margin limits), run the identical command with +`--dry-run` instead of `--yes` first, review, then re-run with `--yes`. +Expected output: `ok: true` with the order/fill result. -Preview the order before signing: +### 5. Verify ```bash -mm perps open --symbol BTC --side long --size 0.01 --leverage 5 --dry-run +mm perps positions --venue hyperliquid --toon ``` -For limit orders, include `--type limit --limit-px `. +Expected output: a row for the new position with matching symbol, side, size, leverage. +Report entry price and liquidation price to the user. -`--max-slippage-bps` is the slippage cap in basis points for IOC market pricing. +## Decision points -## Open +- User rejects at step 3 → stop. Do not open. +- Leverage > `maxLeverage` at step 1 → tell the user the market maximum; re-quote only after + they pick a valid leverage. +- Insufficient `spendableBalance` → offer `mm perps deposit` (references/perps.md), then restart at step 2. +- `--type limit` without a limit price → ask for the price; `--limit-px` is required. -Remove `--dry-run` only after explicit user confirmation: - -```bash -mm perps open --symbol BTC --side long --size 0.01 --leverage 5 -``` +## Errors -Don't add `--yes` unless the user explicitly asked for unattended execution. +| Error / symptom | Recovery | +| --- | --- | +| `ValidationError` (unknown symbol) | `mm perps markets --venue hyperliquid --toon`; confirm the exact symbol with the user | +| Insufficient margin | `mm perps balance --venue hyperliquid --toon`; deposit USDC or reduce size after user approval | +| Position missing at step 5 (limit order) | The order is resting, not filled — show it via `mm perps orders --venue hyperliquid --toon` | diff --git a/skills/metamask-agent-wallet/workflows/predict-funding.md b/skills/metamask-agent-wallet/workflows/predict-funding.md index 2236e80..347ced5 100644 --- a/skills/metamask-agent-wallet/workflows/predict-funding.md +++ b/skills/metamask-agent-wallet/workflows/predict-funding.md @@ -1,90 +1,92 @@ -# Predict funding workflow +# Predict deposit / withdraw pUSD -Use this workflow to deposit or withdraw pUSD from the Predict deposit wallet. +Use when the user wants to fund the Predict deposit wallet or take funds out. Trading: +workflows/predict-place-order.md. Command details: references/predict-account.md. -Reference command syntax in `references/predict.md`. +Chooser: if money moves INTO the deposit wallet → Deposit path (steps 2a-4a). If money moves +OUT to an EOA → Withdraw path (steps 2b-4b). -## Flow +## Preconditions -1. Check deposit wallet balance. -2. Deposit or withdraw. +1. `mm predict status` shows `account.setupComplete: true`. If not: workflows/predict-setup.md. +2. You know the amount. If not stated, ask — do not guess. +3. Deposit only: owner EOA holds enough USDC.e plus POL for gas on Polygon: + `mm wallet balance --chain 137`. -## Check deposit wallet balance +## Steps -```bash -mm predict balance --sync -``` - -## Deposit - -If the user doesn't specify an amount, ask how much they want to deposit. Get the deposit wallet address from `mm predict status`, then check the user's Polygon balance. +### 1. Check the deposit-wallet balance ```bash -mm wallet balance --chain 137 +mm predict balance --sync --toon ``` -### Has POL and pUSD on Polygon - -Use `mm transfer` to send pUSD directly to the deposit wallet address. No conversion needed. Get the pUSD contract address from `mm wallet balance --chain 137` output. - -```bash -mm transfer --to --amount --chain-id 137 --token --wait -``` +Expected output: current pUSD balance, approvals, and setup status. -Get the deposit wallet address from the `mm predict status` output. +### 2a. Deposit — confirm with the user -### Has POL and USDC.e on Polygon +Show: amount, source (owner EOA USDC.e on Polygon, chain 137), destination (Predict deposit +wallet, credited as pUSD — the CLI converts USDC.e to pUSD). Do not continue until the user +explicitly approves. -Run `mm predict deposit`. The CLI converts USDC.e to pUSD in the deposit wallet. +### 3a. Deposit ```bash -mm predict deposit --amount --wait +mm predict deposit --amount 5 --wait --toon ``` -`--amount` is in USDC.e. The owner EOA needs enough USDC.e and POL for gas on Polygon. +Amount is human-readable USDC.e (`5`, `100`), not atomic units. +Expected output: success once the deposit job completes. +Capture: `pollingId` (only if run without `--wait`) → `` for +`mm predict watch --id --wait`. -### Has POL or another token on Polygon (but no USDC.e or pUSD) - -Swap to pUSD on Polygon, then transfer directly to the deposit wallet. The owner EOA needs POL for gas. +### 4a. Verify the deposit ```bash -mm swap quote --from --to pUSD --amount --from-chain 137 -mm swap execute --quote-id "$QUOTE_ID" # quote ID from the swap quote command +mm predict balance --sync --toon ``` -After the swap completes, check the balance to verify pUSD arrived +Expected output: pUSD increased by the deposited amount. Report the new balance. -```bash -mm wallet balance --chain 137 -``` +### 2b. Withdraw — confirm with the user + +Show: amount and recipient. When `--to` is omitted, say "owner EOA" explicitly. Do not +continue until the user explicitly approves. -Get the pUSD contract address from the balance output, then transfer to the deposit wallet: +### 3b. Withdraw ```bash -mm transfer --to --amount --chain-id 137 --token --wait +mm predict withdraw --amount 10 --wait --toon ``` -Get the deposit wallet address from the `mm predict status` output. +Different recipient: add `--to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e`. The CLI validates +the amount against the on-chain deposit-wallet balance before signing. +Expected output: success once the withdraw job completes. +Capture: `pollingId` (only if run without `--wait`) → `` for +`mm predict watch --id --wait`. -### Has assets on another chain - -Bridge to send pUSD directly to the deposit wallet address on Polygon. +### 4b. Verify the withdrawal ```bash -mm swap quote --from --to pUSD --amount --from-chain --to-chain 137 --to-address -mm swap execute --quote-id "$QUOTE_ID" # quote ID from the swap quote command +mm wallet balance --chain 137 --toon ``` -Get the deposit wallet address from the `mm predict status` output. This avoids the extra deposit step. - +Expected output: recipient balance increased; `mm predict balance --sync` shows the reduced +pUSD balance. -## Withdraw +## Decision points -Withdraw pUSD from the deposit wallet to the owner EOA (default) or a specified address. +- User rejects at the confirmation step → stop. Do not execute. +- Owner EOA has POL but no USDC.e on Polygon → swap to USDC.e first (workflows/swap.md), or + bridge from another chain (workflows/bridge.md), then return to step 2a. +- Withdraw amount exceeds the pUSD balance → report the balance from step 1 and ask for a + smaller amount. -```bash -mm predict withdraw --amount --wait -mm predict withdraw --amount --to --wait -``` +## Errors -Confirm the amount and recipient with the user before executing. The CLI validates the amount against the on-chain deposit wallet balance before signing. +| Error / symptom | Recovery | +| --- | --- | +| `WALLET_ERROR` (deposit) | Insufficient USDC.e or POL gas: `mm wallet balance --chain 137`; fund or reduce amount | +| `WALLET_ERROR` (withdraw) | Insufficient pUSD: `mm predict balance --sync`; reduce amount | +| `PREDICT_SETUP_REQUIRED` | Run workflows/predict-setup.md, then retry | +| Job stalls without `--wait` | `mm predict watch --id --wait` | diff --git a/skills/metamask-agent-wallet/workflows/predict-manage-orders.md b/skills/metamask-agent-wallet/workflows/predict-manage-orders.md index 5fd10d7..d6be2a8 100644 --- a/skills/metamask-agent-wallet/workflows/predict-manage-orders.md +++ b/skills/metamask-agent-wallet/workflows/predict-manage-orders.md @@ -1,50 +1,78 @@ -# Predict manage orders workflow +# View / cancel Predict orders and positions -Use this workflow to view, cancel, or manage open Predict orders and positions. +Use when the user wants to review open Predict orders or positions, or cancel orders. Placing +a new order: workflows/predict-place-order.md. Redeeming winnings: +workflows/predict-portfolio.md. Command details: references/predict-trade.md. -Reference command syntax in `references/predict.md`. +## Preconditions -## View orders +1. `mm predict status` shows `account.setupComplete: true`. If not: workflows/predict-setup.md. +2. For cancelling: you know the scope (one order, one market, one outcome token, or ALL). If + ambiguous, ask — do not default to `--all`. -```bash -mm predict orders -mm predict orders --market -``` +## Steps -## View positions +### 1. Review open orders ```bash -mm predict positions -mm predict positions --market +mm predict orders --toon ``` -## Cancel orders +Filter to one market with `--market `; page with `--cursor `. +Expected output: open orders with `orderId`, token, side, size, price. +Capture: `orderId` → `` for step 3. -Cancel a single order: +### 2. Review positions (if the user asked) ```bash -mm predict cancel --order-id +mm predict positions --toon ``` -Cancel by market or asset: +Expected output: positions with market question, outcome, size, and estimated value. If the +user only wanted a review, report and stop here. -```bash -mm predict cancel --market -mm predict cancel --asset -``` +### 3. Confirm the cancel scope with the user + +Choose EXACTLY ONE targeting flag and show the user exactly what it matches from step 1: + +- One named order → `--order-id `. +- All orders in one market → `--market ` (list the matching orders). +- All orders on one outcome token → `--asset ` (list the matching orders). +- Everything → `--all` — say explicitly "this cancels ALL open orders" and list them. -Cancel all open orders: +Do not continue until the user explicitly approves the exact scope. + +### 4. Cancel ```bash -mm predict cancel --all +mm predict cancel --order-id 0x1f9090aae28b8a3dceadf281b0f12828e676c326 --toon ``` -`predict cancel --all` cancels every open order. Require explicit confirmation from the user before executing. +Substitute the confirmed targeting flag from step 3 (`--all`, `--market `, or +`--asset `). Completes inline; no polling ID. +Expected output: list of cancelled order IDs. -## Watch async jobs +### 5. Verify ```bash -mm predict watch --id --wait +mm predict orders --toon ``` -Use this for setup, approve, deposit, withdraw, redeem, and order jobs that haven't reached a terminal state. +Expected output: the cancelled orders are gone (empty list after `--all`). Report the result. + +## Decision points + +- User rejects at step 3 → stop. Do not cancel. +- User says "cancel my order" but multiple are open → show the step 1 list and ask which. +- Cancelled order was partially filled → the filled part remains as a position (step 2); + selling it back is a new order via workflows/predict-place-order.md. +- Position won after resolution → workflows/predict-portfolio.md to redeem. + +## Errors + +| Error / symptom | Recovery | +| --- | --- | +| `ValidationError` (zero or multiple targets) | Pass exactly one of `--order-id`, `--all`, `--market`, `--asset` | +| `NOT_FOUND` / order not in step 5 list already | Order already filled or cancelled; check `mm predict positions --toon` | +| `PREDICT_SETUP_REQUIRED` | workflows/predict-setup.md, then retry | +| `UNKNOWN` (`fetch failed`) | Transient CLOB failure; retry, check `mm predict status` | diff --git a/skills/metamask-agent-wallet/workflows/predict-markets.md b/skills/metamask-agent-wallet/workflows/predict-markets.md index 64d37e0..a6858a0 100644 --- a/skills/metamask-agent-wallet/workflows/predict-markets.md +++ b/skills/metamask-agent-wallet/workflows/predict-markets.md @@ -1,45 +1,65 @@ -# Predict markets workflow +# Browse prediction markets -Use this workflow to search, browse, and inspect prediction markets on Polymarket. +Use when the user wants to find, browse, or inspect Polymarket prediction markets or read an +order book. Placing an order: workflows/predict-place-order.md. Command details: +references/predict-data.md. -Reference command syntax in `references/predict.md`. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. + No Predict setup is needed to browse — these commands are all read-only. +2. You know what the user is looking for (topic, question, or market). If not, ask. -1. Search or browse markets. -2. Inspect the selected market to get outcome token IDs. +## Steps -## Search markets +### 1. Search for markets ```bash -mm predict markets search "Knicks NBA Finals" --limit 5 --toon +mm predict markets search "bitcoin above 52k" --limit 5 --toon ``` -Search can return loosely related markets, so always inspect the selected market before quoting. +The query is positional — there is no query flag; quote multi-word queries. +Expected output: `result.markets[]` with `question`, `slug`, `conditionId`, `outcomes`, +`outcomePrices`, `liquidity`, `active`. Search can return loosely related markets — always +inspect the chosen market in step 2 before trading. +Capture: `slug` or `conditionId` → `` for step 2. -If search is noisy, list active markets and filter manually: +### 2. Inspect the chosen market ```bash -mm predict markets list --active --limit 50 --toon +mm predict markets get --market bitcoin-above-52k-on-july-9-2026 --toon ``` -## Browse by topic +Expected output: market detail with per-outcome token IDs, prices, tick size, and minimum +order size. Outcome token IDs are NOT market IDs — map the user's intended outcome (e.g. +"Yes") to its token ID. +Capture: outcome token ID → `` for step 3 and for quote/place +(references/predict-trade.md); `conditionId` → `` for cancel/redeem. -Use events, series, and tags to browse by topic. Resolve a tag slug or ID first, then filter: +### 3. Read the order book (optional) ```bash -mm predict tags list --limit 50 --toon -mm predict events list --tag-slug sports --active --limit 10 --toon -mm predict events get --toon -mm predict series list --recurrence weekly --limit 10 --toon +mm predict book --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --toon ``` -These browse commands don't return outcome token IDs. Drill into a specific market with `mm predict markets get` before quoting or placing. +Expected output: bids and asks as `{price, size}` levels; prices are per-share in (0, 1]. +Use the best bid/ask to suggest a realistic limit price. -## Inspect a market +## Decision points -```bash -mm predict markets get --toon -``` +- Search results are noisy → `mm predict markets list --active --limit 50 --toon` and filter + manually, or narrow with `--tag ` (get slugs from `mm predict tags list --toon`). +- User wants to browse by topic instead of a specific question → + `mm predict events list --tag-slug sports --active --limit 10 --toon`, then + `mm predict events get --toon`; events/series/tags do not return token IDs, so + always finish with step 2 on a specific market. +- User picks a market and wants to trade → workflows/predict-place-order.md with the captured + ``. + +## Errors -The market detail prints outcome token IDs. Outcome token IDs aren't market IDs. Use the token ID for `quote`, `place`, `book`, and `balance --token-id`. +| Error / symptom | Recovery | +| --- | --- | +| `NOT_FOUND` | Unknown slug/ID/token ID; re-run step 1 and re-copy the exact value | +| Empty search results | Broaden the query or raise `--limit`; try `markets list --active` | +| `UNKNOWN` (`fetch failed`) | Transient Gamma/CLOB failure; retry, check `mm predict status` | diff --git a/skills/metamask-agent-wallet/workflows/predict-place-order.md b/skills/metamask-agent-wallet/workflows/predict-place-order.md index c5372a8..8f5f6bd 100644 --- a/skills/metamask-agent-wallet/workflows/predict-place-order.md +++ b/skills/metamask-agent-wallet/workflows/predict-place-order.md @@ -1,72 +1,79 @@ -# Predict place order workflow +# Quote and place a prediction order -Use this workflow to quote and place a prediction market order. +Use when the user wants to buy or sell shares in a Polymarket outcome. Cancelling or viewing +orders: workflows/predict-manage-orders.md. Command details: references/predict-trade.md. -Reference command syntax in `references/predict.md`. +## Preconditions -## Flow +1. `mm predict status` shows `account.setupComplete: true`. If not: workflows/predict-setup.md. +2. pUSD balance covers the order (size × price for buys): `mm predict balance --sync --toon`. + If insufficient: workflows/predict-funding.md. +3. You know: market, outcome, side (buy/sell), size (shares), and price or "market". If any + is missing, ask — do not guess. -1. Check setup and balance. -2. Inspect the market to get the outcome token ID. -3. Quote the order. -4. Confirm with the user and place. +## Steps -## Check setup and balance - -Verify that Predict is fully set up and get the deposit wallet address: +### 1. Get the outcome token ID ```bash -mm predict status +mm predict markets get --market bitcoin-above-52k-on-july-9-2026 --toon ``` -Check `setupComplete` is `true`. If not, follow `predict-setup.md` to run first-time setup. +Find the market first if needed: workflows/predict-markets.md. +Expected output: market detail with per-outcome token IDs, tick size, and minimum order size. +Map the user's intended outcome to its token ID — token IDs are not market IDs. +Capture: outcome token ID → `` for steps 2 and 4. -Then check the deposit wallet balance: +### 2. Quote the order ```bash -mm predict balance --sync +mm predict quote --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --side buy --size 10 --limit-price 0.55 --toon ``` -If the balance is zero or insufficient for the order, follow `predict-funding.md` to deposit funds. Use the deposit wallet address from `mm predict status` when funding. +Expected output: estimated cost, average fill price, and fillable size. + +### 3. Confirm with the user -## Get outcome token ID +Show ALL of: market question, outcome, token ID, side, size (shares), price per share, order +type (`GTC` default; `GTD` needs `--expiration `; `FOK`/`FAK` are market-style), total +cost for buys, and the quote from step 2. Warn if the price is 1 or the market's end date has +passed but UMA resolution is pending — prices then do not reflect true odds. Do not continue +until the user explicitly approves. -If the user hasn't already identified the market, follow `predict-markets.md` to find and inspect it. +### 4. Place the order ```bash -mm predict markets get --toon +mm predict place --token-id 21742633143463906290569050155826241533067272736897614950488156847949938836455 --side buy --size 10 --price 0.55 --order-type GTC --toon ``` -Map the user's intended outcome to the correct token ID from the market detail. +Orders are signed by the Predict deposit wallet, not the owner EOA. +Expected output: order record with `orderId` and status, or a job ID. +Capture: `orderId` → `` for cancel; a job ID → `` for +`mm predict watch --id --wait`. -## Quote - -Preview the order cost and fill before placing: +### 5. Verify ```bash -mm predict quote \ - --token-id \ - --side buy --size 100 --limit-price 0.55 +mm predict orders --toon ``` -Show the user the estimated cost and fill. - -## Place +Expected output: the new order listed as open (limit orders), or absent because it filled +(FOK/FAK / crossing limit). Check fills with `mm predict positions --toon` and report. -After the user confirms token ID, outcome, side, size, price, and order type: - -```bash -mm predict place \ - --token-id \ - --side buy --size 100 --price 0.55 \ - --order-type GTC -``` +## Decision points -`--order-type` is one of `GTC`, `GTD`, `FOK`, or `FAK`. `--post-only` only applies to GTC/GTD. `--expiration` is unix seconds for GTD. +- User rejects at step 3 → stop. Do not place. +- Quote shows insufficient fillable size or a bad price → show the book + (`mm predict book --token-id --toon`) and re-confirm a new price at step 3. +- GTD order → add `--expiration ` (`date +%s` plus the desired lifetime); `--post-only` + is invalid with FOK/FAK. +- Job ID returned at step 4 → `mm predict watch --id --wait --toon` before step 5. -## Safety notes +## Errors -- Placing orders between a market's end date and its final UMA resolution carries major financial risk. Prices during this window don't reflect true odds and arbitrage strategies can fail if UMA resolves unexpectedly. If the order creation time is after the market end date but before UMA resolution, warn the user about potential financial loss and get explicit confirmation before proceeding. -- Prices are 0-1 floats. Treat `--price 1` as suspicious unless the user explicitly confirms. -- Trades are signed by the deposit wallet address from `mm predict status`, not the connected owner EOA. -- Always inspect the market to map the user's intended outcome to the correct token ID. +| Error / symptom | Recovery | +| --- | --- | +| `PREDICT_SETUP_REQUIRED` | workflows/predict-setup.md, then retry | +| `WALLET_ERROR` (insufficient pUSD) | `mm predict balance --sync`; deposit via workflows/predict-funding.md | +| `ValidationError` | Price outside (0, 1], size below market minimum, `--post-only` with FOK/FAK, or `--expiration` without GTD; fix and retry | +| `NOT_FOUND` on token ID | Re-run step 1 and copy the exact token ID | diff --git a/skills/metamask-agent-wallet/workflows/predict-portfolio.md b/skills/metamask-agent-wallet/workflows/predict-portfolio.md index 05357a2..fb71816 100644 --- a/skills/metamask-agent-wallet/workflows/predict-portfolio.md +++ b/skills/metamask-agent-wallet/workflows/predict-portfolio.md @@ -1,35 +1,79 @@ -# Predict portfolio workflow +# Predict portfolio and redeem winnings -Use this workflow to view the Predict portfolio or redeem winning positions. +Use when the user wants a Predict account overview or to claim winnings from resolved +markets. Cancelling open orders: workflows/predict-manage-orders.md. Command details: +references/predict-trade.md. -Reference command syntax in `references/predict.md`. +## Preconditions -## View portfolio +1. `mm predict status` shows `account.setupComplete: true`. If not: workflows/predict-setup.md. +2. Redeeming only works after a market has resolved; unresolved positions are sold via + workflows/predict-place-order.md instead. -Get a single snapshot of balance, open positions, and redeemable winnings: +## Steps + +### 1. View the portfolio ```bash mm predict portfolio --toon ``` -## Redeem winnings +Expected output: pUSD balance, open positions with estimated value, and redeemable winnings. +If the user only wanted an overview, report and stop here. -After a market resolves, list and claim winning positions: +### 2. List redeemable positions ```bash mm predict redeem list --toon ``` -Redeem a single position: +Expected output: redeemable positions with `conditionId`, market question, and size. If +empty, report that there is nothing to redeem and stop. +Capture: `conditionId` → `` for step 4. + +### 3. Confirm the redeem scope with the user + +Choose EXACTLY ONE form and show the user exactly what it covers from step 2: + +- One market → positional `` (show its question and size). +- Everything → `--all` — say explicitly "this redeems EVERY winning position" and list all + affected markets with expected pUSD proceeds. + +Do not continue until the user explicitly approves the exact scope. + +### 4. Redeem ```bash -mm predict redeem --wait +mm predict redeem 0x5179f59617e32ce893c4ecc0ee1e4916c65f7a85eb3774c87cdc3430cb1d0d73 --wait --toon ``` -Redeem all winning positions: +For everything: `mm predict redeem --all --wait --toon` (no positional). +Expected output: success once the redemption transaction confirms. +Capture: `pollingId` (only if run without `--wait`) → `` for +`mm predict watch --id --wait`. + +### 5. Verify ```bash -mm predict redeem --all --wait +mm predict balance --sync --toon ``` -`predict redeem --all` redeems every winning position. Confirm the target (condition ID or `--all`) with the user before executing. With `--wait`, the CLI polls for the redemption transaction receipt. +Expected output: pUSD increased by the redeemed proceeds; `mm predict redeem list --toon` no +longer lists the redeemed market(s). Report the new balance. + +## Decision points + +- User rejects at step 3 → stop. Do not redeem. +- User expected a win but step 2 is empty → the market may not be resolved yet; check it with + `mm predict markets get --market --toon` (`closed` field). +- User wants the proceeds in their EOA → after step 5, withdraw via + workflows/predict-funding.md. + +## Errors + +| Error / symptom | Recovery | +| --- | --- | +| `ValidationError` (both or neither of positional / `--all`) | Pass exactly one: a `` positional OR `--all` | +| `NOT_FOUND` on condition ID | Re-run step 2 and copy the exact `conditionId` | +| `PREDICT_SETUP_REQUIRED` | workflows/predict-setup.md, then retry | +| Job stalls without `--wait` | `mm predict watch --id --wait` | diff --git a/skills/metamask-agent-wallet/workflows/predict-setup.md b/skills/metamask-agent-wallet/workflows/predict-setup.md index 3aa2985..278ca90 100644 --- a/skills/metamask-agent-wallet/workflows/predict-setup.md +++ b/skills/metamask-agent-wallet/workflows/predict-setup.md @@ -1,54 +1,80 @@ -# Predict setup workflow +# Predict first-time setup -Use this workflow for first-time Predict setup, refreshing credentials, or repairing approvals. +Use when Predict has never been set up for this wallet, or `setupComplete: false` blocks a +trading/funding command. Repairing stale credentials/approvals only: jump to Decision points. +Command details: references/predict-account.md. -Reference command syntax in `references/predict.md`. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. The owner EOA holds POL on Polygon for gas: `mm wallet balance --chain 137`. If empty, + fund the wallet first (references/wallet.md). +3. You know whether the user wants real trading (`mainnet`) or paper trading (`testnet`). + If not stated, ask — do not guess. -1. Choose Predict mode. -2. Run one-time setup. -3. Verify status. +## Steps -## Choose mode +### 1. Check geoblock ```bash -mm predict mode mainnet +mm predict geoblock --toon ``` -Replace `mainnet` with `testnet` if the user wants to paper trade. +Expected output: `data.result.blocked: false`. If `blocked: true`, stop — Predict is +unavailable from this region; do not attempt setup. -## Run setup +### 2. Set the trading mode ```bash -mm predict setup --wait +mm predict mode mainnet --toon ``` -This blocks until credential, deposit-wallet, and approval jobs complete. Without `--wait`, track returned jobs with `mm predict watch --id --wait`. +Positional-only; replace `mainnet` with `testnet` for paper trading. +Expected output: `data.result.mode` matching the requested mode. -The owner EOA needs POL on Polygon for gas to complete the setup transactions. +### 3. Confirm with the user -Polymarket is geoblocked in some regions. `predict setup` checks the caller's IP first and aborts with `PREDICT_GEOBLOCKED` before any wallet interaction if the region is restricted. To check region status independently: +Show: that setup deploys a Predict deposit wallet, creates trading credentials, and grants +token approvals on Polygon (chain 137), plus the chosen mode. Do not continue until the user +explicitly approves. -```bash -mm predict geoblock -``` - -## Verify status - -Confirm `setupComplete` is `true` and note the deposit wallet address: +### 4. Run one-time setup ```bash -mm predict status +mm predict setup --wait --toon ``` -## Refresh credentials or approvals +Expected output: success after credential, deposit-wallet, and approval jobs complete. +Capture: `pollingId` (only if run without `--wait`) → `` for +`mm predict watch --id --wait`. -If credentials or approvals look stale later: +### 5. Verify ```bash -mm predict auth --refresh -mm predict approve --wait +mm predict status --toon ``` -Then verify with `mm predict status`. +Expected output: `account.setupComplete: true`, `account.deployed: true`, +`account.credentials: true`. +Capture: `account.depositWalletAddress` → report to the user for funding +(workflows/predict-funding.md). + +## Decision points + +- Step 1 fails `UNKNOWN` (`fetch failed`) repeatedly → tell the user the geoblock probe is + unreachable and continue; `mm predict setup` itself aborts `PREDICT_GEOBLOCKED` if restricted. +- Step 5 shows `credentials: false` → run `mm predict auth --refresh --toon`, then re-verify. +- Step 5 shows `deployed: true` but `setupComplete: false` (approvals missing) → confirm with + the user, run `mm predict approve --wait --toon`, then re-verify with `mm predict status`. +- User rejects at step 3 → stop. Nothing has changed on-chain. +- Setup succeeded and the user wants to trade → workflows/predict-funding.md, then + workflows/predict-place-order.md. + +## Errors + +| Error / symptom | Recovery | +| --- | --- | +| `PREDICT_GEOBLOCKED` | Region restricted; stop. Re-check with `mm predict geoblock` | +| `WALLET_ERROR` / gas failure | Owner EOA lacks POL on Polygon: `mm wallet balance --chain 137`, fund, retry step 4 | +| `UNKNOWN` (`fetch failed`) | Transient back-end failure; retry, check `mm predict status` | +| Setup stalls without `--wait` | `mm predict watch --id --wait`, then `mm predict status` | diff --git a/skills/metamask-agent-wallet/workflows/swap.md b/skills/metamask-agent-wallet/workflows/swap.md index dad35c4..a240dbd 100644 --- a/skills/metamask-agent-wallet/workflows/swap.md +++ b/skills/metamask-agent-wallet/workflows/swap.md @@ -1,48 +1,63 @@ -# Swap workflow +# Same-chain swap -Use this workflow when the user wants to swap tokens on the same chain. +Use when the user wants to swap one token for another on a single chain. +Cross-chain: use workflows/bridge.md instead. Command details: references/swap.md. -Reference command syntax in `references/swap.md`. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. You know: source token, destination token, amount, chain. If the chain was not named, ask — + do not guess. List chains with `mm chains list`. +3. Balance covers the amount plus gas: `mm wallet balance --chain `. -1. Quote. -2. Confirm with the user. -3. Execute and track status. +## Steps -Don't skip the quote review step. The user needs to see output amount, fees, route, and slippage before executing. - -## Quote +### 1. Get a quote ```bash -mm swap quote --from ETH --to USDC --amount 1 --from-chain 1 +mm swap quote --from ETH --to USDC --amount 0.5 --from-chain 1 --toon ``` -Required flags: `--from`, `--to`, `--amount`, and `--from-chain`. +Do NOT pass `--to-chain`, `--to-address`, or `--refuel` for a same-chain swap. `--to-address` +is rejected same-chain (`INVALID_SWAP_PARAMS`) — output always goes to the active wallet. +Expected output: `data.quoteId` plus a `quote` object with `destAssetAmount`, +`minDestAssetAmount`, and `feeData`. +Capture: `quoteId` → used as `` in steps 3 and 4. -`--to-address` isn't supported for same-chain swaps. Output always goes to the signer's wallet. +### 2. Confirm with the user -Persist the quote id for execution. Show the quote to the user before execution. -Confirm source token, destination token, amount, chain, slippage, expected output, fees, and route. +Show: from token, to token, amount, chain, slippage (default 0.5%), quoted output amount +(`destAssetAmount` scaled by the destination token's `decimals`), minimum received +(`minDestAssetAmount`), fees. Do not continue until the user explicitly approves. -## Execute +### 3. Execute by quote id ```bash -mm swap execute --quote-id "$QUOTE_ID" +mm swap execute --quote-id --toon ``` -Prefer executing by quote ID. Re-quote-and-execute flags exist, but quote ID execution keeps the reviewed quote tied to the submitted action. +Always execute the reviewed quote by id. Never pass token/amount flags here — that re-quotes +and executes a price the user never reviewed. -## Status +### 4. Track status ```bash -mm swap status --quote-id "$QUOTE_ID" +mm swap status --quote-id --toon ``` -## Edge cases +Repeat until the status is terminal (completed or failed), then report the result. + +## Decision points + +- User rejects at step 2 → stop. Do not execute. +- Quote expired or not found at step 3 → return to step 1, then re-confirm at step 2. +- User wants the output at a different address → impossible same-chain; offer a follow-up + `mm transfer` after the swap completes. + +## Errors -- Quote expired: re-quote and ask the user to review the new quote. -- Insufficient balance: surface the error verbatim. -- Slippage exceeded: only increase `--slippage` if the user explicitly accepts more slippage. Always warn the user - if slippage is increased above 1% that it will affect the minimum received. -- Missing chain: use `mm chains list` before guessing a chain ID. +| Error / symptom | Recovery | +| --- | --- | +| `NO_QUOTES` | No route for this pair/amount. Try a different amount or token pair; verify the token exists on the chain with `mm token list search --query --chain ` | +| Insufficient balance | `mm wallet balance --chain `; offer a bridge from another chain (workflows/bridge.md) | +| User asks for higher slippage | Re-quote with `--slippage ` only after explicit user approval; warn above 1% | diff --git a/skills/metamask-agent-wallet/workflows/troubleshooting.md b/skills/metamask-agent-wallet/workflows/troubleshooting.md index 566e86d..f160c6e 100644 --- a/skills/metamask-agent-wallet/workflows/troubleshooting.md +++ b/skills/metamask-agent-wallet/workflows/troubleshooting.md @@ -1,51 +1,81 @@ -# Troubleshooting Workflow +# Troubleshooting -Use this workflow when a command fails, hangs, prompts unexpectedly, or behaves differently in a terminal. +Use when a command fails, hangs, prompts unexpectedly, or returns an unknown error. +Error code meanings: references/errors.md. Command details: references/doctor.md. -## Universal Triage +## Preconditions -Run `mm doctor` first to inspect CLI version, skills, environment, and session health in one shot: +1. CLI reachable: `mm --version` prints a version. If `mm: command not found`: `npm install -g @metamask/agentic-cli@latest` and check `PATH`. + +## Steps + +### 1. Triage with doctor ```bash -mm doctor +mm doctor --toon ``` -If you need more detail, run these in order: +Expected output: `cli`, `env`, `authenticated`, `initialized`, `hints`. + +### 2. Branch on the doctor output + +- If `authenticated: false` → workflows/login.md. Fix auth before anything downstream. +- If `initialized: false` → workflows/onboarding.md (step 4). +- If `hints` is non-empty → follow each hint verbatim first. +- If `env` is not what the user expects → `mm config set env prod` (or `dev`/`uat`) after user approval. +- If all healthy → step 3. + +### 3. Check the failing command's contract ```bash -mm --version -mm auth status -mm --help +mm transfer --help ``` -If `auth status` reports anything other than authenticated, fix authentication before debugging downstream wallet, signing, swap, perps, or predict commands. +(Substitute the failing command.) Trust the `flags` list over the `usage` string — some usage +strings are wrong (e.g. `wallet trading-mode` prints `mm mode ...`, which does not exist). -## Common Symptoms +### 4. Match the error code + +- `NOT_INITIALIZED` → workflows/onboarding.md. +- `AUTH_ERROR` / `TOKEN_REFRESH_FAILED` → workflows/login.md. +- `MNEMONIC_LOCKED` / `WRONG_PASSWORD` → set the correct `MM_PASSWORD` env var, retry. +- `ALREADY_ENCRYPTED` on `wallet password set` → use `mm wallet password change`. +- `NOT_ENCRYPTED` on `wallet password change|remove` → use `mm wallet password set`. +- `CHAIN_ID_MISMATCH` → align payload `domain.chainId` with `--chain-id`. +- Command returned a `pollingId` and seems stuck → `mm wallet requests list --toon`, then `mm wallet requests watch --polling-id ` (references/wallet-requests.md). +- `NO_TTY` → pass explicit subcommands/flags (`mm login browser`, `--yes` after approval); password prompts need a real terminal. +- `NETWORK_UNREACHABLE` → check connectivity, retry. +- Anything else → look it up in references/errors.md and surface the CLI message + hint verbatim. + +### 5. If the command hangs or hides progress, re-run with debug logs + +```bash +mm wallet balance --toon --verbose +``` -| Symptom | Likely cause | Next step | -| --- | --- | --- | -| `mm: command not found` | Binary not installed or not on `PATH` | Check install and PATH | -| Async command returns a polling id and appears stuck | Request was dispatched without `--wait` | Use `mm wallet requests list` or `mm wallet requests watch --polling-id ` | -| Auth errors after previously working | Expired token | Check `mm auth status` and session file under `~/.metamask/` | -| `CHAIN_ID_MISMATCH` on typed data | Payload `domain.chainId` differs from `--chain-id` | Align the two chain IDs | -| `MNEMONIC_LOCKED` or `WRONG_PASSWORD` | BYOK mnemonic is encrypted and password was wrong or missing | Set the correct `MM_PASSWORD` environment variable and re-run | -| `ALREADY_ENCRYPTED` on `wallet password set` | Mnemonic already has a password | Use `mm wallet password change` instead | -| `NOT_ENCRYPTED` on `wallet password change/remove` | Mnemonic is not encrypted | Use `mm wallet password set` instead | +Expected output: progress/debug lines on stderr; the result stays on stdout. -## Verbose Logging +### 6. Last resort: reset -Use `--verbose` when a command appears to hang or hides progress: +Only after steps 1-5 fail, and ONLY with the user's explicit confirmation of the scope +("wipes the entire local CLI session; login + init required again"): ```bash -mm wallet balance --json --verbose +mm reset --yes --toon ``` -Structured logs and progress lines go to stderr; command results remain on stdout. +Expected output: `ok: true`. Then follow workflows/onboarding.md. -## Error Codes +## Decision points -For raw error-code meanings, load `../references/errors.md`. Relay CLI errors verbatim before explaining them. +- Version mismatch warning in preflight → suggest `npm install -g @metamask/agentic-cli@latest`, then `npx skills add metamask/agent-skills`. +- Error text is clear and user-fixable (bad address, insufficient balance) → relay it verbatim; do not reset. +- User declines the reset confirmation → stop; report remaining state. -## Reset Last +## Errors -Use `mm reset` only after checking version, auth status, and the failing command's help output. Reset clears local session state and should not be the first troubleshooting step. Always ask the user for explicit confirmation before running reset. The command itself also prompts for confirmation; pass `--yes` to skip the prompt in non-interactive sessions. +| Error / symptom | Recovery | +| --- | --- | +| `RESET_FAILED` | Retry `mm reset`; check `~/.metamask/` file permissions | +| Auth worked before, fails now | Token expired: workflows/login.md | +| Unknown flag rejected despite appearing in `usage` | Usage strings can be wrong; trust `flags` list and the reference file | diff --git a/skills/metamask-agent-wallet/workflows/x402-pay.md b/skills/metamask-agent-wallet/workflows/x402-pay.md index 36d70b6..0350ce7 100644 --- a/skills/metamask-agent-wallet/workflows/x402-pay.md +++ b/skills/metamask-agent-wallet/workflows/x402-pay.md @@ -1,57 +1,82 @@ -# x402 pay workflow (buyer) +# Pay an HTTP 402 (x402) paywall -Use this when an HTTP request returns `402 Payment Required` (x402), or the user asks to -fetch/pay for a paywalled API, endpoint, file, or resource over HTTP. +Use when an HTTP request returns `402 Payment Required` (x402), or the user asks to fetch or +pay for a paywalled API, endpoint, file, or resource over HTTP. Autonomous auto-pay is +unsupported — every payment needs explicit user approval. Command details: references/x402.md. -`scripts/x402_pay.py` does the payment. Command details are in `references/x402.md`. Call it by -its full path inside this skill's directory (`$SKILL_DIR` is the folder containing `SKILL.md`), not -a bare `scripts/...`, because the shell working directory is not stable between commands. It is a -script, not an `mm` command, so do not pass `--toon`/`--format`; it always prints JSON. +## Preconditions -## Flow +1. `mm doctor` reports `authenticated: true` and `initialized: true`. If not: SKILL.md § Preflight. +2. `$SKILL_DIR` resolved (references/concepts.md) — the script must be called by absolute path. +3. The URL is `https://` (loopback-only exception for local testing). If http: stop, ask the user. +4. BYOK with an encrypted mnemonic: `MM_PASSWORD` is set (references/concepts.md). +5. Never pass `--toon`/`--format` to the script; it always prints JSON. -1. Inspect the resource. -2. Show the payment to the user and get approval. -3. Pay. -4. Report the settlement and return the resource. +## Steps -## Inspect +### 1. Inspect the resource (read-only, no spending) ```bash -python3 "$SKILL_DIR/scripts/x402_pay.py" inspect +python3 "$SKILL_DIR/scripts/x402_pay.py" inspect https://api.example.com/premium ``` -Prints the payment requirement(s) as JSON: asset, human-readable amount, network, `payTo`, and -resource. This is read-only and does not spend. +For a non-GET resource add `--method POST --data '{"query":"eth"}'`. +Expected output: `{"status": "payment_required", "options": [...]}` on stdout. +Capture: from the option with `"eligible": true` → `asset`, `humanAmount` (or atomic `amount`), +`network`, `payTo`. -## Confirm +### 2. Validate the eligible option -Show the user the asset, amount, network, `payTo`, and resource URL from the inspect output, and -get explicit approval. A signature authorizes a real token debit. +If/then checklist — stop and tell the user if any check fails: -## Pay +- `eligible` is `true` for at least one option; else see Decision points. +- `payTo` and `asset` match the legend `
` format (full 40 hex; no `...`). +- `scheme` is `exact` — the signed amount is exactly `amount`, not a maximum. +- `humanAmount` present → sanity-check it is a plausible price; absent → warn the user the + amount is shown in raw atomic units. + +### 3. Confirm with the user + +Show: asset (symbol + contract), amount, network, `payTo`, resource URL. State that a signature +authorizes a real token debit. Do not continue until the user explicitly approves. + +### 4. Pay (one attempt only) ```bash -python3 "$SKILL_DIR/scripts/x402_pay.py" pay --confirm +python3 "$SKILL_DIR/scripts/x402_pay.py" pay https://api.example.com/premium --confirm ``` -Add `--asset ` or `--network ` if the `402` offered more than one eligible -option. For a non-GET resource add `--method` (and `--data` for a body); the same request is -replayed with the payment attached. On success the script prints the settlement transaction and -the resource body. - -## Edge cases - -- `error` with "no eligible option": the server offered no `exact`-scheme payment on a network mm - supports. Show the offered options to the user. -- `error` with "multiple eligible options": the server offered the same scheme on several networks - or assets (e.g. Base and Polygon). Rerun `pay` with `--network` or `--asset` to choose one. -- `error` mentioning "permit2": the only options use the Permit2 transfer method, which this skill - does not sign (it supports EIP-3009 only). Tell the user it is unsupported. -- `error` with "payment not accepted": surface it. Do not rerun blindly; rerunning makes a new - payment. -- `error` with "not a standard x402 challenge": the endpoint returned a 402 in a different payment - scheme (for example pay-first then send a transaction hash). This skill supports the standard - x402 exact scheme only. Tell the user it is unsupported rather than trying to pay. -- Encrypted BYOK mnemonic: set `MM_PASSWORD` so signing is non-interactive. -- Unknown network: the network is not in `mm chains list`; confirm the chain is supported. +Reuse the exact `--method`/`--data` from step 1. If step 1 showed multiple eligible options, add +`--asset
` or `--network ` for the one the user chose. +Expected output: `{"status": "settled", "transaction": "0x...", "resource": ...}` on stdout +(exit 0). On exit 1, stderr carries `{"status": "error", "error": ...}`. +Capture: `transaction` → report to the user; `resource` → the paid content. + +### 5. Verify and report + +If `status` is `settled`: report asset, amount, network, `payTo`, `transaction` (may be `null` +if the server sent no receipt), and return the `resource` body to the user. Anything else: +Decision points below — do NOT rerun `pay`. + +## Decision points + +- No eligible option / `permit2` / `not a standard x402 challenge` → unsupported paywall; show + the offered options to the user and stop. +- `multiple eligible options` error at step 4 → ask the user to pick, rerun step 4 once with + `--asset` or `--network`. +- Error mentions a redirect or `expected HTTP 402, got 3xx` → unexpected redirect; the script + never follows redirects on payment. Stop and show the user the target — do not pay it. +- `expected HTTP 402, got 200` → resource is free or already paid; just return it. +- `payment not accepted (HTTP )` → surface verbatim and STOP. Never rerun `pay` — the debit + may already have settled; a rerun signs a new payment. Only retry with fresh user approval. +- User rejects at step 3 → stop. Do not pay. + +## Errors + +| Error / symptom | Recovery | +| --- | --- | +| `refusing to pay without --confirm` | Complete steps 1–3, then rerun step 4 with `--confirm` | +| `resource URL must be https://` | Ask the user for an https URL | +| `signing failed` | `mm doctor`; BYOK: set `MM_PASSWORD`; references/signing.md | +| `mm produced no JSON` | `mm doctor`; workflows/troubleshooting.md | +| Full table | references/x402.md § Errors |