// API Base URL
const API_BASE_URL = 'https://api.solbotsentinel.com/v1';
// Initialize tooltips and fetch initial data
document.addEventListener('DOMContentLoaded', () => {
// Add tooltips to action buttons
const actionButtons = document.querySelectorAll('[data-action]');
actionButtons.forEach(button => {
const action = button.getAttribute('data-action');
button.setAttribute('data-tooltip', action.charAt(0).toUpperCase() + action.slice(1));
});
// Load initial data
fetchWallets();
fetchPerformanceStats();
// Set up event listeners
setupEventListeners();
});
function setupEventListeners() {
// Add wallet button
document.querySelector('button[data-action="add-wallet"]')?.addEventListener('click', addWallet);
// Copy trade buttons
document.querySelectorAll('button[data-action="copy-trade"]').forEach(btn => {
btn.addEventListener('click', () => {
const wallet = btn.closest('tr').querySelector('td:first-child p').textContent;
startCopyTrading(wallet);
});
});
// Stop trade buttons
document.querySelectorAll('button[data-action="stop-trade"]').forEach(btn => {
btn.addEventListener('click', () => {
const wallet = btn.closest('tr').querySelector('td:first-child p').textContent;
stopCopyTrading(wallet);
});
});
}
async function fetchWallets() {
try {
const response = await fetch(`${API_BASE_URL}/wallets`);
const data = await response.json();
updateWalletTable(data);
} catch (error) {
console.error('Failed to fetch wallets:', error);
showNotification('error', 'Failed to load wallet data');
}
}
async function fetchPerformanceStats() {
try {
const response = await fetch(`${API_BASE_URL}/performance`);
const data = await response.json();
updatePerformanceStats(data);
} catch (error) {
console.error('Failed to fetch performance stats:', error);
showNotification('error', 'Failed to load performance data');
}
}
function updateWalletTable(wallets) {
const tbody = document.querySelector('tbody');
tbody.innerHTML = '';
wallets.forEach(wallet => {
const row = document.createElement('tr');
row.className = 'hover:bg-gray-700 transition';
row.innerHTML = `
${wallet.address.substring(0, 4)}...${wallet.address.substring(wallet.address.length - 4)}
Added ${formatDate(wallet.addedAt)}
|
${wallet.status === 'copying' ? 'Copying' : 'Watching'}
|
${wallet.pnl >= 0 ? '+' : ''}${wallet.pnl.toFixed(2)} |
${wallet.status === 'copying' ?
`` :
``
}
|
`;
tbody.appendChild(row);
});
feather.replace();
}
function updatePerformanceStats(stats) {
document.querySelector('.stats-total-profit').textContent = `+${stats.totalProfit.toFixed(2)}`;
document.querySelector('.stats-total-loss').textContent = `-${Math.abs(stats.totalLoss).toFixed(2)}`;
document.querySelector('.stats-win-rate').textContent = `${stats.winRate.toFixed(1)}%`;
document.querySelector('.stats-active-trades').textContent = stats.activeTrades;
}
async function addWallet() {
const walletInput = document.querySelector('input[placeholder="Enter wallet address"]');
const walletAddress = walletInput.value.trim();
if (!walletAddress || walletAddress.length < 10) {
showNotification('error', 'Please enter a valid wallet address');
return;
}
try {
const response = await fetch(`${API_BASE_URL}/wallets`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ address: walletAddress })
});
if (!response.ok) {
throw new Error(await response.text());
}
walletInput.value = '';
showNotification('success', `Wallet ${walletAddress.substring(0, 6)}... added successfully`);
fetchWallets(); // Refresh wallet list
} catch (error) {
console.error('Failed to add wallet:', error);
showNotification('error', error.message || 'Failed to add wallet');
}
}
async function startCopyTrading(walletAddress) {
try {
const response = await fetch(`${API_BASE_URL}/copy-trade/start`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ address: walletAddress })
});
if (!response.ok) {
throw new Error(await response.text());
}
showNotification('success', `Started copy trading for wallet ${walletAddress.substring(0, 6)}...`);
fetchWallets(); // Refresh wallet list
fetchPerformanceStats(); // Refresh stats
} catch (error) {
console.error('Failed to start copy trading:', error);
showNotification('error', error.message || 'Failed to start copy trading');
}
}
async function stopCopyTrading(walletAddress) {
try {
const response = await fetch(`${API_BASE_URL}/copy-trade/stop`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ address: walletAddress })
});
if (!response.ok) {
throw new Error(await response.text());
}
showNotification('success', `Stopped copy trading for wallet ${walletAddress.substring(0, 6)}...`);
fetchWallets(); // Refresh wallet list
fetchPerformanceStats(); // Refresh stats
} catch (error) {
console.error('Failed to stop copy trading:', error);
showNotification('error', error.message || 'Failed to stop copy trading');
}
}
function showNotification(type, message) {
const notification = document.createElement('div');
notification.className = `fixed top-4 right-4 p-4 rounded-lg shadow-lg z-50 transform transition-all duration-300 ${type === 'error' ? 'bg-red-500' : 'bg-green-500'}`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => {
notification.style.transform = 'translateX(200%)';
setTimeout(() => notification.remove(), 300);
}, 3000);
}
function formatDate(timestamp) {
const now = new Date();
const date = new Date(timestamp);
const diffInDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));
if (diffInDays === 0) return 'today';
if (diffInDays === 1) return 'yesterday';
if (diffInDays < 7) return `${diffInDays} days ago`;
if (diffInDays < 30) return `${Math.floor(diffInDays/7)} weeks ago`;
return `${Math.floor(diffInDays/30)} months ago`;
}