fix: add fid to header

This commit is contained in:
lucas-neynar 2025-03-21 15:12:53 -07:00
parent 089a5ad2b0
commit 1d5a827049
No known key found for this signature in database
3 changed files with 66 additions and 6 deletions

View File

@ -1,6 +1,6 @@
{
"name": "create-neynar-farcaster-frame",
"version": "1.2.1",
"version": "1.2.2",
"type": "module",
"files": [
"bin/index.js"

View File

@ -11,6 +11,33 @@ import crypto from 'crypto';
// First load .env for main config
dotenv.config({ path: '.env' });
async function lookupFidByCustodyAddress(custodyAddress, apiKey) {
if (!apiKey) {
throw new Error('Neynar API key is required');
}
const response = await fetch(
`https://api.neynar.com/v2/farcaster/user/custody-address?custody_address=${custodyAddress}`,
{
headers: {
'accept': 'application/json',
'x-api-key': apiKey
}
}
);
if (!response.ok) {
throw new Error(`Failed to lookup FID: ${response.statusText}`);
}
const data = await response.json();
if (!data.user?.fid) {
throw new Error('No FID found for this custody address');
}
return data.user.fid;
}
async function loadEnvLocal() {
try {
if (fs.existsSync('.env.local')) {
@ -109,10 +136,11 @@ async function validateSeedPhrase(seedPhrase) {
}
}
async function generateFarcasterMetadata(domain, accountAddress, seedPhrase, webhookUrl) {
async function generateFarcasterMetadata(domain, fid, accountAddress, seedPhrase, webhookUrl) {
const header = {
type: 'custody',
key: accountAddress,
fid,
};
const encodedHeader = Buffer.from(JSON.stringify(header), 'utf-8').toString('base64');
@ -285,6 +313,8 @@ async function main() {
const accountAddress = await validateSeedPhrase(seedPhrase);
console.log('✅ Generated account address from seed phrase');
const fid = await lookupFidByCustodyAddress(accountAddress, neynarApiKey ?? 'FARCASTER_V2_FRAMES_DEMO');
// Generate and sign manifest
console.log('\n🔨 Generating frame manifest...');
@ -293,7 +323,7 @@ async function main() {
? `https://api.neynar.com/f/app/${neynarClientId}/event`
: `${domain}/api/webhook`;
const metadata = await generateFarcasterMetadata(domain, accountAddress, seedPhrase, webhookUrl);
const metadata = await generateFarcasterMetadata(domain, fid, accountAddress, seedPhrase, webhookUrl);
console.log('\n✅ Frame manifest generated' + (seedPhrase ? ' and signed' : ''));
// Read existing .env file or create new one

View File

@ -24,11 +24,39 @@ async function validateSeedPhrase(seedPhrase) {
}
}
async function generateFarcasterMetadata(domain, accountAddress, seedPhrase, webhookUrl) {
async function lookupFidByCustodyAddress(custodyAddress, apiKey) {
if (!apiKey) {
throw new Error('Neynar API key is required');
}
const response = await fetch(
`https://api.neynar.com/v2/farcaster/user/custody-address?custody_address=${custodyAddress}`,
{
headers: {
'accept': 'application/json',
'x-api-key': apiKey
}
}
);
if (!response.ok) {
throw new Error(`Failed to lookup FID: ${response.statusText}`);
}
const data = await response.json();
if (!data.user?.fid) {
throw new Error('No FID found for this custody address');
}
return data.user.fid;
}
async function generateFarcasterMetadata(domain, fid, accountAddress, seedPhrase, webhookUrl) {
const trimmedDomain = domain.trim();
const header = {
type: 'custody',
key: accountAddress,
fid,
};
const encodedHeader = Buffer.from(JSON.stringify(header), 'utf-8').toString('base64');
@ -390,16 +418,18 @@ async function deployToVercel(useGitHub = false) {
// Generate frame metadata if we have a seed phrase
let frameMetadata;
let fid;
if (process.env.SEED_PHRASE) {
console.log('\n🔨 Generating frame metadata...');
const accountAddress = await validateSeedPhrase(process.env.SEED_PHRASE);
fid = await lookupFidByCustodyAddress(accountAddress, process.env.NEYNAR_API_KEY ?? 'FARCASTER_V2_FRAMES_DEMO');
// Determine webhook URL based on Neynar configuration
const webhookUrl = process.env.NEYNAR_API_KEY && process.env.NEYNAR_CLIENT_ID
? `https://api.neynar.com/f/app/${process.env.NEYNAR_CLIENT_ID}/event`
: `https://${domain}/api/webhook`;
frameMetadata = await generateFarcasterMetadata(domain, accountAddress, process.env.SEED_PHRASE, webhookUrl);
frameMetadata = await generateFarcasterMetadata(domain, fid, accountAddress, process.env.SEED_PHRASE, webhookUrl);
console.log('✅ Frame metadata generated and signed');
}
@ -493,7 +523,7 @@ async function deployToVercel(useGitHub = false) {
: `https://${actualDomain}/api/webhook`;
if (frameMetadata) {
frameMetadata = await generateFarcasterMetadata(actualDomain, await validateSeedPhrase(process.env.SEED_PHRASE), process.env.SEED_PHRASE, webhookUrl);
frameMetadata = await generateFarcasterMetadata(actualDomain, fid, await validateSeedPhrase(process.env.SEED_PHRASE), process.env.SEED_PHRASE, webhookUrl);
// Update FRAME_METADATA env var using the new function
await setVercelEnvVar('FRAME_METADATA', frameMetadata, projectRoot);
}