Files
trading_bot_v3/components/SessionStatus_new.tsx
mindesbunister e985a9ec6f 🚀 Fix Drift Protocol integration - Connection now working
 Key fixes:
- Bypass problematic SDK subscription that caused 410 Gone errors
- Use direct account verification without subscription
- Add fallback modes for better reliability
- Switch to Helius RPC endpoint for better rate limits
- Implement proper error handling and retry logic

🔧 Technical changes:
- Enhanced drift-trading.ts with no-subscription approach
- Added Drift API endpoints (/api/drift/login, /balance, /positions)
- Created DriftAccountStatus and DriftTradingPanel components
- Updated Dashboard.tsx to show Drift account status
- Added comprehensive test scripts for debugging

📊 Results:
- Connection Status: Connected 
- Account verification: Working 
- Balance retrieval: Working  (21.94 total collateral)
- Private key authentication: Working 
- User account: 3dG7wayp7b9NBMo92D2qL2sy1curSC4TTmskFpaGDrtA

🌐 RPC improvements:
- Using Helius RPC for better reliability
- Added fallback RPC options in .env
- Eliminated rate limiting issues
2025-07-13 00:20:01 +02:00

203 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import React, { useState, useEffect } from 'react'
interface SessionInfo {
isAuthenticated: boolean
hasSavedCookies: boolean
hasSavedStorage: boolean
cookiesCount: number
currentUrl: string
browserActive: boolean
connectionStatus: 'connected' | 'disconnected' | 'unknown' | 'error'
lastChecked: string
dockerEnv?: boolean
environment?: string
}
export default function SessionStatus() {
const [sessionInfo, setSessionInfo] = useState<SessionInfo | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [refreshing, setRefreshing] = useState(false)
const fetchSessionStatus = async () => {
try {
setError(null)
const response = await fetch('/api/session-status', {
cache: 'no-cache' // Important for Docker environment
})
const data = await response.json()
if (data.success) {
setSessionInfo(data.session)
} else {
setError(data.error || 'Failed to fetch session status')
setSessionInfo(data.session || null)
}
} catch (e) {
setError(e instanceof Error ? e.message : 'Network error')
setSessionInfo(null)
} finally {
setLoading(false)
}
}
const handleSessionAction = async (action: string) => {
try {
setRefreshing(true)
setError(null)
const response = await fetch('/api/session-status', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action }),
cache: 'no-cache' // Important for Docker environment
})
const data = await response.json()
if (data.success) {
// Refresh session status after action
await fetchSessionStatus()
} else {
setError(data.error || `Failed to ${action} session`)
}
} catch (e) {
setError(e instanceof Error ? e.message : `Failed to ${action} session`)
} finally {
setRefreshing(false)
}
}
useEffect(() => {
fetchSessionStatus()
// Auto-refresh more frequently in Docker environment (30s vs 60s)
const refreshInterval = 30000 // Start with 30 seconds for all environments
const interval = setInterval(fetchSessionStatus, refreshInterval)
return () => clearInterval(interval)
}, [])
const getConnectionStatus = () => {
if (!sessionInfo) return { color: 'bg-gray-500', text: 'Unknown', icon: '❓' }
if (sessionInfo.isAuthenticated && sessionInfo.connectionStatus === 'connected') {
return { color: 'bg-green-500', text: 'Connected & Authenticated', icon: '✅' }
} else if (sessionInfo.hasSavedCookies || sessionInfo.hasSavedStorage) {
return { color: 'bg-yellow-500', text: 'Session Available', icon: '🟡' }
} else if (sessionInfo.connectionStatus === 'connected') {
return { color: 'bg-blue-500', text: 'Connected (Not Authenticated)', icon: '🔵' }
} else {
return { color: 'bg-red-500', text: 'Disconnected', icon: '🔴' }
}
}
const status = getConnectionStatus()
return (
<div className="card card-gradient">
<div className="flex items-center justify-between mb-6">
<h2 className="text-lg font-bold text-white flex items-center">
<span className="w-8 h-8 bg-gradient-to-br from-blue-400 to-indigo-600 rounded-lg flex items-center justify-center mr-3">
🌐
</span>
Session Status
</h2>
<button
onClick={fetchSessionStatus}
disabled={loading || refreshing}
className="p-2 text-gray-400 hover:text-gray-300 transition-colors"
title="Refresh Status"
>
<svg className={`w-4 h-4 ${(loading || refreshing) ? 'animate-spin' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
</button>
</div>
{/* Connection Status */}
<div className="mb-6">
<div className="flex items-center justify-between p-4 bg-gray-800/30 rounded-lg border border-gray-700">
<div className="flex items-center space-x-3">
<div className={`w-3 h-3 ${status.color} rounded-full ${sessionInfo?.isAuthenticated ? 'animate-pulse' : ''}`}></div>
<div>
<h3 className="text-sm font-semibold text-white">{status.text}</h3>
<p className="text-xs text-gray-400">
{sessionInfo?.dockerEnv ? 'Docker Environment' : 'Local Environment'}
{sessionInfo?.environment && `${sessionInfo.environment}`}
</p>
</div>
</div>
<span className="text-2xl">{status.icon}</span>
</div>
</div>
{/* Session Details */}
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="p-3 bg-gray-800/20 rounded-lg">
<div className="text-xs text-gray-400">Browser Status</div>
<div className={`text-sm font-medium ${sessionInfo?.browserActive ? 'text-green-400' : 'text-red-400'}`}>
{loading ? 'Checking...' : sessionInfo?.browserActive ? 'Active' : 'Inactive'}
</div>
</div>
<div className="p-3 bg-gray-800/20 rounded-lg">
<div className="text-xs text-gray-400">Cookies</div>
<div className="text-sm font-medium text-white">
{loading ? '...' : sessionInfo?.cookiesCount || 0} stored
</div>
</div>
</div>
{sessionInfo?.currentUrl && (
<div className="p-3 bg-gray-800/20 rounded-lg">
<div className="text-xs text-gray-400 mb-1">Current URL</div>
<div className="text-xs text-gray-300 font-mono break-all">
{sessionInfo.currentUrl}
</div>
</div>
)}
{sessionInfo?.lastChecked && (
<div className="text-xs text-gray-500 text-center">
Last updated: {new Date(sessionInfo.lastChecked).toLocaleString()}
</div>
)}
</div>
{/* Error Display */}
{error && (
<div className="mt-4 p-3 bg-red-500/10 border border-red-500/30 rounded-lg">
<div className="flex items-start space-x-2">
<span className="text-red-400 text-sm"></span>
<div>
<h4 className="text-red-400 font-medium text-sm">Connection Error</h4>
<p className="text-red-300 text-xs mt-1">{error}</p>
</div>
</div>
</div>
)}
{/* Action Buttons */}
<div className="mt-6 grid grid-cols-2 gap-3">
<button
onClick={() => handleSessionAction('reconnect')}
disabled={refreshing}
className="btn-primary py-2 px-4 text-sm"
>
{refreshing ? 'Connecting...' : 'Reconnect'}
</button>
<button
onClick={() => handleSessionAction('clear')}
disabled={refreshing}
className="btn-secondary py-2 px-4 text-sm"
>
Clear Session
</button>
</div>
</div>
)
}