# AgentRouter — MetaMask > Base Sepolia testnet. Wallet setup and spending require the owner's authorization. Follow one wallet path. Set up your agent wallet, fund it with test USDC and purchase your AgentRouter key. [Human guide](https://docs.agentrouter.cc/wallets/metamask) · [Pricing](https://agentrouter.cc/pricing#agents) · [Documentation index](https://docs.agentrouter.cc/llms.txt) ## Install the wallet Use a terminal on your Mac or Linux computer. You need Node.js 22.18+, npm, Python 3 and Git. The purchase and inference steps also use curl, jq and uuidgen. Install missing tools before continuing. Run the wallet commands without sudo. This guide uses MetaMask Agent Wallet 7.1.0. Keep the terminal open through setup and purchase. ```sh mkdir -p "$HOME/.local/share/h07-metamask" npx --yes --package=npm@10 npm install \ --prefix "$HOME/.local/share/h07-metamask" \ --save-exact @metamask/agent-wallet@7.1.0 ``` ### Expected result The installation completes without an error. The next step [checks the installed CLI](https://docs.agentrouter.cc/wallets/metamask#metamask-check). ## Check the CLI Add the [installed CLI](https://docs.agentrouter.cc/wallets/metamask#metamask-install) to this terminal's PATH and check it. ```sh export PATH="$HOME/.local/share/h07-metamask/node_modules/.bin:$PATH" mm doctor ``` ### Expected result Check that `cli` is **7.1.0**. Before sign-in, `authenticated` and `initialized` are **false**. ## Get the payment helper Download the official MetaMask payment helper at the tested revision. Keep this directory and the METAMASK_SKILL_DIR setting for the [purchase step](https://docs.agentrouter.cc/wallets/metamask#03-settle). ```sh git clone --no-checkout https://github.com/MetaMask/agent-skills.git \ "$HOME/.local/share/h07-metamask/agent-skills" && git -C "$HOME/.local/share/h07-metamask/agent-skills" checkout --detach \ 317df8eb6efc7cdecc867465bb17f96306759369 export METAMASK_SKILL_DIR="$HOME/.local/share/h07-metamask/agent-skills/skills/metamask-agent-wallet" python3 "$METAMASK_SKILL_DIR/scripts/x402_pay.py" --help ``` ### Expected result Help lists `inspect`, `pay`, `mcp-inspect` and `mcp-sign`. ## Connect your phone Scan the QR with MetaMask Mobile and approve the connection. Your phone identifies you to the Agent Wallet service. This does not copy your personal wallet's seed or transfer funds. Keep the QR, login URL and tokens private. Your personal wallet and the agent wallet remain separate. ```sh mm login qr ``` ### Expected result The phone connection completes. [Check authentication](https://docs.agentrouter.cc/wallets/metamask#metamask-auth) in the next step. ## Check authentication After [approving the connection on your phone](https://docs.agentrouter.cc/wallets/metamask#metamask-login), check the wallet again. ```sh mm doctor ``` ### Expected result `authenticated` is **true**. `initialized` stays **false** until [the next step](https://docs.agentrouter.cc/wallets/metamask#metamask-init). ## Create the agent wallet Choose **Server Wallet**, then **Guard mode** in the interactive setup. MetaMask holds this agent wallet's signing key in a trusted execution environment on its infrastructure. Your computer requests signatures without downloading the private key. Wallet access depends on MetaMask's service. Local credentials are sensitive and are not a private-key backup. [Wallet architecture](https://docs.metamask.io/agent-wallet/reference/architecture/) · [Guard mode](https://docs.metamask.io/agent-wallet/reference/trading-modes/) ```sh mm init ``` ### Expected result Setup completes. [Check the wallet address, mode and allowed chains](https://docs.agentrouter.cc/wallets/metamask#metamask-wallet) next. ## Check wallet and network Keep the agent wallet's address for [funding](https://docs.agentrouter.cc/wallets/metamask#metamask-fund). Use **Base Sepolia only** even if the default policy also allows mainnets. **A zero daily USD limit does not guarantee zero x402 spending.** Signatures are excluded from that limit. A payment can proceed without a phone prompt, even in Guard mode. [Review the offer](https://docs.agentrouter.cc/wallets/metamask#01-quote) and obtain the wallet owner's spending approval. [Spending-limit behavior](https://docs.metamask.io/agent-wallet/reference/outflow-policy/) ```sh mm doctor mm chains list mm wallet show ``` ### Expected result Authentication and initialization are **true**. Base Sepolia (`84532`) is listed, and the wallet shows `guard` mode with `84532` in `allowed_chains`. ## Check testnet funds Read token amounts under Base Sepolia. `unpriced` and `totalValue: 0` can reflect missing testnet prices, not an empty wallet. USDC may be omitted when its balance is zero. ```sh mm wallet balance --testnet-chain-ids 84532 \ --token-contracts 0x036CbD53842c5426634e7929541eC2318f3dCF7e ``` ### Expected result Read each token's `amount`. Have enough Base Sepolia test USDC for the [inspected offer](https://docs.agentrouter.cc/wallets/metamask#01-quote) before purchasing. ## Get test USDC With the wallet owner's approval, open the [Circle faucet](https://faucet.circle.com/). Select **USDC** and **Base Sepolia**, paste the **agent wallet address** from the [wallet check](https://docs.agentrouter.cc/wallets/metamask#metamask-wallet) and choose **Send 20 USDC**. After confirmation, repeat the [balance check](https://docs.agentrouter.cc/wallets/metamask#metamask-balance). Use test tokens only. The documented x402 flow has the facilitator submit the transfer; it does not require ETH in your wallet. [MetaMask x402 guide](https://docs.metamask.io/agent-wallet/guides/pay-for-apis-x402/) ### Expected result After a successful 20-USDC faucet transfer to an initially empty wallet, the USDC amount is **20**. ## Read the offer # Read the purchase offer This unpaid request returns HTTP 402 with a `PAYMENT-REQUIRED` header and an empty body. It neither signs nor pays. The header contains standard-base64 x402 v2 JSON; your wallet client reads it in the next step. Check the current offer before authorizing payment: `exact`, Base Sepolia (`eip155:84532`), USDC asset `0x036CbD53842c5426634e7929541eC2318f3dCF7e`, amount `1000000` (1 test USDC), and the recipient. Stop if the terms differ from what you intend to buy. The quote is for access credit, not the price of one model request. No AgentRouter account or proprietary recovery header is required. The wallet owner still needs to authorize wallet setup and spending. ```sh curl -sS -X POST https://api.agentrouter.cc/v1/purchase \ -D - -o /dev/null ``` ### Expected result HTTP **402 Payment Required**, `Cache-Control: no-store`, a `PAYMENT-REQUIRED` header and an empty body. The decoded header has `x402Version: 2`, `resource.url: /v1/purchase` and an `accepts` array. Each option supplies its network, asset, amount, recipient and EIP-3009 signing metadata. A 402 error without that header is not a usable offer. ## Check the selected wallet # Prepare one wallet Use the same wallet in the purchase step. These checks do not authorize a payment. Keep wallet/session output private. The purchase command also uses `jq` to load the delivered key privately. Have at least 1 test USDC and inspect the offer's amount, network, asset and recipient. The wallet client handles signing; never paste a wallet private key into a prompt or this site. Tested with MetaMask Agent Wallet `7.1.0` in server-wallet mode and its [official payment helper](https://github.com/MetaMask/agent-skills/tree/317df8eb6efc7cdecc867465bb17f96306759369/skills/metamask-agent-wallet). Complete [vendor setup](https://docs.metamask.io/agent-wallet/guides/pay-for-apis-x402/). Set `METAMASK_SKILL_DIR` to that helper's `metamask-agent-wallet` directory. It needs Python 3 and `mm` on PATH. Expect authenticated/initialized and `eligible: true` for the offer. Eligibility alone does not prove settlement. ```sh mm doctor mm wallet balance --testnet-chain-ids 84532 \ --token-contracts 0x036CbD53842c5426634e7929541eC2318f3dCF7e python3 "${METAMASK_SKILL_DIR:?set the official helper directory}/scripts/x402_pay.py" inspect \ https://api.agentrouter.cc/v1/purchase --method POST ``` ### Expected result These readiness checks should not return a bearer key or settle a payment. Compare the decoded offer with step 1. Do not proceed on missing funds, an unavailable wallet, an unsupported offer or unapproved terms. New wallet versions need their own compatibility check. ## Buy once and keep the key # Buy once and keep the key **Run the block for your chosen wallet once, with the owner's spending approval.** After buying, use the delivered key. Switching wallets is not another step and does not undo a purchase. The command saves the full result in a new private directory and loads `AGENTROUTER_KEY` without displaying it. Keep the terminal open for inference. Do not run these commands with shell tracing, paste the result into model context, or put it in a served directory. The client handles `PAYMENT-SIGNATURE` and the `PAYMENT-RESPONSE` receipt. If any command fails, times out, or delivery is uncertain, **stop; do not rerun pay**. Another invocation can create another purchase. Preserve the private response and receipt. These stock-client examples do not retain an optional recovery capability, so self-service lost-key recovery is not available for this flow. Never repay automatically to recover a key. MetaMask's tested helper has no purchase-cap flag: inspect the current offer immediately before running `pay --confirm`. Its signature may authorize payment without another phone prompt. Expect `status: settled`, the API body in `resource`, and the decoded settlement receipt. ```sh umask 077 PURCHASE_DIR="$(mktemp -d "$HOME/agentrouter-purchase.XXXXXX")" && python3 "${METAMASK_SKILL_DIR:?set the official helper directory}/scripts/x402_pay.py" pay \ https://api.agentrouter.cc/v1/purchase --method POST \ --network eip155:84532 \ --asset 0x036CbD53842c5426634e7929541eC2318f3dCF7e --confirm \ >"$PURCHASE_DIR/result.json" 2>"$PURCHASE_DIR/error.log" && AGENTROUTER_KEY="$(jq -er '.resource.key | select(type == "string" and length > 0)' "$PURCHASE_DIR/result.json")" && export AGENTROUTER_KEY ``` ### Expected result The API returns HTTP 200 with `key`, `usage` and `PAYMENT-RESPONSE`. The commands export the opaque bearer key without printing it. A zero client exit code alone is insufficient: the response must contain the key and confirmed payment receipt. Keep the original response privately. Inspect the transaction through the [Base Sepolia explorer](https://sepolia.basescan.org/), without sharing the bearer key. ## Discover models # Read the public model catalog No authentication or payment is required. HTTP 200 returns a JSON array, not an OpenAI object/list envelope; an empty array is valid. Each model has `id`, `protocols`, `context_length`, `max_output_tokens`, `input_per_1m`, and `output_per_1m`. Prices are USD per **million** tokens as decimal strings. Optional fields include aliases, cache prices, and `free`. Use an offered model with the desired protocol; do not copy old fixture prices. On HTTP 429, respect `Retry-After`. Browser cross-origin access requires verified CORS. ```sh curl -sS https://api.agentrouter.cc/v1/models ``` ### Expected result ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "HTTP 200 public model catalog body", "type": "array", "items": { "type": "object", "required": ["id", "input_per_1m", "output_per_1m", "context_length", "max_output_tokens", "protocols"], "properties": { "id": { "type": "string" }, "aliases": { "type": "array", "items": { "type": "string" } }, "input_per_1m": { "type": "string" }, "output_per_1m": { "type": "string" }, "cache_read_per_1m": { "type": "string" }, "cache_write_per_1m": { "type": "string" }, "free": { "type": "boolean" }, "context_length": { "type": "integer" }, "max_output_tokens": { "type": "integer" }, "protocols": { "type": "array", "items": { "type": "string", "enum": ["openai", "anthropic"] } } } } } ``` ## OpenAI-compatible inference # Run OpenAI-compatible inference with a purchased key Verify `zai/glm-5.3` is offered with `openai` in the current catalog before spending. Set `AGENTROUTER_KEY` privately. Create **one** identity per intended request; retain it and the exact body for retries. Do not rerun `uuidgen` to bypass an uncertain result. Purchased keys do not support streaming. HTTP 200 returns an OpenAI-compatible completion. Replays return request status, not the original completion. HTTP 401 means an invalid key; 402 means allowance exhausted. Do not create a fresh identity after an uncertain charge. ```sh REQUEST_ID=$(uuidgen) curl -sS https://api.agentrouter.cc/v1/chat/completions \ -H "Authorization: Bearer ${AGENTROUTER_KEY:?set your key privately}" \ -H "Idempotency-Key: $REQUEST_ID" \ -H 'Content-Type: application/json' \ -d '{ "model": "zai/glm-5.3", "max_tokens": 512, "reasoning_effort": "low", "stream": false, "messages": [{ "role": "user", "content": "Reply with exactly OK." }] }' ``` ### Expected result # Expected inference result HTTP 200 returns an OpenAI-compatible completion, with the answer in `choices[0].message.content` and token counts in `usage`. The tested request returned `OK`; model output can vary. A 200 status with no visible answer is not proof of a useful reply. Keep the request identity if the result is uncertain; do not create a new billable request automatically. ## Anthropic-compatible inference # Run Anthropic-compatible inference with a purchased key Verify `zai/glm-5.3` is offered with `anthropic` in the current catalog before spending. Set `AGENTROUTER_KEY` privately. Retain this identity and exact body for retries; generate another identity only for a genuinely new intended request. HTTP 200 returns an Anthropic-compatible messages object. Purchased keys do not support SSE. Replays return request status, not the original completion. Do not create a fresh identity after an uncertain charge. The native `x-api-key` header is also supported. ```sh REQUEST_ID=$(uuidgen) curl -sS https://api.agentrouter.cc/v1/messages \ -H "Authorization: Bearer ${AGENTROUTER_KEY:?set your key privately}" \ -H "Idempotency-Key: $REQUEST_ID" \ -H 'Content-Type: application/json' \ -H 'anthropic-version: 2023-06-01' \ -d '{ "model": "zai/glm-5.3", "max_tokens": 512, "stream": false, "messages": [{ "role": "user", "content": "Reply with exactly OK." }] }' ``` ### Expected result # Expected inference result HTTP 200 returns an Anthropic-compatible message with content and usage. Output can stop at the requested token limit; a successful HTTP response does not guarantee the requested phrase. Purchased keys use non-streaming responses. Retain the request identity after a timeout or uncertain charge. A replay returns request status, not the original completion; do not generate a new identity merely to retry an uncertain result. ## Troubleshooting ## The wallet will not start For Coinbase on a headless Linux machine, use the [Linux appendix](https://docs.agentrouter.cc/wallets/coinbase-linux). Identify the error before installing packages or changing the sandbox. Keep the wallet's [first terminal running](https://docs.agentrouter.cc/wallets/coinbase-linux#linux-run) while issuing commands in the [second](https://docs.agentrouter.cc/wallets/coinbase-linux#linux-status). For MetaMask, check that the [CLI is on PATH](https://docs.agentrouter.cc/wallets/metamask#metamask-check) and that [authentication](https://docs.agentrouter.cc/wallets/metamask#metamask-auth) and [initialization](https://docs.agentrouter.cc/wallets/metamask#metamask-init) completed. Reopening a terminal does not preserve the PATH or helper-directory settings from an earlier shell. ## Coinbase reports NOT DEPLOYED Stop before purchase. The documented path requires an already-deployed smart account; use the [deployment check](https://docs.agentrouter.cc/wallets/coinbase#coinbase-deployed). There is no supported first-deployment procedure in this guide yet. An address receiving test tokens does not establish that the account is deployed. ## Test tokens appear to have no value In MetaMask, [inspect token amounts under Base Sepolia](https://docs.agentrouter.cc/wallets/metamask#metamask-balance). An unpriced token or a total dollar value of zero can reflect missing testnet pricing. Check the token's amount and network before funding again. ## Payment failed or the response is missing Keep the private response and error files. Do not repeat the pay command automatically: another invocation can create another purchase. A wallet balance change, receipt or transaction reference does not reveal a lost bearer key. The stock-client examples do not retain an optional recovery capability, so self-service lost-key recovery is unavailable for this flow. Do not pay again as a recovery attempt. ## The first inference did not return a useful answer A successful HTTP status alone does not prove a useful response. Follow the documented [model](https://docs.agentrouter.cc/use/models), output bound and non-streaming request in the [OpenAI-compatible](https://docs.agentrouter.cc/use/openai) or [Anthropic-compatible](https://docs.agentrouter.cc/use/anthropic) guide. Preserve the request identity and body when the outcome is uncertain; do not generate a new identity to bypass an uncertain charge. ## You opened another terminal Your wallet settings and bearer-key environment variable may no longer be present. Restore the wallet settings using its guide: [MetaMask sessions](https://docs.agentrouter.cc/wallets/metamask-reconnect) or [Coinbase](https://docs.agentrouter.cc/wallets/coinbase). Keep the original purchase response private and available; do not make another purchase just to restore a session. ## Sharing a problem Share the failing step, operating system, tool version and sanitized error. Never include a login code, QR URL, session credential, wallet private key, bearer key or unredacted purchase response. ## After reconnecting A new shell does not keep the [PATH](https://docs.agentrouter.cc/wallets/metamask#metamask-check) and [helper settings](https://docs.agentrouter.cc/wallets/metamask#metamask-helper) from setup. Restore them before using the wallet again, then check its status and balance. Keep the saved purchase response private; do not buy again just to restore a shell session. ```sh export PATH="$HOME/.local/share/h07-metamask/node_modules/.bin:$PATH" export METAMASK_SKILL_DIR="$HOME/.local/share/h07-metamask/agent-skills/skills/metamask-agent-wallet" ``` ### Expected result The existing CLI and helper are available again. Do not assume a previous bearer-key environment variable survived reconnecting.