class TransferUtils {
static parseCSV(csvText) {
const lines = csvText.split('\n');
const transfers = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (!line) continue;
// 支持逗号分隔或制表符分隔
const parts = line.includes('\t') ? line.split('\t') : line.split(',');
if (parts.length >= 2) {
const address = parts[0].trim();
const amount = parts[1].trim();
const note = parts[2] ? parts[2].trim() : '';
// 基本验证
if (address && amount) {
transfers.push({
address,
amount: parseFloat(amount),
note
});
}
}
}
return transfers;
}
static formatAddress(address) {
if (!address || address.length < 10) return address;
return `${address.slice(0, 6)}...${address.slice(-4)}`;
}
static formatNumber(num, decimals = 4) {
if (isNaN(num)) return '0';
return parseFloat(num.toFixed(decimals)).toString();
}
static generateLogMessage(type, message) {
const time = new Date().toLocaleTimeString();
const types = {
success: { icon: '✅', class: 'success' },
error: { icon: '❌', class: 'error' },
info: { icon: 'ℹ️', class: 'info' },
warning: { icon: '⚠️', class: 'warning' }
};
const typeInfo = types[type] || types.info;
return {
time,
type: typeInfo.class,
message: `${typeInfo.icon} ${message}`,
html: `
${time}
${typeInfo.icon} ${message}
`
};
}
static exportToCSV(data, filename = 'transfer-results.csv') {
const headers = ['序号', '收款地址', '金额(BNB)', '状态', '交易哈希', '备注'];
const rows = data.map(item => [
item.index + 1,
item.to,
item.amount,
item.success ? '成功' : '失败',
item.hash || '',
item.error || ''
]);
const csvContent = [headers, ...rows]
.map(row => row.map(cell => `"${cell}"`).join(','))
.join('\n');
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, filename);
} else {
link.href = URL.createObjectURL(blob);
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
static validateEthereumAddress(address) {
try {
return ethers.utils.isAddress(address);
} catch {
return false;
}
}
static async checkBalanceSufficient(provider, address, requiredAmount) {
try {
const balance = await provider.getBalance(address);
const required = ethers.utils.parseEther(requiredAmount.toString());
return balance.gte(required);
} catch (error) {
console.error('检查余额失败:', error);
return false;
}
}
}
// 导出工具类
window.TransferUtils = TransferUtils;