import { NextResponse } from 'next/server' export async function POST(request) { try { const body = await request.json() const { symbol, side, amount, price, tradingMode = 'SPOT', fromCoin, toCoin } = body console.log(`🔍 Validating trade: ${side} ${amount} ${symbol}`) // For now, use hardcoded wallet balance values for validation // In production, this would fetch from the actual wallet API const mockWalletBalance = { solBalance: 0.0728, // Current actual balance usdValue: 12.12, // Current USD value 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, need USDC or USD equivalent const tradePrice = price || 166.5 // Use provided price or current SOL price requiredBalance = amount * tradePrice requiredCurrency = 'USD' availableBalance = mockWalletBalance.usdValue } else { // For SELL orders, need the actual token requiredBalance = amount requiredCurrency = fromCoin || symbol // Find the token balance const tokenPosition = mockWalletBalance.positions.find(pos => pos.symbol === requiredCurrency || pos.symbol === symbol ) availableBalance = tokenPosition ? tokenPosition.amount : 0 } } else if (tradingMode === 'PERP') { // For perpetuals, only need margin const leverage = 10 // Default leverage const tradePrice = price || 166.5 requiredBalance = (amount * tradePrice) / leverage requiredCurrency = 'USD' availableBalance = mockWalletBalance.usdValue } 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' } }) }