- Added Ethereum Mainnet token list (1 token: USDT) - Updated ChainID 138 token list (6 tokens: added cUSDT and cUSDC) - Added ALL Mainnet token list (9 tokens including AUSDT) - Discovered ALL Mainnet tokens via Transfer event scanning - Updated validation scripts for multi-chain support - Created comprehensive documentation and guides - Updated master documentation indexes - All token lists validated and ready for submission
212 lines
6.2 KiB
JavaScript
Executable File
212 lines
6.2 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
/**
|
||
* Token Discovery Script for ALL Mainnet
|
||
*
|
||
* Attempts to discover ERC-20 tokens by:
|
||
* 1. Checking recent contract creation events
|
||
* 2. Querying known/common token addresses
|
||
* 3. Scanning for ERC-20 Transfer events
|
||
*
|
||
* Usage:
|
||
* node discover-all-mainnet-tokens.js [--recent-blocks=1000] [--check-addresses=0x...,0x...]
|
||
*/
|
||
|
||
import { ethers } from 'ethers';
|
||
|
||
const RPC_URL = 'https://mainnet-rpc.alltra.global';
|
||
const CHAIN_ID = 651940;
|
||
|
||
// ERC-20 ABI (minimal)
|
||
const ERC20_ABI = [
|
||
'function symbol() view returns (string)',
|
||
'function name() view returns (string)',
|
||
'function decimals() view returns (uint8)',
|
||
'function totalSupply() view returns (uint256)'
|
||
];
|
||
|
||
// ERC-20 Transfer event signature
|
||
const TRANSFER_EVENT = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
|
||
|
||
async function checkToken(address, provider) {
|
||
try {
|
||
const code = await provider.getCode(address);
|
||
if (code === '0x' || code.length < 10) {
|
||
return null;
|
||
}
|
||
|
||
const contract = new ethers.Contract(address, ERC20_ABI, provider);
|
||
|
||
const [symbol, name, decimals] = await Promise.all([
|
||
contract.symbol().catch(() => null),
|
||
contract.name().catch(() => null),
|
||
contract.decimals().catch(() => null)
|
||
]);
|
||
|
||
if (!symbol || !name || decimals === null) {
|
||
return null;
|
||
}
|
||
|
||
return {
|
||
chainId: CHAIN_ID,
|
||
address: ethers.getAddress(address),
|
||
name: name,
|
||
symbol: symbol,
|
||
decimals: Number(decimals)
|
||
};
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async function discoverFromRecentBlocks(provider, blockCount = 1000) {
|
||
console.log(`\n🔍 Scanning last ${blockCount} blocks for token contracts...\n`);
|
||
|
||
const currentBlock = await provider.getBlockNumber();
|
||
const startBlock = Math.max(0, currentBlock - blockCount);
|
||
|
||
console.log(`Scanning blocks ${startBlock} to ${currentBlock}...`);
|
||
|
||
// Look for contract creation events
|
||
const tokens = new Set();
|
||
|
||
// Check recent blocks for contract creations
|
||
for (let i = 0; i < Math.min(100, blockCount); i++) {
|
||
const blockNum = currentBlock - i;
|
||
try {
|
||
const block = await provider.getBlock(blockNum, true);
|
||
if (block && block.transactions) {
|
||
for (const tx of block.transactions) {
|
||
if (tx.to === null && tx.creates) {
|
||
// Contract creation
|
||
tokens.add(tx.creates);
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
// Skip errors
|
||
}
|
||
}
|
||
|
||
console.log(`Found ${tokens.size} potential contract addresses\n`);
|
||
|
||
const results = [];
|
||
for (const address of tokens) {
|
||
const token = await checkToken(address, provider);
|
||
if (token) {
|
||
results.push(token);
|
||
console.log(` ✅ ${token.symbol} (${token.name}) - ${token.address}`);
|
||
}
|
||
}
|
||
|
||
return results;
|
||
}
|
||
|
||
async function checkCommonAddresses(provider) {
|
||
console.log('\n🔍 Checking common token addresses...\n');
|
||
|
||
// Common stablecoin addresses (may differ on ALL Mainnet)
|
||
const commonAddresses = [
|
||
// USDT-like addresses (these are examples, actual addresses may differ)
|
||
// USDC-like addresses
|
||
// Add more if known
|
||
];
|
||
|
||
const results = [];
|
||
|
||
if (commonAddresses.length === 0) {
|
||
console.log('No common addresses to check. Add addresses to checkCommonAddresses() function.\n');
|
||
return results;
|
||
}
|
||
|
||
for (const address of commonAddresses) {
|
||
console.log(`Checking ${address}...`);
|
||
const token = await checkToken(address, provider);
|
||
if (token) {
|
||
results.push(token);
|
||
console.log(` ✅ ${token.symbol} (${token.name})\n`);
|
||
} else {
|
||
console.log(` ❌ Not a token contract\n`);
|
||
}
|
||
}
|
||
|
||
return results;
|
||
}
|
||
|
||
async function main() {
|
||
const args = process.argv.slice(2);
|
||
const blockCount = parseInt(args.find(a => a.startsWith('--recent-blocks='))?.split('=')[1] || '1000');
|
||
const checkAddrs = args.find(a => a.startsWith('--check-addresses='))?.split('=')[1]?.split(',') || [];
|
||
|
||
console.log(`🔍 Discovering tokens on ALL Mainnet (ChainID ${CHAIN_ID})\n`);
|
||
console.log(`RPC: ${RPC_URL}\n`);
|
||
|
||
const provider = new ethers.JsonRpcProvider(RPC_URL);
|
||
|
||
// Verify chain
|
||
const network = await provider.getNetwork();
|
||
if (Number(network.chainId) !== CHAIN_ID) {
|
||
console.error(`⚠️ Chain ID mismatch: expected ${CHAIN_ID}, got ${Number(network.chainId)}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
const currentBlock = await provider.getBlockNumber();
|
||
console.log(`✅ Connected (block: ${currentBlock})\n`);
|
||
|
||
const allTokens = [];
|
||
|
||
// Check provided addresses
|
||
if (checkAddrs.length > 0) {
|
||
console.log('🔍 Checking provided addresses...\n');
|
||
for (const addr of checkAddrs) {
|
||
const token = await checkToken(addr, provider);
|
||
if (token) {
|
||
allTokens.push(token);
|
||
console.log(` ✅ ${token.symbol} (${token.name}) - ${token.address}\n`);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check common addresses
|
||
const commonTokens = await checkCommonAddresses(provider);
|
||
allTokens.push(...commonTokens);
|
||
|
||
// Discover from recent blocks (if requested)
|
||
if (blockCount > 0) {
|
||
const discoveredTokens = await discoverFromRecentBlocks(provider, blockCount);
|
||
allTokens.push(...discoveredTokens);
|
||
}
|
||
|
||
// Remove duplicates
|
||
const uniqueTokens = Array.from(
|
||
new Map(allTokens.map(t => [t.address.toLowerCase(), t])).values()
|
||
);
|
||
|
||
if (uniqueTokens.length > 0) {
|
||
console.log(`\n📋 Found ${uniqueTokens.length} token(s):\n`);
|
||
uniqueTokens.forEach((token, i) => {
|
||
console.log(`${i + 1}. ${token.symbol} (${token.name})`);
|
||
console.log(` Address: ${token.address}`);
|
||
console.log(` Decimals: ${token.decimals}\n`);
|
||
});
|
||
|
||
console.log('\n📋 Token List JSON:\n');
|
||
console.log(JSON.stringify({
|
||
tokens: uniqueTokens.map(t => ({
|
||
chainId: t.chainId,
|
||
address: t.address,
|
||
name: t.name,
|
||
symbol: t.symbol,
|
||
decimals: t.decimals
|
||
}))
|
||
}, null, 2));
|
||
} else {
|
||
console.log('\n⚠️ No tokens discovered.\n');
|
||
console.log('To discover tokens:');
|
||
console.log('1. Visit https://alltra.global/tokens');
|
||
console.log('2. Get token addresses from explorer');
|
||
console.log('3. Run: node discover-all-mainnet-tokens.js --check-addresses=0x...,0x...');
|
||
}
|
||
}
|
||
|
||
main().catch(console.error);
|