Files
trading_bot_v3/app/api/trading/execute-dex/route.js
mindesbunister fb8d361020 fix: Update trading API routes for enhanced functionality
API Route Improvements:
- Enhanced execute-dex route for better DEX trade execution
- Improved validation route for comprehensive trade validation
- Better error handling and response formatting
- Supporting infrastructure for Jupiter-style trading interface

These changes complement the new chart trading interface with more robust backend processing.
2025-07-16 16:21:43 +02:00

273 lines
8.6 KiB
JavaScript

import { NextResponse } from 'next/server'
export async function POST(request) {
try {
const body = await request.json()
const {
symbol,
side,
amount,
amountUSD,
stopLoss,
takeProfit,
useRealDEX = false,
tradingPair,
quickSwap = false,
closePosition = false,
fromCoin,
toCoin
} = body
console.log('🔄 Execute DEX trade request:', {
symbol,
side,
amount,
amountUSD,
stopLoss,
takeProfit,
useRealDEX,
tradingPair,
quickSwap
})
// Validate inputs
if (!symbol || !side || !amount) {
return NextResponse.json(
{
success: false,
error: 'Missing required fields: symbol, side, amount'
},
{ status: 400 }
)
}
if (!['BUY', 'SELL'].includes(side.toUpperCase())) {
return NextResponse.json(
{
success: false,
error: 'Invalid side. Must be BUY or SELL'
},
{ status: 400 }
)
}
if (amount <= 0) {
return NextResponse.json(
{
success: false,
error: 'Amount must be greater than 0'
},
{ status: 400 }
)
}
// Validate balance before proceeding (skip for position closing)
if (!closePosition) {
console.log('🔍 Validating wallet balance before DEX trade...')
try {
const validationResponse = await fetch(`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'}/api/trading/validate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
symbol,
side,
amount,
amountUSD,
tradingMode: 'SPOT',
fromCoin,
toCoin
})
})
const validationResult = await validationResponse.json()
if (!validationResult.success) {
console.log('❌ DEX balance validation failed:', validationResult.message)
return NextResponse.json({
success: false,
error: validationResult.error,
message: validationResult.message,
validation: validationResult
}, { status: validationResponse.status })
}
console.log('✅ DEX balance validation passed')
} catch (validationError) {
console.error('❌ DEX balance validation error:', validationError)
return NextResponse.json({
success: false,
error: 'VALIDATION_FAILED',
message: 'Could not validate wallet balance for DEX trade. Please try again.'
}, { status: 500 })
}
}
// For now, simulate the trade until Jupiter integration is fully tested
if (!useRealDEX) {
console.log('🎮 Executing SIMULATED trade (real DEX integration available)')
// Simulate realistic execution
const currentPrice = symbol === 'SOL' ? 166.75 : symbol === 'BTC' ? 121819 : 3041.66
const priceImpact = amount > 10 ? 0.005 : 0.001
const executedPrice = side === 'BUY'
? currentPrice * (1 + priceImpact)
: currentPrice * (1 - priceImpact)
// Simulate network delay
await new Promise(resolve => setTimeout(resolve, 1000))
const result = {
success: true,
trade: {
txId: `sim_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
orderId: `order_${Date.now()}`,
symbol: symbol.toUpperCase(),
side: side.toUpperCase(),
amount: amount,
executedPrice: executedPrice,
timestamp: Date.now(),
status: 'FILLED',
dex: 'SIMULATION',
stopLoss: stopLoss,
takeProfit: takeProfit,
monitoring: !!(stopLoss || takeProfit)
},
message: `${side.toUpperCase()} order for ${amount} ${symbol} simulated at $${executedPrice.toFixed(4)}`
}
if (stopLoss || takeProfit) {
result.message += ` with TP/SL monitoring`
}
return NextResponse.json(result)
}
// Real DEX execution (Jupiter)
console.log('🚀 Executing REAL trade on Jupiter DEX')
try {
// Dynamic import to avoid build issues
const { jupiterDEXService } = await import('../../../../lib/jupiter-dex-service')
if (!jupiterDEXService.isConfigured()) {
return NextResponse.json({
success: false,
error: 'Jupiter DEX service not configured',
message: 'Wallet not initialized for real trading'
}, { status: 503 })
}
const tradeResult = await jupiterDEXService.executeTrade({
symbol: symbol.toUpperCase(),
side: side.toUpperCase(),
amount: parseFloat(amount),
stopLoss: stopLoss ? parseFloat(stopLoss) : undefined,
takeProfit: takeProfit ? parseFloat(takeProfit) : undefined,
tradingPair: tradingPair,
quickSwap: quickSwap
})
if (!tradeResult.success) {
return NextResponse.json({
success: false,
error: tradeResult.error || 'Trade execution failed',
dex: 'JUPITER'
}, { status: 500 })
}
const tradeResponse = {
success: true,
trade: {
txId: tradeResult.txId,
orderId: tradeResult.orderId,
symbol: symbol.toUpperCase(),
side: side.toUpperCase(),
amount: amount,
timestamp: Date.now(),
status: stopLoss || takeProfit ? 'MONITORING' : 'FILLED',
dex: 'JUPITER',
stopLoss: stopLoss,
takeProfit: takeProfit,
monitoring: !!(stopLoss || takeProfit)
},
message: `${side.toUpperCase()} order executed on Jupiter DEX${stopLoss || takeProfit ? ' with TP/SL monitoring' : ''}`
}
// Add trade to history with clear spot swap indication
try {
// Use localhost for internal container communication
await fetch('http://localhost:3001/api/trading/history', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'add',
symbol: tradingPair || `${fromCoin || symbol}/${toCoin || 'USDC'}`,
side: side.toUpperCase(),
amount: amount,
price: 168.1, // Get from actual execution
type: 'SPOT_SWAP', // Clearly indicate this is a spot swap
status: 'executed',
txId: tradeResult.txId,
dex: 'JUPITER',
tradingMode: 'SPOT',
notes: closePosition ? 'Position closing trade' : `Spot swap: ${amount} ${fromCoin || symbol}${toCoin || 'USDC'}`
})
})
console.log('✅ Spot trade added to history')
} catch (error) {
console.error('❌ Failed to add trade to history:', error)
}
// DON'T create positions for spot swaps - they're instant settlements
// Only leverage/perpetual trades should create positions
// For spot trades, we only need trade history entries
// Note: Position creation is intentionally removed for spot trades
// If this trade had stop loss or take profit, those would be handled as separate limit orders
console.log('✅ Spot trade completed - no position created (instant settlement)')
return NextResponse.json(tradeResponse)
} catch (error) {
console.error('❌ Jupiter DEX execution failed:', error)
return NextResponse.json({
success: false,
error: 'Jupiter DEX execution failed',
message: error.message,
dex: 'JUPITER'
}, { status: 500 })
}
} catch (error) {
console.error('❌ Trade execution API error:', error)
return NextResponse.json(
{
success: false,
error: 'Internal server error',
message: error.message
},
{ status: 500 }
)
}
}
export async function GET() {
return NextResponse.json({
message: 'Enhanced Trading Execute API - Real DEX Integration Available',
endpoints: {
POST: '/api/trading/execute-dex - Execute trades on real DEX with TP/SL'
},
parameters: {
symbol: 'string (required) - Trading symbol (SOL, BTC, ETH)',
side: 'string (required) - BUY or SELL',
amount: 'number (required) - Amount to trade',
stopLoss: 'number (optional) - Stop loss price',
takeProfit: 'number (optional) - Take profit price',
useRealDEX: 'boolean (optional) - true for Jupiter DEX, false for simulation'
},
supportedDEX: ['Jupiter (Solana)', 'Simulation'],
features: ['Stop Loss Orders', 'Take Profit Orders', 'Real-time Monitoring']
})
}