ready for first task

This commit is contained in:
thuanle
2025-08-05 00:53:58 +07:00
parent 42950c77cc
commit d2051afab6

View File

@@ -32,7 +32,9 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
const SESSION_STORAGE_KEYS = {
SESSION_ID: 'aRah9OhHeijee6sho3baequu9phoovah',
SESSION_BINDED: 'Oos2uoth2thae8Ir8iakahj1OohaMahb',
SESSION_TOKEN: 'ThiegiecohViuZ1Iecio7gahphiechub',
BOT_STATUS: 'wiethie3boGhoh3iegh3ohnezei2tauj',
CURRENT_TASK: 'Reebo1eitahh2aotumai5jae1neetoh3',
CURRENT_TASK_DATA: 'cheishailoh5keePoo6oe2Quie1gaxah',
CURRENT_STEP: 'eDusaidu2hooweiMoonahng3fua7aoso',
@@ -44,9 +46,10 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
// ====== CONFIGURATION ======
const CONFIG = {
HEARTBEAT_INTERVAL: 10000, // Send heartbeat every 10 seconds
HEARTBEAT_INTERVAL: 10_000, // Send heartbeat every 10 seconds
DASHBOARD_UPDATE_INTERVAL: 500, // Update dashboard overlay every 0.5 seconds
TASK_INTERVAL: 1000, // Check for new task every 1 second
TASK_INTERVAL: 10_000, // Check for new task every 10 seconds
REQUEST_TIMEOUT: 10_000, // Request timeout in milliseconds (10 seconds)
SERVERS: {
local: { label: '🏠 Local', url: 'http://localhost:3000' },
prod: { label: '🌐 Prod', url: 'https://baf.thuanle.me' },
@@ -57,11 +60,17 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
const AppSession = {
SESSION_ID: sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID),
getSessionBinded: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_BINDED) === 'true',
setSessionBinded: binded => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_BINDED, binded ? 'true' : 'false'),
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,
setSessionStatus: status => sessionStorage.setItem(SESSION_STORAGE_KEYS.BOT_STATUS, status),
// Task state - Trạng thái task hiện tại (lưu trong sessionStorage)
getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK),
getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK) || BAF_TASKS.NO_TASK,
setCurrentTask: task => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK, task),
getCurrentTaskData: () => {
@@ -70,15 +79,20 @@ 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),
getCurrentStep: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_STEP) || BAF_TASKS.NO_STEP,
setCurrentStep: step => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_STEP, step),
}
// ====== APP ENUMS ======
const AppEnums = {
BOT_STATUS: {
IDLE: 'idle',
STOP: 'stop',
RUNNING: 'running',
ERROR: 'error',
},
BOT_STARTUP_MODE: {
AUTO: 'auto',
MANUAL: 'manual',
}
};
@@ -226,7 +240,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
const AppSettings = {
key_agent_token: 'baf-agent-token',
key_server_type: 'baf-server-type',
key_bot_status: 'baf-bot-status',
key_bot_startup_mode: 'baf-bot-startup-mode',
key_popup_position: 'baf-popup-position',
key_popup_visible: 'baf-popup-visible',
key_debug: 'baf-debug',
@@ -242,8 +256,8 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
AppState.update({ server_last_seen: null });
},
getBotStatus: () => GM_getValue(AppSettings.key_bot_status, AppEnums.BOT_STATUS.IDLE),
setBotStatus: (status) => GM_setValue(AppSettings.key_bot_status, status),
getBotStartupMode: () => GM_getValue(AppSettings.key_bot_startup_mode, AppEnums.BOT_STARTUP_MODE.MANUAL),
setBotStartupMode: (mode) => GM_setValue(AppSettings.key_bot_startup_mode, mode),
// Popup configuration
getPopupPosition: () => GM_getValue(AppSettings.key_popup_position, 4),
@@ -357,6 +371,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
method: (init.method || 'GET').toUpperCase(),
headers: headersToObject(init.headers),
data: init.body,
timeout: CONFIG.REQUEST_TIMEOUT,
onload: (resp) => {
const text = resp.responseText || '';
let data = text;
@@ -371,8 +386,28 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
headers: null
});
},
onerror: reject,
ontimeout: () => reject(new Error('GM_xmlhttpRequest timeout')),
onerror: (error) => {
TL.error('net', `Request failed: ${url}`, error);
resolve({
status: 0,
ok: false,
data: null,
rawText: '',
headers: null,
error: 'Network error'
});
},
ontimeout: () => {
TL.error('net', `Request timeout after ${CONFIG.REQUEST_TIMEOUT}ms: ${url}`);
resolve({
status: 0,
ok: false,
data: null,
rawText: '',
headers: null,
error: 'Request timeout'
});
},
});
});
},
@@ -380,6 +415,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
};
// ====== BAF API MODULE ======
const BAF_TASKS = {
NO_TASK: 'no_task',
NO_STEP: 'no_step',
};
const BAF = {
_getHost: () => AppState.getServer()?.url,
@@ -657,37 +702,42 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
// Update overlay content
updateContent: () => {
// Get status display
let statusDisplay = '';
switch (AppSettings.getBotStatus()) {
case AppEnums.BOT_STATUS.IDLE:
statusDisplay = '💤 Idle';
break;
case AppEnums.BOT_STATUS.RUNNING:
statusDisplay = '▶️ Running';
break;
default:
statusDisplay = AppSettings.getBotStatus();
}
try {
// Get status display
let statusDisplay = '';
switch (AppSession.getSessionStatus()) {
case AppEnums.BOT_STATUS.RUNNING:
statusDisplay = '▶️ Running';
break;
case AppEnums.BOT_STATUS.STOP:
statusDisplay = '⏹️ Stop';
break;
case AppEnums.BOT_STATUS.ERROR:
statusDisplay = '❌ Error';
break;
default:
statusDisplay = '❌ Error';
break;
}
// Get server info
const serverLabel = AppState.getServer()?.label || 'Unknown';
const serverConnected = AppState.getServerConnected() ? `🟢 (${AppState.getServerLatency()}ms)` : '🔴';
// Get server info
const serverLabel = AppState.getServer()?.label || 'Unknown';
const serverConnected = AppState.getServerConnected() ? `🟢 (${AppState.getServerLatency()}ms)` : '🔴';
// Get page info
const pageDisplay = AppState.getCurrentPage() || 'unknown';
// Get page info
const pageDisplay = AppState.getCurrentPage() || 'unknown';
// Get login status
const loginStatus = AppState.getIsLoggedIn() ? '✅' : '❌';
// Get login status
const loginStatus = AppState.getIsLoggedIn() ? '✅' : '❌';
// Get SafetyGuard status
const safetyStatus = {
enabled: AppSettings.getSafetyGuard(),
message: AppSettings.getSafetyGuard() ? '✅ Operations Enabled' : '🚨 Operations Blocked'
};
// Get SafetyGuard status
const safetyStatus = {
enabled: AppSettings.getSafetyGuard(),
message: AppSettings.getSafetyGuard() ? '✅ Operations Enabled' : '🚨 Operations Blocked'
};
// Build content
const content = `
// Build content
const content = `
<div style="margin-bottom: 8px;"><strong>BAF Agent Dashboard</strong></div>
<div style="margin-bottom: 4px;">
@@ -697,9 +747,17 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
<span style="color: #6c757d; font-size: 11px;">🆔 Tab: ${AppSession.SESSION_ID.slice(-12)}</span>
</div>
<div style="margin-bottom: 4px;">
<span id="bot-status-toggle-btn" style="color: #007bff; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #007bff; background: rgba(0, 123, 255, 0.1); transition: all 0.2s ease;" title="Click to toggle bot status between idle and running">🤖 Bot Status: ${statusDisplay}</span>
<span id="bot-status-toggle-btn" style="color: #007bff; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #007bff; background: rgba(0, 123, 255, 0.1); transition: all 0.2s ease;" title="Click to toggle bot status">🤖 Bot Status: ${statusDisplay}</span>
</div>
<div style="margin-bottom: 4px;">
<span id="startup-mode-toggle-btn" style="color: #ffc107; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #ffc107; background: rgba(255, 193, 7, 0.1); transition: all 0.2s ease;" title="Click to toggle startup mode between auto and manual">🚀 Startup Mode: ${AppSettings.getBotStartupMode() === AppEnums.BOT_STARTUP_MODE.AUTO ? '🔄 Auto' : '✋ Manual'}</span>
</div>
<div style="margin-bottom: 4px;">
<span style="color: #28a745;">📋 Task: ${AppSession.getCurrentTask() || 'None'}</span>
</div>
<div style="margin-bottom: 4px;">
<span style="color: #17a2b8;">📍 Step: ${AppSession.getCurrentStep() || 'None'}</span>
</div>
<div style="margin-bottom: 4px;">
<span style="color: #fd7e14;">👤 Login: ${loginStatus}</span>
</div>
@@ -710,74 +768,98 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
<span id="server-toggle-btn" style="color: #e83e8c; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #e83e8c; background: rgba(232, 62, 140, 0.1); transition: all 0.2s ease;" title="Click to switch between local and prod servers">🌐 Server: ${serverLabel} ${serverConnected}</span>
</div>
<div style="margin-bottom: 4px;">
<span id="debug-toggle-btn" style="color: ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; background: ${AppSettings.getDebug() ? 'rgba(23, 162, 184, 0.1)' : 'rgba(108, 117, 125, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle debug mode">🐛 Debug: ${AppSettings.getDebug() ? '✔️ ON' : ' OFF'}</span>
<span id="debug-toggle-btn" style="color: ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; background: ${AppSettings.getDebug() ? 'rgba(23, 162, 184, 0.1)' : 'rgba(108, 117, 125, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle debug mode">🐛 Debug: ${AppSettings.getDebug() ? '🔈 ON' : '🔇 OFF'}</span>
</div>
`;
`;
// Update content (excluding position button)
const contentDiv = AppUi.dashboardOverlay.element.querySelector('.baf-content') || document.createElement('div');
contentDiv.className = 'baf-content';
contentDiv.innerHTML = content;
// Update content (excluding position button)
const contentDiv = AppUi.dashboardOverlay.element.querySelector('.baf-content') || document.createElement('div');
contentDiv.className = 'baf-content';
contentDiv.innerHTML = content;
if (!AppUi.dashboardOverlay.element.querySelector('.baf-content')) {
AppUi.dashboardOverlay.element.appendChild(contentDiv);
}
if (!AppUi.dashboardOverlay.element.querySelector('.baf-content')) {
AppUi.dashboardOverlay.element.appendChild(contentDiv);
}
// Add event listener for safety toggle button
const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn');
if (safetyToggleBtn) {
safetyToggleBtn.onclick = () => {
const currentStatus = {
enabled: AppSettings.getSafetyGuard(),
message: AppSettings.getSafetyGuard() ? '✅ Operations Enabled' : '🚨 Operations Blocked'
// Add event listener for safety toggle button
const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn');
if (safetyToggleBtn) {
safetyToggleBtn.onclick = () => {
const currentStatus = {
enabled: AppSettings.getSafetyGuard(),
message: AppSettings.getSafetyGuard() ? '✅ Operations Enabled' : '🚨 Operations Blocked'
};
if (currentStatus.enabled) {
AppSettings.setSafetyGuard(false);
} else {
AppSettings.setSafetyGuard(true);
}
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
if (currentStatus.enabled) {
AppSettings.setSafetyGuard(false);
} else {
AppSettings.setSafetyGuard(true);
}
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
}
}
// Add event listener for debug toggle button
const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn');
if (debugToggleBtn) {
debugToggleBtn.onclick = () => {
const newDebugState = !AppSettings.getDebug();
AppSettings.setDebug(newDebugState);
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
}
// Add event listener for debug toggle button
const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn');
if (debugToggleBtn) {
debugToggleBtn.onclick = () => {
const newDebugState = !AppSettings.getDebug();
AppSettings.setDebug(newDebugState);
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
}
// Add event listener for bot status toggle button
const botStatusToggleBtn = contentDiv.querySelector('#bot-status-toggle-btn');
if (botStatusToggleBtn) {
botStatusToggleBtn.onclick = () => {
const currentBotStatus = AppSettings.getBotStatus();
const newBotStatus = currentBotStatus === AppEnums.BOT_STATUS.IDLE ? AppEnums.BOT_STATUS.RUNNING : AppEnums.BOT_STATUS.IDLE;
AppSettings.setBotStatus(newBotStatus);
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
}
// 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;
// Add event listener for server toggle button
const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn');
if (serverToggleBtn) {
serverToggleBtn.onclick = async () => {
const currentServerType = AppSettings.getServerType();
const newServerType = currentServerType === 'local' ? 'prod' : 'local';
// 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;
}
// Update server type in settings
AppSettings.setServerType(newServerType);
await AppState.update({ server_last_seen: null });
AppSession.setSessionStatus(newBotStatus);
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
}
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
// Add event listener for startup mode toggle button
const startupModeToggleBtn = contentDiv.querySelector('#startup-mode-toggle-btn');
if (startupModeToggleBtn) {
startupModeToggleBtn.onclick = () => {
const currentStartupMode = AppSettings.getBotStartupMode();
const newStartupMode = currentStartupMode === AppEnums.BOT_STARTUP_MODE.AUTO ? AppEnums.BOT_STARTUP_MODE.MANUAL : AppEnums.BOT_STARTUP_MODE.AUTO;
AppSettings.setBotStartupMode(newStartupMode);
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
}
// Add event listener for server toggle button
const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn');
if (serverToggleBtn) {
serverToggleBtn.onclick = async () => {
const currentServerType = AppSettings.getServerType();
const newServerType = currentServerType === 'local' ? 'prod' : 'local';
// Update server type in settings
AppSettings.setServerType(newServerType);
await AppState.update({ server_last_seen: null });
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent();
};
}
} catch (error) {
TL.error('DASHBOARD-OVERLAY', 'Error updating content:', error);
}
},
@@ -875,7 +957,9 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
const AppServices = {
initialize: async () => {
await AppState.initialize();
await AppUi.menu.create();
AppUi.dashboardOverlay.init();
// Setup observers for dashboard overlay updates
@@ -883,9 +967,21 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
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');
}
// Setup interval services
AppServices.initInterval();
AppState.update({ appInitialized: true });
TL.debug('APP-SERVICES', 'AppServices initialized');
},
@@ -910,8 +1006,15 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
},
registerSession: async () => {
const msg = await BAF.register({ session_id: AppSession.SESSION_ID });
AppSession.setSessionToken(msg.data.token);
TL.debug('APP-SERVICES', `Session token: ${AppSession.getSessionToken()}`);
//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 {
AppSession.setSessionBinded(false);
TL.error('APP-SERVICES', `Failed to register session: ${msg.error}`);
}
},
// Setup interval services
@@ -927,15 +1030,20 @@ 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;
},
// ====== HEARTBEAT SYSTEM ======
heartbeat: async () => {
if (!AppSettings.getSafetyGuard()) return null;
if (!AppServices.isReadyToRun()) return;
try {
const status = {
logged_in: AppState.getIsLoggedIn(),
current_page: AppState.getCurrentPage(),
bot_status: AppSettings.getBotStatus(),
bot_status: AppSession.getSessionStatus(),
current_task: AppSession.getCurrentTask(),
current_task_data: AppSession.getCurrentTaskData(),
current_step: AppSession.getCurrentStep(),
@@ -962,7 +1070,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
const data = {
logged_in: AppState.getIsLoggedIn(),
current_page: AppState.getCurrentPage(),
bot_status: AppSettings.getBotStatus(),
bot_status: AppSession.getSessionStatus(),
current_task: AppSession.getCurrentTask(),
current_task_data: AppSession.getCurrentTaskData(),
current_step: AppSession.getCurrentStep(),
@@ -973,16 +1081,35 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
handleTask: (task) => {
TL.debug('APP-SERVICES', `Task: ${JSON.stringify(task, null, 2)}`);
AppSession.setCurrentTask(task.task);
AppSession.setCurrentTaskData(task.data || null);
AppSession.setCurrentStep(task.step || null);
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);
break;
}
},
start: async () => {
while (true) {
const task = await AppServices.getTask();
if (task.ok) {
AppServices.handleTask(task.data);
//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');
}
await TL.sleep(CONFIG.TASK_INTERVAL);
await TL.delay(CONFIG.TASK_INTERVAL);
}
}
};