Skip to main content
This guide puts an x402 paywall in front of an HTTP endpoint using the Tentacle Pay facilitator. The example uses Hono, but the same pattern works with any x402 server adapter (Express, Next.js, Fastify, and others).

Full example on GitHub

The complete, runnable version of this guide — examples/x402/exact/server.ts.

Prerequisites

  • A Sui address to receive payments
  • Node.js 24+ (or any runtime with WebCrypto and fetch)
  • A server framework supported by x402 — this guide uses Hono

1. Install dependencies

npm install @tentaclepay/sui-x402 @x402/core @x402/hono hono @hono/node-server

2. Point at the facilitator

Create an HTTPFacilitatorClient targeting https://facilitator.tentaclepay.com. This client handles the /verify and /settle round trips on your behalf.
server.ts
import { serve } from "@hono/node-server";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { paymentMiddleware, x402ResourceServer } from "@x402/hono";
import { Hono } from "hono";
import { logger } from "hono/logger";

import { ExactSuiScheme } from "@tentaclepay/sui-x402/exact/server";

const suiAddress = "0xYourSuiAddress"; // where payments settle

const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://facilitator.tentaclepay.com",
});

const app = new Hono();
app.use(logger());

3. Register the Sui scheme and protect a route

@tentaclepay/sui-x402/exact/server exports ExactSuiScheme, pre-configured for Sui’s default stablecoin. It resolves USD-style prices (for example "$0.01") to the correct token amount automatically.
server.ts
app.use(
  paymentMiddleware(
    {
      "GET /weather": {
        accepts: [
          {
            scheme: "exact",
            price: "$0.01",
            network: "sui:testnet",
            payTo: suiAddress,
          },
        ],
        description: "Weather data",
        mimeType: "application/json",
      },
    },
    new x402ResourceServer(facilitatorClient).register(
      "sui:testnet",
      new ExactSuiScheme()
    )
  )
);

app.get("/weather", (c) =>
  c.json({ report: { weather: "sunny", temperature: 70 } })
);

serve(app, (info) => {
  console.info(`Server running on port ${info.port}`);
});
Use "sui:mainnet" instead of "sui:testnet" to charge on Sui Mainnet. Register the matching network on the x402ResourceServer too.

4. Test it

Start your server and hit the protected route without a payment:
curl -i http://localhost:3000/weather
You should see a 402 Payment Required response with the accepts list in the body. Any x402-compatible client can now pay this endpoint — see Quickstart for agents.

Route configuration reference

Each protected route declares one or more accepts entries. A client picks the first entry it supports.
FieldDescription
scheme"exact" for a fixed price.
priceUSD-style string (for example "$0.01") or an atomic token amount as a string.
networkCAIP-2 network ID — sui:mainnet or sui:testnet.
payToSui address that receives the payment.

Pricing in a specific token

By default, ExactSuiScheme prices routes in USDC. To charge in another token or with an exact atomic amount, pass an AssetAmount as the price instead of a USD string:
accepts: [
  {
    scheme: "exact",
    price: { amount: "10000", asset: "0x…::usdc::USDC" }, // 0.01 USDC (6 decimals)
    network: "sui:mainnet",
    payTo: suiAddress,
  },
],
See Supported networks for coin types and decimals.

Using another framework

The only Tentacle Pay-specific wiring is the ExactSuiScheme import and the HTTPFacilitatorClient URL. The rest is standard x402 — swap @x402/hono for @x402/express, @x402/next, or another adapter and keep the same middleware contract.