Compare commits
4
Commits
48c7c25674
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1423b63c03 | ||
|
|
d2051afab6 | ||
|
|
42950c77cc | ||
|
|
a5325631d0 |
+528
-89
@@ -30,39 +30,96 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
|
|
||||||
const uuid = () => ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
|
const uuid = () => ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
|
||||||
|
|
||||||
const KEYS = {
|
const SESSION_STORAGE_KEYS = {
|
||||||
SESSION_ID: 'aRah9OhHeijee6sho3baequu9phoovah',
|
SESSION_ID: 'aRah9OhHeijee6sho3baequu9phoovah',
|
||||||
|
SESSION_BINDED: 'Oos2uoth2thae8Ir8iakahj1OohaMahb',
|
||||||
SESSION_TOKEN: 'ThiegiecohViuZ1Iecio7gahphiechub',
|
SESSION_TOKEN: 'ThiegiecohViuZ1Iecio7gahphiechub',
|
||||||
|
SESSION_INITIALIZED: 'iR4choo2Ieg2ew0ogheeyaer8Aisheet',
|
||||||
AGENT_TOKEN: 'baf-agent-token',
|
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(KEYS.SESSION_ID)) {
|
|
||||||
sessionStorage.setItem(KEYS.SESSION_ID, uuid());
|
if (!sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID)) {
|
||||||
|
sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_ID, uuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== CONFIGURATION ======
|
// ====== CONFIGURATION ======
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
HEARTBEAT_INTERVAL: 10000,
|
HEARTBEAT_INTERVAL: 10_000, // Send heartbeat every 10 seconds
|
||||||
DASHBOARD_UPDATE_INTERVAL: 500, // Update dashboard overlay every 0.5 seconds
|
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: {
|
SERVERS: {
|
||||||
local: { label: '🏠 Local', url: 'http://localhost:3000' },
|
local: { label: '🏠 Local', url: 'http://localhost:3000' },
|
||||||
prod: { label: '🌐 Prod', url: 'https://baf.thuanle.me' },
|
prod: { label: '🌐 Prod', url: 'https://baf.thuanle.me' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const AppSession = {
|
const AppSession = {
|
||||||
SESSION_ID: sessionStorage.getItem(KEYS.SESSION_ID),
|
SESSION_ID: sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID),
|
||||||
|
|
||||||
getSessionToken: () => sessionStorage.getItem(KEYS.SESSION_TOKEN),
|
getSessionBinded: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_BINDED) === 'true',
|
||||||
setSessionToken: token => sessionStorage.setItem(KEYS.SESSION_TOKEN, token),
|
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),
|
||||||
|
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),
|
||||||
|
setCurrentTask: task => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK, task),
|
||||||
|
|
||||||
|
getCurrentTaskData: () => {
|
||||||
|
const data = sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK_DATA);
|
||||||
|
return data ? JSON.parse(data) : null;
|
||||||
|
},
|
||||||
|
setCurrentTaskData: data => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK_DATA, JSON.stringify(data)),
|
||||||
|
|
||||||
|
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 ======
|
// ====== APP ENUMS ======
|
||||||
const AppEnums = {
|
const AppEnums = {
|
||||||
BOT_STATUS: {
|
BOT_STATUS: {
|
||||||
IDLE: 'idle',
|
INITIALIZING: 'initializing',
|
||||||
RUNNING: 'running',
|
STOP: 'stop',
|
||||||
|
PAUSE: 'pause',
|
||||||
|
WAITING_FOR_TASK: 'waiting_for_task',
|
||||||
|
PERFORMING_TASK: 'performing_task',
|
||||||
|
ERROR: 'error',
|
||||||
|
},
|
||||||
|
BOT_STARTUP_MODE: {
|
||||||
|
AUTO: 'auto',
|
||||||
|
MANUAL: 'manual',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -82,14 +139,9 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
current_page: null, // Trang hiện tại (detected từ URL)
|
current_page: null, // Trang hiện tại (detected từ URL)
|
||||||
is_logged_in: false, // Trạng thái đăng nhập Binance
|
is_logged_in: false, // Trạng thái đăng nhập Binance
|
||||||
|
|
||||||
// UI state - Trạng thái UI
|
|
||||||
is_loading: false, // Đang loading
|
|
||||||
error_message: null, // Thông báo lỗi
|
|
||||||
|
|
||||||
// Session flags - Flags cho session hiện tại (reset khi reload)
|
// Session flags - Flags cho session hiện tại (reset khi reload)
|
||||||
menuCreated: false, // Menu đã được tạo
|
menuCreated: false, // Menu đã được tạo
|
||||||
popupInitialized: false, // Popup đã được khởi 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
|
this.observers = new Map(); // Observer pattern cho state changes
|
||||||
@@ -112,7 +164,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
current_page: currentPage,
|
current_page: currentPage,
|
||||||
});
|
});
|
||||||
|
|
||||||
TL.log('APP-STATE', 'AppState initialized');
|
TL.debug('APP-STATE', 'AppState initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,10 +190,8 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
|
|
||||||
getCurrentPage() { return this.data.current_page; }
|
getCurrentPage() { return this.data.current_page; }
|
||||||
getIsLoggedIn() { return this.data.is_logged_in; }
|
getIsLoggedIn() { return this.data.is_logged_in; }
|
||||||
getIsLoading() { return this.data.is_loading; }
|
|
||||||
getMenuCreated() { return this.data.menuCreated; }
|
getMenuCreated() { return this.data.menuCreated; }
|
||||||
getPopupInitialized() { return this.data.popupInitialized; }
|
getPopupInitialized() { return this.data.popupInitialized; }
|
||||||
getAppInitialized() { return this.data.appInitialized; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cập nhật state với partial update
|
* Cập nhật state với partial update
|
||||||
@@ -215,7 +265,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
const AppSettings = {
|
const AppSettings = {
|
||||||
key_agent_token: 'baf-agent-token',
|
key_agent_token: 'baf-agent-token',
|
||||||
key_server_type: 'baf-server-type',
|
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_position: 'baf-popup-position',
|
||||||
key_popup_visible: 'baf-popup-visible',
|
key_popup_visible: 'baf-popup-visible',
|
||||||
key_debug: 'baf-debug',
|
key_debug: 'baf-debug',
|
||||||
@@ -231,8 +281,8 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
AppState.update({ server_last_seen: null });
|
AppState.update({ server_last_seen: null });
|
||||||
},
|
},
|
||||||
|
|
||||||
getBotStatus: () => GM_getValue(AppSettings.key_bot_status, AppEnums.BOT_STATUS.IDLE),
|
getBotStartupMode: () => GM_getValue(AppSettings.key_bot_startup_mode, AppEnums.BOT_STARTUP_MODE.MANUAL),
|
||||||
setBotStatus: (status) => GM_setValue(AppSettings.key_bot_status, status),
|
setBotStartupMode: (mode) => GM_setValue(AppSettings.key_bot_startup_mode, mode),
|
||||||
|
|
||||||
// Popup configuration
|
// Popup configuration
|
||||||
getPopupPosition: () => GM_getValue(AppSettings.key_popup_position, 4),
|
getPopupPosition: () => GM_getValue(AppSettings.key_popup_position, 4),
|
||||||
@@ -258,10 +308,11 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
* TL - Common utilities cho logging, notifications, và DOM helpers
|
* TL - Common utilities cho logging, notifications, và DOM helpers
|
||||||
*/
|
*/
|
||||||
const TL = {
|
const TL = {
|
||||||
debug: (tag, msg, ...args) => AppSettings.getDebug() && GM_log(`[TL] [${tag}]\n${msg}`, ...args),
|
debug: (tag, msg, ...args) => AppSettings.getDebug() && GM_log(`[TL] [DEBUG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args),
|
||||||
log: (tag, msg, ...args) => GM_log(`[TL] [${tag}]\n${msg}`, ...args),
|
milestone: (tag, msg, ...args) => CONFIG.DEBUG_MILESTONE && GM_log(`[TL] [MILESTONE] [${new Date().toLocaleString()}] [${tag}] 🎯\n${msg}`, ...args),
|
||||||
warn: (tag, msg, ...args) => GM_log(`[TL] [WARN] [${tag}] ⚠️\n${msg}`, ...args),
|
log: (tag, msg, ...args) => GM_log(`[TL] [LOG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args),
|
||||||
error: (tag, msg, ...args) => GM_log(`[TL] [ERROR] [${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),
|
||||||
|
|
||||||
noti: (title, text, timeout = 2500) => {
|
noti: (title, text, timeout = 2500) => {
|
||||||
if (typeof GM_notification === 'function') {
|
if (typeof GM_notification === 'function') {
|
||||||
@@ -327,7 +378,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
* Navigate to URL với option forceReload
|
* Navigate to URL với option forceReload
|
||||||
* @param {string} url - URL cần navigate
|
* @param {string} url - URL cần navigate
|
||||||
*/
|
*/
|
||||||
navigate: (url) => {
|
navigateTo: (url) => {
|
||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -346,6 +397,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
method: (init.method || 'GET').toUpperCase(),
|
method: (init.method || 'GET').toUpperCase(),
|
||||||
headers: headersToObject(init.headers),
|
headers: headersToObject(init.headers),
|
||||||
data: init.body,
|
data: init.body,
|
||||||
|
timeout: CONFIG.REQUEST_TIMEOUT,
|
||||||
onload: (resp) => {
|
onload: (resp) => {
|
||||||
const text = resp.responseText || '';
|
const text = resp.responseText || '';
|
||||||
let data = text;
|
let data = text;
|
||||||
@@ -360,8 +412,28 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
headers: null
|
headers: null
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onerror: reject,
|
onerror: (error) => {
|
||||||
ontimeout: () => reject(new Error('GM_xmlhttpRequest timeout')),
|
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'
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -369,6 +441,21 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ====== BAF API MODULE ======
|
// ====== BAF API MODULE ======
|
||||||
|
|
||||||
|
|
||||||
|
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 = {
|
const BAF = {
|
||||||
_getHost: () => AppState.getServer()?.url,
|
_getHost: () => AppState.getServer()?.url,
|
||||||
|
|
||||||
@@ -574,7 +661,10 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
|
|
||||||
// Create dashboard overlay element
|
// Create dashboard overlay element
|
||||||
create: () => {
|
create: () => {
|
||||||
|
|
||||||
|
|
||||||
if (AppUi.dashboardOverlay.element) {
|
if (AppUi.dashboardOverlay.element) {
|
||||||
|
|
||||||
document.body.removeChild(AppUi.dashboardOverlay.element);
|
document.body.removeChild(AppUi.dashboardOverlay.element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,6 +689,36 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
user-select: none;
|
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
|
// Add position toggle button
|
||||||
const positionBtn = document.createElement('div');
|
const positionBtn = document.createElement('div');
|
||||||
positionBtn.style.cssText = `
|
positionBtn.style.cssText = `
|
||||||
@@ -623,15 +743,18 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
positionBtn.addEventListener('click', () => {
|
positionBtn.addEventListener('click', () => {
|
||||||
const newPosition = (AppSettings.getPopupPosition() % 4) + 1;
|
const newPosition = (AppSettings.getPopupPosition() % 4) + 1;
|
||||||
AppSettings.setPopupPosition(newPosition);
|
AppSettings.setPopupPosition(newPosition);
|
||||||
AppUi.statusOverlay.updatePosition();
|
AppUi.dashboardOverlay.updatePosition();
|
||||||
});
|
});
|
||||||
TL.dom.setHover(positionBtn, 'mouseenter', { scale: 1.5, background: '#0056b3' });
|
TL.dom.setHover(positionBtn, 'mouseenter', { scale: 1.5, background: '#0056b3' });
|
||||||
TL.dom.setHover(positionBtn, 'mouseleave', { scale: 1, background: '#007bff' });
|
TL.dom.setHover(positionBtn, 'mouseleave', { scale: 1, background: '#007bff' });
|
||||||
overlay.appendChild(positionBtn);
|
overlay.appendChild(positionBtn);
|
||||||
|
|
||||||
|
|
||||||
AppUi.dashboardOverlay.element = overlay;
|
AppUi.dashboardOverlay.element = overlay;
|
||||||
|
|
||||||
document.body.appendChild(overlay);
|
document.body.appendChild(overlay);
|
||||||
|
|
||||||
|
|
||||||
return overlay;
|
return overlay;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -646,17 +769,39 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
|
|
||||||
// Update overlay content
|
// Update overlay content
|
||||||
updateContent: () => {
|
updateContent: () => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!AppUi.dashboardOverlay.element) {
|
||||||
|
AppUi.dashboardOverlay.create();
|
||||||
|
}
|
||||||
// Get status display
|
// Get status display
|
||||||
let statusDisplay = '';
|
let statusDisplay = '';
|
||||||
switch (AppSettings.getBotStatus()) {
|
const currentStatus = AppSession.getSessionStatus();
|
||||||
case AppEnums.BOT_STATUS.IDLE:
|
|
||||||
statusDisplay = '💤 Idle';
|
switch (currentStatus) {
|
||||||
|
case AppEnums.BOT_STATUS.INITIALIZING:
|
||||||
|
statusDisplay = '🔄 Initializing';
|
||||||
break;
|
break;
|
||||||
case AppEnums.BOT_STATUS.RUNNING:
|
case AppEnums.BOT_STATUS.STOP:
|
||||||
statusDisplay = '▶️ Running';
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
statusDisplay = AppSettings.getBotStatus();
|
statusDisplay = '❓ Unknown';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get server info
|
// Get server info
|
||||||
@@ -680,15 +825,23 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
<div style="margin-bottom: 8px;"><strong>BAF Agent Dashboard</strong></div>
|
<div style="margin-bottom: 8px;"><strong>BAF Agent Dashboard</strong></div>
|
||||||
|
|
||||||
<div style="margin-bottom: 4px;">
|
<div style="margin-bottom: 4px;">
|
||||||
<span id="safety-toggle-btn" style="color: ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; background: ${safetyStatus.enabled ? 'rgba(40, 167, 69, 0.1)' : 'rgba(220, 53, 69, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle safety status">🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'}</span>
|
<span id="safety-toggle-btn-AithaiG2" style="color: ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; background: ${safetyStatus.enabled ? 'rgba(40, 167, 69, 0.1)' : 'rgba(220, 53, 69, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle safety status">🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-bottom: 4px;">
|
<div style="margin-bottom: 4px;">
|
||||||
<span style="color: #6c757d; font-size: 11px;">🆔 Tab: ${AppSession.SESSION_ID.slice(-12)}</span>
|
<span style="color: #6c757d; font-size: 11px;">🆔 Tab: ${AppSession.SESSION_ID.slice(-12)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-bottom: 4px;">
|
<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 style="color: #007bff; padding: 2px 4px; background: rgba(0, 123, 255, 0.1);" title="Current bot status">🤖 Bot Status: ${statusDisplay}</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-bottom: 4px;">
|
||||||
|
<span id="startup-mode-toggle-btn-tha9ieCa" 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>
|
||||||
|
|
||||||
<div style="margin-bottom: 4px;">
|
<div style="margin-bottom: 4px;">
|
||||||
<span style="color: #fd7e14;">👤 Login: ${loginStatus}</span>
|
<span style="color: #fd7e14;">👤 Login: ${loginStatus}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -696,14 +849,32 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
<span style="color: #6f42c1;">Page: ${pageDisplay}</span>
|
<span style="color: #6f42c1;">Page: ${pageDisplay}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-bottom: 4px;">
|
<div style="margin-bottom: 4px;">
|
||||||
<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>
|
<span id="server-toggle-btn-Youx4pho" 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>
|
||||||
<div style="margin-bottom: 4px;">
|
<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-Tai5guto" 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>
|
||||||
|
<div style="margin-bottom: 4px;">
|
||||||
|
<span style="color: ${CONFIG.DEBUG_MILESTONE ? '#28a745' : '#6c757d'}; padding: 2px 4px; border-radius: 3px; border: 1px solid ${CONFIG.DEBUG_MILESTONE ? '#28a745' : '#6c757d'}; background: ${CONFIG.DEBUG_MILESTONE ? 'rgba(40, 167, 69, 0.1)' : 'rgba(108, 117, 125, 0.1)'};" title="Milestone debug mode (configured in CONFIG)">🎯 Milestone: ${CONFIG.DEBUG_MILESTONE ? '🔈 ON' : '🔇 OFF'}</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px; border-top: 1px solid rgba(255, 255, 255, 0.2); padding-top: 8px;">
|
||||||
|
<div style="text-align: center; margin-bottom: 8px;">
|
||||||
|
<span id="timer-display-ohr1Youj" style="color: #20c997; font-family: 'Courier New', monospace; font-size: 16px; font-weight: bold; padding: 4px 8px; border-radius: 4px; border: 1px solid #20c997; background: rgba(32, 201, 151, 0.1);" title="Session timer">⏱️ ${AppServices.Timer.getDisplay()}</span>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; gap: 4px; justify-content: center;">
|
||||||
|
<span id="play-btn-uPha3Mah" style="color: #28a745; cursor: pointer; padding: 4px 8px; border-radius: 4px; border: 1px solid #28a745; background: ${currentStatus === AppEnums.BOT_STATUS.WAITING_FOR_TASK || currentStatus === AppEnums.BOT_STATUS.PERFORMING_TASK ? 'rgba(40, 167, 69, 0.3)' : 'rgba(40, 167, 69, 0.1)'}; transition: all 0.2s ease; font-size: 14px;" title="Play - Start waiting for tasks">▶️</span>
|
||||||
|
<span id="pause-btn-Gai2quie" style="color: #ffc107; cursor: pointer; padding: 4px 8px; border-radius: 4px; border: 1px solid #ffc107; background: ${currentStatus === AppEnums.BOT_STATUS.PAUSE ? 'rgba(255, 193, 7, 0.3)' : 'rgba(255, 193, 7, 0.1)'}; transition: all 0.2s ease; font-size: 14px;" title="Pause - Stop but keep current task">⏸️</span>
|
||||||
|
<span id="stop-btn-jooK6che" style="color: #dc3545; cursor: pointer; padding: 4px 8px; border-radius: 4px; border: 1px solid #dc3545; background: ${currentStatus === AppEnums.BOT_STATUS.STOP || currentStatus === AppEnums.BOT_STATUS.ERROR ? 'rgba(220, 53, 69, 0.3)' : 'rgba(220, 53, 69, 0.1)'}; transition: all 0.2s ease; font-size: 14px;" title="Stop - Clear task and stop">⏹️</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Update content (excluding position button)
|
// 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');
|
const contentDiv = AppUi.dashboardOverlay.element.querySelector('.baf-content') || document.createElement('div');
|
||||||
contentDiv.className = 'baf-content';
|
contentDiv.className = 'baf-content';
|
||||||
contentDiv.innerHTML = content;
|
contentDiv.innerHTML = content;
|
||||||
@@ -713,7 +884,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add event listener for safety toggle button
|
// Add event listener for safety toggle button
|
||||||
const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn');
|
const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn-AithaiG2');
|
||||||
if (safetyToggleBtn) {
|
if (safetyToggleBtn) {
|
||||||
safetyToggleBtn.onclick = () => {
|
safetyToggleBtn.onclick = () => {
|
||||||
const currentStatus = {
|
const currentStatus = {
|
||||||
@@ -731,7 +902,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add event listener for debug toggle button
|
// Add event listener for debug toggle button
|
||||||
const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn');
|
const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn-Tai5guto');
|
||||||
if (debugToggleBtn) {
|
if (debugToggleBtn) {
|
||||||
debugToggleBtn.onclick = () => {
|
debugToggleBtn.onclick = () => {
|
||||||
const newDebugState = !AppSettings.getDebug();
|
const newDebugState = !AppSettings.getDebug();
|
||||||
@@ -741,20 +912,59 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add event listener for bot status toggle button
|
// Add event listeners for control buttons
|
||||||
const botStatusToggleBtn = contentDiv.querySelector('#bot-status-toggle-btn');
|
const playBtn = contentDiv.querySelector('#play-btn-uPha3Mah');
|
||||||
if (botStatusToggleBtn) {
|
if (playBtn) {
|
||||||
botStatusToggleBtn.onclick = () => {
|
playBtn.onclick = () => {
|
||||||
const currentBotStatus = AppSettings.getBotStatus();
|
AppServices.Status.play();
|
||||||
const newBotStatus = currentBotStatus === AppEnums.BOT_STATUS.IDLE ? AppEnums.BOT_STATUS.RUNNING : AppEnums.BOT_STATUS.IDLE;
|
AppUi.dashboardOverlay.updateContent();
|
||||||
AppSettings.setBotStatus(newBotStatus);
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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-tha9ieCa');
|
||||||
|
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
|
// Update the content to reflect the change
|
||||||
AppUi.dashboardOverlay.updateContent();
|
AppUi.dashboardOverlay.updateContent();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add event listener for server toggle button
|
// Add event listener for server toggle button
|
||||||
const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn');
|
const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn-Youx4pho');
|
||||||
if (serverToggleBtn) {
|
if (serverToggleBtn) {
|
||||||
serverToggleBtn.onclick = async () => {
|
serverToggleBtn.onclick = async () => {
|
||||||
const currentServerType = AppSettings.getServerType();
|
const currentServerType = AppSettings.getServerType();
|
||||||
@@ -768,6 +978,9 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
AppUi.dashboardOverlay.updateContent();
|
AppUi.dashboardOverlay.updateContent();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
TL.error('DASHBOARD-OVERLAY', 'Error updating content:', error);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Show dashboard overlay
|
// Show dashboard overlay
|
||||||
@@ -801,8 +1014,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
|
|
||||||
// Initialize dashboard overlay
|
// Initialize dashboard overlay
|
||||||
init: () => {
|
init: () => {
|
||||||
if (AppSettings.getPopupVisible()) {
|
try {
|
||||||
|
const popupVisible = AppSettings.getPopupVisible();
|
||||||
|
|
||||||
|
if (popupVisible) {
|
||||||
AppUi.dashboardOverlay.show();
|
AppUi.dashboardOverlay.show();
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
TL.error('DASHBOARD-OVERLAY', '1.4.4. Error initializing dashboard overlay:', error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -851,64 +1072,98 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
GM_registerMenuCommand("👁️ Toggle Popup", () => {
|
GM_registerMenuCommand("👁️ Toggle Popup", () => {
|
||||||
AppUi.dashboardOverlay.toggle();
|
AppUi.dashboardOverlay.toggle();
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
TL.error('MENU', 'Failed to create menu:', error);
|
TL.error('MENU', '1.3.5. Failed to create menu:', error);
|
||||||
throw 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 ======
|
// ====== APP SERVICE ======
|
||||||
const AppServices = {
|
const AppServices = {
|
||||||
initialize: async () => {
|
initialize: async () => {
|
||||||
|
try {
|
||||||
await AppState.initialize();
|
await AppState.initialize();
|
||||||
|
await AppSession.initialize();
|
||||||
|
|
||||||
|
// Khởi tạo timer
|
||||||
|
AppServices.Timer.initialize();
|
||||||
|
|
||||||
await AppUi.menu.create();
|
await AppUi.menu.create();
|
||||||
AppUi.dashboardOverlay.init();
|
AppUi.dashboardOverlay.init();
|
||||||
|
|
||||||
// Setup observers for dashboard overlay updates
|
|
||||||
AppServices.initObservers();
|
|
||||||
|
|
||||||
await AppServices.registerSession();
|
await AppServices.registerSession();
|
||||||
|
|
||||||
// Setup interval services
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AppServices.initInterval();
|
AppServices.initInterval();
|
||||||
|
} catch (error) {
|
||||||
TL.log('APP-SERVICES', 'AppServices initialized');
|
TL.error('APP-SERVICES', 'Error during initialization:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
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 () => {
|
registerSession: async () => {
|
||||||
|
try {
|
||||||
const msg = await BAF.register({ session_id: AppSession.SESSION_ID });
|
const msg = await BAF.register({ session_id: AppSession.SESSION_ID });
|
||||||
|
|
||||||
|
if (msg.ok) {
|
||||||
AppSession.setSessionToken(msg.data.token);
|
AppSession.setSessionToken(msg.data.token);
|
||||||
TL.log('APP-SERVICES', `Session token: ${AppSession.getSessionToken()}`);
|
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);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Setup interval services
|
|
||||||
initInterval: () => {
|
initInterval: () => {
|
||||||
|
try {
|
||||||
setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL);
|
setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL);
|
||||||
setInterval(() => AppUi.dashboardOverlay.updateContent(), CONFIG.DASHBOARD_UPDATE_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: () => {
|
isConnected: () => {
|
||||||
@@ -916,18 +1171,100 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
return serverLastSeen && new Date() - serverLastSeen < 60000;
|
return serverLastSeen && new Date() - serverLastSeen < 60000;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isReadyToRun: () => {
|
||||||
|
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 ======
|
// ====== HEARTBEAT SYSTEM ======
|
||||||
heartbeat: async () => {
|
heartbeat: async () => {
|
||||||
if (!AppSettings.getSafetyGuard()) return null;
|
if (!AppServices.isReadyToRun()) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const status = {
|
const status = {
|
||||||
logged_in: AppState.getIsLoggedIn(),
|
logged_in: AppState.getIsLoggedIn(),
|
||||||
current_page: AppState.getCurrentPage(),
|
current_page: AppState.getCurrentPage(),
|
||||||
bot_status: AppSettings.getBotStatus(),
|
bot_status: AppSession.getSessionStatus(),
|
||||||
current_task: null, // TODO: Add to AppState if needed
|
current_task: AppSession.getCurrentTask(),
|
||||||
current_task_data: null, // TODO: Add to AppState if needed
|
current_task_data: AppSession.getCurrentTaskData(),
|
||||||
current_step: null, // TODO: Add to AppState if needed
|
current_step: AppSession.getCurrentStep(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TL.debug(`HEARTBEAT`, `${JSON.stringify(status, null, 2)}`);
|
// TL.debug(`HEARTBEAT`, `${JSON.stringify(status, null, 2)}`);
|
||||||
@@ -945,15 +1282,117 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
|
|||||||
TL.error('HEARTBEAT', e.message);
|
TL.error('HEARTBEAT', e.message);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleNewTask: async () => {
|
||||||
|
const data = {
|
||||||
|
logged_in: AppState.getIsLoggedIn(),
|
||||||
|
current_page: AppState.getCurrentPage(),
|
||||||
|
bot_status: AppSession.getSessionStatus(),
|
||||||
|
current_task: AppSession.getCurrentTask(),
|
||||||
|
current_task_data: AppSession.getCurrentTaskData(),
|
||||||
|
current_step: AppSession.getCurrentStep(),
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resumeTask: async () => {
|
||||||
|
TL.debug('APP-SERVICES', 'Resume task');
|
||||||
|
|
||||||
|
const task = AppSession.getCurrentTask();
|
||||||
|
const data = AppSession.getCurrentTaskData();
|
||||||
|
const step = AppSession.getCurrentStep();
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start the application
|
// Start the application
|
||||||
try {
|
try {
|
||||||
|
|
||||||
await AppServices.initialize();
|
await AppServices.initialize();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
TL.error('MAIN', 'Failed to initialize app:', error);
|
TL.error('MAIN', 'Failed to initialize app:', error);
|
||||||
|
TL.error('MAIN', 'Error stack:', error.stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
TL.log('MAIN', 'App started');
|
TL.log('MAIN', 'App started');
|
||||||
|
await AppServices.start();
|
||||||
})();
|
})();
|
||||||
Reference in New Issue
Block a user