Farcaster 框架:使用 Frog 构建你的第一个框架

本文为机器翻译
展示原文

作者:菲戈, IOSG Ventures

Farcaster 是一个Decentralized Social网络,提供了 Twitter 和 Reddit 等传统平台的替代方案。用户可以建立个人资料、发布「演员表」并追踪其他人,同时保留其帐户和连结的所有权。这种去中心化的方法允许使用者在不同的应用程式之间移动而不会遗失资料或连接,从而优先考虑使用者的自主权、隐私和互通性。

什么是框架?

Farcaster 作者: Andrea Boi

框架是 Farcaster 的一项独特功能,允许用户将互动式体验直接嵌入到他们的 Cast 中。这将静态贴文变成动态内容,增强用户体验。框架可以包括民意调查、即时更新或整个应用程式等元素,为用户参与提供各种方式。

框架如何运作

从技术角度来看,Farcaster Frames 同时使用链上和链下功能。它们是嵌入在 Casts 中的轻量级 Web 应用程式。框架规范概述了创建相容框架的技术要求和标准,确保它们在 Farcaster 生态系统中运作。

来源:Farcaster 文档

框架扩展了开放图谱标准,将静态嵌入转变为互动式体验。开发人员首先选择开放图谱图像,然后添加互动式按钮。单击按钮时,会触发回调,以新内容或操作更新框架。这种互动由使用者和开发人员管理,从而形成了一种去中心化的方法。

Warpcast 是 Farcaster 的主要客户之一,支援这些互动式框架,让用户在平台上建立动态内容。下图说明了标准开放图谱 (OG) 嵌入与 Warpcast 内的框架 OG 之间的差异。

框架范例

Farcaster Frames 的应用是多种多样的,既能满足使用者的需求,也能满足开发者的需求。这里有些例子:

  1. 互动民意调查:用户可以在他们的演员中嵌入即时民意调查,允许追踪者投票并查看即时结果。这增强了用户参与度并促进社区互动。
  2. NFT 展示:开发人员可以创建框架,让使用者可以直接在他们的 Cast 中铸造和展示 NFT。这弥合了社交媒体和 NFT 世界之间的差距,实现了新的创意表达形式。
  3. 即时来源和画廊:框架可用于建立即时来源或互动式画廊,提供一种动态且引人入胜的方式在 Farcaster 上共享内容。

透过实现这些互动体验,Farcaster Frames 正在改变社群媒体上内容的创建、分享和互动方式。它们为开发人员提供了一个框架来建立与 Farcaster 网路无缝整合的创新应用程序,为内容管理和用户参与开辟了新的可能性。

什么以及为什么青蛙?

来源:范式

Frog由Paradigm和Wevm开发,是一个旨在创建Farcaster框架的框架。它简化了流程,使开发人员能够轻松建立互动式和高效能的框架。 Frog 包括内建侦错器、即时重新载入和无缝部署选项。

目前建构 Farcaster 框架的挑战

在新框架上进行开发可能会带来以下挑战:

  • 复杂的状态管理:有效处理客户端反应性和状态。
  • 大小和行为约束:导航框架标签大小和功能的限制。
  • 安全性问题:确保安全讯息验证和帧完整性。
  • 效能最佳化:管理负载效能并最大程度地减少不必要的 HTML 内容。

青蛙如何解决这些挑战

Frog 透过引入简化框架开发的功能来解决这些问题:

  • 具有即时重新载入功能的本机侦错器:提供即时回馈,加快开发速度。
  • 简化的状态管理:利用状态汇出轻松进行状态处理。
  • 增强的安全性:提供用于安全框架开发的内建验证工具。
  • 优化的效能:能够创建高度优化的框架以实现快速载入。
  • 灵活部署:允许部署到任何 JavaScript 执行时,避免供应商锁定并提供更大的灵活性。

使用 Frog 不仅可以简化开发流程,还可以更轻松地创建安全、高效和互动的框架,从而增强开发人员的体验。这为 Farcaster 的创新开启了无限的可能性。

专案教学:MarketCapOf 框架

我们将建立一个受 MarketCapOf 启发的 Farcaster 框架。该工具使我们能够直观地看到一种加密货币 (A) 具有另一种加密货币 (B) 的市值时的价格。它是深入了解加密货币市场的有用工具。

以下是我们将要创建的内容的快速预览:

在本教程结束时,您将:

  • 建立一个 Farcaster 框架,能够根据另一种加密货币的市值动态计算并显示一种加密货币的价格。
  • 在 Warpcast 上验证和测试您的 Frame,确保其在 Farcaster 生态系统中无缝运行。

让我们开始吧!

先决条件

在我们开始之前,请确保您具备以下条件:

  • 已安装 npm :确保您的电脑上安装了 Node Package Manager (npm)。如果您还没有,可以从此处下载并安装。
  • Farcaster 帐户:如果您还没有,请建立 Farcaster 帐户。您可以在 Farcaster 注册。
注意:本教学假设您熟悉 JavaScript 并对 JavaScript 有基本的了解。

设定您的项目

首先,打开终端并使用 Frog 初始化项目:

 npm init frog -- -t next

您应该会看到以下设定提示:

按照说明为您的项目命名。

项目初始化后,

  1. 导航至专案目录: cd 专案名称
  2. 我建议在您首选的 IDE 中开启专案资料夹。例如,如果您使用 VS Code,则可以使用下列命令执行此操作: code 。
  3. 现在在专案资料夹中,安装必要的依赖项: npm install
  4. 启动开发伺服器! npm 运行开发

伺服器运行后,在浏览器中存取 https://localhost:3000/api/dev。

Frog 的最佳功能之一是它配备了内建的框架测试器 UI。该工具提供了一种直观的方式来直观地查看程式码中所做的更改,从而使开发更快、更有效率。

预设模板是一个简单的演示框架,允许您选择一个项目并查看您的选择。虽然这是一个有用的起点,但仍需要一些工作才能将其转换为我们的 MarketCapOf 框架。

建立我们的应用程式

让我们深入建立我们的应用程式。首先导览至app/api/[[...routes]]/route.tsx 。该档案是我们应用程式的核心,也是帧端点所在的位置。您将看到 Frog 应用程式是透过呼叫 Frog 类别来实例化的。

我们将修改它来设定我们的应用程式。让我们从新增标题开始:

常量应用程式 = 新青蛙({
资产路径:“/”,
基本路径:“/api”,
title: "Frame Market Cap", // 新增标题
// 提供一个集线器来启用帧验证。
// hub: neynar({ apiKey: 'NEYNAR_FROG_FM' })
});

Farcaster 框架由两个主要 UI 元件组成:一个图像和一组 Intents。我们可以透过传回的帧响应的图像意图属性在 Frog API 中指定这些元件。

资料来源:青蛙文档

在同一个档案中,您还将看到将图像返回到 UI 是多么容易。透过编写 JSX 程式码并套用样式,Frog 会自动将其转换为图像。

 app.frame('/', (c) => {
const { 按钮值,输入文本,状态 } = c
const 水果 = inputText ||按钮值
返回 c.res({
图像: (
<div>
{/* 这里的JSX程式码会自动转换成图片 */}
</div>
),
意图:[

],
})
})

设计我们的应用程式流程

我们应用程式的主要思想很简单。其工作原理如下:

  1. / root 开始,第一页图像将描述我们的应用程式的功能并提示使用者输入。
  2. 使用者将输入一对令牌(令牌 A 和令牌 B)。用户点击提交。
  3. 我们将此输入传递给新的/compare框架,然后从 CoinMarketCap (CMC) API 取得所要求代币的资料。

Intent属性将保存一系列可操作的项目。在我们的例子中,我们将只为令牌对(格式为 tokenA、tokenB)保留一个 TextInput 和一个提交按钮。

我们还需要指定一个操作来确定使用者提交后将被带到的位置。让我们让此操作将使用者定向到/compare端点。

我们也删除了 return 上面关于c变数的不必要的程式码。我们很快就会讨论更多相关内容。

进行这些更新后,我们将:

 app.frame("/", (c) => {
返回 c.res({
动作:“/比较”,
图像: (
<div
风格={{
alignItems:“中心”,背景:“黑色”,显示:“flex”,flexDirection:“列”,
flexWrap:“nowrap”,高度:“100%”,justifyContent:“中心”,textAlign:“中心”,宽度:“100%”,
}}
>
<div
风格={{
颜色:“白色”,字体大小:60,字体样式:“正常”,空白:“预换行”,
}}
>
{「检查 A 的价格\n 与 B 的市值!」}
</div>
</div>
),
意图:[<TextInput placeholder="TOKENA,TOKENB" />,<Button value="mine">立即检查! </Button>],
});
});

透过这些更改,我们的新根/框架已设定完毕并准备就绪!现在,刷新 Frog UI 以查看包含新描述和输入栏位的更新框架。

但是,如果您输入令牌(例如ETH、 BTC )并按“立即检查!”,则不会发生任何情况。这是因为我们还没有创建/compare端点!让我们现在就开始做吧。

上下文传递

在同一个Route.tsx档案中,我们建立一个新的帧路由。我们可以先复制 / 路线的内容。但是,在进行任何更改之前,让我们透过记录 c 参数的值来仔细了解c参数的实际意义。现在,我们可以先删除这个新框架的动作和意图属性。

 app.frame("/比较", (c) => {
控制台.log({ c })

返回 c.res({
图像: (
<div
风格={{
alignItems:“中心”,背景:“黑色”,显示:“flex”,flexDirection:“列”,
flexWrap:“nowrap”,高度:“100%”,justifyContent:“中心”,textAlign:“中心”,宽度:“100%”,
}}
>
<div
风格={{
颜色:“白色”,字体大小:60,字体样式:“正常”,空白:“预换行”,
}}
>
{「检查 A 的价格\n 与 B 的市值!」}
</div>
</div>

});
});

刷新框架 UI,输入内容,然后按一下「立即检查!」。让我们来看看记录的c值:

从这个日志中,我们看到c实际上是框架上下文物件。它储存有用的信息,例如从最后一帧提交的inputText 。此c参数包含有关帧和先前上下文的其他属性,例如:

  • 帧资料(trustedData/untrustedData)
  • 与之互动的按钮索引/值或输入值
  • 汇出和设定状态的函数
  • 帧的初始/开始路径
  • 框架的当前 URL
  • 和更多

这就是我们将上下文和使用者输入从一帧传递到下一帧的方式。我们可以使用这个上下文来提取使用者提交的令牌对资讯。现在,我们可以忽略frameData ,因为我们还没有验证框架。当我们在后面的部分中设定帧验证时,将介绍这一点。现在,我们将使用c.inputText来取得使用者输入的令牌对,并在/compare路由中对其进行相应处理。

设定我们的“/compare”框架

检索请求的代币(代币 A 和代币 B)后,来自 CoinMarketCap 的必要数据将包括每个代币的当前价格和完全稀释估值 (FDV)。现在,让我们使用静态模拟资料来设定一个基本结构,并建立一个简单的 UI 布局来显示结果。

这是/compare框架的更新程式码:

 app.frame("/比较", (c) => {
const { inputText = "" } = c;

const tokenA = inputText.split(",")[0].toUpperCase(); //ETH
const tokenB = inputText.split(",")[1].toUpperCase(); //BTC

// 令牌 A 和令牌 B 的模拟数据
常量价格A = 3000;
常数 marketCapA = 360000000;

常量价格B = 57000;
const marketCapB = 1100000000;

// 如果代币 A 具有代币 B 的市值,则计算代币 A 的价格
const 乘数 = marketCapB / marketCapA;
const 计算价格 = 乘数 * 价格A;

返回 c.res({
图像: (
<div
风格={{
alignItems:“中心”,背景:“黑色”,显示:“flex”,flexDirection:“列”,高度:“100%”,
justifyContent:“center”,textAlign:“center”,宽度:“100%”,颜色:“白色”,whiteSpace:“预换行”
}}
>
<div
样式={{ fontSize: 40, marginBottom: 20 }}
>
{`${tokenA},市值为 ${tokenB}`}
</div>
<div
样式={{ fontSize: 80, marginBottom: 30 }}
>
{`$${calculatedPrice.toFixed(2)} (${multiplier.toFixed(2)}x)`}
</div>
<div
样式={{ fontSize: 30 }}
>
{`${tokenA} 市值:$${marketCapA.toFixed(2)}\n${tokenB} 市值:$${marketCapB.toFixed(2)}`}
</div>
</div>
),
});
});

现在,返回框架 UI 并输入ETH、 BTC作为输入进行测试。

极好的!现在我们可以看到公式逻辑有效,而且我们的布局看起来也不错。接下来,我们需要设定实际的资料检索。

建立实用函数

在专案的根目录中,建立一个新的utils资料夹并初始化该资料夹中的index.tsx档案。这是我们储存实用函数的地方。

我们的应用程式依赖检索动态价格资料的能力。为此,我们将使用 CoinMarketCap API。您可以在此处取得免费的 API 金钥。

首先,在专案的根目录中建立一个.env.local档案。这是我们储存CMC_API_KEY 的位置。

 // .env.local
CMC_API_KEY=<您的coin市值 API 金钥>

您可能需要在终端机中重新启动程式才能读取环境档案。

接下来,将以下程式码加入utils资料夹中的index.tsx档案:

汇出 const fetchTokenData = async (tokenSymbols: string) => {
const 回应 = 等待 fetch(`https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol=${tokenSymbols}`, {
标题:{
“X-CMC_PRO_API_KEY”:process.env.CMC_API_KEY 作为字串,
},
});

如果(!response.ok){
throw new Error(`无法取得资料:${response.statusText}`);
}

返回response.json();
};

汇出 const getTokenPrice = async (tokenSymbol: string) => {
尝试 {
const tokenData = 等待 fetchTokenData(tokenSymbol);
const tokenArray = tokenData.data[tokenSymbol.toUpperCase()];

if (!tokenArray || tokenArray.length === 0) {
抛出新错误(`未找到 ${tokenSymbol} 的资料`);
}

const tokenInfo = tokenArray[0];
const usdQuote = tokenInfo.quote && tokenInfo.quote.USD;

如果 (!usdQuote) {
抛出新错误(`美元报价不适用于 ${tokenSymbol}`);
}

返回 {
价格:usdQuote.价格,
marketCap: usdQuote.market_cap,
};
} catch(错误:任何){
console.error(`取得 ${tokenSymbol} 的代币价格时出错:`, error.message);
返回 {
价格: 空,
市值:空,
错误:错误讯息,
};
}
};

在同一个档案中,我们还添加一个formatNumber函数,我们可以使用该函数在整个应用程式中正确格式化数字:

汇出 const formatNumber = (num: number) => {
让 formattedNum = num.toFixed(2);
return formattedNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};

有了这些实用函数,我们现在可以从 CoinMarketCap 取得代币资料并格式化数字以供显示。

完成“/比较”

现在让我们用我们写的实用函数来更新/compare框架。由于获取代币价格需要时间,因此请记住将wait添加到函数的开头,并将函数声明设为async

首先,更新/compare框架以使用实用函数:

从 './utils' 导入 { getTokenPrice, formatNumber };

app.frame("/compare", async (c) => {
const { inputText = "" } = c;

const tokenA = inputText.split(",")[0].toUpperCase();
const tokenB = inputText.split(",")[1].toUpperCase();

const { 价格:priceA,marketCap:marketCapA,错误:errorA } =等待 getTokenPrice(tokenA);
const { 价格:priceB,marketCap:marketCapB,错误:errorB } =等待 getTokenPrice(tokenB);

// ...
});

接下来,新增一个按钮以允许使用者返回根框架并输入另一对。为此,我们只需添加一个带有导航回/ 的操作的按钮。

返回 c.res({
行动: ”/”,
图像: (
// ...
),
意图:[<Button>尝试另一对</Button>],
});

最后,让我们添加一些错误处理并完成/compare框架准备就绪!

 app.frame("/compare", async (c) => {
const { inputText = "" } = c;

尝试 {
const tokens = inputText.split(",");
if (tokens.length < 2) {
throw new Error("输入无效。请提供两个标记,以逗号分隔。");
}

const tokenA = tokens[0].toUpperCase();
const tokenB = tokens[1].toUpperCase();

const { 价格:priceA,marketCap:marketCapA,错误:errorA } =等待 getTokenPrice(tokenA);
const { 价格:priceB,marketCap:marketCapB,错误:errorB } =等待 getTokenPrice(tokenB);

if (错误A || 错误B) {
抛出新的错误(错误A || 错误B);
}

const 乘数 = marketCapB / marketCapA;
const 计算价格 = 乘数 * 价格A;

返回 c.res({
行动: ”/”,
图像: (
<div
风格={{
alignItems:“中心”,背景:“黑色”,显示:“flex”,flexDirection:“列”,高度:“100%”,
justifyContent:“center”,textAlign:“center”,宽度:“100%”,颜色:“白色”,whiteSpace:“预换行”
}}
>
<div
样式={{ fontSize: 40, marginBottom: 20 }}
>
{`${tokenA},市值为 ${tokenB}`}
</div>
<div
样式={{ fontSize: 80, marginBottom: 30 }}
>
{`$${formatNumber(calculatedPrice)} (${formatNumber(multiplier)}x)`}
</div>
<div
样式={{ fontSize: 30 }}
>
{`${tokenA} 市值:$${formatNumber(marketCapA)}\n${tokenB} 市值:$${formatNumber(marketCapB)}`}
</div>
</div>
),
意图:[<Button action="/">尝试另一对</Button>],
});
} catch(错误:任何){
console.error("发生错误:", error.message);
返回 c.res({
行动: ”/”,
图像: (
<div
风格={{
alignItems:“中心”,背景:“黑色”,显示:“flex”,flexDirection:“列”,高度:“100%”,
justifyContent:“center”,textAlign:“center”,宽度:“100%”,颜色:“白色”,whiteSpace:“预换行”
}}
>
<div
样式={{ fontSize: 40, marginBottom: 20 }}
>
{`发生错误:(`}
</div>
</div>
),
意图:[<Button action="/">返回并重试</Button>],
});
}
});

试一试!您的应用程式现在应该能够从 CoinMarketCap 检索动态价格资料并在 UI 中显示格式正确的计算。我们的应用程式完成了! 🎉

验证和测试

帧验证

在将框架投入生产之前,验证和验证框架至关重要。如果没有验证,输入可能会被欺骗,从而损害资料完整性。我们希望用户透过 Warpcast 用户端进行验证并登入 Farcaster,确保与框架的互动是真实的。

对于收集选票或其他关键互动等用例,验证至关重要。但是,对于更简单的应用程式(例如我们当前的范例),它可能并不那么重要。

Frog 透过启用集线器让验证过程变得简单。两个最常用的集线器是 Neynar 和 Pinata。在我们的程式码范本中,我们可以取消 Neynar 程式码的注释,以启用对我们的框架的验证。

启用内纳尔的方法如下:

 // 其他进口..
从「青蛙/集线器」导入{ neynar };

常量应用程式 = 新青蛙({
资产路径:“/”,
基本路径:“/api”,
标题:“框架市值”,
集线器: neynar({ apiKey: "NEYNAR_FROG_FM" }),
});

启用后,您的框架现在将需要验证。但是,这表示在 localhost 上执行应用程式将导致无效签章错误,因为 localhost 未登入 Farcaster。

现在,我们需要探索在连接到 Farcaster 用户端的线上设定中测试框架的方法。

线上测试

要正确测试您的 Farcaster 框架,您需要登入 Farcaster 帐户。这可以透过两种方式完成:

  1. 透过 Frog Test UI 登入:点击 Frog Test UI 右上角的登入按钮进行登入。
  2. Warpcast 框架验证器:使用 Warpcast 框架验证器。

对于第二种方法,您需要使本机主机可以存取网际网路。我强烈推荐使用 ngrok。如果您使用的是Mac,则可以透过在终端机中执行brew install ngrok/ngrok/ngrok来安装它。安装后,只需输入ngrok http 3000即可透过公用 URL 存取您的本机主机。

然后,前往 Warpcast 帧验证器并输入您的 ngrok URL。例如: https://7a32-193-142-202-2.ngrok-free.app/api

不过,我个人更喜欢第一种方法,因为它更快、更容易。您只需扫描登入二维码,不到一分钟即可连线!

登入后,让我们尝试在/compare端点再次查看c的值:

我们可以看到已验证的栏位现在显示为true 。有了这个,我们现在还可以从frameData中获取inputText ,这更安全,因为它已经过验证。

更新您的/compare框架以使用frameData提取inputText

 app.frame("/compare", async (c) => {
控制台.log({ c });

// const { inputText = "" } = c;

// 启用验证时使用它
const { 帧数据,已验证 } = c
const { inputText = ""} =frameData || {}

// ...
});

透过确保您的框架经过验证,您可以增强安全性和信任,确保使用者互动合法且受到保护。

奖励:部署!

作为奖励,您还可以使用 Vercel CLI 将应用程式部署到 Vercel。这将允许您与其他人共享您的 Farcaster 框架并在网路上即时查看它。要部署,只需执行以下步骤:

  1. 安装 Vercel CLI: npm install -g vercel
  2. 登入 Vercel: vercel 登入
  3. 要部署您的应用程序,请从专案的根目录执行: npm run deploy

有关更详细的说明,您可以参阅有关部署到 Vercel 的 Frog 文件。

下一步

恭喜建立您的第一个 Farcaster 框架!现在您已经掌握了如何使用 Frog 轻松建立和测试框架的基础知识。借助 Frames,您将步入 Farcaster 上充满互动可能性的世界。这只是个开始;在这个令人兴奋的创新空间中还有很多东西值得探索和创造。创造力和参与的潜力是无限的。

您可以考虑的一些方向是探索更高级的框架交互,例如:

  • 交易框架:发展与智慧合约互动的框架,直接在 Farcaster 内实现链上交易。
  • 社交整合框架:利用 Farcaster 的本地社交资料创建丰富的社交感知应用程式。
  • 进阶互动:设计框架引导使用者完成详细流程以增强参与度。

要进一步探索 Frames,请查看我们的测试版IOSG 开发人员中心网站,您可以在其中找到本教学和未来部落格、学习材料、活动和其他以开发人员为中心的资源的 GitHub 储存库。您也可以加入我们在 Telegram 上的IOSG 开发者社区,获取所有技术方面的支持和讨论!

如果您觉得本教学有帮助,请分享并按赞。再次感谢,请继续关注更多!继续探索和建设!

资源

Farcaster 框架https://docs.farcaster.xyz/learn/what-is-farcaster/frames
青蛙https://www.paradigm.xyz/2024/02/frames


Farcaster 框架:使用 Frog 建立您的第一个框架最初发表在IOSG Ventures 的Medium 上,人们透过突出显示和回应这个故事来继续对话。

相关赛道:
Medium
免责声明:以上内容仅为作者观点,不代表Followin的任何立场,不构成与Followin相关的任何投资建议。
喜欢
12
收藏
3
评论