@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 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
// 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, xPay 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.