Flatlogic Bot c255bd35c4 1
2025-12-05 05:27:33 +00:00

192 lines
7.3 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
// Theme Toggle
const themeToggle = document.getElementById('theme-toggle');
if (themeToggle) {
const currentTheme = localStorage.getItem('theme') || 'dark-theme';
document.body.classList.add(currentTheme);
themeToggle.textContent = currentTheme === 'dark-theme' ? 'Light Mode' : 'Dark Mode';
themeToggle.addEventListener('click', () => {
if (document.body.classList.contains('dark-theme')) {
document.body.classList.replace('dark-theme', 'light-theme');
localStorage.setItem('theme', 'light-theme');
themeToggle.textContent = 'Dark Mode';
} else {
document.body.classList.replace('light-theme', 'dark-theme');
localStorage.setItem('theme', 'dark-theme');
themeToggle.textContent = 'Light Mode';
}
});
}
// Leverage Slider
const leverageSlider = document.getElementById('leverage');
const leverageValue = document.getElementById('leverage-value');
if (leverageSlider && leverageValue) {
leverageValue.textContent = leverageSlider.value;
leverageSlider.addEventListener('input', () => {
leverageValue.textContent = leverageSlider.value;
});
}
// API Key Modal
const apiKeyModal = document.getElementById('api-key-modal');
const apiKeyModalBtn = document.getElementById('api-key-modal-btn');
if (apiKeyModal && apiKeyModalBtn) {
const closeBtn = apiKeyModal.querySelector('.close-btn');
const apiKeyForm = document.getElementById('api-key-form');
const apiKeyStatus = document.getElementById('api-key-status');
apiKeyModalBtn.addEventListener('click', () => {
apiKeyModal.style.display = 'flex';
});
if (closeBtn) {
closeBtn.addEventListener('click', () => {
apiKeyModal.style.display = 'none';
});
}
window.addEventListener('click', (event) => {
if (event.target == apiKeyModal) {
apiKeyModal.style.display = 'none';
}
});
if (apiKeyForm) {
apiKeyForm.addEventListener('submit', (event) => {
event.preventDefault();
const apiKey = document.getElementById('api-key').value;
const apiSecret = document.getElementById('api-secret').value;
fetch('api/save_key.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ apiKey, apiSecret }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
apiKeyStatus.textContent = 'API Key saved successfully!';
apiKeyStatus.style.color = 'var(--success)';
setTimeout(() => { apiKeyModal.style.display = 'none'; }, 2000);
} else {
apiKeyStatus.textContent = `Error: ${data.error}`;
apiKeyStatus.style.color = 'var(--danger)';
}
})
.catch(error => {
apiKeyStatus.textContent = `Error: ${error.message}`;
apiKeyStatus.style.color = 'var(--danger)';
});
});
}
}
// User State Button
const getUserStateButton = document.getElementById('getUserStateButton');
const userStateContainer = document.getElementById('user-state-container');
const userStateData = document.getElementById('user-state-data');
if (getUserStateButton && userStateContainer && userStateData) {
getUserStateButton.addEventListener('click', () => {
fetch('api/proxy.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'clearinghouseState' }),
})
.then(response => {
if (response.status === 401) {
alert('API Key not configured. Please add it via the API Key button.');
return null;
}
return response.json();
})
.then(data => {
if (data) {
userStateData.textContent = JSON.stringify(data, null, 2);
userStateContainer.style.display = 'block';
}
})
.catch(error => {
console.error('Error fetching user state:', error);
alert('An error occurred while fetching user state.');
});
});
}
// WebSocket Connection
connectWebSocket();
});
function connectWebSocket() {
const ws = new WebSocket('wss://api.hyperliquid.xyz/ws');
ws.onopen = () => {
console.log('Connected to Hyperliquid WebSocket API');
ws.send(JSON.stringify({ "method": "subscribe", "subscription": { "type": "l2Book", "coin": "ETH" } }));
ws.send(JSON.stringify({ "method": "subscribe", "subscription": { "type": "trades", "coin": "ETH" } }));
};
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.channel === 'l2Book' && response.data) {
updateOrderBook(response.data);
}
if (response.channel === 'trades' && response.data) {
updateTradeFeed(response.data);
}
};
ws.onerror = (error) => {
console.error('WebSocket Error:', error);
};
ws.onclose = () => {
console.log('WebSocket connection closed. Reconnecting...');
setTimeout(connectWebSocket, 5000);
};
}
function updateOrderBook(data) {
const orderBookData = document.getElementById('order-book-data');
if (!orderBookData) return;
const asks = data.levels[1].slice(0, 8).reverse();
const bids = data.levels[0].slice(0, 8);
let html = '<div class="order-book-column">';
html += '<div class="order-book-header"><div>Price (USD)</div><div>Size</div></div>';
asks.forEach(ask => {
html += `<div class="ask-row"><div>${parseFloat(ask.px).toFixed(2)}</div><div>${parseFloat(ask.sz).toFixed(4)}</div></div>`;
});
bids.forEach(bid => {
html += `<div class="bid-row"><div>${parseFloat(bid.px).toFixed(2)}</div><div>${parseFloat(bid.sz).toFixed(4)}</div></div>`;
});
html += '</div>';
orderBookData.innerHTML = html;
}
function updateTradeFeed(trades) {
const tradeFeedData = document.getElementById('trade-feed-data');
if (!tradeFeedData) return;
const maxTrades = 15;
trades.forEach(trade => {
const tradeElement = document.createElement('div');
tradeElement.className = `trade-row ${trade.side === 'B' ? 'buy' : 'sell'}`;
const time = new Date(trade.time).toLocaleTimeString();
const price = parseFloat(trade.px).toFixed(2);
const size = parseFloat(trade.sz).toFixed(4);
tradeElement.innerHTML = `<div>${price}</div><div>${size}</div><div>${time}</div>`;
tradeFeedData.prepend(tradeElement);
});
while (tradeFeedData.children.length > maxTrades) {
tradeFeedData.removeChild(tradeFeedData.lastChild);
}
}