Metadata-Version: 2.4
Name: x402-fastapi-kit
Version: 0.3.0
Summary: Production-ready starter kit for building x402 payment-gated FastAPI services
Project-URL: Homepage, https://github.com/your-org/x402-fastapi-kit
Project-URL: Documentation, https://github.com/your-org/x402-fastapi-kit#readme
Project-URL: Repository, https://github.com/your-org/x402-fastapi-kit
Project-URL: Issues, https://github.com/your-org/x402-fastapi-kit/issues
Author: x402-fastapi-kit contributors
License: MIT
License-File: LICENSE
Keywords: api,crypto,fastapi,micropayments,monetization,payments,usdc,x402
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Office/Business :: Financial
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.100.0
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: uvicorn>=0.23.0
Provides-Extra: all
Requires-Dist: redis>=5.0.0; extra == 'all'
Requires-Dist: x402[all]; extra == 'all'
Provides-Extra: dev
Requires-Dist: httpx>=0.25.0; extra == 'dev'
Requires-Dist: mypy>=1.5; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: evm
Requires-Dist: x402[evm,fastapi]; extra == 'evm'
Provides-Extra: redis
Requires-Dist: redis>=5.0.0; extra == 'redis'
Provides-Extra: svm
Requires-Dist: x402[fastapi,svm]; extra == 'svm'
Description-Content-Type: text/markdown

# x402-fastapi-kit

**Production-ready starter kit for building x402 payment-gated FastAPI services.**

Turn any FastAPI endpoint into a paid API with one decorator. Built on [Coinbase's x402 protocol](https://x402.org) — the open standard for internet-native payments.

## Features

- **One-line payment gating** — `@require_payment(price="$0.01")` on any route
- **`PaymentApp`** — batteries-included FastAPI subclass with middleware pre-wired
- **Environment-driven config** — Pydantic Settings with `.env` support
- **Multi-chain** — EVM (Base, Ethereum, Polygon) and Solana out of the box
- **Introspection** — built-in `/x402/health` and `/x402/routes` endpoints
- **CLI scaffolding** — `x402kit init my-api` generates a ready-to-run project
- **Spec-compliant** — x402 v2 responses, `PAYMENT-REQUIRED` header, facilitator verification
- **API key fallback** — `X-API-Key` header auth for traditional clients
- **Wallet allowlist** — free-pass access for partners and your own AI agents
- **Rate limiting** — sliding-window rate limiter with per-route limits and `429` responses
- **Event hooks** — `@bus.on("payment.verified")` callbacks for logging, analytics, alerts

## Quick Start

### 1. Install

```bash
pip install x402-fastapi-kit
```

### 2. Set your wallet

```bash
export X402_PAY_TO=0xYourWalletAddress
```

### 3. Write your app

```python
from x402_fastapi_kit import PaymentApp, require_payment

app = PaymentApp()

@app.get("/free")
async def free():
    return {"msg": "hello, no payment needed"}

@app.get("/premium")
@require_payment(price="$0.05", description="Premium data")
async def premium():
    return {"data": "this costs $0.05 per request"}
```

### 4. Run

```bash
uvicorn app:app --reload
```

Try it:

```bash
curl http://localhost:8000/free        # → 200 OK
curl http://localhost:8000/premium     # → 402 Payment Required
curl http://localhost:8000/x402/routes # → list of gated routes
```

## Configuration

All settings are loaded from environment variables (prefix `X402_`) or a `.env` file:

| Variable | Default | Description |
|---|---|---|
| `X402_PAY_TO` | *(required)* | Wallet address (EVM or Solana) |
| `X402_NETWORK` | `eip155:84532` | CAIP-2 network ID |
| `X402_FACILITATOR_URL` | `https://x402.org/facilitator` | Facilitator service URL |
| `X402_DEFAULT_PRICE` | `$0.01` | Default price for gated routes |
| `X402_SCHEME` | `exact` | Payment scheme |
| `X402_MAX_TIMEOUT_SECONDS` | `300` | Payment expiry |
| `X402_HOST` | `0.0.0.0` | Server bind host |
| `X402_PORT` | `8000` | Server bind port |
| `X402_DEBUG` | `false` | Debug mode |
| `X402_SVM_PAY_TO` | *(optional)* | Solana address for dual-chain |
| `X402_RATE_LIMIT_ENABLED` | `true` | Enable rate limiting |
| `X402_RATE_LIMIT_RPM` | `60` | Default requests per minute per client |
| `X402_RATE_LIMIT_ROUTES` | *(empty)* | Per-route limits: `/weather=30,/forecast=10` |
| `X402_API_KEYS_ENABLED` | `false` | Enable API key fallback auth |
| `X402_API_KEYS` | *(empty)* | Keys as `name=secret,name=secret` |
| `X402_ALLOWLIST_ENABLED` | `false` | Enable wallet allowlist |
| `X402_ALLOWLIST_ADDRESSES` | *(empty)* | Comma-separated wallet addresses |

### Supported Networks

| Network | CAIP-2 ID |
|---|---|
| Base Sepolia (testnet) | `eip155:84532` |
| Base Mainnet | `eip155:8453` |
| Ethereum Mainnet | `eip155:1` |
| Polygon Mainnet | `eip155:137` |
| Solana Devnet | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` |
| Solana Mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` |

## Access Control

The middleware runs a 4-step pipeline on every gated request. The first match wins:

```
Request → [1] Wallet Allowlist → [2] API Key → [3] Rate Limit → [4] x402 Payment
               (bypass)            (bypass)        (429)           (402/200)
```

### API Key Fallback

Support traditional clients alongside x402 payers:

```python
from x402_fastapi_kit import PaymentApp, APIKeyManager, require_payment

keys = APIKeyManager()
keys.add_key("partner-1", "sk_live_abc123")
keys.add_key("internal",  APIKeyManager.generate_key())

app = PaymentApp(api_key_manager=keys)

@app.get("/data")
@require_payment(price="$0.05")
async def data():
    return {"result": "works with X-PAYMENT or X-API-Key header"}
```

```bash
curl -H "X-API-Key: sk_live_abc123" http://localhost:8000/data  # 200 — bypassed
```

### Wallet Allowlist

Give free access to partners, your own agents, or test wallets:

```python
from x402_fastapi_kit import PaymentApp, WalletAllowlist

allowlist = WalletAllowlist()
allowlist.add("0xPartnerWallet...", label="acme-corp")
allowlist.add("0xMyAgentWallet...", label="internal-bot")

app = PaymentApp(wallet_allowlist=allowlist)
```

```bash
curl -H "X-WALLET: 0xPartnerWallet..." http://localhost:8000/data  # 200 — free
```

### Rate Limiting

Protect your facilitator from abuse with per-client sliding-window limits:

```python
from x402_fastapi_kit import PaymentApp, RateLimiter

limiter = RateLimiter(
    requests_per_minute=60,
    route_limits={"/expensive": 10, "/cheap": 200},
)

app = PaymentApp(rate_limiter=limiter)
```

Allowlisted wallets and API key holders bypass rate limits (they're checked first).

## Event Hooks

Get notified at every decision point in the pipeline:

```python
from x402_fastapi_kit import PaymentApp, EventBus, EventType

bus = EventBus()

@bus.on(EventType.PAYMENT_VERIFIED)
async def on_paid(event):
    print(f"💰 {event.route} — tx: {event.tx_hash}")

@bus.on(EventType.RATE_LIMITED)
async def on_throttled(event):
    alert(f"⚠️ Client {event.client_id} rate limited on {event.route}")

# Wildcard — see everything
bus.on_all(lambda e: metrics.emit(e.event_type, e.route))

app = PaymentApp(event_bus=bus)
```

Event types: `payment.verified`, `payment.rejected`, `request.gated`, `auth.api_key`, `auth.allowlist`, `rate.limited`, `facilitator.error`

## Service Discovery

Make your API findable by AI agents and the x402 ecosystem:

```python
from x402_fastapi_kit import PaymentApp, ServiceManifest

manifest = ServiceManifest(
    name="Weather API",
    description="Real-time weather data",
    tags=["weather", "data", "climate"],
    homepage="https://weather.example.com",
)

app = PaymentApp(manifest=manifest)
# Now serves /.well-known/x402 automatically
```

Enrich your OpenAPI schema so tools can read pricing from `/openapi.json`:

```python
app.enrich_openapi_schema()
# Each gated endpoint now has x-x402 metadata in the spec
```

Register with the Bazaar discovery layer:

```python
from x402_fastapi_kit import register_with_bazaar

await register_with_bazaar("https://weather.example.com", settings, manifest)
```

## Client SDK (Buyer Side)

Make x402 payments from Python — for AI agents, scripts, and services that *consume* paid APIs:

```python
from x402_fastapi_kit import X402Client, PaymentPolicy, DryRunSigner

# Dry-run mode (no real wallet, for testing)
client = X402Client(signer=DryRunSigner())

# With spending controls
client = X402Client(
    signer=my_wallet_signer,
    policy=PaymentPolicy(
        max_per_request="1.00",
        max_per_session="10.00",
        preferred_network="eip155:8453",
    ),
)

# Transparent 402 → pay → retry
resp = await client.get("https://api.example.com/weather")
print(resp.json())

# Check spending
print(f"Total spent: ${client.total_spent}")
print(f"Receipts: {client.receipts}")

# Discover a service
manifest = await client.discover("https://api.example.com")
```

Implement `PaymentSigner` for real wallets:

```python
from x402_fastapi_kit import PaymentSigner

class MyWalletSigner(PaymentSigner):
    async def sign(self, requirements: dict) -> str:
        # Sign with your wallet (viem, web3.py, solders, etc.)
        return signed_payload_string

    @property
    def address(self) -> str:
        return "0xYourAddress"
```

## Analytics Dashboard

Live revenue and request monitoring, powered by the EventBus:

```python
from x402_fastapi_kit import PaymentApp, EventBus

bus = EventBus()
app = PaymentApp(event_bus=bus, analytics=True)
# Serves:
#   /x402/stats     → JSON snapshot (revenue, routes, auth breakdown)
#   /x402/dashboard → live HTML dashboard (auto-refreshes every 5s)
```

The dashboard shows: total revenue, payment count, per-route breakdown, auth method distribution, rate limit events, and a live event feed.

## CLI

```bash
# Scaffold a new project
x402kit init my-paid-api

# Show version and networks
x402kit info
```

## API Reference

### `PaymentApp`

A `FastAPI` subclass that auto-wires the payment middleware, discovers `@require_payment` routes, and adds introspection endpoints.

```python
from x402_fastapi_kit import PaymentApp

app = PaymentApp(
    title="My API",
    settings=X402Settings(pay_to="0x..."),
)
```

### `@require_payment`

Decorator to gate a route. Apply **after** the route decorator:

```python
@app.get("/data")
@require_payment(
    price="$0.05",           # required
    description="My data",   # shown in 402 response
    network="eip155:8453",   # override global network
    scheme="exact",          # payment scheme
    pay_to="0xOther",        # override global pay_to
)
async def get_data():
    return {"data": "paid content"}
```

### `PaymentGate`

ASGI middleware (used internally by `PaymentApp`, or add manually):

```python
from fastapi import FastAPI
from x402_fastapi_kit import PaymentGate, X402Settings

app = FastAPI()
app.add_middleware(PaymentGate, settings=X402Settings())
```

## How It Works

```
Client                    Your FastAPI               Facilitator
  │                           │                          │
  │  GET /premium             │                          │
  │──────────────────────────▶│                          │
  │                           │ (no X-PAYMENT header)    │
  │  402 + payment details    │                          │
  │◀──────────────────────────│                          │
  │                           │                          │
  │  GET /premium             │                          │
  │  X-PAYMENT: <signed>      │                          │
  │──────────────────────────▶│                          │
  │                           │  POST /verify            │
  │                           │─────────────────────────▶│
  │                           │  { valid: true }         │
  │                           │◀─────────────────────────│
  │  200 + data               │                          │
  │◀──────────────────────────│                          │
```

## Development

```bash
git clone https://github.com/your-org/x402-fastapi-kit
cd x402-fastapi-kit
pip install -e ".[dev]"
pytest
```

## License

MIT
