🖼️Farcaster frame
A guide for running Lilypad jobs in a Farcaster frame
In this guide we will be building a Farcaster frame for local development that runs a Lilysay prompt on the Lilypad Network.

Users of the frame can input a prompt and a generate an image. The generated image will appear in the box above the input and will allow a user to view the ASCII art as an image.
Project Setup
Generate project
For this frame, create a NextJS 14 app:
Next, install the required dependencies. Coinbase onchain kit is used in this project:
Open the project in your code editor.
Get testnet tokens
We will need to fund a wallet with Lilypad and Arbitrum Sepolia testnet tokens. Follow the first 2 sections labelled "Setting up MetaMask" and "Funding your wallet" from our Quick Start docs.
Add .env.local
.env.localAdd the following into your .env.local file. The private key is used to run the CLI jobs. Make sure that your .env.local file is added to the .gitignore file as your private key should not be exposed or pushed.
WEB3_PRIVATE_KEY=YOUR_PRIVATE_KEYNEXT_PUBLIC_BASE_URL=http://localhost:3000
Install Lilypad CLI
Run through this guide to install the Lilypad CLI on your machine. Select the CLI User script.
Run Framegear
Framegear is a simple tool provided by the @coinbase/onchainkit package that allows you to run and test your frames locally without publishing the frame.
In a separate terminal, clone down the onchainkit repo and run Framegear:
Navigate to http://localhost:1337 and keep that window open for when we start to write the frame.
Configuration for frame
We will need to set up the metadata for our Next.js application that includes Farcaster frame information. It will configure the elements and a URL for frame posting, while also specifying Open Graph metadata for improved social sharing.
In app/page.tsx, add the following before the Home function declaration:
UI Components
The UI elements for this frame are all rendered in the app/api/route.ts file, which acts as a request handler for different routes or endpoints within the web application. It defines the logic for handling user input, generating responses, and managing application state. The main functions include processing user prompts, handling status checks, and generating images asynchronously.
Routes
Here’s how the routes are structured for this frame:
/api/frame?action=input: This route displays the initial user interface, which includes a text input field for the prompt and a button to submit the form. The user interface also updates dynamically based on the processing status, such as showing a placeholder image or the final generated image./api/frame?action=submit: This route processes the user input. When a prompt is submitted, the server initiates the image generation process asynchronously. While the image is being generated, the user sees a loading state, and they can check the progress./api/frame?action=check: This route checks the status of the image generation process. It updates the frame with either a completed image, an error message if the generation fails, or the processing state if the image is still being generated.We also include a fallback just in case an error occurs during the processing of job.
/api/frame?action=save: Though not explicitly included, this could be an additional route for handling the logic of saving the generated image to a location for future access.
generateImage
generateImageThe generateImage function handles the user input and generates the final image for display by utilizing the functions in app/services/cli.ts. It ensures that the image is generated asynchronously and the result is available for display in the frame, or handled properly in case of any errors during the generation process.
Frame images
Throughout the interaction process, various images are used. These images serve as visual cues during each step of the frame, such as when the user is prompted for input, while the image is being processed and once the final result is ready or if an error occurs.
To obtain the images used in this guide, save them from the source code here.
Create route.ts
route.tsCreate the api/frame directories in your project. Inside of the app/api/frame directory, create a file named route.ts and add the following code:
Create cli.ts
cli.tsThis is where the execution of the Lilysay job happens. It will run the job, wait for it to finish and then create an image from the return value.
Inside of the app directory, create a new directory named services and inside of that create a file named cli.ts. The functions inside this file will allow us to send a prompt to the Lilypad Network using the user prompt and a predefined command that runs asynchronously in the terminal. Once the command is executed, Lilypad processes the input through its Lilysay module and outputs the results in the form of an ASCII image, which is then converted into a displayable image using an SVG-to-PNG transformation.
Here are the 3 functions inside this file:
createImageBufferFromAscii: Converts ASCII text into an SVG image and then uses thesharplibrary to convert the SVG into a PNG image buffer. This allows the display or saving of an image representation of the ASCII text.runCliCommand: Executes a Lilypad CLI command to process the user's input text, captures the command's output, and converts it into an image buffer. It handles the entire process of running the command, capturing the output, and managing errors.extractStdoutFilePath: Parses the CLI command's stdout to extract the file path where the Lilypad CLI has saved the output. It uses a regex pattern to identify the path in the command's output.
The following code snippet demonstrates the process:
Sending the Request: The user's input text is passed directly into the Lilypad CLI command using a shell process. The input text is embedded within the command's arguments and executed asynchronously in the terminal.
Handling the Response: After the CLI command completes, the output is captured and processed. The response includes the file path to the generated ASCII image, which is then read from the file system and converted into a PNG image for further use.
Error Handling: If an error occurs during the execution of the CLI command or file processing, it is logged to the console, and the process is terminated with appropriate error messaging.
Testing
The Framegear server is running. Next, run your local server in your frame project. We will need to make sure it is running on port 3000:
Navigate to the Framegear host http://localhost:1337 and you will see an input labeled "Enter your frame URL". Add http://localhost:3000 to that and click "Fetch".

You should now see your frame and be able to interact with it. Enter a prompt to display in the Lilysay ACSII image!
Rendering results
As the job is processed, a “Check Status” button will be displayed. Clicking this will check if the job has been completed. Once a job is completed, the results will be displayed in the frame. If there is an issue along the way, an error message will be displayed and the user will be prompted to try again.
Potential Use Cases
Running Lilysay jobs is just one of the ways you can utilize Lilypad in a frame, but you can run jobs with any available modules on the Lilypad Network. Some of these include:
Stable Diffusion image
Stable Diffusion video
Ollama
Resources
Last updated
Was this helpful?

