2// const baseUrl = "https://api.neynar.com/v2/farcaster/";
3
4export async function fetchNeynarGet(path: string) {
5 const res = await fetch(baseUrl + encodeURIComponent(path), {
6 method: "GET",
7 headers: {
15}
16
17export async function fetchNeynarGetPages(path: string, pages: number, dataKey: string) {
18 let data: any = [];
19 let cursor = "";
20 let pagesLeft = pages;
21 while (true) {
22 const res = await fetchNeynarGet(`${path}&cursor=${cursor}`);
23 data = [...data, ...res[dataKey]];
24 cursor = res?.next?.cursor;
35//////////
36
37export function fetchUser(username: string) {
38 return fetchNeynarGet(`user/by_username?username=${username}`).then(r => r.user);
39}
40export function fetchUsersById(fids: string) {
41 return fetchNeynarGet(`user/bulk?fids=${fids}`).then(r => r.users);
42}
43
44export function fetchUserFeed(fid: number) {
45 return fetchNeynarGet(
46 `feed?feed_type=filter&filter_type=fids&fids=${fid}&with_recasts=false&with_replies=false&limit=100&cursor=`,
47 ).then(r => r.casts);
48}
49
50export function fetchChannel(channelId: string) {
51 return fetchNeynarGet(`channel?id=${channelId}`).then(r => r.channel);
52}
53
54export function fetchChannelFeed(channelId: string) {
55 return fetchNeynarGet(
56 `feed/channels?channel_ids=${channelId}&with_recasts=false&limit=100`,
57 ).then(r => r.casts);
58}
59
60export function fetchChannelsFeed(channelIds: array) {
61 return fetchNeynarGet(
62 `feed/channels?channel_ids=${channelIds.join(",")}&with_recasts=false&limit=100`,
63 ).then(r => r.casts);
5};
6
7export const fetchGet = async (path: string) => {
8 return await fetch("https://api.neynar.com/v2/farcaster/" + path, {
9 method: "GET",
10 headers: headers,
12};
13
14export const fetchPost = async (path: string, body: any) => {
15 return await fetch("https://api.neynar.com/v2/farcaster/" + path, {
16 method: "POST",
17 headers: headers,
4import { embedMetadata, handleFarcasterEndpoints, iconUrl, name } from "./farcaster.ts";
5import { handleImageEndpoints } from "./image.tsx";
6import { fetchGet as fetchNeynarGet } from "./neynar.ts";
7
8const app = new Hono();
19
20app.get("/api/miniapps", async (c) => {
21 const response = await fetch(`https://client.warpcast.com/v1/top-frameapps?limit=100`).then(r => r.json()).then(r =>
22 r?.result?.frames
23 );
28 const url = new URL(c.req.url);
29 const path = url.searchParams.get("path");
30 const response = await fetchNeynarGet(path).then(r => r.json());
31 return c.json(response);
32});
73});
74
75// HTTP vals expect an exported "fetch handler"
76// This is how you "run the server" in Val Town with Hono
77export default app.fetch;
82 const fontPromises = fontsConfig.map(async (font) => {
83 const fontUrl = "https://cdn.jsdelivr.net/npm/@tamagui/font-inter@1.108.3/otf/" + font.fontFile;
84 const fontArrayBuf = await fetch(fontUrl).then((res) => res.arrayBuffer());
85 return { name: font.name, data: fontArrayBuf, weight: font.weight };
86 });
93 // const api = `https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/${code.toLowerCase()}.svg`
94 const api = `https://cdn.jsdelivr.net/gh/shuding/fluentui-emoji-unicode/assets/${code.toLowerCase()}_color.svg`;
95 return fetch(api).then((r) => r.text());
96};
97
6
7import { Button, Input, Section, ShareButton } from "../components/ui.tsx";
8import { fetchNeynarGet, fetchNeynarGetPages, fetchUsersById } from "../util/neynar.ts";
9import { useQuery } from "../util/useQuery.ts";
10
38function MiniApps() {
39 const { data: miniapps } = useQuery(["miniapps"], async () => {
40 // return await fetch(`/api/miniapps`).then(r => r.json()).then(r => r);
41 // return await fetchNeynarGet(`frame/catalog?limit=100`).then(r => r.frames);
42 return await fetchNeynarGetPages(`frame/catalog?limit=100`, 4, "frames").then(r => r.frames);
43 });
44
89
90async function sendFarcasterNotification(payload: any) {
91 return await fetch("https://api.warpcast.com/v1/frame-notifications", {
92 method: "POST",
93 headers: { "Content-Type": "application/json" },
6import { Example } from "./components/Example.tsx";
7import { FarcasterMiniApp } from "./components/FarcasterMiniApp.tsx";
8import { fetchNeynarGet } from "./util/neynar.ts";
9
10import { Home } from "./screens/Home.tsx";
34function Neynar() {
35 useEffect(() => {
36 fetchNeynarGet("user/by_username?username=dwr.eth").then(console.log).catch(console.error);
37 }, []);
38
67 const [currentPage, setCurrentPage] = useState(1);
68
69 const fetchMemories = useCallback(async () => {
70 setLoading(true);
71 setError(null);
72 try {
73 const response = await fetch(API_BASE);
74 if (!response.ok) {
75 throw new Error(`HTTP error! status: ${response.status}`);
78 setMemories(data);
79 } catch (e) {
80 console.error("Failed to fetch memories:", e);
81 setError(e.message || "Failed to fetch memories.");
82 } finally {
83 setLoading(false);
86
87 useEffect(() => {
88 fetchMemories();
89 }, [fetchMemories]);
90
91 const handleAddMemory = async (e: React.FormEvent) => {
100
101 try {
102 const response = await fetch(API_BASE, {
103 method: "POST",
104 headers: { "Content-Type": "application/json" },
112 setNewMemoryTags("");
113 setShowAddForm(false);
114 await fetchMemories();
115 } catch (e) {
116 console.error("Failed to add memory:", e);
123
124 try {
125 const response = await fetch(`${API_BASE}/${id}`, {
126 method: "DELETE",
127 });
129 throw new Error(`HTTP error! status: ${response.status}`);
130 }
131 await fetchMemories();
132 } catch (e) {
133 console.error("Failed to delete memory:", e);
155
156 try {
157 const response = await fetch(`${API_BASE}/${editingMemory.id}`, {
158 method: "PUT",
159 headers: { "Content-Type": "application/json" },
164 }
165 setEditingMemory(null);
166 await fetchMemories();
167 } catch (e) {
168 console.error("Failed to update memory:", e);
135 ));
136
137// HTTP vals expect an exported "fetch handler"
138export default app.fetch;
163```
164
1655. **fetchTranspiledJavaScript** - Fetch and transpile TypeScript to JavaScript:
166```ts
167const jsCode = await fetchTranspiledJavaScript("https://esm.town/v/username/project/path/to/file.ts");
168```
169
242
243 // Inject data to avoid extra round-trips
244 const initialData = await fetchInitialData();
245 const dataScript = `<script>
246 window.__INITIAL_DATA__ = ${JSON.stringify(initialData)};
300
3015. **API Design:**
302 - `fetch` handler is the entry point for HTTP vals
303 - Run the Hono app with `export default app.fetch // This is the entry point for HTTP vals`
304 - Properly handle CORS if needed for external access