Wallets for AI agents with x402 payment signing, referral rewards, and policy-controlled actions.
Scanned 5/30/2026
Install via CLI
openskills install Demerzels-lab/elsamultiskillagent---
name: agentwallet
version: 0.1.8
description: Wallets for AI agents with x402 payment signing, referral rewards, and policy-controlled actions.
homepage: https://agentwallet.mcpay.tech
metadata: {"moltbot":{"category":"finance","api_base":"https://agentwallet.mcpay.tech/api"},"x402":{"supported":true,"chains":["solana","evm"],"networks":["solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","eip155:8453","eip155:84532"],"tokens":["USDC"],"endpoint":"/api/wallets/{username}/actions/x402/fetch","legacyEndpoint":"/api/wallets/{username}/actions/x402/pay"},"referrals":{"enabled":true,"endpoint":"/api/wallets/{username}/referrals"}}
---
# 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"}
```
No comments yet. Be the first to comment!