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

x402aff

v0.4.0

Published

Builder-code affiliation for x402 sellers - the Affiliation facade (TypeScript port of affiliation.py).

Readme

x402aff (TypeScript)

npm install size License: MIT

The Affiliation facade for x402 sellers on the Node / TypeScript stack - a port of the repo's Python affiliation.py. Same three on-chain reads, same safe-fallback contract, and it resolves the identical split address as the Python kit for a given (seller, builder) pair (the encoding is asserted byte-for-byte against the Python/cast bytes in the tests).

Only dependency: viem.

Install

npm install x402aff viem   # viem is a peer dependency - you bring your own

Or vendor it: the package ships src/affiliation.ts alongside dist/, so you can copy that one file into your project and depend on nothing but viem.

Working on the kit itself:

npm install        # from this dir
npm test           # needs Node >= 22.18 (runs the .ts tests via type stripping)
npm run build      # emits dist/ via tsconfig.build.json

Use

import { Affiliation } from "x402aff";

const aff = new Affiliation({
  appCode: "bc_yourcode",
  sellerPayout: "0xYourWallet",
  // builderShareBps: 1000,           // 10% (default); also read from X402_BUILDER_SHARE_BPS
  // rpcUrl: "https://…",             // a paid Base RPC for production; also read
  //                                  // from X402_BASE_RPC if you set no rpcUrl.
});

// ── on your x402 route ──
// `aff.payTo` is a drop-in x402 `DynamicPayTo` callback - hand it straight to
// express / hono / next x402 middleware (it reads X-Builder-Code off the request
// via ctx.adapter.getHeader). It's a bound field, so pass it by reference:
const middleware = paymentMiddleware(facilitator, {
  "/api/data": { price: "$0.02", network: "base", payTo: aff.payTo, extensions: aff.extensions },
});

// Or resolve it yourself and wire the result in:
const extensions = aff.extensions;                 // declares your app code `a`
const payTo = await aff.payToFor(req.headers);     // the split, or your wallet

// ── the payout side (permissionless) ──
const { calls, balanceUnits } = await aff.release("bc_alice");
for (const c of calls) {
  // c.step ("deploy_split" | "distribute"), c.target, c.data - submit from any funded Base account
}

payToFor / resolve never throw: a missing, unknown, or unresolvable code falls back to sellerPayout (unsplit, never a failed payment). Inject a viem PublicClient via { client } to share a transport or for tests.

resolve also returns status ("resolved" | "unregistered" | "invalid" | "error" | "none"). Echo it so builders can tell a working code from a dead one:

const pt = await aff.resolve(req.headers);
res.setHeader(STATUS_HEADER, pt.status); // "X-Builder-Code-Status"

Buyer side

Builders attach their code with the official extension - no port needed:

import { BuilderCodeClientExtension } from "@x402/extensions/builder-code";
client.registerExtension(new BuilderCodeClientExtension("bc_yourcode"));
// …and send header  X-Builder-Code: bc_yourcode  on the request.

To make your kit-routed payments discoverable on-chain (across all sellers, one query), attach the shared kit marker as a second s code - it never changes a payout, since the split pays the primary code:

import { markedServiceCodes, AFFILIATION_MARKER } from "./src/affiliation.ts";
// s becomes ["bc_yourcode", AFFILIATION_MARKER]; the split still pays bc_yourcode.
const info = { "builder-code": { info: { s: markedServiceCodes("bc_yourcode") } } };
// …register an extension that sets this `info` (or pass both codes to one that
//   accepts multiple). Discovery: settlements whose `s` includes AFFILIATION_MARKER.

See ../docs/INTEGRATION.md and ../python/x402aff/queries.sql #5.

Develop

npm run typecheck   # tsc --noEmit
npm test            # node --test (offline, mock viem transport)

Runs on Node ≥ 22.18 via built-in TypeScript type-stripping; no build step.