Spaces:
Runtime error
Runtime error
Update index.html
Browse files- index.html +20 -61
index.html
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
-
<meta name="viewport" content="width=1024">
|
6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
<title>Nakhoda4X Pro - Portfolio Dashboard</title>
|
8 |
<script src="https://cdn.tailwindcss.com"></script>
|
@@ -25,33 +25,13 @@
|
|
25 |
}
|
26 |
</script>
|
27 |
<style>
|
28 |
-
.trading-card:hover {
|
29 |
-
|
30 |
-
|
31 |
-
}
|
32 |
-
|
33 |
-
|
34 |
-
}
|
35 |
-
@keyframes pulse {
|
36 |
-
0%, 100% { opacity: 1; }
|
37 |
-
50% { opacity: 0.5; }
|
38 |
-
}
|
39 |
-
.coin-animation {
|
40 |
-
animation: float 3s ease-in-out infinite;
|
41 |
-
}
|
42 |
-
@keyframes float {
|
43 |
-
0% { transform: translateY(0px); }
|
44 |
-
50% { transform: translateY(-10px); }
|
45 |
-
100% { transform: translateY(0px); }
|
46 |
-
}
|
47 |
-
.api-form {
|
48 |
-
max-height: 0;
|
49 |
-
overflow: hidden;
|
50 |
-
transition: max-height 0.3s ease-in-out;
|
51 |
-
}
|
52 |
-
.api-form.open {
|
53 |
-
max-height: 200px;
|
54 |
-
}
|
55 |
</style>
|
56 |
</head>
|
57 |
<body class="bg-gray-100 dark:bg-darkBg transition-colors duration-300">
|
@@ -295,7 +275,7 @@
|
|
295 |
// API Configuration
|
296 |
let API_KEY = localStorage.getItem('bingxApiKey') || '';
|
297 |
let API_SECRET = localStorage.getItem('bingxApiSecret') || '';
|
298 |
-
const
|
299 |
|
300 |
// Toggle API Form
|
301 |
const toggleApiFormBtn = document.getElementById('toggle-api-form');
|
@@ -322,55 +302,34 @@
|
|
322 |
}
|
323 |
});
|
324 |
|
325 |
-
//
|
326 |
-
function
|
327 |
-
return CryptoJS.HmacSHA256(paramsStr, apiSecret).toString(CryptoJS.enc.Hex);
|
328 |
-
}
|
329 |
-
|
330 |
-
// Parse Parameters
|
331 |
-
function parseParams(params) {
|
332 |
-
const sortedKeys = Object.keys(params).sort();
|
333 |
-
const paramPairs = sortedKeys.map(key => `${key}=${params[key]}`);
|
334 |
-
const paramsStr = paramPairs.join('&');
|
335 |
-
return paramsStr ? `${paramsStr}×tamp=${Date.now()}` : `timestamp=${Date.now()}`;
|
336 |
-
}
|
337 |
-
|
338 |
-
// Fetch from API
|
339 |
-
async function fetchFromAPI(endpoint, params = {}) {
|
340 |
if (!API_KEY || !API_SECRET) {
|
341 |
throw new Error('API Key and Secret are not set. Please enter your credentials.');
|
342 |
}
|
343 |
-
params.recvWindow = params.recvWindow || 5000;
|
344 |
-
const
|
345 |
-
const
|
346 |
-
const url = `${API_BASE_URL}${endpoint}?${paramsStr}&signature=${signature}`;
|
347 |
-
const response = await fetch(url, {
|
348 |
-
method: 'GET',
|
349 |
-
headers: {
|
350 |
-
'X-BX-APIKEY': API_KEY,
|
351 |
-
'Content-Type': 'application/json'
|
352 |
-
}
|
353 |
-
});
|
354 |
if (!response.ok) {
|
355 |
-
const
|
356 |
-
throw new Error(`API Error ${response.status}: ${
|
357 |
}
|
358 |
return response.json();
|
359 |
}
|
360 |
|
361 |
// Fetch Specific Data
|
362 |
async function fetchBalance() {
|
363 |
-
const data = await
|
364 |
return data.data.find(b => b.asset === 'USDT')?.walletBalance || 0;
|
365 |
}
|
366 |
|
367 |
async function fetchOpenPositions() {
|
368 |
-
const data = await
|
369 |
return data.data || [];
|
370 |
}
|
371 |
|
372 |
async function fetchTradeHistory() {
|
373 |
-
const data = await
|
374 |
return data.data || [];
|
375 |
}
|
376 |
|
@@ -521,7 +480,7 @@
|
|
521 |
document.getElementById('refresh-btn').addEventListener('click', fetchData);
|
522 |
document.getElementById('sync-now').addEventListener('click', fetchData);
|
523 |
window.addEventListener('load', fetchData);
|
524 |
-
setInterval(fetchData, 120000);
|
525 |
</script>
|
526 |
</body>
|
527 |
</html>
|
|
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=1024">
|
6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
<title>Nakhoda4X Pro - Portfolio Dashboard</title>
|
8 |
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
25 |
}
|
26 |
</script>
|
27 |
<style>
|
28 |
+
.trading-card:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); }
|
29 |
+
.animate-pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
|
30 |
+
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
31 |
+
.coin-animation { animation: float 3s ease-in-out infinite; }
|
32 |
+
@keyframes float { 0% { transform: translateY(0px); } 50% { transform: translateY(-10px); } 100% { transform: translateY(0px); } }
|
33 |
+
.api-form { max-height: 0; overflow: hidden; transition: max-height 0.3s ease-in-out; }
|
34 |
+
.api-form.open { max-height: 200px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
</style>
|
36 |
</head>
|
37 |
<body class="bg-gray-100 dark:bg-darkBg transition-colors duration-300">
|
|
|
275 |
// API Configuration
|
276 |
let API_KEY = localStorage.getItem('bingxApiKey') || '';
|
277 |
let API_SECRET = localStorage.getItem('bingxApiSecret') || '';
|
278 |
+
const PROXY_URL = '/api/proxy'; // Proxy endpoint
|
279 |
|
280 |
// Toggle API Form
|
281 |
const toggleApiFormBtn = document.getElementById('toggle-api-form');
|
|
|
302 |
}
|
303 |
});
|
304 |
|
305 |
+
// Fetch from Proxy
|
306 |
+
async function fetchFromProxy(endpoint, params = {}) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
if (!API_KEY || !API_SECRET) {
|
308 |
throw new Error('API Key and Secret are not set. Please enter your credentials.');
|
309 |
}
|
310 |
+
params.recvWindow = params.recvWindow || 5000;
|
311 |
+
const url = `${PROXY_URL}?endpoint=${encodeURIComponent(endpoint)}&${new URLSearchParams(params).toString()}`;
|
312 |
+
const response = await fetch(url);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
if (!response.ok) {
|
314 |
+
const error = await response.json();
|
315 |
+
throw new Error(`API Error ${response.status}: ${error.error || 'Unknown error'}`);
|
316 |
}
|
317 |
return response.json();
|
318 |
}
|
319 |
|
320 |
// Fetch Specific Data
|
321 |
async function fetchBalance() {
|
322 |
+
const data = await fetchFromProxy('/openApi/swap/v3/user/balance');
|
323 |
return data.data.find(b => b.asset === 'USDT')?.walletBalance || 0;
|
324 |
}
|
325 |
|
326 |
async function fetchOpenPositions() {
|
327 |
+
const data = await fetchFromProxy('/openApi/swap/v2/user/positions', { symbol: 'BTC-USDT' });
|
328 |
return data.data || [];
|
329 |
}
|
330 |
|
331 |
async function fetchTradeHistory() {
|
332 |
+
const data = await fetchFromProxy('/openApi/swap/v2/user/income', { limit: 100 });
|
333 |
return data.data || [];
|
334 |
}
|
335 |
|
|
|
480 |
document.getElementById('refresh-btn').addEventListener('click', fetchData);
|
481 |
document.getElementById('sync-now').addEventListener('click', fetchData);
|
482 |
window.addEventListener('load', fetchData);
|
483 |
+
setInterval(fetchData, 120000);
|
484 |
</script>
|
485 |
</body>
|
486 |
</html>
|