import { NextRequest, NextResponse } from "next/server"; import { Connection, Keypair, PublicKey } from "@solana/web3.js"; import { createLock } from "../../../utils/create-lock"; import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; import { BN } from "bn.js"; import Big from 'big.js'; const connection = new Connection(process.env.NEXT_PUBLIC_SOLANA_RPC_URL!); async function extractInfo(transactionSignature: string) { 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 { info: { amount, authority } } = transferInstruction.parsed; return { authority, amount }; } async function createRewardLock(authority: string, amount: string) { const { USER_PRIVATE_KEY, CLIFF_TIME, WSOL_MINT, NEXT_PUBLIC_MTM_TOKEN_MINT, REWARD_MULTIPLIER } = process.env; if (!USER_PRIVATE_KEY || !CLIFF_TIME || !WSOL_MINT || !NEXT_PUBLIC_MTM_TOKEN_MINT || !REWARD_MULTIPLIER) { throw new Error('Missing required environment variables'); } const duration = new BN(CLIFF_TIME).add(new BN(Math.floor(Date.now() / 1000))); const tokenLockerKeypair = Keypair.fromSecretKey(bs58.decode(USER_PRIVATE_KEY)); const recipientPublicKey = new PublicKey(authority); const url = `https://api.jup.ag/price/v2?ids=${NEXT_PUBLIC_MTM_TOKEN_MINT}&vsToken=${WSOL_MINT}`; const response = await fetch(url); const { data } = await response.json(); const priceWSOLFor1MTM = new Big(data[NEXT_PUBLIC_MTM_TOKEN_MINT].price).toFixed(9); const mtmAmount = new Big(amount).div(new Big(10).pow(6)); const wsolAmount = new BN(new Big(mtmAmount).times(priceWSOLFor1MTM).times(new Big(10).pow(9)).times(REWARD_MULTIPLIER).toFixed(0)); return createLock(tokenLockerKeypair, recipientPublicKey, duration, wsolAmount); } export async function GET(req: NextRequest) { try { const { searchParams } = new URL(req.url); const signature = searchParams.get('signature') || '4HBtnoNUuMGpmbhD9cPiJtbxkhux31pfZs3HYud5eopAU69RaC4UbJsYdj83eafFxV6eH8pSaRgqELrwyjrWp7yz'; const { authority, amount } = await extractInfo(signature); if (!authority || Number(amount) <= 0) { return NextResponse.json({ error: "Invalid transaction details" }, { status: 400 }); } const escrow = await createRewardLock(authority, amount); return NextResponse.json({ success: true, data: { escrow } }); } catch (error) { console.error('API route error:', error); return NextResponse.json({ error: "Internal server error" }, { status: 500 }); } }