X402,一个静态博客盈利化练习

Hacker News Top 工具

摘要

一位开发者使用 Cloudflare Workers 上的 x402 支付中间件为静态博客实现付费墙,探索基于微交易的盈利模式以替代广告收入的潜力。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/06 14:04

# x402,一个静态博客货币化实验 来源:https://shtein.me/posts/x402-poc/ ## x402 Cloudflare 几天前发布了一篇关于 Monetization Gateway 上线的公告 (https://blog.cloudflare.com/monetization-gateway/)。这具有革命性意义,原因很多。它降低了货币化的高门槛,让你能精确控制收费对象和最低支付额度。这实际上可能改变我们使用互联网的方式,让互联网赖以生存的广告经济过时。 这听起来像是博客或 API 货币化的理想工具。尽管我没有什么可货币化的东西,但这项技术似乎太重要了,我不能不尝试一下。那就开始吧。 ## 计划 不幸的是,Cloudflare 的服务似乎仍处于封闭测试阶段(?),这意味着你目前无法自由获取访问权限,需要加入等待列表。所以我们只能自己实现这个功能。这其实更有趣,不是吗?幸运的是,它的设置相当简单。虽然需要给静态博客添加几个活动组件,但没有什么是一天内不能加装的。 那么,我们需要什么才能让这件事工作起来? 1. 一个接收资金的钱包 2. 一个执行支付处理逻辑的 Worker 3. 我们想要设置付费墙的资源 我有第 1 和第 3 项,但没有第 2 项。目前这里我将使用 Cloudflare Workers,因为我的站点就托管在那里。这也决定了我们实现它的语言选择:TypeScript。也许以后我会重新实现它,让它托管在我的本地服务器上,但为了控制实验范围——暂时还是用 Cloudflare。 ## 中间件 那么我们直接开始。我们需要的第一件事是一个中间件,它接收请求,确保只有在支付后才授予访问权限,并处理价格披露。官方文档有一个如何在 Hono 中实现它的示例 (https://docs.x402.org/getting-started/quickstart-for-sellers#2-add-payment-middleware),我们将使用这个示例。做一些修改以适应代码在 Cloudflare Worker 上运行而不是独立服务器的情况,放入我们的钱包,并将示例端点替换为更有用的端点——我们就得到了这个: ``` import { Hono } from "hono"; import type { MiddlewareHandler } from "hono"; import { paymentMiddleware, x402ResourceServer } from "@x402/hono"; import { ExactEvmScheme } from "@x402/evm/exact/server"; import { ExactSvmScheme } from "@x402/svm/exact/server"; import { HTTPFacilitatorClient } from "@x402/core/server"; const app = new Hono(); const evmAddress = "0xD040AEACCdFf083C5D4cB221F1533e8719a84F0e"; const svmAddress = "HjexCvNzgxJT3Ni7rb98WF4pQGEX2fN7G6Zh26B19mBc"; const facilitatorClient = new HTTPFacilitatorClient({ url: "https://x402.org/facilitator", }); let payment: MiddlewareHandler | undefined; app.use(async (c, next) => { payment ??= paymentMiddleware( { "GET /api/joke": { accepts: [ { scheme: "exact", price: "$0.01", network: "eip155:84532", payTo: evmAddress, }, { scheme: "exact", price: "$0.01", network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", payTo: svmAddress, }, ], description: "A premium, hand-picked joke", mimeType: "application/json", }, }, new x402ResourceServer(facilitatorClient) .register("eip155:84532", new ExactEvmScheme()) .register("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", new ExactSvmScheme()), ); return payment(c, next); }); const jokes = []; app.get("/api/joke", (c) => { return c.json({ joke: jokes[Math.floor(Math.random() * jokes.length)], }); }); export default app; ``` Worker 还需要一个 `wrangler.jsonc`(Cloudflare 专用配置): ``` { "name": "x402-poc", "main": "src/index.ts", "compatibility_date": "2026-07-01", "compatibility_flags": ["nodejs_compat"], "env": { "production": { "name": "x402-poc", "routes": [ { "pattern": "shtein.me/api/*", "zone_name": "shtein.me" } ] } } } ``` 其中有两个不太明显的点:`nodejs_compat` 是必需的,因为 x402 包导入了 Node 内置模块(`events`、`crypto`、`url`),没有它构建会失败。而路由是有意只定义在 `production` 环境中:定义了路由后,`wrangler dev` 会模拟该路由的主机,因此中间件生成的 URL 会指向真实域名而不是 localhost。 本地运行: ``` npx wrangler dev ``` 发送一个测试请求——我们看到了付费墙: ``` curl -i http://localhost:8787/api/joke HTTP/1.1 402 Payment Required Content-Length: 2 Content-Type: application/json PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQYXltZW50IHJlcXVpcmVkIiwicmVzb3VyY2UiOnsidXJsIjoiaHR0cDovL2xvY2FsaG9zdDo4Nzg3L2FwaS9qb2tlIiwiZGVzY3JpcHRpb24iOiJBIHByZW1pdW0sIGhhbmQtcGlja2VkIGpva2UiLCJtaW1lVHlwZSI6ImFwcGxpY2F0aW9uL2pzb24ifSwiYWNjZXB0cyI6W3sic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiZWlwMTU1Ojg0NTMyIiwiYW1vdW50IjoiMTAwMDAiLCJhc3NldCI6IjB4MDM2Q2JENTM4NDJjNTQyNjYzNGU3OTI5NTQxZUMyMzE4ZjNkQ0Y3ZSIsInBheVRvIjoiMHhEMDQwQUVBQ0NkRmYwODNDNUQ0Y0IyMjFGMTUzM2U4NzE5YTg0RjBlIiwibWF4VGltZW91dFNlY29uZHMiOjMwMCwiZXh0cmEiOnsibmFtZSI6IlVTREMiLCJ2ZXJzaW9uIjoiMiJ9fSx7InNjaGVtZSI6ImV4YWN0IiwibmV0d29yayI6InNvbGFuYTpFdFdUUkFCWmFZcTZpTWZlWUtvdVJ1MTY2VlUyeHFhMSIsImFtb3VudCI6IjEwMDAwIiwiYXNzZXQiOiI0ek1NQzlzcnQ1Umk1WDE0R0FnWGhhSGlpM0duUEFFRVJZUEpnWkpEbmNEVSIsInBheVRvIjoiSGpleEN2TnpneEpUM05pN3JiOThXRjRwUUdFWDJmTjdHNlpoMjZCMTltQmMiLCJtYXhUaW1lb3V0U2Vjb25kcyI6MzAwLCJleHRyYSI6eyJmZWVQYXllciI6IkNLUEtKV05kSkVxYTgxeDdDa1oxNEJWUGlZNnkxNlN4czdvd3pucXRXWXA1In19XX0= ``` `PAYMENT-REQUIRED` 标头是 base64 编码的接受的支付方式和价格列表: ``` { "x402Version": 2, "error": "Payment required", "resource": { "url": "http://localhost:8787/api/joke", "description": "A premium, hand-picked joke", "mimeType": "application/json" }, "accepts": [ { "scheme": "exact", "network": "eip155:84532", "amount": "10000", "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e", "payTo": "0xD040AEACCdFf083C5D4cB221F1533e8719a84F0e", "maxTimeoutSeconds": 300, "extra": { "name": "USDC", "version": "2" } }, { "scheme": "exact", "network": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", "amount": "10000", "asset": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", "payTo": "HjexCvNzgxJT3Ni7rb98WF4pQGEX2fN7G6Zh26B19mBc", "maxTimeoutSeconds": 300, "extra": { "feePayer": "CKPKJWNdJEqa81x7CkZ14BVPiY6y16Sxs7owznqtWYp5" } } ] } ``` 这正是我们想要看到的:两个测试网络,精确金额为 1 美分。现在让我们尝试支付,好吗?为了测试这种形式——我们需要一个编程客户端,它能够进行支付并重新发送带有确认的请求。不过在这个特定用例中,我想看看浏览器中的最终用户是否能做到这一点。幸运的是,他们可以!如果你现在从浏览器访问相同的 URL,你会看到这个: browser-failed-paywall.png 它用简单的英语告诉我们该怎么做才能让它工作,所以让我们来做: ``` npm install @x402/paywall ``` ``` import { HTTPFacilitatorClient } from "@x402/core/server"; +import { createPaywall, evmPaywall, svmPaywall } from "@x402/paywall"; @@ new x402ResourceServer(facilitatorClient) .register("eip155:84532", new ExactEvmScheme()) .register("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", new ExactSvmScheme()), + { appName: "Igor's corner", testnet: true }, + createPaywall().withNetwork(evmPaywall).withNetwork(svmPaywall).build(), ); return payment(c, next); }); ``` 现在尝试访问它,我们看到了一个漂亮的 UI 帮助我们支付访问权限: browser-success-paywall.png 顶部有充值链接,因为我们当前在测试网上。在生产环境中不会有这个。让我们尝试用 MetaMask 支付。 首先连接 MetaMask: mm-connected.png 现在如果我们继续实际支付: signature-request.png 最后我们终于得到了我们付费的内容: success.png 关于这个最终请求的几点观察: 客户端发送一个签名来确认支付,放在 `PAYMENT-SIGNATURE` 标头中,解码后是: ``` { "x402Version": 2, "payload": { "authorization": { "from": "0xAF40224e2B8fF2B4840c99d8458A0Fd803b15a0e", "to": "0xD040AEACCdFf083C5D4cB221F1533e8719a84F0e", "value": "10000", "validAfter": "1783263532", "validBefore": "1783264432", "nonce": "0x82806d883f9d46e376b9dc9c065560521f1c9064cf58d1d4ea53e9e3be5f01df" }, "signature": "0x7284c4c0da5cd029fff1f07fd4e5ff5b5c51bf13064b9a50e787f83f6e67555a419b85db77f27cb47a2101e03c38b93d1af9e6e4a3b2712675f35c975ea284d51c" }, "resource": { "url": "http://localhost:8787/api/joke", "description": "A premium, hand-picked joke", "mimeType": "application/json" }, "accepted": { "scheme": "exact", "network": "eip155:84532", "amount": "10000", "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e", "payTo": "0xD040AEACCdFf083C5D4cB221F1533e8719a84F0e", "maxTimeoutSeconds": 300, "extra": { "name": "USDC", "version": "2" } } } ``` 如你所见,它包含了我们的中间件确保支付已进行所需的所有信息。因此它用成功的 `PAYMENT-RESPONSE` 标头响应: ``` { "success": true, "payer": "0xAF40224e2B8fF2B4840c99d8458A0Fd803b15a0e", "transaction": "0x88aefe88050c4faaa650383460451ba1faebe3bdc398793970592e6a4ae787dc", "network": "eip155:84532" } ``` 以及包含实际内容的响应体。 另一个有趣的部分是,浏览器在另一个 URL 中打开了付费内容,该 URL 是从响应创建的内存对象 URL。我最初以为这是一个很好的 UI,可以防止刷新时重复支付,但看起来不是:付费墙在后台获取内容,由于我们的响应是 JSON 而不是 HTML,它没有东西可以就地渲染,因此它会导航到从响应创建的内存对象 URL。该协议本身是按使用付费的,所以每次你访问 API 时,都会被收费。 ### 闭环 好了,现在我们已经看到一切正常,让我们切换到生产网络并全部部署: ``` const facilitatorClient = new HTTPFacilitatorClient({ - url: "https://x402.org/facilitator" + url: "https://facilitator.payai.network" }); @@ - network: "eip155:84532", + network: "eip155:8453", @@ - network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", + network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", @@ new x402ResourceServer(facilitatorClient) - .register("eip155:84532", new ExactEvmScheme()) - .register("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", new ExactSvmScheme()), - { appName: "Igor's corner", testnet: true }, + .register("eip155:8453", new ExactEvmScheme()) + .register("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", new ExactSvmScheme()), + { appName: "Igor's corner", testnet: false }, ``` `x402.org` 的 facilitator 只处理测试网,所以对于真实网络,我们指向 Dexter (https://dexter.cash/facilitator) 的 PayAI (https://facilitator.payai.network/)——一个免费的 facilitator,处理 Base 和 Solana 主网,无需短信、注册账户或 API 密钥。Dexter 应该做同样的事情,但它宣布的交易从未到达实际网络,导致支付超时;而 PayAI 一切都完美运行。 就这样。你可以点击下面的按钮自己尝试。在那之前,别忘了在 Base 或 Solana 网络上用 USDC 充值你的钱包。 🎩 获取高级笑话($0.01) (https://shtein.me/api/joke) ## 总结 x402 (https://x402.org/) 不仅适用于对 AI 代理设置付费墙,它几乎已经准备好帮助你为博客货币化。无需摆弄像“Buy Me a Coffee”这样的服务,也不用烦扰用户看广告。 即使对于静态站点,它也很容易集成,尽管你需要一些计算资源。但并不多。 目前还没有现成的解决方案,可以为动态内容实现多网络支付并嵌入页面的 DOM 中。至少在这次简短探索中我没有找到。但浏览器似乎已经准备好对页面设置付费墙,使得实现起来非常简单。

相似文章

Monetization Gateway

Hacker News Top

Cloudflare 宣布推出 Monetization Gateway,使客户能够通过 x402 协议对任何受保护资源(网页、API、数据集、MCP 工具)收费,并在边缘进行稳定币结算,旨在应对AI代理向按使用量付费的转变。

用机器重建我的博客,为机器服务·

Lobsters Hottest

作者重建了博客,加入了完整的结构化数据标记(JSON-LD、微格式),并配备了一个由提示词引导的AI协作写作助手,该提示词避免了常见的LLM模式,同时通过CI验证防止数据损坏。