File size: 4,556 Bytes
d2f0104
4c64df5
d2f0104
3bccb62
 
d9ddbf8
1d7515b
 
501d31d
1d7515b
 
a1abbf9
4c64df5
1d7515b
3bccb62
1d7515b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9fe665b
1d7515b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9fe665b
1d7515b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3bccb62
d2f0104
1d7515b
 
d9ddbf8
1d7515b
3bccb62
d9ddbf8
 
3bccb62
1d7515b
d9ddbf8
1e89dad
d9ddbf8
1d7515b
9fe665b
d9ddbf8
 
 
 
9fe665b
 
1e89dad
1d7515b
1e89dad
 
d9ddbf8
 
 
1d7515b
 
 
 
 
 
d9ddbf8
 
96fc47a
1d7515b
501d31d
1d7515b
d9ddbf8
1d7515b
 
d9ddbf8
1d7515b
 
 
 
d9ddbf8
1d7515b
d2f0104
3bccb62
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentinel Arbitrage Engine</title>
    
    <!-- Pico.css for a clean, modern base -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
    
    <!-- HTMX Core and the Server-Sent Events Extension -->
    <script src="https://unpkg.com/[email protected]"></script>
    <script src="https://unpkg.com/htmx.org/dist/ext/sse.js"></script>

    <style>
        :root {
            --pico-font-family: 'SF Mono', 'Consolas', 'Menlo', monospace;
            --pico-font-size: 14px;
            --pico-color-green-400: #34D399;
            --pico-color-red-400: #F87171;
            --pico-color-amber-400: #FBBF24;
        }

        body {
            background-color: #111927;
        }

        .container {
            max-width: 1280px;
            margin: 1.5rem auto;
            padding: 0 1rem;
        }

        header {
            text-align: center;
            margin-bottom: 1.5rem;
        }

        h1 {
            color: #38BDF8;
            margin-bottom: 0;
            font-weight: 600;
        }

        table {
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
        }

        th {
            background-color: #374151;
            text-align: left;
        }

        td, th {
            padding: 0.75rem 1rem;
            border-bottom: 1px solid #374151;
            white-space: nowrap;
        }

        tbody tr:hover {
            background-color: #1f2937;
        }

        tbody tr:first-child {
            /* Animation for newly added rows */
            animation: fadeIn 0.7s ease-out;
        }

        .buy { color: var(--pico-color-green-400); }
        .sell { color: var(--pico-color-red-400); }
        
        .risk-low { color: var(--pico-color-green-400); }
        .risk-medium { color: var(--pico-color-amber-400); }
        .risk-high { color: var(--pico-color-red-400); }

        .trade-btn {
            --pico-font-size: 12px;
            --pico-padding: 0.5rem 0.75rem;
            width: 100%;
            white-space: normal;
            text-align: left;
            background-color: #4b5563;
            border-color: #4b5563;
        }

        .status-bar {
            font-size: 12px;
            color: #9CA3AF;
            text-align: right;
            margin-bottom: 1rem;
        }

        @keyframes fadeIn {
            from { background-color: rgba(52, 211, 153, 0.2); }
            to { background-color: transparent; }
        }
    </style>
</head>

<!-- Initialize the SSE extension for the entire page -->
<body hx-ext="sse" sse-connect="/api/signals/stream">

    <main class="container">
        <header>
            <h1>Sentinel Arbitrage Engine</h1>
        </header>

        <div class="status-bar">
            Engine Status: <span style="color: #34D399;">ONLINE</span> | Last Signal: <span id="last-update-time">--:--:--</span>
        </div>

        <article data-theme="dark" style="padding: 0; overflow-x: auto;">
            <table>
                <thead>
                    <tr>
                        <th>Pair</th>
                        <th>Oracle 1 (Pyth)</th>
                        <th>Oracle 2 (Chainlink Agg.)</th>
                        <th>Discrepancy</th>
                        <th>Risk Assessment</th>
                        <th>Rationale</th>
                        <th>Suggested Strategy</th>
                    </tr>
                </thead>
                <tbody id="opportunities-table">
                    <!-- New arbitrage opportunities will be inserted here by HTMX -->
                    <tr id="placeholder-row">
                        <td colspan="7" style="text-align:center; padding: 2rem; color: #9CA3AF;">
                            Monitoring for On-Chain/Off-Chain price discrepancies...
                        </td>
                    </tr>
                </tbody>
            </table>
        </article>

    </main>

    <script>
        // This simple listener removes the "Monitoring..." placeholder
        // as soon as the very first signal arrives from the server.
        document.body.addEventListener('htmx:sseMessage', function(evt) {
            const placeholder = document.getElementById('placeholder-row');
            if (placeholder) {
                placeholder.remove();
            }
        });
    </script>
</body>
</html>