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

@countersign-hub/relay

v0.1.1

Published

Countersign relay: charge for your own API in USDT with a paywall and a pay-fetch client.

Readme

@countersign-hub/relay

Charge for an HTTP route in USDT on Whitechain, and pay for such a route from code. The payer holds USDT only, never WBT: a relay submits every transaction and pays the gas.

This runs on the testnet only: Whitechain testnet, chain id 1874. The settlement token is USDT 0xcedfB56113143d55b2358b8CFbB0dEB5Ad2f55a7.

Install

npm i @countersign-hub/relay
  • Runtime: Node 20 or later, or Bun. The package ships compiled JavaScript.
  • The merchant side is Hono middleware, so a merchant also runs npm i hono.

There is no root export. Import one of the three subpaths below.

Charge for a route (the merchant)

import { Hono } from "hono";
import { whitechainPaywall } from "@countersign-hub/relay/paywall";

const app = new Hono();
app.get(
  "/sticker-pack",
  whitechainPaywall({
    price: "0.01",
    payTo: "0xd5882dBC7D41fBcf8ae0B05E9eAc1cbe93d6C71c",
    facilitator: "https://whitechain-relay-production.up.railway.app",
    description: "sticker pack",
  }),
  (c) => c.json({ item: "sticker pack" }),
);
  • An unpaid request gets HTTP 402. Its PAYMENT-REQUIRED header carries an x402 v2 offer for 0.01 USDT on eip155:1874.
  • A paid request is verified and settled through the relay, then served.

The public relay above settles only for its own demo merchant, the payTo shown. It pays gas only for payees on its allowlist, so it refuses any other payTo as payee_not_registered. To charge to your own address, run your own relay: see packages/relay in the repository.

Pay for a route (the customer)

In a browser, pay from the person's own connected wallet; the page only asks it to sign:

import { createPayFetch, walletAccount } from "@countersign-hub/relay/browser";

// address and signTypedData come from the connected wallet (an injected wallet, or Privy).
const account = walletAccount(address, signTypedData);
const pay = createPayFetch({
  account,
  maxPerCall: "0.10",
  payTo: ["0xd5882dBC7D41fBcf8ae0B05E9eAc1cbe93d6C71c"],
});

const res = await pay("https://example.com/sticker-pack");
console.log(await res.json(), res.payment?.transaction);
  • How it pays: pay answers a 402 with one EIP-3009 authorization for the exact price, which the wallet signs. It then sends the request again with it.
  • What it refuses: it never signs for more than maxPerCall, or for a payTo outside the list.
  • The receipt: res.payment.transaction is the settlement transaction on chain 1874.
  • walletAccount signs typed data only.

Refund an order (the merchant)

import { refundOrder, walletAccount } from "@countersign-hub/relay/browser";

refundOrder({ relayUrl, merchant, order }) refunds an order through the relay:

  • A paid order: it signs an EIP-3009 transfer back to the customer. The transfer's nonce names the payment, so a double click refunds once.
  • A held escrow order: it signs a cancel.

The relay submits either one.

walletAccount(address, signTypedData) turns a connected browser wallet into the signer refundOrder takes. It signs typed data only.

Exports

| Import | What it gives you | |---|---| | @countersign-hub/relay/paywall | whitechainPaywall, Hono middleware that puts a USDT price on a route | | @countersign-hub/relay/pay-fetch | createPayFetch, a fetch that pays 402 answers | | @countersign-hub/relay/browser | the browser-safe set: createPayFetch, refundOrder, walletAccount, and the merchant's refund and cancel signers |

What the relay guards

The relay pays gas from its own wallet, so it guards that wallet. Its live state is at GET /status on the relay.

| Guard | What it does | |---|---| | Allowlist | It acts only for its own payees, token and escrows. | | Gas price cap | It refuses to send above its maximum fee. | | Hourly ceiling | It caps its WBT spend and its transactions per hour. | | Balance floor | It refuses new work rather than run dry in the middle of a payment. | | Simulation | Every call is simulated before it is sent, so a refusal costs no gas. |

Test funds and more

  • Getting testnet USDT, and the network details: docs/whitechain.md in the repository.
  • Repository: https://github.com/ss251/countersign, in packages/relay.
  • License: MIT.
  • Names on npm: only @countersign-hub is this project's. countersign, countersign-mcp and the @countersign scope belong to other projects.