npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dexterai/x402

v5.3.1

Published

Full-stack x402 SDK - add paid API monetization to any endpoint. Express middleware, React hooks, Access Pass, dynamic pricing. Solana, Base, Polygon, Arbitrum, Optimism, Avalanche, SKALE.

Readme


The problem

An agent that pays for things needs money it can reach without you in the loop for every charge. The two usual ways to give it that each cost you something you shouldn't have to give up.

  • Prefund an escrow and your money leaves your wallet to sit with a custodian before you've bought anything. Your balance is on the table, and you've paid a stranger in advance.
  • Hand it a spending delegate and you keep custody — but you can also pull the funds mid-charge, so the seller can be left unpaid. Serious sellers decline it.

The tab

A tab keeps both halves. You open one against your own wallet with a single passkey tap and set a cap. Your agent spends against that cap call by call, with no signature on each charge. The money never leaves your wallet — and while the tab is open, the Solana program blocks you from pulling it out from under what the agent has already run up. The seller gets paid when they settle, automatically.

The cap is enforced at consensus by an on-chain program — not by this library, and not by Dexter. The closest familiar shape is an auth-and-capture card hold, except the hold lives on-chain instead of inside a processor, and no one ever takes your money.

import { payUrlWithTab } from '@dexterai/x402/tab';

const tabs = new Map();                          // one open tab per seller, reused across calls
const { result, tab } = await payUrlWithTab(
  'https://api.example.com/paid/infer',
  { method: 'GET' },
  { vault, perUnitCap: '0.01', totalCap: '1.00', tabs },
);
// ...the agent keeps calling; every call reuses the same tab, with no new prompt...
await tab?.close();                              // one on-chain settle pays the seller for everything

That's the whole loop: one tap to open, unlimited calls under the cap, one settle to close. The seller's address comes off the wire from the URL's own 402 challenge — never from your code. The vault is built once from your passkey-rooted wallet; see Setup.


Why you can trust it

"Unruggable" has to be earned, so here is what backs it. Every property below is enforced by the on-chain program, not by this SDK and not by Dexter.

  • Non-custodial. Your USDC never leaves your wallet. The program holds no funds — it records bindings and gates withdrawals. There is no escrow account and no custodian to fail.
  • The cap is consensus-enforced. The limit is checked by the Solana program at consensus, not by this library. Read the program and verify it yourself: Hg3wRaydFtJhYrdvYrKECacpJYDsC9Px7yKmpncj2fhc on Solana mainnet.
  • Only your passkey moves money. Withdrawals require a WebAuthn assertion verified by Solana's secp256r1 precompile. Neither the SDK nor the facilitator holds a key that can drain your wallet.
  • The seller is protected, surgically. As the agent spends, accrued charges crystallize on-chain into a reservation sized to exactly what's been spent — never the whole wallet. The buyer keeps spending or withdrawing the rest of their balance freely, the seller is guaranteed what they're owed, and if a seller ever goes silent the buyer reclaims the abandoned reservation after a fixed grace period. No one's funds can be frozen indefinitely.
  • Live on mainnet, pre-audit, and we say so. Tabs settle on Solana mainnet today; an external audit is funded and in flight. The report and any findings publish in the dexter-vault program repo. Responsible disclosure: [email protected].

The full threat model and trust assumptions live in the program's SECURITY.md.


Setup

Install the SDK alongside @dexterai/vault — it's a peer dependency, so your app and the tab adapter share one vault instance:

npm install @dexterai/x402 @dexterai/vault

Build a vault adapter once, from the wallet addresses you receive when you enroll at dexter.cash, plus your passkey signer:

import { createSolanaVaultAdapter } from '@dexterai/x402/tab/adapters/solana';

const vault = createSolanaVaultAdapter({
  connection,      // your Solana Connection (any RPC)
  swigAddress,     // the vault's Swig state account, from enrollment
  vaultPda,        // the vault's gate PDA, from enrollment
  passkeySigner,   // browser: vault's DexterApiBrowserPasskeySigner · agent: passkeySignerFromP256Keypair(kp)
  feePayer,        // lamport fee payer (a Signer)
});

That vault drives the tab loop above. To inspect a seller's price before you spend, resolveTabTerms(url) reads the terms without paying — for consent screens, directories, or an agent that plans ahead.


Get paid (sellers)

You get paid for exactly what you serve, and you hold no key. As an agent spends against its tab, charges crystallize on-chain into a reservation against the buyer's wallet; one settle at close pays your address for everything metered. One middleware advertises both a tab and a one-shot price in a single 402, so tab-native agents and one-shot callers pay at the same rate.

import { tabOrExactMiddleware, requireTab, openSse } from '@dexterai/x402/tab/seller';
import type { X402Request } from '@dexterai/x402/server';

app.get('/paid/tick',
  tabOrExactMiddleware({ connection, sellerPubkey, network: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', perUnit: '0.01' }),
  async (req, res) => {
    if ((req as X402Request).x402) { res.json({ data: '...' }); return; }   // one-shot caller, already paid
    const meter = openSse(res, { tab: requireTab(req), perUnit: '0.01' });  // tab caller
    await meter.charge(1);                  // demand a fresh voucher; throws if the cap is exceeded
    meter.send(JSON.stringify({ data: '...' }));
    await meter.end();                      // always await — persists the final delivered amount
  });

Want a tab-only endpoint, or to compose the pieces yourself? The full seller surface is in REFERENCE.md.


Hosted approval (partners)

When a partner's app opens a tab for a user, the approval runs on one Dexter-hosted consent screen, deep-linked from the partner's app. The user sees the counterparty, the cap, and the expiry, taps their passkey once, and control returns to the app. The partner builds no approval UI and never handles a passkey.

The screen is hosted for a structural reason, not a stylistic one: the vault's passkey can only sign on Dexter's own origin, so a user cannot be phished into approving on a look-alike page. The safety is a property of where the key signs. Flow and routing: docs.dexter.cash.


Also in this package

Tabs are the headline. The same install carries the rest of the x402 surface — each documented in full in REFERENCE.md.

  • One-shot payments — a single discrete purchase over HTTP 402, USDC on Solana and the major EVM chains. payAndFetch (client), x402Middleware (server), useX402Payment (React).
  • Batch settlement (EVM) — prepay an escrow once, make many paid calls with off-chain vouchers, settle in a handful of transactions to amortize gas. openBatchChannel.
  • Discovery — make any protected route findable by capability through the x402 bazaar spec. bazaarExtension().
  • Sponsored access & auto-listing — endpoints paid through Dexter's facilitator are auto-discovered, named, quality-tested, and surfaced in x402_search across MCP clients, with no registration step.

Supported networks

Tabs are Solana. One-shot and batch settlement span Solana and the major EVM chains; USDC on every chain. Full live list: Dexter facilitator.

| Network | CAIP-2 | Status | |---------|--------|--------| | Solana | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | Production | | Base | eip155:8453 | Production | | Polygon | eip155:137 | Production | | Arbitrum | eip155:42161 | Production | | Optimism | eip155:10 | Production | | Avalanche | eip155:43114 | Production | | BSC | eip155:56 | Production | | SKALE Base | eip155:1187947933 | Production (zero gas) |


More

  • REFERENCE.md — every export, option table, and example: tabs, one-shot, batch settlement, discovery.
  • Upgrading? 5.0.0 makes @dexterai/vault a peer dependency (>=0.19) and unifies the passkey signer on signOperation. Migration from v4/v3: REFERENCE.md.
  • License — MIT, see LICENSE.