import { NextResponse } from 'next/server'; export async function POST(request) { try { const body = await request.json(); const { symbol, orderType, direction, size, price, triggerPrice, reduceOnly = true } = body; console.log('📝 Placing consolidated order:', { symbol, orderType, direction, size, price, triggerPrice, reduceOnly }); // Import Drift SDK const { DriftClient, initialize, MarketType, PositionDirection, OrderType, OrderTriggerCondition, Wallet, BN } = await import('@drift-labs/sdk'); const { Connection, Keypair } = await import('@solana/web3.js'); // Setup connection and wallet const rpcEndpoint = process.env.SOLANA_RPC_URL || 'https://mainnet.helius-rpc.com/?api-key=5e236449-f936-4af7-ae38-f15e2f1a3757'; const connection = new Connection(rpcEndpoint, 'confirmed'); if (!process.env.SOLANA_PRIVATE_KEY) { return NextResponse.json({ success: false, error: 'SOLANA_PRIVATE_KEY not configured' }, { status: 400 }); } const privateKeyArray = JSON.parse(process.env.SOLANA_PRIVATE_KEY); const keypair = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); const wallet = new Wallet(keypair); // Initialize Drift client const env = 'mainnet-beta'; const sdkConfig = initialize({ env }); const driftClient = new DriftClient({ connection, wallet, programID: sdkConfig.DRIFT_PROGRAM_ID, accountSubscription: { type: 'polling', accountLoader: { commitment: 'confirmed' } } }); await driftClient.subscribe(); // Map symbol to market index const marketIndex = symbol === 'SOL-PERP' ? 0 : 1; // SOL-PERP is market 0 // Convert direction to Drift enum const driftDirection = direction.toUpperCase() === 'LONG' || direction.toUpperCase() === 'BUY' ? PositionDirection.LONG : PositionDirection.SHORT; // Convert size to base asset amount (multiply by 1e9 for SOL) const baseAssetAmount = new BN(Math.floor(parseFloat(size) * 1e9)); // Determine trigger condition based on current price and trigger price const currentPrice = parseFloat(price); const trigger = parseFloat(triggerPrice); const triggerCondition = driftDirection === PositionDirection.SHORT ? (trigger > currentPrice ? OrderTriggerCondition.ABOVE : OrderTriggerCondition.BELOW) : (trigger > currentPrice ? OrderTriggerCondition.ABOVE : OrderTriggerCondition.BELOW); // Create order parameters const orderParams = { orderType: OrderType.TRIGGER_LIMIT, marketType: MarketType.PERP, direction: driftDirection, baseAssetAmount: baseAssetAmount, price: new BN(Math.floor(currentPrice * 1e6)), // Price in 6 decimal format marketIndex: marketIndex, triggerPrice: new BN(Math.floor(trigger * 1e6)), triggerCondition: triggerCondition, reduceOnly: reduceOnly, }; console.log('🎯 Placing Drift order with params:', { orderType: 'TRIGGER_LIMIT', direction: driftDirection === PositionDirection.LONG ? 'LONG' : 'SHORT', size: size, price: currentPrice, triggerPrice: trigger, triggerCondition: triggerCondition === OrderTriggerCondition.ABOVE ? 'ABOVE' : 'BELOW' }); // Place the order const txSig = await driftClient.placePerpOrder(orderParams); await driftClient.unsubscribe(); console.log('✅ Consolidated order placed:', txSig); return NextResponse.json({ success: true, message: 'Order placed successfully', orderId: txSig, txSignature: txSig, orderParams: { symbol, orderType, direction, size, price, triggerPrice, reduceOnly } }); } catch (error) { console.error('❌ Place order error:', error); return NextResponse.json({ success: false, error: 'Failed to place order', details: error.message }, { status: 500 }); } }