diff --git a/agent.user.js b/agent.user.js index 0524c56..6bbe864 100644 --- a/agent.user.js +++ b/agent.user.js @@ -27,13 +27,13 @@ if (window.top !== window) { GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); (async () => { - 'use strict'; + 'use strict'; // ====== CONFIGURATION ====== const CONFIG = { heartbeat_interval: 10000, task_poll_interval: 10000, - is_debug: true, + servers: { local: { label: 'π Local', url: 'http://localhost:3000' }, prod: { label: 'π Prod', url: 'https://baf.thuanle.me' }, @@ -47,6 +47,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); // Server configuration server_type: 'prod', server_url: null, + server_last_seen: null, // Page state current_page: null, @@ -67,7 +68,12 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); // Popup state popup_position: 4, // 1: top-left, 2: top-right, 3: bottom-left, 4: bottom-right - popup_visible: true + popup_visible: true, + + // Debug state + is_debug: true + + }; this.observers = new Map(); @@ -85,6 +91,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); this.data.bot_status = await STORAGE.getBotStatus(); this.data.popup_position = await STORAGE.getPopupPosition(); this.data.popup_visible = await STORAGE.getPopupVisible(); + this.data.is_debug = await STORAGE.getDebug(); // Detect current page and login state this.data.current_page = BINANCE.detectPage(); @@ -152,6 +159,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); key_navigation_state: 'baf-navigation-state', key_popup_position: 'baf-popup-position', key_popup_visible: 'baf-popup-visible', + key_debug: 'baf-debug', getToken: () => GM_getValue(STORAGE.key_token, ''), setToken: token => GM_setValue(STORAGE.key_token, String(token || '').trim().replace(/^Bearer\s+/i, '')), @@ -182,12 +190,15 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); setPopupPosition: (position) => GM_setValue(STORAGE.key_popup_position, position), getPopupVisible: () => GM_getValue(STORAGE.key_popup_visible, true), - setPopupVisible: (visible) => GM_setValue(STORAGE.key_popup_visible, visible) + setPopupVisible: (visible) => GM_setValue(STORAGE.key_popup_visible, visible), + + getDebug: () => GM_getValue(STORAGE.key_debug, true), + setDebug: (debug) => GM_setValue(STORAGE.key_debug, debug) }; // ====== UTILITY MODULE ====== const TL = { - debug: (tag, msg, ...args) => CONFIG.is_debug && GM_log(`[TL] [${tag}]\n${msg}`, ...args), + debug: (tag, msg, ...args) => APP_STATE.getData().is_debug && GM_log(`[TL] [${tag}]\n${msg}`, ...args), log: (tag, msg, ...args) => GM_log(`[TL] [${tag}]\n${msg}`, ...args), warn: (tag, msg, ...args) => GM_log(`[TL] [WARN] [${tag}] β οΈ\n${msg}`, ...args), error: (tag, msg, ...args) => GM_log(`[TL] [ERROR] [${tag}] β\n${msg}`, ...args), @@ -375,7 +386,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); const BINANCE = { detectPage: () => { if (!SafetyGuard.check('detectPage')) return BINANCE_PAGES.IGNORE; - + const { hostname, pathname } = window.location; if (window.top !== window) { TL.debug('BINANCE-PAGE-DETECT', 'Call from iframe β'); @@ -394,7 +405,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); // Check patterns in order (most specific first) for (const pattern of hostConfig.patterns) { - if (pathname.includes(pattern.includes)) { + if (pathname.includes(pattern.includes)) { TL.debug('PAGE_DETECT', msg + `Matched pattern: ${pattern.includes} -> ${pattern.page}`); return pattern.page; @@ -417,25 +428,25 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); detectLoginState: () => { if (!SafetyGuard.check('detectLoginState')) return null; - + if (window.top !== window) { TL.debug('BINANCE-LOGIN', 'In iframe - cannot determine login state'); return null; } - if (BINANCE.isOnLoginPage()) { + if (BINANCE.isOnLoginPage()) { return false; } // otherwise // if (BINANCE.isOnAlphaSwapPage()) { - + // Method 1: Check for login/register buttons (indicates NOT logged in) const loginBtn = document.querySelector('#toLoginPage, [data-testid="login-button"], .login-btn'); const regBtn = document.querySelector('#toRegisterPage, [data-testid="register-button"], .register-btn'); let msg = `loginBtn: ${TL.dom.isVisible?.(loginBtn)} regBtn: ${TL.dom.isVisible?.(regBtn)}\n`; - + // If login/register buttons are visible, definitely not logged in if (TL.dom.isVisible?.(loginBtn) || TL.dom.isVisible?.(regBtn)) { TL.debug('BINANCE-LOGIN', msg + 'Login/Register buttons visible -> NOT logged in'); @@ -450,9 +461,9 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); const isDashboardVisible = dashboardLink && TL.dom.isVisible?.(dashboardLink); const isAccountIconVisible = !!accountIcon; const isWalletVisible = walletBtn && TL.dom.isVisible?.(walletBtn); - + // msg += `dashboard: ${dashboardLink}, accountIcon: ${accountIcon}, walletBtn: ${walletBtn}\n`; - msg += `Visible: dashboard: ${isDashboardVisible? 'β' : 'β'}, accountIcon: ${isAccountIconVisible? 'β' : 'β'}, walletBtn: ${isWalletVisible? 'β' : 'β'}\n`; + msg += `Visible: dashboard: ${isDashboardVisible ? 'β' : 'β'}, accountIcon: ${isAccountIconVisible ? 'β' : 'β'}, walletBtn: ${isWalletVisible ? 'β' : 'β'}\n`; // If we see user account elements, likely logged in if (isDashboardVisible && isAccountIconVisible && isWalletVisible) { @@ -897,7 +908,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); // Execute current step async executeCurrentStep() { if (!SafetyGuard.check('executeCurrentStep')) return; - + const data = APP_STATE.getData(); if (!data.current_task || !this.context) { TL.debug('STEP', 'No current task or context available'); @@ -1196,7 +1207,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); }, async checkForNewTasks() { if (!SafetyGuard.check('checkForNewTasks')) return; - + try { const data = APP_STATE.getData(); if (data.bot_status !== BOT_STATUS.WAITING && data.bot_status !== BOT_STATUS.RUNNING) { @@ -1346,7 +1357,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); const data = APP_STATE.getData(); const curSrv = data.server_url; - GM_registerMenuCommand(`Server: ${curSrv.label} (${curSrv.url})`, async () => { + GM_registerMenuCommand(`π Server: ${curSrv.label} (${curSrv.url})`, async () => { try { const next = (data.server_type === 'local') ? 'prod' : 'local'; await APP_STATE.update({ server_type: next }); @@ -1361,7 +1372,7 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); } }); - GM_registerMenuCommand('Token', async () => { + GM_registerMenuCommand('π Token', async () => { try { const curToken = await STORAGE.getToken(); const input = prompt('Bearer token:', curToken || ''); @@ -1382,96 +1393,16 @@ GM_log('[TL] π Welcome to Binance Alpha Farm Agent.'); } }); - // Bot Status Menu vα»i icon vΓ tΓͺn task - const getStatusDisplay = () => { - const data = APP_STATE.getData(); - const taskName = data.current_task?.type || ''; - - switch (data.bot_status) { - case BOT_STATUS.WAITING: - return `π€ Waiting for new task`; - case BOT_STATUS.RUNNING: - return `βΆοΈ Running: ${taskName}`; - case BOT_STATUS.PAUSED: - return `βΈοΈ Paused: ${taskName}`; - case BOT_STATUS.STOPPED: - return `βΉοΈ Stopped`; - default: - return `β Unknown status`; - } - }; - // Popup toggle menu - const popupData = APP_STATE.getData(); - const popupStatus = popupData.popup_visible ? 'ποΈ Hide Popup' : 'ποΈ Show Popup'; - GM_registerMenuCommand(popupStatus, () => { + GM_registerMenuCommand("ποΈ Toggle Popup", () => { UI.statusOverlay.toggle(); }); - - - - - // Debug tools - GM_registerMenuCommand('π Current Status', () => { - const detectedPage = APP_STATE.getData().current_page; - const isLoggedIn = APP_STATE.getData().is_logged_in; - const currentUrl = window.location.href; - - const status = `Page: ${detectedPage}\nLogin: ${isLoggedIn ? 'Yes' : 'No'}\nURL: ${currentUrl}`; - - console.log('Current Status:', status); - alert(status); - }); - - GM_registerMenuCommand('π Debug Login State', () => { - const isInIframe = window.top !== window; - const loginState = BINANCE.detectLoginState(); - - // Check all possible login indicators - const loginIndicators = { - 'In iframe': isInIframe, - 'Login button visible': TL.dom.isVisible?.(document.querySelector('#toLoginPage')), - 'Register button visible': TL.dom.isVisible?.(document.querySelector('#toRegisterPage')), - 'Account icon found': !!document.querySelector('.header-account-icon'), - 'Deposit button found': !!document.querySelector('.deposit-btn'), - 'Wallet button found': !!document.querySelector('#ba-wallet'), - 'User menu found': !!document.querySelector('.header-dropdown-menu'), - 'Dashboard link found': !!document.querySelector('a[href*="/my/dashboard"]'), - 'Detected login state': loginState - }; - - const debugInfo = Object.entries(loginIndicators) - .map(([key, value]) => `${key}: ${value}`) - .join('\n'); - - console.log('=== LOGIN STATE DEBUG ==='); - console.log(debugInfo); - alert(`Login State Debug:\n\n${debugInfo}`); - }); - - GM_registerMenuCommand('π Debug URL Sources', () => { - const mainUrl = window.location.href; - const frames = Array.from(document.querySelectorAll('iframe')).map(frame => frame.src); - const popups = window.opener ? window.opener.location.href : null; - - const debugInfo = ` -Main Window: ${mainUrl} -Frames: ${frames.length > 0 ? frames.join('\n') : 'None'} -Popup Opener: ${popups || 'None'} - `; - - console.log('=== URL SOURCES DEBUG ==='); - console.log(debugInfo); - alert(`URL Sources Debug:\n\n${debugInfo}`); - }); - - } // ====== HEARTBEAT ====== async function heartbeat_report() { if (!SafetyGuard.check('heartbeat_report')) return null; - + try { const data = APP_STATE.getData(); const status = { @@ -1484,7 +1415,11 @@ Popup Opener: ${popups || 'None'} }; // TL.debug(`HEARTBEAT`, `${JSON.stringify(status, null, 2)}`); - await BAF.ping(status); + const res = await BAF.ping(status); + if (res.ok) { + APP_STATE.update({ server_last_seen: new Date() }); + } + return status; } catch (e) { TL.error('HEARTBEAT', e.message); @@ -1593,7 +1528,6 @@ Popup Opener: ${popups || 'None'} // Update overlay content updateContent: () => { - if (!UI.statusOverlay.element) return; const data = APP_STATE.getData(); const taskName = data.current_task?.type || 'No task'; @@ -1620,27 +1554,36 @@ Popup Opener: ${popups || 'None'} // Get server info const serverLabel = data.server_url?.label || 'Unknown'; + // data.server_last_seen < 1min == connected + const serverConnected = data.server_last_seen && new Date() - data.server_last_seen < 60000 ? 'π’' : 'π΄'; // Get page info const pageDisplay = data.current_page || 'unknown'; // Get login status - const loginStatus = data.is_logged_in ? 'β Logged in' : 'β Not logged in'; + const loginStatus = data.is_logged_in ? 'β ' : 'β'; // Get SafetyGuard status const safetyStatus = SafetyGuard.getStatus(); - const safetyDisplay = safetyStatus.enabled ? 'π‘οΈ Safe' : 'π¨ Blocked'; // Build content const content = ` -