// NAC XIC Token Presale — Contract Configuration // Design: Dark Cyberpunk / Quantum Finance // Colors: Amber Gold #f0b429, Quantum Blue #00d4ff, Deep Black #0a0a0f // ============================================================ // CONTRACT ADDRESSES // ============================================================ export const CONTRACTS = { // BSC Mainnet (Chain ID: 56) BSC: { chainId: 56, chainName: "BNB Smart Chain", rpcUrl: "https://bsc-dataseed1.binance.org/", explorerUrl: "https://bscscan.com", nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, presale: "0x5953c025dA734e710886916F2d739A3A78f8bbc4", // XICPresale v2 — 购买即时发放 token: "0x59FF34dD59680a7125782b1f6df2A86ed46F5A24", usdt: "0x55d398326f99059fF775485246999027B3197955", }, // Ethereum Mainnet (Chain ID: 1) ETH: { chainId: 1, chainName: "Ethereum", rpcUrl: "https://eth.llamarpc.com", explorerUrl: "https://etherscan.io", nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, presale: "0x43DAb577f3279e11D311E7d628C6201d893A9Aa3", token: "", // XIC not yet on ETH usdt: "0xdAC17F958D2ee523a2206206994597C13D831ec7", }, // TRON (TRC20) — Manual transfer TRON: { chainId: 0, // Not EVM chainName: "TRON", explorerUrl: "https://tronscan.org", presale: "", // TRC20 uses manual transfer token: "", usdt: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", // Receiving wallet for TRC20 USDT receivingWallet: "TWc2ugYBFN5aSoimAh4qGt9oMyket6NYZp", }, } as const; // ============================================================ // PRESALE PARAMETERS // ============================================================ export const PRESALE_CONFIG = { tokenPrice: 0.02, // $0.02 per XIC tokenSymbol: "XIC", tokenName: "New AssetChain Token", tokenDecimals: 18, minPurchaseUSDT: 0, // No minimum purchase limit maxPurchaseUSDT: 50000, // Max $50,000 USDT per purchase totalSupply: 100_000_000_000, // 100 billion XIC presaleAllocation: 2_500_000_000, // 2.5 billion for presale (25亿) // TRC20 memo format trc20Memo: "XIC_PRESALE", }; // ============================================================ // PRESALE CONTRACT ABI (BSC & ETH — same interface) // ============================================================ export const PRESALE_ABI = [ // Read functions { "inputs": [], "name": "tokenPrice", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalTokensSold", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalRaised", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "presaleActive", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "hardCap", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "user", "type": "address" }], "name": "userPurchases", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, // Write functions { "inputs": [{ "internalType": "uint256", "name": "usdtAmount", "type": "uint256" }], "name": "buyTokensWithUSDT", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "buyTokens", "outputs": [], "stateMutability": "payable", "type": "function" }, // Events { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "buyer", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "usdtAmount", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "tokenAmount", "type": "uint256" } ], "name": "TokensPurchased", "type": "event" } ] as const; // ============================================================ // ERC20 USDT ABI (minimal — approve + allowance + balanceOf) // ============================================================ export const ERC20_ABI = [ { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "balanceOf", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "stateMutability": "view", "type": "function" } ] as const; // ============================================================ // NETWORK SWITCH HELPER // ============================================================ export async function switchToNetwork(chainId: number): Promise { if (!window.ethereum) throw new Error("No wallet detected"); const hexChainId = "0x" + chainId.toString(16); try { await window.ethereum.request({ method: "wallet_switchEthereumChain", params: [{ chainId: hexChainId }], }); } catch (err: unknown) { // Chain not added yet — add it if ((err as { code?: number }).code === 4902) { const network = Object.values(CONTRACTS).find(n => n.chainId === chainId); if (!network || !("rpcUrl" in network)) throw new Error("Unknown network"); await window.ethereum.request({ method: "wallet_addEthereumChain", params: [{ chainId: hexChainId, chainName: network.chainName, rpcUrls: [(network as { rpcUrl: string }).rpcUrl], nativeCurrency: (network as { nativeCurrency: { name: string; symbol: string; decimals: number } }).nativeCurrency, blockExplorerUrls: [network.explorerUrl], }], }); } else { throw err; } } } // ============================================================ // FORMAT HELPERS // ============================================================ export function formatNumber(n: number, decimals = 2): string { if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(decimals) + "B"; if (n >= 1_000_000) return (n / 1_000_000).toFixed(decimals) + "M"; if (n >= 1_000) return (n / 1_000).toFixed(decimals) + "K"; return n.toFixed(decimals); } export function shortenAddress(addr: string): string { if (!addr) return ""; return addr.slice(0, 6) + "..." + addr.slice(-4); } // Declare window.ethereum for TypeScript declare global { interface Window { ethereum?: { request: (args: { method: string; params?: unknown[] }) => Promise; on: (event: string, handler: (...args: unknown[]) => void) => void; removeListener: (event: string, handler: (...args: unknown[]) => void) => void; isMetaMask?: boolean; }; } }