diff --git a/agent.user.js b/agent.user.js index 5cff284..e3eed9e 100644 --- a/agent.user.js +++ b/agent.user.js @@ -34,10 +34,14 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); SESSION_ID: 'aRah9OhHeijee6sho3baequu9phoovah', SESSION_BINDED: 'Oos2uoth2thae8Ir8iakahj1OohaMahb', SESSION_TOKEN: 'ThiegiecohViuZ1Iecio7gahphiechub', + SESSION_INITIALIZED: 'iR4choo2Ieg2ew0ogheeyaer8Aisheet', BOT_STATUS: 'wiethie3boGhoh3iegh3ohnezei2tauj', CURRENT_TASK: 'Reebo1eitahh2aotumai5jae1neetoh3', CURRENT_TASK_DATA: 'cheishailoh5keePoo6oe2Quie1gaxah', CURRENT_STEP: 'eDusaidu2hooweiMoonahng3fua7aoso', + TIMER_START_TIME: 'einguh3eshuiqua7Ux7thaNgai5Axahy', + TIMER_IS_RUNNING: 'iengoose3vie2aikePhooCaPheeceizu', + TIMER_ACCUMULATED: 'aeMaiwae3PohB5Soshaech8eegh5quoo', } if (!sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID)) { @@ -50,13 +54,13 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); DASHBOARD_UPDATE_INTERVAL: 500, // Update dashboard overlay every 0.5 seconds TASK_INTERVAL: 10_000, // Check for new task every 10 seconds REQUEST_TIMEOUT: 10_000, // Request timeout in milliseconds (10 seconds) + DEBUG_MILESTONE: true, // Show milestone debug logs SERVERS: { local: { label: '🏠 Local', url: 'http://localhost:3000' }, prod: { label: '🌐 Prod', url: 'https://baf.thuanle.me' }, }, }; - const AppSession = { SESSION_ID: sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID), @@ -66,11 +70,14 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); getSessionToken: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_TOKEN), setSessionToken: token => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_TOKEN, token), - getSessionStatus: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.BOT_STATUS) || AppEnums.BOT_STATUS.STOP, + getSessionStatus: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.BOT_STATUS), setSessionStatus: status => sessionStorage.setItem(SESSION_STORAGE_KEYS.BOT_STATUS, status), + getSessionInitialized: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_INITIALIZED) === 'true', + setSessionInitialized: initialized => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_INITIALIZED, initialized ? 'true' : 'false'), + // Task state - Trạng thái task hiện tại (lưu trong sessionStorage) - getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK) || BAF_TASKS.NO_TASK, + getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK), setCurrentTask: task => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK, task), getCurrentTaskData: () => { @@ -79,15 +86,35 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); }, setCurrentTaskData: data => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK_DATA, JSON.stringify(data)), - getCurrentStep: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_STEP) || BAF_TASKS.NO_STEP, + getCurrentStep: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_STEP), setCurrentStep: step => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_STEP, step), + + initialize: async () => { + try { + const isInitialized = AppSession.getSessionInitialized(); + + if (!isInitialized) { + AppSession.setSessionStatus(AppEnums.BOT_STATUS.INITIALIZING); + AppSession.setCurrentTask(BAF_TASKS.NO_TASK); + AppSession.setCurrentStep(BAF_TASKS.NO_STEP); + AppSession.setSessionInitialized(true); + } else { + } + } catch (error) { + TL.error('APP-SESSION', '1.2.4. Error during session initialization:', error); + throw error; + } + }, } // ====== APP ENUMS ====== const AppEnums = { BOT_STATUS: { + INITIALIZING: 'initializing', STOP: 'stop', - RUNNING: 'running', + PAUSE: 'pause', + WAITING_FOR_TASK: 'waiting_for_task', + PERFORMING_TASK: 'performing_task', ERROR: 'error', }, BOT_STARTUP_MODE: { @@ -115,7 +142,6 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Session flags - Flags cho session hiện tại (reset khi reload) menuCreated: false, // Menu đã được tạo popupInitialized: false, // Popup đã được khởi tạo - appInitialized: false // App đã được khởi tạo hoàn toàn }; this.observers = new Map(); // Observer pattern cho state changes @@ -166,7 +192,6 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); getIsLoggedIn() { return this.data.is_logged_in; } getMenuCreated() { return this.data.menuCreated; } getPopupInitialized() { return this.data.popupInitialized; } - getAppInitialized() { return this.data.appInitialized; } /** * Cập nhật state với partial update @@ -284,6 +309,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); */ const TL = { debug: (tag, msg, ...args) => AppSettings.getDebug() && GM_log(`[TL] [DEBUG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args), + milestone: (tag, msg, ...args) => CONFIG.DEBUG_MILESTONE && GM_log(`[TL] [MILESTONE] [${new Date().toLocaleString()}] [${tag}] 🎯\n${msg}`, ...args), log: (tag, msg, ...args) => GM_log(`[TL] [LOG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args), warn: (tag, msg, ...args) => GM_log(`[TL] [WARN] [${new Date().toLocaleString()}] [${tag}] ⚠️\n${msg}`, ...args), error: (tag, msg, ...args) => GM_log(`[TL] [ERROR] [${new Date().toLocaleString()}] [${tag}] ❌\n${msg}`, ...args), @@ -352,7 +378,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); * Navigate to URL với option forceReload * @param {string} url - URL cần navigate */ - navigate: (url) => { + navigateTo: (url) => { window.location.href = url; } }, @@ -419,11 +445,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); const BAF_TASKS = { NO_TASK: 'no_task', - + LOGIN: 'login', + WALLET_SPOT: 'wallet_spot', + WALLET_FUNDING: 'wallet_funding', + WALLET_EARN: 'wallet_earn', + ALPHA_SWAP: 'alpha_swap', + ALPHA_ORDER_HISTORY: 'alpha_order_history', NO_STEP: 'no_step', }; - + const BAF = { _getHost: () => AppState.getServer()?.url, @@ -630,7 +661,10 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Create dashboard overlay element create: () => { + + if (AppUi.dashboardOverlay.element) { + document.body.removeChild(AppUi.dashboardOverlay.element); } @@ -655,6 +689,36 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); user-select: none; `; + // Add close button (X) + const closeBtn = document.createElement('div'); + closeBtn.style.cssText = ` + position: absolute; + top: -8px; + left: -8px; + width: 20px; + height: 20px; + background: #dc3545; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + font-size: 12px; + color: white; + border: 2px solid rgba(255, 255, 255, 0.2); + transition: all 0.2s ease; + font-weight: bold; + `; + closeBtn.innerHTML = '×'; + closeBtn.title = 'Close popup'; + closeBtn.addEventListener('click', () => { + AppUi.dashboardOverlay.hide(); + AppSettings.setPopupVisible(false); + }); + TL.dom.setHover(closeBtn, 'mouseenter', { scale: 1.5, background: '#c82333' }); + TL.dom.setHover(closeBtn, 'mouseleave', { scale: 1, background: '#dc3545' }); + overlay.appendChild(closeBtn); + // Add position toggle button const positionBtn = document.createElement('div'); positionBtn.style.cssText = ` @@ -679,15 +743,18 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); positionBtn.addEventListener('click', () => { const newPosition = (AppSettings.getPopupPosition() % 4) + 1; AppSettings.setPopupPosition(newPosition); - AppUi.statusOverlay.updatePosition(); + AppUi.dashboardOverlay.updatePosition(); }); TL.dom.setHover(positionBtn, 'mouseenter', { scale: 1.5, background: '#0056b3' }); TL.dom.setHover(positionBtn, 'mouseleave', { scale: 1, background: '#007bff' }); overlay.appendChild(positionBtn); + AppUi.dashboardOverlay.element = overlay; + document.body.appendChild(overlay); + return overlay; }, @@ -703,20 +770,37 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Update overlay content updateContent: () => { try { + + + + if (!AppUi.dashboardOverlay.element) { + AppUi.dashboardOverlay.create(); + } // Get status display let statusDisplay = ''; - switch (AppSession.getSessionStatus()) { - case AppEnums.BOT_STATUS.RUNNING: - statusDisplay = '▶️ Running'; + const currentStatus = AppSession.getSessionStatus(); + + switch (currentStatus) { + case AppEnums.BOT_STATUS.INITIALIZING: + statusDisplay = '🔄 Initializing'; break; case AppEnums.BOT_STATUS.STOP: statusDisplay = '⏹️ Stop'; break; + case AppEnums.BOT_STATUS.PAUSE: + statusDisplay = '⏸️ Pause'; + break; + case AppEnums.BOT_STATUS.WAITING_FOR_TASK: + statusDisplay = '⏳ Waiting for Task'; + break; + case AppEnums.BOT_STATUS.PERFORMING_TASK: + statusDisplay = '▶️ Performing Task'; + break; case AppEnums.BOT_STATUS.ERROR: statusDisplay = '❌ Error'; break; default: - statusDisplay = '❌ Error'; + statusDisplay = '❓ Unknown'; break; } @@ -741,16 +825,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
BAF Agent Dashboard
- 🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'} + 🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'}
🆔 Tab: ${AppSession.SESSION_ID.slice(-12)}
- 🤖 Bot Status: ${statusDisplay} + 🤖 Bot Status: ${statusDisplay}
- 🚀 Startup Mode: ${AppSettings.getBotStartupMode() === AppEnums.BOT_STARTUP_MODE.AUTO ? '🔄 Auto' : '✋ Manual'} + 🚀 Startup Mode: ${AppSettings.getBotStartupMode() === AppEnums.BOT_STARTUP_MODE.AUTO ? '🔄 Auto' : '✋ Manual'}
📋 Task: ${AppSession.getCurrentTask() || 'None'} @@ -765,14 +849,32 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); Page: ${pageDisplay}
- 🌐 Server: ${serverLabel} ${serverConnected} + 🌐 Server: ${serverLabel} ${serverConnected}
- 🐛 Debug: ${AppSettings.getDebug() ? '🔈 ON' : '🔇 OFF'} + 🐛 Debug: ${AppSettings.getDebug() ? '🔈 ON' : '🔇 OFF'} +
+
+ 🎯 Milestone: ${CONFIG.DEBUG_MILESTONE ? '🔈 ON' : '🔇 OFF'} +
+
+
+ ⏱️ ${AppServices.Timer.getDisplay()} +
+
+ ▶️ + ⏸️ + ⏹️ +
`; // Update content (excluding position button) + if (!AppUi.dashboardOverlay.element) { + TL.error('DASHBOARD-OVERLAY', '8.1. Element is null!'); + return; + } + const contentDiv = AppUi.dashboardOverlay.element.querySelector('.baf-content') || document.createElement('div'); contentDiv.className = 'baf-content'; contentDiv.innerHTML = content; @@ -782,7 +884,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } // Add event listener for safety toggle button - const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn'); + const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn-AithaiG2'); if (safetyToggleBtn) { safetyToggleBtn.onclick = () => { const currentStatus = { @@ -800,7 +902,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } // Add event listener for debug toggle button - const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn'); + const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn-Tai5guto'); if (debugToggleBtn) { debugToggleBtn.onclick = () => { const newDebugState = !AppSettings.getDebug(); @@ -810,29 +912,47 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); }; } - // Add event listener for bot status toggle button - const botStatusToggleBtn = contentDiv.querySelector('#bot-status-toggle-btn'); - if (botStatusToggleBtn) { - botStatusToggleBtn.onclick = () => { - const currentBotStatus = AppSession.getSessionStatus(); - let newBotStatus; - - // Logic: stop/error -> start, start -> stop - if (currentBotStatus === AppEnums.BOT_STATUS.RUNNING) { - newBotStatus = AppEnums.BOT_STATUS.STOP; - } else { - // STOP or ERROR -> RUNNING - newBotStatus = AppEnums.BOT_STATUS.RUNNING; - } - - AppSession.setSessionStatus(newBotStatus); - // Update the content to reflect the change + // Add event listeners for control buttons + const playBtn = contentDiv.querySelector('#play-btn-uPha3Mah'); + if (playBtn) { + playBtn.onclick = () => { + AppServices.Status.play(); AppUi.dashboardOverlay.updateContent(); }; } + const pauseBtn = contentDiv.querySelector('#pause-btn-Gai2quie'); + if (pauseBtn) { + pauseBtn.onclick = () => { + AppServices.Status.pause(); + AppUi.dashboardOverlay.updateContent(); + }; + } + + const stopBtn = contentDiv.querySelector('#stop-btn-jooK6che'); + if (stopBtn) { + stopBtn.onclick = () => { + AppServices.Status.stop(); + AppUi.dashboardOverlay.updateContent(); + }; + } + + // Add hover effects for control buttons + if (playBtn) { + TL.dom.setHover(playBtn, 'mouseenter', { scale: 1.2, background: 'rgba(40, 167, 69, 0.2)' }); + TL.dom.setHover(playBtn, 'mouseleave', { scale: 1, background: 'rgba(40, 167, 69, 0.1)' }); + } + if (pauseBtn) { + TL.dom.setHover(pauseBtn, 'mouseenter', { scale: 1.2, background: 'rgba(255, 193, 7, 0.2)' }); + TL.dom.setHover(pauseBtn, 'mouseleave', { scale: 1, background: 'rgba(255, 193, 7, 0.1)' }); + } + if (stopBtn) { + TL.dom.setHover(stopBtn, 'mouseenter', { scale: 1.2, background: 'rgba(220, 53, 69, 0.2)' }); + TL.dom.setHover(stopBtn, 'mouseleave', { scale: 1, background: 'rgba(220, 53, 69, 0.1)' }); + } + // Add event listener for startup mode toggle button - const startupModeToggleBtn = contentDiv.querySelector('#startup-mode-toggle-btn'); + const startupModeToggleBtn = contentDiv.querySelector('#startup-mode-toggle-btn-tha9ieCa'); if (startupModeToggleBtn) { startupModeToggleBtn.onclick = () => { const currentStartupMode = AppSettings.getBotStartupMode(); @@ -844,7 +964,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } // Add event listener for server toggle button - const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn'); + const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn-Youx4pho'); if (serverToggleBtn) { serverToggleBtn.onclick = async () => { const currentServerType = AppSettings.getServerType(); @@ -894,8 +1014,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Initialize dashboard overlay init: () => { - if (AppSettings.getPopupVisible()) { - AppUi.dashboardOverlay.show(); + try { + const popupVisible = AppSettings.getPopupVisible(); + + if (popupVisible) { + AppUi.dashboardOverlay.show(); + } else { + } + } catch (error) { + TL.error('DASHBOARD-OVERLAY', '1.4.4. Error initializing dashboard overlay:', error); + throw error; } } }, @@ -944,85 +1072,98 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); GM_registerMenuCommand("👁️ Toggle Popup", () => { AppUi.dashboardOverlay.toggle(); }); - } catch (error) { - TL.error('MENU', 'Failed to create menu:', error); + TL.error('MENU', '1.3.5. Failed to create menu:', error); throw error; } } }, }; + // ====== APP TASKS ====== + const AppTasks = { + login: async (step, data) => { + if (!AppServices.isReadyToRun()) { + TL.debug('APP-TASKS', 'Bot is not ready to run'); + return; + } + + TL.debug('APP-TASKS', `Login task ${step}`); + //set steps + switch (step) { + case "start": + AppSession.setSessionStatus(AppEnums.BOT_STATUS.PERFORMING_TASK); + AppSession.setCurrentStep("navigating-to-login-page"); + TL.browser.navigateTo(BINANCE.page.getLoginUrl()); + break; + } + }, + }; + // ====== APP SERVICE ====== const AppServices = { initialize: async () => { - await AppState.initialize(); + try { + await AppState.initialize(); + await AppSession.initialize(); - await AppUi.menu.create(); + // Khởi tạo timer + AppServices.Timer.initialize(); - AppUi.dashboardOverlay.init(); + await AppUi.menu.create(); + AppUi.dashboardOverlay.init(); + await AppServices.registerSession(); - // Setup observers for dashboard overlay updates - AppServices.initObservers(); + const status = AppSession.getSessionStatus(); + if (status === AppEnums.BOT_STATUS.INITIALIZING) { + const startupMode = AppSettings.getBotStartupMode(); + if (startupMode === AppEnums.BOT_STARTUP_MODE.AUTO) { + AppSession.setSessionStatus(AppEnums.BOT_STATUS.WAITING_FOR_TASK); + } else { + AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP); + } + } - await AppServices.registerSession(); - - // Set bot status based on startup mode - const startupMode = AppSettings.getBotStartupMode(); - if (startupMode === AppEnums.BOT_STARTUP_MODE.AUTO) { - AppSession.setSessionStatus(AppEnums.BOT_STATUS.RUNNING); - TL.debug('APP-SERVICES', 'Auto startup mode: Bot status set to RUNNING'); - } else { - AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP); - TL.debug('APP-SERVICES', 'Manual startup mode: Bot status set to STOP'); + AppServices.initInterval(); + } catch (error) { + TL.error('APP-SERVICES', 'Error during initialization:', error); + throw error; } - - // Setup interval services - AppServices.initInterval(); - - AppState.update({ appInitialized: true }); - - TL.debug('APP-SERVICES', 'AppServices initialized'); }, - initObservers: () => { - // AppState.subscribe('server_last_seen', () => { - // if (AppSettings.getPopupVisible()) { - // AppUi.dashboardOverlay.updateContent(); - // } - // }); - - // AppState.subscribe('is_logged_in', () => { - // if (AppSettings.getPopupVisible()) { - // AppUi.dashboardOverlay.updateContent(); - // } - // }); - - // AppState.subscribe('current_page', () => { - // if (AppSettings.getPopupVisible()) { - // AppUi.dashboardOverlay.updateContent(); - // } - // }); - }, registerSession: async () => { - const msg = await BAF.register({ session_id: AppSession.SESSION_ID }); - //if ok, set session token - if (msg.ok) { - AppSession.setSessionToken(msg.data.token); - AppSession.setSessionBinded(true); - TL.debug('APP-SERVICES', `Session token: ${AppSession.getSessionToken()}`); - } else { + try { + const msg = await BAF.register({ session_id: AppSession.SESSION_ID }); + + if (msg.ok) { + AppSession.setSessionToken(msg.data.token); + AppSession.setSessionBinded(true); + } else { + AppSession.setSessionBinded(false); + TL.error('APP-SERVICES', `1.5.3. Failed to register session: ${msg.error}`); + } + } catch (error) { + TL.error('APP-SERVICES', '1.5.3. Error during session registration:', error); AppSession.setSessionBinded(false); - TL.error('APP-SERVICES', `Failed to register session: ${msg.error}`); + throw error; } }, - // Setup interval services initInterval: () => { - setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL); - setInterval(() => AppUi.dashboardOverlay.updateContent(), CONFIG.DASHBOARD_UPDATE_INTERVAL); + try { + setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL); + setInterval(() => AppUi.dashboardOverlay.updateContent(), CONFIG.DASHBOARD_UPDATE_INTERVAL); - TL.debug('APP-SERVICES', 'Interval services started'); + // Timer update interval - cập nhật timer mỗi giây + setInterval(() => { + const timerDisplay = document.querySelector('#timer-display-ohr1Youj'); + if (timerDisplay) { + timerDisplay.textContent = `⏱️ ${AppServices.Timer.getDisplay()}`; + } + }, 1000); + } catch (error) { + throw error; + } }, isConnected: () => { @@ -1030,9 +1171,86 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); return serverLastSeen && new Date() - serverLastSeen < 60000; }, - isReadyToRun: () => { - return AppSession.getSessionBinded() && AppSettings.getSafetyGuard() && AppSession.getSessionStatus() === AppEnums.BOT_STATUS.RUNNING; + return AppSession.getSessionBinded() && AppSettings.getSafetyGuard() && AppSession.getSessionStatus() === AppEnums.BOT_STATUS.WAITING_FOR_TASK; + }, + + // ====== TIMER SYSTEM ====== + Timer: { + // Timer state management - Quản lý trạng thái timer + getStartTime: () => { + const time = sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_START_TIME); + return time ? parseInt(time) : null; + }, + setStartTime: time => { + if (time === null || time === undefined) { + sessionStorage.removeItem(SESSION_STORAGE_KEYS.TIMER_START_TIME); + } else { + sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_START_TIME, time.toString()); + } + }, + + isRunning: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_IS_RUNNING) === 'true', + setRunning: running => sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_IS_RUNNING, running ? 'true' : 'false'), + + getAccumulated: () => { + const time = sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_ACCUMULATED); + return time ? parseInt(time) : 0; + }, + setAccumulated: time => sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_ACCUMULATED, time.toString()), + + // Timer control methods + start: () => { + if (!AppServices.Timer.isRunning()) { + AppServices.Timer.setStartTime(Date.now()); + AppServices.Timer.setRunning(true); + TL.debug('TIMER', 'Timer started'); + } + }, + + pause: () => { + if (AppServices.Timer.isRunning()) { + const startTime = AppServices.Timer.getStartTime(); + const currentTime = Date.now(); + const elapsed = currentTime - startTime; + const accumulated = AppServices.Timer.getAccumulated(); + AppServices.Timer.setAccumulated(accumulated + elapsed); + AppServices.Timer.setRunning(false); + AppServices.Timer.setStartTime(null); + } + }, + + stop: () => { + AppServices.Timer.pause(); + AppServices.Timer.setAccumulated(0); + }, + + getDisplay: () => { + let totalTime = AppServices.Timer.getAccumulated(); + + if (AppServices.Timer.isRunning()) { + const startTime = AppServices.Timer.getStartTime(); + if (startTime) { + const currentTime = Date.now(); + totalTime += (currentTime - startTime); + } + } + + const hours = Math.floor(totalTime / 3600000); + const minutes = Math.floor((totalTime % 3600000) / 60000); + const seconds = Math.floor((totalTime % 60000) / 1000); + + const display = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; + TL.debug('TIMER', `Display: ${display}, Running: ${AppServices.Timer.isRunning()}, Accumulated: ${totalTime}`); + return display; + }, + + initialize: () => { + AppServices.Timer.setAccumulated(0); + AppServices.Timer.setRunning(false); + AppServices.Timer.setStartTime(null); + TL.debug('TIMER', 'Timer initialized'); + } }, // ====== HEARTBEAT SYSTEM ====== @@ -1066,7 +1284,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } }, - getTask: async () => { + handleNewTask: async () => { const data = { logged_in: AppState.getIsLoggedIn(), current_page: AppState.getCurrentPage(), @@ -1075,38 +1293,89 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); current_task_data: AppSession.getCurrentTaskData(), current_step: AppSession.getCurrentStep(), }; - const task = await BAF.getTask(data); - return task; + + const taskResponse = await BAF.getTask(data); + TL.debug('APP-SERVICES', `Task: ${JSON.stringify(taskResponse, null, 2)}`); + + if (taskResponse.ok) { + const task = taskResponse.data; + AppSession.setCurrentTask(task.type); + AppSession.setCurrentTaskData(task.data || null); + + switch (task.type) { + case BAF_TASKS.NO_TASK: + TL.debug('APP-TASK', "No task. Sleep now"); + break; + case BAF_TASKS.LOGIN: + AppTasks.login("start", task.data); + break; + default: + TL.debug('APP-TASK', `Unknown task 🛑`); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.ERROR); + break; + } + } }, - handleTask: (task) => { - TL.debug('APP-SERVICES', `Task: ${JSON.stringify(task, null, 2)}`); + resumeTask: async () => { + TL.debug('APP-SERVICES', 'Resume task'); - AppSession.setCurrentTask(task.task); - AppSession.setCurrentTaskData(task.data || null); - AppSession.setCurrentStep(task.step || null); + const task = AppSession.getCurrentTask(); + const data = AppSession.getCurrentTaskData(); + const step = AppSession.getCurrentStep(); - switch (task.task) { - case BAF_TASKS.NO_TASK: - TL.debug('APP-TASK', "No task. Sleep now"); - break; - default: - TL.debug('APP-TASK', `Unknown task 🛑`); - AppSession.setSessionStatus(AppEnums.BOT_STATUS.ERROR); + switch (task) { + case BAF_TASKS.LOGIN: + AppTasks.login(step, data); break; + }; + }, + + // ====== BOT STATUS CONTROL ====== + Status: { + play: () => { + AppServices.Timer.start(); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.WAITING_FOR_TASK); + }, + + pause: () => { + AppServices.Timer.pause(); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.PAUSE); + }, + + stop: () => { + AppServices.Timer.stop(); + AppSession.setCurrentTask(BAF_TASKS.NO_TASK); + AppSession.setCurrentTaskData(null); + AppSession.setCurrentStep(BAF_TASKS.NO_STEP); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP); } }, start: async () => { while (true) { - //checking bot status: running? - if (AppSession.getSessionStatus() === AppEnums.BOT_STATUS.RUNNING) { - const task = await AppServices.getTask(); - if (task.ok) { - AppServices.handleTask(task.data); - } - } else { - TL.debug('APP-SERVICES', 'Bot is stopped, skipping task check'); + switch (AppSession.getSessionStatus()) { + case AppEnums.BOT_STATUS.INITIALIZING: + TL.debug('APP-SERVICES', 'Bot is initializing, waiting...'); + break; + case AppEnums.BOT_STATUS.STOP: + TL.debug('APP-SERVICES', 'Bot is stopped, skipping task check'); + break; + case AppEnums.BOT_STATUS.PAUSE: + TL.debug('APP-SERVICES', 'Bot is paused, skipping task check'); + break; + case AppEnums.BOT_STATUS.WAITING_FOR_TASK: + await AppServices.handleNewTask(); + break; + case AppEnums.BOT_STATUS.PERFORMING_TASK: + await AppServices.resumeTask(); + break; + case AppEnums.BOT_STATUS.ERROR: + TL.debug('APP-SERVICES', 'Bot is in error state, skipping task check'); + break; + default: + TL.debug('APP-SERVICES', 'Bot is in unknown state, skipping task check'); + break; } await TL.delay(CONFIG.TASK_INTERVAL); @@ -1116,9 +1385,12 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Start the application try { + await AppServices.initialize(); + } catch (error) { TL.error('MAIN', 'Failed to initialize app:', error); + TL.error('MAIN', 'Error stack:', error.stack); } TL.log('MAIN', 'App started');