Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions skills/onchainexpat/x402/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
---
name: x402
description: Pay for x402 APIs autonomously with USDC. Discover endpoints via Bazaar, execute payments, access paid services.
metadata: {"clawdbot":{"emoji":"💸","homepage":"https://x402.org","requires":{"env":["X402_PRIVATE_KEY"]},"primaryEnv":"X402_PRIVATE_KEY","install":[{"id":"npm","kind":"node","package":"@civic/x402-mcp","bins":["npx"],"label":"Install x402-mcp (npm)"}]}}
---

# x402 - Autonomous Agent Payments

Pay for x402-enabled APIs with USDC on Base. Discover paid endpoints via the Bazaar, execute micropayments, and access services without accounts or API keys.

## What is x402?

x402 is an open payment protocol that enables AI agents to pay for API access autonomously using stablecoins (USDC). When a service returns HTTP 402 "Payment Required", the agent can automatically sign a payment and retry the request.

## Quick Start

### 1. Set up your wallet

Export a private key from a wallet with USDC on Base (mainnet or Sepolia testnet):

```bash
export X402_PRIVATE_KEY="0x..."
```

**⚠️ Security**: Use a dedicated wallet with limited funds for agent payments. Never use your main wallet.

### 2. Fund your wallet

- **Testnet (Base Sepolia)**: Get test USDC from [Coinbase Faucet](https://portal.cdp.coinbase.com/products/faucet)
- **Mainnet (Base)**: Bridge USDC to Base via [bridge.base.org](https://bridge.base.org)

## Discovering x402 Endpoints

### Query the Bazaar

The x402 Bazaar is the discovery layer for paid APIs. Query it to find available services:

```bash
# List all available x402 services
curl -s "https://x402.org/facilitator/discovery/resources?limit=20" | jq '.resources[] | {url: .resource, price: .accepts[0].price, network: .accepts[0].network}'

# Search by category (if supported)
curl -s "https://x402.org/facilitator/discovery/resources?type=http&limit=50" | jq '.'
```

### Alternative Directories

- **x402.org/ecosystem** - Curated list of x402-enabled services
- **x402index.com** - Community directory of x402 endpoints
- **x402apis.io** - Decentralized API registry on Solana

## Making Paid Requests

### Using @civic/x402-mcp (Recommended for MCP)

If running as an MCP server (e.g., with Claude Desktop), configure in `~/.config/claude/claude_desktop_config.json`:

```json
{
"mcpServers": {
"x402": {
"command": "npx",
"args": ["@civic/x402-mcp"],
"env": {
"PRIVATE_KEY": "${X402_PRIVATE_KEY}",
"TARGET_URL": "https://x402-mcp.fly.dev/mcp"
}
}
}
}
```

### Using curl with manual payment flow

```bash
# Step 1: Make initial request (will get 402)
curl -i https://api.example.com/x402/endpoint

# Step 2: Parse payment requirements from 402 response
# Look for X-PAYMENT-REQUIRED header with payment details

# Step 3: Sign payment and retry (requires wallet integration)
```

### Using the x402 TypeScript SDK

```typescript
import { x402Client, wrapAxiosWithPayment } from "@x402/axios";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
import axios from "axios";

// Create x402 client
const client = new x402Client();
const signer = privateKeyToAccount(process.env.X402_PRIVATE_KEY);
registerExactEvmScheme(client, { signer });

// Wrap axios with payment handling
const api = wrapAxiosWithPayment(axios.create(), client);

// Make paid request - payment handled automatically on 402
const response = await api.get("https://api.example.com/x402/weather");
```

## Common x402 Endpoints

### Weather Data
- Price: ~$0.001/request
- Returns real-time weather data

### AI Inference
- Price: varies by model
- Run inference on hosted models

### Data APIs
- Price: ~$0.001-0.01/request
- Access premium data feeds

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `X402_PRIVATE_KEY` | Yes | Hex-encoded private key (with 0x prefix) |
| `X402_NETWORK` | No | `base` (mainnet) or `base-sepolia` (testnet). Default: `base-sepolia` |
| `X402_MAX_PAYMENT` | No | Maximum payment per request in USDC (e.g., `0.10`). Default: unlimited |

## Checking Wallet Balance

```bash
# Check USDC balance on Base Sepolia
cast balance --erc20 0x036CbD53842c5426634e7929541eC2318f3dCF7e $WALLET_ADDRESS --rpc-url https://sepolia.base.org

# Check USDC balance on Base Mainnet
cast balance --erc20 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 $WALLET_ADDRESS --rpc-url https://mainnet.base.org
```

## Security Best Practices

1. **Dedicated wallet**: Create a separate wallet just for agent payments
2. **Limited funding**: Only keep small amounts of USDC in the agent wallet
3. **Max payment limits**: Set `X402_MAX_PAYMENT` to cap per-request spending
4. **Testnet first**: Always test on Base Sepolia before mainnet
5. **Monitor spending**: Track wallet balance and transaction history

## Troubleshooting

### "Insufficient funds"
- Check USDC balance on the correct network (Base vs Base Sepolia)
- Ensure you have ETH for gas fees

### "Payment verification failed"
- Verify the facilitator URL is reachable
- Check that your wallet address matches the signer

### "Network mismatch"
- Confirm the endpoint's required network matches your wallet's network
- Some endpoints only support mainnet or testnet

## Resources

- [x402 Documentation](https://docs.cdp.coinbase.com/x402)
- [x402 Protocol Spec](https://x402.org)
- [Coinbase x402 GitHub](https://github.com/coinbase/x402)
- [Base Network](https://base.org)

## Related Skills

- `solana-swaps` - For Solana-based x402 payments
- `crypto-tracker` - Monitor wallet balances
150 changes: 150 additions & 0 deletions skills/onchainexpat/x402/bazaar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/usr/bin/env node
/**
* x402 Bazaar Discovery CLI
*
* Query the x402 Bazaar to discover paid API endpoints.
*
* Usage:
* node bazaar.js list [--limit N]
* node bazaar.js search <query>
* node bazaar.js info <url>
*/

const FACILITATOR_URL = process.env.X402_FACILITATOR_URL || 'https://x402.org/facilitator';

async function listResources(limit = 20) {
const url = `${FACILITATOR_URL}/discovery/resources?type=http&limit=${limit}`;

try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const data = await response.json();

if (!data.resources || data.resources.length === 0) {
console.log('No x402 services found in the Bazaar.');
return;
}

console.log(`\n📦 Found ${data.resources.length} x402 services:\n`);

for (const resource of data.resources) {
const accepts = resource.accepts?.[0] || {};
const price = accepts.price || accepts.maxAmountRequired || 'N/A';
const network = accepts.network || 'unknown';

console.log(` 🔗 ${resource.resource}`);
console.log(` 💰 Price: ${price}`);
console.log(` 🌐 Network: ${network}`);
if (resource.description) {
console.log(` 📝 ${resource.description}`);
}
console.log('');
}

return data.resources;
} catch (error) {
console.error(`Error querying Bazaar: ${error.message}`);
process.exit(1);
}
}

async function getResourceInfo(resourceUrl) {
const url = `${FACILITATOR_URL}/discovery/resources?resource=${encodeURIComponent(resourceUrl)}`;

try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const data = await response.json();
console.log(JSON.stringify(data, null, 2));
return data;
} catch (error) {
console.error(`Error fetching resource info: ${error.message}`);
process.exit(1);
}
}

// Alternative: Query CDP facilitator directly
async function listFromCDP(limit = 20) {
const url = `https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources?limit=${limit}`;

try {
const response = await fetch(url);
if (!response.ok) {
// Fall back to x402.org
console.log('CDP facilitator unavailable, trying x402.org...');
return listResources(limit);
}

const data = await response.json();
return data;
} catch (error) {
console.log('CDP facilitator unavailable, trying x402.org...');
return listResources(limit);
}
}

// Main CLI
const args = process.argv.slice(2);
const command = args[0];

switch (command) {
case 'list':
const limit = args.includes('--limit')
? parseInt(args[args.indexOf('--limit') + 1])
: 20;
listResources(limit);
break;

case 'search':
const query = args[1];
if (!query) {
console.error('Usage: bazaar.js search <query>');
process.exit(1);
}
// Search is just filtered list for now
listResources(50).then(resources => {
if (resources) {
const filtered = resources.filter(r =>
r.resource.toLowerCase().includes(query.toLowerCase()) ||
(r.description && r.description.toLowerCase().includes(query.toLowerCase()))
);
if (filtered.length === 0) {
console.log(`No services matching "${query}" found.`);
}
}
});
break;

case 'info':
const resourceUrl = args[1];
if (!resourceUrl) {
console.error('Usage: bazaar.js info <url>');
process.exit(1);
}
getResourceInfo(resourceUrl);
break;

default:
console.log(`
x402 Bazaar Discovery CLI

Commands:
list [--limit N] List available x402 services (default: 20)
search <query> Search services by keyword
info <url> Get detailed info about a specific endpoint

Environment:
X402_FACILITATOR_URL Override facilitator URL (default: https://x402.org/facilitator)

Examples:
node bazaar.js list --limit 50
node bazaar.js search weather
node bazaar.js info https://api.example.com/x402/data
`);
}