Slug Wallet
README.md
# Slug Wallet
Give your terminal AI agent a guarded USDC wallet. It intercepts HTTP 402 paywalls, enforces budget limits, signs payments automatically, and works with any x402 service — today.
**Chain:** Base mainnet
**Token:** USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`)
---
## Why
AI agents hitting paywalled APIs either crash or need raw access to your credit card. Slug Wallet gives them a wallet with hard guardrails:
- **$2 daily limit, $0.02 per request** — fully configurable
- **Domain whitelist** — agent can only pay approved services
- **Local spend ledger** — tracks every payment, persists across restarts
- **Plugs into Claude Code, OpenCode, any MCP client** — one command
- **Works with real x402 services right now** — Exa, Otto AI, Tavily, and more
No funds move until the firewall approves the payment. If a request falls outside your limits, the agent gets a clear error and nothing is signed.
---
## Quickstart
### 1. Connect to your agent
**Claude Code:**
```bash
claude mcp add slug-wallet -s user -- npx slug-wallet-mcp
```
**OpenCode** (`opencode.json` in your project root):
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"slug-wallet": {
"type": "local",
"command": ["npx", "slug-wallet-mcp"],
"enabled": true
}
}
}
```
### 2. Pick a mode
**Dev mode** (no real money — for testing):
```json
{
"env": { "SLUG_WALLET_DEV_SIGNER": "1" }
}
```
**Live mode** (real USDC on Base):
```json
{
"env": {
"CDP_API_KEY_ID": "your-key-id",
"CDP_API_KEY_SECRET": "your-key-secret",
"CDP_WALLET_SECRET": "your-wallet-secret"
}
}
```
### 3. Try it
Ask your agent:
> *Fetch https://x402.ottoai.services/crypto-news using the slug-wallet tool*
The agent will call `slug_fetch`, Slug Wallet intercepts the 402, checks the firewall, signs the payment, and returns the content. All automatic.
---
## The firewall
Your `slug-config.json` controls exactly what the wallet is allowed to pay:
```json
{
"maxUsdPerRequest": 0.02,
"dailyUsdLimit": 2.00,
"allowedDomains": ["exa.ai", "*.browserbase.com", "x402.ottoai.services"]
}
```
| Rule | What it does |
|------|-------------|
| `maxUsdPerRequest` | Blocks any single payment above this amount |
| `dailyUsdLimit` | Blocks all payments once the daily total is hit |
| `allowedDomains` | Blocks payments to any domain not in the list (supports `*.example.com` wildcards) |
The firewall runs **before** any signature. If a payment is blocked, the agent sees a clear error message explaining why — no funds move, no signature is generated.
Run `npx slug-wallet init` to create a `slug-config.json` with safe defaults.
---
## MCP tools
| Tool | What it does |
|------|-------------|
| `slug_fetch` | Make an HTTP request, auto-paying any 402 within firewall limits |
| `get_wallet_address` | Returns the signing wallet address |
| `get_daily_spend` | Returns `{ spentUsd, limitUsd, remainingUsd, pendingFeesUsd, pendingFeeCount }` |
---
## Real x402 services you can use today
These are live services that return HTTP 402 and work with Slug Wallet out of the box:
| Service | URL | Price | What it does |
|---------|-----|-------|-------------|
| Otto AI | `https://x402.ottoai.services/crypto-news` | $0.001 | Real-time crypto market news with sentiment |
| Otto AI | `https://x402.ottoai.services/trending-altcoins` | $0.001 | Top 3 trending altcoins |
| Exa Search | `https://api.exa.ai/search` | $0.007 | AI web search |
| Tavily | `https://x402.tavily.com/search` | $0.01 | Advanced web search |
| twit.sh | `https://x402.twit.sh/tweets/search` | $0.006 | Twitter/X tweet search |
| CoinGecko | `https://pro-api.coingecko.com/api/v3/x402/onchain/search/pools` | $0.01 | Onchain DEX pool data |
| Anchor | `https://api.anchor-x402.com/v1/price/token` | $0.001 | Token price lookup |
Add the domain to your `allowedDomains` and your agent can start paying for these immediately. Browse more at [x402scan.com](https://x402scan.com) or [agentic.market](https://agentic.market).
---
## Setup
### Getting CDP credentials (live mode)
1. Go to [portal.cdp.coinbase.com/projects/api-keys](https://portal.cdp.coinbase.com/projects/api-keys)
2. Create a Secret API key — copy `CDP_API_KEY_ID` and `CDP_API_KEY_SECRET`
3. Go to Wallets → Non-custodial → Security for `CDP_WALLET_SECRET`
4. Fund your agent wallet with USDC on Base (start with $2)
KYC is required for live accounts. Until KYC is complete, use dev mode.
### Environment variables
| Variable | Required | Description |
|----------|----------|-------------|
| `CDP_API_KEY_ID` | Live mode | Coinbase CDP API key ID |
| `CDP_API_KEY_SECRET` | Live mode | Coinbase CDP API key secret |
| `CDP_WALLET_SECRET` | Live mode | Coinbase CDP wallet secret |
| `SLUG_WALLET_DEV_SIGNER` | Dev mode | Set to `1` for fake signatures (no real payments) |
| `SLUG_WALLET_CONFIG_PATH` | Optional | Path to `slug-config.json` (default: `./slug-config.json`) |
The server hard-fails at startup if neither CDP credentials nor `SLUG_WALLET_DEV_SIGNER=1` is set.
---
## Library usage
Use Slug Wallet programmatically without MCP:
```ts
import { createSlugFetch, CdpPaymentSigner } from "slug-wallet";
const signer = new CdpPaymentSigner();
const slugFetch = await createSlugFetch({ signer });
const response = await slugFetch("https://x402.ottoai.services/crypto-news");
```
Bring your own signer by implementing `PaymentSigner`:
```ts
import type { PaymentSigner, InvoicePayload, PaymentProof } from "slug-wallet";
class MySigner implements PaymentSigner {
async getAddress(): Promise<string> { ... }
async signInvoice(invoice: InvoicePayload): Promise<PaymentProof> { ... }
}
```
The `PaymentSigner` interface is wallet-agnostic. `CdpPaymentSigner` (Coinbase CDP) ships built-in, but you can implement it with any EVM wallet provider — Privy, Fireblocks, local private keys, HSMs, etc. The firewall, interceptor, MCP server, and fee settlement layer work identically regardless of where the signature comes from.
---
## Verify
```bash
npm run check # TypeScript build + 67 unit tests
npm run verify:harness # End-to-end interceptor + MockSigner
npm run verify:mcp # End-to-end MCP subprocess (all 3 tools)
```
---
## For protocol operators
<details>
<summary>Setting up the fee settlement layer (optional)</summary>
Slug Wallet supports an on-chain fee settlement layer. When enabled, every payment generates a separate fee authorization that is batched and submitted to a `SlugSettlement` contract on Base, routing a percentage of each payment to a treasury wallet.
### How it works
```
Agent pays merchant via normal x402 flow
│
├──► Merchant gets paid (normal)
│
└──► Slug Wallet signs fee authorization
│
▼
FeeQueue (.slug-wallet/fee-queue.json)
│ when total >= $0.05
▼
Relay (slug-wallet-relay)
│
▼
SlugSettlement.settleFee() on Base
│
├──► Fee goes to treasury
└──► Settlement event emitted
```
### Configuration
In `slug-config.json`:
```json
{
"settlement": {
"enabled": true,
"contractAddress": "0x...",
"feeBps": 50,
"treasuryAddress": "0x..."
}
}
```
- `feeBps`: Fee in basis points (50 = 0.5%, 500 = 5%)
- `contractAddress`: Deployed `SlugSettlement` address on Base
- `treasuryAddress`: Where fees land (must be set when enabled)
### Running the relay
```bash
npx slug-wallet-relay
```
| Variable | Required | Description |
|----------|----------|-------------|
| `SLUG_RELAY_PRIVATE_KEY` | Yes | Private key of a Base wallet with ETH for gas |
| `SLUG_RELAY_AUTH_TOKEN` | Yes | Secret token shared with the MCP server |
| `SLUG_RELAY_PORT` | Optional | Port to listen on (default: `4022`) |
| `SLUG_WALLET_RELAY_URL` | MCP server | URL of the relay (e.g. `http://127.0.0.1:4022`) |
The relay binds to `127.0.0.1` only. Fund the relay wallet with ~$2 of ETH on Base for gas.
### Fee queue economics
Fees accumulate locally in `.slug-wallet/fee-queue.json`. When the total crosses `$0.05`, the MCP server batches them to the relay, which submits a single on-chain transaction:
```
50 payments at $0.001 each
= $0.05 queued fees
= 1 on-chain tx (~$0.01 gas)
= $0.04 net to treasury per batch
```
### Settlement contract
The Solidity contract is in `contracts/SlugSettlement.sol`. Deploy with:
```bash
forge create --rpc-url https://mainnet.base.org \
--private-key $RELAY_PRIVATE_KEY \
contracts/SlugSettlement.sol:SlugSettlement \
--constructor-args <treasury-address> <feeBps>
```
The contract has two functions:
- `executePayment()` — full payment routing (merchant + fee split in one transaction)
- `settleFee()` — fee-only settlement (used by the relay in dual-signing mode)
</details>
---
## License
MIT
This server cannot be deployed
Maintenance
ActivityNo data
ResponsivenessNo issues