x402 payments in any ERC20 token

x402 payments in any ERC20 token

We've updated our x402 facilitator and SDK to support any token that supports ERC-2612 permit functionality. Supporting this popular signature standard opens up x402 payments to virtually any ERC20 token.

What's new

  • x402 facilitator and SDK now auto-detects ERC-2612 permit vs ERC-3009 transferWithAuthorization (USDC) and uses the right flow.
  • settlePayment and verifyPayment now accept any arbitrary chain.

Example

Client: pay-gated fetch using x402
auto detects ERC-2612 permit when supported, and signs the payment data accordingly.

import { wrapFetchWithPayment } from "thirdweb/x402";
import { createThirdwebClient } from "thirdweb";
import { createWallet } from "thirdweb/wallets";

const client = createThirdwebClient({ clientId: "your-client-id" });
const wallet = createWallet("io.metamask"); // or any other wallet
await wallet.connect({ client });

const fetchWithPay = wrapFetchWithPayment(fetch, client, wallet);

// Make a request that may require payment
const response = await fetchWithPay(
  "https://api.example.com/paid-endpoint",
);

Server: verify and settle via facilitator
When verifying/settling the payment define the price in the ERC20 token of your choice. Here's an example using $higher.

import { createThirdwebClient, toWei } from "thirdweb";
import { facilitator, settlePayment } from "thirdweb/x402";
import { base } from "thirdweb/chains";

const client = createThirdwebClient({ 
  secretKey: process.env.THIRDWEB_SECRET_KEY! 
});

const twFacilitator = facilitator({
  client,
  serverWalletAddress: "0xServerWalletAddress",
});

// e.g. Next.js Route Handler or middleware
export async function POST(req: Request) {
  const method = request.method.toUpperCase();
  const resourceUrl = request.nextUrl.toString();
  const paymentData = request.headers.get("X-PAYMENT");

  const result = await settlePayment({
    resourceUrl,
    method,
    paymentData,
    payTo: "0xTreasuryWalletAddress",
    network: base, // chain
    price: {
      amount: toWei("0.01"), // amount in wei
      asset: {
        address: "0x0578d8A44db98B23BF096A382e016e29a5Ce0ffe", // ERC-20 address
        decimals: 18,
        eip712: {
          name: "Higher",   // token's EIP-712 domain name
          version: "1",     // token's EIP-712 domain version
        },
      },
    },
  });

  if (result.ok) {
    return new Response(
     { message: "Payment successful" }, 
     { status: 200 }
    );
  }
  return new Response(
    result.responseBody, 
    { status: result.status, headers: result.responseHeaders, }
  );
}

Learn more

Happy building!