Skip to main content
WDK (Wallet Development Kit) by Tether is an open-source toolkit for building multi-chain, self-custodial wallets. It handles key derivation, signing, and chain interactions across EVM, Bitcoin, Solana, Spark, and more. This guide covers using WDK with x402 as a buyer (paying for resources) and as a seller (accepting payments).
See a full working demo at github.com/SemanticPay/x402-usdt0-demo

Buyer

WalletAccountEvm satisfies the ClientEvmSigner interface that x402 expects. No adapter needed.
npm install @tetherto/wdk-wallet-evm @x402/fetch @x402/evm
import WalletManagerEvm from "@tetherto/wdk-wallet-evm";
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";

const account = await new WalletManagerEvm(process.env.SEED_PHRASE, {
  provider: "https://rpc.plasma.to",
}).getAccount();

const client = new x402Client();
registerExactEvmScheme(client, { signer: account });

const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment("https://api.example.com/data");
Keys are derived locally from the seed phrase and never leave your environment. See the buyer quickstart for the full walkthrough.

Seller

Option 1: Hosted facilitator

Use Semantic’s facilitator to handle verification and settlement. Your server never interacts with the chain directly.
  • Automatic verification of buyer payment signatures
  • No gas fees, no native token required in your wallet
  • No transaction monitoring or retry logic
  • No facilitator infrastructure to deploy
Derive a receiving address from your seed phrase:
npm install @tetherto/wdk-wallet-evm @x402/express @x402/evm @x402/core
import WalletManagerEvm from "@tetherto/wdk-wallet-evm";

const account = await new WalletManagerEvm(process.env.SEED_PHRASE, {
  provider: "https://rpc.plasma.to",
}).getAccount();

const sellerAddress = await account.getAddress();
Then wire up Express with paymentMiddleware pointing to Semantic’s facilitator:
import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { HTTPFacilitatorClient } from "@x402/core/server";

const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://x402.semanticpay.io/",
});

const app = express();

app.use(
  paymentMiddleware(
    {
      "GET /weather": {
        accepts: [
		{
            scheme: "exact",
            network: "eip155:9745", // Plasma mainnet
            price: {
              amount: "1000000", // $1.00 in base units (6 decimals)
              asset: "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb", // USDT0 contract on Plasma
              extra: { name: "USDT0", version: "1", decimals: 6 }, // EIP-712 domain for signature
            },
            payTo: sellerAddress,
          },
        ],
        description: "Weather data",
        mimeType: "application/json",
      },
    },
    new x402ResourceServer(facilitatorClient).register(
      "eip155:9745",
      new ExactEvmScheme()
    )
  )
);

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

app.listen(4021);
See the seller quickstart for the full walkthrough.

Option 2: Self-hosted facilitator

Run your own facilitator for full control over verification and settlement. The @semanticio/wdk-wallet-evm-x402-facilitator module wraps a WDK wallet as an x402 FacilitatorEvmSigner.
npm install @semanticio/wdk-wallet-evm-x402-facilitator @tetherto/wdk-wallet-evm @x402/core @x402/evm @x402/express

1. Create the facilitator signer

import WalletManagerEvm from "@tetherto/wdk-wallet-evm";
import WalletAccountEvmX402Facilitator from "@semanticio/wdk-wallet-evm-x402-facilitator";

const walletAccount = await new WalletManagerEvm(process.env.MNEMONIC, {
  provider: "https://rpc.plasma.to",
}).getAccount();

const evmSigner = new WalletAccountEvmX402Facilitator(walletAccount);

2. Initialize the facilitator

Register the signer with an x402Facilitator instance. Lifecycle hooks are optional but useful for logging:
import { x402Facilitator } from "@x402/core/facilitator";
import { registerExactEvmScheme } from "@x402/evm/exact/facilitator";

const facilitator = new x402Facilitator()
  .onAfterVerify(async (ctx) => {
    console.log(`[verify] valid=${ctx.result?.isValid}`);
  })
  .onAfterSettle(async (ctx) => {
    console.log(`[settle] tx=${ctx.result?.transaction}`);
  });

registerExactEvmScheme(facilitator, {
  signer: evmSigner,
  networks: "eip155:9745",
});

3. Wire into Express

Same paymentMiddleware pattern as the hosted facilitator, but instead of an HTTPFacilitatorClient, pass the in-process facilitator directly to x402ResourceServer. Verification and settlement happen locally. For a complete working example, see server.js.
@semanticio/wdk-wallet-evm-x402-facilitator is currently in beta. Test thoroughly before using in production.

Summary

RolePackageAdapter
Buyer@tetherto/wdk-wallet-evmNone. WalletAccountEvm satisfies ClientEvmSigner directly.
Seller (hosted)-None. Use your address and point to Semantic’s facilitator.
Seller (self-hosted)@semanticio/wdk-wallet-evm-x402-facilitatorWraps WalletAccountEvm as FacilitatorEvmSigner.

Next steps

Last modified on February 19, 2026