forked from mito-systems/sol-mem-gen
Verify payment on chain before generating image
This commit is contained in:
parent
5277b9d4ca
commit
e2b8e6c584
@ -1,6 +1,8 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { fal } from "@fal-ai/client"
|
||||
|
||||
import { verifyPayment } from '../../../services/paymentService'
|
||||
|
||||
if (!process.env.FAL_AI_KEY) {
|
||||
throw new Error('FAL_AI_KEY is not configured in environment variables')
|
||||
}
|
||||
@ -16,15 +18,28 @@ const IMAGE_HEIGHT: number = 1024
|
||||
|
||||
export async function POST(req: NextRequest): Promise<NextResponse> {
|
||||
try {
|
||||
const { prompt, modelId } = await req.json()
|
||||
const { prompt, modelId, transactionSignature, expectedAmount } = await req.json()
|
||||
|
||||
if (!prompt || !modelId) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Prompt and modelId are required' },
|
||||
{ status: 400 }
|
||||
{ error: 'Prompt and modelId are required' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
if (!transactionSignature || !expectedAmount) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Transaction signature and expected amount are required' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
const isPaymentVerified = await verifyPayment(transactionSignature, expectedAmount);
|
||||
console.log({isPaymentVerified});
|
||||
if (!isPaymentVerified) {
|
||||
throw new Error('Payment verification failed');
|
||||
}
|
||||
|
||||
console.log('Generating with Flux model:', modelId)
|
||||
console.log('Prompt:', prompt)
|
||||
|
||||
|
@ -49,8 +49,10 @@ const Page: React.FC = (): React.ReactElement => {
|
||||
return { error: paymentResult.error }
|
||||
}
|
||||
|
||||
const transactionSignature = paymentResult.signature;
|
||||
|
||||
// Then generate image with specified model
|
||||
return generateWithFlux(prompt, modelId)
|
||||
return generateWithFlux(prompt, modelId, transactionSignature, cost)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,9 @@ export const FLUX_MODELS: FluxModelConfig[] = [
|
||||
|
||||
export async function generateWithFlux(
|
||||
prompt: string,
|
||||
modelId: string
|
||||
modelId: string,
|
||||
transactionSignature: string,
|
||||
expectedAmount: number,
|
||||
): Promise<FluxGenerationResult> {
|
||||
try {
|
||||
const response = await fetch('/api/flux', {
|
||||
@ -44,7 +46,9 @@ export async function generateWithFlux(
|
||||
},
|
||||
body: JSON.stringify({
|
||||
prompt,
|
||||
modelId
|
||||
modelId,
|
||||
transactionSignature,
|
||||
expectedAmount
|
||||
}),
|
||||
})
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Connection, PublicKey, Transaction, SystemProgram } from '@solana/web3.js'
|
||||
import { Connection, PublicKey, Transaction } from '@solana/web3.js'
|
||||
import {
|
||||
TOKEN_PROGRAM_ID,
|
||||
createTransferInstruction,
|
||||
@ -48,7 +48,7 @@ export async function processMTMPayment(
|
||||
walletPublicKey: string,
|
||||
tokenAmount: number,
|
||||
walletType: WalletType
|
||||
): Promise<PaymentResult> {
|
||||
): Promise<PaymentResult & { signature?: string }> {
|
||||
try {
|
||||
let wallet: WalletAdapter | null = null;
|
||||
|
||||
@ -146,7 +146,7 @@ export async function processMTMPayment(
|
||||
throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`)
|
||||
}
|
||||
|
||||
return { success: true }
|
||||
return { success: true, signature };
|
||||
} catch (error) {
|
||||
console.error('Payment error:', error)
|
||||
return {
|
||||
@ -155,3 +155,38 @@ export async function processMTMPayment(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function verifyPayment(
|
||||
transactionSignature: string,
|
||||
expectedAmount: number,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
console.log('Verifying payment:');
|
||||
|
||||
const transaction = await connection.getParsedTransaction(transactionSignature, 'confirmed');
|
||||
if (!transaction) {
|
||||
throw new Error('Transaction not found');
|
||||
}
|
||||
|
||||
const transferInstruction = transaction.transaction.message.instructions.find(
|
||||
(instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID)
|
||||
);
|
||||
|
||||
if (!transferInstruction || !('parsed' in transferInstruction)) {
|
||||
throw new Error('Transfer instruction not found');
|
||||
}
|
||||
|
||||
const { parsed } = transferInstruction;
|
||||
const { info } = parsed;
|
||||
const { amount } = info;
|
||||
|
||||
if (BigInt(amount) === BigInt(expectedAmount * (10 ** 6))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error('Verification error:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user