- Organized 252 files across project - Root directory: 187 → 2 files (98.9% reduction) - Moved configuration guides to docs/04-configuration/ - Moved troubleshooting guides to docs/09-troubleshooting/ - Moved quick start guides to docs/01-getting-started/ - Moved reports to reports/ directory - Archived temporary files - Generated comprehensive reports and documentation - Created maintenance scripts and guides All files organized according to established standards.
130 lines
3.7 KiB
JavaScript
Executable File
130 lines
3.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* Address Checksum Validator and Fixer
|
|
* Validates and optionally fixes EIP-55 checksummed addresses in token lists
|
|
*/
|
|
|
|
import { readFileSync, writeFileSync } from 'fs';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, resolve } from 'path';
|
|
import { ethers } from 'ethers';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
function isChecksummed(address) {
|
|
try {
|
|
return ethers.isAddress(address) && address === ethers.getAddress(address);
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function checksumAddress(address) {
|
|
try {
|
|
// Convert to lowercase first if it's not valid, then checksum
|
|
return ethers.getAddress(address.toLowerCase());
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function validateAndFixAddresses(filePath, dryRun = true) {
|
|
console.log(`\n🔍 ${dryRun ? 'Validating' : 'Fixing'} addresses in: ${filePath}\n`);
|
|
|
|
// Read token list file
|
|
let tokenList;
|
|
try {
|
|
const fileContent = readFileSync(filePath, 'utf-8');
|
|
tokenList = JSON.parse(fileContent);
|
|
} catch (error) {
|
|
console.error('❌ Error reading or parsing token list file:');
|
|
console.error(` ${error.message}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const issues = [];
|
|
const fixed = [];
|
|
|
|
// Check all addresses
|
|
if (tokenList.tokens && Array.isArray(tokenList.tokens)) {
|
|
tokenList.tokens.forEach((token, index) => {
|
|
if (token.address) {
|
|
if (!isChecksummed(token.address)) {
|
|
const checksummed = checksumAddress(token.address);
|
|
if (checksummed) {
|
|
issues.push({
|
|
index,
|
|
token: token.symbol || token.name,
|
|
original: token.address,
|
|
checksummed,
|
|
type: 'non-checksummed'
|
|
});
|
|
|
|
if (!dryRun) {
|
|
token.address = checksummed;
|
|
fixed.push({
|
|
index,
|
|
token: token.symbol || token.name,
|
|
original: token.address,
|
|
fixed: checksummed
|
|
});
|
|
}
|
|
} else {
|
|
issues.push({
|
|
index,
|
|
token: token.symbol || token.name,
|
|
original: token.address,
|
|
checksummed: null,
|
|
type: 'invalid'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Report results
|
|
if (issues.length === 0) {
|
|
console.log('✅ All addresses are properly checksummed!\n');
|
|
return 0;
|
|
}
|
|
|
|
console.log(`Found ${issues.length} address issue(s):\n`);
|
|
issues.forEach(issue => {
|
|
if (issue.type === 'invalid') {
|
|
console.error(`❌ Token[${issue.index}] (${issue.token}): Invalid address format: ${issue.original}`);
|
|
} else {
|
|
console.log(`⚠️ Token[${issue.index}] (${issue.token}):`);
|
|
console.log(` Original: ${issue.original}`);
|
|
console.log(` Checksummed: ${issue.checksummed}`);
|
|
}
|
|
});
|
|
|
|
if (!dryRun && fixed.length > 0) {
|
|
console.log(`\n✏️ Fixed ${fixed.length} address(es)\n`);
|
|
|
|
// Write back to file
|
|
writeFileSync(filePath, JSON.stringify(tokenList, null, 2) + '\n', 'utf-8');
|
|
console.log(`✅ Updated file: ${filePath}\n`);
|
|
} else if (dryRun && issues.some(i => i.type !== 'invalid')) {
|
|
console.log(`\n💡 Run with --fix to automatically fix checksummed addresses\n`);
|
|
}
|
|
|
|
return issues.some(i => i.type === 'invalid') ? 1 : 0;
|
|
}
|
|
|
|
// Main
|
|
const args = process.argv.slice(2);
|
|
const filePath = args.find(arg => !arg.startsWith('--')) || resolve(__dirname, '../lists/dbis-138.tokenlist.json');
|
|
const dryRun = !args.includes('--fix');
|
|
|
|
if (!filePath) {
|
|
console.error('Usage: node checksum-addresses.js [path/to/token-list.json] [--fix]');
|
|
process.exit(1);
|
|
}
|
|
|
|
const exitCode = validateAndFixAddresses(filePath, dryRun);
|
|
process.exit(exitCode);
|
|
|