# AgentRouter — Coinbase > Base Sepolia testnet. Wallet setup and spending require the owner's authorization. Follow one wallet path. Set up Coinbase Agentic Wallet with email, add test funds and use an existing deployed smart account to buy inference. [Human guide](https://docs.agentrouter.cc/wallets/coinbase) · [Pricing](https://agentrouter.cc/pricing#agents) · [Documentation index](https://docs.agentrouter.cc/llms.txt) ## Start the wallet You need Node.js 24+ with npm, an email address and a terminal. The complete guide also uses Python 3, curl, jq and uuidgen. Install missing tools first. A Coinbase exchange account is not required. Coinbase manages the signing key on its backend in secure enclaves. Signing and wallet access depend on Coinbase's service. Local login/session credentials are sensitive; the Linux application directory is not a private-key backup. [Coinbase key storage](https://www.coinbase.com/developer-platform/products/agentic-wallets) ```sh npx awal@2.12.2 status ``` ### Expected result Accept the package installation prompt if shown. The wallet server reports **Running**. For startup problems on a headless Linux host, use the [Linux appendix](https://docs.agentrouter.cc/wallets/coinbase-linux). ## Sign in by email Replace `YOUR_EMAIL` with your email address in your own terminal. ```sh npx awal@2.12.2 auth login 'YOUR_EMAIL' ``` ### Expected result A verification code is sent to your email. Keep it private. ## Verify your email Replace `YOUR_CODE` with the six-digit code from your email. Enter it only in your own terminal, never in an agent conversation. ```sh npx awal@2.12.2 auth verify YOUR_CODE npx awal@2.12.2 status ``` ### Expected result Status reports **Authenticated**. ## Get your address Read your wallet's EVM address. Use this same address when [funding](https://docs.agentrouter.cc/wallets/coinbase#coinbase-fund). ```sh npx awal@2.12.2 address ``` ### Expected result Copy the **EVM address**, not a session credential. ## Get test USDC Open the [Circle faucet](https://faucet.circle.com/), select **USDC** and **Base Sepolia**, paste [your EVM address](https://docs.agentrouter.cc/wallets/coinbase#coinbase-address), and choose **Send 20 USDC**. Wait for confirmation. You can also transfer Base Sepolia test USDC from an existing wallet. If Circle is unavailable, use the [Coinbase CDP faucet](https://docs.cdp.coinbase.com/faucets/introduction/quickstart#ui-cdp-portal): sign in to a CDP developer account, open **Faucets**, choose **Base Sepolia** and **USDC**, enter the address and choose **Claim**. The CDP account is separate from the wallet's email login. Do not buy or send real funds for this setup. ### Expected result The faucet confirms the transfer. [Verify the balance](https://docs.agentrouter.cc/wallets/coinbase#coinbase-balance) in the next step. ## Check your balance Read the USDC balance under **Base Sepolia**. ```sh npx awal@2.12.2 balance --chain base-sepolia ``` ### Expected result Have at least **1.00 test USDC** for the documented offer. Always [inspect the actual offer](https://docs.agentrouter.cc/wallets/coinbase#01-quote) before paying. ## Check account deployment **An already-deployed smart account is required by this purchase path.** This check reads public contract data; it does not deploy the account or make a payment. If it reports **NOT DEPLOYED**, stop before purchase. A supported first-deployment procedure is not yet included here. Funding the address alone is not proof of deployment. ```sh H07_WALLET="$(npx --no-install awal@2.12.2 address --chain base-sepolia)" && curl -fsS https://sepolia.base.org \ -H 'Content-Type: application/json' \ --data "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getCode\",\"params\":[\"$H07_WALLET\",\"latest\"]}" | python3 -c 'import json,sys; c=json.load(sys.stdin).get("result"); print("DEPLOYED" if isinstance(c,str) and c.startswith("0x") and len(c)>2 else "NOT DEPLOYED" if c=="0x" else "CHECK FAILED")' ``` ### Expected result Continue only on **DEPLOYED**. Stop on **NOT DEPLOYED**, **CHECK FAILED**, or an error. ## Optional test ETH The documented USDC x402 flow has the facilitator pay settlement gas. A zero-ETH purchase was not independently tested in the supplied Coinbase walkthrough, so its successful purchase does not prove that case. Only if another transaction requires unsponsored gas, obtain **Base Sepolia test ETH** from the [Coinbase faucet](https://docs.agentrouter.cc/wallets/coinbase#coinbase-fund) by choosing **ETH**, or transfer it from another wallet. The [Pinky Base Sepolia faucet](https://pinky.ishow.biz.id/base) is another supplied option: enter the same public EVM address, complete its human check and request testnet ETH. Never provide a seed phrase or private key to a faucet. [Who pays x402 gas](https://docs.cdp.coinbase.com/x402/support/faq). ### Expected result Keep both assets on Base Sepolia. ETH funding is not a substitute for the [smart-account deployment check](https://docs.agentrouter.cc/wallets/coinbase#coinbase-deployed). ## 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 Coinbase `awal@2.12.2` and a deployed smart account. Complete [Coinbase setup](https://docs.cdp.coinbase.com/agentic-wallet/cli/quickstart) and fund Base Sepolia USDC first. Headless Linux needs a working wallet server/display; stop if `status` cannot reach it. An undeployed smart account is not this tested path. Expect a running, authenticated wallet and the Base Sepolia balance. ```sh npx awal@2.12.2 status npx awal@2.12.2 balance --chain base-sepolia npx awal@2.12.2 x402 details https://api.agentrouter.cc/v1/purchase --json ``` ### 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. Coinbase caps this purchase at 1 test USDC. Expect the API response body in `data`. ```sh umask 077 PURCHASE_DIR="$(mktemp -d "$HOME/agentrouter-purchase.XXXXXX")" && npx --no-install awal@2.12.2 x402 pay \ https://api.agentrouter.cc/v1/purchase \ -X POST --max-amount 1000000 --json \ >"$PURCHASE_DIR/result.json" 2>"$PURCHASE_DIR/error.log" && AGENTROUTER_KEY="$(jq -er '.data.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. ## Diagnose startup Use this appendix only if [normal Coinbase startup](https://docs.agentrouter.cc/wallets/coinbase#coinbase-start) fails on a Linux server without a graphical session. Although awal is a CLI, it starts an Electron application that needs a display and a working sandbox. Run as your normal user, without sudo. Inspect the error before reinstalling packages. ```sh wallet_dir="${XDG_DATA_HOME:-$HOME/.local/share}/awal-nodejs/server" STARTED_BY_CLI=true WALLET_STANDALONE=true \ "$wallet_dir/node_modules/.bin/electron" "$wallet_dir/bundle-electron.js" ``` ### Expected result Identify a [missing display](https://docs.agentrouter.cc/wallets/coinbase-linux#linux-display) or an [AppArmor user-namespace denial](https://docs.agentrouter.cc/wallets/coinbase-linux#linux-denial) before applying the corresponding remedy. Other errors need their own diagnosis. ## Supply a virtual display If the host has no display, install Xvfb and xauth once. Xvfb supplies an invisible display; a physical GPU is not required. ```sh sudo apt-get update && sudo apt-get install --no-install-recommends xvfb xauth ``` ### Expected result The packages install successfully. Stop on an installation error. ## Check AppArmor Apply an AppArmor exception only after confirming an Electron user-namespace denial. Ask your administrator if you do not manage the host. ```sh sudo journalctl -k -b --no-pager \ --grep='apparmor="DENIED".*(userns|electron)' -n 20 ``` ### Expected result Look for a matching AppArmor denial. Do not add an exception solely because the wallet failed to start. ## Permit the wallet sandbox An administrator can add a profile for the exact Electron executable. This grants user-namespace access to code run through that binary; it is not a full confinement policy. If a profile already exists, ask the administrator to review it rather than add another. Otherwise run this as the wallet user; sudo only writes and loads the system profile. Keep Electron's sandbox enabled. ```sh wallet_dir="${XDG_DATA_HOME:-$HOME/.local/share}/awal-nodejs/server" wallet_electron="$wallet_dir/node_modules/electron/dist/electron" if [ -x "$wallet_electron" ]; then sudo sh -c 'set -C; cat > /etc/apparmor.d/awal-wallet-electron' <, profile awal-wallet-electron "$wallet_electron" flags=(default_allow) { userns, } EOF sudo apparmor_parser -a /etc/apparmor.d/awal-wallet-electron else printf 'Wallet Electron executable not found: %s\n' "$wallet_electron" >&2 fi ``` ### Expected result Successful loading is normally silent. Stop on errors. To remove this exception later, stop the wallet, unload the profile with `sudo apparmor_parser -R /etc/apparmor.d/awal-wallet-electron`, then have the administrator remove that file. ## Keep Terminal 1 running Run without sudo and leave Terminal 1 open while using the wallet. This starts no permanent service and does not configure startup after reboot. ```sh wallet_dir="${XDG_DATA_HOME:-$HOME/.local/share}/awal-nodejs/server" xvfb-run -a -s '-screen 0 1280x720x24 -nolisten tcp' \ env STARTED_BY_CLI=true WALLET_STANDALONE=true \ "$wallet_dir/node_modules/.bin/electron" "$wallet_dir/bundle-electron.js" ``` ### Expected result The wallet application stays running. A GPU-process message alone is not proof of failure; [verify CLI status from Terminal 2](https://docs.agentrouter.cc/wallets/coinbase-linux#linux-status). ## Continue in Terminal 2 Open another terminal on the **same host as the same user**. Use Terminal 2 for [login](https://docs.agentrouter.cc/wallets/coinbase#coinbase-login), [funding](https://docs.agentrouter.cc/wallets/coinbase#coinbase-fund) and [purchase](https://docs.agentrouter.cc/wallets/coinbase#03-settle) while [Terminal 1](https://docs.agentrouter.cc/wallets/coinbase-linux#linux-run) remains running. [Electron on headless systems](https://www.electronjs.org/docs/latest/tutorial/testing-on-headless-ci) · [Ubuntu user-namespace profiles](https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces) ```sh npx awal@2.12.2 status ``` ### Expected result Status reports **Running**. Return to [email sign-in](https://docs.agentrouter.cc/wallets/coinbase#coinbase-login). If startup exits or status fails, [inspect the startup error](https://docs.agentrouter.cc/wallets/coinbase-linux#linux-diagnose) before continuing.