用 x402 v2 SDK 构建 Farcaster Mini App:Next.js 支付保护 API 全流程实战 用 x402 v2 SDK 构建 Farcaster Mini AppNext.js 支付保护 API 全流程实战【免费下载链接】x402A payments protocol for the internet. Built on HTTP.项目地址: https://gitcode.com/GitHub_Trending/x4/x402这篇技术指南以仓库中的 x402 Farcaster Mini App 示例 为骨架讲解如何用 Next.js 15/16 App Router、x402 v2 SDKx402/next、x402/fetch、x402/evm与 Farcaster Mini App SDK 搭建一个先付费、后访问的受保护 API 全栈应用。读完本文你将掌握服务端withX402路由保护、客户端wrapFetchWithPayment自动支付、Farcaster Mini App 清单Manifest配置以及 402 响应格式的完整调用链与底层实现原理。前置条件与项目结构示例项目位于仓库的examples/typescript/fullstack/miniapp/目录是一个基于 Next.js 的完整全栈示例。运行它需要满足以下条件Node.js 22pnpm v10示例使用 pnpm workspace 管理多个 TypeScript 包Base Sepolia 测试网上的 USDC用于真实支付测试从 package.json 可以看到项目的依赖组成它们清晰地划分了职责依赖包用途x402/corex402 协议核心资源服务器x402ResourceServer、facilitator 客户端、类型定义x402/evmEVM 网络的 exact 支付方案服务端验签 / 客户端签名x402/fetch客户端 fetch 包装自动处理 402 支付流程x402/nextNext.js 专属适配层提供withX402与支付代理coinbase/onchainkit钱包连接 UIConnectWallet、WalletDropdown 等farcaster/miniapp-sdkFarcaster Mini App 上下文检测与交互wagmi/viem钱包客户端与链交互用于构造 EVM 签名器需要说明的是示例通过 pnpm workspace 直接以workspace:*引用x402/*各包源码因此第一步必须先构建所有依赖包示例才能正常运行。快速启动五步跑通示例按 README 的指引从 typescript examples 根目录开始操作# 1. 回到 typescript examples 根目录安装依赖并构建所有 workspace 包 cd ../../ pnpm install pnpm build cd fullstack/miniapp # 2. 复制本地环境变量模板 cp .env-local .env之后根据下面的环境变量配置章节填写.env然后启动开发服务器pnpm dev浏览器打开http://localhost:3000即可看到页面。页面右上角是 OnchainKit 的钱包连接组件连接钱包并持有 Base Sepolia USDC后点击Call Protected API ($0.01)按钮即可体验一次真实的 x402 支付流程。环境变量配置必需的五个变量在.env中需要配置以下变量其中前两个是 x402 支付配置的核心缺一不可# x402 Payment Configuration (required) FACILITATOR_URLhttps://x402.org/facilitator EVM_ADDRESS0xYourWalletAddress # OnchainKit Configuration NEXT_PUBLIC_ONCHAINKIT_API_KEYyour_onchainkit_api_key_here NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAMEx402 Mini App # App URLs and Images NEXT_PUBLIC_URLhttp://localhost:3000 NEXT_PUBLIC_APP_HERO_IMAGEhttps://example.com/app-logo.png NEXT_PUBLIC_SPLASH_IMAGEhttps://example.com/app-logo-200x200.png NEXT_PUBLIC_SPLASH_BACKGROUND_COLOR#3b82f6 NEXT_PUBLIC_ICON_URLhttps://example.com/app-logo.png各变量说明FACILITATOR_URLfacilitator 服务地址。facilitator 是 x402 协议中负责协调证明收款的角色可以使用公共 facilitator也可以自行部署。EVM_ADDRESS收款钱包地址所有支付最终汇入该地址。NEXT_PUBLIC_ONCHAINKIT_API_KEYOnchainKit 的 API Key从 OnchainKit 开发者平台获取。NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAME项目名称用于钱包 UI 展示。NEXT_PUBLIC_URL应用对外域名开发环境为http://localhost:3000发布前必须改为生产域名同时影响minikit.config.ts中的homeUrl等字段。图片类变量NEXT_PUBLIC_APP_HERO_IMAGE、NEXT_PUBLIC_SPLASH_IMAGE、NEXT_PUBLIC_ICON_URL与NEXT_PUBLIC_SPLASH_BACKGROUND_COLOR分别对应 Mini App 的 hero 图、启动图、图标与启动背景色。这些变量并非全部是纸面配置——它们在源码中真实生效在 app/api/protected/route.ts 中FACILITATOR_URL与EVM_ADDRESS在模块加载时即被读取缺失会直接process.exit(1)终止进程并打印错误提示在 minikit.config.ts 中NEXT_PUBLIC_URL被用于拼接homeUrl、webhookUrl与各图片 URL 的默认值。服务端支付保护withX402 包装器路由实现示例的核心受保护接口是GET /api/protected完整实现见 app/api/protected/route.ts。其骨架如下import { NextRequest, NextResponse } from next/server; import { withX402 } from x402/next; import { x402ResourceServer, HTTPFacilitatorClient } from x402/core/server; import { ExactEvmScheme } from x402/evm/exact/server; const facilitatorClient new HTTPFacilitatorClient({ url: facilitatorUrl }); const server new x402ResourceServer(facilitatorClient); server.register(eip155:*, new ExactEvmScheme()); const handler async (_: NextRequest) { return NextResponse.json({ success: true, message: Protected action completed successfully, timestamp: new Date().toISOString(), data: { secretMessage: This content was paid for with x402!, accessedAt: Date.now(), }, }); }; export const GET withX402( handler, { accepts: [ { scheme: exact, price: $0.01, network: eip155:84532, // base-sepolia payTo: evmAddress, }, ], description: Access to protected Mini App API, mimeType: application/json, }, server, );代码分三层理解HTTPFacilitatorClient封装与 facilitator 的 HTTP 通信用于支付验证与结算。x402ResourceServerregister(eip155:*, new ExactEvmScheme())资源服务器按网络标识注册支付方案。eip155:*是通配注册表示所有 EVM 链都使用 ExactEvmScheme实际生效网络由请求中的支付要求accepts限定。withX402(handler, routeConfig, server)将普通路由处理器包装为先验支付、后执行、成功后结算的受保护路由。routeConfig中的关键字段scheme: exact表示采用 exact 支付方案固定金额price: $0.01指定美元计价金额network: eip155:84532指定 Base SepoliapayTo为收款地址mimeType声明响应媒体类型。withX402 的底层原理withX402实现在 typescript/packages/http/next/src/index.ts。源码注释特别强调与paymentProxymiddleware 形式不同withX402只包裹单个路由处理器并且保证支付结算只会在处理器返回成功响应HTTP 状态码 400之后才发生——这正是示例路由中注释 Payment is only settled after a successful response (status 400) 的来源避免用户付了钱但 API 出错的体验问题。其执行流程对应withX402FromHTTPServer的实现为首次请求时惰性初始化prepareHttpServer内的init同步 facilitator 配置用NextAdapter将NextRequest适配为协议无关的HTTPAdapter请求上下文见 adapter.ts负责抽取 header、method、path、query 与 body调用httpServer.processHTTPRequest处理支付要求产生三种结果no-payment-required直接放行到路由处理器payment-error返回支付错误响应如校验失败、facilitator 拒绝payment-verified先执行路由处理器拿到响应再通过handleSettlement完成结算后才返回给客户端。此外x402/next还导出了paymentProxy、paymentProxyFromHTTPServer、paymentProxyFromConfig三种代理形式适用于proxy.ts/ middleware 场景可按需选用。客户端支付处理wrapFetchWithPayment前端在 app/page.tsx 中完成支付侧逻辑核心调用如下import { x402Client, wrapFetchWithPayment } from x402/fetch; import { ExactEvmScheme } from x402/evm/exact/client; import { toClientEvmSigner } from x402/evm; import type { ClientEvmSigner } from x402/evm; // 将 wagmi/viem 的 WalletClient 适配为 x402 的 ClientEvmSigner function wagmiToClientSigner(walletClient, publicClient): ClientEvmSigner { return toClientEvmSigner( { address: walletClient.account.address, signTypedData: async (message) walletClient.signTypedData({ account: walletClient.account, domain: message.domain, types: message.types, primaryType: message.primaryType, message: message.message, }), }, { readContract: (args) publicClient.readContract(args) } ); } // 创建 x402 客户端并注册 EVM 方案带钱包签名器 const client new x402Client(); const signer wagmiToClientSigner(walletClient, publicClient); client.register(eip155:*, new ExactEvmScheme(signer)); // 包装 fetch支付自动完成 const fetchWithPayment wrapFetchWithPayment(fetch, client); const response await fetchWithPayment(/api/protected, { method: GET });这段代码解决了两个关键问题签名器桥接示例封装了wagmiToClientSigner用toClientEvmSigner将 viemWalletClient的signTypedData与readContract适配为x402/evm所需的ClientEvmSigner这是 EVM 钱包签名与 x402 EIP-712 类型化数据签名打通的关键。自动支付重试wrapFetchWithPayment的实现见 typescript/packages/http/fetch/src/index.ts其工作流程是先发出普通请求若响应状态不是 402直接原样返回若收到 402则从PAYMENT-REQUIRED响应头v2或响应体 JSONv1 兼容解析支付要求用已注册的 scheme 生成支付头自动重放请求完成支付。页面交互上还做了两处细节处理见 app/page.tsx连接钱包后若当前链不是 Base Sepolia会自动调用switchChainAsync切换链再签名点击按钮期间显示 Processing 状态防止重复点击。Farcaster Mini App 集成与清单配置上下文检测在 Mini App 环境内运行时应用通过farcaster/miniapp-sdk主动上报就绪并检测运行环境import { sdk } from farcaster/miniapp-sdk; await sdk.actions.ready(); const isInMiniApp await sdk.isInMiniApp();示例页面据此显示 Running as Mini App / Running in browser 状态标识同时通过coinbase/onchainkit/minikit的useMiniKit设置setMiniAppReady并用useAddFrame提供保存到应用Save App入口。Manifest 与发布前检查清单Mini App 需要提供/.well-known/farcaster.json清单配置集中在 minikit.config.ts。完整的miniapp字段比 README 展示的更丰富export const minikitConfig { accountAssociation: { header: , // 在 https://warpcast.com/~/developers/mini-apps/manifest 生成 payload: , signature: , }, baseBuilder: { ownerAddress: 0xYourWalletAddress, }, miniapp: { version: 1, name: x402 Mini App, subtitle: Payment-protected APIs, description: A Farcaster Mini App with payment protected endpoints, screenshotUrls: [], iconUrl: process.env.NEXT_PUBLIC_ICON_URL || ${ROOT_URL}/icon.png, splashImageUrl: process.env.NEXT_PUBLIC_SPLASH_IMAGE || ${ROOT_URL}/splash.png, splashBackgroundColor: process.env.NEXT_PUBLIC_SPLASH_BACKGROUND_COLOR || #3b82f6, homeUrl: ROOT_URL, webhookUrl: ${ROOT_URL}/api/webhook, primaryCategory: developer-tools, tags: [payments], heroImageUrl: process.env.NEXT_PUBLIC_APP_HERO_IMAGE || ${ROOT_URL}/hero.png, tagline: Payment Protocol, ogTitle: Mini App, ogDescription: Payment protected APIs, ogImageUrl: process.env.NEXT_PUBLIC_APP_HERO_IMAGE || ${ROOT_URL}/hero.png, }, };注意ROOT_URL的解析顺序minikit.config.ts优先取NEXT_PUBLIC_URL其次取VERCEL_URL部署到 Vercel 时自动生效最后回退到http://localhost:3000。发布前必须完成的四项检查README 明确列出使用 Base Dev Mini App Tools 或 Farcaster Manifest 工具生成accountAssociationheader / payload / signature 三项签名数据将baseBuilder.ownerAddress设置为你自己的钱包地址将NEXT_PUBLIC_URL设置为生产域名确认图片尺寸与格式符合要求iconUrl为 1024x1024px PNG无 alpha 通道splashImageUrl为 200x200pxheroImageUrl为 1200x630px宽高比 1.91:1。响应格式402 与成功响应的协议细节Payment Required402当未携带有效支付时服务端返回如下响应HTTP/1.1 402 Payment Required Content-Type: application/json PAYMENT-REQUIRED: base64-encoded JSONPAYMENT-REQUIRED响应头中包含解码后的支付要求v2 协议{ x402Version: 2, error: Payment required, accepts: [ { scheme: exact, network: eip155:84532, amount: 10000, asset: 0x036CbD53842c5426634e7929541eC2318f3dCF7e, payTo: 0x..., maxTimeoutSeconds: 300, extra: { name: USDC, version: 2 } } ] }各字段含义scheme为支付方案exactnetwork为 CAIP-2 网络标识amount为代币最小单位的整数金额10000即 0.01 USDCUSDC 精度 6 位asset为代币合约地址0x036CbD...即 Base Sepolia 上的 USDCpayTo为收款方maxTimeoutSeconds为支付超时窗口extra携带代币名称与版本等元信息。前端wrapFetchWithPayment正是解析该头并按accepts生成支付。成功响应支付验证通过后路由处理器返回{ success: true, message: Protected action completed successfully, timestamp: 2024-01-01T00:00:00Z, data: { secretMessage: This content was paid for with x402!, accessedAt: 1704067200000 } }响应体结构对应 app/api/protected/route.ts 中 handler 的返回值timestamp由new Date().toISOString()生成data.accessedAt为Date.now()毫秒时间戳。扩展示例新增受保护路由与网络标识添加更多受保护路由以新增一个价格为 $0.10 的 premium 路由为例在app/api/premium/route.ts中重复同样的模式即可import { NextRequest, NextResponse } from next/server; import { withX402 } from x402/next; import { x402ResourceServer, HTTPFacilitatorClient } from x402/core/server; import { registerExactEvmScheme } from x402/evm/exact/server; const facilitatorClient new HTTPFacilitatorClient({ url: process.env.FACILITATOR_URL, }); const server new x402ResourceServer(facilitatorClient); registerExactEvmScheme(server); const handler async (_: NextRequest) { return NextResponse.json({ message: Premium content! }); }; export const GET withX402( handler, { accepts: [ { scheme: exact, price: $0.10, network: eip155:84532, payTo: process.env.EVM_ADDRESS, }, ], description: Premium content access, mimeType: application/json, }, server, );定价差异仅体现在accepts[].price字段上其余结构完全一致说明价格与路由是解耦的——同一套支付保护基础设施可以服务于任意多条、任意定价的接口。网络标识CAIP-2network字段使用 CAIP-2 格式的链标识示例中涉及两条链eip155:84532— Base Sepolia测试网eip155:8453— Base Mainnet主网切换主网时只需将路由配置中的network改为eip155:8453并确保payTo地址与 USDC 资产在对应网络上可用即可。这一设计也与服务端server.register(eip155:*, new ExactEvmScheme())的通配注册方式相配合支付方案按链族注册具体网络由请求侧决定。总结与进一步探索本示例展示了 x402 v2 协议在真实全栈场景下的标准落地方式服务端用withX402x402ResourceServer声明式保护任意 Next.js API 路由客户端用wrapFetchWithPayment把解析 402 → 签名支付 → 自动重试整条链路封装成一行调用中间由 facilitator 完成支付验证与结算协调。如果想要深入理解协议本身可以继续阅读仓库中的 x402-specification-v2.md 与 http.mdx402/next的完整 APIpaymentProxy、paymentProxyFromConfig、withX402FromHTTPServer等见 typescript/packages/http/next/src/index.tswrapFetchWithPayment的完整重试与钩子逻辑见 typescript/packages/http/fetch/src/index.ts。其余语言的等价实现可参考 typescript/examples、python/examples 与 go/examples 目录。【免费下载链接】x402A payments protocol for the internet. Built on HTTP.项目地址: https://gitcode.com/GitHub_Trending/x4/x402创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考