Skip to content

Commit 182e97b

Browse files
committed
Add 3 new skills: Liquidity Lifecycle, Capital Rotation, Contract Mutation
Backend: - CoinGecko categories proxy (free, no auth) - Etherscan V2 proxy (sourcecode + ABI, optional API key) - DexScreener chain-specific token endpoint Frontend: - Liquidity Lifecycle panel: LP lock status, holder concentration, health score - Capital Rotation panel: sector rotation radar with CoinGecko categories - Contract Mutation panel: proxy detection, ABI scan, Trust Decay Score - New Security layout (14 total layouts, 37 panels) - i18n: 4 keys x 10 languages - Bar fill set to gray for Alpha Radar and Liquidation Heatmap - Hide hamburger drawer on desktop
1 parent f8903f3 commit 182e97b

14 files changed

Lines changed: 832 additions & 33 deletions

frontend/css/main.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ status-bar {
776776
/* Mobile bottom nav + actions — hidden on desktop */
777777
#mobile-nav { display: none; }
778778
#mobile-actions { display: none; }
779+
.hamburger-drawer { display: none; }
779780

780781
.mobile-action-btn {
781782
background: none;

frontend/index.html

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<meta name="theme-color" content="#0b0e11">
99
<title>Binance Skills Terminal</title>
1010
<base href="/superbsc/">
11-
<link rel="stylesheet" href="static/css/main.css?v=1709560000">
11+
<link rel="stylesheet" href="static/css/main.css?v=1709570000">
1212
</head>
1313
<body>
1414
<!-- Inline fallback: ensures globals are available before modules load -->
@@ -162,6 +162,7 @@
162162
<button class="layout-btn" data-layout="intel" data-i18n="nav.intel">Intel</button>
163163
<button class="layout-btn" data-layout="defi" data-i18n="nav.defi">DeFi</button>
164164
<button class="layout-btn" data-layout="risk" data-i18n="nav.risk">Risk</button>
165+
<button class="layout-btn" data-layout="security" data-i18n="nav.security">Security</button>
165166
</nav>
166167
</div>
167168
<div class="header-right">
@@ -218,6 +219,7 @@
218219
<button class="hamburger-item" data-layout="intel"><span data-i18n="nav.intel">Intel</span></button>
219220
<button class="hamburger-item" data-layout="defi"><span data-i18n="nav.defi">DeFi</span></button>
220221
<button class="hamburger-item" data-layout="risk"><span data-i18n="nav.risk">Risk</span></button>
222+
<button class="hamburger-item" data-layout="security"><span data-i18n="nav.security">Security</span></button>
221223
</div>
222224
<div class="hamburger-actions">
223225
<button class="hamburger-action" id="mobile-search" data-i18n="btn.search">Search</button>
@@ -325,22 +327,22 @@ <h2>Settings</h2>
325327
<div id="toast-container"></div>
326328

327329
<!-- Scripts -->
328-
<script type="module" src="static/js/store.js?v=1709560000"></script>
329-
<script type="module" src="static/js/api.js?v=1709560000"></script>
330-
<script type="module" src="static/js/utils.js?v=1709560000"></script>
331-
<script type="module" src="static/js/components/base-panel.js?v=1709560000"></script>
332-
<script type="module" src="static/js/components/data-table.js?v=1709560000"></script>
333-
<script type="module" src="static/js/components/status-bar.js?v=1709560000"></script>
334-
<script type="module" src="static/js/components/search-bar.js?v=1709560000"></script>
335-
<script type="module" src="static/js/components/command-palette.js?v=1709560000"></script>
336-
<script type="module" src="static/js/components/context-menu.js?v=1709560000"></script>
337-
<script type="module" src="static/js/components/toast.js?v=1709560000"></script>
338-
<script type="module" src="static/js/components/risk-badge.js?v=1709560000"></script>
339-
<script type="module" src="static/js/components/mini-chart.js?v=1709560000"></script>
340-
<script type="module" src="static/js/components/chart.js?v=1709560000"></script>
341-
<script type="module" src="static/js/components/ws-stream.js?v=1709560000"></script>
342-
<script type="module" src="static/js/components/settings.js?v=1709560000"></script>
343-
<script type="module" src="static/js/i18n.js?v=1709560000"></script>
344-
<script type="module" src="static/js/app.js?v=1709560000"></script>
330+
<script type="module" src="static/js/store.js?v=1709570000"></script>
331+
<script type="module" src="static/js/api.js?v=1709570000"></script>
332+
<script type="module" src="static/js/utils.js?v=1709570000"></script>
333+
<script type="module" src="static/js/components/base-panel.js?v=1709570000"></script>
334+
<script type="module" src="static/js/components/data-table.js?v=1709570000"></script>
335+
<script type="module" src="static/js/components/status-bar.js?v=1709570000"></script>
336+
<script type="module" src="static/js/components/search-bar.js?v=1709570000"></script>
337+
<script type="module" src="static/js/components/command-palette.js?v=1709570000"></script>
338+
<script type="module" src="static/js/components/context-menu.js?v=1709570000"></script>
339+
<script type="module" src="static/js/components/toast.js?v=1709570000"></script>
340+
<script type="module" src="static/js/components/risk-badge.js?v=1709570000"></script>
341+
<script type="module" src="static/js/components/mini-chart.js?v=1709570000"></script>
342+
<script type="module" src="static/js/components/chart.js?v=1709570000"></script>
343+
<script type="module" src="static/js/components/ws-stream.js?v=1709570000"></script>
344+
<script type="module" src="static/js/components/settings.js?v=1709570000"></script>
345+
<script type="module" src="static/js/i18n.js?v=1709570000"></script>
346+
<script type="module" src="static/js/app.js?v=1709570000"></script>
345347
</body>
346348
</html>

frontend/js/api.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,17 @@ export const api = {
198198
latestProfiles: () => get('/api/dex/latest-profiles', {}, 30000),
199199
search: (q, chain) => get('/api/dex/search', { q, chainIds: chain || 'bsc' }, 30000),
200200
token: (addr) => get('/api/dex/token', { address: addr }, 30000),
201+
tokenChain: (chain, addr) => get('/api/dex/token-chain', { chain, address: addr }, 30000),
202+
},
203+
// Skill 11: CoinGecko
204+
coingecko: {
205+
categories: (order) => get('/api/coingecko/categories', { order: order || 'market_cap_desc' }, 120000),
206+
categoryCoins: (cat, n) => get('/api/coingecko/category-coins', { category: cat, per_page: n || 20 }, 120000),
207+
},
208+
// Skill 12: Etherscan
209+
etherscan: {
210+
sourceCode: (addr, chain) => get('/api/etherscan/sourcecode', { address: addr, chainId: chain || '56' }, 300000),
211+
abi: (addr, chain) => get('/api/etherscan/abi', { address: addr, chainId: chain || '56' }, 300000),
201212
},
202213
health: () => get('/health', {}, 30000),
203214
};

frontend/js/app.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ const panelRegistry = {
4040
'dex-intel': 'dex-intel-panel',
4141
'goplus-scanner': 'goplus-scanner-panel',
4242
'multi-chain-wallet': 'multi-chain-wallet-panel',
43+
'liquidity-lifecycle': 'liquidity-lifecycle-panel',
44+
'capital-rotation': 'capital-rotation-panel',
45+
'contract-mutation': 'contract-mutation-panel',
4346
};
4447

4548
// Layout presets
@@ -109,6 +112,11 @@ const layouts = {
109112
grid: 'grid-2x2',
110113
panels: ['liquidation-heatmap', 'futures-pulse', 'funding-arb', 'order-book-intel'],
111114
},
115+
'security': {
116+
name: 'Security',
117+
grid: 'grid-2x2',
118+
panels: ['contract-mutation', 'liquidity-lifecycle', 'goplus-scanner', 'capital-rotation'],
119+
},
112120
};
113121

114122
const grid = document.getElementById('grid');
@@ -125,10 +133,11 @@ async function loadPanels() {
125133
'futures-pulse', 'sm-acceleration', 'token-scout', 'funding-arb', 'social-divergence',
126134
'whale-intel', 'order-book-intel', 'token-grad',
127135
'liquidation-heatmap', 'dex-intel', 'goplus-scanner', 'multi-chain-wallet',
136+
'liquidity-lifecycle', 'capital-rotation', 'contract-mutation',
128137
];
129138
await Promise.allSettled(
130139
panelModules.map(name =>
131-
import(`./panels/${name}.js?v=1709560000`).catch(e => console.warn(`Panel ${name} not loaded:`, e.message))
140+
import(`./panels/${name}.js?v=1709570000`).catch(e => console.warn(`Panel ${name} not loaded:`, e.message))
132141
)
133142
);
134143
}
@@ -250,7 +259,7 @@ document.addEventListener('keydown', (e) => {
250259

251260
// 1-7 — switch layout
252261
const num = parseInt(e.key);
253-
if (num >= 1 && num <= 13) {
262+
if (num >= 1 && num <= 14) {
254263
const keys = Object.keys(layouts);
255264
if (keys[num - 1]) setLayout(keys[num - 1]);
256265
return;

frontend/js/i18n.js

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ const T = {
134134
// Liquidation Heatmap, DEX Intel, GoPlus Scanner, Multi-Chain Wallet
135135
'panel.liqHeatmap': 'Liquidation Heatmap', 'panel.dexIntel': 'DEX Intel',
136136
'panel.goplusScanner': 'GoPlus Security', 'panel.multiChainWallet': 'Multi-Chain Wallet',
137-
'nav.defi': 'DeFi', 'nav.risk': 'Risk',
137+
'nav.defi': 'DeFi', 'nav.risk': 'Risk', 'nav.security': 'Security',
138+
'panel.liqLifecycle': 'Liquidity Lifecycle', 'panel.capitalRotation': 'Capital Rotation',
139+
'panel.contractMutation': 'Contract Mutation',
138140
'liq.noData': 'No liquidation data', 'liq.risk': 'Risk', 'liq.crowd': 'Crowding',
139141
'dex.noData': 'No DEX data', 'dex.boosted': 'Boosted', 'dex.trending': 'Trending',
140142
'dex.chain': 'Chain', 'dex.info': 'Info', 'dex.noProfiles': 'No boosted profiles',
@@ -240,7 +242,9 @@ const T = {
240242
'grad.noData': '无毕业数据', 'grad.score': '毕业分', 'grad.holders': '持有者',
241243
'panel.liqHeatmap': '清算热力图', 'panel.dexIntel': 'DEX情报',
242244
'panel.goplusScanner': 'GoPlus安全', 'panel.multiChainWallet': '多链钱包',
243-
'nav.defi': 'DeFi', 'nav.risk': '风险',
245+
'nav.defi': 'DeFi', 'nav.risk': '风险', 'nav.security': '安全',
246+
'panel.liqLifecycle': '流动性生命周期', 'panel.capitalRotation': '资金轮动',
247+
'panel.contractMutation': '合约变异',
244248
'liq.noData': '无清算数据', 'liq.risk': '风险', 'liq.crowd': '拥挤度',
245249
'dex.noData': '无DEX数据', 'dex.boosted': '推广', 'dex.trending': '趋势',
246250
'dex.chain': '链', 'dex.info': '信息', 'dex.noProfiles': '无推广数据',
@@ -346,7 +350,9 @@ const T = {
346350
'grad.noData': 'Mezuniyet verisi yok', 'grad.score': 'Mezuniyet', 'grad.holders': 'Sahipler',
347351
'panel.liqHeatmap': 'Likidasyon Haritası', 'panel.dexIntel': 'DEX İstihbarat',
348352
'panel.goplusScanner': 'GoPlus Güvenlik', 'panel.multiChainWallet': 'Çoklu Zincir Cüzdan',
349-
'nav.defi': 'DeFi', 'nav.risk': 'Risk',
353+
'nav.defi': 'DeFi', 'nav.risk': 'Risk', 'nav.security': 'Security',
354+
'panel.liqLifecycle': 'Liquidity Lifecycle', 'panel.capitalRotation': 'Capital Rotation',
355+
'panel.contractMutation': 'Contract Mutation',
350356
'liq.noData': 'Likidasyon verisi yok', 'liq.risk': 'Risk', 'liq.crowd': 'Kalabalık',
351357
'dex.noData': 'DEX verisi yok', 'dex.boosted': 'Öne Çıkan', 'dex.trending': 'Trend',
352358
'dex.chain': 'Zincir', 'dex.info': 'Bilgi', 'dex.noProfiles': 'Öne çıkan profil yok',
@@ -452,7 +458,9 @@ const T = {
452458
'grad.noData': 'Không có dữ liệu tốt nghiệp', 'grad.score': 'Điểm TN', 'grad.holders': 'Người giữ',
453459
'panel.liqHeatmap': 'Bản đồ Thanh lý', 'panel.dexIntel': 'Tình báo DEX',
454460
'panel.goplusScanner': 'GoPlus Bảo mật', 'panel.multiChainWallet': 'Ví Đa chuỗi',
455-
'nav.defi': 'DeFi', 'nav.risk': 'Rủi ro',
461+
'nav.defi': 'DeFi', 'nav.risk': 'Rủi ro', 'nav.security': 'Bảo mật',
462+
'panel.liqLifecycle': 'Vòng đời Thanh khoản', 'panel.capitalRotation': 'Luân chuyển Vốn',
463+
'panel.contractMutation': 'Đột biến Hợp đồng',
456464
'liq.noData': 'Không có dữ liệu thanh lý', 'liq.risk': 'Rủi ro', 'liq.crowd': 'Đông đúc',
457465
'dex.noData': 'Không có dữ liệu DEX', 'dex.boosted': 'Nổi bật', 'dex.trending': 'Xu hướng',
458466
'dex.chain': 'Chuỗi', 'dex.info': 'Thông tin', 'dex.noProfiles': 'Không có hồ sơ nổi bật',
@@ -558,7 +566,9 @@ const T = {
558566
'grad.noData': 'कोई ग्रेजुएशन डेटा नहीं', 'grad.score': 'ग्रेड स्कोर', 'grad.holders': 'धारक',
559567
'panel.liqHeatmap': 'लिक्विडेशन हीटमैप', 'panel.dexIntel': 'DEX इंटेल',
560568
'panel.goplusScanner': 'GoPlus सुरक्षा', 'panel.multiChainWallet': 'मल्टी-चेन वॉलेट',
561-
'nav.defi': 'DeFi', 'nav.risk': 'जोखिम',
569+
'nav.defi': 'DeFi', 'nav.risk': 'जोखिम', 'nav.security': 'सुरक्षा',
570+
'panel.liqLifecycle': 'तरलता जीवनचक्र', 'panel.capitalRotation': 'पूंजी रोटेशन',
571+
'panel.contractMutation': 'अनुबंध उत्परिवर्तन',
562572
'liq.noData': 'कोई लिक्विडेशन डेटा नहीं', 'liq.risk': 'जोखिम', 'liq.crowd': 'भीड़',
563573
'dex.noData': 'कोई DEX डेटा नहीं', 'dex.boosted': 'बूस्टेड', 'dex.trending': 'ट्रेंडिंग',
564574
'dex.chain': 'चेन', 'dex.info': 'जानकारी', 'dex.noProfiles': 'कोई बूस्टेड प्रोफ़ाइल नहीं',
@@ -664,7 +674,9 @@ const T = {
664674
'grad.noData': 'داده فارغ‌التحصیلی نیست', 'grad.score': 'امتیاز', 'grad.holders': 'نگهدارندگان',
665675
'panel.liqHeatmap': 'نقشه لیکوئید', 'panel.dexIntel': 'اطلاعات DEX',
666676
'panel.goplusScanner': 'امنیت GoPlus', 'panel.multiChainWallet': 'کیف پول چندزنجیره',
667-
'nav.defi': 'DeFi', 'nav.risk': 'ریسک',
677+
'nav.defi': 'DeFi', 'nav.risk': 'ریسک', 'nav.security': 'امنیت',
678+
'panel.liqLifecycle': 'چرخه نقدینگی', 'panel.capitalRotation': 'چرخش سرمایه',
679+
'panel.contractMutation': 'جهش قرارداد',
668680
'liq.noData': 'داده لیکوئید موجود نیست', 'liq.risk': 'ریسک', 'liq.crowd': 'ازدحام',
669681
'dex.noData': 'داده DEX موجود نیست', 'dex.boosted': 'تقویت‌شده', 'dex.trending': 'ترند',
670682
'dex.chain': 'زنجیره', 'dex.info': 'اطلاعات', 'dex.noProfiles': 'پروفایل تقویت‌شده نیست',
@@ -770,7 +782,9 @@ const T = {
770782
'grad.noData': 'Keine Graduierungsdaten', 'grad.score': 'Grad-Score', 'grad.holders': 'Halter',
771783
'panel.liqHeatmap': 'Liquidations-Heatmap', 'panel.dexIntel': 'DEX-Intel',
772784
'panel.goplusScanner': 'GoPlus Sicherheit', 'panel.multiChainWallet': 'Multi-Chain Wallet',
773-
'nav.defi': 'DeFi', 'nav.risk': 'Risiko',
785+
'nav.defi': 'DeFi', 'nav.risk': 'Risiko', 'nav.security': 'Sicherheit',
786+
'panel.liqLifecycle': 'Liquiditätszyklus', 'panel.capitalRotation': 'Kapitalrotation',
787+
'panel.contractMutation': 'Vertragsmutation',
774788
'liq.noData': 'Keine Liquidationsdaten', 'liq.risk': 'Risiko', 'liq.crowd': 'Überfüllung',
775789
'dex.noData': 'Keine DEX-Daten', 'dex.boosted': 'Gefördert', 'dex.trending': 'Trending',
776790
'dex.chain': 'Kette', 'dex.info': 'Info', 'dex.noProfiles': 'Keine geförderten Profile',
@@ -876,7 +890,9 @@ const T = {
876890
'grad.noData': 'Aucune donnée de graduation', 'grad.score': 'Score Grad', 'grad.holders': 'Détenteurs',
877891
'panel.liqHeatmap': 'Carte de Liquidation', 'panel.dexIntel': 'Intel DEX',
878892
'panel.goplusScanner': 'Sécurité GoPlus', 'panel.multiChainWallet': 'Portefeuille Multi-chaîne',
879-
'nav.defi': 'DeFi', 'nav.risk': 'Risque',
893+
'nav.defi': 'DeFi', 'nav.risk': 'Risque', 'nav.security': 'Sécurité',
894+
'panel.liqLifecycle': 'Cycle de Liquidité', 'panel.capitalRotation': 'Rotation du Capital',
895+
'panel.contractMutation': 'Mutation de Contrat',
880896
'liq.noData': 'Aucune donnée de liquidation', 'liq.risk': 'Risque', 'liq.crowd': 'Encombrement',
881897
'dex.noData': 'Aucune donnée DEX', 'dex.boosted': 'Promu', 'dex.trending': 'Tendance',
882898
'dex.chain': 'Chaîne', 'dex.info': 'Info', 'dex.noProfiles': 'Aucun profil promu',
@@ -982,7 +998,9 @@ const T = {
982998
'grad.noData': 'لا توجد بيانات تخرج', 'grad.score': 'درجة التخرج', 'grad.holders': 'الحاملون',
983999
'panel.liqHeatmap': 'خريطة التصفية', 'panel.dexIntel': 'استخبارات DEX',
9841000
'panel.goplusScanner': 'أمان GoPlus', 'panel.multiChainWallet': 'محفظة متعددة السلاسل',
985-
'nav.defi': 'DeFi', 'nav.risk': 'مخاطر',
1001+
'nav.defi': 'DeFi', 'nav.risk': 'مخاطر', 'nav.security': 'أمان',
1002+
'panel.liqLifecycle': 'دورة السيولة', 'panel.capitalRotation': 'تدوير رأس المال',
1003+
'panel.contractMutation': 'تحور العقد',
9861004
'liq.noData': 'لا توجد بيانات تصفية', 'liq.risk': 'مخاطر', 'liq.crowd': 'ازدحام',
9871005
'dex.noData': 'لا توجد بيانات DEX', 'dex.boosted': 'معزز', 'dex.trending': 'رائج',
9881006
'dex.chain': 'سلسلة', 'dex.info': 'معلومات', 'dex.noProfiles': 'لا توجد ملفات معززة',
@@ -1088,7 +1106,9 @@ const T = {
10881106
'grad.noData': 'Sin datos de graduación', 'grad.score': 'Score Grad', 'grad.holders': 'Titulares',
10891107
'panel.liqHeatmap': 'Mapa de Liquidación', 'panel.dexIntel': 'Intel DEX',
10901108
'panel.goplusScanner': 'Seguridad GoPlus', 'panel.multiChainWallet': 'Cartera Multi-cadena',
1091-
'nav.defi': 'DeFi', 'nav.risk': 'Riesgo',
1109+
'nav.defi': 'DeFi', 'nav.risk': 'Riesgo', 'nav.security': 'Seguridad',
1110+
'panel.liqLifecycle': 'Ciclo de Liquidez', 'panel.capitalRotation': 'Rotación de Capital',
1111+
'panel.contractMutation': 'Mutación de Contrato',
10921112
'liq.noData': 'Sin datos de liquidación', 'liq.risk': 'Riesgo', 'liq.crowd': 'Aglomeración',
10931113
'dex.noData': 'Sin datos DEX', 'dex.boosted': 'Promocionado', 'dex.trending': 'Tendencia',
10941114
'dex.chain': 'Cadena', 'dex.info': 'Info', 'dex.noProfiles': 'Sin perfiles promocionados',
@@ -1121,6 +1141,9 @@ const _tagToKey = {
11211141
'dex-intel-panel': 'panel.dexIntel',
11221142
'goplus-scanner-panel': 'panel.goplusScanner',
11231143
'multi-chain-wallet-panel': 'panel.multiChainWallet',
1144+
'liquidity-lifecycle-panel': 'panel.liqLifecycle',
1145+
'capital-rotation-panel': 'panel.capitalRotation',
1146+
'contract-mutation-panel': 'panel.contractMutation',
11241147
};
11251148

11261149
let _lang = 'en';

frontend/js/panels/alpha-radar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ export class AlphaRadarPanel extends BasePanel {
197197
const icon = iconUrl ? `<img src="${iconUrl}" style="width:14px;height:14px;border-radius:50%;vertical-align:middle;margin-right:4px" onerror="this.style.display='none'">` : '';
198198

199199
const tierCls = r.alphaScore >= 80 ? 'alpha-gold' : r.alphaScore >= 60 ? 'alpha-green' : r.alphaScore >= 40 ? 'alpha-yellow' : 'alpha-gray';
200-
const barColor = r.alphaScore >= 80 ? '#f0b90b' : r.alphaScore >= 60 ? '#0ecb81' : r.alphaScore >= 40 ? '#e8a317' : '#474d57';
201-
const barGlow = r.alphaScore >= 80 ? 'box-shadow:0 0 8px rgba(240,185,11,.6)' : r.alphaScore >= 60 ? 'box-shadow:0 0 6px rgba(14,203,129,.4)' : '';
200+
const barColor = '#474d57';
201+
const barGlow = '';
202202
const pct = Math.min(100, r.alphaScore);
203203

204204
const badgesHtml = r.badges.map(b =>

0 commit comments

Comments
 (0)