createSeller mounts the real x402 middleware on the routes you choose and resolves payTo to the seller agent’s Asset Signer PDA, so funds land directly in the on-chain treasury — the seller agent never needs a private key.
import { Hono } from 'hono';
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCore } from '@metaplex-foundation/mpl-core';
import { createSeller } from '@leash/seller-kit';

const umi = createUmi(process.env.SOLANA_RPC ?? 'https://api.devnet.solana.com').use(mplCore());
const app = new Hono();

createSeller(app, {
  umi,
  sellerAgent: { asset: process.env.AGENT_ASSET! },
  routes: {
    'POST /tag': {
      price: '$0.001',
      description: 'Tag a payload',
      currency: 'USDC',
      acceptsCurrencies: [], // optional: e.g. ['USDG'] to also accept USDG
    },
  },
  onReceipt: (r) =>
    fetch(`http://localhost:8787/a/${r.agent}/receipts`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(r),
    }),
});

app.post('/tag', (c) => c.json({ tagged: true }));
Behaviour out of the box:
  • Unauthenticated requests → 402 + PAYMENT-REQUIRED (base64 JSON).
  • Settled requests → real handler runs, then an earn ReceiptV1 is emitted with the real tx_sig and payment_requirements_hash from the facilitator’s PAYMENT-RESPONSE.
  • Default facilitator: https://devnet-facilitator.leash.market (devnet) / https://facilitator.leash.market (mainnet). Override with LEASH_FACILITATOR_URL.

Probing without paying

curl -i -X POST http://localhost:3001/tag -d '{"hello":"leash"}'
# HTTP/1.1 402 Payment Required
# PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi…
Decode the header (base64 → JSON) to inspect the offer. The Seller playground does this for you. See Real x402 on Solana for the protocol-level walkthrough and how to swap facilitators. If you don’t want to host a Hono app, the playground at apps/web/seller is a Payment-Link Builder (“Stripe Payment Links for x402”): pick one of your agents, declare a method + path + price + response template, and the runner serves the result back as a real x402 paywall at https://<host>/x/<id> — same createSeller middleware under the hood. See Create a payment link for the full walkthrough.