SELLER SDK

thesellside-x4-agent

A Python/FastAPI middleware that turns any API endpoint into a pay-per-call service. Supports x402 (Base + Solana) and MPP (Solana). Your buyers never need to know how payments work — jaypay handles both sides.

Python 3.10+FastAPIBase USDCSolana USDCx402 v2MPP

Install

# 1. create and activate a virtual environment:
python3 -m venv .venv
source .venv/bin/activate
# 2. install jaypay:
pip install git+https://github.com/jaysperspective/thesellside-x402-agent.git
# 3. grab the starter .env and fill in your values:
curl -o .env https://raw.githubusercontent.com/jaysperspective/thesellside-x402-agent/main/.env.example

Open .env and fill in your wallet address, CDP keys, and (once you have it) your JAYPAY_ACTIVATION_KEY. Every time you open a new terminal, re-run source .venv/bin/activate before starting your server.

FASTEST PATH

Set up with Claude Code

Copy this prompt and paste it into Claude Code, Cursor, or any AI coding assistant open in your project. It will ask you about your routes and wallet, then wire up everything automatically. Manual step-by-step instructions are below if you prefer.

You are helping me add jaypay payment middleware to my existing FastAPI app. jaypay enables x402 (Base USDC) pay-per-call billing on any route — buyers pay automatically via their AI agent, I receive USDC directly to my wallet with no processor or monthly fee.

STEP 1 — Set up the environment
Run these in my project directory:
  python3 -m venv .venv
  source .venv/bin/activate
  pip install git+https://github.com/jaysperspective/thesellside-x402-agent.git
  curl -o .env https://raw.githubusercontent.com/jaysperspective/thesellside-x402-agent/main/.env.example

STEP 2 — Ask me these questions before writing any code:
  1. Which file is my FastAPI app defined in? (default: main.py)
  2. Which routes do I want to charge for?
     For each route: the URL path, HTTP method, a plain-English description, and the price in USDC
  3. What is my Base (EVM) wallet address where payments should land?
  4. Do I also want to accept Solana payments via MPP?
     If yes: what is my Solana wallet public key?

STEP 3 — Once I answer, update my app file to include:
  a. register_pricing({...}) with one ResourcePrice entry per paid route —
     key and route_pattern use the same string; resource_template is the URL path
  b. install_x402(app) and install_mpp_middleware(app) called after app = FastAPI()
  c. dependencies=[Depends(payment_guard("key"))] on each paid route decorator
  d. A GET /api/v1/pricing.json endpoint that returns pricing_catalog()

STEP 4 — Update .env:
  - Set AGENT_PAYMENT_ADDRESS to my Base wallet
  - Set X402_MODE=advertised (NOT active yet — activation comes after)
  - Fill in any Solana keys if I said yes to MPP

STEP 5 — When done, show me a summary of every file changed, then remind me:
  1. I still need a JAYPAY_ACTIVATION_KEY — get it by following the activation
     flow at 402directory.com/sellers (costs $0.10 USDC, proves setup is correct)
  2. After I have the key: set JAYPAY_ACTIVATION_KEY and X402_MODE=active in .env, then restart
  3. Once live, submit my API to the directory at 402directory.com/submit

PRIVACY — treat all of the following as secrets. Never echo them in chat, never include them in commit messages, diffs, summaries, or any visible output:
  - wallet addresses (EVM and Solana)
  - API keys and secrets (CDP, JWT, internal)
  - JAYPAY_ACTIVATION_KEY
  - MPP_FACILITATOR_SECRET_KEY
  - any value that goes into .env
Write them only to the .env file. If you need to reference them in conversation, use placeholders like 0x... or jpay_... instead.

The prompt sets X402_MODE=advertised so your server starts cleanly while you complete the activation step below. Flip to X402_MODE=active once you have your key.

🔑
One-time activation required

Before your seller middleware can go live, it needs to prove it works. You make one test payment of $0.10 USDCto jaypay's wallet using your buyer agent. That transaction confirms your full setup is correct — buyer agent, wallet, and seller middleware in sync. You get an JAYPAY_ACTIVATION_KEY back. Set it in your .envand you're live.

# Step 1 — ask your agent (Claude Code, Desktop, or Cursor):
"Use pay.fetch to GET https://402directory.com/api/activate/pay"
# The agent pays $0.10 USDC, settlement confirms on-chain.
# Response:
{
"activated": true,
"activation_key": "jpay_a3f91b...",
"next_step": "Set JAYPAY_ACTIVATION_KEY=jpay_a3f91b... in .env"
}
# Step 2 — add to your .env:
JAYPAY_ACTIVATION_KEY=jpay_a3f91b...
X402_MODE=active
# Step 3 — restart your server. You're live.
jaypay: activation key verified ✓ — going active.

The transaction is on-chain and permanent. It's your proof of correct setup — not just a checkbox, but a real payment that validated the entire stack end-to-end.

Manual setup — step by step

These snippets all go inside your FastAPI app file — typically main.py. Replace the placeholder route and description with your actual endpoint. Do not paste them into the terminal.

# create your app file if you don't have one yet:
nano main.py
# or open it in VS Code, Cursor, or any editor:
code main.py

Then paste each snippet below into the file in order, save, and run your server.

1
Define your pricing

ResourcePrice is a config form — one per paid route. The dictionary key ("my_endpoint") is the internal nickname your code uses to reference this route. The key field inside repeats it — same value, needed so the middleware can look it up either way.

resource_template is the URL path shown to buyers in the pricing catalog. route_patternis the same path formatted for the middleware to match incoming requests — they'll almost always be the same string. Price is in atomic USDC: 1,000,000 = $1.00, so 5000 = $0.005.

# main.py
from jaypay.pricing import ResourcePrice, register_pricing
register_pricing({
"my_endpoint": ResourcePrice( # nickname — used in payment_guard()
key="my_endpoint", # same nickname, repeated inside
resource_template="/api/v1/your-route", # path shown to buyers
route_pattern="GET /api/v1/your-route", # path matched by middleware
method="GET",
description="What this endpoint does", # shown on 402 responses
max_amount_required="5000", # $0.005 USDC
display="$0.005 USDC",
),
# one ResourcePrice entry per paid route
})
2
Install the middleware

Call these after app = FastAPI() and after register_pricing().

# main.py
from jaypay.middleware import install_x402
from jaypay.mpp.middleware import install_mpp_middleware
app = FastAPI()
install_x402(app) # handles EVM + Solana x402 payments
install_mpp_middleware(app) # handles Solana MPP — must come after

Order matters: FastAPI runs middleware last-added-first, so MPP must be added after x402 to wrap it correctly.

3
Gate your routes

Add a payment_guard dependency to each endpoint you want to charge for. Use the same key you registered in step 1.

# main.py
from fastapi import Depends
from jaypay.guards import payment_guard
@app.get("/api/v1/your-route",
dependencies=[Depends(payment_guard("my_endpoint"))])
async def your_route():
return {"data": "your response here"}
4
Fill in your .env

You already copied .env.example to .env during install. Open it and fill in:

# .env
X402_MODE=active
JAYPAY_ACTIVATION_KEY=jpay_... # from the activation step above
AGENT_PAYMENT_ADDRESS=0x... # your Base wallet — where USDC lands
X402_NETWORK=eip155:8453 # Base mainnet
X402_CDP_API_KEY_ID=...
X402_CDP_API_KEY_SECRET=...
# optional: also accept Solana MPP payments
MPP_MODE=active
MPP_RECIPIENT_PUBKEY=... # your Solana wallet
MPP_FACILITATOR_PUBKEY=...
MPP_FACILITATOR_SECRET_KEY=...
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
REDIS_URL=redis://localhost:6379/0
5
Expose your pricing catalog (optional but recommended)

Lets buyer agents discover what your API costs. The 402directory.com listing page reads it automatically.

# main.py
from jaypay.catalog import pricing_catalog
@app.get("/api/v1/pricing.json")
async def pricing():
return pricing_catalog()

What your sellers see

When an agent hits your gated endpoint without payment, it receives an HTTP 402 with full payment instructions in the headers. The agent pays automatically. You receive USDC directly to your wallet — no processor, no monthly fee, no chargebacks. Every transaction is on-chain and auditable.

HTTP/2 402
payment-required: <x402 challenge>
www-authenticate: Payment id=..., method=solana, ...
# agent pays, retries —
HTTP/2 200
payment-receipt: <on-chain tx signature>