From 2e8fca47269491c0a428b1b7baae15f54888c8c6 Mon Sep 17 00:00:00 2001 From: Joaquim Verges Date: Fri, 10 Oct 2025 10:13:35 +1300 Subject: [PATCH] [Playground] Add payTo parameter to X402 payment API --- .../src/app/api/paywall/route.ts | 33 ++++++++++--------- .../x402/components/X402LeftSection.tsx | 24 ++++++++++++++ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/apps/playground-web/src/app/api/paywall/route.ts b/apps/playground-web/src/app/api/paywall/route.ts index f32638cd635..96a7534f573 100644 --- a/apps/playground-web/src/app/api/paywall/route.ts +++ b/apps/playground-web/src/app/api/paywall/route.ts @@ -7,24 +7,25 @@ import { token } from "../../payments/x402/components/constants"; // Allow streaming responses up to 5 minutes export const maxDuration = 300; -export async function GET(request: NextRequest) { - const client = createThirdwebClient({ - secretKey: process.env.THIRDWEB_SECRET_KEY as string, - }); +const client = createThirdwebClient({ + secretKey: process.env.THIRDWEB_SECRET_KEY as string, +}); - const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_WALLET as string; - // const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_SMART_WALLET as string; - const ENGINE_VAULT_ACCESS_TOKEN = process.env - .ENGINE_VAULT_ACCESS_TOKEN as string; - const API_URL = `https://${process.env.NEXT_PUBLIC_API_URL || "api.thirdweb.com"}`; +const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_WALLET as string; +// const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_SMART_WALLET as string; +const ENGINE_VAULT_ACCESS_TOKEN = process.env + .ENGINE_VAULT_ACCESS_TOKEN as string; +// const API_URL = `https://${process.env.NEXT_PUBLIC_API_URL || "api.thirdweb.com"}`; +const API_URL = "http://localhost:3030"; - const twFacilitator = facilitator({ - baseUrl: `${API_URL}/v1/payments/x402`, - client, - serverWalletAddress: BACKEND_WALLET_ADDRESS, - vaultAccessToken: ENGINE_VAULT_ACCESS_TOKEN, - }); +const twFacilitator = facilitator({ + baseUrl: `${API_URL}/v1/payments/x402`, + client, + serverWalletAddress: BACKEND_WALLET_ADDRESS, + vaultAccessToken: ENGINE_VAULT_ACCESS_TOKEN, +}); +export async function GET(request: NextRequest) { const paymentData = request.headers.get("X-PAYMENT"); const queryParams = request.nextUrl.searchParams; @@ -38,6 +39,7 @@ export async function GET(request: NextRequest) { } const amount = queryParams.get("amount") || "0.01"; + const payTo = queryParams.get("payTo") ?? undefined; const tokenAddress = queryParams.get("tokenAddress") || token.address; const decimals = queryParams.get("decimals") || token.decimals.toString(); const waitUntil = @@ -49,6 +51,7 @@ export async function GET(request: NextRequest) { method: "GET", paymentData, network: defineChain(Number(chainId)), + payTo, price: { amount: toUnits(amount, parseInt(decimals)).toString(), asset: { diff --git a/apps/playground-web/src/app/payments/x402/components/X402LeftSection.tsx b/apps/playground-web/src/app/payments/x402/components/X402LeftSection.tsx index 977a73bd747..2709d5eec4b 100644 --- a/apps/playground-web/src/app/payments/x402/components/X402LeftSection.tsx +++ b/apps/playground-web/src/app/payments/x402/components/X402LeftSection.tsx @@ -45,6 +45,7 @@ export function X402LeftSection(props: { const tokenId = useId(); const amountId = useId(); const waitUntilId = useId(); + const payToId = useId(); const handleChainChange = (chainId: number) => { setSelectedChain(chainId); @@ -81,6 +82,13 @@ export function X402LeftSection(props: { })); }; + const handlePayToChange = (e: React.ChangeEvent) => { + setOptions((v) => ({ + ...v, + payTo: e.target.value as `0x${string}`, + })); + }; + const handleWaitUntilChange = ( value: "simulated" | "submitted" | "confirmed", ) => { @@ -140,6 +148,22 @@ export function X402LeftSection(props: { )} + {/* Pay To input */} +
+ + +

+ The wallet address that will receive the payment +

+
+ {/* Wait Until selection */}