# Agentwallet

> Wallets for AI agents with x402 payment signing, referral rewards, and policy-controlled actions.

- Skill: `kbarbel640-del/agentwallet` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add kbarbel640-del/agentwallet`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kbarbel640-del/agentwallet/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: kbarbel640-del (https://skillmd.com/u/kbarbel640-del)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/kbarbel640-del/agentwallet

---


# AgentWallet

AgentWallet provides server wallets for AI agents. Wallets are provisioned after email OTP verification. All signing happens server-side and is policy-controlled.

---

## TL;DR - Quick Reference

**FIRST: Check if already connected** by reading `~/.agentwallet/config.json`. If file exists with `apiToken`, you're connected - DO NOT ask user for email.

**Need to connect (no config file)?** Ask user for email → POST to `/api/connect/start` → user enters OTP → POST to `/api/connect/complete` → save API token.

**x402 Payments?** Use the ONE-STEP `/x402/fetch` endpoint (recommended) - just send target URL + body, server handles everything.

---

## ⭐ x402/fetch - ONE-STEP PAYMENT PROXY (RECOMMENDED)

**This is the simplest way to call x402 APIs.** Send the target URL and body - the server handles 402 detection, payment signing, and retry automatically.

```bash
curl -s -X POST "https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/fetch" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://enrichx402.com/api/exa/search","method":"POST","body":{"query":"AI agents","numResults":3}}'
```

**That's it!** The response contains the final API result:

```json
{
  "success": true,
  "response": {
    "status": 200,
    "body": {"results": [...]},
    "contentType": "application/json"
  },
  "payment": {
    "chain": "eip155:8453",
    "amountFormatted": "0.01 USDC",
    "recipient": "0x..."
  },
  "paid": true,
  "attempts": 2,
  "duration": 1234
}
```

### x402/fetch Request Options

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `url` | string | ✅ | Target API URL (must be HTTPS in production) |
| `method` | string | ❌ | HTTP method: GET, POST, PUT, DELETE, PATCH (default: GET) |
| `body` | object | ❌ | Request body (auto-serialized to JSON) |
| `headers` | object | ❌ | Additional headers to send |
| `preferredChain` | string | ❌ | `"auto"` (default), `"evm"`, or `"solana"`. Auto selects chain with sufficient USDC balance |
| `dryRun` | boolean | ❌ | Preview payment cost without paying |
| `timeout` | number | ❌ | Request timeout in ms (default: 30000, max: 120000) |
| `idempotencyKey` | string | ❌ | For deduplication |

### Dry Run (Preview Cost)

Check how much an API call will cost without paying:

```bash
curl -s -X POST "https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/fetch" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://enrichx402.com/api/exa/search","method":"POST","body":{"query":"test"},"dryRun":true}'
```

Response:
```json
{
  "success": true,
  "dryRun": true,
  "payment": {
    "required": true,
    "chain": "eip155:8453",
    "amountFormatted": "0.01 USDC",
    "policyAllowed": true
  }
}
```

### Error Codes

| Code | HTTP | Description |
|------|------|-------------|
| `INVALID_URL` | 400 | URL malformed or blocked (localhost, internal IPs) |
| `POLICY_DENIED` | 403 | Policy check failed (amount too high, etc.) |
| `WALLET_FROZEN` | 403 | Wallet is frozen |
| `TARGET_TIMEOUT` | 504 | Target API timed out |
| `TARGET_ERROR` | 502 | Target API returned 5xx error |
| `PAYMENT_REJECTED` | 402 | Payment was rejected by target API |
| `NO_PAYMENT_OPTION` | 400 | No compatible payment network |

### Why Use x402/fetch?

- ✅ **One request** instead of 4-5 manual steps
- ✅ **No header parsing** - server extracts payment-required automatically
- ✅ **No escaping issues** - no multiline curl, no temp files
- ✅ **Automatic retry** - handles 402 → sign → retry flow
- ✅ **Policy enforced** - respects your spending limits
- ✅ **Proper error handling** - clear error codes

---

## ⚠️ x402 Payment - MANUAL FLOW (Legacy)

If you need fine-grained control, use the manual 4-step flow below. **For most cases, use x402/fetch above instead.**

### COPY THIS EXACT SCRIPT

**Only use this if you can't use x402/fetch. DO NOT improvise. DO NOT use multiline curl. Copy this script exactly:**

```bash
# === x402 PAYMENT SCRIPT - COPY EXACTLY ===
# Replace: API_URL, USERNAME, TOKEN, REQUEST_BODY

# Step 1: Get payment requirement (writes to temp file to avoid escaping issues)
curl -s -i -X POST "API_URL" -H "Content-Type: application/json" -d 'REQUEST_BODY' > /tmp/x402_response.txt

# Step 2: Extract the payment-required header
PAYMENT_REQ=$(grep -i "payment-required:" /tmp/x402_response.txt | cut -d' ' -f2 | tr -d '\r\n')

# Step 3: Sign with AgentWallet
# ENDPOINT: /api/wallets/USERNAME/actions/x402/pay (x402/pay with SLASH, not x402-sign with DASH)
# FIELD: Use "requirement" (not "paymentRequiredHeader")
curl -s -X POST "https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/pay" -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" -d "{\"requirement\":\"$PAYMENT_REQ\",\"preferredChain\":\"evm\"}" > /tmp/x402_signed.txt

# Step 4: Extract signature
PAYMENT_SIG=$(cat /tmp/x402_signed.txt | jq -r '.paymentSignature')

# Step 5: Make paid request (header is PAYMENT-SIGNATURE for v2)
curl -s -X POST "API_URL" -H "Content-Type: application/json" -H "PAYMENT-SIGNATURE: $PAYMENT_SIG" -d 'REQUEST_BODY'
```

**WRONG endpoints (will return 404/405):**
- ❌ `/api/x402/sign`
- ❌ `/api/x402-sign`
- ❌ `/api/wallets/{USERNAME}/actions/x402-sign` ← note the DASH is wrong
- ❌ `/api/sign`
- ❌ `/api/pay`

**CORRECT endpoint (note: x402/pay with SLASH not dash):**
- ✅ `https://agentwallet.mcpay.tech/api/wallets/{USERNAME}/actions/x402/pay`

**The path is:** `/api/wallets/` + `USERNAME` + `/actions/x402/pay`

**Common mistakes:**
- ❌ Using multiline curl with `\` → causes `blank argument` errors
- ❌ Checking response body for 402 → body is empty `{}`, check `payment-required` HEADER
- ❌ Using `X-PAYMENT` header → use `PAYMENT-SIGNATURE` for v2 APIs
- ❌ Reusing payment signatures → each signature is ONE-TIME USE
- ❌ Using `paymentRequiredHeader` field → use `requirement` instead (works with both base64 and JSON)

---

### Real Example: Calling enrichx402.com/api/exa/search

```bash
# Concrete example with real values (replace USERNAME and TOKEN)

# Step 1: Get 402 response
curl -s -i -X POST "https://enrichx402.com/api/exa/search" -H "Content-Type: application/json" -d '{"query":"AI agents","numResults":3}' > /tmp/x402_response.txt

# Step 2: Extract payment requirement
PAYMENT_REQ=$(grep -i "payment-required:" /tmp/x402_response.txt | cut -d' ' -f2 | tr -d '\r\n')

# Step 3: Sign (IMPORTANT: path is /actions/x402/pay NOT /actions/x402-sign)
curl -s -X POST "https://agentwallet.mcpay.tech/api/wallets/microchipgnu/actions/x402/pay" -H "Authorization: Bearer mf_YOUR_TOKEN_HERE" -H "Content-Type: application/json" -d "{\"requirement\":\"$PAYMENT_REQ\",\"preferredChain\":\"evm\"}" > /tmp/x402_signed.txt

# Step 4: Get signature
PAYMENT_SIG=$(cat /tmp/x402_signed.txt | jq -r '.paymentSignature')

# Step 5: Make paid request
curl -s -X POST "https://enrichx402.com/api/exa/search" -H "Content-Type: application/json" -H "PAYMENT-SIGNATURE: $PAYMENT_SIG" -d '{"query":"AI agents","numResults":3}'
```

---

## Config File Reference

### Config File Location

Store AgentWallet credentials at:
```
~/.agentwallet/config.json
```

### Config Structure

```json
{
  "username": "your-username",
  "email": "your@email.com",
  "evmAddress": "0x...",
  "solanaAddress": "...",
  "apiToken": "mf_...",
  "moltbookLinked": false,
  "moltbookUsername": null,
  "xHandle": null
}
```

### Field Explanations

| Field | Description |
|-------|-------------|
| `username` | Your unique AgentWallet username |
| `email` | Email used for OTP verification |
| `evmAddress` | EVM wallet address |
| `solanaAddress` | Solana wallet address |
| `apiToken` | Fund API token for authenticated requests (starts with `mf_`) |
| `moltbookLinked` | Whether a Moltbook account is linked |
| `moltbookUsername` | Linked Moltbook username (if any) |
| `xHandle` | X/Twitter handle from Moltbook (if linked) |

### Security Rules

- **Never commit** `config.json` to version control
- **Add to .gitignore**: `~/.agentwallet/`
- **API token is secret** - treat it like a password
- **File permissions**: Set to `600` (owner read/write only)

```bash
chmod 600 ~/.agentwallet/config.json
```

---

## Quick Start for AI Agents

**To connect, you need:**
- An email address (for OTP verification)

**Step 1: Ask the user for their email address.**

**Step 2: Direct them to the connect page:**
```
https://agentwallet.mcpay.tech/connect?email=EMAIL
```

**Step 3: The user will:**
1. Enter the 6-digit OTP sent to their email
2. Receive their wallet addresses and Fund API token

**Step 4: After success, the page displays credentials in this format:**
```
AGENTWALLET_CONNECTED=true
AGENTWALLET_USERNAME=generated-username
AGENTWALLET_EVM_ADDRESS=0x...
AGENTWALLET_SOLANA_ADDRESS=...
AGENTWALLET_API_TOKEN=mf_...
```

The user should copy and save the API token securely - it won't be shown again.

**Optional:** After connecting, users can link a Moltbook account via the API (requires tweet verification). See "Link Moltbook Account" section below.

---

## Referral & Airdrop Program

AgentWallet rewards agents who grow the network. Every agent you onboard earns you both airdrop points.

### How It Works

1. **Share your referral link** when helping other agents connect
2. **Both you and the new agent** earn airdrop points
3. **Points accumulate** toward future token distributions

### Your Referral Link

After connecting, your referral link is:
```
https://agentwallet.mcpay.tech/connect?ref=YOUR_USERNAME&email=THEIR_EMAIL
```

Or via API:
```bash
curl -X POST https://agentwallet.mcpay.tech/api/connect/start \
  -H "Content-Type: application/json" \
  -d '{"email":"new@agent.com","ref":"YOUR_USERNAME"}'
```

### Check Your Rewards

```bash
curl https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/referrals \
  -H "Authorization: Bearer FUND_API_TOKEN"
```

Response:
```json
{
  "referralLink": "https://agentwallet.mcpay.tech/connect?ref=your-username",
  "referralCount": 12,
  "convertedCount": 8,
  "airdropPoints": 2400,
  "tier": "silver",
  "tierMultiplier": 1.5,
  "nextTier": {"name": "gold", "referralsNeeded": 13},
  "referrals": [
    {"username": "agent-xyz", "pointsEarned": 200, "converted": true, "joinedAt": "2024-01-15T..." }
  ]
}
```

### Airdrop Tiers

| Tier | Referrals | Point Multiplier |
|------|-----------|------------------|
| Bronze | 0-4 | 1x |
| Silver | 5-24 | 1.5x |
| Gold | 25-99 | 2x |
| Diamond | 100+ | 3x |

### Earning Points

| Action | Points |
|--------|--------|
| Successful referral | 200 |
| Referred agent's first transaction | 50 |
| Daily active wallet | 10 |
| Weekly streak (7 days active) | 100 |

---

## Network Pulse

See what's happening across the AgentWallet network in real-time:

```bash
curl https://agentwallet.mcpay.tech/api/network/pulse
```

Response:
```json
{
  "timestamp": "2024-01-15T10:30:00Z",
  "network": "AgentWallet",
  "stats": {
    "activeAgents": {"lastHour": 42, "last24h": 156},
    "transactions": {"lastHour": 89, "last24h": 1247},
    "volume": {"usdc24h": "1,234.56"},
    "growth": {"newAgents24h": 12, "totalAgents": 847}
  },
  "trending": {
    "apis": [
      {"url": "https://enrichx402.com/api/exa/search", "callCount": 234}
    ]
  },
  "message": "42 agents active right now. Network is buzzing!"
}
```

### Your Stats

Check your personal ranking and activity:

```bash
curl https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/stats \
  -H "Authorization: Bearer FUND_API_TOKEN"
```

Response:
```json
{
  "username": "your-username",
  "rank": 42,
  "transactions": {"total": 156, "last24h": 12, "last7d": 67, "successRate": 98},
  "volume": {"usdc": "234.56"},
  "referrals": {"count": 5, "converted": 3, "airdropPoints": 1200, "tier": "silver"},
  "streakDays": 7,
  "joinedAt": "2024-01-01T..."
}
```

---

## CLI Connect (Get API Token)

Use this flow to get an API token. Works for new users AND existing users who need a new token.

### Step 1: Start (sends OTP to email)

```bash
curl -X POST https://agentwallet.mcpay.tech/api/connect/start \
  -H "Content-Type: application/json" \
  -d '{"email":"your@email.com"}'
```

Response:
```json
{
  "success": true,
  "username": "generated-username",
  "moltbookLinked": false,
  "message": "Enter the OTP sent to your email to complete connection.",
  "nextStep": "POST /api/connect/complete with {username, email, otp}",
  "hint": "You can link a Moltbook account later via POST /api/connect/link-moltbook (requires tweet verification)"
}
```

### Step 2: Ask user for OTP, then complete
Ask the user: **"Please enter the 6-digit code sent to your email."**

```bash
curl -X POST https://agentwallet.mcpay.tech/api/connect/complete \
  -H "Content-Type: application/json" \
  -d '{"username":"USERNAME_FROM_STEP_1","email":"your@email.com","otp":"USER_OTP"}'
```

Response (includes new API token):
```json
{
  "success": true,
  "connected": true,
  "username": "your-username",
  "moltbookLinked": false,
  "evmAddress": "0x...",
  "solanaAddress": "...",
  "apiToken": "mf_..."
}
```

Use the `apiToken` for all wallet operations.

---

## Skill Files

| File | URL |
|------|-----|
| **SKILL.md** (this file) | `https://agentwallet.mcpay.tech/skill.md` |
| **HEARTBEAT.md** | `https://agentwallet.mcpay.tech/heartbeat.md` |
| **package.json** (metadata) | `https://agentwallet.mcpay.tech/skill.json` |

### Heartbeat

Run the heartbeat periodically to check for skill updates, monitor wallet status, and review recent activity:

```bash
curl https://agentwallet.mcpay.tech/heartbeat.md
```

The heartbeat will guide you through checking balances, activity, and alerting the user if action is needed.

**Base URL:** `https://agentwallet.mcpay.tech/api/v1`

## Authentication

After connecting, you receive a **Fund API token** (starts with `mf_`). Use this token for all wallet operations:

```
Authorization: Bearer FUND_API_TOKEN
```

Do not log or share this token.

## Check Connection Status

Before starting onboarding, check if a user is already connected (public, no auth required):

```bash
curl https://agentwallet.mcpay.tech/api/wallets/USERNAME
```

**If connected:**
```json
{
  "connected": true,
  "username": "agent-name",
  "displayName": "Agent Name",
  "moltbookLinked": true,
  "moltbookUsername": "moltbook-name",
  "xHandle": "their_x_handle",
  "evmAddress": "0x...",
  "solanaAddress": "..."
}
```

Note: `moltbookLinked`, `moltbookUsername`, and `xHandle` are only present if the user linked a Moltbook account.

**If not connected:**
```json
{"connected": false, "error": "User not found"}
```

## Link Moltbook Account (Optional)

Users who registered with email-only can link their Moltbook account later. This requires tweet verification to prove ownership.

### Step 1: Start linking (get verification code)
```bash
curl -X POST https://agentwallet.mcpay.tech/api/connect/link-moltbook \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"moltbookUsername":"YOUR_MOLTBOOK_USERNAME"}'
```

Response:
```json
{
  "success": true,
  "step": "tweet_required",
  "moltbookUsername": "your-moltbook-username",
  "xHandle": "your_x_handle",
  "code": "A1B2C3D4",
  "tweetTemplate": "Linking my Moltbook account @your-moltbook-username to AgentWallet\n\nVerification: A1B2C3D4\n\n#AgentWallet",
  "tweetIntentUrl": "https://twitter.com/intent/tweet?text=...",
  "expiresIn": "30 minutes"
}
```

### Step 2: Post the tweet from the linked X account

The user must post the tweet from the X account linked to their Moltbook profile.

### Step 3: Verify and complete linking
```bash
curl -X POST https://agentwallet.mcpay.tech/api/connect/link-moltbook \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"moltbookUsername":"YOUR_MOLTBOOK_USERNAME","tweetUrl":"https://x.com/handle/status/123..."}'
```

Response:
```json
{
  "success": true,
  "message": "Moltbook account linked successfully",
  "moltbookLinked": true,
  "moltbookUsername": "your-moltbook-username",
  "xHandle": "your_x_handle"
}
```

---

## Funding Wallets (Coinbase Onramp)

AgentWallet wallets can be funded directly with fiat currency via **Coinbase Onramp** integration.

### Funding URL

Direct users to their wallet dashboard to add funds:

```
https://agentwallet.mcpay.tech/u/YOUR_USERNAME
```

### How It Works

1. User visits their wallet dashboard
2. Clicks the **"Fund"** link next to any wallet address
3. Coinbase Onramp modal opens with pre-configured options
4. User completes purchase via card, bank, or Coinbase account
5. Funds arrive in wallet (typically within minutes)

### Supported Funding Methods

| Method | Availability |
|--------|--------------|
| Credit/Debit Card | Worldwide |
| Bank Transfer (ACH) | US only |
| Coinbase Account | Coinbase users |

### Default Configuration

| Chain | Default Asset | Default Amount |
|-------|---------------|----------------|
| **EVM (Base)** | USDC | $10 |
| **Solana** | SOL | $10 equivalent |

### Supported Networks

**EVM Chains:**
- Base (chainId: 8453)
- Base Sepolia testnet (chainId: 84532)

**Solana:**
- Mainnet-beta
- Devnet

### For AI Agents

When a user needs to fund their wallet, instruct them to:

1. Visit `https://agentwallet.mcpay.tech/u/USERNAME`
2. Click "Fund" next to the wallet they want to fund
3. Complete the Coinbase checkout flow
4. Wait for funds to arrive (check balance via API)

**Check balance after funding:**
```bash
curl https://agentwallet.mcpay.tech/api/wallets/USERNAME/balances \
  -H "Authorization: Bearer FUND_API_TOKEN"
```

---

## Wallet Operations (Requires Fund API Token)

Get balances:
```bash
curl https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/balances \
  -H "Authorization: Bearer FUND_API_TOKEN"
```

## Activity

Get transaction history and wallet events:
```bash
curl https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/activity \
  -H "Authorization: Bearer FUND_API_TOKEN"
```

Optional query params:
- `limit`: Number of events to return (default: 50, max: 100)

Response includes:
```json
{
  "events": [
    {
      "id": "...",
      "occurredAt": "2024-01-15T10:30:00Z",
      "eventType": "wallet.action.confirmed",
      "status": "confirmed",
      "chainId": "8453",
      "assetSymbol": "USDC",
      "amount": "1000000",
      "decimals": 6,
      "txHash": "0x..."
    }
  ]
}
```

Event types:
- `otp.started`, `otp.verified`
- `policy.allowed`, `policy.denied`
- `wallet.action.requested`, `wallet.action.submitted`, `wallet.action.confirmed`, `wallet.action.failed`
- `x402.authorization.signed`

Public activity (no auth required):
```bash
curl https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/activity
```

Note: Without authentication, only public events are returned. With a valid token, the owner sees all events including private metadata.

## Actions (Policy Controlled)

### EVM Transfer
```bash
curl -X POST https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/actions/transfer \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"to":"0x...","value":"1000000","chainId":8453}'
```

| Field | Type | Description |
|-------|------|-------------|
| `to` | string | Recipient address |
| `value` | string | Amount in wei |
| `chainId` | number | Chain ID (8453 for Base) |
| `data` | string | Optional calldata |
| `idempotencyKey` | string | Optional deduplication key |

### Solana Transfer
```bash
curl -X POST https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/actions/transfer-solana \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"to":"RECIPIENT_ADDRESS","amount":"1000000000","asset":"sol","network":"devnet"}'
```

| Field | Type | Description |
|-------|------|-------------|
| `to` | string | Recipient Solana address (32-44 chars) |
| `amount` | string | Amount in smallest units (lamports for SOL, 6 decimals for USDC) |
| `asset` | string | `"sol"` or `"usdc"` (default: sol) |
| `network` | string | `"mainnet"` or `"devnet"` (default: mainnet) |
| `idempotencyKey` | string | Optional deduplication key |

**Amount Examples:**
- 1 SOL = `"1000000000"` (9 decimals)
- 0.1 SOL = `"100000000"`
- 1 USDC = `"1000000"` (6 decimals)
- 0.01 USDC = `"10000"`

**Response:**
```json
{
  "actionId": "...",
  "status": "confirmed",
  "txHash": "...",
  "explorer": "https://solscan.io/tx/...?cluster=devnet"
}
```

### EVM Contract Call
```bash
curl -X POST https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/actions/contract-call \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"to":"0x...","data":"0x...","value":"0","chainId":8453}'
```

### Sign Message
```bash
curl -X POST https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/actions/sign-message \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chain":"solana","message":"hello"}'
```

---

## x402 Payments (HTTP 402 Protocol)

x402 enables pay-per-request APIs. When a service returns HTTP 402, use AgentWallet to sign the payment authorization.

**⚠️ CRITICAL NOTES:**
1. **Signatures are ONE-TIME USE** - consumed even on failed requests. Verify params BEFORE signing.
2. **Empty `{}` body is normal** - HTTP 402 responses often have an empty body. The payment info is in the `payment-required` HEADER.
3. **Use single-line curl** - Multiline curl with `\` causes escaping errors. Keep commands on one line.
4. **Exact endpoint path** - Use `/api/wallets/{USERNAME}/actions/x402/pay` exactly. Do not guess other paths.

### x402 Protocol Versions

AgentWallet supports both x402 versions. The version is determined by the server's 402 response:

| Version | Network Format | Amount Field | Payment Header |
|---------|----------------|--------------|----------------|
| **v1** | Short names (`solana`, `base`) | `amount` or `maxAmountRequired` | `X-PAYMENT` |
| **v2** | CAIP-2 (`solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`) | `amount` | `PAYMENT-SIGNATURE` |

### Understanding Amounts

Amounts in x402 are in the token's smallest unit (like wei for ETH):
- **USDC has 6 decimals**, so `10000` = $0.01, `20000` = $0.02
- To calculate: divide by 1,000,000 to get USD value

### Complete x402 Flow

**Step 1: Call the paid API (get 402 response)**
```bash
curl -si "https://example.com/api/endpoint"
```

The 402 response contains payment requirements in one of two places:
- **Response body** (v1 style) - JSON object directly
- **`payment-required` header** (v2 style) - base64-encoded JSON string

**v1 example (in response body):**
```json
{"x402Version":1,"accepts":[{"scheme":"exact","network":"solana","amount":"10000","asset":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","payTo":"RECIPIENT","maxTimeoutSeconds":60}]}
```

**v2 example (in `payment-required` header, base64-encoded):**
```
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiYWNjZXB0cyI6W3sic2NoZW1lIjoiZXhhY3QiLC...
```

**Tip:** You do NOT need to base64-decode the header value. Pass it directly to AgentWallet - the API auto-detects and handles both formats.

**Step 2: Sign the payment with AgentWallet**

Pass the requirement exactly as received (JSON object OR base64 string):
```bash
curl -s -X POST "https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/pay" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"requirement": "eyJ4NDAyVmVyc2lvbiI6Mi...", "preferredChain": "evm"}'
```

**Full signing response:**
```json
{
  "authorizationId": "uuid-of-this-authorization",
  "paymentSignature": "eyJ4NDAyVmVyc2lvbiI6...",
  "expiresAt": "2026-02-02T08:41:32.000Z",
  "chain": "eip155:8453",
  "amountRaw": "10000",
  "recipient": "0x1E54dd08e5FD673d3F96080B35d973f0EB840353",
  "usage": {
    "header": "PAYMENT-SIGNATURE",
    "example": "curl -X POST API_URL -H \"PAYMENT-SIGNATURE: eyJ4NDAyVmVyc2lvbiI6...\""
  }
}
```

**Key fields:**
- `paymentSignature` - Use this value in your paid request
- `usage.header` - The header name to use (`X-PAYMENT` for v1, `PAYMENT-SIGNATURE` for v2)
- `expiresAt` - Signature expires after this time
- `amountRaw` - Amount in smallest units (divide by 1,000,000 for USDC dollars)

**IMPORTANT:** Use the header name from `usage.header` - it's `X-PAYMENT` for v1 or `PAYMENT-SIGNATURE` for v2. Using the wrong header will fail.

**Step 3: Retry the original request with the payment header**
```bash
# Use the header name from usage.header in the response
curl https://example.com/api/paid-endpoint \
  -H "<HEADER_NAME>: <paymentSignature>"
```

### Recommended Workflow

**Use `dryRun: true` to test without consuming a signature:**
```bash
curl -s -X POST 'https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/pay' -H 'Content-Type: application/json' -H 'Authorization: Bearer TOKEN' -d '{"requirement":REQUIREMENT,"preferredChain":"solana","dryRun":true}'
```

This returns full signing details without storing the authorization - useful for testing your request format.

### Single-Line Curl Pattern

Avoid multiline curl commands which cause escaping issues. Use single-line format:
```bash
# Step 1: Get payment signature (single line)
curl -s -X POST 'https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/pay' -H 'Content-Type: application/json' -H 'Authorization: Bearer TOKEN' -d '{"requirement":{"x402Version":1,"accepts":[...]},"preferredChain":"solana"}'

# Step 2: Use the signature (single line) - use jq to extract values
SIG=$(curl -s -X POST '...' | jq -r '.paymentSignature')
HEADER=$(curl -s -X POST '...' | jq -r '.usage.header')
curl -s 'https://api.example.com/endpoint?param=value' -H "$HEADER: $SIG"
```

### IMPORTANT: Avoid Multiline Curl Commands

Multiline curl commands with `\` often cause `curl: option : blank argument` errors due to escaping issues. **Always use single-line commands** or write to a script file if needed.

**Bad (causes errors):**
```bash
curl -X POST "https://example.com" \
  -H "Header: value" \
  -d '{"key": "value"}'
```

**Good (single line):**
```bash
curl -s -X POST "https://example.com" -H "Content-Type: application/json" -d '{"key":"value"}'
```

### Minimal Copy-Paste Pattern

This is the simplest working pattern for most x402 APIs (all single-line):

```bash
# 1. Get payment requirement from 402 header (single line!)
REQ=$(curl -si -X POST "https://api.example.com/endpoint" -H "Content-Type: application/json" -d '{"query":"test"}' | grep -i "payment-required:" | cut -d' ' -f2 | tr -d '\r')

# 2. Sign with AgentWallet (single line!)
RESP=$(curl -s -X POST "https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/pay" -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" -d "{\"requirement\":\"$REQ\",\"preferredChain\":\"evm\"}")

# 3. Extract signature
SIG=$(echo "$RESP" | jq -r '.paymentSignature')

# 4. Make paid request (single line!)
curl -s -X POST "https://api.example.com/endpoint" -H "Content-Type: application/json" -H "PAYMENT-SIGNATURE: $SIG" -d '{"query":"test"}'
```

### Complete Working Example (with dynamic header)

If multiline curl commands cause escaping errors, write to a script file:

```bash
# Write the paid request to a script file to avoid escaping issues
cat > /tmp/paid_request.sh << 'SCRIPT'
#!/bin/bash
curl -s -X POST "https://api.example.com/endpoint" -H "Content-Type: application/json" -H "PAYMENT-SIGNATURE: $1" -d '{"query":"test"}'
SCRIPT
chmod +x /tmp/paid_request.sh

# Then run it with the signature
/tmp/paid_request.sh "$SIG"
```

**Alternative: All-in-one single commands**
```bash
# Step 1: Get requirement
REQ=$(curl -si -X POST 'https://api.example.com/endpoint' -H 'Content-Type: application/json' -d '{}' | grep -i "payment-required:" | cut -d' ' -f2 | tr -d '\r')

# Step 2: Sign (note: use single quotes for JSON, escape inner quotes)
SIGN=$(curl -s -X POST 'https://agentwallet.mcpay.tech/api/wallets/USERNAME/actions/x402/pay' -H 'Content-Type: application/json' -H 'Authorization: Bearer TOKEN' -d '{"requirement":"'"$REQ"'","preferredChain":"evm"}')

# Step 3: Extract
SIG=$(echo "$SIGN" | jq -r '.paymentSignature')
HDR=$(echo "$SIGN" | jq -r '.usage.header')

# Step 4: Paid request
curl -s -X POST 'https://api.example.com/endpoint' -H 'Content-Type: application/json' -H "$HDR: $SIG" -d '{}'
```

### Common Errors and Solutions

| Error | Cause | Solution |
|-------|-------|----------|
| `404` or `405` on signing | Wrong endpoint path | Path is `/api/wallets/{USERNAME}/actions/x402/pay` (SLASH not dash: `x402/pay` NOT `x402-sign`) |
| `Missing payment requirement` | Wrong field name | Use `"requirement"` field, not `"paymentRequiredHeader"` |
| `curl: option : blank argument` | Multiline curl escaping | Use single-line curl or write to a shell script file |
| Empty `{}` response | Normal 402 behavior | Check `payment-required` header - body is intentionally empty |
| `AlreadyProcessed` | Reused signature | Get a NEW signature for each request |
| `insufficient_funds` | Wallet empty | Fund wallet at `https://agentwallet.mcpay.tech/u/USERNAME` |
| `No compatible payment option` | Network not supported | Check supported networks below |

### Decoding Error Responses

x402 errors are often base64-encoded in the `payment-required` header. To decode:
```bash
echo "eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJ2ZXJpZmljYXRpb24gZmFpbGVkOiBpbnN1ZmZpY2llbnRfZnVuZHMifQ==" | base64 -d
# Output: {"x402Version":2,"error":"verification failed: insufficient_funds"}
```

### Request Options

**IMPORTANT: Always use `requirement` field.** It accepts both base64 strings AND JSON objects.

| Field | Type | Description |
|-------|------|-------------|
| `requirement` | string or object | **USE THIS.** Pass the base64 string from `payment-required` header directly |
| `preferredChain` | `"evm"` \| `"solana"` | Preferred blockchain |
| `preferredChainId` | number | Specific EVM chain ID (e.g., 8453 for Base) |
| `idempotencyKey` | string | For deduplication (returns cached signature if same key) |
| `dryRun` | boolean | Sign but don't store (for testing/learning) |

**Do NOT use `paymentRequiredHeader`** - it's deprecated. Just use `requirement` for everything.

### Dry Run Mode (Testing/Learning)

Use `dryRun: true` to see detailed signing info without storing:

```bash
curl -X POST https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/actions/x402/pay \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requirement": {"x402Version":2,"accepts":[...]},
    "preferredChain": "solana",
    "dryRun": true
  }'
```

Dry run response includes:
- `paymentSignature` - The signed authorization
- `usage` - curl example showing how to use the header
- `payment` - Full details (chain, amount, recipient, token, expiry)
- `signedPayload` - Raw signed payload structure
- `wallet` - Which wallet signed

### How x402 Works

1. **Signing only** - AgentWallet signs an authorization but does NOT submit a transaction
2. **One-time use** - Each signature can only be used ONCE. The service settles on-chain on first use
3. **Service settles** - The paid service submits the transaction on-chain when you use the signature
4. **EVM** - Uses EIP-3009 `transferWithAuthorization` (gasless permit)
5. **Solana** - Uses a pre-signed SPL token transfer transaction

**Important:** Your wallet must have sufficient token balance (usually USDC) for the service to settle the payment.

### Supported Networks

| Network | CAIP-2 Identifier | Token |
|---------|-------------------|-------|
| Base Mainnet | `eip155:8453` | USDC |
| Base Sepolia | `eip155:84532` | USDC |
| Solana Mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | USDC |
| Solana Devnet | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | USDC |

---

## Policies

Get current policy:
```bash
curl https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/policy \
  -H "Authorization: Bearer FUND_API_TOKEN"
```

Update policy:
```bash
curl -X PATCH https://agentwallet.mcpay.tech/api/wallets/YOUR_USERNAME/policy \
  -H "Authorization: Bearer FUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"max_per_tx_usd":"25","allow_chains":["base","solana"],"allow_contracts":["0x..."]}'
```

## Response Format

Success:
```json
{"success": true, "data": {...}}
```

Error:
```json
{"success": false, "error": "Description", "hint": "How to fix"}
```

