Closed iamacook closed 1 month ago
@compojoom shared the following script he used to scrape the stablecoins from CoinGecko:
const axios = require('axios');
const fs = require('fs');
const API_URL = 'https://api.coingecko.com/api/v3';
const API_KEY = ''; // Replace with your actual API key
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
async function getStablecoins() {
try {
const url = `${API_URL}/coins/markets`;
const params = {
vs_currency: 'usd',
category: 'stablecoins',
order: 'market_cap_desc',
per_page: 250, // Get the first 10 stablecoins
page: 1,
sparkline: false
};
const headers = {
'accept': 'application/json',
'x-cg-demo-api-key': API_KEY
};
const { data } = await axios.get(url, { params, headers });
return data.map(coin => ({
id: coin.id,
name: coin.name,
symbol: coin.symbol
}));
} catch (error) {
// console.log(error)
// if (error.response && error.response.status === 429) {
// console.log('Rate limited. Waiting for 10 seconds...');
// await delay(10000);
// return getCoinDetails(coinId);
// }
handleError(error, 'Error fetching stablecoins');
}
}
const MAX_RETRIES = 3
async function getCoinDetails(coinId, retries = 1) {
try {
await delay(3000);
const url = `${API_URL}/coins/${coinId}?tickers=false&market_data=false&community_data=false&developer_data=false&sparkline=false&localization=false`;
console.log('url for coin details:', url)
const headers = {
'accept': 'application/json',
'x-cg-demo-api-key': API_KEY,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept-Language': 'en-US,en;q=0.9',
};
const { data } = await axios.get(url, { headers });
return data;
} catch (error) {
// console.log(error)
// if error 429, try again after 10 seconds
// if (error.response && error.response.status === 429) {
if (retries < MAX_RETRIES) {
console.log('Rate limited. Waiting for 10 seconds...');
await delay(10000*retries);
return getCoinDetails(coinId, retries + 1);
}
handleError(error, `Error fetching details for coin ID: ${coinId}`);
}
}
async function getContractAddresses(coinDetails) {
const contracts = {};
const networks = ['ethereum', 'gnosis', 'arbitrum-one'];
networks.forEach(network => {
if (coinDetails.platforms[network]) {
contracts[network] = coinDetails.platforms[network];
}
});
return contracts;
}
async function formatData(stablecoins) {
const formattedData = {};
for (const stablecoin of stablecoins) {
try {
const coinDetails = await getCoinDetails(stablecoin.id);
const contracts = await getContractAddresses(coinDetails);
for (const [network, address] of Object.entries(contracts)) {
if (!formattedData[address]) {
formattedData[address] = {
name: stablecoin.name,
symbol: stablecoin.symbol,
chains: [network]
};
} else {
formattedData[address].chains.push(network);
}
}
} catch (error) {
console.error(`Error processing stablecoin ${stablecoin.name} (${stablecoin.symbol}):`, error.message);
}
}
return formattedData;
}
function handleError(error, message) {
if (error.response) {
console.error(`${message}: ${error.response.status} - ${error.response.statusText}`);
} else if (error.request) {
console.error(`${message}: No response received from the server`);
} else {
console.error(`${message}: ${error.message}`);
}
process.exit(1); // Exit the process with an error code
}
(async () => {
try {
const stablecoins = await getStablecoins();
if (!stablecoins) return;
const formattedData = await formatData(stablecoins);
// Save data to a JSON file
fs.writeFileSync('stablecoins.json', JSON.stringify(formattedData, null, 2));
console.log('Data saved to stablecoins.json');
} catch (error) {
handleError(error, 'Error during processing');
}
})();
After discussion within the team (and as stablecoins don't frequently change), we will continue using a hardcoded list. Should this chage, we can consider revisiting this. cc @compojoom
Description
Clients require a list of stablecoins for swaps. This is currently hardcoded but was scraped from CoinGecko.
Whilst this could be included in the Config Service, we might be able to return it directly from CoinGecko as they are integrated in the project.
Note: if the CoinGecko API does not expose a dedicated stablecoin list, it would make sense to move these to the Config Service. Whether it be to the
Chain
model or not needs to be decided as we shoul avoid bloating it.Requirements
Integrate new endpoint to return stablecoins for a given chain, either from CoinGecko or the Config Service.
Additional information
No response