Documentation
The agentic-commerce wallet — multi-network USDC, x402 payments, and discovery across 21,000+ services. Ships as a CLI, an SDK, and an MCP server.
Install
The CLI and MCP server install globally; the SDK installs into a project. They share the same core, so you can mix them.
# CLI + MCP server, system-wide
npm install -g @xona-labs/xpay
# SDK, in a project
npm install @xona-labs/xpayQuickstart
Create a profile, fund the addresses with a little USDC on Solana or Base, then discover and pay.
$ npm install -g @xona-labs/xpay $ xpay init✔ Solana 7RB7frd…6qkpf5ph✔ EVM 0xA5D9…1023dfa $ xpay discover "short video" $0.5000 solana api.xona-agent.com $ xpay pay api.xona-agent.com/video/…✔ Paid $0.5000 on solana · 1.2sinit prints a 24-word seed once and encrypts your keys with a passphrase. There is no way to recover it if you lose it.CLI commands
xpay init [name]Create a profile — Solana + EVM from one seed. --import, --no-encrypt, --workspace.xpay accountslist · show · use — manage and switch profiles.xpay balanceUSDC balance per network for the active profile.xpay discover [query]Search 21k+ x402 services. --network, --limit, --json.xpay pay <url>Pay an x402 endpoint (catalog or live 402). --max-usd, --body, -y.xpay transfer <amt> USDC <to>Direct USDC transfer, subject to the guardrail. --network, -y.xpay reportComprehensive USDC report (daily / weekly / monthly) — totals, net flow, timeline, top counterparties. --period, --network, --json.xpay guardrailshow · set · clear — manage spending caps and allowed hosts.xpay biometricstatus · enable · disable — Touch ID unlock for the wallet passphrase (macOS).xpay mcpStart the MCP server on stdio.SDK
The CLI is a thin shell over the SDK — every command has a programmatic equivalent. One entry point, fully typed.
import { createXPay, loadProfile } from "@xona-labs/xpay" const xpay = createXPay({ profile: await loadProfile({ passphrase }),}); // pay any x402 endpoint, get the resultconst video = await xpay.useByUrl( "https://api.xona-agent.com/video/short-generation", { body: { prompt: "a cat astronaut" } });Other surface you’ll use often:
await xpay.discover({ query: "weather" });
await xpay.do("translate this PDF to Japanese");
await xpay.transfer({ amount: 1, to, token: "USDC" });
await xpay.report({ period: "weekly" }); // daily | weekly | monthly
await xpay.wallet.balance("solana");Agent runtimes get first-class tool definitions: forClaude(xpay), forOpenAI(xpay), and forGemini(xpay) — same handlers, vendor-shaped schemas.
Activity reports
xpay report replaces the old direct-RPC history command. On-chain data is fetched server-side by OrbitX402 — no RPC URL, no rate-limiting, no 429 errors on your end.
# CLI
xpay report # weekly (default)
xpay report --period daily
xpay report --period monthly --json
# SDK
const report = await xpay.report({ period: "weekly" });
// report.summary → { totalSent, totalReceived, netFlow, txCount }
// report.timeline → daily buckets with sent / received / txCount
// report.topCounterparties → sorted by volume
// report.topTransactions → biggest individual paymentsThe MCP tool is xpay_report — agents can ask for a spending summary without any additional setup.
MCP server
Drop xPay into any MCP host — Claude Desktop, Cursor, Codex — with no code and no keys. On first run the agent is given its own wallet; the address is printed to the server log, so fund it with USDC and the agent can pay. The wallet persists, so the address stays stable across restarts.
// claude_desktop_config.json — no keys, no setup{ "mcpServers": { "xpay": { "command": "npx", "args": ["-y", "@xona-labs/xpay", "mcp"] } }} // first run → the agent gets its own wallet; fund the printed address› "pay api.xona-agent.com to make a short video"Already have a wallet? Set XPAY_SOLANA_SECRET in the config’s env, or point at an xpay init profile with XPAY_PROFILE + XPAY_PASSPHRASE — either takes precedence over the generated wallet.
The host then exposes seven tools: xpay_discover, xpay_use, xpay_do, xpay_transfer, xpay_balance, xpay_report, xpay_guardrail.
Guardrails
Guardrails run before any signer is touched, so a misbehaving agent can’t bypass them. Amount caps apply to both paid calls and transfers; allowed hosts apply only to x402 calls.
xpay guardrail set \
--max-per-tx 0.5 \
--max-per-day 5 \
--require-approval-above 1 \
--allowed-hosts 'api.payai.network,*.xona.xyz'Calls at or above requireApprovalAbove need explicit approval: a Touch ID prompt when biometric unlock is enabled, otherwise a y/n confirm in the terminal. In the MCP server it is Touch ID only — an agent's large payment surfaces as a system dialog you physically approve. In the SDK, wire the onApprovalRequired hook to whatever you like: push notification, biometric prompt, or webhook.
Caps stop overspending, but they can't tell a legitimate payment from a prompt-injected one. For that, enable the optional Bento intent firewall — every payment is screened for malicious intent (prompt-injection, wallet-drain) before signing. Turn it on with xpay bento enable.
Biometric unlock (macOS)
Skip typing the passphrase on every command — unlock with Touch ID instead.
xpay biometric enable # verifies your passphrase, then stores it Touch ID-gated
xpay balance # → Touch ID prompt instead of a passphrase prompt
xpay biometric status # availability + current state
xpay biometric disable # removes the keychain entryThe wallet's scrypt + AES-256-GCM encryption is unchanged. enable places the passphrase in your login keychain, and a small native helper releases it only after a LocalAuthentication check (compiled on first use; requires the Xcode Command Line Tools). Unlock order: --passphrase → $XPAY_PASSPHRASE → Touch ID → interactive prompt.
XPAY_PASSPHRASE in plaintext host config — it shows one Touch ID dialog at startup.Profiles
Each profile is a directory under ~/.xpay/:
~/.xpay/
└── default/
├── wallet.json # BIP-39 seed, AES-256-GCM encrypted
└── config.json # networks, guardrail, RPC overridesOne mnemonic derives Solana (m/44'/501', Phantom-compatible) and EVM (m/44'/60', MetaMask-compatible). Override the root with XPAY_HOME, or use xpay init --workspace for project-local profiles.