Constructing Your Own Farcaster Frame
Overview
Farcaster is an innovative platform enhancing social interactions by providing a dynamic and engaging ecosystem for user interactions. A standout feature is its API, which enables developers to craft interactive applications within the Farcaster environment.
Farcaster Frames: Interactive In-Feed Applications
Farcaster's latest feature, Frames, revolutionizes user interaction on social feeds. Unlike traditional methods that redirect users via links, Frames allow interactions directly within the social feed. Users can perform actions such as using an app, minting an NFT, or tracking crypto prices without leaving the feed. This feature significantly enhances user experience by maintaining seamless engagement within the platform.
Guide: Building a Farcaster Frame with CoinGecko API
This tutorial will guide you through creating a Farcaster Frame using CoinGecko API’s trending pools data.
Prerequisites
- CoinGecko API: Obtain data for top trending crypto pools via the Analyst API plan. Ensure you have a Pro API key.
- Node.js and npm: Download from the official Node.js website.
- Text Editor or IDE: Recommended options include Visual Studio Code.
- Vercel Account: For public deployment and testing.
- Warpcast and Neynar Accounts: Required for testing and API key usage.
- OpenGraph: For enhancing social media sharing visibility with meta tags.
Creating a Next.js Application
- Open Visual Studio Code.
- Open the terminal and run
npx create-next-app@latest
. - Follow the steps to set up your Next.js app.
Code Example: Page.tsx
typescript import { getFrameMetadata } from '@coinbase/onchainkit'; import type { Metadata } from 'next'; import { NEXT_PUBLIC_URL } from './config'; const frameMetadata = getFrameMetadata({ buttons: [ { label: 'Trending Crypto Pools' }, { action: 'link', label: 'Visit Coingcko', target: 'https://www.coingecko.com' }, ], image: { src: `${NEXT_PUBLIC_URL}/gecko_frame.JPG`, aspectRatio: '1:1', }, postUrl: `${NEXT_PUBLIC_URL}/api/trendingPools`, }); export const metadata: Metadata = { metadataBase: new URL(NEXT_PUBLIC_URL), title: 'Crypto Farcaster Frames - Powered by CoinGecko', description: 'LFG', openGraph: { title: 'Crypto Farcaster Frames - Powered by CoinGecko', description: 'LFG', images: [`${NEXT_PUBLIC_URL}/gecko_frame.JPG`], }, other: { ...frameMetadata }, }; export default function Page() { return <h1>Welcome to Crypto Farcaster Frames - Powered by CoinGecko</h1>; }
Creating a Serverless Function: route.ts
typescript import { FrameRequest, getFrameMessage, getFrameHtmlResponse } from '@coinbase/onchainkit'; import { NextRequest, NextResponse } from 'next/server'; import { NEXT_PUBLIC_URL } from '../../config'; import { getChartOptions } from '../lib/getChartOptions'; import { throwErr } from '../lib/throwErr'; async function getResponse(req: NextRequest): Promise<NextResponse> { let text: string | undefined = ''; let pool: any | undefined = {}; let chain: string = ''; let data: [number, number, number, number, number, number][] = []; const body: FrameRequest = await req.json(); const { isValid, message } = await getFrameMessage(body, { neynarApiKey: 'YOUR_API_KEY' }); if (!isValid) { return throwErr('error.jpg'); } try { const trendingPoolsRes = await fetch(`https://pro-api.coingecko.com/api/v3/onchain/networks/trending_pools`, { headers: { 'accept': 'application/json', 'Authorization': `Bearer YOUR_CG_API_KEY` } }); if (!trendingPoolsRes.ok) { throw new Error(`HTTP error! status: ${trendingPoolsRes.status}`); } const trendingPoolsJson = await trendingPoolsRes.json(); const trendingPoolsData = trendingPoolsJson.data.map((pool: any) => { return { id: pool.id, name: pool.attributes.name, baseTokenPriceUSD: pool.attributes.base_token_price_usd, quoteTokenPriceUSD: pool.attributes.quote_token_price_usd, volumeUSD: pool.attributes.volume_usd.m5, reserveInUSD: pool.attributes.reserve_in_usd, transactions: pool.attributes.transactions.m5, }; }); pool = trendingPoolsData[0]; chain = pool.relationships.network.data.id; data = pool.attributes.volume_usd; const chartOptions = getChartOptions(text, data, pool, chain); const chartRes = await fetch(`https://quickchart.io/apex-charts/render`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ config: chartOptions, height: 400, width: 800 }), }); const chartBlob = await chartRes.blob(); const chartBuffer = await chartBlob.arrayBuffer(); const chartBase64 = Buffer.from(chartBuffer).toString('base64'); if (message?.button === 2) { return NextResponse.redirect('https://www.coingecko.com', { status: 302 }); } return new NextResponse( getFrameHtmlResponse({ buttons: [ { label: `Load new chart` }, { action: 'link', label: 'View on GeckoTerminal', target: `https://www.geckoterminal.com/explore/trending-pools` }, ], image: { src: `data:image/png;base64,${chartBase64}` }, postUrl: `${NEXT_PUBLIC_URL}/api/frame`, }), ); } catch (e) { return throwErr('error.png'); } } export async function POST(req: NextRequest): Promise<Response> { return getResponse(req); } export const dynamic = 'force-dynamic';
Running the Application Locally
- Open Terminal.
- Navigate to your project directory using
cd my-next-app
. - Install dependencies with
npm install
. - Start the development server using
npm run dev
. - Access your application at
http://localhost:3000
.
Testing Farcaster Frames Locally
- Clone the OnChainKit repository from GitHub.
- Navigate to the framegear directory within OnChainKit.
- Install dependencies with
npm install
. - Run the tests with
npm run dev
and test your application URL athttp://localhost:3000
via the frames validator.
Deploying on Vercel
- Push your changes to GitHub.
- Connect your GitHub repository to Vercel and deploy the project.
- Test your deployed application at the provided URL.
Testing on Warpcast
- Navigate to Warpcast Developer Playground.
- Enter your Frame URL and send a test request.
- Inspect and iterate based on the results.
Casting Farcaster Frames in Warpcast
- Log in to Warpcast.
- Create a new cast and embed your app URL.
- Publish and interact with your Frame on your social feed.
Advanced Functionalities
- Cryptocurrency Price Converter
- Display BTCDominance
- Real-Time Price Updates
Conclusion
Developing a Farcaster Frame application enriches social media experiences by integrating dynamic Frames within the Farcaster ecosystem. Utilize the comprehensive CoinGecko API to create engaging Frames. This guide serves as a foundation for both novice and experienced developers, emphasizing functionality, user experience, and interactivity.