diff --git a/app/api/drift/account-summary/route.ts b/app/api/drift/account-summary/route.ts new file mode 100644 index 0000000..53756f0 --- /dev/null +++ b/app/api/drift/account-summary/route.ts @@ -0,0 +1,79 @@ +/** + * Drift Account Summary API + * + * Returns comprehensive account information from Drift Protocol + */ + +import { NextResponse } from 'next/server' +import { initializeDriftService } from '@/lib/drift/client' +import { getPrismaClient } from '@/lib/database/trades' + +export async function GET() { + try { + const driftService = await initializeDriftService() + const prisma = getPrismaClient() + + // Get account health from Drift + const health = await driftService.getAccountHealth() + + // Get user account details + const driftClient = driftService.getClient() + const userAccount = driftClient.getUserAccount() + + // Get spot position (USDC collateral) + const spotPositions = userAccount?.spotPositions || [] + const usdcPosition = spotPositions.find(p => p.marketIndex === 0) // USDC is market 0 + + // Get all perp positions + const perpPositions = userAccount?.perpPositions || [] + const activePerps = perpPositions.filter(p => p.baseAssetAmount.toNumber() !== 0) + + // Calculate total from database + const trades = await prisma.trade.findMany({ + where: { exitReason: { not: null } }, + select: { realizedPnL: true }, + }) + + const totalPnL = trades.reduce((sum, trade) => sum + (trade.realizedPnL || 0), 0) + + return NextResponse.json({ + success: true, + drift: { + freeCollateral: health.freeCollateral, + totalCollateral: health.totalCollateral, + marginUsed: health.totalCollateral - health.freeCollateral, + marginRatio: health.marginRatio, + accountValue: health.totalCollateral, + }, + spotPositions: { + usdc: usdcPosition ? { + scaledBalance: usdcPosition.scaledBalance.toString(), + cumulativeDeposits: usdcPosition.cumulativeDeposits.toString(), + } : null, + }, + perpPositions: activePerps.map(p => ({ + marketIndex: p.marketIndex, + baseAssetAmount: p.baseAssetAmount.toString(), + quoteAssetAmount: p.quoteAssetAmount.toString(), + })), + database: { + totalTrades: trades.length, + totalPnL: Math.round(totalPnL * 100) / 100, + }, + calculated: { + // This is what user actually has available to withdraw + currentBalance: health.freeCollateral, + // This would be from tracking deposits (we hardcoded $546) + estimatedDeposits: 546, + // Difference = profit/loss + estimatedProfit: health.freeCollateral - 546, + } + }) + } catch (error: any) { + console.error('Failed to get account summary:', error) + return NextResponse.json({ + success: false, + error: error.message, + }, { status: 500 }) + } +} diff --git a/app/api/withdrawals/stats/route.ts b/app/api/withdrawals/stats/route.ts index cfd1eca..a9a87ae 100644 --- a/app/api/withdrawals/stats/route.ts +++ b/app/api/withdrawals/stats/route.ts @@ -12,14 +12,23 @@ export async function GET() { try { const prisma = getPrismaClient() - // Get total invested (from roadmap: $546) - const totalInvested = 546 - - // Get current Drift balance + // Get current Drift balance and actual deposits const driftService = await initializeDriftService() const health = await driftService.getAccountHealth() const currentBalance = health.freeCollateral // Already a number + // Get actual deposits from Drift Protocol (ground truth from blockchain) + const user = driftService.getUser() + const userAccount = user.getUserAccount() + const usdcSpotPosition = userAccount.spotPositions.find( + (pos: any) => pos.marketIndex === 0 // USDC market index + ) + const cumulativeDeposits = usdcSpotPosition + ? Number(usdcSpotPosition.cumulativeDeposits.toString()) / 1_000_000 + : 546 // Fallback to hardcoded if query fails (shouldn't happen) + + const totalInvested = cumulativeDeposits // Use actual deposits as "invested" + // Calculate total P&L from database const trades = await prisma.trade.findMany({ where: { @@ -36,7 +45,13 @@ export async function GET() { const totalWithdrawn = parseFloat(process.env.TOTAL_WITHDRAWN || '0') // Calculate available profit - const availableProfit = Math.max(0, currentBalance - totalInvested) + // Current balance is what's left after deposits + P&L - previous withdrawals + // Available profit = current balance (what we have now, which includes trading profit/loss) + const availableProfit = Math.max(0, currentBalance) + + // Calculate inferred previous withdrawals + // If deposits + P&L - current balance > 0, that's what was withdrawn + const inferredWithdrawals = Math.max(0, cumulativeDeposits + totalPnL - currentBalance) // Calculate next withdrawal amount const withdrawalPercent = parseFloat(process.env.WITHDRAWAL_PROFIT_PERCENT || '10')