| |
| |
| |
|
|
|
|
|
|
| const API_BASE_URL = window.location.origin;
|
|
|
|
|
| window.API_CONFIG = {
|
|
|
| baseUrl: API_BASE_URL,
|
| apiUrl: `${API_BASE_URL}/api`,
|
| smartApiUrl: `${API_BASE_URL}/api/smart`,
|
|
|
|
|
| endpoints: {
|
|
|
| smart: {
|
| market: `${API_BASE_URL}/api/smart/market`,
|
| news: `${API_BASE_URL}/api/smart/news`,
|
| sentiment: `${API_BASE_URL}/api/smart/sentiment`,
|
| whaleAlerts: `${API_BASE_URL}/api/smart/whale-alerts`,
|
| blockchain: `${API_BASE_URL}/api/smart/blockchain`,
|
| healthReport: `${API_BASE_URL}/api/smart/health-report`,
|
| stats: `${API_BASE_URL}/api/smart/stats`,
|
| },
|
|
|
|
|
| market: `${API_BASE_URL}/api/market`,
|
| marketHistory: `${API_BASE_URL}/api/market/history`,
|
| sentiment: `${API_BASE_URL}/api/sentiment/analyze`,
|
| health: `${API_BASE_URL}/api/health`,
|
|
|
|
|
| alphavantage: {
|
| health: `${API_BASE_URL}/api/alphavantage/health`,
|
| prices: `${API_BASE_URL}/api/alphavantage/prices`,
|
| ohlcv: `${API_BASE_URL}/api/alphavantage/ohlcv`,
|
| marketStatus: `${API_BASE_URL}/api/alphavantage/market-status`,
|
| cryptoRating: `${API_BASE_URL}/api/alphavantage/crypto-rating`,
|
| quote: `${API_BASE_URL}/api/alphavantage/quote`,
|
| },
|
|
|
|
|
| massive: {
|
| health: `${API_BASE_URL}/api/massive/health`,
|
| dividends: `${API_BASE_URL}/api/massive/dividends`,
|
| splits: `${API_BASE_URL}/api/massive/splits`,
|
| quotes: `${API_BASE_URL}/api/massive/quotes`,
|
| trades: `${API_BASE_URL}/api/massive/trades`,
|
| aggregates: `${API_BASE_URL}/api/massive/aggregates`,
|
| ticker: `${API_BASE_URL}/api/massive/ticker`,
|
| marketStatus: `${API_BASE_URL}/api/massive/market-status`,
|
| },
|
|
|
|
|
| docs: `${API_BASE_URL}/docs`,
|
| redoc: `${API_BASE_URL}/redoc`,
|
| },
|
|
|
|
|
| features: {
|
| useSmartFallback: true,
|
| resourceRotation: true,
|
| proxySupport: true,
|
| backgroundCollection: true,
|
| healthMonitoring: true,
|
| autoCleanup: true,
|
| },
|
|
|
|
|
| request: {
|
| timeout: 30000,
|
| retries: 3,
|
| retryDelay: 1000,
|
| },
|
|
|
|
|
| resources: {
|
| total: '305+',
|
| categories: {
|
| marketData: 21,
|
| blockExplorers: 40,
|
| news: 15,
|
| sentiment: 12,
|
| whaleTracking: 9,
|
| onchainAnalytics: 13,
|
| rpcNodes: 24,
|
| localBackend: 106,
|
| corsProxies: 7,
|
| }
|
| }
|
| };
|
|
|
| |
| |
|
|
| class SmartAPIClient {
|
| constructor(config = window.API_CONFIG) {
|
| this.config = config;
|
| this.authToken = this.getAuthToken();
|
| }
|
|
|
| |
| |
|
|
| getAuthToken() {
|
|
|
| let token = localStorage.getItem('hf_token');
|
|
|
|
|
| if (!token) {
|
| token = sessionStorage.getItem('hf_token');
|
| }
|
|
|
|
|
| if (!token) {
|
| const params = new URLSearchParams(window.location.search);
|
| token = params.get('token');
|
| }
|
|
|
| return token;
|
| }
|
|
|
| |
| |
|
|
| setAuthToken(token) {
|
| this.authToken = token;
|
| localStorage.setItem('hf_token', token);
|
| }
|
|
|
| |
| |
|
|
| getHeaders() {
|
| const headers = {
|
| 'Content-Type': 'application/json',
|
| 'Accept': 'application/json',
|
| };
|
|
|
| if (this.authToken) {
|
| headers['Authorization'] = `Bearer ${this.authToken}`;
|
| }
|
|
|
| return headers;
|
| }
|
|
|
| |
| |
|
|
| async fetchWithRetry(url, options = {}, retries = 3) {
|
| for (let i = 0; i < retries; i++) {
|
| try {
|
| const response = await fetch(url, {
|
| ...options,
|
| headers: {
|
| ...this.getHeaders(),
|
| ...options.headers,
|
| },
|
| timeout: this.config.request.timeout,
|
| });
|
|
|
| if (!response.ok) {
|
| throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
| }
|
|
|
| return await response.json();
|
| } catch (error) {
|
| console.warn(`Attempt ${i + 1} failed:`, error);
|
|
|
| if (i === retries - 1) {
|
| throw error;
|
| }
|
|
|
|
|
| await new Promise(resolve =>
|
| setTimeout(resolve, this.config.request.retryDelay * (i + 1))
|
| );
|
| }
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getMarketData(limit = 100) {
|
| try {
|
|
|
| return await this.fetchWithRetry(
|
| `${this.config.endpoints.smart.market}?limit=${limit}`
|
| );
|
| } catch (error) {
|
| console.error('Smart market data failed:', error);
|
|
|
|
|
| try {
|
| return await this.fetchWithRetry(
|
| `${this.config.endpoints.market}?limit=${limit}`
|
| );
|
| } catch (fallbackError) {
|
| console.error('All market data endpoints failed');
|
| throw fallbackError;
|
| }
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getNews(limit = 20) {
|
| try {
|
| return await this.fetchWithRetry(
|
| `${this.config.endpoints.smart.news}?limit=${limit}`
|
| );
|
| } catch (error) {
|
| console.error('Smart news failed:', error);
|
| throw error;
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getSentiment(symbol = null) {
|
| const url = symbol
|
| ? `${this.config.endpoints.smart.sentiment}?symbol=${symbol}`
|
| : this.config.endpoints.smart.sentiment;
|
|
|
| try {
|
| return await this.fetchWithRetry(url);
|
| } catch (error) {
|
| console.error('Smart sentiment failed:', error);
|
| throw error;
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getWhaleAlerts(limit = 20) {
|
| try {
|
| return await this.fetchWithRetry(
|
| `${this.config.endpoints.smart.whaleAlerts}?limit=${limit}`
|
| );
|
| } catch (error) {
|
| console.error('Smart whale alerts failed:', error);
|
| throw error;
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getBlockchainData(chain = 'ethereum') {
|
| try {
|
| return await this.fetchWithRetry(
|
| `${this.config.endpoints.smart.blockchain}/${chain}`
|
| );
|
| } catch (error) {
|
| console.error('Smart blockchain data failed:', error);
|
| throw error;
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getHealthReport() {
|
| try {
|
| return await this.fetchWithRetry(
|
| this.config.endpoints.smart.healthReport
|
| );
|
| } catch (error) {
|
| console.error('Health report failed:', error);
|
| throw error;
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getStats() {
|
| try {
|
| return await this.fetchWithRetry(
|
| this.config.endpoints.smart.stats
|
| );
|
| } catch (error) {
|
| console.error('Stats failed:', error);
|
| throw error;
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getAlphaVantageData(endpoint, params = {}) {
|
| const url = new URL(endpoint);
|
| Object.keys(params).forEach(key =>
|
| url.searchParams.append(key, params[key])
|
| );
|
|
|
| try {
|
| return await this.fetchWithRetry(url.toString());
|
| } catch (error) {
|
| console.error('Alpha Vantage request failed:', error);
|
| throw error;
|
| }
|
| }
|
|
|
| |
| |
|
|
| async getMassiveData(endpoint, params = {}) {
|
| const url = new URL(endpoint);
|
| Object.keys(params).forEach(key =>
|
| url.searchParams.append(key, params[key])
|
| );
|
|
|
| try {
|
| return await this.fetchWithRetry(url.toString());
|
| } catch (error) {
|
| console.error('Massive.com request failed:', error);
|
| throw error;
|
| }
|
| }
|
| }
|
|
|
|
|
| window.apiClient = new SmartAPIClient();
|
|
|
|
|
| if (typeof module !== 'undefined' && module.exports) {
|
| module.exports = { API_CONFIG, SmartAPIClient };
|
| }
|
|
|
| console.log('β
API Configuration loaded successfully');
|
| console.log('π Smart Fallback System: 305+ resources available');
|
| console.log('π Resource rotation: ENABLED');
|
| console.log('π Proxy support: ENABLED');
|
| console.log('β¨ Features:', window.API_CONFIG.features);
|
|
|