Skip to content

Commit ca26869

Browse files
authored
Merge pull request #13 from hpp-io/docs/x402-section
docs: add x402 payments section at /x402
2 parents 1f2ae67 + 785f0f7 commit ca26869

9 files changed

Lines changed: 877 additions & 1 deletion

‎docusaurus.config.ts‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,26 @@ const config: Config = {
9292
sidebarPath: false,
9393
},
9494
],
95+
// x402 payment-protocol docs — a standalone product section served at /x402
96+
// (modeled on docs.cdp.coinbase.com/x402), independent of the main HPP docs.
97+
[
98+
'@docusaurus/plugin-content-docs',
99+
{
100+
id: 'x402',
101+
path: 'x402',
102+
routeBasePath: 'x402',
103+
sidebarPath: './sidebarsX402.ts',
104+
editUrl: 'https://github.com/hpp-io/docs/tree/main/',
105+
},
106+
],
95107
],
96108
themes: [
97109
[
98110
'@easyops-cn/docusaurus-search-local',
99111
{
100112
hashed: true,
101113
indexDocs: true,
102-
docsRouteBasePath: ['/', 'hub', 'hpp-router'],
114+
docsRouteBasePath: ['/', 'hub', 'hpp-router', 'x402'],
103115
highlightSearchTermsOnTargetPage: true,
104116
language: ['en'],
105117
},
@@ -137,6 +149,13 @@ const config: Config = {
137149
label: 'HPP Router',
138150
position: 'right',
139151
},
152+
{
153+
type: 'docSidebar',
154+
sidebarId: 'x402Sidebar',
155+
docsPluginId: 'x402',
156+
label: 'x402',
157+
position: 'right',
158+
},
140159
{
141160
href: 'https://github.com/hpp-io/docs',
142161
label: 'GitHub',

‎sidebarsX402.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
2+
3+
// Sidebar for the standalone "x402" product docs (the `x402` docs instance, served at /x402).
4+
// Modeled on the CDP x402 docs: Overview -> concepts -> quickstarts -> facilitator -> reference.
5+
// Add new pages here as you create them under `x402/` (the id is the file path without extension).
6+
const sidebars: SidebarsConfig = {
7+
x402Sidebar: [
8+
{type: 'doc', id: 'intro', label: 'Overview'},
9+
'how-it-works',
10+
'networks-and-token',
11+
{
12+
type: 'category',
13+
label: 'Quickstart',
14+
collapsed: false,
15+
items: ['quickstart-sellers', 'quickstart-buyers'],
16+
},
17+
'facilitator',
18+
'sdk',
19+
],
20+
};
21+
22+
export default sidebars;

‎x402/facilitator.mdx‎

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
---
2+
title: HPP Facilitator
3+
sidebar_label: Facilitator
4+
description: HPP's hosted x402 facilitator — verify and settle USDC.e payments on HPP Mainnet and Sepolia, with gasless upto settlement.
5+
---
6+
7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
10+
# HPP Facilitator
11+
12+
A **facilitator** is the service an x402 resource server delegates payment **verification** and
13+
**onchain settlement** to. HPP operates production facilitators for both its Mainnet and Sepolia
14+
networks, so sellers never have to run an RPC node, manage a settlement key, or hold buyer funds —
15+
the facilitator only verifies signatures and submits the settlement transaction.
16+
17+
## Endpoints
18+
19+
| Network | Base URL |
20+
| --- | --- |
21+
| HPP Mainnet (`eip155:190415`) | `https://facilitator.hpp.io` |
22+
| HPP Sepolia (`eip155:181228`) | `https://facilitator-sepolia.hpp.io` |
23+
24+
Each facilitator exposes the standard x402 facilitator API:
25+
26+
| Route | Method | Purpose |
27+
| --- | --- | --- |
28+
| `/supported` | `GET` | Lists the `(scheme, network)` pairs and extensions the facilitator supports. |
29+
| `/verify` | `POST` | Verifies a signed payment payload without settling. |
30+
| `/settle` | `POST` | Submits the payment onchain and returns a settlement receipt. |
31+
32+
**CORS is enabled**, so browser-based clients can call the facilitator directly.
33+
34+
You can confirm what a facilitator supports at any time:
35+
36+
```bash
37+
curl https://facilitator.hpp.io/supported
38+
```
39+
40+
```json
41+
{
42+
"kinds": [
43+
{ "x402Version": 2, "scheme": "exact", "network": "eip155:190415" },
44+
{ "x402Version": 2, "scheme": "upto", "network": "eip155:190415",
45+
"extra": { "facilitatorAddress": "0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033" } }
46+
],
47+
"extensions": ["eip2612GasSponsoring"],
48+
"signers": { "eip155:*": ["0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033"] }
49+
}
50+
```
51+
52+
The Sepolia facilitator (`https://facilitator-sepolia.hpp.io/supported`) returns the same shape with
53+
`network: "eip155:181228"` and its own signer `0x420bd05aB1103b0F4A02B39Ca07C92677b5CFD9d`.
54+
55+
## Supported schemes
56+
57+
| Scheme | Standard | Notes |
58+
| --- | --- | --- |
59+
| `exact` | EIP-3009 (`transferWithAuthorization`) | Fixed-price payments. |
60+
| `upto` | Permit2 | Authorize a maximum, settle the actual amount. Supports gasless settlement. |
61+
62+
Both schemes settle in **USDC.e** (`0x401eCb1D350407f13ba348573E5630B83638E30D`, 6 decimals) on both
63+
networks. See [How it works → Payment schemes](./how-it-works.md#payment-schemes).
64+
65+
## Connecting to it
66+
67+
You don't call the facilitator directly in normal use — your resource server does. Point a
68+
facilitator client at the right base URL:
69+
70+
```ts
71+
import { HTTPFacilitatorClient } from "@x402/core/server";
72+
73+
// HPP Mainnet
74+
const facilitator = new HTTPFacilitatorClient({ url: "https://facilitator.hpp.io" });
75+
// HPP Sepolia
76+
// const facilitator = new HTTPFacilitatorClient({ url: "https://facilitator-sepolia.hpp.io" });
77+
```
78+
79+
Then register your schemes against it — see [Quickstart: Sellers](./quickstart-sellers.mdx). Buyers
80+
never configure the facilitator at all; they discover it implicitly from the seller's `402` challenge.
81+
82+
## Verify and settle
83+
84+
`HTTPFacilitatorClient` wraps the two POST endpoints. Both take the same body — the buyer's signed
85+
`paymentPayload` plus the `paymentRequirements` it is paying — and the SDK calls them for you during
86+
`paymentMiddleware`. The shapes:
87+
88+
```jsonc
89+
// POST /verify and POST /settle request
90+
{
91+
"x402Version": 2,
92+
"paymentPayload": { /* the decoded X-PAYMENT payload the buyer signed */ },
93+
"paymentRequirements": { /* the matching accept from the 402 */ }
94+
}
95+
```
96+
97+
```jsonc
98+
// POST /verify response — checks the signature WITHOUT moving funds
99+
{ "isValid": true, "payer": "0x…" }
100+
// on failure: { "isValid": false, "invalidReason": "...", "invalidMessage": "..." }
101+
```
102+
103+
```jsonc
104+
// POST /settle response — submits the payment onchain
105+
{
106+
"success": true,
107+
"transaction": "0x…", // settlement tx hash
108+
"network": "eip155:190415",
109+
"payer": "0x…",
110+
"amount": "10000" // actual amount settled (for `upto`, ≤ the max)
111+
}
112+
// on failure: { "success": false, "errorReason": "...", "errorMessage": "...", "transaction": "0x…" }
113+
```
114+
115+
In the SDK, a failed `/verify` or `/settle` surfaces **to the resource server** as `VerifyError` or
116+
`SettleError` (exported from `@x402/core`), carrying `invalidReason` / `errorReason` for branching.
117+
Buyers don't see these types — they get a non-2xx response instead (see
118+
[Quickstart: Buyers → Handling failures](./quickstart-buyers.mdx#handling-failures)).
119+
120+
## Gasless settlement (`upto`)
121+
122+
For the `upto` scheme, HPP's facilitator advertises the **`eip2612GasSponsoring`** extension. This
123+
lets the facilitator sponsor the buyer's one-time Permit2 approval via
124+
[EIP-2612](https://eips.ethereum.org/EIPS/eip-2612), so a paying agent needs **only USDC.e and zero
125+
native ETH** to transact.
126+
127+
The **sponsoring signer** — the facilitator's onchain address that pays gas and submits settlement —
128+
is the same value shown as `signers` and as the `upto` `facilitatorAddress` in `/supported`:
129+
130+
| Network | Sponsoring signer (`facilitatorAddress`) |
131+
| --- | --- |
132+
| HPP Mainnet | `0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033` |
133+
| HPP Sepolia | `0x420bd05aB1103b0F4A02B39Ca07C92677b5CFD9d` |
134+
135+
When a seller offers an `upto` route, the SDK surfaces the `facilitatorAddress` and the
136+
`eip2612GasSponsoring` extension in the `402` challenge automatically, and a compatible buyer signs
137+
the gasless approval path with no extra configuration.
138+
139+
## Self-hosting
140+
141+
HPP's facilitator is a deployment of the standard open-source x402 facilitator, so you are not locked
142+
in: you can run your own and point your resource server at it instead. Use HPP's hosted endpoints to
143+
get started, and self-host if you need custom signing keys, private RPC, or independent operations.
144+
See the [x402 SDK & reference](./sdk.md) for the upstream packages.
145+
146+
## Quick reference
147+
148+
| Field | HPP Mainnet | HPP Sepolia |
149+
| --- | --- | --- |
150+
| Facilitator URL | `https://facilitator.hpp.io` | `https://facilitator-sepolia.hpp.io` |
151+
| Network (CAIP-2) | `eip155:190415` | `eip155:181228` |
152+
| Token (USDC.e) | `0x401eCb1D350407f13ba348573E5630B83638E30D` | `0x401eCb1D350407f13ba348573E5630B83638E30D` |
153+
| Schemes | `exact`, `upto` | `exact`, `upto` |
154+
| Gasless extension | `eip2612GasSponsoring` | `eip2612GasSponsoring` |
155+
| Sponsor signer | `0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033` | `0x420bd05aB1103b0F4A02B39Ca07C92677b5CFD9d` |

‎x402/how-it-works.md‎

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
title: How it works
3+
sidebar_label: How it works
4+
description: The x402 payment flow on HPP — the three roles, the 402 challenge, and the exact and upto payment schemes.
5+
---
6+
7+
# How it works
8+
9+
x402 turns a normal HTTP request into a paid one using the `402 Payment Required` status code.
10+
Nothing about the transport changes — a paid endpoint is still a regular URL that returns `402`
11+
until a valid payment is attached.
12+
13+
## The three roles
14+
15+
- **Resource server (the seller).** An HTTP service that puts a price on one or more routes.
16+
When an unpaid request arrives, it replies with `402` and a list of acceptable payment terms
17+
(`accepts`). When a paid request arrives, it verifies and settles the payment, then returns the resource.
18+
- **Client (the buyer).** A browser, a backend, or an AI agent that wants the resource. It reads the
19+
`402`, signs a stablecoin authorization for one of the offered terms, and retries with an `X-PAYMENT` header.
20+
- **Facilitator.** A service that the resource server delegates two jobs to: **verify** a payment
21+
signature, and **settle** it onchain. HPP operates the facilitators so sellers never run an RPC node
22+
or hold a settlement key. See [Facilitator](./facilitator.mdx).
23+
24+
## The payment flow
25+
26+
```text
27+
Buyer (client) Seller (resource server) HPP Facilitator
28+
│ │ │
29+
│ 1. GET /paid/resource │ │
30+
│ ───────────────────────────────► │ │
31+
│ │ │
32+
│ 2. 402 Payment Required │ │
33+
│ { accepts: [ {scheme, │ │
34+
│ network, asset, amount, │ │
35+
│ payTo, … } ] } │ │
36+
│ ◄─────────────────────────────── │ │
37+
│ │ │
38+
│ 3. sign payment authorization │ │
39+
│ (EIP-3009 / Permit2) │ │
40+
│ │ │
41+
│ 4. GET /paid/resource │ │
42+
│ X-PAYMENT: <signed payload> │ │
43+
│ ───────────────────────────────► │ 5. verify(payload) │
44+
│ │ ──────────────────────────────► │
45+
│ │ ◄────────────────────────────── │
46+
│ │ 6. run the work / serve │
47+
│ │ 7. settle(payload) │
48+
│ │ ──────────────────────────────► │ ──► onchain tx
49+
│ │ ◄────────────────────────────── │
50+
│ 8. 200 OK + resource │ │
51+
│ X-PAYMENT-RESPONSE: <receipt>│ │
52+
│ ◄─────────────────────────────── │ │
53+
```
54+
55+
HPP's resource-server middleware uses **serve-then-settle**: it verifies the payment first, serves the
56+
response, and settles after a successful result (`status < 400`). The buyer gets a settlement receipt
57+
back in the `X-PAYMENT-RESPONSE` header.
58+
59+
## The 402 challenge
60+
61+
The body of the `402` response (x402 version 2) tells the buyer exactly how it may pay. Each entry in
62+
`accepts` is one acceptable `(scheme, network)` with its price and asset:
63+
64+
```json
65+
{
66+
"x402Version": 2,
67+
"resource": {
68+
"url": "https://seller.example.com/paid/hello",
69+
"description": "A paid hello-world endpoint."
70+
},
71+
"accepts": [
72+
{
73+
"scheme": "exact",
74+
"network": "eip155:190415",
75+
"amount": "10000",
76+
"asset": "0x401eCb1D350407f13ba348573E5630B83638E30D",
77+
"payTo": "0xYourReceivingAddress",
78+
"maxTimeoutSeconds": 600,
79+
"extra": { "name": "Bridged USDC", "version": "2" }
80+
}
81+
],
82+
"extensions": {}
83+
}
84+
```
85+
86+
- `amount` is in the asset's base units — `"10000"` is `0.01` USDC.e (6 decimals).
87+
- `extra` carries the EIP-712 domain the buyer needs to sign (`exact`), and scheme-specific data such
88+
as the `facilitatorAddress` for gas-sponsored `upto`.
89+
- A multi-network or multi-scheme seller returns several `accepts`; the buyer's SDK selects one (next
90+
section). The settlement receipt comes back base64-encoded in the `X-PAYMENT-RESPONSE` header and
91+
decodes to `{ success, transaction, network, payer, amount? }`.
92+
93+
## Payment schemes
94+
95+
A *scheme* defines how the buyer authorizes payment and how the facilitator settles it onchain. The
96+
seller lists one or more schemes per route, in priority order; the buyer's SDK picks the first one it supports.
97+
HPP supports two upstream-standard schemes:
98+
99+
### `exact`
100+
101+
Pay an **exact** amount using [EIP-3009](https://eips.ethereum.org/EIPS/eip-3009)
102+
(`transferWithAuthorization`). The buyer signs a transfer for the precise price; the facilitator
103+
submits it. Simple and final — best when the price is known up front.
104+
105+
### `upto`
106+
107+
Authorize **up to** a maximum using [Permit2](https://github.com/Uniswap/permit2), and settle the
108+
actual amount consumed (which may be less than the cap). This fits metered or usage-based pricing
109+
where the final cost isn't known until the work runs.
110+
111+
On HPP, `upto` also supports **gasless settlement**: the one-time Permit2 approval can be sponsored
112+
via [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612), so a paying agent needs **zero native ETH** —
113+
only USDC.e. See [Facilitator → Gasless settlement](./facilitator.mdx#gasless-settlement-upto).
114+
115+
> Both schemes are part of the standard x402 specification. A facilitator advertises exactly which
116+
> `(network, scheme)` pairs it supports at its `/supported` endpoint, and the seller's accepts must be
117+
> a subset of that.
118+
119+
Each payment authorization is **single-use**: it carries a unique nonce and a validity window, so a
120+
captured `X-PAYMENT` header cannot be replayed for a second charge, and the buyer signs a fresh
121+
authorization for every request.
122+
123+
## Next
124+
125+
- [Networks & Token](./networks-and-token.mdx) — the chains and the USDC.e asset.
126+
- [Quickstart: Sellers](./quickstart-sellers.mdx) / [Buyers](./quickstart-buyers.mdx) — working code.

‎x402/intro.md‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
title: x402 on HPP
3+
sidebar_label: Overview
4+
slug: /
5+
description: Accept and pay for HTTP resources with onchain stablecoins on HPP using the x402 payment protocol.
6+
---
7+
8+
# x402 on HPP
9+
10+
**x402** is an open payment protocol that revives the long-dormant HTTP `402 Payment Required`
11+
status code. It lets any HTTP endpoint charge for access with onchain stablecoins — no API keys,
12+
no accounts, no manual invoicing. A client requests a resource, receives a `402` with machine-readable
13+
payment terms, pays by signing a stablecoin authorization, and retries. Settlement happens onchain.
14+
15+
HPP runs **production x402 facilitators on both its Mainnet and Sepolia networks**, so you can
16+
monetize an API — or pay for one — using **USDC.e** with a few lines of code.
17+
18+
## Why x402
19+
20+
- **Built for agents and machines.** Payment is a single signed message on a standard HTTP
21+
response. No human-in-the-loop, no dashboard signup. AI agents can discover a price and pay it autonomously.
22+
- **No accounts, no custody.** Payment moves from the buyer's wallet to the seller's `payTo` address;
23+
HPP's facilitator never custodies funds — it only verifies the signature and submits the settlement
24+
transaction (a direct transfer for `exact`, or a Permit2 transfer for `upto`).
25+
- **Stablecoin-native.** Prices are quoted in USDC.e. What the buyer signs is what the seller receives.
26+
- **Open standard.** x402 is maintained by the [x402 Foundation](https://github.com/x402-foundation/x402),
27+
and HPP uses the same `@x402` SDK that works on Base, Polygon, and others — pointed at HPP's networks
28+
and facilitator. One small setup step registers USDC.e as HPP's default asset (shown in the quickstarts).
29+
30+
## What HPP provides
31+
32+
| Piece | What it is |
33+
| --- | --- |
34+
| **Facilitators** | Hosted `verify` / `settle` services for HPP Mainnet (`facilitator.hpp.io`) and HPP Sepolia (`facilitator-sepolia.hpp.io`). See [Facilitator](./facilitator.mdx). |
35+
| **Networks** | HPP Mainnet (`eip155:190415`) and HPP Sepolia (`eip155:181228`), recognized natively by the `@x402` SDK. See [Networks & Token](./networks-and-token.mdx). |
36+
| **Token** | USDC.e (Bridged USDC) at `0x401eCb1D350407f13ba348573E5630B83638E30D` on both chains. |
37+
| **Schemes** | `exact` (EIP-3009) and `upto` (Permit2 with optional gasless settlement). See [How it works](./how-it-works.md). |
38+
39+
## Where to go next
40+
41+
- **[How it works](./how-it-works.md)** — the `402` flow, the three roles, and the payment schemes.
42+
- **[Networks & Token](./networks-and-token.mdx)** — chain IDs, RPC endpoints, and the USDC.e asset.
43+
- **[Quickstart: Sellers](./quickstart-sellers.mdx)** — charge for an HTTP endpoint.
44+
- **[Quickstart: Buyers](./quickstart-buyers.mdx)** — pay for an x402 endpoint from a client or agent.
45+
- **[Facilitator](./facilitator.mdx)** — endpoints, supported schemes, gasless settlement, and self-hosting.

0 commit comments

Comments
 (0)