- Fix timeframe parameter handling in enhanced-screenshot API route - Support both 'timeframe' (singular) and 'timeframes' (array) parameters - Add proper sessionId propagation for real-time progress tracking - Enhance MACD analysis prompt with detailed crossover definitions - Add progress tracker service with Server-Sent Events support - Fix Next.js build errors in chart components (module variable conflicts) - Change dev environment port from 9000:3000 to 9001:3000 - Improve AI analysis layout detection logic - Add comprehensive progress tracking through all service layers
231 lines
7.5 KiB
JavaScript
231 lines
7.5 KiB
JavaScript
import { NextResponse } from 'next/server'
|
|
import { jupiterDEXService } from '@/lib/jupiter-dex-service'
|
|
import { jupiterTriggerService } from '@/lib/jupiter-trigger-service'
|
|
|
|
export async function POST(request) {
|
|
try {
|
|
const body = await request.json()
|
|
const {
|
|
symbol,
|
|
side,
|
|
amount,
|
|
leverage = 1,
|
|
stopLoss,
|
|
takeProfit,
|
|
useRealDEX = false
|
|
} = body
|
|
|
|
console.log('🚀 Jupiter Leveraged Spot Trade request:', {
|
|
symbol,
|
|
side,
|
|
amount,
|
|
leverage,
|
|
stopLoss,
|
|
takeProfit,
|
|
useRealDEX
|
|
})
|
|
|
|
// 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 }
|
|
)
|
|
}
|
|
|
|
if (leverage < 1 || leverage > 10) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: 'Leverage must be between 1x and 10x'
|
|
},
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
if (!useRealDEX) {
|
|
// Simulation mode
|
|
console.log('🎮 Executing SIMULATED leveraged spot trade')
|
|
|
|
const currentPrice = symbol === 'SOL' ? 166.75 : symbol === 'BTC' ? 121819 : 3041.66
|
|
const leveragedAmount = amount * leverage
|
|
const estimatedTokens = side === 'BUY' ? leveragedAmount / currentPrice : leveragedAmount
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 1200))
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
trade: {
|
|
txId: `jupiter_leverage_sim_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
|
|
symbol: symbol.toUpperCase(),
|
|
side: side.toUpperCase(),
|
|
amount: leveragedAmount,
|
|
leverage: leverage,
|
|
originalAmount: amount,
|
|
estimatedTokens: estimatedTokens,
|
|
entryPrice: currentPrice,
|
|
timestamp: Date.now(),
|
|
status: 'FILLED',
|
|
platform: 'Jupiter DEX (Leveraged Spot)',
|
|
stopLoss: stopLoss,
|
|
takeProfit: takeProfit,
|
|
triggerOrders: stopLoss || takeProfit ? 'PENDING' : 'NONE'
|
|
},
|
|
message: `${side.toUpperCase()} ${leveragedAmount} USD worth of ${symbol} (${leverage}x leveraged spot trade) - SIMULATED`
|
|
})
|
|
}
|
|
|
|
// Real trading with Jupiter DEX + Trigger Orders
|
|
console.log('💰 Executing REAL leveraged spot trade via Jupiter DEX + Trigger Orders')
|
|
|
|
// Step 1: Execute the main trade with leveraged amount
|
|
const leveragedAmount = amount * leverage
|
|
const tradingPair = symbol === 'SOL' ? (side === 'BUY' ? 'USDC/SOL' : 'SOL/USDC') : 'SOL/USDC'
|
|
|
|
const tradeResult = await jupiterDEXService.executeTrade({
|
|
symbol,
|
|
side,
|
|
amount: leveragedAmount,
|
|
tradingPair,
|
|
quickSwap: false
|
|
})
|
|
|
|
if (!tradeResult.success) {
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: `Main trade failed: ${tradeResult.error}`
|
|
}, { status: 400 })
|
|
}
|
|
|
|
console.log('✅ Main leveraged trade executed:', tradeResult.txId)
|
|
|
|
// Step 2: Calculate position size for trigger orders
|
|
const currentPrice = symbol === 'SOL' ? 166.75 : 3041.66 // Get from price API in production
|
|
const tokenAmount = side === 'BUY'
|
|
? leveragedAmount / currentPrice // If buying SOL, calculate SOL amount
|
|
: leveragedAmount // If selling, amount is already in the token
|
|
|
|
// Step 3: Create trigger orders for stop loss and take profit
|
|
let triggerResults = null
|
|
if (stopLoss || takeProfit) {
|
|
console.log('📋 Creating trigger orders for TP/SL...')
|
|
|
|
triggerResults = await jupiterTriggerService.createTradingOrders({
|
|
tokenSymbol: symbol,
|
|
amount: tokenAmount,
|
|
stopLoss: stopLoss,
|
|
takeProfit: takeProfit,
|
|
slippageBps: 50, // 0.5% slippage for trigger orders
|
|
expiredAt: Math.floor(Date.now() / 1000) + (30 * 24 * 60 * 60) // 30 days expiry
|
|
})
|
|
|
|
if (triggerResults.success) {
|
|
console.log('✅ Trigger orders created:', {
|
|
stopLoss: triggerResults.stopLossOrder,
|
|
takeProfit: triggerResults.takeProfitOrder
|
|
})
|
|
} else {
|
|
console.warn('⚠️ Trigger orders failed:', triggerResults.error)
|
|
}
|
|
}
|
|
|
|
// Step 4: Return comprehensive result
|
|
const result = {
|
|
success: true,
|
|
trade: {
|
|
txId: tradeResult.txId,
|
|
orderId: tradeResult.orderId,
|
|
symbol: symbol.toUpperCase(),
|
|
side: side.toUpperCase(),
|
|
amount: leveragedAmount,
|
|
leverage: leverage,
|
|
originalAmount: amount,
|
|
tokenAmount: tokenAmount,
|
|
entryPrice: currentPrice,
|
|
timestamp: Date.now(),
|
|
status: 'FILLED',
|
|
platform: 'Jupiter DEX (Leveraged Spot)',
|
|
dex: 'JUPITER_DEX_REAL',
|
|
stopLoss: stopLoss,
|
|
takeProfit: takeProfit
|
|
},
|
|
triggerOrders: triggerResults ? {
|
|
stopLossOrderId: triggerResults.stopLossOrder,
|
|
takeProfitOrderId: triggerResults.takeProfitOrder,
|
|
status: triggerResults.success ? 'CREATED' : 'FAILED',
|
|
error: triggerResults.error
|
|
} : null,
|
|
message: `${side.toUpperCase()} $${leveragedAmount} worth of ${symbol} executed successfully`,
|
|
explanation: [
|
|
`🔥 Leveraged Spot Trade: Used ${leverage}x leverage to trade $${leveragedAmount} instead of $${amount}`,
|
|
`💰 Main Trade: ${side === 'BUY' ? 'Bought' : 'Sold'} ~${tokenAmount.toFixed(6)} ${symbol} via Jupiter DEX`,
|
|
stopLoss ? `🛑 Stop Loss: Trigger order created at $${stopLoss}` : null,
|
|
takeProfit ? `🎯 Take Profit: Trigger order created at $${takeProfit}` : null,
|
|
`📈 This gives you ${leverage}x exposure to ${symbol} price movements using spot trading`
|
|
].filter(Boolean)
|
|
}
|
|
|
|
return NextResponse.json(result)
|
|
|
|
} catch (error) {
|
|
console.error('❌ Leveraged spot trade execution error:', error)
|
|
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: 'Internal server error',
|
|
message: 'Failed to execute leveraged spot trade. Please try again.'
|
|
},
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
}
|
|
|
|
export async function GET() {
|
|
return NextResponse.json({
|
|
message: 'Jupiter Leveraged Spot Trading API',
|
|
description: 'Leveraged trading using Jupiter DEX spot swaps + Trigger Orders for TP/SL',
|
|
endpoints: {
|
|
'POST /api/trading/execute-leverage': 'Execute leveraged spot trades with trigger orders',
|
|
},
|
|
features: [
|
|
'Leveraged spot trading (1x-10x)',
|
|
'Direct wallet trading (no deposits needed)',
|
|
'Jupiter Trigger Orders for Stop Loss & Take Profit',
|
|
'Real-time execution via Jupiter DEX',
|
|
'Automatic position monitoring'
|
|
],
|
|
advantages: [
|
|
'✅ No fund deposits required (unlike Drift)',
|
|
'✅ Real leverage effect through increased position size',
|
|
'✅ Professional stop loss & take profit via Jupiter Triggers',
|
|
'✅ Best execution through Jupiter routing',
|
|
'✅ Low fees (0.03% for stables, 0.1% others)'
|
|
],
|
|
note: 'Uses Jupiter DEX for main trades and Jupiter Trigger API for stop loss/take profit orders.'
|
|
})
|
|
}
|