| … | … | @@ -1746,7 +1746,21 @@ async function loadCurrentBalance() { |
| 1746 | 1746 | // Load unified Ethereum balances (ETH + USDT + USDC) |
| 1747 | 1747 | async function loadEthereumBalances() { |
| 1748 | 1748 | const container = document.getElementById('wallet-balance-display') |
| 1749 | | container.innerHTML = '<div class="spinner"></div>' |
| 1749 | |
| 1750 | // Show loading with asset placeholders |
| 1751 | container.innerHTML = ` |
| 1752 | <div class="unified-balance"> |
| 1753 | <div class="total-value"> |
| 1754 | <span class="total-usd">Loading...</span> |
| 1755 | <span class="total-label">Total Balance</span> |
| 1756 | </div> |
| 1757 | <div class="asset-list"> |
| 1758 | <div class="asset-row"><span class="asset-icon">Ξ</span><span class="asset-name">ETH</span><span class="asset-balance">...</span></div> |
| 1759 | <div class="asset-row"><span class="asset-icon">₮</span><span class="asset-name">USDT</span><span class="asset-balance">...</span></div> |
| 1760 | <div class="asset-row"><span class="asset-icon">$</span><span class="asset-name">USDC</span><span class="asset-balance">...</span></div> |
| 1761 | </div> |
| 1762 | </div> |
| 1763 | ` |
| 1750 | 1764 | |
| 1751 | 1765 | try { |
| 1752 | 1766 | const res = await authFetch(`/api/balances/ethereum`) |
| … | … | @@ -1759,20 +1773,29 @@ async function loadEthereumBalances() { |
| 1759 | 1773 | |
| 1760 | 1774 | const { balances } = data |
| 1761 | 1775 | |
| 1762 | | const ethAmount = Number(balances.eth.balance) / 1e18 |
| 1763 | | const usdtAmount = Number(balances.usdt.balance) / 1e6 |
| 1764 | | const usdcAmount = Number(balances.usdc.balance) / 1e6 |
| 1776 | // Handle missing balances gracefully |
| 1777 | const ethBalance = balances?.eth?.balance || '0' |
| 1778 | const usdtBalance = balances?.usdt?.balance || '0' |
| 1779 | const usdcBalance = balances?.usdc?.balance || '0' |
| 1765 | 1780 | |
| 1766 | | const ethUsd = ethAmount * (prices.ethereum || 0) |
| 1767 | | const usdtUsd = usdtAmount * (prices.tether || 1) |
| 1768 | | const usdcUsd = usdcAmount * (prices['usd-coin'] || 1) |
| 1781 | const ethAmount = Number(ethBalance) / 1e18 |
| 1782 | const usdtAmount = Number(usdtBalance) / 1e6 |
| 1783 | const usdcAmount = Number(usdcBalance) / 1e6 |
| 1784 | |
| 1785 | // Use testnet-appropriate USD values (show 0 for testnet) |
| 1786 | const isTestnet = selectedNetwork === 'testnet' |
| 1787 | const ethUsd = isTestnet ? 0 : ethAmount * (prices.ethereum || 0) |
| 1788 | const usdtUsd = isTestnet ? 0 : usdtAmount * (prices.tether || 1) |
| 1789 | const usdcUsd = isTestnet ? 0 : usdcAmount * (prices['usd-coin'] || 1) |
| 1769 | 1790 | const totalUsd = ethUsd + usdtUsd + usdcUsd |
| 1770 | 1791 | |
| 1792 | const totalDisplay = isTestnet ? 'Testnet' : formatUSD(totalUsd) |
| 1793 | |
| 1771 | 1794 | container.innerHTML = ` |
| 1772 | 1795 | <div class="unified-balance"> |
| 1773 | 1796 | <div class="total-value"> |
| 1774 | | <span class="total-usd">${formatUSD(totalUsd)}</span> |
| 1775 | | <span class="total-label">Total Balance</span> |
| 1797 | <span class="total-usd">${totalDisplay}</span> |
| 1798 | <span class="total-label">${isTestnet ? 'Sepolia Testnet' : 'Total Balance'}</span> |
| 1776 | 1799 | </div> |
| 1777 | 1800 | |
| 1778 | 1801 | <div class="asset-list"> |
| … | … | @@ -1781,7 +1804,7 @@ async function loadEthereumBalances() { |
| 1781 | 1804 | <span class="asset-icon">Ξ</span> |
| 1782 | 1805 | <span class="asset-name">ETH</span> |
| 1783 | 1806 | <span class="asset-balance">${ethAmount.toFixed(6)}</span> |
| 1784 | | <span class="asset-usd">${formatUSD(ethUsd)}</span> |
| 1807 | <span class="asset-usd">${isTestnet ? '' : formatUSD(ethUsd)}</span> |
| 1785 | 1808 | </div> |
| 1786 | 1809 | |
| 1787 | 1810 | <div class="asset-row ${selectedAsset === 'usdt' ? 'selected' : ''}" |
| … | … | @@ -1789,7 +1812,7 @@ async function loadEthereumBalances() { |
| 1789 | 1812 | <span class="asset-icon">₮</span> |
| 1790 | 1813 | <span class="asset-name">USDT</span> |
| 1791 | 1814 | <span class="asset-balance">${usdtAmount.toFixed(2)}</span> |
| 1792 | | <span class="asset-usd">${formatUSD(usdtUsd)}</span> |
| 1815 | <span class="asset-usd">${isTestnet ? '' : formatUSD(usdtUsd)}</span> |
| 1793 | 1816 | </div> |
| 1794 | 1817 | |
| 1795 | 1818 | <div class="asset-row ${selectedAsset === 'usdc' ? 'selected' : ''}" |
| … | … | @@ -1797,20 +1820,25 @@ async function loadEthereumBalances() { |
| 1797 | 1820 | <span class="asset-icon">$</span> |
| 1798 | 1821 | <span class="asset-name">USDC</span> |
| 1799 | 1822 | <span class="asset-balance">${usdcAmount.toFixed(2)}</span> |
| 1800 | | <span class="asset-usd">${formatUSD(usdcUsd)}</span> |
| 1823 | <span class="asset-usd">${isTestnet ? '' : formatUSD(usdcUsd)}</span> |
| 1801 | 1824 | </div> |
| 1802 | 1825 | </div> |
| 1803 | 1826 | |
| 1804 | 1827 | ${ethAmount < 0.001 ? ` |
| 1805 | 1828 | <div class="gas-warning"> |
| 1806 | | ⚠️ Low ETH balance - needed for gas fees |
| 1829 | ⚠️ Low ETH - needed for gas fees to send tokens |
| 1807 | 1830 | </div> |
| 1808 | 1831 | ` : ''} |
| 1809 | 1832 | </div> |
| 1810 | 1833 | ` |
| 1811 | 1834 | } catch (err) { |
| 1812 | 1835 | console.error('Load balances error:', err) |
| 1813 | | container.innerHTML = '<span class="error">Failed to load balances</span>' |
| 1836 | container.innerHTML = ` |
| 1837 | <div class="unified-balance"> |
| 1838 | <div class="error">Failed to load balances</div> |
| 1839 | <button onclick="loadEthereumBalances()" class="btn-secondary">Retry</button> |
| 1840 | </div> |
| 1841 | ` |
| 1814 | 1842 | } |
| 1815 | 1843 | } |
| 1816 | 1844 | |
| … | … | @@ -2686,12 +2714,36 @@ function closeTxDetails() { |
| 2686 | 2714 | async function showSend(chain) { |
| 2687 | 2715 | currentSendChain = chain |
| 2688 | 2716 | const modal = document.getElementById('send-modal') |
| 2689 | | const chainName = chain.charAt(0).toUpperCase() + chain.slice(1) |
| 2717 | |
| 2718 | // Get proper display name for chain/token |
| 2719 | let displayName, unit, decimals |
| 2720 | if (chain === 'ethereum-usdt') { |
| 2721 | displayName = 'USDT' |
| 2722 | unit = 'USDT' |
| 2723 | decimals = 6 |
| 2724 | } else if (chain === 'ethereum-usdc') { |
| 2725 | displayName = 'USDC' |
| 2726 | unit = 'USDC' |
| 2727 | decimals = 6 |
| 2728 | } else if (chain === 'ethereum') { |
| 2729 | displayName = 'Ethereum' |
| 2730 | unit = 'ETH' |
| 2731 | decimals = 18 |
| 2732 | } else if (chain === 'bitcoin') { |
| 2733 | displayName = 'Bitcoin' |
| 2734 | unit = 'sats' |
| 2735 | decimals = 0 |
| 2736 | } else { |
| 2737 | displayName = chain.charAt(0).toUpperCase() + chain.slice(1) |
| 2738 | unit = chain |
| 2739 | decimals = 18 |
| 2740 | } |
| 2741 | |
| 2690 | 2742 | const networkLabel = selectedNetwork === 'testnet' |
| 2691 | | ? (chain === 'ethereum' ? 'Sepolia' : 'Testnet') |
| 2743 | ? (chain.startsWith('ethereum') ? 'Sepolia' : 'Testnet') |
| 2692 | 2744 | : 'Mainnet' |
| 2693 | 2745 | |
| 2694 | | document.getElementById('send-chain').textContent = `${chainName} (${networkLabel})` |
| 2746 | document.getElementById('send-chain').textContent = `${displayName} (${networkLabel})` |
| 2695 | 2747 | |
| 2696 | 2748 | // Reset form |
| 2697 | 2749 | document.getElementById('send-to').value = '' |
| … | … | @@ -2712,9 +2764,16 @@ async function showSend(chain) { |
| 2712 | 2764 | const data = await res.json() |
| 2713 | 2765 | currentBalance = Number(data.balance) |
| 2714 | 2766 | |
| 2715 | | const unit = chain === 'bitcoin' ? 'sats' : 'wei' |
| 2716 | | document.getElementById('send-amount-helper').textContent = |
| 2717 | | `Balance: ${currentBalance.toLocaleString()} ${unit}` |
| 2767 | // Format balance based on decimals |
| 2768 | let balanceDisplay |
| 2769 | if (chain === 'bitcoin') { |
| 2770 | balanceDisplay = `${currentBalance.toLocaleString()} sats` |
| 2771 | } else if (decimals === 6) { |
| 2772 | balanceDisplay = `${(currentBalance / 1e6).toFixed(2)} ${unit}` |
| 2773 | } else { |
| 2774 | balanceDisplay = `${(currentBalance / 1e18).toFixed(6)} ${unit}` |
| 2775 | } |
| 2776 | document.getElementById('send-amount-helper').textContent = `Balance: ${balanceDisplay}` |
| 2718 | 2777 | } catch (err) { |
| 2719 | 2778 | console.error('Failed to load balance:', err) |
| 2720 | 2779 | document.getElementById('send-amount-helper').textContent = 'Balance: unavailable' |