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: Chat Completion

Send a chat completion request to Llama 3.1 8B:
const url = "https://netmind.api.corbits.dev/chat/completions";

const response = await fetchWithPayer(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "meta-llama/Meta-Llama-3.1-8B-Instruct",
    messages: [
      {
        role: "system",
        content: "Act like you are a helpful assistant.",
      },
      {
        role: "user",
        content: "Hi there!",
      },
    ],
    max_tokens: 512,
  }),
});

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("Assistant response:", data.choices[0].message.content);
Response:
{
  "id": "4f8688b3f5f048578b5d6aa9d8509ba6",
  "object": "chat.completion",
  "created": 1762363931,
  "model": "meta-llama/Meta-Llama-3.1-8B-Instruct",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "How can I assist you today?",
        "tool_calls": null
      },
      "logprobs": null,
      "finish_reason": "stop",
      "matched_stop": 128009
    }
  ],
  "usage": {
    "prompt_tokens": 22,
    "completion_tokens": 14,
    "total_tokens": 36
  }
}
The response includes:
  • choices: Array of completion results
  • message.content: The assistant’s response text
  • usage: Token counts for billing and monitoring
  • finish_reason: Why generation stopped (stop, length, etc.)

Payment Flow

When you make a request, the following happens automatically:
  1. Initial Request: Client sends chat completion request
  2. 402 Response: Proxy returns payment requirements
{
  "accepts": [{
    "network": "solana-mainnet-beta",
    "maxAmountRequired": 10000,
    "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "payTo": "corzHctjX9Wtcrkfxz3Se8zdXqJYCaamWcQA7vwKF7Q"
  }]
}
  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