sumittechmero's picture
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();
}