88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
#!/usr/bin/env node
|
|
// Temporary script: fetch name + homepage URL for every token in tokenList.js
|
|
// Phase 1: CoinGecko /coins/list (1 bulk call) for names — gets 100%
|
|
// Phase 2: ethereum-lists GitHub repo for project URLs — gets ~15%
|
|
|
|
import { readFileSync, writeFileSync } from "fs";
|
|
|
|
const src = readFileSync("src/shared/tokenList.js", "utf8");
|
|
|
|
const tokens = [];
|
|
const re =
|
|
/\{\s*address:\s*"(0x[a-fA-F0-9]{40})",\s*symbol:\s*"([^"]+)",\s*decimals:\s*(\d+)/g;
|
|
let m;
|
|
while ((m = re.exec(src)) !== null) {
|
|
tokens.push({ address: m[1], symbol: m[2], decimals: parseInt(m[3]) });
|
|
}
|
|
console.error(`Parsed ${tokens.length} tokens`);
|
|
|
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
|
// --- Phase 1: bulk names from CoinGecko ---
|
|
console.error("Fetching CoinGecko coins list...");
|
|
const listResp = await fetch(
|
|
"https://api.coingecko.com/api/v3/coins/list?include_platform=true",
|
|
);
|
|
if (!listResp.ok) throw new Error(`CoinGecko list HTTP ${listResp.status}`);
|
|
const coins = await listResp.json();
|
|
|
|
const addrMap = new Map();
|
|
for (const coin of coins) {
|
|
const eth = (coin.platforms?.ethereum || "").toLowerCase().trim();
|
|
if (eth && eth.startsWith("0x")) {
|
|
addrMap.set(eth, { name: coin.name, id: coin.id });
|
|
}
|
|
}
|
|
console.error(`CoinGecko map: ${addrMap.size} Ethereum tokens`);
|
|
|
|
const enriched = new Map();
|
|
for (const t of tokens) {
|
|
const info = addrMap.get(t.address.toLowerCase());
|
|
enriched.set(t.address, { name: info?.name || t.symbol, url: "" });
|
|
}
|
|
console.error(
|
|
`Matched ${[...enriched.values()].filter((e) => e.name).length}/${tokens.length} names`,
|
|
);
|
|
|
|
// --- Phase 2: ethereum-lists GitHub for URLs ---
|
|
console.error("Fetching URLs from ethereum-lists GitHub...");
|
|
const CONCURRENT = 10;
|
|
let urlsFound = 0;
|
|
|
|
for (let i = 0; i < tokens.length; i += CONCURRENT) {
|
|
const batch = tokens.slice(i, i + CONCURRENT);
|
|
await Promise.allSettled(
|
|
batch.map(async (t) => {
|
|
try {
|
|
const r = await fetch(
|
|
`https://raw.githubusercontent.com/ethereum-lists/tokens/master/tokens/eth/${t.address}.json`,
|
|
);
|
|
if (!r.ok) return;
|
|
const data = await r.json();
|
|
const website = (data.website || "").trim();
|
|
if (website && website !== "https://") {
|
|
enriched.get(t.address).url = website;
|
|
urlsFound++;
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}),
|
|
);
|
|
if (i % 100 === 0) {
|
|
console.error(
|
|
` GitHub: ${Math.min(i + CONCURRENT, tokens.length)}/${tokens.length}, ${urlsFound} URLs`,
|
|
);
|
|
}
|
|
await sleep(200);
|
|
}
|
|
console.error(`Phase 2 done: ${urlsFound} URLs from ethereum-lists`);
|
|
|
|
// --- Output ---
|
|
const output = {};
|
|
for (const [addr, e] of enriched) {
|
|
output[addr] = { name: e.name, url: e.url };
|
|
}
|
|
writeFileSync("scripts/token-enrichment.json", JSON.stringify(output, null, 2));
|
|
console.error(`Done! ${tokens.length} names, ${urlsFound} URLs.`);
|