Bug: Second withdrawal showed $5.92 cumulative instead of $12.50 Root cause: process.env caches values at container startup, doesn't update when .env file changes. Fix: Parse TOTAL_WITHDRAWN directly from .env file content instead of using cached process.env value. Added: Debug logging showing calculation Manual fix: Updated .env to $12.50 (sum of $6.58 + $5.92) Result: Withdrawal stats now correctly show cumulative total.
106 lines
3.6 KiB
TypeScript
106 lines
3.6 KiB
TypeScript
/**
|
|
* Withdrawal Execution API
|
|
*
|
|
* POST: Execute withdrawal of trading profits
|
|
*/
|
|
|
|
import { NextRequest, NextResponse } from 'next/server'
|
|
import { calculateWithdrawalAmount, withdrawFromDrift } from '@/lib/drift/withdraw'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import { sendTelegramNotification } from '@/lib/notifications/telegram'
|
|
|
|
const ENV_PATH = path.join(process.cwd(), '.env')
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
console.log('🎯 Manual withdrawal triggered')
|
|
|
|
// Calculate withdrawal amount with safety checks
|
|
const calculation = await calculateWithdrawalAmount()
|
|
|
|
if (!calculation.safeToWithdraw) {
|
|
console.log(`⚠️ Withdrawal blocked: ${calculation.reason}`)
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: calculation.reason,
|
|
availableProfit: calculation.availableProfit,
|
|
withdrawalAmount: calculation.withdrawalAmount,
|
|
})
|
|
}
|
|
|
|
console.log(`✅ Withdrawal approved: $${calculation.withdrawalAmount.toFixed(2)}`)
|
|
|
|
// Execute withdrawal
|
|
const result = await withdrawFromDrift(calculation.withdrawalAmount)
|
|
|
|
if (!result.success) {
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: result.error,
|
|
}, { status: 500 })
|
|
}
|
|
|
|
// Update LAST_WITHDRAWAL_TIME and TOTAL_WITHDRAWN in .env
|
|
// IMPORTANT: Read from file, not process.env (which is cached at startup)
|
|
let envContent = fs.readFileSync(ENV_PATH, 'utf-8')
|
|
|
|
// Parse current total from file, not from cached process.env
|
|
const totalMatch = envContent.match(/^TOTAL_WITHDRAWN=(.*)$/m)
|
|
const currentTotal = totalMatch ? parseFloat(totalMatch[1]) : 0
|
|
const newTotal = currentTotal + calculation.withdrawalAmount
|
|
const now = new Date().toISOString()
|
|
|
|
console.log(`💾 Updating withdrawal tracking: $${currentTotal.toFixed(2)} + $${calculation.withdrawalAmount.toFixed(2)} = $${newTotal.toFixed(2)}`)
|
|
|
|
// Update LAST_WITHDRAWAL_TIME
|
|
const timeRegex = /^LAST_WITHDRAWAL_TIME=.*$/m
|
|
if (timeRegex.test(envContent)) {
|
|
envContent = envContent.replace(timeRegex, `LAST_WITHDRAWAL_TIME=${now}`)
|
|
} else {
|
|
envContent += `\nLAST_WITHDRAWAL_TIME=${now}`
|
|
}
|
|
|
|
// Update TOTAL_WITHDRAWN
|
|
const totalRegex = /^TOTAL_WITHDRAWN=.*$/m
|
|
if (totalRegex.test(envContent)) {
|
|
envContent = envContent.replace(totalRegex, `TOTAL_WITHDRAWN=${newTotal}`)
|
|
} else {
|
|
envContent += `\nTOTAL_WITHDRAWN=${newTotal}`
|
|
}
|
|
|
|
fs.writeFileSync(ENV_PATH, envContent)
|
|
|
|
// Send Telegram notification
|
|
try {
|
|
await sendTelegramNotification({
|
|
type: 'withdrawal',
|
|
amount: calculation.withdrawalAmount,
|
|
signature: result.signature!,
|
|
availableProfit: calculation.availableProfit,
|
|
totalWithdrawn: newTotal,
|
|
})
|
|
} catch (telegramError) {
|
|
console.error('Failed to send Telegram notification:', telegramError)
|
|
// Don't fail the withdrawal if notification fails
|
|
}
|
|
|
|
console.log(`✅ Withdrawal complete! $${calculation.withdrawalAmount.toFixed(2)} → wallet`)
|
|
console.log(`📊 Total withdrawn: $${newTotal.toFixed(2)}`)
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
amount: calculation.withdrawalAmount,
|
|
signature: result.signature,
|
|
totalWithdrawn: newTotal,
|
|
timestamp: now,
|
|
})
|
|
} catch (error: any) {
|
|
console.error('❌ Withdrawal execution failed:', error)
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: error.message || 'Withdrawal execution failed',
|
|
}, { status: 500 })
|
|
}
|
|
}
|