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

@vauban-pay/x402-starknet

v0.2.1

Published

x402 v2 mechanism for the registered `exact` scheme on Starknet, both halves: the client (SNIP-9 outside execution signed as SNIP-12 typed data, with any starknet.js Account) for @x402/core's x402Client, and the merchant side for x402ResourceServer and ev

Readme

@vauban-pay/x402-starknet

Both halves of the registered x402 v2 exact scheme on Starknet (x402-foundation/x402, specs/schemes/exact/scheme_exact_starknet.md): the client half, as a mechanism for @x402/core's x402Client, and the merchant half (@vauban-pay/x402-starknet/server), as a mechanism for x402ResourceServer and every @x402/* middleware built on it.

The payer signs a SNIP-9 v2 outside execution (SNIP-12 typed data, revision 1) authorizing exactly one transfer from its own account; the facilitator submits it and pays the gas. No approval, no client gas, replay protection by the account's own single-use SNIP-9 nonce.

Use

import { Account, RpcProvider } from "starknet";
import { x402Client } from "@x402/core/client";
import { wrapFetchWithPayment } from "@x402/fetch";
import { registerExactStarknetScheme } from "@vauban-pay/x402-starknet";

const account = new Account({ provider: new RpcProvider({ nodeUrl }), address, signer: privateKey });
const client = registerExactStarknetScheme(new x402Client(), { signer: account });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);

const res = await fetchWithPayment("https://demo.pay.vauban.tech/v1/quote");

Any object with address and signMessage(typedData) works as the signer, so a wallet adapter fits where the Account is.

Accept it, as a merchant

A merchant built with the foundation's middleware accepts Starknet by pointing its facilitator client at a facilitator that implements the scheme and registering the merchant half. Routes, prices and payTo are declared the way the foundation documents them for any other network:

import express from "express";
import { HTTPFacilitatorClient, x402ResourceServer } from "@x402/core/server";
import { paymentMiddleware } from "@x402/express";
import { registerExactStarknetServerScheme } from "@vauban-pay/x402-starknet/server";

const server = registerExactStarknetServerScheme(
  new x402ResourceServer(new HTTPFacilitatorClient({ url: "https://demo.pay.vauban.tech/starknet" })),
);
const app = express();
app.use(paymentMiddleware({
  "GET /weather": {
    accepts: { scheme: "exact", network: "starknet:SN_SEPOLIA", price: "0.01", payTo: "0x…your account…" },
  },
}, server));
app.get("/weather", (_req, res) => res.json({ weather: "sunny" }));

https://demo.pay.vauban.tech/starknet implements /supported, /verify and /settle for exact on starknet:SN_SEPOLIA, announces its submitter (extra.feePayer) and pays the gas of every settlement it broadcasts. Testnet only; its /supported says so by naming the network.

A price is a dollar string ("$0.10" is USDC, 6 decimals, at the addresses the foundation's reference implementation lists), STRK ("0.01", "0.01 STRK" or 0.01, 18 decimals), a default asset by symbol ("1.50 USDC"), or an explicit { amount, asset } in atomic units for any other token; everything is converted on digits and no rate is ever applied. Both STRK and USDC are default assets of the client half too, so a stock client pays either offer without touching its spend controls. The merchant half copies the facilitator's feePayer into every requirement and refuses an override, because the specification makes the facilitator reject any other value (rule 1).

test/merchant-with-stock-express.test.ts runs exactly this merchant, with a different payTo and price than the facilitator's own offer, against the real zkpay-facilitator binary, paid by the foundation's client with the client half. test/merchant-pays-on-sepolia.test.ts did it for real on 2026-09-08 against the public facilitator: a stock @x402/express merchant with its own address received exactly 0.005 STRK, gas paid by the facilitator:

tx    0x78f6773ecdff976e85de26742c7fe1f80f7ea50a1c8b492a245a56cac874912
block 14732675, SUCCEEDED, ACCEPTED_ON_L2

It has paid for real

On 2026-09-07, this mechanism, driven by @x402/fetch, paid 0.01 STRK on Starknet Sepolia to a live zkpay-facilitator:

tx    0x1b88b79ffaa84344d36fdab48e322a86d687a3eb4e9e2f45edae4c01b5b548d
block 14708171, SUCCEEDED, ACCEPTED_ON_L2

The test that produced it waits for the transaction on the chain and looks for the Transfer(payer -> merchant, price) event before it believes the receipt (test/pays-on-sepolia.test.ts). To our knowledge it is the first settlement of the registered exact/Starknet scheme on a real chain with the foundation's own client.

What it establishes, and what it does not

  • The mechanism produces payloads a spec-conforming facilitator accepts. It is tested against the real zkpay-facilitator binary, driven by the foundation's own @x402/fetch client, with starknet.js doing the hashing and signing; that test lives in test/.
  • The hermetic test settles against an in-memory chain and every receipt it produces says so (transaction: "mock:…", extra.mock: true). The live test above needs a node and two funded testnet accounts, and skips loudly without them. Nothing in this package moves value by itself; the facilitator's chain adapter decides that.
  • STRK is the default asset on both networks. @x402/core refuses any other asset unless you allow it in spendControls; that is the client's spend cap doing its job, not a defect of this package.

Why this package exists

As of 2026-09-07 the foundation's reference client for this scheme is an unmerged pull request, and the only published Starknet client follows an earlier, incompatible draft. A server that implements the specification had nobody to be paid by. This is the missing half.

Source, issues

This directory is mirrored to github.com/vauban-org/x402-starknet on every push from the Vauban Pay monorepo, which is where the facilitator (zkpay-facilitator, Rust) lives. Issues and pull requests are welcome on the mirror; the tests that need the facilitator binary or a funded Sepolia account skip there and say so.

License

Apache-2.0.