npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

x402-wallet-mcp

v0.6.7

Published

Self-custodial USDC wallet + x402 payment signing as an MCP server for AI agents

Downloads

2,142

Readme


Give Claude Code, Cursor, or any MCP client its own wallet. It discovers x402 endpoints, signs USDC payments on Base, and handles the full HTTP 402 negotiation — so your AI agent can call paid APIs without human intervention.

You: "Get me the top Hacker News stories from the x402 API"
Claude: Using call_endpoint to pay $0.002 USDC...
       ✓ Payment signed (EIP-3009 TransferWithAuthorization)
       ✓ Got 10 stories from https://x402.onchainexpat.com/api/x402-tools/hackernews/top

Why This Exists

AI agents need to spend money. Today that means hardcoded API keys, credit cards on file, or manual approval for every request. The x402 protocol fixes this: servers return HTTP 402 with a price, clients sign a USDC payment, and the request goes through. No API keys. No subscriptions. Pay per call.

This project is the missing piece: an open-source MCP server that gives any AI agent a USDC wallet, spending controls, and the ability to pay for x402 APIs autonomously.

Features

  • Zero-config wallets — works out of the box with no API keys or signup required
  • Privy HSM-backed keys — keys never leave Privy's HSM/TEE infrastructure
  • Three wallet modes — Proxy (zero-config default), Linked (email-recoverable), or Privy direct (BYOK)
  • Email recovery — link your wallet to an email, recover it on any device via OTP
  • Full x402 negotiation — handles 402 → sign → retry automatically
  • EVM exact + escrow — EIP-3009 TransferWithAuthorization and ReceiveWithAuthorization
  • Endpoint discovery — fetches .well-known/x402 documents and searches x402scan.com
  • Spending controls — per-call maximum and daily cap with automatic enforcement
  • Transaction history — append-only log of every payment
  • Coinbase Onramp — buy USDC with a debit card or Apple Pay, no crypto experience needed
  • 13 MCP tools — everything an agent needs to discover, query, pay, and audit

Quick Start

No API keys or signup required. Just install and go:

Claude Code

claude mcp add x402-wallet -- npx x402-wallet-mcp

Cursor / Windsurf / Claude Desktop

Add to your MCP config file (.mcp.json, ~/.cursor/mcp.json, or Claude Desktop settings):

{
  "mcpServers": {
    "x402-wallet": {
      "command": "npx",
      "args": ["x402-wallet-mcp"]
    }
  }
}

On first run an HSM-backed wallet is automatically provisioned via the x402 provisioning service. Fund your wallet using the fund_wallet tool (generates a Coinbase Onramp link) or send USDC on Base directly to the wallet address.

Link Your Wallet to Email (Recommended)

After setup, use wallet_link to connect your wallet to an email address. This enables recovery on any device:

You: "Link my wallet to [email protected]"
Claude: Verification code sent! Enter the 6-digit code from your email.
You: "123456"
Claude: ✓ Wallet linked to [email protected]. You can recover this wallet on any device.

Recover on Another Device

You: "Recover my wallet using [email protected]"
Claude: ✓ Wallet recovered — same address, same balance.

If you have multiple wallets linked to the same email, you'll be shown each wallet's address and USDC balance so you can choose which one to load.

Your Keys Are Always Yours

No private key is ever stored on your machine. All keys live in Privy's HSM/TEE secure enclaves — hardware security modules that never expose raw key material.

Once you link your email with wallet_link, you can:

  • Export your private key at home.privy.io — log in with your email, verify via OTP, and click "Export keys"
  • Recover your wallet on any device using wallet_recover with the same email
  • Access your funds even if this package, the x402 provisioning service, or our website disappears entirely

This works for all wallet modes (proxy, linked, and BYOK). You do not need your own Privy credentials — the default setup is fully recoverable and exportable after linking your email.

Power Users: Bring Your Own Privy Credentials

For full control, sign up for a Privy account and pass your own credentials. This bypasses the proxy and talks directly to Privy:

claude mcp add x402-wallet \
  -e PRIVY_APP_ID=your-app-id \
  -e PRIVY_APP_SECRET=your-app-secret \
  -- npx x402-wallet-mcp

How It Works

┌──────────────┐     1. POST /api/data          ┌──────────────┐
│              │ ──────────────────────────────→  │              │
│   AI Agent   │     2. 402 + price: $0.002      │  x402 Server │
│  (via MCP)   │ ←──────────────────────────────  │              │
│              │     3. POST + X-PAYMENT header   │              │
│              │ ──────────────────────────────→  │              │
│              │     4. 200 + data                │              │
│              │ ←──────────────────────────────  │              │
└──────────────┘                                  └──────────────┘
       │                                                 │
       │ sign EIP-3009                                   │ verify signature
       │ TransferWithAuthorization                       │ settle USDC on Base
       ▼                                                 ▼
┌──────────────┐                                  ┌──────────────┐
│ x402-wallet  │                                  │   USDC on    │
│  (Privy HSM) │                                  │     Base     │
└──────────────┘                                  └──────────────┘
  1. The agent calls call_endpoint with a URL
  2. The server returns HTTP 402 with payment requirements (accepts array)
  3. x402-wallet-mcp picks the best payment option, checks spending limits, signs an EIP-3009 authorization
  4. Retries the request with the signed payment in the X-PAYMENT header
  5. Returns the API response to the agent and logs the transaction

MCP Tools

The server exposes 13 tools that any MCP client can call:

| Tool | Description | Key Parameters | |------|-------------|----------------| | call_endpoint | Make a paid API call (handles full 402 flow) | url, method?, body?, headers?, prefer_escrow? | | query_endpoint | Probe pricing without paying | url, method? | | discover_endpoints | Search for available x402 APIs | query?, source? | | check_balance | USDC balance on Base + deposit address | — | | wallet_info | Wallet mode, addresses, recovery status | — | | fund_wallet | Buy USDC via Coinbase Onramp (debit card / Apple Pay) | amount? | | transaction_history | Recent payment log | limit? | | configure_spending | Set per-call max and daily cap | per_call_max?, daily_cap? | | add_endpoint_source | Register a .well-known/x402 source | base_url?, endpoint_url? | | manage_allowlist | Add/remove merchant allowlist entries | allow?, remove?, mode? | | wallet_link | Link wallet to email for recovery | email?, session_token?, code? | | wallet_recover | Recover a linked wallet on any device | email?, session_token?, code?, wallet_id? | | export_key | Instructions for exporting private key via Privy | — |

Example: Paid API Call

When an agent calls call_endpoint:

{
  "url": "https://x402.onchainexpat.com/api/x402-tools/hackernews/top",
  "method": "POST",
  "body": "{\"num_stories\": 5}"
}

The tool returns:

{
  "success": true,
  "status": 200,
  "amountPaid": "$0.01",
  "scheme": "exact",
  "network": "eip155:8453",
  "data": {
    "stories": ["..."]
  }
}

Spending Controls

Built-in safeguards prevent runaway spending:

| Control | Default | Override Env Var | |---------|---------|------------------| | Per-call maximum | $5.00 USDC | X402_PER_CALL_MAX | | Daily cap | $50.00 USDC | X402_DAILY_CAP |

The daily cap resets at midnight UTC. Both limits can also be changed at runtime using the configure_spending tool.

If a payment would exceed either limit, the tool returns an error explaining why — the agent can then ask the user for approval or skip the call.

Payment Schemes

Exact (EIP-3009 TransferWithAuthorization)

The default and most common scheme. Signs a one-time USDC transfer authorization:

  • Domain: USDC contract on Base (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913)
  • Type: TransferWithAuthorization(from, to, value, validAfter, validBefore, nonce)
  • Expiry: Configurable via maxTimeoutSeconds (default 60s)
  • Nonce: Random 32 bytes (one-time use)

Escrow (EIP-3009 ReceiveWithAuthorization)

For endpoints that use the x402r escrow middleware. Funds are held in escrow and settled after the API response:

  • Type: ReceiveWithAuthorization(from, to, value, validAfter, validBefore, nonce)
  • to: Token collector contract (not the final recipient)
  • Nonce: Deterministic — computed from keccak256(chainId, escrowAddress, paymentInfoHash)
  • Expiry: validAfter=0, validBefore=MAX_UINT48

The tool auto-detects which scheme to use based on the server's accepts array. By default it prefers exact; pass prefer_escrow: true to prefer escrow when both are available.

Configuration

Environment Variables

| Variable | Purpose | Required | |----------|---------|----------| | PRIVY_APP_ID | Privy application ID (enables direct Privy mode) | No | | PRIVY_APP_SECRET | Privy application secret | No | | X402_PROXY_URL | Custom proxy URL (default: https://x402.onchainexpat.com/api/wallet) | No | | X402_PER_CALL_MAX | Max USDC per API call (e.g. "10.00") | No | | X402_DAILY_CAP | Max USDC per day (e.g. "100.00") | No | | X402_RPC_URL | Custom Base RPC endpoint | No | | X402_SKIP_LINKING | Skip email link prompt on first run | No |

No environment variables are required. The wallet works zero-config out of the box, including Coinbase Onramp for buying USDC.

Wallet mode priority: If PRIVY_APP_ID and PRIVY_APP_SECRET are set, the wallet connects directly to Privy. Otherwise, it uses the hosted proxy for zero-config operation.

Data Directory

All persistent data is stored in ~/.x402-wallet/:

~/.x402-wallet/
├── config.json          # Settings, wallet ID, endpoint sources
├── history.jsonl        # Transaction log (append-only)
├── spending.json        # Daily spending tracker
└── endpoints-cache.json # Discovery cache (1hr TTL)

Default Configuration

{
  "version": 2,
  "wallet": { "mode": "proxy" },
  "spending": { "perCallMaxUsdc": "5.00", "dailyCapUsdc": "50.00" },
  "endpointSources": [
    "https://x402.onchainexpat.com",
    "https://padelmaps.org",
    "https://stableenrich.dev",
    "https://stablestudio.dev",
    "https://x402.twit.sh"
  ],
  "preferences": { "preferEscrow": false, "preferredNetwork": "evm" }
}

Note: The default mode is "proxy" (zero-config). Use wallet_link to upgrade to "linked" mode with email recovery and key export. When PRIVY_APP_ID and PRIVY_APP_SECRET env vars are set, the wallet automatically switches to "privy" mode.

Architecture

x402-wallet-mcp/
├── bin/
│   └── x402-wallet-mcp.ts          # CLI entry point
├── src/
│   ├── index.ts                     # Main: wallet + MCP server + stdio
│   ├── server.ts                    # McpServer with 13 tools
│   ├── wallet/
│   │   ├── types.ts                 # WalletProvider interface
│   │   ├── factory.ts               # Wallet creation (proxy/linked/privy)
│   │   ├── proxy-wallet.ts          # Zero-config wallet via hosted proxy
│   │   ├── proxy-api.ts             # REST client for proxy service
│   │   ├── privy-wallet.ts          # Direct Privy server wallets (HSM/TEE)
│   │   ├── privy-api.ts             # REST client for Privy API
│   │   ├── link-api.ts              # Email linking & recovery API client
│   │   └── null-wallet.ts           # Placeholder for unconfigured state
│   ├── payment/
│   │   ├── evm-exact.ts             # EIP-3009 TransferWithAuthorization
│   │   ├── evm-escrow.ts            # ReceiveWithAuthorization + nonce
│   │   ├── negotiator.ts            # 402 → sign → retry orchestrator
│   │   ├── types.ts                 # AcceptEntry, PaymentRequired, etc.
│   │   └── constants.ts             # USDC addresses, chain IDs
│   ├── discovery/
│   │   ├── well-known.ts            # Fetch .well-known/x402
│   │   ├── x402scan.ts              # Query x402scan.com
│   │   └── registry.ts              # Merge + deduplicate + cache
│   ├── spending/
│   │   ├── tracker.ts               # Per-call + daily cap enforcement
│   │   ├── allowlist.ts             # Merchant allowlist validation
│   │   └── store.ts                 # Persist daily spend totals
│   ├── tools/                       # 13 MCP tool implementations
│   ├── store/
│   │   ├── config.ts                # ~/.x402-wallet/config.json
│   │   ├── history.ts               # Append-only JSONL transaction log
│   │   └── paths.ts                 # Cross-platform path resolution
│   └── utils/
│       ├── logger.ts                # stderr-only (stdout = MCP JSON-RPC)
│       ├── http.ts                  # Fetch with timeout + retries
│       ├── format.ts                # USDC atomic ↔ human-readable
│       ├── deposit-qr.ts            # QR code generation for deposits
│       └── onramp.ts                # Coinbase Onramp URL generation
└── tests/
    ├── unit/                        # 127 tests across 16 files
    ├── integration/                 # Live endpoint tests (costs real USDC)
    └── e2e/                         # Full MCP server over stdio

Development

Prerequisites

  • Node.js >= 18
  • npm

Setup

git clone https://github.com/onchainexpat/x402-wallet-mcp.git
cd x402-wallet-mcp
npm install

Build

npm run build       # TypeScript → dist/
npm run lint        # Type-check without emitting

Run in Development

npm run dev         # Run with tsx (auto-reloads)

Testing

# Unit tests (127 tests, no network calls, no USDC spent)
npm test

# Watch mode
npm run test:watch

# Integration tests (hits real x402 endpoints, costs real USDC)
# Requires a funded wallet
RUN_LIVE_TESTS=1 npm run test:live

# E2E tests (spawns MCP server over stdio, calls all 13 tools)
RUN_E2E_TESTS=1 npx vitest run tests/e2e

The unit test suite covers:

  • Wallet: Proxy + Privy + Linked API mocking, factory routing, email linking/recovery
  • Payment: EIP-3009 exact/escrow signing, escrow nonce determinism, full negotiator flow (402 → sign → retry), edge cases (double-402, empty accepts, spending limits)
  • Spending: per-call max, daily cap, midnight reset, env var overrides, merchant allowlist
  • Discovery: endpoint merging, deduplication, cache behavior, fetch failure handling
  • Store: config defaults/persistence, history append/query, USDC formatting, Coinbase onramp URLs

Local Testing with an MCP Client

# Build and run
npm run build
node dist/bin/x402-wallet-mcp.js

# Or use npx to test the published package experience
npx .

The server communicates over stdio (JSON-RPC), so you need an MCP client to interact with it. The easiest way is to add it to Claude Code's config and test through the chat.

Terminology

| Term | Definition | |------|------------| | x402 | Protocol for HTTP 402 payments — servers price API calls, clients pay with crypto | | MCP | Model Context Protocol — standard for AI tool servers | | EIP-3009 | Ethereum standard for gasless USDC transfers via signed authorizations | | Base | Coinbase's L2 network where USDC payments settle | | Exact | Direct payment scheme — USDC transfers immediately to the server | | Escrow | Protected payment scheme — funds held in smart contract, settled after API response |

Security Considerations

[!IMPORTANT] This software manages real cryptocurrency. Review the security policy before using in production.

  • No keys on your machine: Private keys are never stored locally — not in plaintext, not encrypted, not anywhere on disk. All keys live in Privy's HSM/TEE secure enclaves.
  • Survivable: If this package, the x402 provisioning service, or our website disappears, go to home.privy.io, log in with your linked email, and export your private key. Your funds are always accessible.
  • HSM-backed signing: Whether using proxy or direct Privy mode, keys never leave Privy's hardware security modules.
  • Proxy signing validation: The hosted proxy validates every signing request — only USDC transfers on Base, capped at 100 USDC per transaction.
  • Spending limits: Enforced locally before signing. Cannot be bypassed by the AI agent.
  • No stdout leaks: All logging goes to stderr. stdout is reserved for MCP JSON-RPC. Private keys never appear in logs.
  • Email recovery: OTP-verified, rate-limited, HMAC-derived codes with 10-minute expiry.

Roadmap

  • [ ] Multi-chain support (Ethereum mainnet, Arbitrum, Optimism)
  • [ ] Payment receipts and on-chain verification
  • [ ] Webhook notifications for payments
  • [ ] Rate limiting and circuit breaker patterns
  • [ ] Dashboard UI for spending analytics

Contributing

Contributions are welcome. See CONTRIBUTING.md for guidelines.

Before submitting a PR:

  1. Run npm test and ensure all 127 tests pass
  2. Run npm run lint for type checking
  3. Add tests for new functionality
  4. Keep PRs focused — one feature or fix per PR

Related Projects

  • x402 — The x402 protocol specification by Coinbase
  • MCP — Model Context Protocol by Anthropic
  • viem — TypeScript library for Ethereum (used for signing)
  • x402scan.com — Directory of x402-enabled endpoints

License

MIT