PageSourceSearch

https://www.bitcoinmining.com/assets/js/live-stats.js

js bitcoinmining.com collected 2026-10-02 05:22:39 UTC 4,505 bytes, 163 lines download raw bytes

1// live-stats.js — Fetches live Bitcoin network stats and updates the page
2// Primary: mempool.space | Fallback: blockchain.info
3// Caches in localStorage for 10 minutes to reduce API calls
4
5(function () {
6  var CACHE_KEY = 'bm_live_stats';
7  var CACHE_TTL = 10 * 60 * 1000; // 10 minutes
8
9  function getCached() {
10    try {
11      var raw = localStorage.getItem(CACHE_KEY);
12      if (!raw) return null;
13      var data = JSON.parse(raw);
14      if (Date.now() - data.ts > CACHE_TTL) return null;
15      return data;
16    } catch (e) {
17      return null;
18    }
19  }
20
21  function setCache(stats) {
22    try {
23      stats.ts = Date.now();
24      localStorage.setItem(CACHE_KEY, JSON.stringify(stats));
25    } catch (e) {
26      // localStorage unavailable
27    }
28  }
29
30  function formatHashrate(ehps) {
31    if (ehps >= 1000) {
32      return '~' + (ehps / 1000).toFixed(1) + ' ZH/s';
33    }
34    return '~' + Math.round(ehps) + ' EH/s';
35  }
36
37  function formatPrice(usd) {
38    if (usd >= 1000000) {
39      return '$' + (usd / 1000000).toFixed(1) + 'M';
40    }
41    return '$' + Math.round(usd).toLocaleString('en-US');
42  }
43
44  function formatSupply(btc) {
45    return (btc / 1000000).toFixed(2) + ' million';
46  }
47
48  function formatBlockRewardValue(rewardBtc, priceUsd) {
49    var val = rewardBtc * priceUsd;
50    return 'over ' + formatPrice(val);
51  }
52
53  function applyStats(stats) {
54    // Update standalone stat elements
55    var els = document.querySelectorAll('[data-live-stat]');
56    for (var i = 0; i < els.length; i++) {
57      var el = els[i];
58      var key = el.getAttribute('data-live-stat');
59      var value = null;
60
61      switch (key) {
62        case 'hashrate':
63          value = formatHashrate(stats.hashrate);
64          break;
65        case 'hashrate-plain':
66          value = Math.round(stats.hashrate) + ' EH/s';
67          break;
68        case 'price':
69          value = formatPrice(stats.price);
70          break;
71        case 'block-reward-value':
72          value = formatBlockRewardValue(3.125, stats.price);
73          break;
74        case 'supply':
75          value = formatSupply(stats.supply);
76          break;
77        case 'difficulty':
78          value = stats.difficulty;
79          break;
80      }
81
82      if (value !== null) {
83        el.textContent = value;
84        el.removeAttribute('data-live-fallback');
85      }
86    }
87  }
88
89  function fetchMempool() {
90    return fetch('https://mempool.space/api/v1/mining/hashrate/3d')
91      .then(function (r) {
92        if (!r.ok) throw new Error(r.status);
93        return r.json();
94      })
95      .then(function (data) {
96        return {
97          hashrate: data.currentHashrate / 1e18,
98          difficulty: data.currentDifficulty
99        };
100      });
101  }
102
103  function fetchBlockchainInfo() {
104    return fetch('https://api.blockchain.info/stats')
105      .then(function (r) {
106        if (!r.ok) throw new Error(r.status);
107        return r.json();
108      })
109      .then(function (data) {
110        return {
111          hashrate: data.hash_rate / 1e9,
112          difficulty: data.difficulty,
113          price: data.market_price_usd
114        };
115      });
116  }
117
118  function fetchStats() {
119    // Try mempool for hashrate, blockchain.info for price/supply
120    // blockchain.info has price; mempool does not
121    return Promise.all([
122      fetchMempool().catch(function () { return null; }),
123      fetchBlockchainInfo().catch(function () { return null; })
124    ]).then(function (results) {
125      var mempool = results[0];
126      var blockchain = results[1];
127
128      if (!mempool && !blockchain) return null;
129
130      return {
131        hashrate: (mempool && mempool.hashrate) || (blockchain && blockchain.hashrate) || null,
132        difficulty: (mempool && mempool.difficulty) || (blockchain && blockchain.difficulty) || null,
133        price: (blockchain && blockchain.price) || null,
134        supply: null // blockchain.info stats doesn't include supply; we'll keep hardcoded for now
135      };
136    });
137  }
138
139  function init() {
140    var elements = document.querySelectorAll('[data-live-stat]');
141    if (!elements.length) return;
142
143    var cached = getCached();
144    if (cached) {
145      applyStats(cached);
146      return;
147    }
148
149    fetchStats().then(function (stats) {
150      if (!stats) return; // both APIs failed; hardcoded fallbacks remain
151      setCache(stats);
152      applyStats(stats);
153    }).catch(function () {
154      // silent fail; hardcoded values stay
155    });
156  }
157
158  if (document.readyState === 'loading') {
159    document.addEventListener('DOMContentLoaded', init);
160  } else {
161    init();
162  }
163})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.