@xona-labs/xpay

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/xpay

Quickstart

Create a profile, fund the addresses with a little USDC on Solana or Base, then discover and pay.

bash
$ 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.2s
bash@xona-labs/xpay
Back up your recovery phrase. init 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.

agent.ts
import { createXPay, loadProfile } from "@xona-labs/xpay"
const xpay = createXPay({
profile: await loadProfile({ passphrase }),
});
// pay any x402 endpoint, get the result
const video = await xpay.useByUrl(
"https://api.xona-agent.com/video/short-generation",
{ body: { prompt: "a cat astronaut" } }
);
typescript@xona-labs/xpay

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 payments

The MCP tool is xpay_report - agents can ask for a spending summary without any additional setup.

MCP server

Drop Xona Wallet 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
// 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"
json@xona-labs/xpay

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.

Smart network routing. When a service accepts more than one network, Xona Wallet pays from whichever wallet has the balance - a $0 Base wallet falls through to a funded Solana one. If none can cover the cost, the call fails fast with a clear per-network balance message instead of a raw error.

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 entry

The 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.

Biometrics gate the passphrase - they never replace it. Your passphrase keeps working everywhere and remains the only recovery path. If Touch ID is unavailable, the CLI falls back to asking for it. Bonus: with biometric unlock enabled, the MCP server no longer needs 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 overrides

One 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.