mgbam commited on
Commit
3e3365d
·
verified ·
1 Parent(s): 7731384

Update static/index.html

Browse files
Files changed (1) hide show
  1. static/index.html +46 -24
static/index.html CHANGED
@@ -5,7 +5,6 @@
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Sentinel Arbitrage Engine</title>
7
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
8
- <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
9
  <style>
10
  :root { font-family: 'SF Mono', 'Consolas', 'Menlo', monospace; }
11
  body { background-color: #111927; color: #E5E7EB; font-size: 14px; margin: 0; padding: 1rem; }
@@ -23,14 +22,14 @@
23
  @keyframes fadeIn { from { background-color: rgba(52, 211, 153, 0.2); } to { background-color: transparent; } }
24
  .asset-cell { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: center; }
25
  .asset-logo { width: 24px; height: 24px; }
26
- .asset-cell a { color: inherit; text-decoration: none; font-weight: bold; }
27
  </style>
28
  </head>
29
  <body>
30
  <main class="container">
31
  <header><h1>Sentinel Arbitrage Engine</h1></header>
32
  <div class="status-bar">
33
- Engine Status: <span id="status-light" class="status-offline">OFFLINE</span> | Last Signal: <span id="last-update-time">--:--:--</span>
34
  </div>
35
  <article>
36
  <table>
@@ -45,17 +44,18 @@
45
  </tr>
46
  </thead>
47
  <tbody id="opportunities-table">
48
- <tr id="placeholder-row"><td colspan="6" style="text-align:center; padding: 2rem;">Connecting to engine...</td></tr>
49
  </tbody>
50
  </table>
51
  </article>
52
  </main>
 
53
  <script>
54
- const ASSET_CONFIG = {
55
- 'BTC': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/1.png' },
56
- 'ETH': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png' },
57
- 'SOL': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/5426.png' },
58
- 'XRP': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/52.png' },
59
  'DOGE': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/74.png' },
60
  'ADA': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/2010.png' },
61
  'AVAX': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/5805.png' },
@@ -64,26 +64,47 @@
64
  'MATIC': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/3890.png' }
65
  };
66
 
67
- const socket = io();
68
  const statusLight = document.getElementById('status-light');
69
  const opportunitiesTable = document.getElementById('opportunities-table');
70
  const lastUpdateTime = document.getElementById('last-update-time');
71
 
72
- socket.on('connect', () => {
73
- statusLight.textContent = 'ONLINE';
74
- statusLight.className = 'status-online';
75
- document.getElementById('placeholder-row').cells[0].textContent = 'Monitoring for oracle dislocations...';
76
- });
 
 
 
 
77
 
78
- socket.on('disconnect', () => {
79
- statusLight.textContent = 'OFFLINE';
80
- statusLight.className = 'status-offline';
81
- });
 
 
82
 
83
- socket.on('new_signal', (signal) => {
84
- document.getElementById('placeholder-row')?.remove();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  const newRow = opportunitiesTable.insertRow(0);
86
- const assetInfo = ASSET_CONFIG[signal.asset] || { logo: '' };
87
 
88
  newRow.innerHTML = `
89
  <td><div class="asset-cell"><img src="${assetInfo.logo}" class="asset-logo"><strong>${signal.asset}/USD</strong></div></td>
@@ -93,9 +114,10 @@
93
  <td><span class="risk-${signal.risk.toLowerCase()}">${signal.risk}</span></td>
94
  <td>${signal.strategy}</td>
95
  `;
96
-
97
  lastUpdateTime.textContent = new Date(signal.timestamp).toLocaleTimeString('en-US');
98
- });
 
 
99
  </script>
100
  </body>
101
  </html>
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Sentinel Arbitrage Engine</title>
7
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
 
8
  <style>
9
  :root { font-family: 'SF Mono', 'Consolas', 'Menlo', monospace; }
10
  body { background-color: #111927; color: #E5E7EB; font-size: 14px; margin: 0; padding: 1rem; }
 
22
  @keyframes fadeIn { from { background-color: rgba(52, 211, 153, 0.2); } to { background-color: transparent; } }
23
  .asset-cell { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: center; }
24
  .asset-logo { width: 24px; height: 24px; }
25
+ .asset-cell strong { color: inherit; text-decoration: none; font-weight: bold; }
26
  </style>
27
  </head>
28
  <body>
29
  <main class="container">
30
  <header><h1>Sentinel Arbitrage Engine</h1></header>
31
  <div class="status-bar">
32
+ Engine Status: <span id="status-light" class="status-offline">CONNECTING...</span> | Last Signal: <span id="last-update-time">--:--:--</span>
33
  </div>
34
  <article>
35
  <table>
 
44
  </tr>
45
  </thead>
46
  <tbody id="opportunities-table">
47
+ <tr id="placeholder-row"><td colspan="6" style="text-align:center; padding: 2rem;">Initializing signal stream...</td></tr>
48
  </tbody>
49
  </table>
50
  </article>
51
  </main>
52
+
53
  <script>
54
+ const ASSET_LOGOS = {
55
+ 'BTC': 'https://s2.coinmarketcap.com/static/img/coins/64x64/1.png',
56
+ 'ETH': 'https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png',
57
+ 'SOL': 'https://s2.coinmarketcap.com/static/img/coins/64x64/5426.png',
58
+ 'XRP': 'https://s2.coinmarketcap.com/static/img/coins/64x64/52.png',
59
  'DOGE': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/74.png' },
60
  'ADA': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/2010.png' },
61
  'AVAX': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/5805.png' },
 
64
  'MATIC': { logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/3890.png' }
65
  };
66
 
 
67
  const statusLight = document.getElementById('status-light');
68
  const opportunitiesTable = document.getElementById('opportunities-table');
69
  const lastUpdateTime = document.getElementById('last-update-time');
70
 
71
+ async function connectToStream() {
72
+ try {
73
+ const response = await fetch('/api/signals/stream');
74
+ statusLight.textContent = 'ONLINE';
75
+ statusLight.className = 'status-online';
76
+ document.getElementById('placeholder-row')?.remove();
77
+
78
+ const reader = response.body.getReader();
79
+ const decoder = new TextDecoder();
80
 
81
+ while (true) {
82
+ const { value, done } = await reader.read();
83
+ if (done) break;
84
+
85
+ const chunk = decoder.decode(value, { stream: true });
86
+ const lines = chunk.split('\n').filter(line => line.trim() !== '');
87
 
88
+ for (const line of lines) {
89
+ try {
90
+ const signal = JSON.parse(line);
91
+ renderSignal(signal);
92
+ } catch (e) {
93
+ console.error("Failed to parse signal line:", line, e);
94
+ }
95
+ }
96
+ }
97
+ } catch (error) {
98
+ console.error("Stream connection failed:", error);
99
+ statusLight.textContent = 'OFFLINE';
100
+ statusLight.className = 'status-offline';
101
+ setTimeout(connectToStream, 5000); // Retry after 5 seconds
102
+ }
103
+ }
104
+
105
+ function renderSignal(signal) {
106
  const newRow = opportunitiesTable.insertRow(0);
107
+ const assetInfo = ASSET_LOGOS[signal.asset] || { logo: '' };
108
 
109
  newRow.innerHTML = `
110
  <td><div class="asset-cell"><img src="${assetInfo.logo}" class="asset-logo"><strong>${signal.asset}/USD</strong></div></td>
 
114
  <td><span class="risk-${signal.risk.toLowerCase()}">${signal.risk}</span></td>
115
  <td>${signal.strategy}</td>
116
  `;
 
117
  lastUpdateTime.textContent = new Date(signal.timestamp).toLocaleTimeString('en-US');
118
+ }
119
+
120
+ connectToStream();
121
  </script>
122
  </body>
123
  </html>