Supply

Merchants

Put a price on an HTTP route. Tollex handles the 402, verification, settlement and the receipt.

TypeScript · runs in the Tollex test suite
app.post(
  "/v1/forecast",
  paywall.protect({
    id: "forecast",
    description: "Seven-day demand forecast for a SKU",
    scheme: "exact",
    amount: usdg("0.002"),
    inputSchema: { type: "object", properties: { sku: { type: "string" } }, required: ["sku"] },
    tags: ["forecast", "retail"],
  }),
  async (c) => c.json({ sku: (await c.req.json()).sku, days: [12, 14, 11, 9, 15, 18, 16] }),
);

What the paywall guarantees

  • One execution per authorization. Authorizations are reserved durably before the handler runs. A replayed authorization gets the stored response or is refused; it never runs the handler twice.
  • Success-only charging. A handler that fails is not charged.
  • A receipt with every paid response, signed with your receipt key and published key set.
  • Settlement you can wait for. High-value routes can hold the result until a settlement assurance level is reached.
  • Reconciliation. Payments whose outcome is unknown are reconciled against the chain, not marked failed.

Metered and batch routes

For upto and batch-settlement, the handler reports what it used. The charge is computed from your declared unit price and capped at the ceiling the payer signed.

Reporting usage inside a metered handler
app.post("/generate", paywall.protect({ id: "generate", description: "Metered generation",
  scheme: "upto", amount: 50_000n, unitPrice: 10n }), async (c) => {
  const tokens = await generate(c);
  reportUsage(c, { units: BigInt(tokens), unit: "token" });
  return c.json({ tokens });
});

Other frameworks

The paywall is built on standard Request and Response objects. TollexMerchant wraps it as a web handler, with adapters for Express (expressHandler), Fastify (fastifyHandler) and Next.js route handlers (nextRouteHandler).