Dexterx402 SDK

Pay x402 endpoints from Node or React, add paid routes to an Express server, and run repeated calls against a wallet-approved Tab.

shell
npm install @dexterai/x402 @dexterai/vault

@dexterai/vault supplies wallet signing and Tab support.

Pay for a request

payAndFetch reads the endpoint's payment terms, pays with the wallet you supply, and returns a typed result. For USDC,5000000 sets a $5 ceiling.

typescript
import {
  createKeypairWallet,
  payAndFetch,
} from '@dexterai/x402/client';

const solana = await createKeypairWallet(process.env.AGENT_KEY!);

const payment = await payAndFetch(
  serviceUrl,
  {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(input),
  },
  { solana },
  { maxAmountAtomic: '5000000' },
);

if (!payment.ok) throw new Error(payment.reason);
if (!payment.response) throw new Error('The seller returned no response');

const result = await payment.response.json();

PayResult reports whether the request was paid and carries the response, amount, network, and transaction signature when available.

Tabs

An application asks for a counterparty, cap, and expiry. The wallet owner can lower the numbers before approving with a passkey. Paid calls then draw against that Tab.

DEXTERTABS

Open a tab

Exa Search API is asking for a spending limit.

Exa Search APIDraft

Get paid

tabOrExactMiddleware advertises one-time and Tab payment options on the same Express route. The price stays the same whether the buyer pays once or uses a Tab.

typescript
import { Connection } from '@solana/web3.js';
import { tabOrExactMiddleware } from '@dexterai/x402/tab/seller';

const connection = new Connection(process.env.SOLANA_RPC_URL!);

app.post(
  '/v1/report',
  tabOrExactMiddleware({
    connection,
    sellerPubkey: process.env.SELLER_SOLANA_ADDRESS!,
    network: 'solana:mainnet',
    perUnit: '0.002',
    facilitatorUrl: 'https://x402.dexter.cash',
    description: 'Research report',
  }),
  async (request, response) => {
    response.json(await buildReport(request.body));
  },
);