Spaces:
Running
Running
Update index.html
Browse files- index.html +153 -18
index.html
CHANGED
|
@@ -1,19 +1,154 @@
|
|
| 1 |
<!doctype html>
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
<!doctype html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8" />
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 6 |
+
<title>Wallet Balance – Demo UI</title>
|
| 7 |
+
<style>
|
| 8 |
+
:root{
|
| 9 |
+
--bg:#0f1220;--card:#171a2b;--text:#e7e9f3;--muted:#a7adc2;--accent:#6d8dff;--accent-2:#9b6dff;--danger:#ff6d6d;--ok:#60d394;
|
| 10 |
+
--border:rgba(255,255,255,.08);--shadow:0 10px 30px rgba(0,0,0,.35);
|
| 11 |
+
}
|
| 12 |
+
*{box-sizing:border-box} body{margin:0;background:radial-gradient(1200px 600px at 10% -10%, #1e2240 0%, #0f1220 60%), #0f1220;color:var(--text);font:16px/1.4 system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif}
|
| 13 |
+
.container{max-width:900px;margin:40px auto;padding:16px}
|
| 14 |
+
.banner{background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(255,255,255,.02));border:1px solid var(--border);padding:12px 14px;border-radius:14px;margin-bottom:16px}
|
| 15 |
+
.banner strong{color:var(--ok)}
|
| 16 |
+
.row{display:grid;grid-template-columns:1.2fr .8fr auto;gap:10px}
|
| 17 |
+
.card{background:linear-gradient(180deg, rgba(255,255,255,.04), rgba(255,255,255,.02));border:1px solid var(--border);border-radius:20px;box-shadow:var(--shadow);padding:18px}
|
| 18 |
+
.title{font-size:24px;font-weight:700;margin:2px 0 14px}
|
| 19 |
+
label{display:block;font-size:12px;color:var(--muted);margin-bottom:6px}
|
| 20 |
+
input,select,button{width:100%;border-radius:14px;border:1px solid var(--border);padding:12px 14px;background:#0f1220;color:var(--text)}
|
| 21 |
+
input:focus,select:focus,button:focus{outline:2px solid color-mix(in oklab, var(--accent) 60%, white)}
|
| 22 |
+
button{cursor:pointer;background:linear-gradient(135deg, var(--accent), var(--accent-2));border:none;font-weight:700}
|
| 23 |
+
button[disabled]{opacity:.6;cursor:not-allowed}
|
| 24 |
+
.muted{color:var(--muted)}
|
| 25 |
+
.result{display:none;margin-top:14px;border-top:1px dashed var(--border);padding-top:14px}
|
| 26 |
+
.result.visible{display:block}
|
| 27 |
+
.pill{display:inline-flex;gap:8px;align-items:center;border:1px solid var(--border);padding:6px 10px;border-radius:999px;background:rgba(255,255,255,.04);font-size:12px}
|
| 28 |
+
.grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
|
| 29 |
+
.footer{margin-top:30px;color:var(--muted);font-size:12px;text-align:center}
|
| 30 |
+
.error{color:var(--danger);font-size:13px;margin-top:8px}
|
| 31 |
+
.copy{background:transparent;border:1px dashed var(--border);padding:8px 12px}
|
| 32 |
+
@media (max-width:800px){.row{grid-template-columns:1fr}}
|
| 33 |
+
</style>
|
| 34 |
+
</head>
|
| 35 |
+
<body>
|
| 36 |
+
<div class="container">
|
| 37 |
+
<div class="banner">
|
| 38 |
+
<strong>Demo only:</strong> This page is a front‑end example. It does <em>not</em> query a real blockchain or wallet provider. Replace the mock code with your own API calls if you are building a legitimate balance checker.
|
| 39 |
+
</div>
|
| 40 |
+
|
| 41 |
+
<div class="card">
|
| 42 |
+
<div class="title">Wallet Balance</div>
|
| 43 |
+
<div class="row">
|
| 44 |
+
<div>
|
| 45 |
+
<label for="address">Wallet Address</label>
|
| 46 |
+
<input id="address" placeholder="0x… or other format" autocomplete="off" />
|
| 47 |
+
</div>
|
| 48 |
+
<div>
|
| 49 |
+
<label for="network">Network</label>
|
| 50 |
+
<select id="network">
|
| 51 |
+
<option value="ethereum" selected>Ethereum</option>
|
| 52 |
+
<option value="bsc">BNB Smart Chain</option>
|
| 53 |
+
<option value="solana">Solana</option>
|
| 54 |
+
<option value="polygon">Polygon</option>
|
| 55 |
+
<option value="tron">TRON</option>
|
| 56 |
+
</select>
|
| 57 |
+
</div>
|
| 58 |
+
<div style="align-self:end">
|
| 59 |
+
<button id="checkBtn">Check Balance</button>
|
| 60 |
+
</div>
|
| 61 |
+
</div>
|
| 62 |
+
<div class="error" id="error"></div>
|
| 63 |
+
|
| 64 |
+
<div class="result" id="result">
|
| 65 |
+
<div class="grid">
|
| 66 |
+
<div>
|
| 67 |
+
<div class="muted">Normalized Balance</div>
|
| 68 |
+
<div id="balance" style="font-size:28px;font-weight:800;">—</div>
|
| 69 |
+
</div>
|
| 70 |
+
<div>
|
| 71 |
+
<div class="muted">Address</div>
|
| 72 |
+
<div style="display:flex;gap:8px;align-items:center">
|
| 73 |
+
<code id="addrOut" style="font-size:12px;opacity:.9"></code>
|
| 74 |
+
<button class="pill copy" id="copyBtn" title="Copy address">Copy</button>
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
<div style="margin-top:10px" class="muted" id="note"></div>
|
| 79 |
+
</div>
|
| 80 |
+
</div>
|
| 81 |
+
|
| 82 |
+
<div class="footer">
|
| 83 |
+
<p>For production, use official SDKs/APIs (e.g., Alchemy, Infura, QuickNode, Solana RPC), validate inputs, and never misrepresent balances or brands.</p>
|
| 84 |
+
</div>
|
| 85 |
+
</div>
|
| 86 |
+
|
| 87 |
+
<script>
|
| 88 |
+
// --- Simple deterministic mock so results are stable for the same input ---
|
| 89 |
+
function hashToNumber(str){
|
| 90 |
+
let h1 = 0xdeadbeef ^ str.length, h2 = 0x41c6ce57 ^ str.length;
|
| 91 |
+
for (let i=0; i<str.length; i++){
|
| 92 |
+
const ch = str.charCodeAt(i);
|
| 93 |
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
| 94 |
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
| 95 |
+
}
|
| 96 |
+
h1 = (h1 ^ (h1>>>16)) >>> 0; h2 = (h2 ^ (h2>>>13)) >>> 0;
|
| 97 |
+
return (h1 + h2) >>> 0; // 0..2^32-1
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
function format(num){
|
| 101 |
+
return new Intl.NumberFormat(undefined, {maximumFractionDigits:6}).format(num);
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
const address = document.getElementById('address');
|
| 105 |
+
const network = document.getElementById('network');
|
| 106 |
+
const btn = document.getElementById('checkBtn');
|
| 107 |
+
const error = document.getElementById('error');
|
| 108 |
+
const result = document.getElementById('result');
|
| 109 |
+
const balanceEl = document.getElementById('balance');
|
| 110 |
+
const addrOut = document.getElementById('addrOut');
|
| 111 |
+
const note = document.getElementById('note');
|
| 112 |
+
const copyBtn = document.getElementById('copyBtn');
|
| 113 |
+
|
| 114 |
+
function validate(addr){
|
| 115 |
+
if (!addr || addr.trim().length < 6) return 'Enter a valid address.';
|
| 116 |
+
// Very light checks – expand per network as needed
|
| 117 |
+
if (network.value === 'ethereum' || network.value === 'bsc' || network.value === 'polygon'){
|
| 118 |
+
if (!/^0x[0-9a-fA-F]{6,}$/.test(addr)) return 'Expected an 0x… style address for this network.';
|
| 119 |
+
}
|
| 120 |
+
return '';
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
btn.addEventListener('click', () => {
|
| 124 |
+
error.textContent = '';
|
| 125 |
+
result.classList.remove('visible');
|
| 126 |
+
|
| 127 |
+
const addr = address.value.trim();
|
| 128 |
+
const v = validate(addr);
|
| 129 |
+
if (v){ error.textContent = v; return; }
|
| 130 |
+
|
| 131 |
+
btn.disabled = true; btn.textContent = 'Checking…';
|
| 132 |
+
// Simulate delay
|
| 133 |
+
setTimeout(() => {
|
| 134 |
+
const seed = hashToNumber(addr + '|' + network.value);
|
| 135 |
+
const base = (seed % 10_000_000) / 100_000; // up to 100
|
| 136 |
+
const decimals = network.value === 'solana' || network.value === 'tron' ? 2 : 4;
|
| 137 |
+
const displayed = Number(base.toFixed(decimals));
|
| 138 |
+
|
| 139 |
+
balanceEl.textContent = format(displayed);
|
| 140 |
+
addrOut.textContent = addr;
|
| 141 |
+
note.textContent = `Mock value based on input • Network: ${network.options[network.selectedIndex].text}`;
|
| 142 |
+
result.classList.add('visible');
|
| 143 |
+
btn.disabled = false; btn.textContent = 'Check Balance';
|
| 144 |
+
}, 500);
|
| 145 |
+
});
|
| 146 |
+
|
| 147 |
+
copyBtn.addEventListener('click', async () => {
|
| 148 |
+
const text = addrOut.textContent || '';
|
| 149 |
+
if (!text) return;
|
| 150 |
+
try { await navigator.clipboard.writeText(text); copyBtn.textContent = 'Copied'; setTimeout(()=>copyBtn.textContent='Copy', 1200);} catch(e){ console.warn(e); }
|
| 151 |
+
});
|
| 152 |
+
</script>
|
| 153 |
+
</body>
|
| 154 |
+
</html>
|