# Quicknode RPC via x402 > Pay-per-request blockchain RPC access using the x402 payment protocol. Authenticate with SIWE (Ethereum) or SIWX (multi-chain including Solana), pay with stablecoin micropayments, and make JSON-RPC calls to 140+ blockchain networks. No signup, no API keys — just a wallet. ## How it works Quicknode RPC via x402 lets you access blockchain data through standard JSON-RPC calls, paid for with stablecoin micropayments on Base, Polygon, XLayer (EVM) or Solana. The flow is: 1. **Authenticate** — Sign a SIWE or SIWX message with your wallet and exchange it for a JWT token at `POST /auth`. 2. **Make RPC calls** — Send JSON-RPC requests to `POST /:network` with your JWT in the `Authorization: Bearer` header. 3. **Pay when prompted** — When credits run out, the server returns HTTP 402. The `@quicknode/x402` package (or `@x402/fetch` for manual setups) automatically signs a stablecoin payment and retries. On testnet you receive 100 credits for $0.01 USDC; on mainnet you receive 1,000,000 credits for $10 USDC. 4. **Repeat** — Credits are consumed (1 per successful JSON-RPC response). When exhausted, another 402 triggers a new payment automatically. Base URL: `https://x402.quicknode.com` **EVM (Base):** Testnet (Base Sepolia, chain ID 84532) and Mainnet (Base, chain ID 8453) are available. A `/drip` endpoint provides free testnet USDC for Base Sepolia. **EVM (Polygon):** Testnet (Polygon Amoy, chain ID 80002) and Mainnet (Polygon, chain ID 137) are available. No `/drip` faucet for Polygon — pre-fund your wallet with USDC on Polygon Amoy. **EVM (XLayer):** Testnet (XLayer Testnet, chain ID 1952) and Mainnet (XLayer, chain ID 196) are available. No `/drip` faucet for XLayer — pre-fund your wallet with USDG (Global Dollar by Paxos) on XLayer Testnet. **Solana:** Devnet (`solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1`) and Mainnet (`solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`) are available. No faucet — pre-fund your wallet with USDC on Solana Devnet. ## Bootstrapping (no existing wallet needed) ### EVM (Base Sepolia — recommended for development) 1. **Generate a wallet** — Use `generatePrivateKey()` and `privateKeyToAccount()` from `viem/accounts` to create a fresh Ethereum keypair. 2. **Authenticate** — Sign a SIWE message and exchange it at `POST /auth` for a JWT (see Authentication section). 3. **Request testnet USDC** — Call `POST /drip` with your JWT. This is a one-time faucet that sends USDC to your wallet on Base Sepolia. 4. **Wait for USDC to arrive** — The faucet transaction is on-chain and takes a few seconds to confirm. Poll your wallet's USDC balance via `eth_call` on a public Base Sepolia RPC before proceeding. 5. **Make RPC calls** — Once your wallet has USDC, the `@x402/fetch` wrapper handles all subsequent payment negotiation automatically. > **Tip:** Using `@quicknode/x402` with `preAuth: true` handles steps 2–5 automatically. ```typescript import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; // No existing key needed — generate one on the fly const privateKey = generatePrivateKey(); const account = privateKeyToAccount(privateKey); // Store privateKey securely — you will need it for future sessions ``` ### Solana 1. **Generate a keypair** — Use `@solana/kit` or `tweetnacl` to generate an Ed25519 keypair, or use an existing Solana wallet. 2. **Pre-fund with USDC** — Transfer Solana Devnet USDC (mint: `4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU`) to your wallet. There is no `/drip` faucet for Solana. 3. **Authenticate via SIWX** — Construct a SIWX/Solana message and sign with Ed25519. POST to `/auth` with `type: "siwx"`. 4. **Make RPC calls** — Use `@x402/fetch` with `@x402/svm` for automatic Solana USDC payment handling. ## Authentication All endpoints except `/auth` require a JWT Bearer token. The `/auth` endpoint supports three authentication paths: ### Path 1: Legacy SIWE (EVM only, backwards compatible) POST `{ "message": "", "signature": "0x" }` — no `type` field needed. The `message` is a standard EIP-4361 SIWE message. This is the original auth method and remains fully supported. ### Path 2: SIWX/EVM POST `{ "message": "", "signature": "0x", "type": "siwx" }`. The `message` follows the same EIP-4361 format as legacy SIWE. The `type: "siwx"` tells the server to use the SIWX verification path (functionally equivalent for EVM). ### Path 3: SIWX/Solana POST `{ "message": "", "signature": "", "type": "siwx" }`. The `message` follows CAIP-122 / SIWS format: ``` x402.quicknode.com wants you to sign in with your Solana account: I accept the Quicknode Terms of Service: https://www.quicknode.com/terms URI: https://x402.quicknode.com Version: 1 Chain ID: EtWTRABZaYq6iMfeYKouRu166VU2xqa1 Nonce: Issued At: ``` Sign the message with Ed25519 and encode the signature as Base58. ### Required message fields (all paths) - `domain`: `x402.quicknode.com` - `address`: your wallet address (0x... for EVM, Base58 for Solana) - `statement`: `I accept the Quicknode Terms of Service: https://www.quicknode.com/terms` - `uri`: `https://x402.quicknode.com` - `version`: `1` - `chainId`: See Payment Configuration table for supported values - `nonce`: at least 8 random characters (single-use) - `issuedAt`: current ISO 8601 timestamp (must be within 5 minutes) ### Auth response `{ "token": "", "expiresAt": "", "accountId": "" }`. The JWT expires in 1 hour. The `chainId` in the JWT is a CAIP-2 string (e.g., `"eip155:84532"` or `"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"`). Include `Authorization: Bearer ` on all subsequent requests. ## Making JSON-RPC calls Send a standard JSON-RPC request to `POST /:network`: ``` POST /ethereum-mainnet HTTP/1.1 Authorization: Bearer Content-Type: application/json {"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]} ``` Replace `ethereum-mainnet` with any supported network slug (see Supported Networks section). Note: the auth chain determines your payment method, not which networks you can query. A Solana-authed user can query EVM networks and vice versa. When credits are available, you get the RPC response directly. When credits are depleted, you receive HTTP 402 with payment requirements in the response body and `PAYMENT-REQUIRED` header. The `@x402/fetch` library handles this automatically. ## x402 Payment handling The x402 protocol uses HTTP 402 responses to negotiate payment. You can handle this manually or use the `@x402/fetch` npm package which automates the entire flow. **Recommended: @quicknode/x402 package:** Install: `npm install @quicknode/x402` ```typescript import { createQuicknodeX402Client } from '@quicknode/x402'; const client = await createQuicknodeX402Client({ baseUrl: 'https://x402.quicknode.com', network: 'eip155:84532', evmPrivateKey: '0xYOUR_PRIVATE_KEY', preAuth: true, }); // client.fetch handles auth, SIWX, payment, and session management automatically const response = await client.fetch('https://x402.quicknode.com/base-sepolia', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_blockNumber', params: [] }), }); ``` **Automatic handling with @x402/fetch (EVM):** Install: `npm install @x402/fetch @x402/evm viem siwe` ```typescript import { wrapFetchWithPayment, x402Client } from '@x402/fetch'; import { ExactEvmScheme, toClientEvmSigner } from '@x402/evm'; // Create an EVM signer from your wallet const evmSigner = toClientEvmSigner({ address: walletClient.account.address, signTypedData: (params) => walletClient.signTypedData(params), }); // Register the signer for Base Sepolia const client = new x402Client() .register('eip155:84532', new ExactEvmScheme(evmSigner)); // IMPORTANT: @x402/fetch passes a Request object (not url+init) on payment // retries. The inner fetch must handle both calling conventions or the JWT // will be silently dropped on the retry and the request will fail with 401. const authedFetch = async (input: RequestInfo | URL, init?: RequestInit) => { if (input instanceof Request) { const req = input.clone(); req.headers.set('Authorization', `Bearer ${jwtToken}`); return fetch(req); } const headers = new Headers(init?.headers); headers.set('Authorization', `Bearer ${jwtToken}`); return fetch(input, { ...init, headers }); }; const x402Fetch = wrapFetchWithPayment(authedFetch, client); // Use x402Fetch like normal fetch — payments happen transparently const response = await x402Fetch('https://x402.quicknode.com/base-sepolia', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_blockNumber', params: [] }), }); ``` **Automatic handling with @x402/fetch (Solana):** Install: `npm install @x402/fetch @x402/svm @solana/kit tweetnacl bs58` ```typescript import { createKeyPairSignerFromBytes } from '@solana/kit'; import { wrapFetchWithPayment, x402Client } from '@x402/fetch'; import { ExactSvmScheme } from '@x402/svm'; // Create a Solana signer from your secret key (64 bytes) const signer = await createKeyPairSignerFromBytes(secretKey); // Register the signer for Solana Devnet const client = new x402Client() .register('solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', new ExactSvmScheme(signer)); const x402Fetch = wrapFetchWithPayment(authedFetch, client); const response = await x402Fetch('https://x402.quicknode.com/solana-devnet', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'getBlockHeight', params: [] }), }); ``` **Manual handling:** When you receive HTTP 402, the response body contains an `accepts` array describing payment options. Each entry includes `network` (CAIP-2 chain ID), `amount` (in smallest unit), `payTo` (recipient address), and `asset` (token contract/mint address). For EVM, sign an EIP-712 typed data payment. For Solana, construct a partially-signed USDC transfer using the `feePayer` from the `extra` field. Include the payment as a base64-encoded `PAYMENT-SIGNATURE` header on your retry request. **Payment configuration:** | Environment | CAIP-2 Chain ID | Token | Token Address | Amount (raw) | Amount (USD) | Credits | |---|---|---|---|---|---|---| | Base Sepolia (EVM testnet) | eip155:84532 | USDC | 0x036CbD53842c5426634e7929541eC2318f3dCF7e | 10000 | $0.01 | 100 | | Base Mainnet (EVM) | eip155:8453 | USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | 10000000 | $10.00 | 1,000,000 | | Polygon Amoy (EVM testnet) | eip155:80002 | USDC | 0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582 | 10000 | $0.01 | 100 | | Polygon Mainnet (EVM) | eip155:137 | USDC | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 | 10000000 | $10.00 | 1,000,000 | | XLayer Testnet (EVM testnet) | eip155:1952 | USDG | 0xF0863D7A29a55d0c4263c11bFac754312ff078DF | 10000 | $0.01 | 100 | | XLayer Mainnet (EVM) | eip155:196 | USDG | 0x4ae46a509F6b1D9056937BA4500cb143933D2dc8 | 10000000 | $10.00 | 1,000,000 | | Solana Devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 | USDC | 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU | 10000 | $0.01 | 100 | | Solana Mainnet | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | 10000000 | $10.00 | 1,000,000 | ## x402 Extension-Based Authentication (SIWX Header) For x402-native agents, a fully self-describing flow is available — no out-of-band knowledge of the `/auth` endpoint needed: 1. **Hit any endpoint with no auth** — The server returns HTTP 402 with `extensions` in the response body and `PAYMENT-REQUIRED` header. 2. **Read the `sign-in-with-x` extension** — Contains a SIWX challenge with `domain`, `uri`, `nonce`, `issuedAt`, `expirationTime`, and `supportedChains` (all EVM + Solana chains). 3. **Sign the SIWX challenge** — Construct a SIWX message from the challenge params, sign with your wallet, and encode as a `SIGN-IN-WITH-X` header (Base64-encoded JSON). 4. **Pay** — Include `PAYMENT-SIGNATURE` header with the x402 payment. The settlement response contains a `quicknode-session` extension with a JWT. 5. **Extract JWT from settlement** — Read `extensions['quicknode-session'].info.token` from the `PAYMENT-RESPONSE` header and use as `Authorization: Bearer ` for subsequent requests. ### `SIGN-IN-WITH-X` header format The header value is Base64-encoded JSON matching the `SIWxPayload` schema: ```json { "type": "eip191", "domain": "x402.quicknode.com", "address": "0xYourAddress", "uri": "https://x402.quicknode.com/ethereum-mainnet", "version": "1", "chainId": "eip155:8453", "nonce": "abc123...", "issuedAt": "2026-01-01T00:00:00.000Z", "signature": "0x..." } ``` For Solana, use `"type": "ed25519"` and Base58 signature. Smart wallets (EIP-1271/6492) are supported on EVM chains. ### 402 Response Extensions Every 402 response includes these extensions: - **`sign-in-with-x`**: SIWX challenge with `info` (domain, uri, nonce, issuedAt, expirationTime, resources) and `supportedChains` array. Nonce expires in 5 minutes. - **`bazaar`**: JSON-RPC POST input schema (`jsonrpc`, `method`, `params`, `id`) and example output (`{ jsonrpc: "2.0", result: "0x1234567", id: 1 }`). - **`quicknode-session`**: Declares that a JWT will be issued in the settlement response at `extensions.quicknode-session.info.token`. Includes `expirySeconds`, `authEndpoint` (`/auth`), and `usage` (`Authorization: Bearer `). All fields are nested under `info` per x402 extension convention. ### Discovery Endpoints `GET /openapi.json` — Public, no auth required. Returns an OpenAPI 3.1 spec with `x-agentcash-auth` and `x-payment-info` annotations on payable routes. This is the canonical x402 discovery method. `GET /discovery/resources` — Public, no auth required. Returns a paginated Bazaar-compatible catalog of all ~137 supported network endpoints with pricing and JSON-RPC schema. Query parameters: `limit` (default 50, max 200), `offset` (default 0). ## Checking credits ``` GET /credits HTTP/1.1 Authorization: Bearer ``` Returns `{ "accountId": "", "credits": 95 }`. ## Testnet faucet Request free testnet USDC (one-time per account, **Base Sepolia (EVM) only** — no Polygon, XLayer, or Solana faucet): ``` POST /drip HTTP/1.1 Authorization: Bearer ``` Returns `{ "accountId": "...", "walletAddress": "0x...", "transactionHash": "0x..." }`. Polygon, XLayer, and Solana-authed users will receive 401 from `/drip`. Pre-fund your wallet with the appropriate stablecoin (USDC for Polygon, USDG for XLayer) on the respective testnet before authenticating. ## Endpoints - `POST /auth` — Exchange SIWE/SIWX message + signature for JWT (public, no auth). Optional `type: "siwx"` field for multi-chain auth. - `GET /credits` — Check credit balance (JWT required) - `POST /drip` — Request testnet USDC (JWT required, Base Sepolia only, one-time) - `POST /:network` — JSON-RPC proxy to Quicknode (JWT or SIWX header + x402 payment). Anonymous requests return 402 with extensions. - `GET /:network/ws` — WebSocket proxy for persistent JSON-RPC (JWT required, credits must exist) - `GET /discovery/resources` — Bazaar-compatible catalog of all supported networks (public, no auth) - `GET /openapi.json` — OpenAPI 3.1 spec with x402 payment annotations (public, no auth) ## Rate limits - `/auth`: 10 requests per 10 seconds per IP - `/credits`: 50 requests per 10 seconds per account - `/drip`: 5 requests per 60 seconds per account - `/:network`: 1,000 requests per 10 seconds per network:account pair ## Metering - JSON-RPC: 1 credit per successful (HTTP 200) response - WebSocket: 1 credit per successful JSON-RPC response message - Error responses and JSON-RPC errors are not metered ## Error responses All errors return JSON: `{ "error": "", "message": "" }`. Common error codes: `invalid_json`, `missing_params`, `missing_token`, `invalid_token`, `token_expired`, `unsupported_network`, `rate_limit_exceeded`, `lifetime_limit_reached`. Testnet accounts have a lifetime credit cap. After reaching the cap, upgrade to mainnet (Base Mainnet for Base users, Polygon Mainnet for Polygon users, XLayer Mainnet for XLayer users, Solana Mainnet for Solana users). ## Supported Networks ### EVM Networks - `/ethereum-mainnet` — Ethereum Mainnet - `/ethereum-sepolia` — Ethereum Sepolia Testnet - `/base-mainnet` — Base Mainnet - `/base-sepolia` — Base Sepolia Testnet - `/arbitrum-mainnet` — Arbitrum One - `/arbitrum-sepolia` — Arbitrum Sepolia - `/optimism-mainnet` — Optimism Mainnet - `/optimism-sepolia` — Optimism Sepolia - `/matic-mainnet` — Polygon Mainnet - `/matic-amoy` — Polygon Amoy Testnet - `/bsc-mainnet` — BNB Smart Chain - `/bsc-testnet` — BNB Smart Chain Chapel - `/avalanche-mainnet` — Avalanche C-Chain - `/fantom-mainnet` — Fantom - `/linea-mainnet` — Linea - `/scroll-mainnet` — Scroll - `/zksync-mainnet` — zkSync - `/blast-mainnet` — Blast - `/mantle-mainnet` — Mantle - `/mode-mainnet` — Mode - `/zora-mainnet` — Zora (not in paths.json but in API docs) - `/sonic-mainnet` — Sonic - `/bera-mainnet` — Berachain - `/ink-mainnet` — Ink - `/unichain-mainnet` — Unichain - `/worldchain-mainnet` — World Chain - `/story-mainnet` — Story - `/hype-mainnet` — Hyperliquid - `/nova-mainnet` — Arbitrum Nova - `/strk-mainnet` — Starknet - `/xlayer-mainnet` — XLayer Mainnet - `/xlayer-testnet` — XLayer Testnet - `/zkevm-mainnet` — Polygon zkEVM - `/imx-mainnet` — Immutable X ### Non-EVM Networks - `/solana-mainnet` — Solana Mainnet - `/solana-devnet` — Solana Devnet - `/btc-mainnet` — Bitcoin Mainnet - `/flow-mainnet` — Flow Mainnet - `/near-mainnet` — NEAR Mainnet - `/cosmos-mainnet` — Cosmos Hub - `/sui-mainnet` — Sui - `/aptos-mainnet` — Aptos - `/ton-mainnet` — TON - `/tron-mainnet` — TRON - `/dot-mainnet` — Polkadot - `/stacks-mainnet` — Stacks - `/stellar-mainnet` — Stellar - `/doge-mainnet` — Dogecoin - `/xrp-mainnet` — XRP Ledger - `/hedera-mainnet` — Hedera - `/celestia-mainnet` — Celestia - `/injective-mainnet` — Injective - `/osmosis-mainnet` — Osmosis - `/sei-pacific` — Sei Most networks also have testnets available (append `-testnet`, `-sepolia`, or `-devnet` to the slug). ## Complete TypeScript example (EVM) ```typescript import { createWalletClient, http } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { baseSepolia } from 'viem/chains'; import { SiweMessage, generateNonce } from 'siwe'; import { wrapFetchWithPayment, x402Client } from '@x402/fetch'; import { ExactEvmScheme, toClientEvmSigner } from '@x402/evm'; const BASE_URL = 'https://x402.quicknode.com'; // 1. Set up wallet const walletClient = createWalletClient({ account: privateKeyToAccount('0xYOUR_PRIVATE_KEY'), chain: baseSepolia, transport: http(), }); // 2. Authenticate with SIWE const siweMessage = new SiweMessage({ domain: 'x402.quicknode.com', address: walletClient.account.address, statement: 'I accept the Quicknode Terms of Service: https://www.quicknode.com/terms', uri: BASE_URL, version: '1', chainId: 84532, nonce: generateNonce(), issuedAt: new Date().toISOString(), }); const message = siweMessage.prepareMessage(); const signature = await walletClient.signMessage({ message }); const authResponse = await fetch(`${BASE_URL}/auth`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message, signature }), }); const { token } = await authResponse.json(); // 3. Create x402-enabled fetch (handles payments automatically) const evmSigner = toClientEvmSigner({ address: walletClient.account.address, signTypedData: (params) => walletClient.signTypedData(params), }); const client = new x402Client() .register('eip155:84532', new ExactEvmScheme(evmSigner)); // IMPORTANT: @x402/fetch passes a Request object (not url+init) on payment // retries, so the inner fetch must handle both calling conventions. const authedFetch = async (input: RequestInfo | URL, init?: RequestInit) => { if (input instanceof Request) { const req = input.clone(); req.headers.set('Authorization', `Bearer ${token}`); return fetch(req); } const headers = new Headers(init?.headers); headers.set('Authorization', `Bearer ${token}`); return fetch(input, { ...init, headers }); }; const x402Fetch = wrapFetchWithPayment(authedFetch, client); // 4. Make RPC calls — payment is automatic on 402 const response = await x402Fetch(`${BASE_URL}/base-sepolia`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_blockNumber', params: [], }), }); const { result } = await response.json(); console.log('Block number:', BigInt(result)); // 5. Check remaining credits const creditsResponse = await fetch(`${BASE_URL}/credits`, { headers: { Authorization: `Bearer ${token}` }, }); const { credits } = await creditsResponse.json(); console.log('Credits remaining:', credits); ``` ## npm packages - `@quicknode/x402` — Official Quicknode x402 client package. Handles SIWX authentication, x402 USDC payments, JWT session management, gRPC-Web transport, and WebSocket connections. Recommended for all new integrations. - `@x402/fetch` — Wraps `fetch` to automatically handle 402 payment negotiation - `@x402/evm` — EVM payment scheme (EIP-712 signing) for x402 - `@x402/svm` — Solana payment scheme (SPL Token transfer) for x402 - `viem` — Ethereum wallet client, signing, and chain utilities - `siwe` — Sign-In with Ethereum (EIP-4361) message construction and signing - `@solana/kit` — Solana SDK (for creating keypair signers used by @x402/svm) - `tweetnacl` — Ed25519 cryptography (keypair generation, SIWX message signing) - `bs58` — Base58 encoding/decoding for Solana keys and signatures ## Optional ### Additional documentation - [x402 on Quicknode: Access Quicknode endpoints with x402 payments](https://www.quicknode.com/guides/x402/access-quicknode-endpoints-with-x402-payments): Quicknode's technical guide on x402 - [x402 on Quicknode: Instant Blockchain Access for Developers and AI Agents](https://blog.quicknode.com/x402-micropayments-quicknode-rpc-endpoints/): Quicknode's announcement blog post on x402 - [x402 Protocol](https://www.x402.org/): The x402 payment protocol specification - [SIWE (EIP-4361)](https://eips.ethereum.org/EIPS/eip-4361): Sign-In with Ethereum standard - [CAIP-122](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-122.md): Sign-In with X (SIWX) standard