import { NextRequest, NextResponse } from 'next/server' import BN from 'bn.js'; import { fal } from "@fal-ai/client" import { FLUX_MODELS } from '../../../services/fluxService' import { initializeDataSource } from '../../../data-source' import { verifyPayment, markSignatureAsUsed } from '../../../utils/verifyPayment'; if (!process.env.FAL_AI_KEY) { throw new Error('FAL_AI_KEY is not configured in environment variables') } // Configure fal client fal.config({ credentials: process.env.FAL_AI_KEY }) // Consistent image size for all generations const IMAGE_WIDTH: number = 1024 const IMAGE_HEIGHT: number = 1024 export async function POST(req: NextRequest): Promise { try { await initializeDataSource(); const { prompt, modelId, transactionSignature } = await req.json() if (!prompt || !modelId) { return NextResponse.json( { error: 'Prompt and modelId are required' }, { status: 400 } ) } if (!transactionSignature) { return NextResponse.json( { error: 'Transaction signature is required' }, { status: 400 } ) } const model = FLUX_MODELS.find((model) => model.modelId === modelId) if (!model) { return NextResponse.json( { error: 'Invalid modelId' }, { status: 400 } ) } const quotes: BN[] = (global as any).quotesService.getQuotes(); const lowestQuote = quotes.reduce((minQuote, currentQuote) => BN.min(minQuote, currentQuote), quotes[0]); const scale = new BN(100); const scaledCost = new BN(model.cost * 100); const tokenAmount = scaledCost.mul(new BN(lowestQuote)).div(scale); const isPaymentVerified = await verifyPayment(transactionSignature, tokenAmount); if (!isPaymentVerified) { return NextResponse.json( { error: 'Payment verification failed or transaction signature has already been used' }, { status: 400 } ) } await markSignatureAsUsed(transactionSignature); console.log('Generating with Flux model:', modelId) console.log('Prompt:', prompt) const result = await fal.subscribe(modelId, { input: { prompt: prompt, image_size: { width: IMAGE_WIDTH, height: IMAGE_HEIGHT }, }, logs: true, onQueueUpdate: (update) => { if (update.status === "IN_PROGRESS") { console.log('Generation progress:', update.logs.map((log) => log.message)) } }, }) console.log('Flux generation result:', result) // Extract the image URL from the response const imageUrl = result.data?.images?.[0]?.url if (!imageUrl) { console.error('No image URL in response:', result) throw new Error('No image URL in response') } return NextResponse.json({ imageUrl }) } catch (error) { console.error('Flux generation error:', error) return NextResponse.json( { error: error instanceof Error ? error.message : 'Failed to generate image' }, { status: 500 } ) } } export const dynamic = 'force-dynamic'