branch:
README.md
2631 bytesRaw
# x402 HTTP Payments
HTTP payment gating using the [x402 protocol](https://x402.org) with Hono middleware. A `/protected-route` requires a $0.10 payment on Base Sepolia — an Agent with a test wallet pays automatically.
## What it demonstrates
- **`@x402/hono` middleware** — `paymentMiddleware()` gates any Hono route behind a price
- **`@x402/fetch`** — `wrapFetchWithPayment(fetch)` wraps `fetch` so the agent signs and pays automatically
- **`@x402/evm`** — EVM scheme registration for both client and server
- **`@callable`** — the agent exposes `fetchProtectedRoute` as a callable method
- **`useAgent` + `agent.call()`** — the React frontend triggers the paid fetch via WebSocket RPC
## Running
Copy the environment file and fill in your keys:
```sh
cp .env.example .env
```
You need:
- `SERVER_ADDRESS` — an Ethereum address to receive payments (Base Sepolia testnet)
- `CLIENT_TEST_PK` — a private key for signing payments (test key only, get test funds from https://faucet.circle.com/)
Then:
```sh
npm install
npm start
```
Press "Fetch & Pay" to have the agent access the protected route and automatically pay.
## How it works
### Server: gating a route
```typescript
import { paymentMiddleware, x402ResourceServer } from "@x402/hono";
app.use(
paymentMiddleware(
{
"GET /protected-route": {
accepts: [
{
scheme: "exact",
price: "$0.10",
network: "eip155:84532",
payTo: process.env.SERVER_ADDRESS
}
],
description: "Access to premium content"
}
},
resourceServer
)
);
app.get("/protected-route", (c) => c.json({ message: "Thanks for paying!" }));
```
### Agent: paying automatically
```typescript
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
export class PayAgent extends Agent<Env> {
onStart() {
const client = new x402Client();
registerClientEvmScheme(client, { signer: account });
this.fetchWithPay = wrapFetchWithPayment(fetch, client);
}
@callable()
async fetchProtectedRoute() {
const res = await this.fetchWithPay("/protected-route", {});
return { text: await res.text(), isError: !res.ok };
}
}
```
## Compared to x402-mcp
This example gates **HTTP endpoints** using `@x402/*` libraries directly. The [`x402-mcp`](../x402-mcp/) example gates **MCP tools** using the Agents SDK's `withX402()` / `withX402Client()` wrappers. Different protocols, different APIs.
## Related examples
- [`x402-mcp`](../x402-mcp/) — paid MCP tools using the Agents SDK's x402 integration