From 3186cb7fc8a809231ababf3891273096b952abc5 Mon Sep 17 00:00:00 2001 From: lucas-neynar Date: Thu, 13 Mar 2025 14:07:55 -0700 Subject: [PATCH] feat: ask for splash image url --- bin/index.js | 24 +++++++++- src/app/.well-known/farcaster.json/route.ts | 5 +- .../frames/hello/[name]/opengraph-image.tsx | 32 ------------- src/app/frames/hello/[name]/page.tsx | 47 ------------------- src/app/frames/hello/opengraph-image.tsx | 24 ---------- src/app/frames/hello/page.tsx | 35 -------------- .../[chainId]/[address]/opengraph-image.tsx | 35 -------------- .../frames/token/[chainId]/[address]/page.tsx | 47 ------------------- src/app/page.tsx | 6 ++- 9 files changed, 29 insertions(+), 226 deletions(-) delete mode 100644 src/app/frames/hello/[name]/opengraph-image.tsx delete mode 100644 src/app/frames/hello/[name]/page.tsx delete mode 100644 src/app/frames/hello/opengraph-image.tsx delete mode 100644 src/app/frames/hello/page.tsx delete mode 100644 src/app/frames/token/[chainId]/[address]/opengraph-image.tsx delete mode 100644 src/app/frames/token/[chainId]/[address]/page.tsx diff --git a/bin/index.js b/bin/index.js index bbd7701..f01e57f 100755 --- a/bin/index.js +++ b/bin/index.js @@ -38,6 +38,24 @@ async function init() { return true; } }, + { + type: 'input', + name: 'buttonText', + message: 'Enter the button text for your frame:', + default: 'Launch Frame', + validate: (input) => { + if (input.trim() === '') { + return 'Button text cannot be empty'; + } + return true; + } + }, + { + type: 'input', + name: 'splashImageUrl', + message: 'Enter the URL for your splash image\n(optional -- leave blank to use the default public/splash.png image or replace public/splash.png with your own)\n\nExternal splash image URL:', + default: null + }, { type: 'password', name: 'seedPhrase', @@ -92,9 +110,11 @@ async function init() { const envExampleContent = fs.readFileSync(envExamplePath, 'utf8'); // Write it to .env fs.writeFileSync(envPath, envExampleContent); - // Append project name and description to .env + // Append project name, description, and button text to .env fs.appendFileSync(envPath, `\nNEXT_PUBLIC_FRAME_NAME="${answers.projectName}"`); fs.appendFileSync(envPath, `\nNEXT_PUBLIC_FRAME_DESCRIPTION="${answers.description}"`); + fs.appendFileSync(envPath, `\nNEXT_PUBLIC_FRAME_BUTTON_TEXT="${answers.buttonText}"`); + fs.appendFileSync(envPath, `\nNEXT_PUBLIC_FRAME_SPLASH_IMAGE_URL="${answers.splashImageUrl}"`); fs.unlinkSync(envExamplePath); console.log('\nCreated .env file from .env.example'); } else { @@ -138,7 +158,7 @@ async function init() { execSync('git add .', { cwd: projectPath }); execSync('git commit -m "initial commit from frames-v2-quickstart"', { cwd: projectPath }); - console.log(`\n🪐 ✨ Successfully created frame ${projectName} with git and dependencies installed! ✨🪐`); + console.log(`\n🪐✨ Successfully created frame ${projectName} with git and dependencies installed! ✨🪐`); console.log('\nTo run the app:'); console.log(` cd ${projectName}`); console.log(' npm run dev\n'); diff --git a/src/app/.well-known/farcaster.json/route.ts b/src/app/.well-known/farcaster.json/route.ts index cec0a9a..94788c9 100644 --- a/src/app/.well-known/farcaster.json/route.ts +++ b/src/app/.well-known/farcaster.json/route.ts @@ -3,6 +3,7 @@ import { join } from 'path'; export async function GET() { const appUrl = process.env.NEXT_PUBLIC_URL; + const splashImageUrl = process.env.NEXT_PUBLIC_FRAME_SPLASH_IMAGE_URL || `${appUrl}/splash.png`; let accountAssociation; // TODO: add type try { @@ -22,8 +23,8 @@ export async function GET() { iconUrl: `${appUrl}/icon.png`, homeUrl: appUrl, imageUrl: `${appUrl}/frames/hello/opengraph-image`, - buttonTitle: "Launch Frame", - splashImageUrl: `${appUrl}/splash.png`, + buttonTitle: process.env.NEXT_PUBLIC_FRAME_BUTTON_TEXT || "Launch Frame", + splashImageUrl, splashBackgroundColor: "#f7f7f7", webhookUrl: `${appUrl}/api/webhook`, }, diff --git a/src/app/frames/hello/[name]/opengraph-image.tsx b/src/app/frames/hello/[name]/opengraph-image.tsx deleted file mode 100644 index 16221af..0000000 --- a/src/app/frames/hello/[name]/opengraph-image.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { ImageResponse } from "next/og"; - -export const runtime = "edge"; - -export const alt = "Hello Frame"; -export const size = { - width: 600, - height: 400, -}; - -export const contentType = "image/png"; - -interface Props { - params: Promise<{ - name: string; - }>; -} - -export default async function Image({ params }: Props) { - const { name } = await params; - - return new ImageResponse( - ( -
-

Hello, {name}

-
- ), - { - ...size, - } - ); -} diff --git a/src/app/frames/hello/[name]/page.tsx b/src/app/frames/hello/[name]/page.tsx deleted file mode 100644 index 10196aa..0000000 --- a/src/app/frames/hello/[name]/page.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Metadata } from "next"; -import App from "~/app/app"; - -const appUrl = process.env.NEXT_PUBLIC_URL; - -interface Props { - params: Promise<{ - name: string; - }>; -} - -export async function generateMetadata({ params }: Props): Promise { - const { name } = await params; - - const frame = { - version: "next", - imageUrl: `${appUrl}/frames/hello/${name}/opengraph-image`, - button: { - title: "Launch Frame", - action: { - type: "launch_frame", - name: process.env.NEXT_PUBLIC_FRAME_NAME || "Frames v2 Demo", - url: `${appUrl}/frames/hello/${name}/`, - splashImageUrl: `${appUrl}/splash.png`, - splashBackgroundColor: "#f7f7f7", - }, - }, - }; - - return { - title: `Hello, ${name}`, - description: `A personalized hello frame for ${name}`, - openGraph: { - title: `Hello, ${name}`, - description: `A personalized hello frame for ${name}`, - }, - other: { - "fc:frame": JSON.stringify(frame), - }, - }; -} - -export default async function HelloNameFrame({ params }: Props) { - const { name } = await params; - - return ; -} diff --git a/src/app/frames/hello/opengraph-image.tsx b/src/app/frames/hello/opengraph-image.tsx deleted file mode 100644 index 5d0c3fb..0000000 --- a/src/app/frames/hello/opengraph-image.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { ImageResponse } from "next/og"; - -export const runtime = "edge"; - -export const alt = "Hello Frame"; -export const size = { - width: 600, - height: 400, -}; - -export const contentType = "image/png"; - -export default async function Image() { - return new ImageResponse( - ( -
-

Hello, world!

-
- ), - { - ...size, - } - ); -} diff --git a/src/app/frames/hello/page.tsx b/src/app/frames/hello/page.tsx deleted file mode 100644 index bfd2e56..0000000 --- a/src/app/frames/hello/page.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Metadata } from "next"; -import App from "~/app/app"; - -const appUrl = process.env.NEXT_PUBLIC_URL; - -const frame = { - version: "next", - imageUrl: `${appUrl}/frames/hello/opengraph-image`, - button: { - title: "Launch Frame", - action: { - type: "launch_frame", - name: process.env.NEXT_PUBLIC_FRAME_NAME || "Frames v2 Demo", - url: `${appUrl}/frames/hello/`, - splashImageUrl: `${appUrl}/splash.png`, - splashBackgroundColor: "#f7f7f7", - }, - }, -}; - -export const metadata: Metadata = { - title: "Hello, world!", - description: "A simple hello world frame", - openGraph: { - title: "Hello, world!", - description: "A simple hello world frame", - }, - other: { - "fc:frame": JSON.stringify(frame), - }, -}; - -export default function HelloFrame() { - return ; -} diff --git a/src/app/frames/token/[chainId]/[address]/opengraph-image.tsx b/src/app/frames/token/[chainId]/[address]/opengraph-image.tsx deleted file mode 100644 index 5ce9d39..0000000 --- a/src/app/frames/token/[chainId]/[address]/opengraph-image.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { ImageResponse } from "next/og"; - -export const runtime = "edge"; - -export const alt = "Hello Frame"; -export const size = { - width: 600, - height: 600, -}; - -export const contentType = "image/png"; - -interface Props { - params: Promise<{ - chainId: string; - address: string; - }>; -} - -export default async function Image({ params }: Props) { - const { chainId, address } = await params; - const token = `eip155:${chainId}/erc20:${address}`; - - return new ImageResponse( - ( -
-

View Token

-

{token}

-
- ), - { - ...size, - } - ); -} diff --git a/src/app/frames/token/[chainId]/[address]/page.tsx b/src/app/frames/token/[chainId]/[address]/page.tsx deleted file mode 100644 index ee33b89..0000000 --- a/src/app/frames/token/[chainId]/[address]/page.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Metadata } from "next"; - -const appUrl = process.env.NEXT_PUBLIC_URL; - -interface Props { - params: Promise<{ - chainId: string; - address: string; - }>; -} - -export async function generateMetadata({ params }: Props): Promise { - const { chainId, address } = await params; - const token = `eip155:${chainId}/erc20:${address}`; - - const frame = { - version: "next", - imageUrl: `${appUrl}/frames/token/${chainId}/${address}/opengraph-image`, - aspectRatio: "1:1", - button: { - title: "View Token", - action: { - type: "view_token", - token, - }, - }, - }; - - return { - title: "View Token", - description: token, - openGraph: { - title: "View Token", - description: token, - }, - other: { - "fc:frame": JSON.stringify(frame), - }, - }; -} - -export default async function HelloNameFrame({ params }: Props) { - const { chainId, address } = await params; - const token = `eip155:${chainId}/erc20:${address}`; - - return

View token: {token}

; -} diff --git a/src/app/page.tsx b/src/app/page.tsx index e38a910..5065aab 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,18 +4,20 @@ import App from "./app"; const appUrl = process.env.NEXT_PUBLIC_URL; // frame preview metadata +// question: do we need metadata both in this file and in the .well-known/farcaster.json file? const appName = process.env.NEXT_PUBLIC_FRAME_NAME || "Frames v2 Demo"; +const splashImageUrl = process.env.NEXT_PUBLIC_FRAME_SPLASH_IMAGE_URL || `${appUrl}/splash.png`; const frame = { version: "next", imageUrl: `${appUrl}/opengraph-image`, button: { - title: "Launch Frame", + title: process.env.NEXT_PUBLIC_FRAME_BUTTON_TEXT || "Launch Frame", action: { type: "launch_frame", name: appName, url: appUrl, - splashImageUrl: `${appUrl}/splash.png`, + splashImageUrl, splashBackgroundColor: "#f7f7f7", }, },