mirror of
https://github.com/neynarxyz/create-farcaster-mini-app.git
synced 2025-11-16 08:08:56 -05:00
fix: add fid to header
This commit is contained in:
parent
089a5ad2b0
commit
1d5a827049
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "create-neynar-farcaster-frame",
|
"name": "create-neynar-farcaster-frame",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
"bin/index.js"
|
"bin/index.js"
|
||||||
|
|||||||
@ -11,6 +11,33 @@ import crypto from 'crypto';
|
|||||||
// First load .env for main config
|
// First load .env for main config
|
||||||
dotenv.config({ path: '.env' });
|
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() {
|
async function loadEnvLocal() {
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync('.env.local')) {
|
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 = {
|
const header = {
|
||||||
type: 'custody',
|
type: 'custody',
|
||||||
key: accountAddress,
|
key: accountAddress,
|
||||||
|
fid,
|
||||||
};
|
};
|
||||||
const encodedHeader = Buffer.from(JSON.stringify(header), 'utf-8').toString('base64');
|
const encodedHeader = Buffer.from(JSON.stringify(header), 'utf-8').toString('base64');
|
||||||
|
|
||||||
@ -285,6 +313,8 @@ async function main() {
|
|||||||
const accountAddress = await validateSeedPhrase(seedPhrase);
|
const accountAddress = await validateSeedPhrase(seedPhrase);
|
||||||
console.log('✅ Generated account address from seed phrase');
|
console.log('✅ Generated account address from seed phrase');
|
||||||
|
|
||||||
|
const fid = await lookupFidByCustodyAddress(accountAddress, neynarApiKey ?? 'FARCASTER_V2_FRAMES_DEMO');
|
||||||
|
|
||||||
// Generate and sign manifest
|
// Generate and sign manifest
|
||||||
console.log('\n🔨 Generating frame manifest...');
|
console.log('\n🔨 Generating frame manifest...');
|
||||||
|
|
||||||
@ -293,7 +323,7 @@ async function main() {
|
|||||||
? `https://api.neynar.com/f/app/${neynarClientId}/event`
|
? `https://api.neynar.com/f/app/${neynarClientId}/event`
|
||||||
: `${domain}/api/webhook`;
|
: `${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' : ''));
|
console.log('\n✅ Frame manifest generated' + (seedPhrase ? ' and signed' : ''));
|
||||||
|
|
||||||
// Read existing .env file or create new one
|
// Read existing .env file or create new one
|
||||||
|
|||||||
@ -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 trimmedDomain = domain.trim();
|
||||||
const header = {
|
const header = {
|
||||||
type: 'custody',
|
type: 'custody',
|
||||||
key: accountAddress,
|
key: accountAddress,
|
||||||
|
fid,
|
||||||
};
|
};
|
||||||
const encodedHeader = Buffer.from(JSON.stringify(header), 'utf-8').toString('base64');
|
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
|
// Generate frame metadata if we have a seed phrase
|
||||||
let frameMetadata;
|
let frameMetadata;
|
||||||
|
let fid;
|
||||||
if (process.env.SEED_PHRASE) {
|
if (process.env.SEED_PHRASE) {
|
||||||
console.log('\n🔨 Generating frame metadata...');
|
console.log('\n🔨 Generating frame metadata...');
|
||||||
const accountAddress = await validateSeedPhrase(process.env.SEED_PHRASE);
|
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
|
// Determine webhook URL based on Neynar configuration
|
||||||
const webhookUrl = process.env.NEYNAR_API_KEY && process.env.NEYNAR_CLIENT_ID
|
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://api.neynar.com/f/app/${process.env.NEYNAR_CLIENT_ID}/event`
|
||||||
: `https://${domain}/api/webhook`;
|
: `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');
|
console.log('✅ Frame metadata generated and signed');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +523,7 @@ async function deployToVercel(useGitHub = false) {
|
|||||||
: `https://${actualDomain}/api/webhook`;
|
: `https://${actualDomain}/api/webhook`;
|
||||||
|
|
||||||
if (frameMetadata) {
|
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
|
// Update FRAME_METADATA env var using the new function
|
||||||
await setVercelEnvVar('FRAME_METADATA', frameMetadata, projectRoot);
|
await setVercelEnvVar('FRAME_METADATA', frameMetadata, projectRoot);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user