Case 3: Raffle events among the filtered casts

guide on how to create the desired frame using frog.fm

** The full code for this example can be found here. ** You can check the operation of the completed sample here. ** This example demonstrates creating a frame via frog.fm. For more details about frog, please refer to the official documentation below.

This example sequentially takes the following three inputs and randomly selects one of the authors from the filtered casts based on those inputs.

  1. Data Query Using Lum0x SDK 1) The getUserDisplayName function and the getUserPfpUrl function are used to retrieve user information through Lum0x.farcasterUser.getUserByFids

    export async function getUserPfpUrl(fid: number): Promise<string> {
      const res = await Lum0x.farcasterUser.getUserByFids({ fids: String(fid) });
      const user = res.users[0];
      return user.pfp_url;
    }
    
    export async function getUserDisplayName(fid: number): Promise<string> {
      const res = await Lum0x.farcasterUser.getUserByFids({ fids: String(fid) });
      const user = res.users[0];
      return user.display_name;
    }

    2) The part that retrieves the feed is done through Lum0x.farcasterUser.getFeed

    let res = await Lum0x.farcasterFeed.getFeed({
        feed_type: "filter",
        filter_type: "channel_id",
        channel_id: channel,
        limit: limit,
      });

  1. Managing input data for each screen as state 1) Set initialState

    const app = new Frog({
      assetsPath: "/",
      basePath: "/api",
      hub: neynar({ apiKey: process.env.NEYNAR_API_KEY ?? "" }),
      title: "Raffle among your fans",
      imageAspectRatio: "1:1",
      imageOptions: {
        height: 800,
        width: 800,
      },
      initialState: {
        channel: "",
        startDate: "",
        limit: 25,
      },
    });
    

2) Update state with values entered via TextInput (using deriveState, previousState)

  c.deriveState((previousState: any) => {
    previousState.channel = c.inputText;
  });
  1. Adding an Image to the Screen and Binding Data 1) Add Image

app.frame("/limit", async (c) => {
  const fid = c.frameData?.fid;
  await postLum0xTestFrameValidation(Number(fid), "limit");

  c.deriveState((previousState: any) => {
    previousState.endDate = c.inputText;
  });

  return c.res({
    image: "/Steps.png",
    intents: [
      <TextInput placeholder="Enter limit... default: 25" />,
      <Button action="/end-date">Back</Button>,
      <Button action="/raffle">Next</Button>,
    ],
  });
});

2) Data Binding Pass the return value of the getShareImage function to the image property of the frame. getShareImage is a function that returns a <BOX/> element.

app.frame("/result", async (c: any) => {
  const { channel, startDate, limit } = c.previousState;
  const winner: Participant = await getUser(channel, startDate, limit);
  const displayName = await getUserDisplayName(winner.fid);
  const pfpUrl = await getUserPfpUrl(winner.fid);

  return c.res({
    image: getShareImage(displayName, pfpUrl),
    intents: [<Button action="/">Home</Button>],
  });
});

4. Add postLum0xTestFrameValidation By adding this part, the user information of those who pressed the frame will be sent to Lum0x, and later, statistics based on this data will be provided.

  1. Please deploy the completed project code on Vercel. For instructions on how to deploy via Vercel, refer to this guide here.

Last updated