@leashmarket/seller-kit mounts the real @x402/hono middleware on a list of METHOD /path routes and resolves payTo to the seller agent’s Asset Signer PDA so funds land directly in the agent’s treasury. If your seller route is also published as an identity capability, emit the same identity metadata next to the endpoint with buildSellerIdentityMetadata. Buyer agents can feed that selector and capability card into POST /v1/identity/verify before paying:
import { buildSellerIdentityMetadata } from '@leashmarket/seller-kit';

const identity = buildSellerIdentityMetadata({
  agent_mint: '<seller agent mint>',
  handle: 'quote-agent',
  domain: 'seller.example',
  capabilities: ['seller_api:sol-usd-quote', 'protocol:x402'],
  capability_cards: [{ kind: 'seller_api', slug: 'seller/quote-api', protocol: 'x402' }],
});
The helper returns { leash: { identity: { v: "0.1", ... } } }, so you can attach it to hosted payment-link metadata, your own API discovery JSON, or any directory listing that wants to make seller identity verifiable.
import { Hono } from 'hono';
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCore } from '@metaplex-foundation/mpl-core';
import { createSeller } from '@leashmarket/seller-kit';

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

createSeller(app, {
  umi,
  sellerAgent: { asset: '<your Core asset mint>' },
  routes: {
    // Primary settlement currency + optional extra stables in x402 `accepts[]`.
    // Buyers can pay in any listed mint (same atomic amount per option).
    'POST /tag': {
      price: '$0.001',
      description: 'Tag a payload',
      currency: 'USDC',
      acceptsCurrencies: ['USDG'], // also accept USDG on the same route
    },
  },
  onReceipt: async (r) => {
    await 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 }));

What createSeller actually does

  1. Resolves the seller agent’s Asset Signer PDA via mpl-core and derives the on-chain destination for SPL transfers (payTo). All x402 settlements credit this PDA, so the agent’s treasury balance grows automatically as buyers pay.
  2. Builds a createSvmResourceServer (from @leashmarket/seller-kit/x402) bound to facilitator-devnet.leash.market on solana-devnet (or the network you configure) by default. Other facilitators are fully supported — see Configuring the facilitator. The facilitator pays the network fee on payTo so neither the seller nor the buyer needs SOL on the receiving side.
  3. Registers paymentMiddlewareFromHTTPServer from @x402/hono for each route. Unauthenticated requests get 402 Payment Required with a base64-encoded PAYMENT-REQUIRED header that lists the accepts[] (one entry per accepted stablecoin: asset mint, atomic amount, payTo, fee payer, scheme). When you set currency plus acceptsCurrencies, the seller advertises multiple mints at the same price so buyers can pick e.g. USDG while the link is priced in USDC.
  4. After settlement, the onAfterSettle hook produces an earn ReceiptV1 with the real tx_sig + payment_requirements_hash and ships it through the resolved receipt sink (see below).

Receipts by default

onReceipt is now optional. When LEASH_API_URL + LEASH_API_KEY (or LEASH_RUNNER_URL) are set in the environment, every earn receipt is forwarded automatically to those destinations. Pass onReceipt: false to opt out, or set receipts: { runnerUrl, apiUrl, apiKey } to override. The full defaulting logic is shared with the buyer kit and documented in Receipts by default.

Probing without paying

curl -i -X POST http://localhost:3001/tag -d '{"hello":"leash"}'
# HTTP/1.1 402 Payment Required
# PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi…
Decode PAYMENT-REQUIRED (base64 → JSON) to see the offer. The web playground at /seller does this for you.

Configuring the facilitator

The default is https://facilitator-devnet.leash.market (devnet) / https://facilitator.leash.market (mainnet). To use a different HTTPS-compatible facilitator:
import { createSvmResourceServer } from '@leashmarket/seller-kit/x402';

const server = createSvmResourceServer({
  network: 'solana-devnet',
  payTo,
  asset: '<USDC mint>',
  facilitatorUrl: 'https://your-facilitator.example.com',
});
See Real x402 on Solana for the protocol-level walkthrough.

MPP (createMppSeller)

For sellers that emit application/problem+json challenges and settle via a facilitator’s POST /mpp/settle, mount createMppSeller from @leashmarket/seller-kit instead of createSeller. The same Asset Signer PDA treasury model applies; only the paywall wire format and settlement path differ. If you use hosted payment links instead of self-hosting, set protocol: "mpp" on Payment links so runners and buyers see consistent payment_protocol. See MPP on Solana (Leash).

HTTP equivalent (polyglot SDKs)

If you’re not on TypeScript, the same primitives are exposed as REST under /v1/seller/* and /v1/payment-links. The Seller utilities page covers parse-price, facilitator, networks, and pay-to. The Payment links page covers the hosted-paywall shape — declare a price + a response template, get a sharable URL. Both surfaces produce the same on-chain result and the same explorer entries as createSeller does in-process.