v3.1.1@dexterai/x402

The SDK for x402, on the server and the client.

Install one package. Add payments to any API in about ten lines, or pay for someone else’s API from your own code. Ships Express middleware, a browser and Node client, React hooks, Access Pass, and token-accurate LLM pricing.

$npm install @dexterai/x402
§ 02Server and client

One package, both sides.

Server

Monetize your API.

Drop one Express middleware on a route. An unpaid request gets a 402 Payment Required with the price and chains you accept. The handler only runs after USDC has settled.

import { x402Middleware } from '@dexterai/x402/server';

app.get('/api/data',
  x402Middleware({
    payTo:  'YourAddress...',
    amount: '0.01',
  }),
  (req, res) => {
    res.json({ data: 'protected content' });
  }
);
  • Signature verification, settlement, and response all handled
  • One address or per-chain routing via payTo object
  • Accept one chain or a list: Solana, Base, Polygon, Arbitrum, Optimism, Avalanche, SKALE
Client

Pay for any x402 API.

Wrap fetch with a wallet. The wrapper catches the 402, signs the payment, retries, and returns the real response. Works the same in Node and the browser.

import { wrapFetch } from '@dexterai/x402/client';

const x402Fetch = wrapFetch(fetch, {
  walletPrivateKey: process.env.SOLANA_PRIVATE_KEY,
});

const response = await x402Fetch(
  'https://api.example.com/protected'
);
  • Pre-flight balance check before signing
  • Pass both Solana and EVM keys: picks the chain with balance
  • Browser flavor: createX402Client with your wallet objects
§ 03Live demo

Real payment, mainnet, right now.

Live · mainnet · useX402Payment$0.03 USDC
WalletNot connected

This is a real payment on mainnet. $0.03 USDC moves from your wallet to the Dexter facilitator, which returns live Solscan trending data.

What’s happening
import { useX402Payment } from '@dexterai/x402/react';

const { fetch, isLoading, transactionUrl }
  = useX402Payment({ wallets: { solana, evm } });

await fetch(
  '/api/tools/solscan/trending',
  { method: 'POST', body: JSON.stringify({ limit: 10 }) }
);

The hook receives a 402, signs a USDC transfer on the active chain, retries the request, and surfaces the settlement receipt. Same flow in Node with wrapFetch.

§ 04Access Pass

Pay once, call freely.

x402AccessPass

Time-windowed access, one line.

Per-call signing gets expensive for high-frequency workloads. Access Pass charges once for a time window, issues a JWT, and skips the 402 on every subsequent request. Tiers map a duration to a price. Pair with the client accessPass option and calls stop costing anything until the window expires.

import { x402AccessPass } from '@dexterai/x402/server';

app.use('/api', x402AccessPass({
  payTo: 'YourAddress...',
  tiers: {
    '1h':  '0.50',
    '24h': '2.00',
  },
  ratePerHour: '0.50',
}));
§ 05Dynamic pricing

Pay by the token.

createTokenPricing

tiktoken in, USDC out.

Flat-rate LLM pricing overcharges short prompts and loses money on long ones. Token pricing quotes input tokens at the model’s real per-1M rate, signs a hash so the price can’t drift between quote and settlement, and rejects the call if the prompt changes. Ships with the common OpenAI models; bring your own rates for Anthropic, Gemini, Mistral, or a local model. Works alongside createDynamicPricing for char, pixel, or record billing.

import {
  createX402Server,
  createTokenPricing,
} from '@dexterai/x402/server';

const server  = createX402Server({ payTo, network });
const pricing = createTokenPricing({ model: 'gpt-4o-mini' });

app.post('/api/chat', async (req, res) => {
  const quote = pricing.calculate(req.body.prompt);
  // 402 first, settle on retry, then run the model
});
§ 06React hooks

Drop it into a React app.

@dexterai/x402/react

One hook per payment model.

useX402Payment for per-call payment, useAccessPass for time-windowed access. Pass the wallet objects from your existing providers. The hook figures out which chain has balance and routes the payment there. No redirects. No server round-trip for signing. Balances, loading state, and transaction URLs come back in the hook return.

import { useX402Payment } from '@dexterai/x402/react';

function PayButton() {
  const { fetch, isLoading, transactionUrl } =
    useX402Payment({ wallets: { solana, evm } });

  return (
    <button onClick={() => fetch('/api/data')}>
      {isLoading ? 'Paying…' : 'Pay'}
    </button>
  );
}

When a payment doesn’t work, /sdk/debug.

Paste an endpoint and watch the 402 flow run end to end. Compare facilitators side by side, lint the requirements header, inspect the signature, see exactly where settlement broke. It was built to debug production incidents, not to look pretty.

Open debugger →
Chains supported by @dexterai/x402
SolanaBasePolygonArbitrumOptimismAvalancheSKALE