# X402 Micropayments

X402 is a micropayment protocol that enables pay-per-request access to premium data sources on Solana. By integrating X402 with Switchboard, you can access paywalled APIs and RPC endpoints directly from oracle jobs, paying only for the data you consume.

## What is X402?

X402 (named after the HTTP 402 "Payment Required" status code) is a protocol for micropayments on Solana. It allows data providers to monetize their APIs and services on a per-request basis, while consumers can access premium data without subscriptions or upfront commitments.

Key benefits:

* **Pay-per-use**: Only pay for the data you actually consume
* **No subscriptions**: Access premium data without monthly commitments
* **Instant payments**: USDC micropayments settle immediately on Solana
* **Seamless integration**: Works with standard HTTP APIs via authentication headers

**Prerequisite:** A Solana keypair funded with USDC on mainnet-beta (including a USDC associated token account with balance) is required to generate PAYMENT-SIGNATURE headers.

## How It Works with Switchboard

Switchboard integrates with X402 through **variable overrides**, a powerful feature that allows you to inject dynamic values into oracle job definitions at runtime. This enables oracles to authenticate with paywalled endpoints without storing sensitive credentials on-chain or in IPFS.

```
┌─────────────────────────────────────────────────────────────────────────┐
│                           X402 + Switchboard Flow                       │
└─────────────────────────────────────────────────────────────────────────┘

  ┌──────────┐      1. Derive            ┌────────────────┐
  │   Your   │      PAYMENT-SIGNATURE   │  x402 v2 Client │
  │   App    │ ────────────────────────► │                │
  └──────────┘                           └────────────────┘
       │                                         │
       │ 2. Pass headers as                      │
       │    variable overrides                   │
       ▼                                         │
  ┌──────────┐                                   │
  │Crossbar  │ ◄─────────────────────────────────┘
  │          │     PAYMENT-SIGNATURE header
  └──────────┘
       │
       │ 3. Fetch oracle update
       │    with auth headers
       ▼
  ┌──────────┐      4. Authenticated     ┌────────────────┐
  │  Oracle  │      HTTP request         │  Paywalled     │
  │  (TEE)   │ ────────────────────────► │  RPC/API       │
  └──────────┘                           └────────────────┘
       │                                         │
       │ 5. Return signed                        │
       │    oracle data                          │
       ▼                                         │
  ┌──────────┐                                   │
  │  Quote   │ ◄─────────────────────────────────┘
  │ Account  │       Verified data
  └──────────┘
```

The key innovation is that oracle feeds are defined **inline** (not stored on IPFS), with placeholder variables like `${X402_PAYMENT_SIGNATURE}` that get replaced at runtime with actual authentication headers.

## Key Concepts

### x402 v2 Client

Create an x402 v2 client that can sign USDC payments on Solana:

```typescript
import { x402Client } from "@x402/fetch";
import { registerExactSvmScheme } from "@x402/svm/exact/client";
import { toClientSvmSigner } from "@x402/svm";
import { createKeyPairSignerFromBytes } from "@solana/kit";

const signer = await createKeyPairSignerFromBytes(keypair.secretKey);
const client = new x402Client();
registerExactSvmScheme(client, { signer: toClientSvmSigner(signer) });
```

### Variable Overrides

Instead of hardcoding authentication headers in your feed definition, you use placeholders:

```typescript
const ORACLE_FEED = {
  name: "X402 Paywalled RPC Call",
  jobs: [{
    tasks: [{
      httpTask: {
        url: "https://paywalled-api.example.com",
        headers: [
          { key: "PAYMENT-SIGNATURE", value: "${X402_PAYMENT_SIGNATURE}" }
        ]
      }
    }]
  }]
};
```

At runtime, you derive the actual headers and pass them as overrides:

```typescript
const instructions = await queue.fetchManagedUpdateIxs(crossbar, [ORACLE_FEED], {
  variableOverrides: {
    X402_PAYMENT_SIGNATURE: paymentSignature
  }
});
```

### Quote Accounts

Verified oracle data is stored in a canonical **quote account** derived from the feed hash. This allows your on-chain program to read the authenticated data:

```typescript
const feedId = FeedHash.computeOracleFeedId(ORACLE_FEED);
const [quoteAccount] = OracleQuote.getCanonicalPubkey(queue.pubkey, [feedId]);
```

## Use Cases

* **Premium RPC Endpoints**: Access high-performance, paywalled Solana RPC nodes
* **Authenticated APIs**: Fetch data from APIs requiring micropayment authentication
* **Dynamic Authentication**: Support custom authentication schemes without storing credentials
* **Pay-per-Request Data**: Access expensive data sources only when needed

## Next Steps

* Follow the [X402 Tutorial](/docs-by-chain/solana-svm/x402/x402-tutorial.md) for a complete implementation walkthrough
* Explore [Variable Overrides](/custom-feeds/advanced-feed-configuration/data-feed-variable-overrides.md) for more dynamic feed patterns
* Learn about [Custom Feeds](/custom-feeds/build-and-deploy-feed.md) for building your own oracle jobs


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.switchboard.xyz/docs-by-chain/solana-svm/x402.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
