// Configuration const GAMMA_API = 'https://gamma-api.polymarket.com/markets'; const CLOB_API = 'https://clob.polymarket.com/markets'; const DATA_API = 'https://data-api.polymarket.com/trades?limit=5'; const FALLBACK_API = 'https://strapi-matic.poly.market/markets'; // Fallback if gamma fails const DEFAULT_PARAMS = { limit: 20, order: 'volumeNum desc', active: true }; const USE_FALLBACK = true; const REFRESH_INTERVAL = 30000; // 30 seconds // DOM Elements const marketsContainer = document.getElementById('markets-container'); const loadingElement = document.getElementById('loading'); const errorMessage = document.getElementById('error-message'); const refreshBtn = document.getElementById('refresh-btn'); const retryBtn = document.getElementById('retry-btn'); const categoryFilter = document.getElementById('category-filter'); // State let marketsData = []; let isLoading = false; // Initialize document.addEventListener('DOMContentLoaded', () => { fetchMarkets(); // Set up refresh interval setInterval(fetchMarkets, REFRESH_INTERVAL); // Event listeners refreshBtn.addEventListener('click', fetchMarkets); retryBtn.addEventListener('click', fetchMarkets); categoryFilter.addEventListener('change', filterMarkets); }); // Fetch markets data async function fetchMarkets() { if (isLoading) return; isLoading = true; loadingElement.classList.remove('hidden'); errorMessage.classList.add('hidden'); marketsContainer.innerHTML = ''; try { // Build URL with query params const url = new URL(GAMMA_API); Object.entries(DEFAULT_PARAMS).forEach(([key, value]) => { url.searchParams.append(key, value); }); // Try primary Gamma API first let response; try { response = await fetch(url, { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); if (!response.ok) throw new Error('Gamma API failed'); const data = await response.json(); marketsData = data.map(market => ({ id: market.id, title: market.question, category: market.category, volume: parseFloat(market.volumeNum), liquidity: parseFloat(market.liquidityNum), endDate: market.endDate, imageUrl: market.imageUrl || 'http://static.photos/abstract/640x360', outcomes: market.outcomePrices.split(',').map((price, i) => ({ name: i === 0 ? 'Yes' : 'No', price: parseFloat(price), probability: parseFloat(price) })) })); renderMarkets(marketsData); } catch (error) { console.error('Gamma API failed, trying fallback:', error); // Try fallback API if gamma fails try { const fallbackUrl = new URL(FALLBACK_API); Object.entries(DEFAULT_PARAMS).forEach(([key, value]) => { fallbackUrl.searchParams.append(key, value); }); response = await fetch(fallbackUrl); if (!response.ok) throw new Error('Fallback API failed'); const data = await response.json(); // Process fallback data differently if needed marketsData = data.map(market => ({ id: market.id, title: market.question, category: market.category, volume: parseFloat(market.volumeNum), liquidity: parseFloat(market.liquidityNum), endDate: market.endDate, imageUrl: market.imageUrl || 'http://static.photos/abstract/640x360', outcomes: market.outcomePrices.split(',').map((price, i) => ({ name: i === 0 ? 'Yes' : 'No', price: parseFloat(price), probability: parseFloat(price) })) })); renderMarkets(marketsData); showWarning('Using fallback data. Gamma API unavailable.'); } catch (fallbackError) { console.error('Fallback API also failed:', fallbackError); showError(); // If we have cached data, show it with a warning if (marketsData.length > 0) { renderMarkets(marketsData); showWarning('Showing cached data. Connection issues detected.'); } } } finally { isLoading = false; loadingElement.classList.add('hidden'); } } // Render markets function renderMarkets(markets) { marketsContainer.innerHTML = ''; if (markets.length === 0) { marketsContainer.innerHTML = `
Try adjusting your filters
${message}