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).
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.
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
| Role | Package | Adapter |
|---|
| Buyer | @tetherto/wdk-wallet-evm | None. WalletAccountEvm satisfies ClientEvmSigner directly. |
| Seller (hosted) | - | None. Use your address and point to Semantic’s facilitator. |
| Seller (self-hosted) | @semanticio/wdk-wallet-evm-x402-facilitator | Wraps WalletAccountEvm as FacilitatorEvmSigner. |
Next steps