字节笔记本
2026年8月29日
用 Gemini 造并上架一个 Farcaster Mini App
Farcaster Mini App 本质是嵌在客户端里的网页。HTML、CSS、JS 再加一层 SDK,就能用上登录、钱包和通知。
很多人现在直接把需求丢给 Gemini 或同类编码模型,一次生成 Frog、Hono、Vercel 工程,再补图、部署、挂清单。下面按这条路走一遍。
参考实现是 kobe2408-nb/kobe-fans。官方文档:Getting Started,上架说明:Publishing。
先搞清 Mini App 要过哪几关
客户端不会去某个中心化商店审核通过才收录你。它认域名,并在这个域名上找 .well-known/farcaster.json。文件里写清楚应用名、首页、图标,以及一段用你的托管密钥签过的 accountAssociation。清单对了,客户端就能把网页当 Mini App 打开。
上线前至少要满足这四件事:
- 页面加载完立刻调用 sdk.actions.ready(),否则闪屏不关
- 域名稳定,之后改不了,域名就是应用身份
- 图标、启动图按尺寸放好
- 清单能被公开访问,HTTP 200,域名和签名里的 domain 完全一致
Node 版本建议 22.11 以上。官方 CLI 和 SDK 对旧 Node 很挑。
两条起步路径
官方脚手架
新项目可以用官方的 create mini-app 脚手架。已有项目则安装 @farcaster/miniapp-sdk,页面就绪后调用 ready()。
import { sdk } from "@farcaster/miniapp-sdk"
await sdk.actions.ready()不想装包也可以走 esm.sh 的 CDN,在页面底下一句 import 再 ready。
kobe-fans 用的还是旧包 frame-sdk。新项目请用 @farcaster/miniapp-sdk,第一步同样是 ready()。
把需求写成英文提示词交给模型
kobe-fans 仓库本身就是一份可复用的英文提示词,加上一套已经能部署的示例。作者的经验是:中文聊需求,英文下指令,变量名、Edge 兼容和框架术语会稳很多。提示词写在仓库 Markdown 目录里。
提示词里值钱的是那几条容易翻车的约束,产品长什么样反而不重要。
- Vercel Function 用 Edge runtime。Node runtime 配 Frog 和 JSX 导入时经常直接 SyntaxError。
- Frog 的 basePath 设成根路径,全站流量用 vercel.json rewrite 打到 /api。
- 导出 GET 和 POST 用 app.fetch。不要用 frog 的 vercel 适配器,也不要开 devtools,Edge 上不兼容。
- Mini App 页面用 app.hono.get 吐 HTML,不要乱改响应对象。
- HTML 里立刻调 sdk.actions.ready()。
- 签到积分可以先用 localStorage 顶一下,真上链再换。
生成后你要自己建 public 目录,放 icon.png、image.png、splash.png。模型画不了这三张图,漏了清单里的地址就是 404。
示例项目长什么样
kobe-fans 是一个 Vercel Edge 上的 Frog 应用。首页是紫金配色的积分卡:每日签到加 10 分,外链到社交账号。核心文件很少。
| 文件 | 作用 |
|---|---|
| package.json | frog、hono、vercel,type 为 module |
| api/index.tsx | 清单接口加首页 HTML、CSS、签到逻辑 |
| vercel.json | 全站 rewrite 到 /api,以及 hosted manifest 跳转 |
| public 下的 png | 图标、分享图、闪屏 |
本地先安装依赖再跑 frog dev。浏览器能打开、签到数字会变,再谈上架。
签到这段就是读本地日期,同一天不能连点。下面这段可以直接放进页面脚本。
const today = new Date().toISOString().split("T")[0]
const lastCheckIn = localStorage.getItem("lastCheckIn")
let points = parseInt(localStorage.getItem("points") || "0")
if (lastCheckIn === today) {
alert("今天已经签到过了")
return
}
points += 10
localStorage.setItem("points", String(points))
localStorage.setItem("lastCheckIn", today)这只是前端模拟。按钮上写链上签到,也不等于已经接了钱包或转过代币。真要上链,清单里还得声明 requiredChains 和 requiredCapabilities。
部署到一个稳定域名
域名一旦写进清单和签名,就不能换。预览域名、带随机后缀的临时域名都别拿来上架。常见做法是先绑一个固定的 vercel.app,或自己的子域。
vercel.json 至少要有 rewrite,把所有路径打到 /api,否则清单和首页都不会进 api/index.tsx。
{
"rewrites": [
{ "source": "/(.*)", "destination": "/api" }
]
}部署完先在普通浏览器打开首页,确认 ready() 之后页面能出来。再检查清单地址是不是 200。不要 301 绕到带 www 或不带 www 的另一个 host。签名按精确域名算,apex 和 www 是两个身份。
写清单,或者让平台托管
清单最小字段是 version、name、homeUrl、iconUrl。version 必须是字符串 1,name 最长 32 字符。图标要求 1024 乘 1024 的 PNG,不要透明通道。闪屏图可选,官方写的是 200 乘 200。
自己托管时,在应用里给 .well-known/farcaster.json 返回 JSON。kobe-fans 最初就是这么干的。
{
"miniapp": {
"version": "1",
"name": "Kobe Fans",
"iconUrl": "https://your-domain.example/icon.png",
"homeUrl": "https://your-domain.example",
"splashImageUrl": "https://your-domain.example/splash.png",
"splashBackgroundColor": "#000000",
"subtitle": "daily check-in",
"description": "A tiny fan check-in mini app",
"primaryCategory": "entertainment"
},
"accountAssociation": {
"header": "from-manifest-tool",
"payload": "from-manifest-tool",
"signature": "from-manifest-tool"
}
}新字段名是 miniapp。老客户端还认 frame,kobe-fans 仓库里仍写着 frame。两边可以并存,新项目优先 miniapp。
另一种更省事:用 Hosted Manifest。填域名和应用信息,拿到托管 id,然后只做一次 307 跳转,之后改名字、改图都不用重新部署。kobe-fans 现在的 vercel.json 就是这条路。
{
"redirects": [
{
"source": "/.well-known/farcaster.json",
"destination": "https://api.farcaster.xyz/miniapps/hosted-manifest/YOUR_ID",
"permanent": false
}
]
}跳转不要写成永久 301。写成 301,客户端或 CDN 会把旧清单缓存死。
签名:证明这个域名是你的
accountAssociation 是一段签名。payload 里是域名,header 里是你的 fid 和托管地址。
先打开 Developer Tools,打开 Developer Mode。再到 Mini App Manifest 页,或客户端设置里的 Developer Domains,填和线上完全一致的域名,生成 header、payload、signature。贴回清单,或交给 Hosted Manifest。
域名差一个字符、多一个路径、带了端口,客户端都会判失败。签完再改域名,旧签名立刻作废。
在客户端里验
打开 Developer Mode 之后,桌面端左侧会出现开发者入口。把 Mini App 地址丢进去,看闪屏会不会在 ready() 之后关掉,清单有没有报错。也可以用 Neynar 的校验工具核对 HTTP 状态和字段。
常见翻车:
| 现象 | 多半是 |
|---|---|
| 闪屏一直转 | 没调 ready(),或脚本被拦截 |
| 客户端找不到应用 | 清单 404,或 rewrite 没覆盖 well-known 路径 |
| 所有权校验失败 | 签名域名和实际 host 不一致 |
| 图标是空白 | 不是 1024 方图,或带了透明通道 |
| Edge 部署直接 500 | 用了 Node runtime,或引入了不兼容的适配器 |
| 本地好、线上路由乱 | 忘了 vercel.json 的全站 rewrite |
分享到信息流还要在页面 head 里加 miniapp 元数据,按钮动作一般是 launch_miniapp。这一步不影响能打开,但影响能被转发。细节见官方 sharing 指南。
提示词怎么改成自己的应用
不要整段复制那个粉丝签到。保留运行时约束,把产品部分换成你的:应用名、配色、按钮文案和链接;首页和图标地址换成你的域名;积分逻辑继续用本地存储,或改成读自己的接口。真要钱包时,再往清单加 requiredChains(Base 是 eip155:8453)和 requiredCapabilities。
把改过的英文提示词丢给模型,让它按那几个文件生成。报错就把终端原文贴回去,比空喊修一下有效。图还是你自己放进 public。
官方文档对模型也友好。整站有 llms-full.txt,可以把最新规范塞进上下文,减少 SDK 包名和字段过期。
相关链接
- 示例仓库:https://github.com/kobe2408-nb/kobe-fans
- 官方起步:https://miniapps.farcaster.xyz/docs/getting-started
- 上架清单:https://miniapps.farcaster.xyz/docs/guides/publishing
- Hosted Manifest:https://farcaster.xyz/~/developers/mini-apps/manifest
- Developer Tools:https://farcaster.xyz/~/settings/developer-tools
- 整站给模型用的文本:https://miniapps.farcaster.xyz/llms-full.txt