Create multi step cast action

In this guide, we’ll make a multi-step cast action, within a few minutes! The cast action will go ahead and return a frame which will show the cast hash.

Let's get started!

Creating a new frames project

We will use bun and frog for building the cast action in this guide, but feel free to use framejs, onchainkit, or anything else as well!

Enter this command in your terminal to create a new app:

bunx create-frog -t bun

Enter a name for your project and it will spin up a new project for you. Once the project is created install the dependencies:

cd <project_name>
bun install

Once everything is done, open up index.tsx and update the Frog instance to use neynar hubs and make sure to update the api key so that you can get analytics for your frame and cast action!

import { neynar } from "frog/hubs";

export const app = new Frog({
  hub: neynar({ apiKey: "NEYNAR_FROG_FM" }),
});

Creating the add cast action frame

Firstly, let's create the home screen frame that will link to adding the cast action. So, head over to the index.tsx file and update the / frame to this:

app.frame("/", (c) => {
  return c.res({
    image: (
      <div
        style={{
          alignItems: "center",
          background: "black",
          backgroundSize: "100% 100%",
          height: "100%",
          textAlign: "center",
          width: "100%",
          display: "flex",
        }}
      >
        <div
          style={{
            color: "white",
            fontSize: 60,
            padding: "0 120px",
            whiteSpace: "pre-wrap",
          }}
        >
          Create a multi step cast action
        </div>
      </div>
    ),
    intents: [
      <Button.AddCastAction action="/get-cast-hash">Add</Button.AddCastAction>,
    ],
  });
});

This should render a pretty simple frame like this:

Let's now build the actual cast action.

Creating the cast action

The frog instance provides us with a .castAction which can be used to create new cast actions like this:


app.castAction(
  "/get-cast-hash",
  (c) => {
    return c.frame({ path: "/cast-hash" });
  },
  { name: "Get cast hash", icon: "hash" }
);

This creates a new cast action on the /get-cast-hash route which will return a new frame linking to /cast-hash. In the last object, you can change the name and icon of your cast action and add a description as well!

Now, let's create the frame that the cast action will return.

Creating the cast hash frame

Create a new frame on the /cast-hash route like this:

app.frame("/cast-hash", (c) => {
  return c.res({
    image: (
      <div
        style={{
          alignItems: "center",
          background: "black",
          backgroundSize: "100% 100%",
          display: "flex",
          flexDirection: "column",
          height: "100%",
          justifyContent: "center",
          textAlign: "center",
          width: "100%",
        }}
      >
        <div
          style={{
            color: "white",
            fontSize: 48,
            marginTop: 30,
            padding: "0 120px",
          }}
        >
          Cast hash is:
        </div>
        <div
          style={{
            color: "white",
            fontSize: 48,
            marginTop: 30,
            padding: "0 120px",
          }}
        >
          {c.frameData?.castId.hash}
        </div>
      </div>
    ),
  });
});

This frame gets the cast hash from the frameData object and displays it.

Now we can go ahead and test our cast action. But for that, you need to host your server somewhere, for local development you can use ngrok.

If you don’t already have it installed, install it from here. Once it’s installed authenticate using your auth token and serve your app using this command:

ngrok http http://localhost:5173/

This command will give you a URL which will forward the requests to your localhost:

If you go ahead and try out your action you'll see a frame like this 🥳


Conclusion

This guide taught us how to create a multi-step cast action, which returns a frame! If you want to look at the completed code, check out the GitHub Gist.

Lastly, make sure to sure what you built with us on Farcaster by tagging @neynar and if you have any questions, reach out to us on warpcast or Telegram!