feat: Add automated profit withdrawal system
- UI page: /withdrawals with stats dashboard and config form - Settings API: GET/POST for .env configuration - Stats API: Real-time profit and withdrawal calculations - Execute API: Safe withdrawal with Drift SDK integration - Drift service: withdrawFromDrift() with USDC spot market (index 0) - Safety checks: Min withdrawal amount, min account balance, profit-only - Telegram notifications: Withdrawal alerts with Solscan links - Dashboard navigation: Added Withdrawals card (3-card grid) User goal: 10% of profits automatically withdrawn on schedule Current: Manual trigger ready, scheduled automation pending Files: 5 new (withdrawals page, 3 APIs, Drift service), 2 modified
This commit is contained in:
@@ -17,6 +17,16 @@ interface TelegramNotificationOptions {
|
||||
maxGain?: number
|
||||
}
|
||||
|
||||
interface TelegramWithdrawalOptions {
|
||||
type: 'withdrawal'
|
||||
amount: number
|
||||
signature: string
|
||||
availableProfit: number
|
||||
totalWithdrawn: number
|
||||
}
|
||||
|
||||
type TelegramOptions = TelegramNotificationOptions | TelegramWithdrawalOptions
|
||||
|
||||
/**
|
||||
* Send Telegram notification for position closure
|
||||
*/
|
||||
@@ -107,3 +117,59 @@ function formatHoldTime(seconds: number): string {
|
||||
return `${secs}s`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Telegram notification (supports both position closures and withdrawals)
|
||||
*/
|
||||
export async function sendTelegramNotification(options: TelegramOptions): Promise<void> {
|
||||
if ('type' in options && options.type === 'withdrawal') {
|
||||
return sendWithdrawalNotification(options)
|
||||
}
|
||||
return sendPositionClosedNotification(options as TelegramNotificationOptions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Send withdrawal notification
|
||||
*/
|
||||
async function sendWithdrawalNotification(options: TelegramWithdrawalOptions): Promise<void> {
|
||||
try {
|
||||
const token = process.env.TELEGRAM_BOT_TOKEN
|
||||
const chatId = process.env.TELEGRAM_CHAT_ID
|
||||
|
||||
if (!token || !chatId) {
|
||||
console.log('⚠️ Telegram credentials not configured, skipping notification')
|
||||
return
|
||||
}
|
||||
|
||||
const message = `💸 PROFIT WITHDRAWAL
|
||||
|
||||
💰 Amount: $${options.amount.toFixed(2)} USDC
|
||||
|
||||
📊 Available Profit: $${options.availableProfit.toFixed(2)}
|
||||
📈 Total Withdrawn: $${options.totalWithdrawn.toFixed(2)}
|
||||
|
||||
🔗 Transaction: <a href="https://solscan.io/tx/${options.signature}">${options.signature.substring(0, 8)}...</a>
|
||||
|
||||
✅ Funds sent to your wallet`
|
||||
|
||||
const url = `https://api.telegram.org/bot${token}/sendMessage`
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
chat_id: chatId,
|
||||
text: message,
|
||||
parse_mode: 'HTML'
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
console.error('❌ Telegram notification failed:', errorData)
|
||||
} else {
|
||||
console.log('✅ Telegram withdrawal notification sent')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Error sending Telegram notification:', error)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user