197 | );
198 |
199 | async function handleSignIn() {
200 | setLoading(true);
201 | await createAndStoreSigner();
202 | setLoading(false);
203 | }
204 |
205 | async function createAndStoreSigner() {
206 | try {
207 | const response = await axios.post("/api/signer");
208 | if (response.status === 200) {
209 | localStorage.setItem(
210 | LOCAL_STORAGE_KEYS.FARCASTER_USER,
211 | JSON.stringify(response.data)
212 | );
213 | setFarcasterUser(response.data);
214 | }
215 | } catch (error) {
216 | console.error("API Call failed", error);
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/cast-action/README.md:
--------------------------------------------------------------------------------
1 | # Cast Action
2 |
3 | In this guide, we’ll make a cast action with the neynar SDK and frog.fm, within a few minutes! The cast action will fetch the follower count of the cast's author using its fid and display it.
4 |
5 | Before we begin, you can access the [complete source code](https://github.com/neynarxyz/farcaster-examples/tree/main/cast-action) for this guide on GitHub.
6 |
7 | Let's get started!
8 |
9 |
10 |
11 | ## Creating a new frames project
12 |
13 | We will use [bun](https://bun.sh/) and [frog](https://frog.fm/) for building the cast action in this guide, but you can feel free to use anything else!
14 |
15 | Enter this command in your terminal to create a new app:
16 |
17 | ```powershell
18 | bunx create-frog -t bun
19 | ```
20 |
21 | Enter a name for your project and it will spin up a new project for you. Once the project is created install the dependencies:
22 |
23 | ```powershell
24 | cd
25 | bun install
26 | ```
27 |
28 | Now, let's install the dependencies that we are going to need to build out this action:
29 |
30 | ```powershell
31 | bun add @neynar/nodejs-sdk dotenv
32 | ```
33 |
34 | ### Creating the cast action route
35 |
36 | Head over to the `src/index.ts` file. Here, you'll be able to see a starter frame on the / route. But first, let's change the Frog configuration to use `/api` as the base path and use neynar for hubs like this:
37 |
38 | ```typescript index.tsx
39 | export const app = new Frog({
40 | hub: neynar({ apiKey: "NEYNAR_FROG_FM" }),
41 | basePath: "/api",
42 | });
43 | ```
44 |
45 | You also might need to import neynar from "frogs/neynar":
46 |
47 | ```typescript index.tsx
48 | import { neynar } from "frog/hubs";
49 | ```
50 |
51 | Now, we'll create a new post route which will handle our cast actions. So, create a new route like this:
52 |
53 | ```typescript index.tsx
54 | app.hono.post("/followers", async (c) => {
55 | try {
56 | let message = "GM";
57 | return c.json({ message });
58 | } catch (error) {
59 | console.error(error);
60 | }
61 | });
62 | ```
63 |
64 | This route will return a GM message every time the action is clicked, but let's now use the neynar SDK to get the follower count of the cast's author!
65 |
66 | Create a new `src/lib/neynarClient.ts` file and add the following:
67 |
68 | ```typescript neynarClient.ts
69 | import { NeynarAPIClient } from "@neynar/nodejs-sdk";
70 | import { config } from "dotenv";
71 | config();
72 |
73 | if (!process.env.NEYNAR_API_KEY) {
74 | throw new Error("Make sure you set NEYNAR_API_KEY in your .env file");
75 | }
76 |
77 | const neynarClient = new NeynarAPIClient(process.env.NEYNAR_API_KEY);
78 |
79 | export default neynarClient;
80 | ```
81 |
82 | Here, we initialise the neynarClient with the neynar api key which you can get from your dashboard:
83 |
84 | 
85 |
86 | Add the api key in a `.env` file with the name `NEYNAR_API_KEY`.
87 |
88 | Head back to the `src/index.tsx` file and add the following in the followers route instead of the GM message:
89 |
90 | ```typescript index.tsx
91 | try {
92 | const body = await c.req.json();
93 | const result = await neynarClient.validateFrameAction(
94 | body.trustedData.messageBytes
95 | );
96 |
97 | const { users } = await neynarClient.fetchBulkUsers([
98 | Number(result.action.cast.author.fid),
99 | ]);
100 |
101 | if (!users) {
102 | return c.json({ message: "Error. Try Again." }, 500);
103 | }
104 |
105 | let message = `Count:${users[0].follower_count}`;
106 |
107 | return c.json({ message });
108 | } catch (e) {
109 | return c.json({ message: "Error. Try Again." }, 500);
110 | }
111 | ```
112 |
113 | Here, we use the neynar client that we just initialised to first validate the action and get the data from the message bytes. Then, we use it to fetch the user information using the `fetchBulkUsers` function. Finally, we return a message with the follower count!
114 |
115 | ### Creating a frame with add cast action button
116 |
117 | I am also adding a simple frame that allows anyone to install the action. But for that, you need to host your server somewhere, for local development you can use ngrok.
118 |
119 | If you don’t already have it installed, install it from [here](https://ngrok.com/download). Once it’s installed authenticate using your auth token and serve your app using this command:
120 |
121 | ```powershell
122 | ngrok http http://localhost:5173/
123 | ```
124 |
125 | This command will give you a URL which will forward the requests to your localhost:
126 |
127 | 
128 |
129 | You can now head over to the [cast action playground](https://warpcast.com/~/developers/cast-actions) and generate a new URL by adding in the info as such:
130 |
131 | 
132 |
133 | Copy the install URL and paste it into a new variable in the `index.tsx` like this:
134 |
135 | ```typescript index.tsx
136 | const ADD_URL =
137 | "https://warpcast.com/~/add-cast-action?actionType=post&name=Followers&icon=person&postUrl=https%3A%2F%2F05d3-2405-201-800c-6a-70a7-56e4-516c-2d3c.ngrok-free.app%2Fapi%2Ffollowers";
138 | ```
139 |
140 | Finally, you can replace the / route with the following to have a simple frame which links to this URL:
141 |
142 | ```typescript index.tsx
143 | app.frame("/", (c) => {
144 | return c.res({
145 | image: (
146 |