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

s402

v0.1.6

Published

s402 — Sui-native HTTP 402 wire format. Types, HTTP encoding, and scheme registry for five payment schemes. Wire-compatible with x402. Zero runtime dependencies.

Downloads

290

Readme

s402

CI npm version

Sui-native HTTP 402 protocol. Atomic settlement via Sui's Programmable Transaction Blocks (PTBs). Includes an optional compat layer (s402/compat) for normalizing x402 input.

npm install s402
pnpm add s402
bun add s402
deno add npm:s402

ESM-only. This package ships ES modules only ("type": "module"). Requires Node.js >= 18. CommonJS require() is not supported.

Why s402?

HTTP 402 ("Payment Required") has been reserved since 1999 — waiting for a payment protocol that actually works. Coinbase's x402 proved the concept on EVM. s402 takes it further by leveraging what makes Sui different.

s402 vs x402

| | x402 (Coinbase) | s402 | |---|---|---| | Settlement | Two-step: verify then settle (temporal gap) | Atomic: verify + settle in one PTB | | Finality | 12+ second blocks (EVM L1) | ~400ms (Sui) | | Payment models | Exact (one-shot) only | Five schemes: Exact, Prepaid, Escrow, Unlock, Stream | | Micro-payments | $7.00 gas per 1K calls (broken) | $0.014 gas per 1K calls (prepaid) | | Coin handling | approve + transferFrom | Native coinWithBalance + splitCoins | | Agent auth | None | AP2 mandate delegation | | Direct mode | No | Yes (no facilitator needed) | | Receipts | Off-chain | On-chain NFT proofs | | Compatibility | n/a | Optional x402 compat layer (s402/compat) |

s402 is Sui-native by design. These advantages come from Sui's object model, PTBs, and sub-second finality. They can't be replicated on EVM — and they don't need to be. x402 already handles EVM well. s402 handles Sui better.

Architecture

s402          <-- You are here. Protocol spec. Zero runtime deps.
  |
  |-- Types         Payment requirements, payloads, responses
  |-- Schemes       Client/Server/Facilitator interfaces per scheme
  |-- HTTP          Encode/decode for HTTP headers (base64 JSON)
  |-- Compat        Optional x402 migration aid
  |-- Errors        Typed error codes with recovery hints
  |
@sweefi/sui         <-- Sui-specific implementations (coming soon)
@sweefi/sdk         <-- High-level DX (coming soon)

s402 is chain-agnostic protocol plumbing. It defines what gets sent over HTTP. The Sui-specific how will live in @sweefi/sui (coming soon).

Payment Schemes

Exact (v0.1)

One-shot payment. Client builds a signed transfer PTB, facilitator verifies + broadcasts atomically.

Client                    Server                  Facilitator
  |--- GET /api/data ------->|                         |
  |<-- 402 + requirements ---|                         |
  |                          |                         |
  |  (build PTB, sign)       |                         |
  |--- GET + x-payment ----->|--- verify + settle ---->|
  |                          |<--- { success, tx } ----|
  |<-- 200 + data -----------|                         |

This is the x402-compatible baseline. An x402 client can talk to an s402 server using this scheme with zero modifications.

Prepaid (v0.1)

Deposit-based access. Agent deposits funds into an on-chain Balance shared object targeted at a specific provider. API calls happen off-chain. Provider batch-claims accumulated usage. Move module enforces rate caps — no trust required.

Phase 1 (deposit — one on-chain TX):
  Agent deposits 10 SUI → Balance shared object created
  Gas: ~$0.007

Phase 2 (usage — off-chain, zero gas):
  Agent makes 1,000 API calls
  Server tracks usage, no on-chain TX per call

Phase 3 (claim — one on-chain TX):
  Provider claims accumulated $1.00 from Balance
  Gas: ~$0.007
  ─────────────────────────────────────────────────────
  Total gas: $0.014 for 1,000 calls
  Per-call effective gas: $0.000014

This is the agent-native payment pattern. Without prepaid, per-call settlement costs $7.00 in gas for $1.00 of API usage (economically impossible). With prepaid, it costs $0.014 (economically trivial).

Use cases: AI agent API budgets, high-frequency API access, compute metering.

Escrow (v0.1)

Time-locked vault with arbiter dispute resolution. Full state machine: ACTIVE -> DISPUTED -> RELEASED / REFUNDED.

  • Buyer deposits funds, locked until release or deadline
  • Buyer confirms delivery -> funds release to seller (receipt minted)
  • Deadline passes -> permissionless refund (anyone can trigger)
  • Either party disputes -> arbiter resolves

Use cases: digital goods delivery, freelance payments, trustless commerce.

Unlock

Pay-to-decrypt encrypted content. Escrow + encrypted content delivery. The buyer pays into escrow; on release, the EscrowReceipt unlocks encrypted content stored on Walrus. Currently powered by Sui SEAL.

This scheme depends on encryption key server infrastructure and is under active development.

Stream

Per-second micropayments via on-chain StreamingMeter. Client deposits funds into a shared object; recipient claims accrued tokens over time.

Phase 1 (402 exchange):
  Client builds stream creation PTB --> facilitator broadcasts
  Result: StreamingMeter shared object on-chain

Phase 2 (ongoing access):
  Client includes x-stream-id header --> server checks on-chain balance
  Server grants access as long as stream has funds

Use cases: AI inference sessions, video streaming, real-time data feeds.

Quick Start

Types only (most common)

import type {
  s402PaymentRequirements,
  s402PaymentPayload,
  s402SettleResponse,
} from 's402';

HTTP header encoding

import {
  encodePaymentRequired,
  decodePaymentRequired,
  encodePaymentPayload,
  decodePaymentPayload,
  detectProtocol,
} from 's402';

// Server: build 402 response
const requirements: s402PaymentRequirements = {
  s402Version: '1',
  accepts: ['exact', 'stream'],
  network: 'sui:mainnet',
  asset: '0x2::sui::SUI',
  amount: '1000000', // 0.001 SUI in MIST
  payTo: '0xrecipient...',
};

response.status = 402;
response.headers.set('payment-required', encodePaymentRequired(requirements));

// Client: read 402 response
const header = response.headers.get('payment-required')!;
const reqs = decodePaymentRequired(header);
console.log(reqs.accepts); // ['exact', 'stream']
console.log(reqs.amount);  // '1000000'

x402 compat (opt-in)

import {
  normalizeRequirements,
  isS402,
  isX402,
  toX402Requirements,
  fromX402Requirements,
} from 's402/compat';

// Normalize x402 JSON (V1 or V2) to s402 format
const requirements = normalizeRequirements(rawJsonObject);

// Convert s402 -> x402 V1 for legacy clients
const x402Reqs = toX402Requirements(requirements);

Error handling

import { s402Error, s402ErrorCode } from 's402';

try {
  await facilitator.settle(payload, requirements);
} catch (e) {
  if (e instanceof s402Error) {
    console.log(e.code);            // 'INSUFFICIENT_BALANCE'
    console.log(e.retryable);       // false
    console.log(e.suggestedAction); // 'Top up wallet balance...'
  }
}

Scheme registry (client)

import { s402Client } from 's402';

const client = new s402Client();

// Register scheme implementations (from @sweefi/sui or your own)
client.register('sui:mainnet', exactScheme);
client.register('sui:mainnet', streamScheme);

// Auto-selects best scheme from server's accepts array
const payload = await client.createPayment(requirements);

Scheme registry (facilitator)

import { s402Facilitator } from 's402';

const facilitator = new s402Facilitator();
facilitator.register('sui:mainnet', exactFacilitatorScheme);

// Atomic verify + settle
const result = await facilitator.process(payload, requirements);
if (result.success) {
  console.log(result.txDigest); // Sui transaction digest
}

Sub-path Exports

import { ... } from 's402';         // Everything
import type { ... } from 's402/types';   // Types + constants only
import { ... } from 's402/http';     // HTTP encode/decode
import { ... } from 's402/compat';   // x402 interop
import { ... } from 's402/errors';   // Error types

Implementing a Scheme

s402 is designed as a plugin system. Each payment scheme implements three interfaces:

import type {
  s402ClientScheme,       // Client: build payment payload
  s402ServerScheme,       // Server: build payment requirements
  s402FacilitatorScheme,  // Facilitator: verify + settle
  s402DirectScheme,       // Optional: settle without facilitator
} from 's402';

The reference Sui implementation of all five schemes will be available in @sweefi/sui (coming soon).

Wire Format

s402 uses the same HTTP headers as x402 V1:

| Header | Direction | Content | |--------|-----------|---------| | payment-required | Server -> Client | Base64-encoded s402PaymentRequirements JSON | | x-payment | Client -> Server | Base64-encoded s402PaymentPayload JSON | | payment-response | Server -> Client | Base64-encoded s402SettleResponse JSON |

Note: x402 V2 renamed the client payment header to payment-signature. s402 uses x-payment (matching x402 V1). All header names are lowercase per HTTP/2 (RFC 9113 §8.2.1). x402 V2 servers accept both headers, so s402 clients work with both versions. If your server needs to accept x402 V2 clients, also check payment-signature.

The presence of s402Version in the decoded JSON distinguishes s402 from x402. Clients and servers can auto-detect the protocol using detectProtocol().

Discovery

Servers can advertise s402 support at /.well-known/s402.json:

{
  "s402Version": "1",
  "schemes": ["exact", "stream", "escrow", "unlock", "prepaid"],
  "networks": ["sui:mainnet"],
  "assets": ["0x2::sui::SUI", "0xdba...::usdc::USDC"],
  "directSettlement": true,
  "mandateSupport": true,
  "protocolFeeBps": 50
}

Security

HTTPS is required. s402 payment data (requirements, payloads, settlement responses) travels in HTTP headers as base64-encoded JSON. Without TLS, this data is visible to any network observer. All production deployments MUST use HTTPS.

Requirements expiration. Servers SHOULD set expiresAt on payment requirements to prevent replay of stale 402 responses. The facilitator rejects expired requirements before processing.

const requirements: s402PaymentRequirements = {
  s402Version: '1',
  accepts: ['exact'],
  network: 'sui:mainnet',
  asset: '0x2::sui::SUI',
  amount: '1000000',
  payTo: '0xrecipient...',
  expiresAt: Date.now() + 5 * 60 * 1000, // 5-minute window
};

Design Principles

  1. Protocol-agnostic core, Sui-native reference. s402 defines chain-agnostic protocol types and HTTP encoding. The reference implementation (@sweefi/sui, coming soon) will exploit Sui's unique properties — PTBs, object model, sub-second finality. Other chains can implement s402 schemes using their own primitives.

  2. Optional x402 compat. The s402/compat subpath provides a migration aid for codebases with x402-formatted JSON. It normalizes x402 V1 (maxAmountRequired) and V2 (amount) to s402 format. This is opt-in — the core protocol has no x402 dependency.

  3. Scheme-specific verification. Each scheme has its own verify logic. Exact verify (signature recovery + dry-run) is fundamentally different from stream verify (deposit check + rate validation). The facilitator dispatches — it doesn't share logic.

  4. Zero runtime dependencies. s402 is pure TypeScript protocol definitions. No Sui SDK, no crypto libraries, no HTTP framework. Chain-specific code belongs in adapters.

  5. Errors tell you what to do. Every error code includes retryable (can the client try again?) and suggestedAction (what should it do?). Agents can self-recover.

License

Apache-2.0 — see LICENSE for details.