Skip to main content

Setup

First, set up your payment handler and wallet:
import {
  clusterApiUrl,
  Connection,
  Keypair,
  PublicKey,
} from "@solana/web3.js";
import { createLocalWallet } from "@faremeter/wallet-solana";
import { lookupKnownSPLToken } from "@faremeter/info/solana";
import {
  createPaymentHandler,
  lookupX402Network,
} from "@faremeter/payment-solana/exact";
import { wrap as wrapFetch } from "@faremeter/fetch";

// Load keypair from environment
const { PAYER_KEYPAIR } = process.env;
if (!PAYER_KEYPAIR) throw new Error("PAYER_KEYPAIR must be set");

const network = "mainnet-beta";
const x402Network = lookupX402Network(network);

// Lookup USDC mint address automatically
const usdcInfo = lookupKnownSPLToken(network, "USDC");
if (!usdcInfo) throw new Error("Could not find USDC mint");

const keypair = Keypair.fromSecretKey(
  Uint8Array.from(JSON.parse(PAYER_KEYPAIR)),
);
const connection = new Connection(clusterApiUrl(network));
const mint = new PublicKey(usdcInfo.address);

const wallet = await createLocalWallet(x402Network, keypair);
const fetchWithPayer = wrapFetch(fetch, {
  handlers: [createPaymentHandler(wallet, mint, connection)],
});

Example: Get Swap Quote

Get a quote for swapping SOL to USDC:
const url = "https://dflow.api.corbits.dev/quote";
const params = new URLSearchParams({
  inputMint: "So11111111111111111111111111111111111111112", // SOL
  outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
  amount: "1000000000", // 1 SOL (9 decimals)
});

const response = await fetchWithPayer(`${url}?${params}`, {
  method: "GET",
  headers: {
    Accept: "application/json",
  },
});

if (!response.ok) {
  const text = await response.text().catch(() => "");
  throw new Error(`HTTP ${response.status} ${response.statusText} ${text}`);
}

const data = await response.json();
console.log("Quote:", data);
Response:
{
  "inputMint": "So11111111111111111111111111111111111111112",
  "inAmount": "1000000000",
  "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "outAmount": "221719181",
  "otherAmountThreshold": "220610586",
  "minOutAmount": "220610586",
  "slippageBps": 50,
  "platformFee": null,
  "outTransferFee": null,
  "priceImpactPct": "0",
  "routePlan": [
    {
      "venue": "PancakeSwap",
      "marketKey": "22HUWiJaTNph96KQTKZVy2wg8KzfCems5nyW7E5H5J6w",
      "inputMint": "So11111111111111111111111111111111111111112",
      "outputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
      "inAmount": "620400000",
      "outAmount": "137474513",
      "inputMintDecimals": 9,
      "outputMintDecimals": 6
    },
    {
      "venue": "Meteora DLMM",
      "marketKey": "HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR",
      "inputMint": "So11111111111111111111111111111111111111112",
      "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "inAmount": "379600000",
      "outAmount": "84164182",
      "inputMintDecimals": 9,
      "outputMintDecimals": 6
    },
    {
      "venue": "AlphaQ",
      "marketKey": "Pi9nzTjPxD8DsRfRBGfKYzmefJoJM8TcXu2jyaQjSHm",
      "inputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
      "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "inAmount": "137474513",
      "outAmount": "137554999",
      "inputMintDecimals": 6,
      "outputMintDecimals": 6
    }
  ],
  "contextSlot": 372366010,
  "simulatedComputeUnits": 333000,
  "requestId": "5bf1b708-be9a-4cbb-a7a0-fe3f99f0b5c3"
}
The response includes:
  • outAmount: Expected output amount (221.72 USDC for 1 SOL)
  • minOutAmount: Minimum amount with slippage protection
  • routePlan: Optimal routing across multiple DEXs (PancakeSwap, Meteora DLMM, AlphaQ)
  • slippageBps: Slippage tolerance in basis points (50 = 0.5%)

Payment Flow

When you make a request, the following happens automatically:
  1. Initial Request: Client sends quote request
  2. 402 Response: Proxy returns payment requirements
{
  "accepts": [{
    "network": "solana-mainnet-beta",
    "maxAmountRequired": 10000,
    "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "payTo": "AepWpq3GQwL8CeKMtZyKtKPa7W91Coygh3ropAJapVdU"
  }]
}
  1. Payment: Payment handler processes USDC transfer (0.01 USDC)
  2. Success: Proxy fulfills original request with 200 OK
All of this is handled automatically by fetchWithPayer!

External Resources