Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,26 @@ const config: Config = {
sidebarPath: false,
},
],
// x402 payment-protocol docs — a standalone product section served at /x402
// (modeled on docs.cdp.coinbase.com/x402), independent of the main HPP docs.
[
'@docusaurus/plugin-content-docs',
{
id: 'x402',
path: 'x402',
routeBasePath: 'x402',
sidebarPath: './sidebarsX402.ts',
editUrl: 'https://github.com/hpp-io/docs/tree/main/',
},
],
],
themes: [
[
'@easyops-cn/docusaurus-search-local',
{
hashed: true,
indexDocs: true,
docsRouteBasePath: ['/', 'hub', 'hpp-router'],
docsRouteBasePath: ['/', 'hub', 'hpp-router', 'x402'],
highlightSearchTermsOnTargetPage: true,
language: ['en'],
},
Expand Down Expand Up @@ -137,6 +149,13 @@ const config: Config = {
label: 'HPP Router',
position: 'right',
},
{
type: 'docSidebar',
sidebarId: 'x402Sidebar',
docsPluginId: 'x402',
label: 'x402',
position: 'right',
},
{
href: 'https://github.com/hpp-io/docs',
label: 'GitHub',
Expand Down
22 changes: 22 additions & 0 deletions sidebarsX402.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';

// Sidebar for the standalone "x402" product docs (the `x402` docs instance, served at /x402).
// Modeled on the CDP x402 docs: Overview -> concepts -> quickstarts -> facilitator -> reference.
// Add new pages here as you create them under `x402/` (the id is the file path without extension).
const sidebars: SidebarsConfig = {
x402Sidebar: [
{type: 'doc', id: 'intro', label: 'Overview'},
'how-it-works',
'networks-and-token',
{
type: 'category',
label: 'Quickstart',
collapsed: false,
items: ['quickstart-sellers', 'quickstart-buyers'],
},
'facilitator',
'sdk',
],
};

export default sidebars;
155 changes: 155 additions & 0 deletions x402/facilitator.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
title: HPP Facilitator
sidebar_label: Facilitator
description: HPP's hosted x402 facilitator — verify and settle USDC.e payments on HPP Mainnet and Sepolia, with gasless upto settlement.
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# HPP Facilitator

A **facilitator** is the service an x402 resource server delegates payment **verification** and
**onchain settlement** to. HPP operates production facilitators for both its Mainnet and Sepolia
networks, so sellers never have to run an RPC node, manage a settlement key, or hold buyer funds —
the facilitator only verifies signatures and submits the settlement transaction.

## Endpoints

| Network | Base URL |
| --- | --- |
| HPP Mainnet (`eip155:190415`) | `https://facilitator.hpp.io` |
| HPP Sepolia (`eip155:181228`) | `https://facilitator-sepolia.hpp.io` |

Each facilitator exposes the standard x402 facilitator API:

| Route | Method | Purpose |
| --- | --- | --- |
| `/supported` | `GET` | Lists the `(scheme, network)` pairs and extensions the facilitator supports. |
| `/verify` | `POST` | Verifies a signed payment payload without settling. |
| `/settle` | `POST` | Submits the payment onchain and returns a settlement receipt. |

**CORS is enabled**, so browser-based clients can call the facilitator directly.

You can confirm what a facilitator supports at any time:

```bash
curl https://facilitator.hpp.io/supported
```

```json
{
"kinds": [
{ "x402Version": 2, "scheme": "exact", "network": "eip155:190415" },
{ "x402Version": 2, "scheme": "upto", "network": "eip155:190415",
"extra": { "facilitatorAddress": "0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033" } }
],
"extensions": ["eip2612GasSponsoring"],
"signers": { "eip155:*": ["0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033"] }
}
```

The Sepolia facilitator (`https://facilitator-sepolia.hpp.io/supported`) returns the same shape with
`network: "eip155:181228"` and its own signer `0x420bd05aB1103b0F4A02B39Ca07C92677b5CFD9d`.

## Supported schemes

| Scheme | Standard | Notes |
| --- | --- | --- |
| `exact` | EIP-3009 (`transferWithAuthorization`) | Fixed-price payments. |
| `upto` | Permit2 | Authorize a maximum, settle the actual amount. Supports gasless settlement. |

Both schemes settle in **USDC.e** (`0x401eCb1D350407f13ba348573E5630B83638E30D`, 6 decimals) on both
networks. See [How it works → Payment schemes](./how-it-works.md#payment-schemes).

## Connecting to it

You don't call the facilitator directly in normal use — your resource server does. Point a
facilitator client at the right base URL:

```ts
import { HTTPFacilitatorClient } from "@x402/core/server";

// HPP Mainnet
const facilitator = new HTTPFacilitatorClient({ url: "https://facilitator.hpp.io" });
// HPP Sepolia
// const facilitator = new HTTPFacilitatorClient({ url: "https://facilitator-sepolia.hpp.io" });
```

Then register your schemes against it — see [Quickstart: Sellers](./quickstart-sellers.mdx). Buyers
never configure the facilitator at all; they discover it implicitly from the seller's `402` challenge.

## Verify and settle

`HTTPFacilitatorClient` wraps the two POST endpoints. Both take the same body — the buyer's signed
`paymentPayload` plus the `paymentRequirements` it is paying — and the SDK calls them for you during
`paymentMiddleware`. The shapes:

```jsonc
// POST /verify and POST /settle request
{
"x402Version": 2,
"paymentPayload": { /* the decoded X-PAYMENT payload the buyer signed */ },
"paymentRequirements": { /* the matching accept from the 402 */ }
}
```

```jsonc
// POST /verify response — checks the signature WITHOUT moving funds
{ "isValid": true, "payer": "0x…" }
// on failure: { "isValid": false, "invalidReason": "...", "invalidMessage": "..." }
```

```jsonc
// POST /settle response — submits the payment onchain
{
"success": true,
"transaction": "0x…", // settlement tx hash
"network": "eip155:190415",
"payer": "0x…",
"amount": "10000" // actual amount settled (for `upto`, ≤ the max)
}
// on failure: { "success": false, "errorReason": "...", "errorMessage": "...", "transaction": "0x…" }
```

In the SDK, a failed `/verify` or `/settle` surfaces **to the resource server** as `VerifyError` or
`SettleError` (exported from `@x402/core`), carrying `invalidReason` / `errorReason` for branching.
Buyers don't see these types — they get a non-2xx response instead (see
[Quickstart: Buyers → Handling failures](./quickstart-buyers.mdx#handling-failures)).

## Gasless settlement (`upto`)

For the `upto` scheme, HPP's facilitator advertises the **`eip2612GasSponsoring`** extension. This
lets the facilitator sponsor the buyer's one-time Permit2 approval via
[EIP-2612](https://eips.ethereum.org/EIPS/eip-2612), so a paying agent needs **only USDC.e and zero
native ETH** to transact.

The **sponsoring signer** — the facilitator's onchain address that pays gas and submits settlement —
is the same value shown as `signers` and as the `upto` `facilitatorAddress` in `/supported`:

| Network | Sponsoring signer (`facilitatorAddress`) |
| --- | --- |
| HPP Mainnet | `0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033` |
| HPP Sepolia | `0x420bd05aB1103b0F4A02B39Ca07C92677b5CFD9d` |

When a seller offers an `upto` route, the SDK surfaces the `facilitatorAddress` and the
`eip2612GasSponsoring` extension in the `402` challenge automatically, and a compatible buyer signs
the gasless approval path with no extra configuration.

## Self-hosting

HPP's facilitator is a deployment of the standard open-source x402 facilitator, so you are not locked
in: you can run your own and point your resource server at it instead. Use HPP's hosted endpoints to
get started, and self-host if you need custom signing keys, private RPC, or independent operations.
See the [x402 SDK & reference](./sdk.md) for the upstream packages.

## Quick reference

| Field | HPP Mainnet | HPP Sepolia |
| --- | --- | --- |
| Facilitator URL | `https://facilitator.hpp.io` | `https://facilitator-sepolia.hpp.io` |
| Network (CAIP-2) | `eip155:190415` | `eip155:181228` |
| Token (USDC.e) | `0x401eCb1D350407f13ba348573E5630B83638E30D` | `0x401eCb1D350407f13ba348573E5630B83638E30D` |
| Schemes | `exact`, `upto` | `exact`, `upto` |
| Gasless extension | `eip2612GasSponsoring` | `eip2612GasSponsoring` |
| Sponsor signer | `0xaA03c7BD2fAf554db507D78CD3bF126a3DD2E033` | `0x420bd05aB1103b0F4A02B39Ca07C92677b5CFD9d` |
126 changes: 126 additions & 0 deletions x402/how-it-works.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
title: How it works
sidebar_label: How it works
description: The x402 payment flow on HPP — the three roles, the 402 challenge, and the exact and upto payment schemes.
---

# How it works

x402 turns a normal HTTP request into a paid one using the `402 Payment Required` status code.
Nothing about the transport changes — a paid endpoint is still a regular URL that returns `402`
until a valid payment is attached.

## The three roles

- **Resource server (the seller).** An HTTP service that puts a price on one or more routes.
When an unpaid request arrives, it replies with `402` and a list of acceptable payment terms
(`accepts`). When a paid request arrives, it verifies and settles the payment, then returns the resource.
- **Client (the buyer).** A browser, a backend, or an AI agent that wants the resource. It reads the
`402`, signs a stablecoin authorization for one of the offered terms, and retries with an `X-PAYMENT` header.
- **Facilitator.** A service that the resource server delegates two jobs to: **verify** a payment
signature, and **settle** it onchain. HPP operates the facilitators so sellers never run an RPC node
or hold a settlement key. See [Facilitator](./facilitator.mdx).

## The payment flow

```text
Buyer (client) Seller (resource server) HPP Facilitator
│ │ │
│ 1. GET /paid/resource │ │
│ ───────────────────────────────► │ │
│ │ │
│ 2. 402 Payment Required │ │
│ { accepts: [ {scheme, │ │
│ network, asset, amount, │ │
│ payTo, … } ] } │ │
│ ◄─────────────────────────────── │ │
│ │ │
│ 3. sign payment authorization │ │
│ (EIP-3009 / Permit2) │ │
│ │ │
│ 4. GET /paid/resource │ │
│ X-PAYMENT: <signed payload> │ │
│ ───────────────────────────────► │ 5. verify(payload) │
│ │ ──────────────────────────────► │
│ │ ◄────────────────────────────── │
│ │ 6. run the work / serve │
│ │ 7. settle(payload) │
│ │ ──────────────────────────────► │ ──► onchain tx
│ │ ◄────────────────────────────── │
│ 8. 200 OK + resource │ │
│ X-PAYMENT-RESPONSE: <receipt>│ │
│ ◄─────────────────────────────── │ │
```

HPP's resource-server middleware uses **serve-then-settle**: it verifies the payment first, serves the
response, and settles after a successful result (`status < 400`). The buyer gets a settlement receipt
back in the `X-PAYMENT-RESPONSE` header.

## The 402 challenge

The body of the `402` response (x402 version 2) tells the buyer exactly how it may pay. Each entry in
`accepts` is one acceptable `(scheme, network)` with its price and asset:

```json
{
"x402Version": 2,
"resource": {
"url": "https://seller.example.com/paid/hello",
"description": "A paid hello-world endpoint."
},
"accepts": [
{
"scheme": "exact",
"network": "eip155:190415",
"amount": "10000",
"asset": "0x401eCb1D350407f13ba348573E5630B83638E30D",
"payTo": "0xYourReceivingAddress",
"maxTimeoutSeconds": 600,
"extra": { "name": "Bridged USDC", "version": "2" }
}
],
"extensions": {}
}
```

- `amount` is in the asset's base units — `"10000"` is `0.01` USDC.e (6 decimals).
- `extra` carries the EIP-712 domain the buyer needs to sign (`exact`), and scheme-specific data such
as the `facilitatorAddress` for gas-sponsored `upto`.
- A multi-network or multi-scheme seller returns several `accepts`; the buyer's SDK selects one (next
section). The settlement receipt comes back base64-encoded in the `X-PAYMENT-RESPONSE` header and
decodes to `{ success, transaction, network, payer, amount? }`.

## Payment schemes

A *scheme* defines how the buyer authorizes payment and how the facilitator settles it onchain. The
seller lists one or more schemes per route, in priority order; the buyer's SDK picks the first one it supports.
HPP supports two upstream-standard schemes:

### `exact`

Pay an **exact** amount using [EIP-3009](https://eips.ethereum.org/EIPS/eip-3009)
(`transferWithAuthorization`). The buyer signs a transfer for the precise price; the facilitator
submits it. Simple and final — best when the price is known up front.

### `upto`

Authorize **up to** a maximum using [Permit2](https://github.com/Uniswap/permit2), and settle the
actual amount consumed (which may be less than the cap). This fits metered or usage-based pricing
where the final cost isn't known until the work runs.

On HPP, `upto` also supports **gasless settlement**: the one-time Permit2 approval can be sponsored
via [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612), so a paying agent needs **zero native ETH** —
only USDC.e. See [Facilitator → Gasless settlement](./facilitator.mdx#gasless-settlement-upto).

> Both schemes are part of the standard x402 specification. A facilitator advertises exactly which
> `(network, scheme)` pairs it supports at its `/supported` endpoint, and the seller's accepts must be
> a subset of that.

Each payment authorization is **single-use**: it carries a unique nonce and a validity window, so a
captured `X-PAYMENT` header cannot be replayed for a second charge, and the buyer signs a fresh
authorization for every request.

## Next

- [Networks & Token](./networks-and-token.mdx) — the chains and the USDC.e asset.
- [Quickstart: Sellers](./quickstart-sellers.mdx) / [Buyers](./quickstart-buyers.mdx) — working code.
45 changes: 45 additions & 0 deletions x402/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: x402 on HPP
sidebar_label: Overview
slug: /
description: Accept and pay for HTTP resources with onchain stablecoins on HPP using the x402 payment protocol.
---

# x402 on HPP

**x402** is an open payment protocol that revives the long-dormant HTTP `402 Payment Required`
status code. It lets any HTTP endpoint charge for access with onchain stablecoins — no API keys,
no accounts, no manual invoicing. A client requests a resource, receives a `402` with machine-readable
payment terms, pays by signing a stablecoin authorization, and retries. Settlement happens onchain.

HPP runs **production x402 facilitators on both its Mainnet and Sepolia networks**, so you can
monetize an API — or pay for one — using **USDC.e** with a few lines of code.

## Why x402

- **Built for agents and machines.** Payment is a single signed message on a standard HTTP
response. No human-in-the-loop, no dashboard signup. AI agents can discover a price and pay it autonomously.
- **No accounts, no custody.** Payment moves from the buyer's wallet to the seller's `payTo` address;
HPP's facilitator never custodies funds — it only verifies the signature and submits the settlement
transaction (a direct transfer for `exact`, or a Permit2 transfer for `upto`).
- **Stablecoin-native.** Prices are quoted in USDC.e. What the buyer signs is what the seller receives.
- **Open standard.** x402 is maintained by the [x402 Foundation](https://github.com/x402-foundation/x402),
and HPP uses the same `@x402` SDK that works on Base, Polygon, and others — pointed at HPP's networks
and facilitator. One small setup step registers USDC.e as HPP's default asset (shown in the quickstarts).

## What HPP provides

| Piece | What it is |
| --- | --- |
| **Facilitators** | Hosted `verify` / `settle` services for HPP Mainnet (`facilitator.hpp.io`) and HPP Sepolia (`facilitator-sepolia.hpp.io`). See [Facilitator](./facilitator.mdx). |
| **Networks** | HPP Mainnet (`eip155:190415`) and HPP Sepolia (`eip155:181228`), recognized natively by the `@x402` SDK. See [Networks & Token](./networks-and-token.mdx). |
| **Token** | USDC.e (Bridged USDC) at `0x401eCb1D350407f13ba348573E5630B83638E30D` on both chains. |
| **Schemes** | `exact` (EIP-3009) and `upto` (Permit2 with optional gasless settlement). See [How it works](./how-it-works.md). |

## Where to go next

- **[How it works](./how-it-works.md)** — the `402` flow, the three roles, and the payment schemes.
- **[Networks & Token](./networks-and-token.mdx)** — chain IDs, RPC endpoints, and the USDC.e asset.
- **[Quickstart: Sellers](./quickstart-sellers.mdx)** — charge for an HTTP endpoint.
- **[Quickstart: Buyers](./quickstart-buyers.mdx)** — pay for an x402 endpoint from a client or agent.
- **[Facilitator](./facilitator.mdx)** — endpoints, supported schemes, gasless settlement, and self-hosting.
Loading