Files
create-farcaster-mini-app/src/lib/neynar.ts
2025-05-09 10:55:22 -07:00

76 lines
1.9 KiB
TypeScript

import { NeynarAPIClient, Configuration, WebhookUserCreated } from '@neynar/nodejs-sdk';
import { APP_URL } from './constants';
let neynarClient: NeynarAPIClient | null = null;
// Example usage:
// const client = getNeynarClient();
// const user = await client.lookupUserByFid(fid);
export function getNeynarClient() {
if (!neynarClient) {
const apiKey = process.env.NEYNAR_API_KEY;
if (!apiKey) {
throw new Error('NEYNAR_API_KEY not configured');
}
const config = new Configuration({ apiKey });
neynarClient = new NeynarAPIClient(config);
}
return neynarClient;
}
type User = WebhookUserCreated['data'];
export async function getNeynarUser(fid: number): Promise<User | null> {
try {
const client = getNeynarClient();
const usersResponse = await client.fetchBulkUsers({ fids: [fid] });
return usersResponse.users[0];
} catch (error) {
console.error('Error getting Neynar user:', error);
return null;
}
}
type SendFrameNotificationResult =
| {
state: "error";
error: unknown;
}
| { state: "no_token" }
| { state: "rate_limit" }
| { state: "success" };
export async function sendNeynarFrameNotification({
fid,
title,
body,
}: {
fid: number;
title: string;
body: string;
}): Promise<SendFrameNotificationResult> {
try {
const client = getNeynarClient();
const targetFids = [fid];
const notification = {
title,
body,
target_url: APP_URL,
};
const result = await client.publishFrameNotifications({
targetFids,
notification
});
if (result.notification_deliveries.length > 0) {
return { state: "success" };
} else if (result.notification_deliveries.length === 0) {
return { state: "no_token" };
} else {
return { state: "error", error: result || "Unknown error" };
}
} catch (error) {
return { state: "error", error };
}
}