import { NextResponse } from 'next/server' export async function POST(request) { try { const body = await request.json() const { symbol, side, amount, amountUSD, price, tradingMode = 'SPOT', fromCoin, toCoin } = body console.log(`🔍 Validating trade: ${side} ${amount} ${symbol} (USD: ${amountUSD})`) // Fetch real wallet balance from the wallet API let walletBalance try { const walletResponse = await fetch(`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'}/api/wallet/balance`) const walletData = await walletResponse.json() if (walletData.success && walletData.wallet) { walletBalance = { solBalance: walletData.wallet.solBalance, usdValue: walletData.wallet.usdValue, positions: walletData.balance.positions || [] } console.log(`✅ Real wallet balance: ${walletBalance.solBalance} SOL ($${walletBalance.usdValue.toFixed(2)})`) } else { throw new Error('Failed to fetch wallet balance') } } catch (error) { console.log(`⚠️ Failed to fetch real wallet balance, using fallback: ${error.message}`) // Fallback to hardcoded values only if API fails walletBalance = { solBalance: 0.0728, usdValue: 12.12, positions: [ { symbol: 'SOL', amount: 0.0728, price: 166.5 } ] } } // Determine required balance for the trade let requiredBalance = 0 let requiredCurrency = '' let availableBalance = 0 if (tradingMode === 'SPOT') { if (side.toUpperCase() === 'BUY') { // For BUY orders, use the USD amount directly (not amount * price) requiredBalance = amountUSD || (amount * (price || 166.5)) requiredCurrency = 'USD' availableBalance = walletBalance.usdValue console.log(`💰 BUY validation: Need $${requiredBalance} USD, Have $${availableBalance}`) } else { // For SELL orders, need the actual token amount requiredBalance = amount requiredCurrency = fromCoin || symbol.replace('USD', '') // Find the token balance const tokenPosition = walletBalance.positions.find(pos => pos.symbol === requiredCurrency || pos.symbol === symbol ) availableBalance = tokenPosition ? tokenPosition.amount : walletBalance.solBalance console.log(`💰 SELL validation: Need ${requiredBalance} ${requiredCurrency}, Have ${availableBalance}`) } } else if (tradingMode === 'PERP') { // For perpetuals, only need margin const leverage = 10 // Default leverage requiredBalance = (amountUSD || (amount * (price || 166.5))) / leverage requiredCurrency = 'USD' availableBalance = walletBalance.usdValue console.log(`💰 PERP validation: Need $${requiredBalance} USD margin, Have $${availableBalance}`) } console.log(`💰 Balance check: Need ${requiredBalance} ${requiredCurrency}, Have ${availableBalance}`) // Validate sufficient balance if (requiredBalance > availableBalance) { const shortfall = requiredBalance - availableBalance return NextResponse.json({ success: false, error: 'INSUFFICIENT_BALANCE', message: `Insufficient balance. Need ${requiredBalance.toFixed(6)} ${requiredCurrency}, have ${availableBalance.toFixed(6)}. Shortfall: ${shortfall.toFixed(6)}`, required: requiredBalance, available: availableBalance, shortfall: shortfall, currency: requiredCurrency }, { status: 400 }) } // Validate minimum trade size const minTradeUsd = 1.0 // Minimum $1 trade const tradeValueUsd = side.toUpperCase() === 'BUY' ? requiredBalance : amount * (price || 166.5) if (tradeValueUsd < minTradeUsd) { return NextResponse.json({ success: false, error: 'TRADE_TOO_SMALL', message: `Trade value too small. Minimum trade: $${minTradeUsd}, your trade: $${tradeValueUsd.toFixed(2)}`, minTradeUsd: minTradeUsd, tradeValueUsd: tradeValueUsd }, { status: 400 }) } // Validate maximum trade size (safety check) const maxTradePercent = 0.95 // Max 95% of balance per trade const maxAllowedTrade = availableBalance * maxTradePercent if (requiredBalance > maxAllowedTrade) { return NextResponse.json({ success: false, error: 'TRADE_TOO_LARGE', message: `Trade too large. Maximum allowed: ${maxAllowedTrade.toFixed(6)} ${requiredCurrency} (95% of balance)`, maxAllowed: maxAllowedTrade, requested: requiredBalance, currency: requiredCurrency }, { status: 400 }) } // If we get here, the trade is valid return NextResponse.json({ success: true, validation: { requiredBalance: requiredBalance, availableBalance: availableBalance, currency: requiredCurrency, tradeValueUsd: tradeValueUsd, valid: true }, message: `Trade validation passed: ${side} ${amount} ${symbol}` }) } catch (error) { console.error('❌ Balance validation error:', error) return NextResponse.json({ success: false, error: 'VALIDATION_ERROR', message: 'Failed to validate trade balance: ' + error.message }, { status: 500 }) } } export async function GET() { return NextResponse.json({ message: 'Trade Balance Validation API', description: 'Validates if wallet has sufficient balance for proposed trades', endpoints: { 'POST /api/trading/validate': 'Validate trade against wallet balance' }, parameters: { symbol: 'Trading symbol (SOL, BTC, etc.)', side: 'BUY or SELL', amount: 'Trade amount', price: 'Trade price (optional, uses current market price)', tradingMode: 'SPOT or PERP', fromCoin: 'Source currency', toCoin: 'Target currency' } }) }