It is calling this ednpoing which is incorrect: https://strapi-matic.poly.market/markets
1646b03
verified
| // 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 = ` | |
| <div class="col-span-full text-center py-10"> | |
| <i data-feather="inbox" class="w-12 h-12 text-gray-400 mx-auto"></i> | |
| <h2 class="text-xl font-semibold text-gray-800 dark:text-gray-200 mt-4">No markets found</h2> | |
| <p class="text-gray-600 dark:text-gray-400 mt-2">Try adjusting your filters</p> | |
| </div> | |
| `; | |
| feather.replace(); | |
| return; | |
| } | |
| markets.forEach(market => { | |
| const marketCard = document.createElement('market-card'); | |
| marketCard.setAttribute('title', market.title); | |
| marketCard.setAttribute('category', market.category); | |
| marketCard.setAttribute('volume', market.volume.toLocaleString()); | |
| marketCard.setAttribute('liquidity', market.liquidity.toLocaleString()); | |
| marketCard.setAttribute('end-date', new Date(market.endDate).toLocaleDateString()); | |
| marketCard.setAttribute('image-url', market.imageUrl || 'http://static.photos/abstract/640x360'); | |
| // Add outcomes | |
| market.outcomes.forEach((outcome, index) => { | |
| marketCard.setAttribute(`outcome-${index}-name`, outcome.name); | |
| marketCard.setAttribute(`outcome-${index}-price`, outcome.price.toFixed(2)); | |
| marketCard.setAttribute(`outcome-${index}-probability`, (outcome.probability * 100).toFixed(1)); | |
| }); | |
| marketsContainer.appendChild(marketCard); | |
| }); | |
| feather.replace(); | |
| } | |
| // Filter markets by category | |
| function filterMarkets() { | |
| const selectedCategory = categoryFilter.value; | |
| if (selectedCategory === 'all') { | |
| renderMarkets(marketsData); | |
| return; | |
| } | |
| const filteredMarkets = marketsData.filter(market => | |
| market.category === selectedCategory | |
| ); | |
| renderMarkets(filteredMarkets); | |
| } | |
| // Enhanced market data processing | |
| function processMarketData(rawData) { | |
| return rawData.map(market => { | |
| const outcomes = market.outcomePrices.split(','); | |
| return { | |
| ...market, | |
| outcomes: [ | |
| { name: 'Yes', price: parseFloat(outcomes[0]), probability: parseFloat(outcomes[0]) }, | |
| { name: 'No', price: parseFloat(outcomes[1]), probability: parseFloat(outcomes[1]) } | |
| ], | |
| volume: market.volumeNum, | |
| liquidity: market.liquidityNum | |
| }; | |
| }); | |
| } | |
| // Fetch recent trades for a market (optional) | |
| async function fetchMarketTrades(marketId) { | |
| try { | |
| const response = await fetch(`${DATA_API}&market=${marketId}`); | |
| if (!response.ok) return null; | |
| return await response.json(); | |
| } catch (error) { | |
| console.error('Error fetching trades:', error); | |
| return null; | |
| } | |
| } | |
| // Show error message | |
| function showError() { | |
| errorMessage.classList.remove('hidden'); | |
| marketsContainer.innerHTML = ''; | |
| } | |
| // Show warning message | |
| function showWarning(message) { | |
| const warningElement = document.createElement('div'); | |
| warningElement.className = 'bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4 mb-6'; | |
| warningElement.innerHTML = ` | |
| <div class="flex items-center"> | |
| <i data-feather="alert-triangle" class="w-5 h-5 mr-2"></i> | |
| <p>${message}</p> | |
| </div> | |
| `; | |
| marketsContainer.parentNode.insertBefore(warningElement, marketsContainer); | |
| feather.replace(); | |
| } | |