forked from mito-systems/sol-mem-gen
Move util to separate file
This commit is contained in:
parent
e2b8e6c584
commit
86b168af4d
@ -1,7 +1,8 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server'
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
import { fal } from "@fal-ai/client"
|
import { fal } from "@fal-ai/client"
|
||||||
|
import { FLUX_MODELS } from '../../../services/fluxService'
|
||||||
|
|
||||||
import { verifyPayment } from '../../../services/paymentService'
|
import { verifyPayment } from '../../../utils/verifyPayment'
|
||||||
|
|
||||||
if (!process.env.FAL_AI_KEY) {
|
if (!process.env.FAL_AI_KEY) {
|
||||||
throw new Error('FAL_AI_KEY is not configured in environment variables')
|
throw new Error('FAL_AI_KEY is not configured in environment variables')
|
||||||
@ -18,7 +19,7 @@ const IMAGE_HEIGHT: number = 1024
|
|||||||
|
|
||||||
export async function POST(req: NextRequest): Promise<NextResponse> {
|
export async function POST(req: NextRequest): Promise<NextResponse> {
|
||||||
try {
|
try {
|
||||||
const { prompt, modelId, transactionSignature, expectedAmount } = await req.json()
|
const { prompt, modelId, transactionSignature } = await req.json()
|
||||||
|
|
||||||
if (!prompt || !modelId) {
|
if (!prompt || !modelId) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@ -27,15 +28,24 @@ export async function POST(req: NextRequest): Promise<NextResponse> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!transactionSignature || !expectedAmount) {
|
if (!transactionSignature) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Transaction signature and expected amount are required' },
|
{ error: 'Transaction signature is required' },
|
||||||
{ status: 400 }
|
{ status: 400 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPaymentVerified = await verifyPayment(transactionSignature, expectedAmount);
|
const model = FLUX_MODELS.find((model) => model.modelId === modelId)
|
||||||
console.log({isPaymentVerified});
|
if (!model) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Invalid modelId' },
|
||||||
|
{ status: 400 }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedAmount = model.cost;
|
||||||
|
const isPaymentVerified = await verifyPayment(transactionSignature, expectedAmount)
|
||||||
|
|
||||||
if (!isPaymentVerified) {
|
if (!isPaymentVerified) {
|
||||||
throw new Error('Payment verification failed');
|
throw new Error('Payment verification failed');
|
||||||
}
|
}
|
||||||
|
@ -49,10 +49,10 @@ const Page: React.FC = (): React.ReactElement => {
|
|||||||
return { error: paymentResult.error }
|
return { error: paymentResult.error }
|
||||||
}
|
}
|
||||||
|
|
||||||
const transactionSignature = paymentResult.signature;
|
const transactionSignature = paymentResult.transactionSignature;
|
||||||
|
|
||||||
// Then generate image with specified model
|
// Then generate image with specified model
|
||||||
return generateWithFlux(prompt, modelId, transactionSignature, cost)
|
return generateWithFlux(prompt, modelId, transactionSignature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ export async function generateWithFlux(
|
|||||||
prompt: string,
|
prompt: string,
|
||||||
modelId: string,
|
modelId: string,
|
||||||
transactionSignature: string,
|
transactionSignature: string,
|
||||||
expectedAmount: number,
|
|
||||||
): Promise<FluxGenerationResult> {
|
): Promise<FluxGenerationResult> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/flux', {
|
const response = await fetch('/api/flux', {
|
||||||
@ -48,7 +47,6 @@ export async function generateWithFlux(
|
|||||||
prompt,
|
prompt,
|
||||||
modelId,
|
modelId,
|
||||||
transactionSignature,
|
transactionSignature,
|
||||||
expectedAmount
|
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ const connection = new Connection(
|
|||||||
|
|
||||||
export interface PaymentResult {
|
export interface PaymentResult {
|
||||||
success: boolean
|
success: boolean
|
||||||
|
transactionSignature?: string,
|
||||||
error?: string
|
error?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ export async function processMTMPayment(
|
|||||||
walletPublicKey: string,
|
walletPublicKey: string,
|
||||||
tokenAmount: number,
|
tokenAmount: number,
|
||||||
walletType: WalletType
|
walletType: WalletType
|
||||||
): Promise<PaymentResult & { signature?: string }> {
|
): Promise<PaymentResult> {
|
||||||
try {
|
try {
|
||||||
let wallet: WalletAdapter | null = null;
|
let wallet: WalletAdapter | null = null;
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ export async function processMTMPayment(
|
|||||||
throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`)
|
throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return { success: true, signature };
|
return { success: true, transactionSignature: signature };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Payment error:', error)
|
console.error('Payment error:', error)
|
||||||
return {
|
return {
|
||||||
@ -155,38 +156,3 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
47
src/utils/verifyPayment.ts
Normal file
47
src/utils/verifyPayment.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { Connection } from '@solana/web3.js';
|
||||||
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||||
|
|
||||||
|
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL || 'https://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4';
|
||||||
|
const SOLANA_WEBSOCKET_URL = process.env.NEXT_PUBLIC_SOLANA_WEBSOCKET_URL || 'wss://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4';
|
||||||
|
|
||||||
|
const connection = new Connection(
|
||||||
|
SOLANA_RPC_URL,
|
||||||
|
{
|
||||||
|
commitment: 'confirmed',
|
||||||
|
wsEndpoint: SOLANA_WEBSOCKET_URL,
|
||||||
|
confirmTransactionInitialTimeout: 60000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export async function verifyPayment(
|
||||||
|
transactionSignature: string,
|
||||||
|
expectedAmount: number,
|
||||||
|
): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const transaction = await connection.getParsedTransaction(transactionSignature, 'finalized');
|
||||||
|
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