/** * Configuration Helper Modal - Updated with All Services * Shows users how to configure and use all backend services * * Services Include: * - Market Data (8+ providers) * - News (9+ sources) * - Sentiment Analysis (4+ providers) * - On-Chain Analytics (4+ providers) * - DeFi Data (3+ providers) * - Technical Analysis * - AI Models * - Block Explorers */ export class ConfigHelperModal { constructor() { this.modal = null; this.services = this.getServicesConfig(); } getServicesConfig() { const baseUrl = window.location.origin; return [ // ===== QUICK DISCOVERY ===== { name: 'Discovery & Health', category: 'Getting Started', description: 'Verify the server is online and discover all available endpoints', endpoints: [ { method: 'GET', path: '/api/health', desc: 'Health check' }, { method: 'GET', path: '/api/status', desc: 'System status' }, { method: 'GET', path: '/api/routers', desc: 'Loaded routers status' }, { method: 'GET', path: '/api/endpoints', desc: 'Full endpoints list (grouped)' }, { method: 'GET', path: '/docs', desc: 'Swagger UI documentation' } ], example: `// Health check fetch('${baseUrl}/api/health') .then(res => res.json()) .then(console.log); // Get full endpoints list fetch('${baseUrl}/api/endpoints') .then(res => res.json()) .then(data => console.log('Total:', data.total_endpoints));` }, // ===== UNIFIED SERVICE API ===== { name: 'Unified Service API', category: 'Core Services', description: 'Single entry point for all cryptocurrency data needs', endpoints: [ { method: 'GET', path: '/api/service/rate?pair=BTC/USDT', desc: 'Get exchange rate' }, { method: 'GET', path: '/api/service/rate/batch?pairs=BTC/USDT,ETH/USDT', desc: 'Multiple rates' }, { method: 'GET', path: '/api/service/history?symbol=BTC&interval=60&limit=200', desc: 'Historical OHLC (minutes interval)' }, { method: 'GET', path: '/api/service/market-status', desc: 'Market overview' }, { method: 'GET', path: '/api/service/top?n=10', desc: 'Top cryptocurrencies' }, { method: 'GET', path: '/api/service/sentiment?symbol=BTC', desc: 'Get sentiment' }, { method: 'GET', path: '/api/service/whales?chain=ethereum&min_amount_usd=1000000', desc: 'Whale transactions (service)' }, { method: 'GET', path: '/api/service/onchain?address=0x...&chain=ethereum', desc: 'On-chain data (service)' }, { method: 'POST', path: '/api/service/query', desc: 'Universal query endpoint' } ], example: `// Get BTC price fetch('${baseUrl}/api/service/rate?pair=BTC/USDT') .then(res => res.json()) .then(data => console.log('BTC Price:', data.data.price)); // Get multiple prices fetch('${baseUrl}/api/service/rate/batch?pairs=BTC/USDT,ETH/USDT,BNB/USDT') .then(res => res.json()) .then(data => data.data.forEach(r => console.log(r.pair + ': $' + r.price)));` }, // ===== MARKET DATA ===== { name: 'Market Data API', category: 'Market Data', description: 'Real-time prices, OHLC/OHLCV, and market statistics', endpoints: [ { method: 'GET', path: '/api/market?limit=100', desc: 'Market data with prices' }, { method: 'GET', path: '/api/coins/top?limit=50', desc: 'Top coins by market cap' }, { method: 'GET', path: '/api/trending', desc: 'Trending cryptocurrencies' }, { method: 'GET', path: '/api/market/ohlc?symbol=BTC&timeframe=1h', desc: 'OHLC (multi-source, recommended)' }, { method: 'GET', path: '/api/ohlcv?symbol=BTC&timeframe=1h&limit=100', desc: 'OHLCV (query-style)' }, { method: 'GET', path: '/api/klines?symbol=BTCUSDT&interval=1h&limit=100', desc: 'Klines alias (Binance style)' }, { method: 'GET', path: '/api/historical?symbol=BTC&days=30', desc: 'Daily historical candles (alias)' } ], example: `// Get OHLCV data for charting fetch('${baseUrl}/api/ohlcv?symbol=BTC&timeframe=1h&limit=100') .then(res => res.json()) .then(data => { console.log('OHLCV data:', data.data); // Each candle: { timestamp, open, high, low, close, volume } });` }, // ===== NEWS ===== { name: 'News Aggregator API', category: 'News & Media', description: 'Crypto news from 9+ sources including RSS feeds', endpoints: [ { method: 'GET', path: '/api/news/latest?limit=20', desc: 'Latest crypto news' }, { method: 'GET', path: '/api/news?limit=20', desc: 'Alias for latest (compat)' } ], example: `// Get latest news fetch('${baseUrl}/api/news/latest?limit=10') .then(res => res.json()) .then(data => { data.articles.forEach(article => { console.log(article.title, '-', article.source); }); });` }, // ===== SENTIMENT ===== { name: 'Sentiment Analysis API', category: 'Sentiment', description: 'Fear & Greed Index, social sentiment, and AI-powered analysis', endpoints: [ { method: 'GET', path: '/api/sentiment/global', desc: 'Global market sentiment' }, { method: 'GET', path: '/api/fear-greed', desc: 'Fear & Greed Index (alias)' }, { method: 'GET', path: '/api/sentiment/asset/{symbol}', desc: 'Asset-specific sentiment' }, { method: 'POST', path: '/api/sentiment/analyze', desc: 'Analyze custom text' } ], example: `// Get Fear & Greed Index fetch('${baseUrl}/api/fear-greed') .then(res => res.json()) .then(data => { console.log('Fear & Greed:', data.value, '-', data.classification); }); // Analyze text sentiment fetch('${baseUrl}/api/sentiment/analyze', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Bitcoin is going to the moon!', mode: 'crypto' }) }) .then(res => res.json()) .then(data => console.log('Sentiment:', data.sentiment, data.score));` }, // ===== ON-CHAIN ANALYTICS ===== { name: 'On-Chain Analytics API', category: 'Analytics', description: 'Blockchain data, whale tracking, and network statistics', endpoints: [ { method: 'GET', path: '/api/service/whales?chain=ethereum&min_amount_usd=1000000&limit=20', desc: 'Whale transactions (service)' }, { method: 'GET', path: '/api/service/onchain?address=0x...&chain=ethereum', desc: 'On-chain snapshot (service)' } ], example: `// Get whale transactions fetch('${baseUrl}/api/service/whales?chain=ethereum&min_amount_usd=1000000&limit=20') .then(res => res.json()) .then(data => console.log(data));` }, // ===== TECHNICAL ANALYSIS ===== { name: 'Technical Analysis API', category: 'Analysis Services', description: '5 analysis modes: Quick TA, Fundamental, On-Chain, Risk, Comprehensive', endpoints: [ { method: 'POST', path: '/api/technical/ta-quick', desc: 'Quick technical analysis' }, { method: 'POST', path: '/api/technical/fa-eval', desc: 'Fundamental evaluation' }, { method: 'POST', path: '/api/technical/onchain-health', desc: 'On-chain network health' }, { method: 'POST', path: '/api/technical/risk-assessment', desc: 'Risk & volatility assessment' }, { method: 'POST', path: '/api/technical/comprehensive', desc: 'Comprehensive analysis' } ], example: `// Quick Technical Analysis const ohlcv = await fetch('${baseUrl}/api/ohlcv?symbol=BTC&timeframe=4h&limit=200') .then(r => r.json()).then(d => d.data); fetch('${baseUrl}/api/technical/ta-quick', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ symbol: 'BTC', timeframe: '4h', ohlcv: ohlcv }) }) .then(res => res.json()) .then(data => { console.log('Trend:', data.trend); console.log('RSI:', data.rsi); console.log('Entry Range:', data.entry_range); });` }, // ===== INDICATORS ===== { name: 'Indicator Services API', category: 'Analysis Services', description: 'Technical indicators (RSI, MACD, SMA/EMA, BB, ATR, StochRSI) + comprehensive signals', endpoints: [ { method: 'GET', path: '/api/indicators/services', desc: 'List available indicator services' }, { method: 'GET', path: '/api/indicators/rsi?symbol=BTC&timeframe=1h&period=14', desc: 'RSI' }, { method: 'GET', path: '/api/indicators/macd?symbol=BTC&timeframe=1h', desc: 'MACD' }, { method: 'GET', path: '/api/indicators/comprehensive?symbol=BTC&timeframe=1h', desc: 'Comprehensive indicator analysis' } ], example: `// List indicator services fetch('${baseUrl}/api/indicators/services') .then(r => r.json()) .then(console.log); // RSI fetch('${baseUrl}/api/indicators/rsi?symbol=BTC&timeframe=1h&period=14') .then(r => r.json()) .then(console.log);` }, // ===== AI MODELS ===== { name: 'AI Models API', category: 'AI Services', description: 'HuggingFace AI models for sentiment, analysis, and predictions', endpoints: [ { method: 'GET', path: '/api/models/status', desc: 'Models status' }, { method: 'GET', path: '/api/models/list', desc: 'List all models' }, { method: 'GET', path: '/api/models/summary', desc: 'Models grouped by category (frontend-ready)' }, { method: 'GET', path: '/api/models/health', desc: 'Model health check' }, { method: 'POST', path: '/api/models/reinitialize', desc: 'Reinitialize models (UI button)' }, { method: 'POST', path: '/api/ai/decision', desc: 'AI trading decision' } ], example: `// Get AI trading decision fetch('${baseUrl}/api/ai/decision', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ symbol: 'BTC', horizon: 'swing', risk_tolerance: 'moderate' }) }) .then(res => res.json()) .then(data => { console.log('Decision:', data.decision); console.log('Confidence:', data.confidence); console.log('Signals:', data.signals); });` }, // ===== DEFI DATA ===== { name: 'DeFi Data API', category: 'DeFi Services', description: 'DefiLlama public endpoints (no API key): TVL, protocols, yields', endpoints: [ { method: 'GET', path: '/api/defi/tvl', desc: 'Total Value Locked' }, { method: 'GET', path: '/api/defi/protocols?limit=20', desc: 'Top DeFi protocols' }, { method: 'GET', path: '/api/defi/yields?limit=20', desc: 'DeFi yield pools' } ], example: `// Get DeFi TVL data fetch('${baseUrl}/api/defi/protocols?limit=10') .then(res => res.json()) .then(data => { (data.protocols || []).forEach(p => { console.log(p.name, '- TVL:', p.tvl); }); });` }, // ===== TRADING & BACKTESTING ===== { name: 'Trading & Backtesting API', category: 'Trading', description: 'Historical backtests and strategy runs (uses exchange/data fallbacks)', endpoints: [ { method: 'GET', path: '/api/trading/backtest/historical/BTCUSDT?timeframe=1h&days=30', desc: 'Historical candles for backtest' }, { method: 'GET', path: '/api/trading/backtest/run/BTCUSDT?strategy=sma_crossover&days=30&initial_capital=10000', desc: 'Run a backtest strategy' } ], example: `// Run SMA crossover backtest fetch('${baseUrl}/api/trading/backtest/run/BTCUSDT?strategy=sma_crossover&days=30&initial_capital=10000') .then(r => r.json()) .then(console.log);` }, // ===== RESOURCES & MONITORING ===== { name: 'Resources & Monitoring API', category: 'System Services', description: 'API resources, providers status, and system health', endpoints: [ { method: 'GET', path: '/api/resources/stats', desc: 'Resources statistics' }, { method: 'GET', path: '/api/resources/apis', desc: 'All APIs list' }, { method: 'GET', path: '/api/resources/summary', desc: 'Resources summary' }, { method: 'GET', path: '/api/providers', desc: 'Data providers list' }, { method: 'GET', path: '/api/status', desc: 'System status' }, { method: 'GET', path: '/api/health', desc: 'Health check' } ], example: `// Check system health fetch('${baseUrl}/api/health') .then(res => res.json()) .then(data => { console.log('Status:', data.status); console.log('Providers:', data.providers); }); // Get resources stats fetch('${baseUrl}/api/resources/stats') .then(res => res.json()) .then(data => { console.log('Total APIs:', data.total_functional); console.log('Success Rate:', data.success_rate + '%'); });` }, // ===== SUPPORT / DEBUG ===== { name: 'Support & Debug API', category: 'System Services', description: 'Client-accessible support files and real endpoint list', endpoints: [ { method: 'GET', path: '/api/support/realendpoints', desc: 'Endpoints list (JSON)' }, { method: 'GET', path: '/api/support/realendpoints?format=txt', desc: 'Endpoints list (TXT)' }, { method: 'GET', path: '/realendpoint.txt', desc: 'Download endpoints list (TXT)' }, { method: 'GET', path: '/api/support/fualt?tail=200', desc: 'Tail of fault log (JSON)' }, { method: 'GET', path: '/fualt.txt', desc: 'Download full fault log (TXT)' } ], example: `// Fetch tail of fualt.txt fetch('${baseUrl}/api/support/fualt?tail=200') .then(r => r.json()) .then(data => console.log(data.content));` } ]; } show() { if (this.modal) { this.modal.style.display = 'flex'; return; } this.modal = this.createModal(); document.body.appendChild(this.modal); } hide() { if (this.modal) { this.modal.style.display = 'none'; } } createModal() { const modal = document.createElement('div'); modal.className = 'config-helper-modal'; modal.innerHTML = `

API Configuration Guide

Use this guide to integrate quickly. Every endpoint listed below exists in the server and is safe to copy.

Base URL: ${window.location.origin}
✅ Copy-ready URLs ✅ Copy-ready code snippets ✅ `/api/endpoints` for discovery ✅ `/docs` for Swagger
cURL
curl -s '${window.location.origin}/api/health' | jq .
JavaScript (fetch)
fetch('${window.location.origin}/api/market?limit=10')
  .then(r => r.json())
  .then(console.log);
Python (requests)
import requests
print(requests.get('${window.location.origin}/api/market?limit=10', timeout=10).json())
Optional HF Token
export HF_TOKEN='YOUR_TOKEN_HERE'
${this.renderServices()}
`; // Event listeners modal.querySelector('.config-helper-close').addEventListener('click', () => this.hide()); modal.querySelector('.config-helper-overlay').addEventListener('click', () => this.hide()); // Copy buttons modal.querySelectorAll('.copy-btn').forEach(btn => { btn.addEventListener('click', (e) => { e.stopPropagation(); let text = btn.getAttribute('data-copy'); if (!text) { // Snippet cards copy their visible code block const codeEl = btn.closest('.snippet-card')?.querySelector('pre code'); text = codeEl?.textContent || ''; } this.copyToClipboard(text, btn); }); }); // Collapsible sections modal.querySelectorAll('.service-header').forEach(header => { header.addEventListener('click', () => { const service = header.parentElement; service.classList.toggle('expanded'); }); }); return modal; } renderServices() { const categories = {}; // Group by category this.services.forEach(service => { if (!categories[service.category]) { categories[service.category] = []; } categories[service.category].push(service); }); return Object.entries(categories).map(([category, services]) => `

${category}

${services.map(service => this.renderService(service)).join('')}
`).join(''); } renderService(service) { return `
${service.name}

${service.description}

Endpoints:

${service.endpoints.map(ep => `
${ep.method} ${ep.path} ${ep.desc}
`).join('')}
Example Usage:
${this.escapeHtml(service.example)}
`; } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } async copyToClipboard(text, button) { try { if (navigator.clipboard?.writeText) { await navigator.clipboard.writeText(text); } else { // Fallback for older browsers / restricted contexts const ta = document.createElement('textarea'); ta.value = text; ta.setAttribute('readonly', ''); ta.style.position = 'fixed'; ta.style.left = '-9999px'; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove(); } // Visual feedback const originalHTML = button.innerHTML; button.innerHTML = ` `; button.classList.add('copied'); setTimeout(() => { button.innerHTML = originalHTML; button.classList.remove('copied'); }, 2000); } catch (err) { console.error('Failed to copy:', err); } } } // Styles const style = document.createElement('style'); style.textContent = ` .config-helper-modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000; display: flex; align-items: center; justify-content: center; padding: 20px; } .config-helper-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(4px); } .config-helper-content { position: relative; background: var(--bg-main, #ffffff); border-radius: 16px; max-width: 900px; width: 100%; max-height: 85vh; display: flex; flex-direction: column; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); animation: modalSlideIn 0.3s ease; } @keyframes modalSlideIn { from { opacity: 0; transform: translateY(-20px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } .config-helper-header { display: flex; align-items: center; justify-content: space-between; padding: 24px; border-bottom: 1px solid var(--border-light, #e5e7eb); } .config-helper-header h2 { display: flex; align-items: center; gap: 12px; margin: 0; font-size: 20px; font-weight: 600; color: var(--text-primary, #0f2926); } .config-helper-header svg { color: var(--teal, #14b8a6); } .config-helper-close { background: none; border: none; padding: 8px; cursor: pointer; border-radius: 8px; color: var(--text-muted, #6b7280); transition: all 0.2s; } .config-helper-close:hover { background: var(--bg-secondary, #f3f4f6); color: var(--text-primary, #0f2926); } .config-helper-body { overflow-y: auto; padding: 24px; } .config-helper-intro { margin-bottom: 24px; } .config-helper-intro p { color: var(--text-secondary, #6b7280); margin-bottom: 12px; } .config-helper-base-url { display: flex; align-items: center; gap: 8px; padding: 12px; background: var(--bg-secondary, #f3f4f6); border-radius: 8px; font-size: 14px; margin-bottom: 12px; } .config-helper-base-url code { flex: 1; padding: 4px 8px; background: var(--bg-main, #ffffff); border-radius: 4px; font-family: 'Courier New', monospace; font-size: 13px; } .config-helper-stats { display: flex; flex-wrap: wrap; gap: 12px; padding: 12px; background: linear-gradient(135deg, #e0f2f1 0%, #b2dfdb 100%); border-radius: 8px; font-size: 13px; font-weight: 500; } .config-helper-stats span { padding: 4px 8px; background: rgba(255,255,255,0.7); border-radius: 4px; } .config-helper-snippets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 12px; } .snippet-card { background: var(--bg-secondary, #f8fdfc); border: 1px solid var(--border-light, #e5e7eb); border-radius: 12px; padding: 12px; overflow: hidden; } .snippet-head { display: flex; align-items: center; justify-content: space-between; font-size: 12px; font-weight: 700; color: var(--text-secondary, #6b7280); margin-bottom: 8px; } .snippet-card pre { margin: 0; background: #0b1220; color: #e2e8f0; padding: 10px; border-radius: 10px; overflow-x: auto; font-size: 12px; line-height: 1.5; } .service-category { margin-bottom: 24px; } .category-title { font-size: 16px; font-weight: 600; color: var(--teal, #14b8a6); margin-bottom: 12px; padding-bottom: 8px; border-bottom: 2px solid var(--teal-light, #2dd4bf); } .service-item { background: var(--bg-secondary, #f8fdfc); border: 1px solid var(--border-light, #e5e7eb); border-radius: 12px; margin-bottom: 12px; overflow: hidden; transition: all 0.2s; } .service-item:hover { border-color: var(--teal-light, #2dd4bf); } .service-header { padding: 16px; cursor: pointer; user-select: none; } .service-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; } .service-name { font-weight: 600; color: var(--text-primary, #0f2926); font-size: 15px; } .expand-icon { color: var(--text-muted, #6b7280); transition: transform 0.2s; } .service-item.expanded .expand-icon { transform: rotate(180deg); } .service-desc { color: var(--text-secondary, #6b7280); font-size: 13px; margin: 0; } .service-details { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } .service-item.expanded .service-details { max-height: 1000px; } .endpoints-list { padding: 0 16px 16px; } .endpoints-list h4 { font-size: 13px; font-weight: 600; color: var(--text-secondary, #6b7280); margin-bottom: 8px; } .endpoint-item { display: flex; align-items: center; gap: 8px; padding: 8px; background: var(--bg-main, #ffffff); border-radius: 6px; margin-bottom: 6px; font-size: 13px; } .method-badge { padding: 2px 8px; border-radius: 4px; font-weight: 600; font-size: 11px; text-transform: uppercase; } .method-badge.get { background: #10b981; color: white; } .method-badge.post { background: #3b82f6; color: white; } .method-badge.ws { background: #8b5cf6; color: white; } .endpoint-path { flex: 1; font-family: 'Courier New', monospace; font-size: 12px; color: var(--text-primary, #0f2926); word-break: break-all; } .endpoint-desc { color: var(--text-muted, #6b7280); font-size: 12px; white-space: nowrap; } .code-example { padding: 0 16px 16px; } .code-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; font-size: 13px; font-weight: 600; color: var(--text-secondary, #6b7280); } .code-example pre { background: #1e293b; color: #e2e8f0; padding: 12px; border-radius: 8px; overflow-x: auto; margin: 0; font-size: 12px; line-height: 1.6; } .copy-btn { background: var(--teal, #14b8a6); color: white; border: none; padding: 6px 12px; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; font-size: 12px; transition: all 0.2s; } .copy-btn:hover { background: var(--teal-dark, #0d7377); transform: translateY(-1px); } .copy-btn.copied { background: #10b981; } @media (max-width: 768px) { .config-helper-content { max-width: 100%; max-height: 95vh; margin: 10px; } .endpoint-item { flex-wrap: wrap; } .endpoint-desc { width: 100%; margin-top: 4px; white-space: normal; } .config-helper-stats { flex-direction: column; } .config-helper-snippets { grid-template-columns: 1fr; } } `; document.head.appendChild(style);