File size: 7,249 Bytes
58c926b
22b90b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Wallet Balance – Demo UI</title>
  <style>
    :root{
      --bg:#0f1220;--card:#171a2b;--text:#e7e9f3;--muted:#a7adc2;--accent:#6d8dff;--accent-2:#9b6dff;--danger:#ff6d6d;--ok:#60d394;
      --border:rgba(255,255,255,.08);--shadow:0 10px 30px rgba(0,0,0,.35);
    }
    *{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}
    .container{max-width:900px;margin:40px auto;padding:16px}
    .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}
    .banner strong{color:var(--ok)}
    .row{display:grid;grid-template-columns:1.2fr .8fr auto;gap:10px}
    .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}
    .title{font-size:24px;font-weight:700;margin:2px 0 14px}
    label{display:block;font-size:12px;color:var(--muted);margin-bottom:6px}
    input,select,button{width:100%;border-radius:14px;border:1px solid var(--border);padding:12px 14px;background:#0f1220;color:var(--text)}
    input:focus,select:focus,button:focus{outline:2px solid color-mix(in oklab, var(--accent) 60%, white)}
    button{cursor:pointer;background:linear-gradient(135deg, var(--accent), var(--accent-2));border:none;font-weight:700}
    button[disabled]{opacity:.6;cursor:not-allowed}
    .muted{color:var(--muted)}
    .result{display:none;margin-top:14px;border-top:1px dashed var(--border);padding-top:14px}
    .result.visible{display:block}
    .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}
    .grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
    .footer{margin-top:30px;color:var(--muted);font-size:12px;text-align:center}
    .error{color:var(--danger);font-size:13px;margin-top:8px}
    .copy{background:transparent;border:1px dashed var(--border);padding:8px 12px}
    @media (max-width:800px){.row{grid-template-columns:1fr}} 
  </style>
</head>
<body>
  <div class="container">
    <div class="banner">
      <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.
    </div>

    <div class="card">
      <div class="title">Wallet Balance</div>
      <div class="row">
        <div>
          <label for="address">Wallet Address</label>
          <input id="address" placeholder="0x… or other format" autocomplete="off" />
        </div>
        <div>
          <label for="network">Network</label>
          <select id="network">
            <option value="ethereum" selected>Ethereum</option>
            <option value="bsc">BNB Smart Chain</option>
            <option value="solana">Solana</option>
            <option value="polygon">Polygon</option>
            <option value="tron">TRON</option>
          </select>
        </div>
        <div style="align-self:end">
          <button id="checkBtn">Check Balance</button>
        </div>
      </div>
      <div class="error" id="error"></div>

      <div class="result" id="result">
        <div class="grid">
          <div>
            <div class="muted">Normalized Balance</div>
            <div id="balance" style="font-size:28px;font-weight:800;"></div>
          </div>
          <div>
            <div class="muted">Address</div>
            <div style="display:flex;gap:8px;align-items:center">
              <code id="addrOut" style="font-size:12px;opacity:.9"></code>
              <button class="pill copy" id="copyBtn" title="Copy address">Copy</button>
            </div>
          </div>
        </div>
        <div style="margin-top:10px" class="muted" id="note"></div>
      </div>
    </div>

    <div class="footer">
      <p>For production, use official SDKs/APIs (e.g., Alchemy, Infura, QuickNode, Solana RPC), validate inputs, and never misrepresent balances or brands.</p>
    </div>
  </div>

  <script>
    // --- Simple deterministic mock so results are stable for the same input ---
    function hashToNumber(str){
      let h1 = 0xdeadbeef ^ str.length, h2 = 0x41c6ce57 ^ str.length;
      for (let i=0; i<str.length; i++){
        const ch = str.charCodeAt(i);
        h1 = Math.imul(h1 ^ ch, 2654435761);
        h2 = Math.imul(h2 ^ ch, 1597334677);
      }
      h1 = (h1 ^ (h1>>>16)) >>> 0; h2 = (h2 ^ (h2>>>13)) >>> 0;
      return (h1 + h2) >>> 0; // 0..2^32-1
    }

    function format(num){
      return new Intl.NumberFormat(undefined, {maximumFractionDigits:6}).format(num);
    }

    const address = document.getElementById('address');
    const network = document.getElementById('network');
    const btn = document.getElementById('checkBtn');
    const error = document.getElementById('error');
    const result = document.getElementById('result');
    const balanceEl = document.getElementById('balance');
    const addrOut = document.getElementById('addrOut');
    const note = document.getElementById('note');
    const copyBtn = document.getElementById('copyBtn');

    function validate(addr){
      if (!addr || addr.trim().length < 6) return 'Enter a valid address.';
      // Very light checks – expand per network as needed
      if (network.value === 'ethereum' || network.value === 'bsc' || network.value === 'polygon'){
        if (!/^0x[0-9a-fA-F]{6,}$/.test(addr)) return 'Expected an 0x… style address for this network.';
      }
      return '';
    }

    btn.addEventListener('click', () => {
      error.textContent = '';
      result.classList.remove('visible');

      const addr = address.value.trim();
      const v = validate(addr);
      if (v){ error.textContent = v; return; }

      btn.disabled = true; btn.textContent = 'Checking…';
      // Simulate delay
      setTimeout(() => {
        const seed = hashToNumber(addr + '|' + network.value);
        const base = (seed % 10_000_000) / 100_000; // up to 100
        const decimals = network.value === 'solana' || network.value === 'tron' ? 2 : 4;
        const displayed = Number(base.toFixed(decimals));

        balanceEl.textContent = format(displayed);
        addrOut.textContent = addr;
        note.textContent = `Mock value based on input • Network: ${network.options[network.selectedIndex].text}`;
        result.classList.add('visible');
        btn.disabled = false; btn.textContent = 'Check Balance';
      }, 500);
    });

    copyBtn.addEventListener('click', async () => {
      const text = addrOut.textContent || '';
      if (!text) return;
      try { await navigator.clipboard.writeText(text); copyBtn.textContent = 'Copied'; setTimeout(()=>copyBtn.textContent='Copy', 1200);} catch(e){ console.warn(e); }
    });
  </script>
</body>
</html>