From dfd7614804554642f0d1ac0ec4e2c0b91c71cda1 Mon Sep 17 00:00:00 2001 From: Faris Date: Wed, 7 Jan 2026 21:13:14 -0800 Subject: [PATCH 01/12] migrate to mintlify --- .github/workflows/update-docs.yml | 81 +++ docs/AGENTS.md | 62 ++ docs/README.md | 5 +- docs/SUMMARY.md | 26 - docs/core-concepts/bazaar-discovery-layer.md | 426 ------------- docs/core-concepts/bazaar-discovery-layer.mdx | 427 +++++++++++++ docs/core-concepts/client-server.md | 5 + docs/core-concepts/facilitator.md | 5 + docs/core-concepts/http-402.md | 5 + ...pport.md => network-and-token-support.mdx} | 104 ++-- docs/core-concepts/wallet.md | 5 + docs/docs.json | 75 +++ docs/faq.md | 5 + docs/getting-started/quickstart-for-buyers.md | 373 ----------- .../getting-started/quickstart-for-buyers.mdx | 371 +++++++++++ .../getting-started/quickstart-for-sellers.md | 578 ------------------ .../quickstart-for-sellers.mdx | 569 +++++++++++++++++ docs/guides/mcp-server-with-x402.md | 5 + docs/guides/migration-v1-to-v2.md | 5 + 19 files changed, 1676 insertions(+), 1456 deletions(-) create mode 100644 .github/workflows/update-docs.yml create mode 100644 docs/AGENTS.md delete mode 100644 docs/SUMMARY.md delete mode 100644 docs/core-concepts/bazaar-discovery-layer.md create mode 100644 docs/core-concepts/bazaar-discovery-layer.mdx rename docs/core-concepts/{network-and-token-support.md => network-and-token-support.mdx} (84%) create mode 100644 docs/docs.json delete mode 100644 docs/getting-started/quickstart-for-buyers.md create mode 100644 docs/getting-started/quickstart-for-buyers.mdx delete mode 100644 docs/getting-started/quickstart-for-sellers.md create mode 100644 docs/getting-started/quickstart-for-sellers.mdx diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml new file mode 100644 index 000000000..612a3e42f --- /dev/null +++ b/.github/workflows/update-docs.yml @@ -0,0 +1,81 @@ +name: Update Docs + +on: + push: + branches: [main] + paths-ignore: + - 'docs/**' + +jobs: + update-docs: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v7 + env: + MINTLIFY_API_KEY: ${{ secrets.MINTLIFY_API_KEY }} + PROJECT_ID: ${{ secrets.MINTLIFY_PROJECT_ID }} + with: + script: | + const { owner, repo } = context.repo; + const projectId = process.env.PROJECT_ID; + const apiKey = process.env.MINTLIFY_API_KEY; + + if (!projectId || !apiKey) { + core.setFailed('Missing MINTLIFY_PROJECT_ID or MINTLIFY_API_KEY secrets'); + return; + } + + const url = `https://api.mintlify.com/v1/agent/${projectId}/job`; + const payload = { + branch: `mintlify/docs-update-${Date.now()}`, + messages: [ + { + role: 'system', + content: 'You are an action runner that updates documentation based on code changes. You should never ask questions. If you are not able to access the repository, report the error and exit.' + }, + { + role: 'user', + content: `Update the documentation for recent pushes to main:\n\nRepository: ${owner}/${repo}` + } + ], + asDraft: false + }; + + try { + const response = await fetch(url, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(payload) + }); + + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}: ${await response.text()}`); + } + + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + let buffer = ''; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split('\n'); + buffer = lines.pop() || ''; + for (const line of lines) { + if (line.trim()) { + console.log(line); + } + } + } + if (buffer.trim()) { + console.log(buffer); + } + + core.notice(`Documentation update job triggered for ${owner}/${repo}`); + } catch (error) { + core.setFailed(`Failed to create documentation update job: ${error.message}`); + } diff --git a/docs/AGENTS.md b/docs/AGENTS.md new file mode 100644 index 000000000..59310f32f --- /dev/null +++ b/docs/AGENTS.md @@ -0,0 +1,62 @@ +# Documentation Agent Instructions + +## Package Identity +- Mintlify documentation source for docs.x402.org +- MDX/Markdown files with `docs.json` as navigation configuration + +## Directory Structure +- `core-concepts/` — Protocol explanations (HTTP 402, client-server, facilitator, wallet) +- `getting-started/` — Quickstart guides for buyers and sellers (MDX files with tabs) +- `guides/` — How-to guides (MCP server, v1→v2 migration) +- `README.md` — Welcome/landing page +- `docs.json` — Mintlify navigation and configuration + +## Code-to-Doc Mapping +- Changes to `typescript/packages/core/src/` affect Core Concepts docs +- Changes to `typescript/packages/*/src/` affect SDK references and quickstart guides +- Changes to `python/x402/src/` affect Python SDK references +- Changes to `go/` affect Go SDK references +- Changes to facilitator endpoints affect quickstart guides +- Changes to `specs/` may require updates to core-concepts docs + +## Style Guidelines +- Use TypeScript for primary code examples (it's the reference SDK) +- Include error handling in all API examples +- Write for developers with 2-5 years experience +- Use MDX components (``, ``, ``, ``) for interactive content +- Show both success and error response examples for API endpoints +- Use real-world parameter values in examples (not foo/bar placeholders) + +## Conventions +- DO: Add new pages to `docs.json` navigation +- DO: Include code examples from real SDK files (not made-up snippets) +- DO: Link to relevant specs in `specs/` for protocol details +- DO: Use `` for multi-language code examples +- DO: Add frontmatter (title, description) to all pages +- DON'T: Duplicate protocol details from `specs/` — link instead +- DON'T: Add pages without updating `docs.json` +- **Git: Create PRs for review; NEVER commit directly to main** + +## Touch Points / Key Files +- `README.md` — Landing page +- `docs.json` — Navigation and configuration (MUST update when adding pages) +- `core-concepts/*.md` — Conceptual documentation +- `getting-started/*.mdx` — Quickstart guides (MDX for tab components) +- `guides/*.md` — How-to guides + +## File Extensions +- Use `.md` for standard markdown pages +- Use `.mdx` for pages with React components (Tabs, Cards, etc.) + +## Common Gotchas +- `docs.json` controls Mintlify navigation; pages not listed won't appear +- Images/diagrams go in project root `static/` directory +- Code examples should reference actual SDK file paths +- Links between pages should omit file extensions (e.g., `../core-concepts/http-402` not `../core-concepts/http-402.md`) + +## Pre-PR Checks +- All links work (no broken references) +- New pages added to `docs.json` navigation +- Code examples are from actual SDK files and compile +- Frontmatter present on all pages (title, description) +- MDX syntax is valid (run `mint dev` to verify) diff --git a/docs/README.md b/docs/README.md index b9684cef5..70b572ec9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,6 @@ --- -description: >- - This guide will help you understand x402, the open payment standard, and help - you get started building or integrating services with x402. +title: "Welcome to x402" +description: "Get started with x402, the open payment standard for HTTP APIs and AI agents" --- # Welcome to x402 diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md deleted file mode 100644 index da25f2e95..000000000 --- a/docs/SUMMARY.md +++ /dev/null @@ -1,26 +0,0 @@ -# Table of contents - -* [Welcome to x402](README.md) -* [x402 Landing Page](https://x402.org) -* [GitBook Repo (open for contributions)](https://github.com/coinbase/x402) -* [Vercel x402 Starter Template](https://vercel.com/templates/ai/x402-ai-starter) -* [FAQ](faq.md) - -## Getting Started - -* [Quickstart for Buyers](getting-started/quickstart-for-buyers.md) -* [Quickstart for Sellers](getting-started/quickstart-for-sellers.md) - -## Core Concepts - -* [HTTP 402](core-concepts/http-402.md) -* [Client / Server](core-concepts/client-server.md) -* [Facilitator](core-concepts/facilitator.md) -* [Wallet](core-concepts/wallet.md) -* [Networks & Token Support](core-concepts/network-and-token-support.md) -* [Bazaar (Discovery Layer)](core-concepts/bazaar-discovery-layer.md) - -## Guides - -* [MCP Server with x402](guides/mcp-server-with-x402.md) -* [Migration Guide: V1 to V2](guides/migration-v1-to-v2.md) diff --git a/docs/core-concepts/bazaar-discovery-layer.md b/docs/core-concepts/bazaar-discovery-layer.md deleted file mode 100644 index 7cb4b404c..000000000 --- a/docs/core-concepts/bazaar-discovery-layer.md +++ /dev/null @@ -1,426 +0,0 @@ -# Bazaar (Discovery Layer) - -The x402 Bazaar is the discovery layer for the x402 ecosystem - a machine-readable catalog that helps developers and AI agents find and integrate with x402-compatible API endpoints. Think of it as a search index for payable APIs, enabling the autonomous discovery and consumption of services. - -The x402 Bazaar is in early development. While our vision is to build the "Google for agentic endpoints," we're currently more like "Yahoo search" - functional but evolving. Features and APIs may change as we gather feedback and expand capabilities. - -### Overview - -The Bazaar solves a critical problem in the x402 ecosystem: **discoverability**. Without it, x402-compatible endpoints are like hidden stalls in a vast market. The Bazaar provides: - -* **For Buyers (API Consumers)**: Programmatically discover available x402-enabled services, understand their capabilities, pricing, and schemas -* **For Sellers (API Providers)**: Automatic visibility for your x402-enabled services to a global audience of developers and AI agents -* **For AI Agents**: Dynamic service discovery without pre-baked integrations - query, find, pay, and use - -### How It Works - -The Bazaar currently provides a simple `/list` endpoint that returns all x402-compatible services registered with the CDP facilitator. Services are automatically opted-in when they use the CDP facilitator and enable the bazaar extension, making discovery frictionless for sellers. - -**Note:** While a discovery layer is live today for the CDP Facilitator, the spec for the marketplace items is open and part of the x402 scheme, meaning any facilitator can create their own discovery layer. - -#### Basic Flow - -1. **Discovery**: Clients query the `/list` endpoint to find available services -2. **Selection**: Choose a service based on price, capabilities, and requirements -3. **Execution**: Use x402 to pay for and access the selected service -4. **No Manual Setup**: No API keys, no account creation, just discover and pay - -### API Reference - -#### List Endpoint - -Retrieve all available x402-compatible endpoints: - -```bash -GET https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources -``` - -**Note**: The recommended way to use this endpoint is to use the `useFacilitator` hook as described below. - -**Response Schema** - -Each endpoint in the list contains the following fields: - -```json -{ - "accepts": [ - { - "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", - "description": "", - "extra": { - "name": "USD Coin", - "version": "2" - }, - "maxAmountRequired": "200", - "maxTimeoutSeconds": 60, - "mimeType": "", - "network": "eip155:8453", - "outputSchema": { - "input": { - "method": "GET", - "type": "http" - }, - "output": null - }, - "payTo": "0xa2477E16dCB42E2AD80f03FE97D7F1a1646cd1c0", - "resource": "https://api.example.com/x402/weather", - "scheme": "exact" - } - ], - "lastUpdated": "2025-08-09T01:07:04.005Z", - "metadata": {}, - "resource": "https://api.example.com/x402/weather", - "type": "http", - "x402Version": 2 -} -``` - -### Quickstart for Buyers - -See the full example here for [Python](https://github.com/coinbase/x402/tree/main/examples/python/discovery) and [Node.js](https://github.com/coinbase/x402/tree/main/examples/typescript/discovery). - -#### Step 1: Discover Available Services - -Fetch the list of available x402 services using the facilitator client: - -{% tabs %} -{% tab title="TypeScript" %} -```typescript -import { HTTPFacilitatorClient } from "@x402/core/http"; -import { withBazaar } from "@x402/extensions"; - -// Create facilitator client with Bazaar discovery extension -const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://x402.org/facilitator" -}); -const client = withBazaar(facilitatorClient); - -// Fetch all available services -const response = await client.extensions.discovery.listResources({ type: "http" }); - -// NOTE: in an MCP context, you can see the full list then decide which service to use - -// Find services under $0.10 -const usdcAsset = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; -const maxPrice = 100000; // $0.10 in USDC atomic units (6 decimals) - -const affordableServices = response.items.filter(item => - item.accepts.find(paymentRequirements => - paymentRequirements.asset === usdcAsset && - Number(paymentRequirements.maxAmountRequired) < maxPrice - ) -); -``` -{% endtab %} - -{% tab title="Python" %} -```python -from x402.facilitator import FacilitatorClient - -# Set up facilitator client (defaults to https://x402.org/facilitator) -facilitator = FacilitatorClient() - -# Fetch all available services -response = await facilitator.list() - -# NOTE: in an MCP context, you can see the full list then decide which service to use - -# Find services under $0.10 -usdc_asset = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" -max_price = 100000 # $0.10 in USDC atomic units (6 decimals) - -affordable_services = [ - item - for item in response.items - if any( - payment_req.asset == usdc_asset - and int(payment_req.max_amount_required) < max_price - for payment_req in item.accepts - ) -] -``` -{% endtab %} -{% endtabs %} - -#### Step 2: Call a Discovered Service - -Once you've found a suitable service, use an x402 client to call it: - -{% tabs %} -{% tab title="TypeScript" %} -```typescript -import { wrapAxiosWithPayment, x402Client } from "@x402/axios"; -import { registerExactEvmScheme } from "@x402/evm/exact/client"; -import axios from "axios"; -import { privateKeyToAccount } from "viem/accounts"; - -// Set up your payment account -const account = privateKeyToAccount("0xYourPrivateKey"); -const client = new x402Client(); -registerExactEvmScheme(client, { signer: account }); - -// Select a service from discovery -const selectedService = affordableServices[0]; - -// Create a payment-enabled client for that service -const api = wrapAxiosWithPayment( - axios.create({ baseURL: selectedService.resource }), - client -); - -// Select the payment method of your choice -const selectedPaymentRequirements = selectedService.accepts[0]; -const inputSchema = selectedPaymentRequirements.outputSchema.input; - -// Build the request using the service's schema -const response = await api.request({ - method: inputSchema.method, - url: inputSchema.resource, - params: { location: "San Francisco" } // Based on inputSchema -}); - -console.log("Response data:", response.data); -``` -{% endtab %} - -{% tab title="Python" %} -```python -from x402.client import X402Client -from eth_account import Account - -# Set up your payment account -account = Account.from_key("0xYourPrivateKey") -client = X402Client(account) - -# Select a service from discovery -selected_service = affordable_services[0] - -# Select the payment method of your choice -selected_payment_requirements = selected_service.accepts[0] -input_schema = selected_payment_requirements.output_schema.input - -# Make the request -response = client.request( - method=input_schema.method, - url=input_schema.resource, - params={"location": "San Francisco"} # Based on input_schema -) - -print(f"Response data: {response}") -``` -{% endtab %} -{% endtabs %} - -### Quickstart for Sellers - -#### Automatic Listing with Bazaar Extension - -If your API uses the CDP facilitator for x402 payments, it's **automatically listed in the bazaar when you enable the bazaar extension with `discoverable: true`**. - -#### Adding Metadata - -To enhance your listing with descriptions and schemas, include them when setting up your x402 middleware. **You should include descriptions for each parameter to make it clear for agents to call your endpoints**: - -{% tabs %} -{% tab title="TypeScript" %} -```typescript -import { paymentMiddleware } from "@x402/express"; -import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; -import { registerExactEvmScheme } from "@x402/evm/exact/server"; -import { bazaarResourceServerExtension } from "@x402/extensions"; - -const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://x402.org/facilitator" -}); -const server = new x402ResourceServer(facilitatorClient); -registerExactEvmScheme(server); - -const routes = { - "GET /weather": { - price: "$0.001", - network: "eip155:8453", - resource: "0xYourAddress", - description: "Get current weather data for any location", - extensions: { - bazaar: { - discoverable: true, - inputSchema: { - queryParams: { - location: { - type: "string", - description: "City name or coordinates", - required: true - } - } - }, - outputSchema: { - type: "object", - properties: { - temperature: { type: "number" }, - conditions: { type: "string" }, - humidity: { type: "number" } - } - } - } - } - } -}; - -app.use(paymentMiddleware(routes, server)); -``` -{% endtab %} - -{% tab title="Python" %} -```python -from x402.middleware.fastapi import payment_middleware -from x402.facilitators import cdp_facilitator - -app.middleware("http")( - payment_middleware( - routes={ - "/weather": { - "price": "$0.001", - "network": "eip155:8453", - "resource": "0xYourAddress", - "description": "Get current weather data for any location", - "extensions": { - "bazaar": { - "discoverable": True, - "inputSchema": { - "queryParams": { - "location": { - "type": "string", - "description": "City name or coordinates", - "required": True - } - } - }, - "outputSchema": { - "type": "object", - "properties": { - "temperature": {"type": "number"}, - "conditions": {"type": "string"}, - "humidity": {"type": "number"} - } - } - } - } - } - }, - facilitator=cdp_facilitator - ) -) -``` -{% endtab %} - -{% tab title="Go" %} -```go -package main - -import ( - x402 "github.com/coinbase/x402/go" - "github.com/coinbase/x402/go/extensions/bazaar" - "github.com/coinbase/x402/go/extensions/types" - x402http "github.com/coinbase/x402/go/http" - ginmw "github.com/coinbase/x402/go/http/gin" - evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" - "github.com/gin-gonic/gin" -) - -func main() { - r := gin.Default() - - facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ - URL: "https://x402.org/facilitator", - }) - - // Create Bazaar Discovery Extension with input/output schemas - discoveryExtension, _ := bazaar.DeclareDiscoveryExtension( - bazaar.MethodGET, - map[string]interface{}{"location": "San Francisco"}, - types.JSONSchema{ - "properties": map[string]interface{}{ - "location": map[string]interface{}{ - "type": "string", - "description": "City name or coordinates", - }, - }, - "required": []string{"location"}, - }, - "", - &types.OutputConfig{ - Schema: types.JSONSchema{ - "properties": map[string]interface{}{ - "temperature": map[string]interface{}{"type": "number"}, - "conditions": map[string]interface{}{"type": "string"}, - "humidity": map[string]interface{}{"type": "number"}, - }, - }, - }, - ) - - routes := x402http.RoutesConfig{ - "GET /weather": { - Accepts: x402http.PaymentOptions{{ - Scheme: "exact", - PayTo: "0xYourAddress", - Price: "$0.001", - Network: x402.Network("eip155:8453"), - }}, - Description: "Get current weather data for any location", - Extensions: map[string]interface{}{ - types.BAZAAR: discoveryExtension, - }, - }, - } - - r.Use(ginmw.X402Payment(ginmw.Config{ - Routes: routes, - Facilitator: facilitatorClient, - Schemes: []ginmw.SchemeConfig{{ - Network: x402.Network("eip155:8453"), - Server: evm.NewExactEvmScheme(), - }}, - })) - - r.GET("/weather", func(c *gin.Context) { - location := c.DefaultQuery("location", "San Francisco") - c.JSON(200, gin.H{ - "location": location, - "temperature": 70, - "conditions": "sunny", - "humidity": 45, - }) - }) - - r.Run(":4021") -} -``` -{% endtab %} -{% endtabs %} - -### Coming Soon - -The x402 Bazaar is rapidly evolving, and your feedback helps us prioritize features. - -### Support - -* **GitHub**: [github.com/coinbase/x402](https://github.com/coinbase/x402) -* **Discord**: [Join #x402 channel](https://discord.com/invite/cdp) - -### FAQ - -**Q: How do I get my service listed?** -A: If you're using the CDP facilitator, your service is listed once you enable the bazaar extension with `discoverable: true`. - -**Q: How can I make endpoint calls more accurate?** -A: Include descriptions clearly stating what each parameter does and how to call your endpoint, but do so as succinctly as possible. - -**Q: How does pricing work?** -A: Listing is free. Services set their own prices per API call, paid via x402. - -**Q: What networks are supported?** -A: Currently Base (`eip155:8453`) and Base Sepolia (`eip155:84532`) with USDC payments. - -**Q: Can I list non-x402 services?** -A: No, only x402-compatible endpoints can be listed. See our [Quickstart for Sellers](../getting-started/quickstart-for-sellers.md) to make your API x402-compatible. diff --git a/docs/core-concepts/bazaar-discovery-layer.mdx b/docs/core-concepts/bazaar-discovery-layer.mdx new file mode 100644 index 000000000..4c6285a2b --- /dev/null +++ b/docs/core-concepts/bazaar-discovery-layer.mdx @@ -0,0 +1,427 @@ +--- +title: "Bazaar (Discovery Layer)" +description: "Discover x402-compatible API endpoints with the Bazaar discovery layer" +--- + +# Bazaar (Discovery Layer) + +The x402 Bazaar is the discovery layer for the x402 ecosystem - a machine-readable catalog that helps developers and AI agents find and integrate with x402-compatible API endpoints. Think of it as a search index for payable APIs, enabling the autonomous discovery and consumption of services. + +The x402 Bazaar is in early development. While our vision is to build the "Google for agentic endpoints," we're currently more like "Yahoo search" - functional but evolving. Features and APIs may change as we gather feedback and expand capabilities. + +### Overview + +The Bazaar solves a critical problem in the x402 ecosystem: **discoverability**. Without it, x402-compatible endpoints are like hidden stalls in a vast market. The Bazaar provides: + +* **For Buyers (API Consumers)**: Programmatically discover available x402-enabled services, understand their capabilities, pricing, and schemas +* **For Sellers (API Providers)**: Automatic visibility for your x402-enabled services to a global audience of developers and AI agents +* **For AI Agents**: Dynamic service discovery without pre-baked integrations - query, find, pay, and use + +### How It Works + +The Bazaar currently provides a simple `/list` endpoint that returns all x402-compatible services registered with the CDP facilitator. Services are automatically opted-in when they use the CDP facilitator and enable the bazaar extension, making discovery frictionless for sellers. + +**Note:** While a discovery layer is live today for the CDP Facilitator, the spec for the marketplace items is open and part of the x402 scheme, meaning any facilitator can create their own discovery layer. + +#### Basic Flow + +1. **Discovery**: Clients query the `/list` endpoint to find available services +2. **Selection**: Choose a service based on price, capabilities, and requirements +3. **Execution**: Use x402 to pay for and access the selected service +4. **No Manual Setup**: No API keys, no account creation, just discover and pay + +### API Reference + +#### List Endpoint + +Retrieve all available x402-compatible endpoints: + +```bash +GET https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources +``` + +**Note**: The recommended way to use this endpoint is to use the `useFacilitator` hook as described below. + +**Response Schema** + +Each endpoint in the list contains the following fields: + +```json +{ + "accepts": [ + { + "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + "description": "", + "extra": { + "name": "USD Coin", + "version": "2" + }, + "maxAmountRequired": "200", + "maxTimeoutSeconds": 60, + "mimeType": "", + "network": "eip155:8453", + "outputSchema": { + "input": { + "method": "GET", + "type": "http" + }, + "output": null + }, + "payTo": "0xa2477E16dCB42E2AD80f03FE97D7F1a1646cd1c0", + "resource": "https://api.example.com/x402/weather", + "scheme": "exact" + } + ], + "lastUpdated": "2025-08-09T01:07:04.005Z", + "metadata": {}, + "resource": "https://api.example.com/x402/weather", + "type": "http", + "x402Version": 2 +} +``` + +### Quickstart for Buyers + +See the full example here for [Python](https://github.com/coinbase/x402/tree/main/examples/python/discovery) and [Node.js](https://github.com/coinbase/x402/tree/main/examples/typescript/discovery). + +#### Step 1: Discover Available Services + +Fetch the list of available x402 services using the facilitator client: + + + + ```typescript + import { HTTPFacilitatorClient } from "@x402/core/http"; + import { withBazaar } from "@x402/extensions"; + + // Create facilitator client with Bazaar discovery extension + const facilitatorClient = new HTTPFacilitatorClient({ + url: "https://x402.org/facilitator" + }); + const client = withBazaar(facilitatorClient); + + // Fetch all available services + const response = await client.extensions.discovery.listResources({ type: "http" }); + + // NOTE: in an MCP context, you can see the full list then decide which service to use + + // Find services under $0.10 + const usdcAsset = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; + const maxPrice = 100000; // $0.10 in USDC atomic units (6 decimals) + + const affordableServices = response.items.filter(item => + item.accepts.find(paymentRequirements => + paymentRequirements.asset === usdcAsset && + Number(paymentRequirements.maxAmountRequired) < maxPrice + ) + ); + ``` + + + ```python + from x402.facilitator import FacilitatorClient + + # Set up facilitator client (defaults to https://x402.org/facilitator) + facilitator = FacilitatorClient() + + # Fetch all available services + response = await facilitator.list() + + # NOTE: in an MCP context, you can see the full list then decide which service to use + + # Find services under $0.10 + usdc_asset = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" + max_price = 100000 # $0.10 in USDC atomic units (6 decimals) + + affordable_services = [ + item + for item in response.items + if any( + payment_req.asset == usdc_asset + and int(payment_req.max_amount_required) < max_price + for payment_req in item.accepts + ) + ] + ``` + + + +#### Step 2: Call a Discovered Service + +Once you've found a suitable service, use an x402 client to call it: + + + + ```typescript + import { wrapAxiosWithPayment, x402Client } from "@x402/axios"; + import { registerExactEvmScheme } from "@x402/evm/exact/client"; + import axios from "axios"; + import { privateKeyToAccount } from "viem/accounts"; + + // Set up your payment account + const account = privateKeyToAccount("0xYourPrivateKey"); + const client = new x402Client(); + registerExactEvmScheme(client, { signer: account }); + + // Select a service from discovery + const selectedService = affordableServices[0]; + + // Create a payment-enabled client for that service + const api = wrapAxiosWithPayment( + axios.create({ baseURL: selectedService.resource }), + client + ); + + // Select the payment method of your choice + const selectedPaymentRequirements = selectedService.accepts[0]; + const inputSchema = selectedPaymentRequirements.outputSchema.input; + + // Build the request using the service's schema + const response = await api.request({ + method: inputSchema.method, + url: inputSchema.resource, + params: { location: "San Francisco" } // Based on inputSchema + }); + + console.log("Response data:", response.data); + ``` + + + ```python + from x402.client import X402Client + from eth_account import Account + + # Set up your payment account + account = Account.from_key("0xYourPrivateKey") + client = X402Client(account) + + # Select a service from discovery + selected_service = affordable_services[0] + + # Select the payment method of your choice + selected_payment_requirements = selected_service.accepts[0] + input_schema = selected_payment_requirements.output_schema.input + + # Make the request + response = client.request( + method=input_schema.method, + url=input_schema.resource, + params={"location": "San Francisco"} # Based on input_schema + ) + + print(f"Response data: {response}") + ``` + + + +### Quickstart for Sellers + +#### Automatic Listing with Bazaar Extension + +If your API uses the CDP facilitator for x402 payments, it's **automatically listed in the bazaar when you enable the bazaar extension with `discoverable: true`**. + +#### Adding Metadata + +To enhance your listing with descriptions and schemas, include them when setting up your x402 middleware. **You should include descriptions for each parameter to make it clear for agents to call your endpoints**: + + + + ```typescript + import { paymentMiddleware } from "@x402/express"; + import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; + import { registerExactEvmScheme } from "@x402/evm/exact/server"; + import { bazaarResourceServerExtension } from "@x402/extensions"; + + const facilitatorClient = new HTTPFacilitatorClient({ + url: "https://x402.org/facilitator" + }); + const server = new x402ResourceServer(facilitatorClient); + registerExactEvmScheme(server); + + const routes = { + "GET /weather": { + price: "$0.001", + network: "eip155:8453", + resource: "0xYourAddress", + description: "Get current weather data for any location", + extensions: { + bazaar: { + discoverable: true, + inputSchema: { + queryParams: { + location: { + type: "string", + description: "City name or coordinates", + required: true + } + } + }, + outputSchema: { + type: "object", + properties: { + temperature: { type: "number" }, + conditions: { type: "string" }, + humidity: { type: "number" } + } + } + } + } + } + }; + + app.use(paymentMiddleware(routes, server)); + ``` + + + ```python + from x402.middleware.fastapi import payment_middleware + from x402.facilitators import cdp_facilitator + + app.middleware("http")( + payment_middleware( + routes={ + "/weather": { + "price": "$0.001", + "network": "eip155:8453", + "resource": "0xYourAddress", + "description": "Get current weather data for any location", + "extensions": { + "bazaar": { + "discoverable": True, + "inputSchema": { + "queryParams": { + "location": { + "type": "string", + "description": "City name or coordinates", + "required": True + } + } + }, + "outputSchema": { + "type": "object", + "properties": { + "temperature": {"type": "number"}, + "conditions": {"type": "string"}, + "humidity": {"type": "number"} + } + } + } + } + } + }, + facilitator=cdp_facilitator + ) + ) + ``` + + + ```go + package main + + import ( + x402 "github.com/coinbase/x402/go" + "github.com/coinbase/x402/go/extensions/bazaar" + "github.com/coinbase/x402/go/extensions/types" + x402http "github.com/coinbase/x402/go/http" + ginmw "github.com/coinbase/x402/go/http/gin" + evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" + "github.com/gin-gonic/gin" + ) + + func main() { + r := gin.Default() + + facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: "https://x402.org/facilitator", + }) + + // Create Bazaar Discovery Extension with input/output schemas + discoveryExtension, _ := bazaar.DeclareDiscoveryExtension( + bazaar.MethodGET, + map[string]interface{}{"location": "San Francisco"}, + types.JSONSchema{ + "properties": map[string]interface{}{ + "location": map[string]interface{}{ + "type": "string", + "description": "City name or coordinates", + }, + }, + "required": []string{"location"}, + }, + "", + &types.OutputConfig{ + Schema: types.JSONSchema{ + "properties": map[string]interface{}{ + "temperature": map[string]interface{}{"type": "number"}, + "conditions": map[string]interface{}{"type": "string"}, + "humidity": map[string]interface{}{"type": "number"}, + }, + }, + }, + ) + + routes := x402http.RoutesConfig{ + "GET /weather": { + Accepts: x402http.PaymentOptions{{ + Scheme: "exact", + PayTo: "0xYourAddress", + Price: "$0.001", + Network: x402.Network("eip155:8453"), + }}, + Description: "Get current weather data for any location", + Extensions: map[string]interface{}{ + types.BAZAAR: discoveryExtension, + }, + }, + } + + r.Use(ginmw.X402Payment(ginmw.Config{ + Routes: routes, + Facilitator: facilitatorClient, + Schemes: []ginmw.SchemeConfig{{ + Network: x402.Network("eip155:8453"), + Server: evm.NewExactEvmScheme(), + }}, + })) + + r.GET("/weather", func(c *gin.Context) { + location := c.DefaultQuery("location", "San Francisco") + c.JSON(200, gin.H{ + "location": location, + "temperature": 70, + "conditions": "sunny", + "humidity": 45, + }) + }) + + r.Run(":4021") + } + ``` + + + +### Coming Soon + +The x402 Bazaar is rapidly evolving, and your feedback helps us prioritize features. + +### Support + +* **GitHub**: [github.com/coinbase/x402](https://github.com/coinbase/x402) +* **Discord**: [Join #x402 channel](https://discord.com/invite/cdp) + +### FAQ + +**Q: How do I get my service listed?** +A: If you're using the CDP facilitator, your service is listed once you enable the bazaar extension with `discoverable: true`. + +**Q: How can I make endpoint calls more accurate?** +A: Include descriptions clearly stating what each parameter does and how to call your endpoint, but do so as succinctly as possible. + +**Q: How does pricing work?** +A: Listing is free. Services set their own prices per API call, paid via x402. + +**Q: What networks are supported?** +A: Currently Base (`eip155:8453`) and Base Sepolia (`eip155:84532`) with USDC payments. + +**Q: Can I list non-x402 services?** +A: No, only x402-compatible endpoints can be listed. See our [Quickstart for Sellers](../getting-started/quickstart-for-sellers) to make your API x402-compatible. diff --git a/docs/core-concepts/client-server.md b/docs/core-concepts/client-server.md index 5dcd8a83d..647d1cde3 100644 --- a/docs/core-concepts/client-server.md +++ b/docs/core-concepts/client-server.md @@ -1,3 +1,8 @@ +--- +title: "Client / Server" +description: "Understanding the roles of clients (buyers) and servers (sellers) in the x402 protocol" +--- + # Client / Server This page explains the roles and responsibilities of the **client** and **server** in the x402 protocol. diff --git a/docs/core-concepts/facilitator.md b/docs/core-concepts/facilitator.md index 316c94304..ff83aa597 100644 --- a/docs/core-concepts/facilitator.md +++ b/docs/core-concepts/facilitator.md @@ -1,3 +1,8 @@ +--- +title: "Facilitator" +description: "Learn about the facilitator role in x402 for payment verification and settlement" +--- + # Facilitator This page explains the role of the **facilitator** in the x402 protocol. diff --git a/docs/core-concepts/http-402.md b/docs/core-concepts/http-402.md index 51c246f72..eb822b483 100644 --- a/docs/core-concepts/http-402.md +++ b/docs/core-concepts/http-402.md @@ -1,3 +1,8 @@ +--- +title: "HTTP 402" +description: "Understanding the HTTP 402 Payment Required status code and how x402 implements it" +--- + # HTTP 402 For decades, HTTP 402 Payment Required has been reserved for future use. x402 unlocks it, and [absolves the internet of its original sin](https://economyofbits.substack.com/p/marc-andreessens-original-sin). diff --git a/docs/core-concepts/network-and-token-support.md b/docs/core-concepts/network-and-token-support.mdx similarity index 84% rename from docs/core-concepts/network-and-token-support.md rename to docs/core-concepts/network-and-token-support.mdx index dd65108ef..9a75d1e31 100644 --- a/docs/core-concepts/network-and-token-support.md +++ b/docs/core-concepts/network-and-token-support.mdx @@ -1,3 +1,8 @@ +--- +title: "Networks & Token Support" +description: "Supported blockchain networks and tokens in x402, including Base, Solana, and USDC" +--- + # Network & Token Support This page explains which blockchain networks and tokens are supported by x402, and how to extend support to additional networks. @@ -132,11 +137,11 @@ The EIP-3009 standard is essential for x402 because it enables: | Facilitator | Networks Supported (CAIP-2) | Production Ready | Requirements | | --------------- | --------------------------------------- | ---------------- | --------------- | -| x402.org | `eip155:84532`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | ❌ Testnet only | None | -| CDP Facilitator | `eip155:8453`, `eip155:84532`, `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | ✅ | CDP API keys | -| x402.rs | `eip155:84532`, `eip155:8453`, xdc | ✅ | None | -| PayAI Facilitator | solana, solana-devnet, base, base-sepolia, polygon, polygon-amoy, avalanche, avalanche-fuji, sei, sei-testnet, peaq, iotex | ✅ | None | -| Self-hosted | Any EVM network (CAIP-2 format) | ✅ | Technical setup | +| x402.org | `eip155:84532`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | Testnet only | None | +| CDP Facilitator | `eip155:8453`, `eip155:84532`, `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | Yes | CDP API keys | +| x402.rs | `eip155:84532`, `eip155:8453`, xdc | Yes | None | +| PayAI Facilitator | solana, solana-devnet, base, base-sepolia, polygon, polygon-amoy, avalanche, avalanche-fuji, sei, sei-testnet, peaq, iotex | Yes | None | +| Self-hosted | Any EVM network (CAIP-2 format) | Yes | Technical setup | **Note**: On EVM networks, facilitators support any EIP-3009 compatible token; on Solana, facilitators support any SPL/Token-2022 token. @@ -148,51 +153,50 @@ x402 V2 uses dynamic network registration - you can support any EVM network with In V2, networks are supported through the registration pattern using CAIP-2 identifiers. No source code changes are required: -{% tabs %} -{% tab title="TypeScript" %} -```typescript -import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; -import { registerExactEvmScheme } from "@x402/evm/exact/server"; - -const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://your-facilitator.com" // Facilitator that supports your network -}); - -const server = new x402ResourceServer(facilitatorClient); -registerExactEvmScheme(server); // Registers wildcard support for all EVM chains - -// Now use any CAIP-2 network identifier in your routes: -const routes = { - "GET /api/data": { - accepts: [{ - scheme: "exact", - price: "$0.001", - network: "eip155:43114", // Avalanche mainnet - payTo: "0xYourAddress", - }], - }, -}; -``` -{% endtab %} - -{% tab title="Go" %} -```go -import ( - x402http "github.com/coinbase/x402/go/http" - evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" -) - -facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ - URL: "https://your-facilitator.com", -}) - -// Register EVM scheme - supports any CAIP-2 EVM network -schemes := []ginmw.SchemeConfig{ - {Network: x402.Network("eip155:43114"), Server: evm.NewExactEvmScheme()}, // Avalanche -} -``` -{% endtab %} -{% endtabs %} + + + ```typescript + import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; + import { registerExactEvmScheme } from "@x402/evm/exact/server"; + + const facilitatorClient = new HTTPFacilitatorClient({ + url: "https://your-facilitator.com" // Facilitator that supports your network + }); + + const server = new x402ResourceServer(facilitatorClient); + registerExactEvmScheme(server); // Registers wildcard support for all EVM chains + + // Now use any CAIP-2 network identifier in your routes: + const routes = { + "GET /api/data": { + accepts: [{ + scheme: "exact", + price: "$0.001", + network: "eip155:43114", // Avalanche mainnet + payTo: "0xYourAddress", + }], + }, + }; + ``` + + + ```go + import ( + x402http "github.com/coinbase/x402/go/http" + evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" + ) + + facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: "https://your-facilitator.com", + }) + + // Register EVM scheme - supports any CAIP-2 EVM network + schemes := []ginmw.SchemeConfig{ + {Network: x402.Network("eip155:43114"), Server: evm.NewExactEvmScheme()}, // Avalanche + } + ``` + + **Key Points:** - Use CAIP-2 format: `eip155:` for any EVM network diff --git a/docs/core-concepts/wallet.md b/docs/core-concepts/wallet.md index 90995bd94..5e37d166a 100644 --- a/docs/core-concepts/wallet.md +++ b/docs/core-concepts/wallet.md @@ -1,3 +1,8 @@ +--- +title: "Wallet" +description: "How crypto wallets work as payment mechanisms and identities in x402" +--- + # Wallet This page explains the role of the **wallet** in the x402 protocol. diff --git a/docs/docs.json b/docs/docs.json new file mode 100644 index 000000000..830093a8e --- /dev/null +++ b/docs/docs.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://mintlify.com/docs.json", + "theme": "maple", + "name": "x402", + "colors": { + "primary": "#0052FF", + "light": "#4D7CFF", + "dark": "#0039B3" + }, + + "seo": { + "metatags": { + "canonical": "https://docs.x402.org" + } + }, + "navigation": { + "global": { + "anchors": [ + { + "anchor": "x402.org", + "icon": "globe", + "href": "https://x402.org" + }, + { + "anchor": "GitHub", + "icon": "github", + "href": "https://github.com/coinbase/x402" + }, + { + "anchor": "Discord", + "icon": "discord", + "href": "https://discord.gg/cdp" + } + ] + }, + "groups": [ + { + "group": "Welcome", + "pages": ["README", "faq"] + }, + { + "group": "Getting Started", + "pages": [ + "getting-started/quickstart-for-buyers", + "getting-started/quickstart-for-sellers" + ] + }, + { + "group": "Core Concepts", + "pages": [ + "core-concepts/http-402", + "core-concepts/client-server", + "core-concepts/facilitator", + "core-concepts/wallet", + "core-concepts/network-and-token-support", + "core-concepts/bazaar-discovery-layer" + ] + }, + { + "group": "Guides", + "pages": [ + "guides/mcp-server-with-x402", + "guides/migration-v1-to-v2" + ] + } + ] + }, + "feedback": { + "thumbsRating": true, + "suggestEdit": true + }, + "search": { + "prompt": "Search x402 docs..." + } +} diff --git a/docs/faq.md b/docs/faq.md index ce9fc3095..99856ca7b 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,3 +1,8 @@ +--- +title: "FAQ" +description: "Frequently asked questions about x402, the open payment standard for HTTP" +--- + # FAQ ### General diff --git a/docs/getting-started/quickstart-for-buyers.md b/docs/getting-started/quickstart-for-buyers.md deleted file mode 100644 index bc4bf8cbd..000000000 --- a/docs/getting-started/quickstart-for-buyers.md +++ /dev/null @@ -1,373 +0,0 @@ -# Quickstart for Buyers - -This guide walks you through how to use **x402** to interact with services that require payment. By the end of this guide, you will be able to programmatically discover payment requirements, complete a payment, and access a paid resource. - -### Prerequisites - -Before you begin, ensure you have: - -* A crypto wallet with USDC (any EVM-compatible wallet) -* [Node.js](https://nodejs.org/en) and npm, [Go](https://go.dev/), or Python and pip -* A service that requires payment via x402 - -**Note**\ -We have pre-configured [examples available in our repo](https://github.com/coinbase/x402/tree/main/examples), including examples for fetch, Axios, Go, and MCP. - -### 1. Install Dependencies - -{% tabs %} -{% tab title="Node.js" %} -Install the x402 client packages: - -```bash -# For fetch-based clients -npm install @x402/fetch @x402/evm - -# For axios-based clients -npm install @x402/axios @x402/evm - -# For Solana support, also add: -npm install @x402/svm -``` -{% endtab %} - -{% tab title="Go" %} -Add the x402 Go module to your project: - -```bash -go get github.com/coinbase/x402/go -``` -{% endtab %} - -{% tab title="Python" %} -Install the [x402 package](https://pypi.org/project/x402/) - -```bash -pip install x402 -``` - -**Note:** Python SDK currently uses v1 patterns. For v2 support, use TypeScript or Go. -{% endtab %} -{% endtabs %} - -### 2. Create a Wallet Signer - -{% tabs %} -{% tab title="Node.js (viem)" %} -Install the required package: - -```bash -npm install viem -``` - -Then instantiate the wallet signer: - -```typescript -import { privateKeyToAccount } from "viem/accounts"; - -// Create a signer from private key (use environment variable) -const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); -``` -{% endtab %} - -{% tab title="Go" %} -```go -import ( - evmsigners "github.com/coinbase/x402/go/signers/evm" -) - -// Load private key from environment -evmSigner, err := evmsigners.NewClientSignerFromPrivateKey(os.Getenv("EVM_PRIVATE_KEY")) -if err != nil { - log.Fatal(err) -} -``` -{% endtab %} - -{% tab title="Python (eth-account)" %} -Install the required package: - -```bash -pip install eth_account -``` - -Then instantiate the wallet account: - -```python -from eth_account import Account - -account = Account.from_key(os.getenv("PRIVATE_KEY")) -``` -{% endtab %} -{% endtabs %} - -#### Solana (SVM) - -Use [SolanaKit](https://www.solanakit.com/) to instantiate a signer: - -```typescript -import { createKeyPairSignerFromBytes } from "@solana/kit"; -import { base58 } from "@scure/base"; - -// 64-byte base58 secret key (private + public) -const svmSigner = await createKeyPairSignerFromBytes( - base58.decode(process.env.SOLANA_PRIVATE_KEY!) -); -``` - -### 3. Make Paid Requests Automatically - -{% tabs %} -{% tab title="Fetch" %} -**@x402/fetch** extends the native `fetch` API to handle 402 responses and payment headers for you. [Full example here](https://github.com/coinbase/x402/tree/main/examples/typescript/clients/fetch) - -```typescript -import { wrapFetchWithPayment } from "@x402/fetch"; -import { x402Client, x402HTTPClient } from "@x402/core/client"; -import { registerExactEvmScheme } from "@x402/evm/exact/client"; -import { privateKeyToAccount } from "viem/accounts"; - -// Create signer -const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); - -// Create x402 client and register EVM scheme -const client = new x402Client(); -registerExactEvmScheme(client, { signer }); - -// Wrap fetch with payment handling -const fetchWithPayment = wrapFetchWithPayment(fetch, client); - -// Make request - payment is handled automatically -const response = await fetchWithPayment("https://api.example.com/paid-endpoint", { - method: "GET", -}); - -const data = await response.json(); -console.log("Response:", data); - -// Get payment receipt from response headers -if (response.ok) { - const httpClient = new x402HTTPClient(client); - const paymentResponse = httpClient.getPaymentSettleResponse( - (name) => response.headers.get(name) - ); - console.log("Payment settled:", paymentResponse); -} -``` -{% endtab %} - -{% tab title="Axios" %} -**@x402/axios** adds a payment interceptor to Axios, so your requests are retried with payment headers automatically. [Full example here](https://github.com/coinbase/x402/tree/main/examples/typescript/clients/axios) - -```typescript -import { x402Client, wrapAxiosWithPayment, x402HTTPClient } from "@x402/axios"; -import { registerExactEvmScheme } from "@x402/evm/exact/client"; -import { privateKeyToAccount } from "viem/accounts"; -import axios from "axios"; - -// Create signer -const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); - -// Create x402 client and register EVM scheme -const client = new x402Client(); -registerExactEvmScheme(client, { signer }); - -// Create an Axios instance with payment handling -const api = wrapAxiosWithPayment( - axios.create({ baseURL: "https://api.example.com" }), - client, -); - -// Make request - payment is handled automatically -const response = await api.get("/paid-endpoint"); -console.log("Response:", response.data); - -// Get payment receipt -const httpClient = new x402HTTPClient(client); -const paymentResponse = httpClient.getPaymentSettleResponse( - (name) => response.headers[name.toLowerCase()] -); -console.log("Payment settled:", paymentResponse); -``` -{% endtab %} - -{% tab title="Go" %} -[Full example here](https://github.com/coinbase/x402/tree/main/examples/go/clients/http) - -```go -package main - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "os" - "time" - - x402 "github.com/coinbase/x402/go" - x402http "github.com/coinbase/x402/go/http" - evm "github.com/coinbase/x402/go/mechanisms/evm/exact/client" - evmsigners "github.com/coinbase/x402/go/signers/evm" -) - -func main() { - url := "http://localhost:4021/weather" - - // Create EVM signer - evmSigner, _ := evmsigners.NewClientSignerFromPrivateKey(os.Getenv("EVM_PRIVATE_KEY")) - - // Create x402 client and register EVM scheme - x402Client := x402.Newx402Client(). - Register("eip155:*", evm.NewExactEvmScheme(evmSigner)) - - // Wrap HTTP client with payment handling - httpClient := x402http.WrapHTTPClientWithPayment( - http.DefaultClient, - x402http.Newx402HTTPClient(x402Client), - ) - - // Make request - payment is handled automatically - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - req, _ := http.NewRequestWithContext(ctx, "GET", url, nil) - resp, err := httpClient.Do(req) - if err != nil { - fmt.Printf("Request failed: %v\n", err) - return - } - defer resp.Body.Close() - - // Read response - var data map[string]interface{} - json.NewDecoder(resp.Body).Decode(&data) - fmt.Printf("Response: %+v\n", data) - - // Check payment response header - paymentHeader := resp.Header.Get("PAYMENT-RESPONSE") - if paymentHeader != "" { - fmt.Println("Payment settled successfully!") - } -} -``` -{% endtab %} - -{% tab title="Python" %} -**Note:** Python SDK currently uses v1 patterns. - -You can use either `httpx` or `Requests` to automatically handle 402 Payment Required responses. - -[Full HTTPX example](https://github.com/coinbase/x402/tree/main/examples/python/clients/httpx) | [Full Requests example](https://github.com/coinbase/x402/tree/main/examples/python/clients/requests) - -```python -from x402.clients.httpx import x402HttpxClient -from eth_account import Account - -# Create wallet account -account = Account.from_key(os.getenv("PRIVATE_KEY")) - -# Create client and make request -async with x402HttpxClient(account=account, base_url="https://api.example.com") as client: - response = await client.get("/protected-endpoint") - print(await response.aread()) -``` -{% endtab %} -{% endtabs %} - -### Multi-Network Client Setup - -You can register multiple payment schemes to handle different networks: - -```typescript -import { wrapFetchWithPayment } from "@x402/fetch"; -import { x402Client } from "@x402/core/client"; -import { registerExactEvmScheme } from "@x402/evm/exact/client"; -import { registerExactSvmScheme } from "@x402/svm/exact/client"; -import { privateKeyToAccount } from "viem/accounts"; -import { createKeyPairSignerFromBytes } from "@solana/kit"; -import { base58 } from "@scure/base"; - -// Create signers -const evmSigner = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); -const svmSigner = await createKeyPairSignerFromBytes( - base58.decode(process.env.SOLANA_PRIVATE_KEY!) -); - -// Create client with multiple schemes -const client = new x402Client(); -registerExactEvmScheme(client, { signer: evmSigner }); -registerExactSvmScheme(client, { signer: svmSigner }); - -const fetchWithPayment = wrapFetchWithPayment(fetch, client); - -// Now handles both EVM and Solana networks automatically! -``` - -### 4. Discover Available Services (Optional) - -Instead of hardcoding endpoints, you can use the x402 Bazaar to dynamically discover available services. This is especially powerful for building autonomous agents. - -```typescript -// Fetch available services from the Bazaar API -const response = await fetch( - "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources" -); -const services = await response.json(); - -// Filter services by criteria -const affordableServices = services.items.filter((item) => - item.accepts.some((req) => Number(req.amount) < 100000) // Under $0.10 -); - -console.log("Available services:", affordableServices); -``` - -Learn more about service discovery in the [Bazaar documentation](../core-concepts/bazaar-discovery-layer.md). - -### 5. Error Handling - -Clients will throw errors if: - -* No scheme is registered for the required network -* The request configuration is missing -* A payment has already been attempted for the request -* There is an error creating the payment header - -Common error handling: - -```typescript -try { - const response = await fetchWithPayment(url, { method: "GET" }); - // Handle success -} catch (error) { - if (error.message.includes("No scheme registered")) { - console.error("Network not supported - register the appropriate scheme"); - } else if (error.message.includes("Payment already attempted")) { - console.error("Payment failed on retry"); - } else { - console.error("Request failed:", error); - } -} -``` - -### Summary - -* Install x402 client packages (`@x402/fetch` or `@x402/axios`) and mechanism packages (`@x402/evm`, `@x402/svm`) -* Create a wallet signer -* Create an `x402Client` and register payment schemes -* Use the provided wrapper/interceptor to make paid API requests -* (Optional) Use the x402 Bazaar to discover services dynamically -* Payment flows are handled automatically for you - -*** - -**References:** - -* [@x402/fetch on npm](https://www.npmjs.com/package/@x402/fetch) -* [@x402/axios on npm](https://www.npmjs.com/package/@x402/axios) -* [@x402/evm on npm](https://www.npmjs.com/package/@x402/evm) -* [x402 Go module](https://github.com/coinbase/x402/tree/main/go) -* [x402 Bazaar documentation](../core-concepts/bazaar-discovery-layer.md) - Discover available services - -For questions or support, join our [Discord](https://discord.gg/invite/cdp). diff --git a/docs/getting-started/quickstart-for-buyers.mdx b/docs/getting-started/quickstart-for-buyers.mdx new file mode 100644 index 000000000..49441a175 --- /dev/null +++ b/docs/getting-started/quickstart-for-buyers.mdx @@ -0,0 +1,371 @@ +--- +title: "Quickstart for Buyers" +description: "Get started making paid API requests with x402" +--- + +# Quickstart for Buyers + +This guide walks you through how to use **x402** to interact with services that require payment. By the end of this guide, you will be able to programmatically discover payment requirements, complete a payment, and access a paid resource. + +### Prerequisites + +Before you begin, ensure you have: + +* A crypto wallet with USDC (any EVM-compatible wallet) +* [Node.js](https://nodejs.org/en) and npm, [Go](https://go.dev/), or Python and pip +* A service that requires payment via x402 + +**Note**\ +We have pre-configured [examples available in our repo](https://github.com/coinbase/x402/tree/main/examples), including examples for fetch, Axios, Go, and MCP. + +### 1. Install Dependencies + + + + Install the x402 client packages: + + ```bash + # For fetch-based clients + npm install @x402/fetch @x402/evm + + # For axios-based clients + npm install @x402/axios @x402/evm + + # For Solana support, also add: + npm install @x402/svm + ``` + + + Add the x402 Go module to your project: + + ```bash + go get github.com/coinbase/x402/go + ``` + + + Install the [x402 package](https://pypi.org/project/x402/) + + ```bash + pip install x402 + ``` + + **Note:** Python SDK currently uses v1 patterns. For v2 support, use TypeScript or Go. + + + +### 2. Create a Wallet Signer + + + + Install the required package: + + ```bash + npm install viem + ``` + + Then instantiate the wallet signer: + + ```typescript + import { privateKeyToAccount } from "viem/accounts"; + + // Create a signer from private key (use environment variable) + const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); + ``` + + + ```go + import ( + evmsigners "github.com/coinbase/x402/go/signers/evm" + ) + + // Load private key from environment + evmSigner, err := evmsigners.NewClientSignerFromPrivateKey(os.Getenv("EVM_PRIVATE_KEY")) + if err != nil { + log.Fatal(err) + } + ``` + + + Install the required package: + + ```bash + pip install eth_account + ``` + + Then instantiate the wallet account: + + ```python + from eth_account import Account + + account = Account.from_key(os.getenv("PRIVATE_KEY")) + ``` + + + +#### Solana (SVM) + +Use [SolanaKit](https://www.solanakit.com/) to instantiate a signer: + +```typescript +import { createKeyPairSignerFromBytes } from "@solana/kit"; +import { base58 } from "@scure/base"; + +// 64-byte base58 secret key (private + public) +const svmSigner = await createKeyPairSignerFromBytes( + base58.decode(process.env.SOLANA_PRIVATE_KEY!) +); +``` + +### 3. Make Paid Requests Automatically + + + + **@x402/fetch** extends the native `fetch` API to handle 402 responses and payment headers for you. [Full example here](https://github.com/coinbase/x402/tree/main/examples/typescript/clients/fetch) + + ```typescript + import { wrapFetchWithPayment } from "@x402/fetch"; + import { x402Client, x402HTTPClient } from "@x402/core/client"; + import { registerExactEvmScheme } from "@x402/evm/exact/client"; + import { privateKeyToAccount } from "viem/accounts"; + + // Create signer + const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); + + // Create x402 client and register EVM scheme + const client = new x402Client(); + registerExactEvmScheme(client, { signer }); + + // Wrap fetch with payment handling + const fetchWithPayment = wrapFetchWithPayment(fetch, client); + + // Make request - payment is handled automatically + const response = await fetchWithPayment("https://api.example.com/paid-endpoint", { + method: "GET", + }); + + const data = await response.json(); + console.log("Response:", data); + + // Get payment receipt from response headers + if (response.ok) { + const httpClient = new x402HTTPClient(client); + const paymentResponse = httpClient.getPaymentSettleResponse( + (name) => response.headers.get(name) + ); + console.log("Payment settled:", paymentResponse); + } + ``` + + + **@x402/axios** adds a payment interceptor to Axios, so your requests are retried with payment headers automatically. [Full example here](https://github.com/coinbase/x402/tree/main/examples/typescript/clients/axios) + + ```typescript + import { x402Client, wrapAxiosWithPayment, x402HTTPClient } from "@x402/axios"; + import { registerExactEvmScheme } from "@x402/evm/exact/client"; + import { privateKeyToAccount } from "viem/accounts"; + import axios from "axios"; + + // Create signer + const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); + + // Create x402 client and register EVM scheme + const client = new x402Client(); + registerExactEvmScheme(client, { signer }); + + // Create an Axios instance with payment handling + const api = wrapAxiosWithPayment( + axios.create({ baseURL: "https://api.example.com" }), + client, + ); + + // Make request - payment is handled automatically + const response = await api.get("/paid-endpoint"); + console.log("Response:", response.data); + + // Get payment receipt + const httpClient = new x402HTTPClient(client); + const paymentResponse = httpClient.getPaymentSettleResponse( + (name) => response.headers[name.toLowerCase()] + ); + console.log("Payment settled:", paymentResponse); + ``` + + + [Full example here](https://github.com/coinbase/x402/tree/main/examples/go/clients/http) + + ```go + package main + + import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "time" + + x402 "github.com/coinbase/x402/go" + x402http "github.com/coinbase/x402/go/http" + evm "github.com/coinbase/x402/go/mechanisms/evm/exact/client" + evmsigners "github.com/coinbase/x402/go/signers/evm" + ) + + func main() { + url := "http://localhost:4021/weather" + + // Create EVM signer + evmSigner, _ := evmsigners.NewClientSignerFromPrivateKey(os.Getenv("EVM_PRIVATE_KEY")) + + // Create x402 client and register EVM scheme + x402Client := x402.Newx402Client(). + Register("eip155:*", evm.NewExactEvmScheme(evmSigner)) + + // Wrap HTTP client with payment handling + httpClient := x402http.WrapHTTPClientWithPayment( + http.DefaultClient, + x402http.Newx402HTTPClient(x402Client), + ) + + // Make request - payment is handled automatically + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + req, _ := http.NewRequestWithContext(ctx, "GET", url, nil) + resp, err := httpClient.Do(req) + if err != nil { + fmt.Printf("Request failed: %v\n", err) + return + } + defer resp.Body.Close() + + // Read response + var data map[string]interface{} + json.NewDecoder(resp.Body).Decode(&data) + fmt.Printf("Response: %+v\n", data) + + // Check payment response header + paymentHeader := resp.Header.Get("PAYMENT-RESPONSE") + if paymentHeader != "" { + fmt.Println("Payment settled successfully!") + } + } + ``` + + + **Note:** Python SDK currently uses v1 patterns. + + You can use either `httpx` or `Requests` to automatically handle 402 Payment Required responses. + + [Full HTTPX example](https://github.com/coinbase/x402/tree/main/examples/python/clients/httpx) | [Full Requests example](https://github.com/coinbase/x402/tree/main/examples/python/clients/requests) + + ```python + from x402.clients.httpx import x402HttpxClient + from eth_account import Account + + # Create wallet account + account = Account.from_key(os.getenv("PRIVATE_KEY")) + + # Create client and make request + async with x402HttpxClient(account=account, base_url="https://api.example.com") as client: + response = await client.get("/protected-endpoint") + print(await response.aread()) + ``` + + + +### Multi-Network Client Setup + +You can register multiple payment schemes to handle different networks: + +```typescript +import { wrapFetchWithPayment } from "@x402/fetch"; +import { x402Client } from "@x402/core/client"; +import { registerExactEvmScheme } from "@x402/evm/exact/client"; +import { registerExactSvmScheme } from "@x402/svm/exact/client"; +import { privateKeyToAccount } from "viem/accounts"; +import { createKeyPairSignerFromBytes } from "@solana/kit"; +import { base58 } from "@scure/base"; + +// Create signers +const evmSigner = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); +const svmSigner = await createKeyPairSignerFromBytes( + base58.decode(process.env.SOLANA_PRIVATE_KEY!) +); + +// Create client with multiple schemes +const client = new x402Client(); +registerExactEvmScheme(client, { signer: evmSigner }); +registerExactSvmScheme(client, { signer: svmSigner }); + +const fetchWithPayment = wrapFetchWithPayment(fetch, client); + +// Now handles both EVM and Solana networks automatically! +``` + +### 4. Discover Available Services (Optional) + +Instead of hardcoding endpoints, you can use the x402 Bazaar to dynamically discover available services. This is especially powerful for building autonomous agents. + +```typescript +// Fetch available services from the Bazaar API +const response = await fetch( + "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources" +); +const services = await response.json(); + +// Filter services by criteria +const affordableServices = services.items.filter((item) => + item.accepts.some((req) => Number(req.amount) < 100000) // Under $0.10 +); + +console.log("Available services:", affordableServices); +``` + +Learn more about service discovery in the [Bazaar documentation](../core-concepts/bazaar-discovery-layer). + +### 5. Error Handling + +Clients will throw errors if: + +* No scheme is registered for the required network +* The request configuration is missing +* A payment has already been attempted for the request +* There is an error creating the payment header + +Common error handling: + +```typescript +try { + const response = await fetchWithPayment(url, { method: "GET" }); + // Handle success +} catch (error) { + if (error.message.includes("No scheme registered")) { + console.error("Network not supported - register the appropriate scheme"); + } else if (error.message.includes("Payment already attempted")) { + console.error("Payment failed on retry"); + } else { + console.error("Request failed:", error); + } +} +``` + +### Summary + +* Install x402 client packages (`@x402/fetch` or `@x402/axios`) and mechanism packages (`@x402/evm`, `@x402/svm`) +* Create a wallet signer +* Create an `x402Client` and register payment schemes +* Use the provided wrapper/interceptor to make paid API requests +* (Optional) Use the x402 Bazaar to discover services dynamically +* Payment flows are handled automatically for you + +*** + +**References:** + +* [@x402/fetch on npm](https://www.npmjs.com/package/@x402/fetch) +* [@x402/axios on npm](https://www.npmjs.com/package/@x402/axios) +* [@x402/evm on npm](https://www.npmjs.com/package/@x402/evm) +* [x402 Go module](https://github.com/coinbase/x402/tree/main/go) +* [x402 Bazaar documentation](../core-concepts/bazaar-discovery-layer) - Discover available services + +For questions or support, join our [Discord](https://discord.gg/cdp). diff --git a/docs/getting-started/quickstart-for-sellers.md b/docs/getting-started/quickstart-for-sellers.md deleted file mode 100644 index 86ec1295f..000000000 --- a/docs/getting-started/quickstart-for-sellers.md +++ /dev/null @@ -1,578 +0,0 @@ -# Quickstart for Sellers - -This guide walks you through integrating with **x402** to enable payments for your API or service. By the end, your API will be able to charge buyers and AI agents for access. - -**Note:** This quickstart begins with testnet configuration for safe testing. When you're ready for production, see [Running on Mainnet](#running-on-mainnet) for the simple changes needed to accept real payments on Base (EVM) and Solana networks. - -### Prerequisites - -Before you begin, ensure you have: - -* A crypto wallet to receive funds (any EVM-compatible wallet) -* [Node.js](https://nodejs.org/en) and npm, [Go](https://go.dev/), or Python and pip installed -* An existing API or server - -**Note:** The Python SDK is currently under development for x402 v2. For immediate v2 support, use TypeScript or Go. - -**Note**\ -We have pre-configured examples available in our repo for both [Node.js](https://github.com/coinbase/x402/tree/main/examples/typescript/servers) and [Go](https://github.com/coinbase/x402/tree/main/examples/go/servers). We also have an [advanced example](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/advanced) that shows how to use the x402 SDKs to build a more complex payment flow. - -### 1. Install Dependencies - -{% tabs %} -{% tab title="Express" %} -Install the [x402 Express middleware package](https://www.npmjs.com/package/@x402/express). - -```bash -npm install @x402/express @x402/core @x402/evm -``` -{% endtab %} - -{% tab title="Next.js" %} -Install the [x402 Next.js middleware package](https://www.npmjs.com/package/@x402/next). - -```bash -npm install @x402/next @x402/core @x402/evm -``` -{% endtab %} - -{% tab title="Hono" %} -Install the [x402 Hono middleware package](https://www.npmjs.com/package/@x402/hono). - -```bash -npm install @x402/hono @x402/core @x402/evm -``` -{% endtab %} - -{% tab title="Go" %} -Add the x402 Go module to your project: - -```bash -go get github.com/coinbase/x402/go -``` -{% endtab %} - -{% tab title="FastAPI" %} -[Install the x402 Python package](https://pypi.org/project/x402/) - -```bash -pip install x402 -``` - -**Note:** Python SDK currently uses v1 patterns. -{% endtab %} - -{% tab title="Flask" %} -[Install the x402 Python package](https://pypi.org/project/x402/) - -```bash -pip install x402 -``` - -**Note:** Python SDK currently uses v1 patterns. -{% endtab %} -{% endtabs %} - -### 2. Add Payment Middleware - -Integrate the payment middleware into your application. You will need to provide: - -* The Facilitator URL or facilitator client. For testing, use `https://x402.org/facilitator` which works on Base Sepolia and Solana devnet. - * For mainnet setup, see [Running on Mainnet](#running-on-mainnet) -* The routes you want to protect. -* Your receiving wallet address. - -{% tabs %} -{% tab title="Express" %} -Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/express). - -```typescript -import express from "express"; -import { paymentMiddleware } from "@x402/express"; -import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; -import { registerExactEvmScheme } from "@x402/evm/exact/server"; - -const app = express(); - -// Your receiving wallet address -const payTo = "0xYourAddress"; - -// Create facilitator client (testnet) -const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://x402.org/facilitator" -}); - -// Create resource server and register EVM scheme -const server = new x402ResourceServer(facilitatorClient); -registerExactEvmScheme(server); - -app.use( - paymentMiddleware( - { - "GET /weather": { - accepts: [ - { - scheme: "exact", - price: "$0.001", // USDC amount in dollars - network: "eip155:84532", // Base Sepolia (CAIP-2 format) - payTo, - }, - ], - description: "Get current weather data for any location", - mimeType: "application/json", - }, - }, - server, - ), -); - -// Implement your route -app.get("/weather", (req, res) => { - res.send({ - report: { - weather: "sunny", - temperature: 70, - }, - }); -}); - -app.listen(4021, () => { - console.log(`Server listening at http://localhost:4021`); -}); -``` -{% endtab %} - -{% tab title="Next.js" %} -Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/typescript/fullstack/next). - -```typescript -// middleware.ts -import { paymentProxy } from "@x402/next"; -import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; -import { registerExactEvmScheme } from "@x402/evm/exact/server"; - -const payTo = "0xYourAddress"; - -const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://x402.org/facilitator" -}); - -const server = new x402ResourceServer(facilitatorClient); -registerExactEvmScheme(server); - -export const middleware = paymentProxy( - { - "/api/protected": { - accepts: [ - { - scheme: "exact", - price: "$0.01", - network: "eip155:84532", - payTo, - }, - ], - description: "Access to protected content", - mimeType: "application/json", - }, - }, - server, -); - -export const config = { - matcher: ["/api/protected/:path*"], -}; -``` -{% endtab %} - -{% tab title="Hono" %} -Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/hono). - -```typescript -import { Hono } from "hono"; -import { serve } from "@hono/node-server"; -import { paymentMiddleware } from "@x402/hono"; -import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; -import { registerExactEvmScheme } from "@x402/evm/exact/server"; - -const app = new Hono(); -const payTo = "0xYourAddress"; - -const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://x402.org/facilitator" -}); - -const server = new x402ResourceServer(facilitatorClient); -registerExactEvmScheme(server); - -app.use( - paymentMiddleware( - { - "/protected-route": { - accepts: [ - { - scheme: "exact", - price: "$0.10", - network: "eip155:84532", - payTo, - }, - ], - description: "Access to premium content", - mimeType: "application/json", - }, - }, - server, - ), -); - -app.get("/protected-route", (c) => { - return c.json({ message: "This content is behind a paywall" }); -}); - -serve({ fetch: app.fetch, port: 3000 }); -``` -{% endtab %} - -{% tab title="Go (Gin)" %} -Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/go/servers/gin). - -```go -package main - -import ( - "net/http" - "time" - - x402 "github.com/coinbase/x402/go" - x402http "github.com/coinbase/x402/go/http" - ginmw "github.com/coinbase/x402/go/http/gin" - evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" - "github.com/gin-gonic/gin" -) - -func main() { - payTo := "0xYourAddress" - network := x402.Network("eip155:84532") // Base Sepolia (CAIP-2 format) - - r := gin.Default() - - // Create facilitator client - facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ - URL: "https://x402.org/facilitator", - }) - - // Apply x402 payment middleware - r.Use(ginmw.X402Payment(ginmw.Config{ - Routes: x402http.RoutesConfig{ - "GET /weather": { - Accepts: x402http.PaymentOptions{ - { - Scheme: "exact", - PayTo: payTo, - Price: "$0.001", - Network: network, - }, - }, - Description: "Get weather data for a city", - MimeType: "application/json", - }, - }, - Facilitator: facilitatorClient, - Schemes: []ginmw.SchemeConfig{ - {Network: network, Server: evm.NewExactEvmScheme()}, - }, - SyncFacilitatorOnStart: true, - Timeout: 30 * time.Second, - })) - - // Protected endpoint - r.GET("/weather", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "weather": "sunny", - "temperature": 70, - }) - }) - - r.Run(":4021") -} -``` -{% endtab %} - -{% tab title="FastAPI" %} -Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/python/legacy). - -**Note:** Python SDK currently uses v1 patterns with string network identifiers. - -```python -from typing import Any, Dict -from fastapi import FastAPI -from x402.fastapi.middleware import require_payment - -app = FastAPI() - -# Apply payment middleware to specific routes -app.middleware("http")( - require_payment( - path="/weather", - price="$0.001", - pay_to_address="0xYourAddress", - network="base-sepolia", # v1 string identifier - ) -) - -@app.get("/weather") -async def get_weather() -> Dict[str, Any]: - return { - "report": { - "weather": "sunny", - "temperature": 70, - } - } -``` -{% endtab %} - -{% tab title="Flask" %} -Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/python/legacy). - -**Note:** Python SDK currently uses v1 patterns with string network identifiers. - -```python -from flask import Flask -from x402.flask.middleware import PaymentMiddleware - -app = Flask(__name__) - -# Initialize payment middleware -payment_middleware = PaymentMiddleware(app) - -# Apply payment middleware to specific routes -payment_middleware.add( - path="/weather", - price="$0.001", - pay_to_address="0xYourAddress", - network="base-sepolia", # v1 string identifier -) -``` -{% endtab %} -{% endtabs %} - -**Route Configuration Interface:** - -```typescript -interface RouteConfig { - accepts: Array<{ - scheme: string; // Payment scheme (e.g., "exact") - price: string; // Price in dollars (e.g., "$0.01") - network: string; // Network in CAIP-2 format (e.g., "eip155:84532") - payTo: string; // Your wallet address - }>; - description?: string; // Description of the resource - mimeType?: string; // MIME type of the response - extensions?: object; // Optional extensions (e.g., Bazaar) -} -``` - -When a request is made to these routes without payment, your server will respond with the HTTP 402 Payment Required code and payment instructions. - -### 3. Test Your Integration - -To verify: - -1. Make a request to your endpoint (e.g., `curl http://localhost:4021/weather`). -2. The server responds with a 402 Payment Required, including payment instructions in the `PAYMENT-REQUIRED` header. -3. Complete the payment using a compatible client, wallet, or automated agent. This typically involves signing a payment payload, which is handled by the client SDK detailed in the [Quickstart for Buyers](quickstart-for-buyers.md). -4. Retry the request, this time including the `PAYMENT-SIGNATURE` header containing the cryptographic proof of payment. -5. The server verifies the payment via the facilitator and, if valid, returns your actual API response (e.g., `{ "data": "Your paid API response." }`). - -### 4. Enhance Discovery with Metadata (Recommended) - -When using the CDP facilitator, your endpoints can be listed in the [x402 Bazaar](../core-concepts/bazaar-discovery-layer.md), our discovery layer that helps buyers and AI agents find services. To enable discovery: - -```typescript -{ - "GET /weather": { - accepts: [ - { - scheme: "exact", - price: "$0.001", - network: "eip155:8453", - payTo: "0xYourAddress", - }, - ], - description: "Get real-time weather data including temperature, conditions, and humidity", - mimeType: "application/json", - extensions: { - bazaar: { - discoverable: true, - category: "weather", - tags: ["forecast", "real-time"], - }, - }, - }, -} -``` - -Learn more about the discovery layer in the [Bazaar documentation](../core-concepts/bazaar-discovery-layer.md). - -### 5. Error Handling - -* If you run into trouble, check out the examples in the [repo](https://github.com/coinbase/x402/tree/main/examples) for more context and full code. -* Run `npm install` or `go mod tidy` to install dependencies - ---- - -## Running on Mainnet - -Once you've tested your integration on testnet, you're ready to accept real payments on mainnet. - -### 1. Update the Facilitator URL - -For mainnet, use the CDP facilitator: - -{% tabs %} -{% tab title="Node.js" %} -```typescript -const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://api.cdp.coinbase.com/platform/v2/x402" -}); -``` -{% endtab %} - -{% tab title="Go" %} -```go -facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ - URL: "https://api.cdp.coinbase.com/platform/v2/x402", -}) -``` -{% endtab %} -{% endtabs %} - -### 2. Update Your Network Identifier - -Change from testnet to mainnet network identifiers: - -{% tabs %} -{% tab title="Base Mainnet" %} -```typescript -// Testnet → Mainnet -network: "eip155:8453", // Base mainnet (was eip155:84532) -``` -{% endtab %} - -{% tab title="Solana Mainnet" %} -```typescript -// Testnet → Mainnet -network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // Solana mainnet - -// For Solana, use a Solana wallet address (base58 format) -payTo: "YourSolanaWalletAddress", -``` -{% endtab %} - -{% tab title="Multi-Network" %} -```typescript -// Support multiple networks on the same endpoint -{ - "GET /weather": { - accepts: [ - { - scheme: "exact", - price: "$0.001", - network: "eip155:8453", // Base mainnet - payTo: "0xYourEvmAddress", - }, - { - scheme: "exact", - price: "$0.001", - network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // Solana mainnet - payTo: "YourSolanaAddress", - }, - ], - description: "Weather data", - }, -} -``` -{% endtab %} -{% endtabs %} - -### 3. Register Multiple Schemes (Multi-Network) - -For multi-network support, register both EVM and SVM schemes: - -{% tabs %} -{% tab title="Node.js" %} -```typescript -import { registerExactEvmScheme } from "@x402/evm/exact/server"; -import { registerExactSvmScheme } from "@x402/svm/exact/server"; - -const server = new x402ResourceServer(facilitatorClient); -registerExactEvmScheme(server); -registerExactSvmScheme(server); -``` -{% endtab %} - -{% tab title="Go" %} -```go -import ( - evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" - svm "github.com/coinbase/x402/go/mechanisms/svm/exact/server" -) - -r.Use(ginmw.X402Payment(ginmw.Config{ - // ... - Schemes: []ginmw.SchemeConfig{ - {Network: x402.Network("eip155:8453"), Server: evm.NewExactEvmScheme()}, - {Network: x402.Network("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"), Server: svm.NewExactSvmScheme()}, - }, -})) -``` -{% endtab %} -{% endtabs %} - -### 4. Update Your Wallet - -Make sure your receiving wallet address is a real mainnet address where you want to receive USDC payments. - -### 5. Test with Real Payments - -Before going live: -1. Test with small amounts first -2. Verify payments are arriving in your wallet -3. Monitor the facilitator for any issues - -**Warning:** Mainnet transactions involve real money. Always test thoroughly on testnet first and start with small amounts on mainnet. - ---- - -## Network Identifiers (CAIP-2) - -x402 v2 uses [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) format for network identifiers: - -| Network | CAIP-2 Identifier | -|---------|-------------------| -| Base Mainnet | `eip155:8453` | -| Base Sepolia | `eip155:84532` | -| Solana Mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | -| Solana Devnet | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | - -See [Network Support](../core-concepts/network-and-token-support.md) for the full list. - ---- - -### Next Steps - -* Looking for something more advanced? Check out the [Advanced Example](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/advanced) -* Get started as a [buyer](quickstart-for-buyers.md) -* Learn about the [Bazaar discovery layer](../core-concepts/bazaar-discovery-layer.md) - -For questions or support, join our [Discord](https://discord.gg/invite/cdp). - -### Summary - -This quickstart covered: - -* Installing the x402 SDK and relevant middleware -* Adding payment middleware to your API and configuring it -* Testing your integration -* Deploying to mainnet with CAIP-2 network identifiers - -Your API is now ready to accept crypto payments through x402. diff --git a/docs/getting-started/quickstart-for-sellers.mdx b/docs/getting-started/quickstart-for-sellers.mdx new file mode 100644 index 000000000..d2e0a2ac3 --- /dev/null +++ b/docs/getting-started/quickstart-for-sellers.mdx @@ -0,0 +1,569 @@ +--- +title: "Quickstart for Sellers" +description: "Get started accepting x402 payments for your API or service" +--- + +# Quickstart for Sellers + +This guide walks you through integrating with **x402** to enable payments for your API or service. By the end, your API will be able to charge buyers and AI agents for access. + +**Note:** This quickstart begins with testnet configuration for safe testing. When you're ready for production, see [Running on Mainnet](#running-on-mainnet) for the simple changes needed to accept real payments on Base (EVM) and Solana networks. + +### Prerequisites + +Before you begin, ensure you have: + +* A crypto wallet to receive funds (any EVM-compatible wallet) +* [Node.js](https://nodejs.org/en) and npm, [Go](https://go.dev/), or Python and pip installed +* An existing API or server + +**Note:** The Python SDK is currently under development for x402 v2. For immediate v2 support, use TypeScript or Go. + +**Note**\ +We have pre-configured examples available in our repo for both [Node.js](https://github.com/coinbase/x402/tree/main/examples/typescript/servers) and [Go](https://github.com/coinbase/x402/tree/main/examples/go/servers). We also have an [advanced example](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/advanced) that shows how to use the x402 SDKs to build a more complex payment flow. + +### 1. Install Dependencies + + + + Install the [x402 Express middleware package](https://www.npmjs.com/package/@x402/express). + + ```bash + npm install @x402/express @x402/core @x402/evm + ``` + + + Install the [x402 Next.js middleware package](https://www.npmjs.com/package/@x402/next). + + ```bash + npm install @x402/next @x402/core @x402/evm + ``` + + + Install the [x402 Hono middleware package](https://www.npmjs.com/package/@x402/hono). + + ```bash + npm install @x402/hono @x402/core @x402/evm + ``` + + + Add the x402 Go module to your project: + + ```bash + go get github.com/coinbase/x402/go + ``` + + + [Install the x402 Python package](https://pypi.org/project/x402/) + + ```bash + pip install x402 + ``` + + **Note:** Python SDK currently uses v1 patterns. + + + [Install the x402 Python package](https://pypi.org/project/x402/) + + ```bash + pip install x402 + ``` + + **Note:** Python SDK currently uses v1 patterns. + + + +### 2. Add Payment Middleware + +Integrate the payment middleware into your application. You will need to provide: + +* The Facilitator URL or facilitator client. For testing, use `https://x402.org/facilitator` which works on Base Sepolia and Solana devnet. + * For mainnet setup, see [Running on Mainnet](#running-on-mainnet) +* The routes you want to protect. +* Your receiving wallet address. + + + + Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/express). + + ```typescript + import express from "express"; + import { paymentMiddleware } from "@x402/express"; + import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; + import { registerExactEvmScheme } from "@x402/evm/exact/server"; + + const app = express(); + + // Your receiving wallet address + const payTo = "0xYourAddress"; + + // Create facilitator client (testnet) + const facilitatorClient = new HTTPFacilitatorClient({ + url: "https://x402.org/facilitator" + }); + + // Create resource server and register EVM scheme + const server = new x402ResourceServer(facilitatorClient); + registerExactEvmScheme(server); + + app.use( + paymentMiddleware( + { + "GET /weather": { + accepts: [ + { + scheme: "exact", + price: "$0.001", // USDC amount in dollars + network: "eip155:84532", // Base Sepolia (CAIP-2 format) + payTo, + }, + ], + description: "Get current weather data for any location", + mimeType: "application/json", + }, + }, + server, + ), + ); + + // Implement your route + app.get("/weather", (req, res) => { + res.send({ + report: { + weather: "sunny", + temperature: 70, + }, + }); + }); + + app.listen(4021, () => { + console.log(`Server listening at http://localhost:4021`); + }); + ``` + + + Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/typescript/fullstack/next). + + ```typescript + // middleware.ts + import { paymentProxy } from "@x402/next"; + import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; + import { registerExactEvmScheme } from "@x402/evm/exact/server"; + + const payTo = "0xYourAddress"; + + const facilitatorClient = new HTTPFacilitatorClient({ + url: "https://x402.org/facilitator" + }); + + const server = new x402ResourceServer(facilitatorClient); + registerExactEvmScheme(server); + + export const middleware = paymentProxy( + { + "/api/protected": { + accepts: [ + { + scheme: "exact", + price: "$0.01", + network: "eip155:84532", + payTo, + }, + ], + description: "Access to protected content", + mimeType: "application/json", + }, + }, + server, + ); + + export const config = { + matcher: ["/api/protected/:path*"], + }; + ``` + + + Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/hono). + + ```typescript + import { Hono } from "hono"; + import { serve } from "@hono/node-server"; + import { paymentMiddleware } from "@x402/hono"; + import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server"; + import { registerExactEvmScheme } from "@x402/evm/exact/server"; + + const app = new Hono(); + const payTo = "0xYourAddress"; + + const facilitatorClient = new HTTPFacilitatorClient({ + url: "https://x402.org/facilitator" + }); + + const server = new x402ResourceServer(facilitatorClient); + registerExactEvmScheme(server); + + app.use( + paymentMiddleware( + { + "/protected-route": { + accepts: [ + { + scheme: "exact", + price: "$0.10", + network: "eip155:84532", + payTo, + }, + ], + description: "Access to premium content", + mimeType: "application/json", + }, + }, + server, + ), + ); + + app.get("/protected-route", (c) => { + return c.json({ message: "This content is behind a paywall" }); + }); + + serve({ fetch: app.fetch, port: 3000 }); + ``` + + + Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/go/servers/gin). + + ```go + package main + + import ( + "net/http" + "time" + + x402 "github.com/coinbase/x402/go" + x402http "github.com/coinbase/x402/go/http" + ginmw "github.com/coinbase/x402/go/http/gin" + evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" + "github.com/gin-gonic/gin" + ) + + func main() { + payTo := "0xYourAddress" + network := x402.Network("eip155:84532") // Base Sepolia (CAIP-2 format) + + r := gin.Default() + + // Create facilitator client + facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: "https://x402.org/facilitator", + }) + + // Apply x402 payment middleware + r.Use(ginmw.X402Payment(ginmw.Config{ + Routes: x402http.RoutesConfig{ + "GET /weather": { + Accepts: x402http.PaymentOptions{ + { + Scheme: "exact", + PayTo: payTo, + Price: "$0.001", + Network: network, + }, + }, + Description: "Get weather data for a city", + MimeType: "application/json", + }, + }, + Facilitator: facilitatorClient, + Schemes: []ginmw.SchemeConfig{ + {Network: network, Server: evm.NewExactEvmScheme()}, + }, + SyncFacilitatorOnStart: true, + Timeout: 30 * time.Second, + })) + + // Protected endpoint + r.GET("/weather", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "weather": "sunny", + "temperature": 70, + }) + }) + + r.Run(":4021") + } + ``` + + + Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/python/legacy). + + **Note:** Python SDK currently uses v1 patterns with string network identifiers. + + ```python + from typing import Any, Dict + from fastapi import FastAPI + from x402.fastapi.middleware import require_payment + + app = FastAPI() + + # Apply payment middleware to specific routes + app.middleware("http")( + require_payment( + path="/weather", + price="$0.001", + pay_to_address="0xYourAddress", + network="base-sepolia", # v1 string identifier + ) + ) + + @app.get("/weather") + async def get_weather() -> Dict[str, Any]: + return { + "report": { + "weather": "sunny", + "temperature": 70, + } + } + ``` + + + Full example in the repo [here](https://github.com/coinbase/x402/tree/main/examples/python/legacy). + + **Note:** Python SDK currently uses v1 patterns with string network identifiers. + + ```python + from flask import Flask + from x402.flask.middleware import PaymentMiddleware + + app = Flask(__name__) + + # Initialize payment middleware + payment_middleware = PaymentMiddleware(app) + + # Apply payment middleware to specific routes + payment_middleware.add( + path="/weather", + price="$0.001", + pay_to_address="0xYourAddress", + network="base-sepolia", # v1 string identifier + ) + ``` + + + +**Route Configuration Interface:** + +```typescript +interface RouteConfig { + accepts: Array<{ + scheme: string; // Payment scheme (e.g., "exact") + price: string; // Price in dollars (e.g., "$0.01") + network: string; // Network in CAIP-2 format (e.g., "eip155:84532") + payTo: string; // Your wallet address + }>; + description?: string; // Description of the resource + mimeType?: string; // MIME type of the response + extensions?: object; // Optional extensions (e.g., Bazaar) +} +``` + +When a request is made to these routes without payment, your server will respond with the HTTP 402 Payment Required code and payment instructions. + +### 3. Test Your Integration + +To verify: + +1. Make a request to your endpoint (e.g., `curl http://localhost:4021/weather`). +2. The server responds with a 402 Payment Required, including payment instructions in the `PAYMENT-REQUIRED` header. +3. Complete the payment using a compatible client, wallet, or automated agent. This typically involves signing a payment payload, which is handled by the client SDK detailed in the [Quickstart for Buyers](quickstart-for-buyers). +4. Retry the request, this time including the `PAYMENT-SIGNATURE` header containing the cryptographic proof of payment. +5. The server verifies the payment via the facilitator and, if valid, returns your actual API response (e.g., `{ "data": "Your paid API response." }`). + +### 4. Enhance Discovery with Metadata (Recommended) + +When using the CDP facilitator, your endpoints can be listed in the [x402 Bazaar](../core-concepts/bazaar-discovery-layer), our discovery layer that helps buyers and AI agents find services. To enable discovery: + +```typescript +{ + "GET /weather": { + accepts: [ + { + scheme: "exact", + price: "$0.001", + network: "eip155:8453", + payTo: "0xYourAddress", + }, + ], + description: "Get real-time weather data including temperature, conditions, and humidity", + mimeType: "application/json", + extensions: { + bazaar: { + discoverable: true, + category: "weather", + tags: ["forecast", "real-time"], + }, + }, + }, +} +``` + +Learn more about the discovery layer in the [Bazaar documentation](../core-concepts/bazaar-discovery-layer). + +### 5. Error Handling + +* If you run into trouble, check out the examples in the [repo](https://github.com/coinbase/x402/tree/main/examples) for more context and full code. +* Run `npm install` or `go mod tidy` to install dependencies + +--- + +## Running on Mainnet + +Once you've tested your integration on testnet, you're ready to accept real payments on mainnet. + +### 1. Update the Facilitator URL + +For mainnet, use the CDP facilitator: + + + + ```typescript + const facilitatorClient = new HTTPFacilitatorClient({ + url: "https://api.cdp.coinbase.com/platform/v2/x402" + }); + ``` + + + ```go + facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: "https://api.cdp.coinbase.com/platform/v2/x402", + }) + ``` + + + +### 2. Update Your Network Identifier + +Change from testnet to mainnet network identifiers: + + + + ```typescript + // Testnet → Mainnet + network: "eip155:8453", // Base mainnet (was eip155:84532) + ``` + + + ```typescript + // Testnet → Mainnet + network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // Solana mainnet + + // For Solana, use a Solana wallet address (base58 format) + payTo: "YourSolanaWalletAddress", + ``` + + + ```typescript + // Support multiple networks on the same endpoint + { + "GET /weather": { + accepts: [ + { + scheme: "exact", + price: "$0.001", + network: "eip155:8453", // Base mainnet + payTo: "0xYourEvmAddress", + }, + { + scheme: "exact", + price: "$0.001", + network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // Solana mainnet + payTo: "YourSolanaAddress", + }, + ], + description: "Weather data", + }, + } + ``` + + + +### 3. Register Multiple Schemes (Multi-Network) + +For multi-network support, register both EVM and SVM schemes: + + + + ```typescript + import { registerExactEvmScheme } from "@x402/evm/exact/server"; + import { registerExactSvmScheme } from "@x402/svm/exact/server"; + + const server = new x402ResourceServer(facilitatorClient); + registerExactEvmScheme(server); + registerExactSvmScheme(server); + ``` + + + ```go + import ( + evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server" + svm "github.com/coinbase/x402/go/mechanisms/svm/exact/server" + ) + + r.Use(ginmw.X402Payment(ginmw.Config{ + // ... + Schemes: []ginmw.SchemeConfig{ + {Network: x402.Network("eip155:8453"), Server: evm.NewExactEvmScheme()}, + {Network: x402.Network("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"), Server: svm.NewExactSvmScheme()}, + }, + })) + ``` + + + +### 4. Update Your Wallet + +Make sure your receiving wallet address is a real mainnet address where you want to receive USDC payments. + +### 5. Test with Real Payments + +Before going live: +1. Test with small amounts first +2. Verify payments are arriving in your wallet +3. Monitor the facilitator for any issues + +**Warning:** Mainnet transactions involve real money. Always test thoroughly on testnet first and start with small amounts on mainnet. + +--- + +## Network Identifiers (CAIP-2) + +x402 v2 uses [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) format for network identifiers: + +| Network | CAIP-2 Identifier | +|---------|-------------------| +| Base Mainnet | `eip155:8453` | +| Base Sepolia | `eip155:84532` | +| Solana Mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | +| Solana Devnet | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | + +See [Network Support](../core-concepts/network-and-token-support) for the full list. + +--- + +### Next Steps + +* Looking for something more advanced? Check out the [Advanced Example](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/advanced) +* Get started as a [buyer](quickstart-for-buyers) +* Learn about the [Bazaar discovery layer](../core-concepts/bazaar-discovery-layer) + +For questions or support, join our [Discord](https://discord.gg/cdp). + +### Summary + +This quickstart covered: + +* Installing the x402 SDK and relevant middleware +* Adding payment middleware to your API and configuring it +* Testing your integration +* Deploying to mainnet with CAIP-2 network identifiers + +Your API is now ready to accept crypto payments through x402. diff --git a/docs/guides/mcp-server-with-x402.md b/docs/guides/mcp-server-with-x402.md index 7e428ef05..ac20296b6 100644 --- a/docs/guides/mcp-server-with-x402.md +++ b/docs/guides/mcp-server-with-x402.md @@ -1,3 +1,8 @@ +--- +title: "MCP Server with x402" +description: "Integrate x402 payments with Claude Desktop using Model Context Protocol (MCP)" +--- + # MCP Server with x402 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is a protocol for passing context between LLMs and other AI agents. This page shows how to use the x402 payment protocol with MCP to make paid API requests through an MCP server, and how to connect it to Claude Desktop. diff --git a/docs/guides/migration-v1-to-v2.md b/docs/guides/migration-v1-to-v2.md index 21323c492..407acd4ca 100644 --- a/docs/guides/migration-v1-to-v2.md +++ b/docs/guides/migration-v1-to-v2.md @@ -1,3 +1,8 @@ +--- +title: "Migration Guide: V1 to V2" +description: "Step-by-step guide to migrate from x402 V1 to V2" +--- + # Migration Guide: V1 to V2 This guide helps you migrate from x402 V1 to V2. The V2 protocol introduces standardized identifiers, improved type safety, and a more modular architecture. From b36e1caee0fe3dca410c221601c63d12e0f2bcec Mon Sep 17 00:00:00 2001 From: Faris Date: Wed, 7 Jan 2026 21:46:00 -0800 Subject: [PATCH 02/12] rename README.md to introduction.md for Mintlify compatibility --- docs/docs.json | 2 +- docs/{README.md => introduction.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/{README.md => introduction.md} (100%) diff --git a/docs/docs.json b/docs/docs.json index 830093a8e..1fe23695f 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -36,7 +36,7 @@ "groups": [ { "group": "Welcome", - "pages": ["README", "faq"] + "pages": ["introduction", "faq"] }, { "group": "Getting Started", diff --git a/docs/README.md b/docs/introduction.md similarity index 100% rename from docs/README.md rename to docs/introduction.md From 757da8bf7742dc1975480dfb2448677f65a3e7f6 Mon Sep 17 00:00:00 2001 From: Faris Date: Wed, 7 Jan 2026 21:59:07 -0800 Subject: [PATCH 03/12] add vercel starter kit to docs --- docs/docs.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/docs.json b/docs/docs.json index 1fe23695f..670a7b316 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -30,6 +30,11 @@ "anchor": "Discord", "icon": "discord", "href": "https://discord.gg/cdp" + }, + { + "anchor": "Vercel Starter", + "icon": "triangle", + "href": "https://vercel.com/templates/ai/x402-ai-starter" } ] }, From 4e454134511f53a89261b153e8e2a805788112d7 Mon Sep 17 00:00:00 2001 From: Faris Date: Wed, 7 Jan 2026 22:28:42 -0800 Subject: [PATCH 04/12] update descriptions --- docs/core-concepts/bazaar-discovery-layer.mdx | 6 ++---- docs/core-concepts/client-server.md | 6 +----- docs/core-concepts/facilitator.md | 6 +----- docs/core-concepts/http-402.md | 6 +----- docs/core-concepts/network-and-token-support.mdx | 6 +----- docs/core-concepts/wallet.md | 6 +----- docs/faq.md | 2 -- docs/getting-started/quickstart-for-buyers.mdx | 6 +----- docs/getting-started/quickstart-for-sellers.mdx | 6 +----- docs/guides/mcp-server-with-x402.md | 6 +----- docs/guides/migration-v1-to-v2.md | 6 +----- docs/introduction.md | 6 +++--- 12 files changed, 14 insertions(+), 54 deletions(-) diff --git a/docs/core-concepts/bazaar-discovery-layer.mdx b/docs/core-concepts/bazaar-discovery-layer.mdx index 4c6285a2b..74c90ca14 100644 --- a/docs/core-concepts/bazaar-discovery-layer.mdx +++ b/docs/core-concepts/bazaar-discovery-layer.mdx @@ -1,11 +1,9 @@ --- title: "Bazaar (Discovery Layer)" -description: "Discover x402-compatible API endpoints with the Bazaar discovery layer" +description: "The x402 Bazaar is the discovery layer for the x402 ecosystem - a machine-readable catalog that helps developers and AI agents find and integrate with x402-compatible API endpoints." --- -# Bazaar (Discovery Layer) - -The x402 Bazaar is the discovery layer for the x402 ecosystem - a machine-readable catalog that helps developers and AI agents find and integrate with x402-compatible API endpoints. Think of it as a search index for payable APIs, enabling the autonomous discovery and consumption of services. +Think of it as a search index for payable APIs, enabling the autonomous discovery and consumption of services. The x402 Bazaar is in early development. While our vision is to build the "Google for agentic endpoints," we're currently more like "Yahoo search" - functional but evolving. Features and APIs may change as we gather feedback and expand capabilities. diff --git a/docs/core-concepts/client-server.md b/docs/core-concepts/client-server.md index 647d1cde3..27bc1aba7 100644 --- a/docs/core-concepts/client-server.md +++ b/docs/core-concepts/client-server.md @@ -1,12 +1,8 @@ --- title: "Client / Server" -description: "Understanding the roles of clients (buyers) and servers (sellers) in the x402 protocol" +description: "This page explains the roles and responsibilities of the **client** and **server** in the x402 protocol." --- -# Client / Server - -This page explains the roles and responsibilities of the **client** and **server** in the x402 protocol. - Understanding these roles is essential to designing, building, or integrating services that use x402 for programmatic payments. **Note**\ diff --git a/docs/core-concepts/facilitator.md b/docs/core-concepts/facilitator.md index ff83aa597..ac24fe43e 100644 --- a/docs/core-concepts/facilitator.md +++ b/docs/core-concepts/facilitator.md @@ -1,12 +1,8 @@ --- title: "Facilitator" -description: "Learn about the facilitator role in x402 for payment verification and settlement" +description: "This page explains the role of the **facilitator** in the x402 protocol." --- -# Facilitator - -This page explains the role of the **facilitator** in the x402 protocol. - The facilitator is an optional but recommended service that simplifies the process of verifying and settling payments between clients (buyers) and servers (sellers). ### What is a Facilitator? diff --git a/docs/core-concepts/http-402.md b/docs/core-concepts/http-402.md index eb822b483..97f26d17b 100644 --- a/docs/core-concepts/http-402.md +++ b/docs/core-concepts/http-402.md @@ -1,12 +1,8 @@ --- title: "HTTP 402" -description: "Understanding the HTTP 402 Payment Required status code and how x402 implements it" +description: "For decades, HTTP 402 Payment Required has been reserved for future use. x402 unlocks it, and [absolves the internet of its original sin](https://economyofbits.substack.com/p/marc-andreessens-original-sin)." --- -# HTTP 402 - -For decades, HTTP 402 Payment Required has been reserved for future use. x402 unlocks it, and [absolves the internet of its original sin](https://economyofbits.substack.com/p/marc-andreessens-original-sin). - ### What is HTTP 402? [HTTP 402](https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.2) is a standard, but rarely used, HTTP response status code indicating that payment is required to access a resource. diff --git a/docs/core-concepts/network-and-token-support.mdx b/docs/core-concepts/network-and-token-support.mdx index 9a75d1e31..110fa37e1 100644 --- a/docs/core-concepts/network-and-token-support.mdx +++ b/docs/core-concepts/network-and-token-support.mdx @@ -1,12 +1,8 @@ --- title: "Networks & Token Support" -description: "Supported blockchain networks and tokens in x402, including Base, Solana, and USDC" +description: "This page explains which blockchain networks and tokens are supported by x402, and how to extend support to additional networks." --- -# Network & Token Support - -This page explains which blockchain networks and tokens are supported by x402, and how to extend support to additional networks. - ## V2 Network Identifiers (CAIP-2) x402 V2 uses [CAIP-2](https://chainagnostic.org/CAIPs/caip-2) standard network identifiers for unambiguous cross-chain support. This format follows the pattern `namespace:reference`. diff --git a/docs/core-concepts/wallet.md b/docs/core-concepts/wallet.md index 5e37d166a..971559977 100644 --- a/docs/core-concepts/wallet.md +++ b/docs/core-concepts/wallet.md @@ -1,12 +1,8 @@ --- title: "Wallet" -description: "How crypto wallets work as payment mechanisms and identities in x402" +description: "This page explains the role of the **wallet** in the x402 protocol." --- -# Wallet - -This page explains the role of the **wallet** in the x402 protocol. - In x402, a wallet is both a payment mechanism and a form of unique identity for buyers and sellers. Wallet addresses are used to send, receive, and verify payments, while also serving as identifiers within the protocol. ### Role of the Wallet diff --git a/docs/faq.md b/docs/faq.md index 99856ca7b..da7b9ffa9 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -3,8 +3,6 @@ title: "FAQ" description: "Frequently asked questions about x402, the open payment standard for HTTP" --- -# FAQ - ### General #### What _is_ x402 in a single sentence? diff --git a/docs/getting-started/quickstart-for-buyers.mdx b/docs/getting-started/quickstart-for-buyers.mdx index 49441a175..4d270809c 100644 --- a/docs/getting-started/quickstart-for-buyers.mdx +++ b/docs/getting-started/quickstart-for-buyers.mdx @@ -1,12 +1,8 @@ --- title: "Quickstart for Buyers" -description: "Get started making paid API requests with x402" +description: "This guide walks you through how to use **x402** to interact with services that require payment. By the end of this guide, you will be able to programmatically discover payment requirements, complete a payment, and access a paid resource." --- -# Quickstart for Buyers - -This guide walks you through how to use **x402** to interact with services that require payment. By the end of this guide, you will be able to programmatically discover payment requirements, complete a payment, and access a paid resource. - ### Prerequisites Before you begin, ensure you have: diff --git a/docs/getting-started/quickstart-for-sellers.mdx b/docs/getting-started/quickstart-for-sellers.mdx index d2e0a2ac3..f2f22034d 100644 --- a/docs/getting-started/quickstart-for-sellers.mdx +++ b/docs/getting-started/quickstart-for-sellers.mdx @@ -1,12 +1,8 @@ --- title: "Quickstart for Sellers" -description: "Get started accepting x402 payments for your API or service" +description: "This guide walks you through integrating with **x402** to enable payments for your API or service. By the end, your API will be able to charge buyers and AI agents for access." --- -# Quickstart for Sellers - -This guide walks you through integrating with **x402** to enable payments for your API or service. By the end, your API will be able to charge buyers and AI agents for access. - **Note:** This quickstart begins with testnet configuration for safe testing. When you're ready for production, see [Running on Mainnet](#running-on-mainnet) for the simple changes needed to accept real payments on Base (EVM) and Solana networks. ### Prerequisites diff --git a/docs/guides/mcp-server-with-x402.md b/docs/guides/mcp-server-with-x402.md index ac20296b6..3fb555e97 100644 --- a/docs/guides/mcp-server-with-x402.md +++ b/docs/guides/mcp-server-with-x402.md @@ -1,12 +1,8 @@ --- title: "MCP Server with x402" -description: "Integrate x402 payments with Claude Desktop using Model Context Protocol (MCP)" +description: "[Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is a protocol for passing context between LLMs and other AI agents. This page shows how to use the x402 payment protocol with MCP to make paid API requests through an MCP server, and how to connect it to Claude Desktop." --- -# MCP Server with x402 - -[Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is a protocol for passing context between LLMs and other AI agents. This page shows how to use the x402 payment protocol with MCP to make paid API requests through an MCP server, and how to connect it to Claude Desktop. - ### What is this integration? This guide walks you through running an MCP server that can access paid APIs using the x402 protocol. The MCP server acts as a bridge between Claude Desktop (or any MCP-compatible client) and a paid API (such as the sample weather API in the x402 repo). When Claude (or another agent) calls a tool, the MCP server will: diff --git a/docs/guides/migration-v1-to-v2.md b/docs/guides/migration-v1-to-v2.md index 407acd4ca..991284f54 100644 --- a/docs/guides/migration-v1-to-v2.md +++ b/docs/guides/migration-v1-to-v2.md @@ -1,12 +1,8 @@ --- title: "Migration Guide: V1 to V2" -description: "Step-by-step guide to migrate from x402 V1 to V2" +description: "This guide helps you migrate from x402 V1 to V2. The V2 protocol introduces standardized identifiers, improved type safety, and a more modular architecture." --- -# Migration Guide: V1 to V2 - -This guide helps you migrate from x402 V1 to V2. The V2 protocol introduces standardized identifiers, improved type safety, and a more modular architecture. - ## Overview | Aspect | V1 | V2 | diff --git a/docs/introduction.md b/docs/introduction.md index 70b572ec9..a1f998eef 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -1,10 +1,10 @@ --- title: "Welcome to x402" -description: "Get started with x402, the open payment standard for HTTP APIs and AI agents" +description: >- + This guide will help you understand x402, the open payment standard, and help + you get started building or integrating services with x402. --- -# Welcome to x402 - x402 is the open payment standard that enables services to charge for access to their APIs and content directly over HTTP. It is built around the HTTP `402 Payment Required` status code and allows clients to programmatically pay for resources without accounts, sessions, or credential management. With x402, any web service can require payment before serving a response, using crypto-native payments for speed, privacy, and efficiency. From 299af704dc9587dfa52dbe74382d7c2cd0705ba4 Mon Sep 17 00:00:00 2001 From: Faris Date: Wed, 7 Jan 2026 23:10:52 -0800 Subject: [PATCH 05/12] fix links --- docs/core-concepts/client-server.md | 4 ++-- docs/core-concepts/facilitator.md | 4 ++-- docs/faq.md | 1 - docs/getting-started/quickstart-for-sellers.mdx | 4 ++-- docs/guides/mcp-server-with-x402.md | 2 +- docs/guides/migration-v1-to-v2.md | 6 +++--- docs/introduction.md | 12 ++++++------ 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/docs/core-concepts/client-server.md b/docs/core-concepts/client-server.md index 27bc1aba7..739a98b34 100644 --- a/docs/core-concepts/client-server.md +++ b/docs/core-concepts/client-server.md @@ -70,5 +70,5 @@ This interaction is stateless, HTTP-native, and compatible with both human appli Next, explore: -* [Facilitator](facilitator.md) — how servers verify and settle payments -* [HTTP 402](http-402.md) — how servers communicate payment requirements to clients +* [Facilitator](/core-concepts/facilitator) — how servers verify and settle payments +* [HTTP 402](/core-concepts/http-402) — how servers communicate payment requirements to clients diff --git a/docs/core-concepts/facilitator.md b/docs/core-concepts/facilitator.md index ac24fe43e..89de34586 100644 --- a/docs/core-concepts/facilitator.md +++ b/docs/core-concepts/facilitator.md @@ -62,5 +62,5 @@ The facilitator acts as an independent verification and settlement layer within Next, explore: -* [Client / Server ](client-server.md)— understand the roles and responsibilities of clients and servers -* [HTTP 402](http-402.md) — understand how payment requirements are communicated to clients +* [Client / Server](/core-concepts/client-server) — understand the roles and responsibilities of clients and servers +* [HTTP 402](/core-concepts/http-402) — understand how payment requirements are communicated to clients diff --git a/docs/faq.md b/docs/faq.md index da7b9ffa9..0f3167ee3 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,6 +1,5 @@ --- title: "FAQ" -description: "Frequently asked questions about x402, the open payment standard for HTTP" --- ### General diff --git a/docs/getting-started/quickstart-for-sellers.mdx b/docs/getting-started/quickstart-for-sellers.mdx index f2f22034d..7c73fd0ae 100644 --- a/docs/getting-started/quickstart-for-sellers.mdx +++ b/docs/getting-started/quickstart-for-sellers.mdx @@ -370,7 +370,7 @@ To verify: 1. Make a request to your endpoint (e.g., `curl http://localhost:4021/weather`). 2. The server responds with a 402 Payment Required, including payment instructions in the `PAYMENT-REQUIRED` header. -3. Complete the payment using a compatible client, wallet, or automated agent. This typically involves signing a payment payload, which is handled by the client SDK detailed in the [Quickstart for Buyers](quickstart-for-buyers). +3. Complete the payment using a compatible client, wallet, or automated agent. This typically involves signing a payment payload, which is handled by the client SDK detailed in the [Quickstart for Buyers](/getting-started/quickstart-for-buyers). 4. Retry the request, this time including the `PAYMENT-SIGNATURE` header containing the cryptographic proof of payment. 5. The server verifies the payment via the facilitator and, if valid, returns your actual API response (e.g., `{ "data": "Your paid API response." }`). @@ -548,7 +548,7 @@ See [Network Support](../core-concepts/network-and-token-support) for the full l ### Next Steps * Looking for something more advanced? Check out the [Advanced Example](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/advanced) -* Get started as a [buyer](quickstart-for-buyers) +* Get started as a [buyer](/getting-started/quickstart-for-buyers) * Learn about the [Bazaar discovery layer](../core-concepts/bazaar-discovery-layer) For questions or support, join our [Discord](https://discord.gg/cdp). diff --git a/docs/guides/mcp-server-with-x402.md b/docs/guides/mcp-server-with-x402.md index 3fb555e97..bc41b00a4 100644 --- a/docs/guides/mcp-server-with-x402.md +++ b/docs/guides/mcp-server-with-x402.md @@ -309,4 +309,4 @@ The example uses these x402 v2 packages: * [See the full example in the repo](https://github.com/coinbase/x402/tree/main/examples/typescript/clients/mcp) * Try integrating with your own x402-compatible APIs * Extend the MCP server with more tools or custom logic as needed -* [Learn about building x402 servers](../getting-started/quickstart-for-sellers.md) +* [Learn about building x402 servers](/getting-started/quickstart-for-sellers) diff --git a/docs/guides/migration-v1-to-v2.md b/docs/guides/migration-v1-to-v2.md index 991284f54..4b72607f1 100644 --- a/docs/guides/migration-v1-to-v2.md +++ b/docs/guides/migration-v1-to-v2.md @@ -209,6 +209,6 @@ The facilitator supports both V1 and V2 protocols. During migration, your V2 ser ## Next Steps -- [Quickstart for Buyers](../getting-started/quickstart-for-buyers.md) -- [Quickstart for Sellers](../getting-started/quickstart-for-sellers.md) -- [Network and Token Support](../core-concepts/network-and-token-support.md) +- [Quickstart for Buyers](/getting-started/quickstart-for-buyers) +- [Quickstart for Sellers](/getting-started/quickstart-for-sellers) +- [Network and Token Support](/core-concepts/network-and-token-support) diff --git a/docs/introduction.md b/docs/introduction.md index a1f998eef..821406bbc 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -50,9 +50,9 @@ At a high level, the flow is simple: For more detail, see: -* Client / Server -* Facilitator -* HTTP 402 +* [Client / Server](/core-concepts/client-server) +* [Facilitator](/core-concepts/facilitator) +* [HTTP 402](/core-concepts/http-402) The goal is to make programmatic commerce accessible, permissionless, and developer-friendly. @@ -60,7 +60,7 @@ The goal is to make programmatic commerce accessible, permissionless, and develo Ready to build? Start here: -* [Quickstart for Sellers](getting-started/quickstart-for-sellers.md) -* [Quickstart for Buyers](getting-started/quickstart-for-buyers.md) -* [Explore Core Concepts](core-concepts/http-402.md) +* [Quickstart for Sellers](/getting-started/quickstart-for-sellers) +* [Quickstart for Buyers](/getting-started/quickstart-for-buyers) +* [Explore Core Concepts](/core-concepts/http-402) * [Join our community on Discord](https://discord.gg/invite/cdp) From b5534b9a1c11d771e7398bdb680721bf29c55283 Mon Sep 17 00:00:00 2001 From: Faris Date: Wed, 7 Jan 2026 23:41:37 -0800 Subject: [PATCH 06/12] fix legacy link --- docs/core-concepts/bazaar-discovery-layer.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core-concepts/bazaar-discovery-layer.mdx b/docs/core-concepts/bazaar-discovery-layer.mdx index 74c90ca14..1f25441f9 100644 --- a/docs/core-concepts/bazaar-discovery-layer.mdx +++ b/docs/core-concepts/bazaar-discovery-layer.mdx @@ -80,7 +80,7 @@ Each endpoint in the list contains the following fields: ### Quickstart for Buyers -See the full example here for [Python](https://github.com/coinbase/x402/tree/main/examples/python/discovery) and [Node.js](https://github.com/coinbase/x402/tree/main/examples/typescript/discovery). +See the full example here for [Python](https://github.com/coinbase/x402/tree/main/examples/python/legacy/discovery). #### Step 1: Discover Available Services @@ -422,4 +422,4 @@ A: Listing is free. Services set their own prices per API call, paid via x402. A: Currently Base (`eip155:8453`) and Base Sepolia (`eip155:84532`) with USDC payments. **Q: Can I list non-x402 services?** -A: No, only x402-compatible endpoints can be listed. See our [Quickstart for Sellers](../getting-started/quickstart-for-sellers) to make your API x402-compatible. +A: No, only x402-compatible endpoints can be listed. See our [Quickstart for Sellers](/getting-started/quickstart-for-sellers) to make your API x402-compatible. From 2315b6a29a4d24ce6f9669ceced7c0624aae5f57 Mon Sep 17 00:00:00 2001 From: Faris Date: Wed, 7 Jan 2026 23:55:23 -0800 Subject: [PATCH 07/12] nit --- docs/getting-started/quickstart-for-buyers.mdx | 4 ++-- docs/getting-started/quickstart-for-sellers.mdx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/getting-started/quickstart-for-buyers.mdx b/docs/getting-started/quickstart-for-buyers.mdx index 4d270809c..9a50d5552 100644 --- a/docs/getting-started/quickstart-for-buyers.mdx +++ b/docs/getting-started/quickstart-for-buyers.mdx @@ -317,7 +317,7 @@ const affordableServices = services.items.filter((item) => console.log("Available services:", affordableServices); ``` -Learn more about service discovery in the [Bazaar documentation](../core-concepts/bazaar-discovery-layer). +Learn more about service discovery in the [Bazaar documentation](/core-concepts/bazaar-discovery-layer). ### 5. Error Handling @@ -362,6 +362,6 @@ try { * [@x402/axios on npm](https://www.npmjs.com/package/@x402/axios) * [@x402/evm on npm](https://www.npmjs.com/package/@x402/evm) * [x402 Go module](https://github.com/coinbase/x402/tree/main/go) -* [x402 Bazaar documentation](../core-concepts/bazaar-discovery-layer) - Discover available services +* [x402 Bazaar documentation](/core-concepts/bazaar-discovery-layer) - Discover available services For questions or support, join our [Discord](https://discord.gg/cdp). diff --git a/docs/getting-started/quickstart-for-sellers.mdx b/docs/getting-started/quickstart-for-sellers.mdx index 7c73fd0ae..393b0a6b8 100644 --- a/docs/getting-started/quickstart-for-sellers.mdx +++ b/docs/getting-started/quickstart-for-sellers.mdx @@ -376,7 +376,7 @@ To verify: ### 4. Enhance Discovery with Metadata (Recommended) -When using the CDP facilitator, your endpoints can be listed in the [x402 Bazaar](../core-concepts/bazaar-discovery-layer), our discovery layer that helps buyers and AI agents find services. To enable discovery: +When using the CDP facilitator, your endpoints can be listed in the [x402 Bazaar](/core-concepts/bazaar-discovery-layer), our discovery layer that helps buyers and AI agents find services. To enable discovery: ```typescript { @@ -402,7 +402,7 @@ When using the CDP facilitator, your endpoints can be listed in the [x402 Bazaar } ``` -Learn more about the discovery layer in the [Bazaar documentation](../core-concepts/bazaar-discovery-layer). +Learn more about the discovery layer in the [Bazaar documentation](/core-concepts/bazaar-discovery-layer). ### 5. Error Handling @@ -541,7 +541,7 @@ x402 v2 uses [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/cai | Solana Mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | | Solana Devnet | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | -See [Network Support](../core-concepts/network-and-token-support) for the full list. +See [Network Support](/core-concepts/network-and-token-support) for the full list. --- @@ -549,7 +549,7 @@ See [Network Support](../core-concepts/network-and-token-support) for the full l * Looking for something more advanced? Check out the [Advanced Example](https://github.com/coinbase/x402/tree/main/examples/typescript/servers/advanced) * Get started as a [buyer](/getting-started/quickstart-for-buyers) -* Learn about the [Bazaar discovery layer](../core-concepts/bazaar-discovery-layer) +* Learn about the [Bazaar discovery layer](/core-concepts/bazaar-discovery-layer) For questions or support, join our [Discord](https://discord.gg/cdp). From 45c1a35a6b59ff8cb90cd53423d9e19f1388ede5 Mon Sep 17 00:00:00 2001 From: Faris Date: Thu, 8 Jan 2026 10:31:38 -0800 Subject: [PATCH 08/12] adjust instructions for mintlify agent --- .github/workflows/update-docs.yml | 78 +++++++++++++++++++++++++++---- docs/AGENTS.md | 44 +++++++++++++++++ 2 files changed, 114 insertions(+), 8 deletions(-) diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml index 612a3e42f..c0fc419a4 100644 --- a/.github/workflows/update-docs.yml +++ b/.github/workflows/update-docs.yml @@ -5,6 +5,11 @@ on: branches: [main] paths-ignore: - 'docs/**' + - '**/*.test.ts' + - '**/*.test.js' + - '**/__tests__/**' + - '**/test/**' + - '**/tests/**' jobs: update-docs: @@ -25,17 +30,73 @@ jobs: return; } - const url = `https://api.mintlify.com/v1/agent/${projectId}/job`; + // Extract commit details from push payload + const commits = context.payload.commits || []; + const headCommit = context.payload.head_commit; + + // Build list of changed files (excluding test files) + const testFilePattern = /\.(test|spec)\.(ts|js|tsx|jsx)$|__tests__|\/test\/|\/tests\//; + const changedFiles = commits.flatMap(c => [ + ...(c.added || []), + ...(c.modified || []), + ...(c.removed || []) + ]).filter(f => !testFilePattern.test(f)); + const uniqueFiles = [...new Set(changedFiles)]; + + // Skip if no non-test files changed + if (uniqueFiles.length === 0) { + core.notice('No documentation-relevant files changed. Skipping agent trigger.'); + return; + } + + // Build commit messages (first line only) + const commitMessages = commits + .map(c => '- ' + c.message.split('\n')[0]) + .join('\n'); + + // Compare URL for reference + const compareUrl = context.payload.compare || ''; + + // Build the system prompt + const systemPrompt = [ + 'You are a documentation updater that ONLY updates docs directly related to specific code changes.', + '', + 'CRITICAL RULES:', + '- ONLY update documentation that is directly affected by the code changes provided', + '- DO NOT perform general documentation audits or sync operations', + '- DO NOT add documentation for unrelated features, ecosystem partners, or missing content', + '- If the code changes do not require documentation updates, report "No documentation updates needed" and exit without creating a PR', + '- Focus on the specific files and commits mentioned, not the entire repository state', + '- Read the AGENTS.md file in the docs directory for additional guidance' + ].join('\n'); + + // Build the user prompt + const userPrompt = [ + 'Review these SPECIFIC code changes and update documentation ONLY if directly related:', + '', + '**Repository:** ' + owner + '/' + repo, + '**Compare URL:** ' + compareUrl, + '', + '**Changed Files (' + uniqueFiles.length + '):**', + uniqueFiles.join('\n'), + '', + '**Commit Messages:**', + commitMessages || 'No commit messages', + '', + 'IMPORTANT: Only update documentation that is directly impacted by these specific file changes. Do not add documentation for unrelated features or perform general audits. If these changes do not affect documentation, do NOT create a PR.' + ].join('\n'); + + const url = 'https://api.mintlify.com/v1/agent/' + projectId + '/job'; const payload = { - branch: `mintlify/docs-update-${Date.now()}`, + branch: 'mintlify/docs-update-' + Date.now(), messages: [ { role: 'system', - content: 'You are an action runner that updates documentation based on code changes. You should never ask questions. If you are not able to access the repository, report the error and exit.' + content: systemPrompt }, { role: 'user', - content: `Update the documentation for recent pushes to main:\n\nRepository: ${owner}/${repo}` + content: userPrompt } ], asDraft: false @@ -45,14 +106,15 @@ jobs: const response = await fetch(url, { method: 'POST', headers: { - 'Authorization': `Bearer ${apiKey}`, + 'Authorization': 'Bearer ' + apiKey, 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { - throw new Error(`API request failed with status ${response.status}: ${await response.text()}`); + const errorText = await response.text(); + throw new Error('API request failed with status ' + response.status + ': ' + errorText); } const reader = response.body.getReader(); @@ -75,7 +137,7 @@ jobs: console.log(buffer); } - core.notice(`Documentation update job triggered for ${owner}/${repo}`); + core.notice('Documentation update job triggered for ' + owner + '/' + repo); } catch (error) { - core.setFailed(`Failed to create documentation update job: ${error.message}`); + core.setFailed('Failed to create documentation update job: ' + error.message); } diff --git a/docs/AGENTS.md b/docs/AGENTS.md index 59310f32f..4f8ead708 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -60,3 +60,47 @@ - Code examples are from actual SDK files and compile - Frontmatter present on all pages (title, description) - MDX syntax is valid (run `mint dev` to verify) + +## Agent Behavior Rules (Automated Workflows) + +When triggered by GitHub Actions or other automated workflows: + +### DO +- ONLY update documentation directly related to the specific code changes +- Focus on the files and commits mentioned in the trigger +- Update SDK references if API signatures change +- Update quickstart guides if SDK usage patterns change +- Update core-concepts if protocol behavior changes + +### DO NOT +- Perform general documentation audits or sync operations +- Add documentation for ecosystem partners not mentioned in the code change +- Add documentation for features unrelated to the trigger +- Create PRs for trivial changes (comment removal, formatting, etc.) +- Sync ecosystem partner data from `typescript/site/app/ecosystem/` unless explicitly changed + +### Code-to-Doc Mapping (for automated updates) + +| Code Change | Doc Update Required | +|-------------|---------------------| +| `typescript/packages/*/src/*.ts` API changes | SDK reference, quickstart guides | +| `python/x402/src/*.py` API changes | Python SDK reference | +| `go/*.go` API changes | Go SDK reference | +| `java/src/**/*.java` API changes | Java SDK reference | +| `specs/*.md` protocol changes | core-concepts docs | +| Comment removal, formatting | NO update needed | +| Test file changes | NO update needed | +| Build/CI config changes | NO update needed | +| Ecosystem partner metadata only | NO update needed (site handles this) | + +### When to Skip (No PR) + +If the code changes are limited to: +- Removing or adding code comments +- Formatting/style changes (prettier, linting) +- Test files only (`*.test.ts`, `__tests__/`, etc.) +- CI/build configuration only (`.github/`, `turbo.json`, etc.) +- Dependency updates without API changes (`package.json`, `go.mod`, etc.) +- Ecosystem partner metadata (`typescript/site/app/ecosystem/partners-data/`) + +Then report "No documentation updates needed" and **do not create a PR**. From 96f08fc6914b4d6b443fc2a60cdf9af501503fc9 Mon Sep 17 00:00:00 2001 From: Faris Date: Thu, 8 Jan 2026 11:46:01 -0800 Subject: [PATCH 09/12] Update to use github api to detect code changes --- .github/workflows/update-docs.yml | 68 +++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml index c0fc419a4..ec9381556 100644 --- a/.github/workflows/update-docs.yml +++ b/.github/workflows/update-docs.yml @@ -30,30 +30,56 @@ jobs: return; } - // Extract commit details from push payload - const commits = context.payload.commits || []; - const headCommit = context.payload.head_commit; - - // Build list of changed files (excluding test files) - const testFilePattern = /\.(test|spec)\.(ts|js|tsx|jsx)$|__tests__|\/test\/|\/tests\//; - const changedFiles = commits.flatMap(c => [ - ...(c.added || []), - ...(c.modified || []), - ...(c.removed || []) - ]).filter(f => !testFilePattern.test(f)); - const uniqueFiles = [...new Set(changedFiles)]; - + // Get SHAs from push payload + const beforeSha = context.payload.before; + const afterSha = context.payload.after; + + // Skip initial commits (no previous SHA to compare against) + if (/^0+$/.test(beforeSha)) { + core.notice('Initial commit detected. Skipping documentation update.'); + return; + } + + // Get changed files using GitHub Compare API (reliable for all merge types) + let uniqueFiles = []; + + try { + const compareResponse = await github.rest.repos.compareCommits({ + owner, + repo, + base: beforeSha, + head: afterSha + }); + + // Extract filenames, excluding test files + const testFilePattern = /\.(test|spec)\.(ts|js|tsx|jsx)$|__tests__|\/test\/|\/tests\//; + uniqueFiles = (compareResponse.data.files || []) + .map(f => f.filename) + .filter(f => !testFilePattern.test(f)); + + } catch (error) { + core.setFailed('Failed to compare commits: ' + error.message); + return; + } + + // Log changed files for debugging + console.log('Changed files (' + uniqueFiles.length + '):', uniqueFiles.slice(0, 10)); + if (uniqueFiles.length > 10) { + console.log('... and ' + (uniqueFiles.length - 10) + ' more'); + } + // Skip if no non-test files changed if (uniqueFiles.length === 0) { core.notice('No documentation-relevant files changed. Skipping agent trigger.'); return; } - - // Build commit messages (first line only) - const commitMessages = commits - .map(c => '- ' + c.message.split('\n')[0]) - .join('\n'); - + + // Get commit message from head commit + const headCommit = context.payload.head_commit; + const commitMessage = headCommit + ? '- ' + headCommit.message.split('\n')[0] + : '- No commit message available'; + // Compare URL for reference const compareUrl = context.payload.compare || ''; @@ -80,8 +106,8 @@ jobs: '**Changed Files (' + uniqueFiles.length + '):**', uniqueFiles.join('\n'), '', - '**Commit Messages:**', - commitMessages || 'No commit messages', + '**Commit Message:**', + commitMessage, '', 'IMPORTANT: Only update documentation that is directly impacted by these specific file changes. Do not add documentation for unrelated features or perform general audits. If these changes do not affect documentation, do NOT create a PR.' ].join('\n'); From 3b6c34bd90870cfed8198296579ec4e20e4a078a Mon Sep 17 00:00:00 2001 From: Faris Date: Mon, 12 Jan 2026 08:38:23 -0800 Subject: [PATCH 10/12] fix links --- docs/core-concepts/network-and-token-support.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core-concepts/network-and-token-support.mdx b/docs/core-concepts/network-and-token-support.mdx index 110fa37e1..1037359af 100644 --- a/docs/core-concepts/network-and-token-support.mdx +++ b/docs/core-concepts/network-and-token-support.mdx @@ -241,7 +241,7 @@ Key takeaways: Next, explore: -* Quickstart for Sellers — Start accepting payments on supported networks -* Core Concepts — Learn how x402 works under the hood -* Facilitator — Understand the role of facilitators -* MCP Server — Set up AI agents to use x402 payments +* [Quickstart for Sellers](/docs/quickstart/sellers) — Start accepting payments on supported networks +* [Core Concepts](/docs/core-concepts) — Learn how x402 works under the hood +* [Facilitator](/docs/core-concepts/facilitator) — Understand the role of facilitators +* [MCP Server](/docs/advanced/mcp-server) — Set up AI agents to use x402 payments From 62ace22ffe2f2b52ea57c96e7022e7778530ec2a Mon Sep 17 00:00:00 2001 From: Faris Date: Mon, 12 Jan 2026 08:44:10 -0800 Subject: [PATCH 11/12] fix links --- docs/core-concepts/network-and-token-support.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core-concepts/network-and-token-support.mdx b/docs/core-concepts/network-and-token-support.mdx index 1037359af..afa06c2ce 100644 --- a/docs/core-concepts/network-and-token-support.mdx +++ b/docs/core-concepts/network-and-token-support.mdx @@ -241,7 +241,7 @@ Key takeaways: Next, explore: -* [Quickstart for Sellers](/docs/quickstart/sellers) — Start accepting payments on supported networks -* [Core Concepts](/docs/core-concepts) — Learn how x402 works under the hood -* [Facilitator](/docs/core-concepts/facilitator) — Understand the role of facilitators -* [MCP Server](/docs/advanced/mcp-server) — Set up AI agents to use x402 payments +* [Quickstart for Sellers](/getting-started/quickstart-for-sellers) — Start accepting payments on supported networks +* [Core Concepts](/core-concepts/http-402) — Learn how x402 works under the hood +* [Facilitator](/core-concepts/facilitator) — Understand the role of facilitators +* [MCP Server](/guides/mcp-server-with-x402) — Set up AI agents to use x402 payments From 032bbc5a6347bc9d1c6d33cda1beed583f45e990 Mon Sep 17 00:00:00 2001 From: Faris Date: Thu, 15 Jan 2026 10:30:18 -0800 Subject: [PATCH 12/12] exclude website --- .github/workflows/update-docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml index ec9381556..80e5e53e5 100644 --- a/.github/workflows/update-docs.yml +++ b/.github/workflows/update-docs.yml @@ -10,6 +10,7 @@ on: - '**/__tests__/**' - '**/test/**' - '**/tests/**' + - '**/typescript/site/*' jobs: update-docs: