diff --git a/app/api/drift/transaction-history/route.ts b/app/api/drift/transaction-history/route.ts
new file mode 100644
index 0000000..596530e
--- /dev/null
+++ b/app/api/drift/transaction-history/route.ts
@@ -0,0 +1,98 @@
+import { NextResponse } from 'next/server'
+import { Connection, PublicKey } from '@solana/web3.js'
+import { Wallet } from '@coral-xyz/anchor'
+import { Keypair } from '@solana/web3.js'
+
+export async function GET(request: Request) {
+ try {
+ const { searchParams } = new URL(request.url)
+ const limit = parseInt(searchParams.get('limit') || '50')
+
+ console.log('📊 API: Getting Solana transaction history...')
+
+ // Get private key from environment
+ const privateKeyString = process.env.PRIVATE_KEY
+ if (!privateKeyString) {
+ throw new Error('PRIVATE_KEY not found in environment variables')
+ }
+
+ // Convert private key to Keypair
+ const privateKeyBytes = JSON.parse(privateKeyString)
+ const keypair = Keypair.fromSecretKey(new Uint8Array(privateKeyBytes))
+ const wallet = new Wallet(keypair)
+
+ // Connect to Helius RPC
+ const connection = new Connection(process.env.HELIUS_RPC_ENDPOINT || 'https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY')
+
+ // Get transaction signatures for this wallet
+ const signatures = await connection.getSignaturesForAddress(
+ wallet.publicKey,
+ { limit: limit * 2 } // Get more signatures to filter for Drift transactions
+ )
+
+ console.log(`🔍 Found ${signatures.length} total signatures`)
+
+ // Get transaction details for each signature
+ const transactions = []
+ const driftProgramId = 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH' // Drift program ID
+
+ for (const sig of signatures.slice(0, limit)) {
+ try {
+ const tx = await connection.getTransaction(sig.signature, {
+ maxSupportedTransactionVersion: 0
+ })
+
+ if (!tx) continue
+
+ // Check if this transaction involves the Drift program
+ const isDriftTransaction = tx.transaction.message.staticAccountKeys?.some(
+ key => key.toString() === driftProgramId
+ ) || tx.transaction.message.compiledInstructions?.some(
+ instruction => {
+ const programKey = tx.transaction.message.staticAccountKeys?.[instruction.programIdIndex]
+ return programKey?.toString() === driftProgramId
+ }
+ )
+
+ if (isDriftTransaction) {
+ // Parse the transaction to extract trading information
+ const blockTime = tx.blockTime ? new Date(tx.blockTime * 1000) : new Date()
+
+ transactions.push({
+ id: sig.signature,
+ signature: sig.signature,
+ blockTime: blockTime.toISOString(),
+ slot: tx.slot,
+ status: sig.err ? 'FAILED' : 'SUCCESS',
+ fee: tx.meta?.fee || 0,
+ // Try to extract more details from logs
+ logs: tx.meta?.logMessages?.slice(0, 5) || [],
+ accounts: tx.transaction.message.staticAccountKeys?.slice(0, 10).map(k => k.toString()) || []
+ })
+ }
+ } catch (txError) {
+ console.log(`⚠️ Failed to get transaction ${sig.signature}:`, txError)
+ }
+ }
+
+ console.log(`📊 Found ${transactions.length} Drift transactions`)
+
+ return NextResponse.json({
+ success: true,
+ transactions,
+ count: transactions.length,
+ totalSignatures: signatures.length
+ })
+
+ } catch (error: any) {
+ console.error('❌ API: Error getting transaction history:', error)
+ return NextResponse.json(
+ {
+ success: false,
+ error: error.message,
+ transactions: []
+ },
+ { status: 500 }
+ )
+ }
+}
diff --git a/components/AIAnalysisPanel_old.tsx b/components/AIAnalysisPanel_old.tsx
index 1eb9697..05c870a 100644
--- a/components/AIAnalysisPanel_old.tsx
+++ b/components/AIAnalysisPanel_old.tsx
@@ -387,175 +387,4 @@ export default function AIAnalysisPanel() {
)}
)
-}
- {error && (
-
-
- {error.includes('frame was detached') ? (
- <>
- TradingView Error: Chart could not be loaded. Please check your symbol and layout, or try again.
- Technical: {error}
- >
- ) : error.includes('layout not found') ? (
- <>
- Layout Error: TradingView layout not found. Please select a valid layout.
- Technical: {error}
- >
- ) : error.includes('Private layout access denied') ? (
- <>
- Access Error: The selected layout is private or requires authentication. Try a different layout or check your TradingView login.
- Technical: {error}
- >
- ) : (
- <>
- Analysis Error: {error}
- >
- )}
-
-
- )}
- {loading && (
-
-
-
-
-
-
-
Analyzing {symbol} chart...
-
-
- )}
- {result && (
-
-
Analysis Results
- {result.layoutsAnalyzed && (
-
- Layouts analyzed:
- {result.layoutsAnalyzed.join(', ')}
-
- )}
-
-
-
Summary:
-
{safeRender(result.summary)}
-
-
-
-
Sentiment:
-
{safeRender(result.marketSentiment)}
-
-
-
Recommendation:
-
{safeRender(result.recommendation)}
-
({safeRender(result.confidence)}% confidence)
-
-
- {result.keyLevels && (
-
-
-
Support Levels:
-
{result.keyLevels.support?.join(', ') || 'None identified'}
-
-
-
Resistance Levels:
-
{result.keyLevels.resistance?.join(', ') || 'None identified'}
-
-
- )}
-
- {/* Enhanced Trading Analysis */}
- {result.entry && (
-
-
Entry:
-
${safeRender(result.entry.price || result.entry)}
- {result.entry.buffer &&
{safeRender(result.entry.buffer)}
}
- {result.entry.rationale &&
{safeRender(result.entry.rationale)}
}
-
- )}
-
- {result.stopLoss && (
-
-
Stop Loss:
-
${safeRender(result.stopLoss.price || result.stopLoss)}
- {result.stopLoss.rationale &&
{safeRender(result.stopLoss.rationale)}
}
-
- )}
-
- {result.takeProfits && (
-
-
Take Profits:
- {typeof result.takeProfits === 'object' ? (
- <>
- {result.takeProfits.tp1 && (
-
-
TP1: ${safeRender(result.takeProfits.tp1.price || result.takeProfits.tp1)}
- {result.takeProfits.tp1.description &&
{safeRender(result.takeProfits.tp1.description)}
}
-
- )}
- {result.takeProfits.tp2 && (
-
-
TP2: ${safeRender(result.takeProfits.tp2.price || result.takeProfits.tp2)}
- {result.takeProfits.tp2.description &&
{safeRender(result.takeProfits.tp2.description)}
}
-
- )}
- >
- ) : (
-
{safeRender(result.takeProfits)}
- )}
-
- )}
-
- {result.riskToReward && (
-
-
Risk to Reward:
-
{safeRender(result.riskToReward)}
-
- )}
-
- {result.confirmationTrigger && (
-
-
Confirmation Trigger:
-
{safeRender(result.confirmationTrigger)}
-
- )}
-
- {result.indicatorAnalysis && (
-
-
Indicator Analysis:
- {typeof result.indicatorAnalysis === 'object' ? (
-
- {result.indicatorAnalysis.rsi && (
-
- RSI:
- {safeRender(result.indicatorAnalysis.rsi)}
-
- )}
- {result.indicatorAnalysis.vwap && (
-
- VWAP:
- {safeRender(result.indicatorAnalysis.vwap)}
-
- )}
- {result.indicatorAnalysis.obv && (
-
- OBV:
- {safeRender(result.indicatorAnalysis.obv)}
-
- )}
-
- ) : (
-
{safeRender(result.indicatorAnalysis)}
- )}
-
- )}
-
-
-
Reasoning:
-
{safeRender(result.reasoning)}
-
-
-
- )}
-
- )
}
diff --git a/components/SessionStatus_old.tsx b/components/SessionStatus_old.tsx
index c13d68d..a8c0c6f 100644
--- a/components/SessionStatus_old.tsx
+++ b/components/SessionStatus_old.tsx
@@ -199,120 +199,4 @@ export default function SessionStatus() {
)
-}
- } else if (sessionInfo.hasSavedCookies || sessionInfo.hasSavedStorage) {
- return `Session Available${dockerSuffix}`
- } else {
- return `Not Logged In${dockerSuffix}`
- }
- }
-
- const getDetailedStatus = () => {
- if (!sessionInfo) return []
-
- return [
- { label: 'Authenticated', value: sessionInfo.isAuthenticated ? '✅' : '❌' },
- { label: 'Connection', value: sessionInfo.connectionStatus === 'connected' ? '✅' :
- sessionInfo.connectionStatus === 'disconnected' ? '🔌' :
- sessionInfo.connectionStatus === 'error' ? '❌' : '❓' },
- { label: 'Browser Active', value: sessionInfo.browserActive ? '✅' : '❌' },
- { label: 'Saved Cookies', value: sessionInfo.hasSavedCookies ? `✅ (${sessionInfo.cookiesCount})` : '❌' },
- { label: 'Saved Storage', value: sessionInfo.hasSavedStorage ? '✅' : '❌' },
- { label: 'Environment', value: sessionInfo.dockerEnv ? '🐳 Docker' : '💻 Local' },
- ]
- }
-
- return (
-
-
-
TradingView Session
- fetchSessionStatus()}
- disabled={loading || refreshing}
- className="px-3 py-1 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50"
- >
- {loading || refreshing ? '⟳' : '🔄'}
-
-
-
- {/* Status Indicator */}
-
-
- {/* Detailed Status */}
- {sessionInfo && (
-
- {getDetailedStatus().map((item, index) => (
-
- {item.label}:
- {item.value}
-
- ))}
-
- Last Checked:
-
- {new Date(sessionInfo.lastChecked).toLocaleTimeString()}
-
-
-
- )}
-
- {/* Error Display */}
- {error && (
-
- )}
-
- {/* Action Buttons */}
-
- handleSessionAction('refresh')}
- disabled={refreshing}
- className="px-3 py-1 bg-green-600 text-white rounded text-sm hover:bg-green-700 disabled:opacity-50"
- >
- Refresh Session
-
- handleSessionAction('test')}
- disabled={refreshing}
- className="px-3 py-1 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50"
- >
- Test Session
-
- handleSessionAction('clear')}
- disabled={refreshing}
- className="px-3 py-1 bg-red-600 text-white rounded text-sm hover:bg-red-700 disabled:opacity-50"
- >
- Clear Session
-
-
-
- {/* Usage Instructions */}
- {sessionInfo && !sessionInfo.isAuthenticated && (
-
-
- 💡 To establish session: Run the analysis or screenshot capture once to trigger manual login,
- then future requests will use the saved session and avoid captchas.
- {sessionInfo.dockerEnv && (
- <> 🐳 Docker: Session data is persisted in the container volume for reuse across restarts.>
- )}
-
-
- )}
-
- {/* Docker Environment Info */}
- {sessionInfo?.dockerEnv && (
-
-
- 🐳 Docker Environment: Running in containerized mode. Session persistence is enabled
- via volume mount at /.tradingview-session
-
-
- )}
-
- )
}
diff --git a/components/TradingHistory_old.tsx b/components/TradingHistory_old.tsx
index 8d9621c..2d38f45 100644
--- a/components/TradingHistory_old.tsx
+++ b/components/TradingHistory_old.tsx
@@ -175,14 +175,4 @@ export default function TradingHistory() {
)}
)
-}
- {trade.status}
- {trade.executedAt}
-
- ))}
-
-
- )}
-
- )
}
diff --git a/lib/drift-trading.ts b/lib/drift-trading.ts
index b298478..d137649 100644
--- a/lib/drift-trading.ts
+++ b/lib/drift-trading.ts
@@ -28,8 +28,20 @@ export interface TradeParams {
stopLossType?: 'PRICE' | 'PERCENTAGE'
takeProfitType?: 'PRICE' | 'PERCENTAGE'
}
-
-export interface TradeResult {
+ if (localTrades.length > 0) {
+ console.log(`📊 Found ${localTrades.length} trades in local database`)
+ return localTrades.map((trade: any) => ({
+ id: trade.id.toString(),
+ symbol: trade.symbol,
+ side: trade.side as 'BUY' | 'SELL',
+ amount: trade.amount,
+ price: trade.price,
+ status: trade.status as 'FILLED' | 'PENDING' | 'CANCELLED',
+ executedAt: trade.executedAt ? trade.executedAt.toISOString() : trade.createdAt.toISOString(),
+ pnl: trade.profit || 0,
+ txId: trade.driftTxId || trade.id
+ }))
+ }ace TradeResult {
success: boolean
txId?: string
error?: string
@@ -431,11 +443,51 @@ export class DriftTradingService {
}
}
- return {
+ const result = {
success: true,
txId: txSig,
conditionalOrders: conditionalOrders.length > 0 ? conditionalOrders : undefined
}
+
+ // Store the trade in local database for history tracking
+ try {
+ const { default: prisma } = await import('./prisma')
+
+ // Get current market price (simplified - using a default for now)
+ let currentPrice = 160; // Default SOL price
+ try {
+ // Try to get actual market price from the market
+ const perpMarket = this.driftClient.getPerpMarketAccount(marketIndex)
+ if (perpMarket && perpMarket.amm) {
+ // Use oracle price or mark price if available
+ const oraclePrice = perpMarket.amm.historicalOracleData?.lastOraclePrice ||
+ perpMarket.amm.lastMarkPriceTwap ||
+ new BN(160 * PRICE_PRECISION.toNumber())
+ currentPrice = convertToNumber(oraclePrice, PRICE_PRECISION)
+ }
+ } catch (priceError) {
+ console.log('⚠️ Could not get current market price, using default')
+ }
+
+ await prisma.trade.create({
+ data: {
+ userId: 'default-user', // TODO: Implement proper user management
+ symbol: params.symbol,
+ side: params.side,
+ amount: params.amount,
+ price: currentPrice,
+ status: 'FILLED',
+ executedAt: new Date(),
+ driftTxId: txSig
+ }
+ })
+ console.log(`💾 Trade saved to database: ${params.side} ${params.amount} ${params.symbol} at $${currentPrice}`)
+ } catch (dbError) {
+ console.log('⚠️ Failed to save trade to database:', (dbError as Error).message)
+ // Don't fail the trade if database save fails
+ }
+
+ return result
} catch (e: any) {
return { success: false, error: e.message }
} finally {
@@ -576,116 +628,122 @@ export class DriftTradingService {
async getTradingHistory(limit: number = 50): Promise {
try {
- console.log('📊 Fetching trading history...')
+ console.log('📊 Fetching trading history from Drift...')
- // Try to get order records from Drift SDK if available
- if (this.driftClient && this.isInitialized) {
- try {
- console.log('🔍 Attempting to get order records from Drift SDK...')
- await this.driftClient.subscribe()
-
- const user = this.driftClient.getUser()
- const trades: TradeHistory[] = []
-
- // Get order history - try different approaches
- try {
- // Method 1: Try to get order history directly
- if ('getOrderHistory' in user) {
- const orderHistory = (user as any).getOrderHistory()
- console.log('📋 Found order history method, processing orders...')
-
- // Process order history into our format
- for (const order of orderHistory.slice(0, limit)) {
- trades.push({
- id: order.orderId?.toString() || Date.now().toString(),
- symbol: this.getSymbolFromMarketIndex(order.marketIndex || 0),
- side: order.direction === 0 ? 'BUY' : 'SELL', // Assuming 0 = LONG/BUY
- amount: convertToNumber(order.baseAssetAmount || new BN(0), BASE_PRECISION),
- price: convertToNumber(order.price || new BN(0), PRICE_PRECISION),
- status: order.status === 'FILLED' ? 'FILLED' : 'PENDING',
- executedAt: new Date(order.timestamp || Date.now()).toISOString(),
- txId: order.txSig
- })
- }
- }
-
- // Method 2: Try to get recent transactions/fills
- if (trades.length === 0 && 'getRecentFills' in user) {
- console.log('📋 Trying recent fills method...')
- const recentFills = (user as any).getRecentFills(limit)
-
- for (const fill of recentFills) {
- trades.push({
- id: fill.fillId?.toString() || Date.now().toString(),
- symbol: this.getSymbolFromMarketIndex(fill.marketIndex || 0),
- side: fill.direction === 0 ? 'BUY' : 'SELL',
- amount: convertToNumber(fill.baseAssetAmount || new BN(0), BASE_PRECISION),
- price: convertToNumber(fill.fillPrice || new BN(0), PRICE_PRECISION),
- status: 'FILLED',
- executedAt: new Date(fill.timestamp || Date.now()).toISOString(),
- txId: fill.txSig
- })
- }
- }
-
- console.log(`📊 Found ${trades.length} trades from Drift SDK`)
-
- } catch (sdkError: any) {
- console.log('⚠️ SDK order history methods failed:', sdkError.message)
- } finally {
- await this.driftClient.unsubscribe()
- }
-
- if (trades.length > 0) {
- return trades.sort((a, b) => new Date(b.executedAt).getTime() - new Date(a.executedAt).getTime())
- }
-
- } catch (sdkError: any) {
- console.log('⚠️ SDK trading history failed, using fallback:', sdkError.message)
- }
+ if (!this.driftClient || !this.isInitialized) {
+ console.log('⚠️ Drift client not initialized, trying local database...')
+ return await this.getLocalTradingHistory(limit)
}
-
- // Fallback: Check if we have any trades in local database (Prisma)
+
try {
- console.log('📊 Checking local trade database...')
+ // Subscribe to get access to user data
+ await this.driftClient.subscribe()
+ const user = this.driftClient.getUser()
- // Import Prisma here to avoid issues if it's not available
- try {
- const { default: prisma } = await import('./prisma')
- const localTrades = await prisma.trade.findMany({
- orderBy: { executedAt: 'desc' },
- take: limit
- })
-
- if (localTrades.length > 0) {
- console.log(`📊 Found ${localTrades.length} trades in local database`)
- return localTrades.map((trade: any) => ({
- id: trade.id.toString(),
- symbol: trade.symbol,
- side: trade.side as 'BUY' | 'SELL',
- amount: trade.amount,
- price: trade.price,
- status: trade.status as 'FILLED' | 'PENDING' | 'CANCELLED',
- executedAt: trade.executedAt.toISOString(),
- pnl: trade.pnl,
- txId: trade.txId
- }))
+ console.log('📊 Getting user order records from Drift SDK...')
+
+ console.log('📊 Getting user account data from Drift SDK...')
+
+ // Get user account which contains order and trade history
+ const userAccount = user.getUserAccount()
+ console.log(`📊 User account found with ${userAccount.orders?.length || 0} orders`)
+
+ // Convert orders to trade history
+ const trades: TradeHistory[] = []
+
+ if (userAccount.orders) {
+ for (const order of userAccount.orders.slice(0, limit)) {
+ try {
+ // Only include filled orders (status 2 = filled)
+ if (order.status === 2) {
+ const marketIndex = order.marketIndex
+ const symbol = this.getSymbolFromMarketIndex(marketIndex)
+ const side = order.direction === 0 ? 'BUY' : 'SELL' // 0 = PositionDirection.LONG
+ const baseAmount = order.baseAssetAmountFilled || order.baseAssetAmount
+ const quoteAmount = order.quoteAssetAmountFilled || order.quoteAssetAmount
+
+ // Calculate executed price from filled amounts
+ const amount = Number(baseAmount.toString()) / 1e9 // Convert from base precision
+ const totalValue = Number(quoteAmount.toString()) / 1e6 // Convert from quote precision
+ const price = amount > 0 ? totalValue / amount : 0
+
+ const trade: TradeHistory = {
+ id: order.orderId?.toString() || `order_${Date.now()}_${trades.length}`,
+ symbol,
+ side,
+ amount,
+ price,
+ status: 'FILLED',
+ executedAt: new Date().toISOString(), // Use current time as fallback
+ txId: order.orderId?.toString() || '',
+ pnl: 0 // PnL calculation would require more complex logic
+ }
+
+ trades.push(trade)
+ console.log(`✅ Processed trade: ${symbol} ${side} ${amount.toFixed(4)} @ $${price.toFixed(2)}`)
+ }
+ } catch (orderError) {
+ console.warn('⚠️ Error processing order:', orderError)
+ continue
+ }
}
- } catch (prismaError) {
- console.log('⚠️ Local database not available:', (prismaError as Error).message)
}
- // Return empty array instead of demo data
- console.log('📊 No trading history found - returning empty array')
- return []
+ // Sort by execution time (newest first)
+ trades.sort((a, b) => new Date(b.executedAt).getTime() - new Date(a.executedAt).getTime())
- } catch (dbError: any) {
- console.log('⚠️ Database query failed:', dbError.message)
- return []
+ console.log(`✅ Successfully fetched ${trades.length} trades from Drift`)
+ return trades
+
+ } catch (sdkError: any) {
+ console.error('❌ Error fetching from Drift SDK:', sdkError.message)
+ return await this.getLocalTradingHistory(limit)
+ } finally {
+ if (this.driftClient) {
+ try {
+ await this.driftClient.unsubscribe()
+ } catch (e) {
+ // Ignore unsubscribe errors
+ }
+ }
}
} catch (error: any) {
console.error('❌ Error getting trading history:', error)
+ return await this.getLocalTradingHistory(limit)
+ }
+ }
+
+ private async getLocalTradingHistory(limit: number): Promise {
+ try {
+ console.log('📊 Checking local trade database...')
+
+ const { default: prisma } = await import('./prisma')
+ const localTrades = await prisma.trade.findMany({
+ orderBy: { executedAt: 'desc' },
+ take: limit
+ })
+
+ if (localTrades.length > 0) {
+ console.log(`📊 Found ${localTrades.length} trades in local database`)
+ return localTrades.map((trade: any) => ({
+ id: trade.id.toString(),
+ symbol: trade.symbol,
+ side: trade.side as 'BUY' | 'SELL',
+ amount: trade.amount,
+ price: trade.price,
+ status: trade.status as 'FILLED' | 'PENDING' | 'CANCELLED',
+ executedAt: trade.executedAt.toISOString(),
+ pnl: trade.pnl || 0,
+ txId: trade.driftTxId || trade.txId || ''
+ }))
+ }
+
+ console.log('📊 No local trades found')
+ return []
+
+ } catch (prismaError) {
+ console.log('⚠️ Local database not available:', (prismaError as Error).message)
return []
}
}
diff --git a/lib/tradingview-automation.ts b/lib/tradingview-automation.ts
index 05a6cb2..9b4b020 100644
--- a/lib/tradingview-automation.ts
+++ b/lib/tradingview-automation.ts
@@ -144,7 +144,7 @@ export class TradingViewAutomation {
console.error('ERROR: Failed to launch browser:', error)
// Cleanup any partial state
await this.forceCleanup()
- throw new Error(`Failed to launch browser: ${error) + ")"
+ throw new Error('Failed to launch browser: ' + error)
}
if (!this.browser) {
@@ -402,7 +402,7 @@ export class TradingViewAutomation {
for (const selector of anonymousSelectors) {
try {
if (await this.page.locator(selector).isVisible({ timeout: 1500 })) {
- console.log("ERROR: Found anonymous indicator: " + selector} - not logged in`)
+ console.log(`ERROR: Found anonymous indicator: ${selector} - not logged in`)
foundAnonymousElement = true
break
}
@@ -450,7 +450,7 @@ export class TradingViewAutomation {
}
}
- console.log("DATA: Total cookies: ${cookies.length}, Auth cookies found: " + hasAuthCookies) + ")"
+ console.log('DATA: Total cookies: ' + cookies.length + ', Auth cookies found: ' + hasAuthCookies)
}
// Strategy 5: Try to detect personal elements by checking page content
@@ -628,7 +628,7 @@ export class TradingViewAutomation {
}
} catch (e) {
- console.log("ERROR: Failed to load " + url}:`, e)
+ console.log(`ERROR: Failed to load ${url}:`, e)
continue
}
}
@@ -686,7 +686,7 @@ export class TradingViewAutomation {
// Get all buttons and check their text content
const buttons = await this.page.locator('button').all()
- console.log("CHECKING: Found " + buttons.length} buttons to check`)
+ console.log(`CHECKING: Found ${buttons.length} buttons to check`)
for (let i = 0; i < buttons.length; i++) {
try {
@@ -695,7 +695,7 @@ export class TradingViewAutomation {
const text = await button.textContent() || ''
const trimmedText = text.trim().toLowerCase()
- console.log(`INFO:
+ console.log(`INFO: Button ${i + 1}: "${trimmedText}"`)
if (trimmedText.includes('email') ||
trimmedText.includes('continue with email') ||
@@ -798,7 +798,7 @@ export class TradingViewAutomation {
console.log('🔄 Selector approach failed, trying manual input search...')
try {
const inputs = await this.page.locator('input').all()
- console.log("CHECKING: Found " + inputs.length} inputs to check`)
+ console.log(`CHECKING: Found ${inputs.length} inputs to check`)
for (let i = 0; i < inputs.length; i++) {
try {
@@ -808,14 +808,14 @@ export class TradingViewAutomation {
const name = await input.getAttribute('name') || ''
const placeholder = await input.getAttribute('placeholder') || ''
- console.log("INFO: Input ${i + 1}: type="${type}" name="${name}" placeholder="" + placeholder}"`)
+ console.log(`INFO: Input ${i + 1}: type="${type}" name="${name}" placeholder="${placeholder}"`)
if (type === 'email' ||
name.toLowerCase().includes('email') ||
name.toLowerCase().includes('username') ||
placeholder.toLowerCase().includes('email') ||
placeholder.toLowerCase().includes('username')) {
- console.log("TARGET: Found email input manually: " + name || type || placeholder) + ")"
+ console.log(`TARGET: Found email input manually: ${name || type || placeholder}`)
emailInput = `input:nth-of-type(${i + 1})`
break
}
@@ -973,7 +973,7 @@ export class TradingViewAutomation {
console.log('🔄 Selector approach failed, trying manual button search for submit...')
try {
const buttons = await this.page.locator('button').all()
- console.log("CHECKING: Found " + buttons.length} buttons to check for submit`)
+ console.log(`CHECKING: Found ${buttons.length} buttons to check for submit`)
for (let i = 0; i < buttons.length; i++) {
try {
@@ -982,13 +982,13 @@ export class TradingViewAutomation {
const text = (await button.textContent() || '').toLowerCase()
const type = await button.getAttribute('type') || ''
- console.log("INFO: Submit Button ${i + 1}: "${text}" type="" + type}"`)
+ console.log(`INFO: Submit Button ${i + 1}: "${text}" type="${type}"`)
if (type === 'submit' ||
text.includes('sign in') ||
text.includes('login') ||
text.includes('submit')) {
- console.log("TARGET: Found submit button manually: "" + text}"`)
+ console.log(`TARGET: Found submit button manually: "${text}"`)
submitButton = `button:nth-of-type(${i + 1})`
break
}
@@ -1026,7 +1026,7 @@ export class TradingViewAutomation {
await this.page.waitForTimeout(1000) // Wait 1 second
attempts++
- console.log("🔄 Login check attempt ${attempts}/" + maxAttempts) + ")"
+ console.log('Login check attempt ' + attempts + '/' + maxAttempts)
// Check if we navigated away from login page
const currentUrl = await this.page.url()
@@ -1059,8 +1059,8 @@ export class TradingViewAutomation {
for (const selector of errorSelectors) {
if (await this.page.locator(selector).isVisible({ timeout: 500 })) {
const errorText = await this.page.locator(selector).textContent()
- console.log("ERROR: Login error detected: " + errorText) + ")"
- throw new Error(`Login failed: ${errorText) + ")"
+ console.log('ERROR: Login error detected: ' + errorText)
+ throw new Error('Login failed: ' + errorText)
}
}
} catch (e) {
@@ -1312,17 +1312,17 @@ export class TradingViewAutomation {
// Change symbol if not BTC
if (symbol !== 'BTCUSD') {
- console.log("Changing symbol to " + symbol}...`)
+ console.log(`Changing symbol to ${symbol}...`)
await this.changeSymbol(symbol)
}
// Change timeframe if specified
if (timeframe) {
- console.log("Setting timeframe to " + timeframe}...`)
+ console.log(`Setting timeframe to ${timeframe}...`)
await this.changeTimeframe(timeframe)
}
- console.log("Successfully navigated to ${symbol} chart with " + timeframe} timeframe`)
+ console.log(`Successfully navigated to ${symbol} chart with ${timeframe} timeframe`)
return true
} catch (error) {
@@ -1352,7 +1352,7 @@ export class TradingViewAutomation {
symbolElement = selector
break
} catch (e) {
- console.log("Symbol selector " + selector} not found, trying next...`)
+ console.log(`Symbol selector ${selector} not found, trying next...`)
}
}
@@ -1377,7 +1377,7 @@ export class TradingViewAutomation {
searchInput = selector
break
} catch (e) {
- console.log("Search input selector " + selector} not found, trying next...`)
+ console.log(`Search input selector ${selector} not found, trying next...`)
}
}
@@ -1409,7 +1409,7 @@ export class TradingViewAutomation {
break
}
} catch (e) {
- console.log("Result selector " + selector} not found, trying next...`)
+ console.log(`Result selector ${selector} not found, trying next...`)
}
}
@@ -1481,7 +1481,7 @@ export class TradingViewAutomation {
break
}
} catch (e) {
- console.log("Interval legend selector " + selector} not found`)
+ console.log(`Interval legend selector ${selector} not found`)
}
}
@@ -1539,7 +1539,7 @@ export class TradingViewAutomation {
break
}
} catch (e) {
- console.log("Timeframe option selector " + selector} not found or not clickable`)
+ console.log(`Timeframe option selector ${selector} not found or not clickable`)
}
}
if (found) break
@@ -1572,7 +1572,7 @@ export class TradingViewAutomation {
console.log("SUCCESS: Successfully changed timeframe to " + timeframe) + ")"
await this.takeDebugScreenshot('after_timeframe_change')
} else {
- console.log("ERROR: Could not change timeframe to " + timeframe} - timeframe options not found`)
+ console.log(`ERROR: Could not change timeframe to ${timeframe} - timeframe options not found`)
// Take a debug screenshot to see current state
await this.takeDebugScreenshot('timeframe_change_failed')
@@ -1848,7 +1848,7 @@ export class TradingViewAutomation {
const cookiesData = await fs.readFile(COOKIES_FILE, 'utf8')
const cookies = JSON.parse(cookiesData)
await this.context!.addCookies(cookies)
- console.log("SUCCESS: Loaded " + cookies.length} cookies from saved session`)
+ console.log(`SUCCESS: Loaded ${cookies.length} cookies from saved session`)
}
// Note: Session storage will be loaded after page navigation
@@ -1870,7 +1870,7 @@ export class TradingViewAutomation {
// Save cookies
const cookies = await this.context.cookies()
await fs.writeFile(COOKIES_FILE, JSON.stringify(cookies, null, 2))
- console.log("SUCCESS: Saved " + cookies.length} cookies`)
+ console.log(`SUCCESS: Saved ${cookies.length} cookies`)
// Save session storage and localStorage
const sessionData = await this.page.evaluate(() => {
@@ -2072,7 +2072,7 @@ export class TradingViewAutomation {
if (!this.humanBehaviorEnabled) return
const delay = Math.random() * (maxMs - minMs) + minMs
- console.log("⏱️ Human-like delay: " + Math.round(delay)}ms`)
+ console.log(`⏱️ Human-like delay: ${Math.round(delay)}ms`)
await new Promise(resolve => setTimeout(resolve, delay))
}
@@ -2129,7 +2129,7 @@ export class TradingViewAutomation {
if (timeSinceLastRequest < minInterval) {
const waitTime = minInterval - timeSinceLastRequest
- console.log("🚦 Throttling request: waiting ${Math.round(waitTime / 1000)}s before next request (request #" + this.requestCount + 1})`)
+ console.log(`🚦 Throttling request: waiting ${Math.round(waitTime / 1000)}s before next request (request #${this.requestCount + 1})`)
await new Promise(resolve => setTimeout(resolve, waitTime))
}
@@ -2288,7 +2288,7 @@ export class TradingViewAutomation {
}
await fs.writeFile(captchaMarkerFile, JSON.stringify(markerData, null, 2))
- console.log("INFO: Marked captcha detection #${markerData.count} at " + markerData.timestamp) + ")"
+ console.log('INFO: Marked captcha detection #' + markerData.count + ' at ' + markerData.timestamp)
} catch (error) {
console.log('WARNING: Error marking captcha detection:', error)
}