|
|
@@ -5,14 +5,17 @@ |
|
|
|
const API_PREFIX = "https://blockstream.info/api"; |
|
|
|
|
|
|
|
const IRON_BLOCK = "https://gamepedia.cursecdn.com/minecraft_gamepedia/7/7e/Block_of_Iron_JE4_BE3.png?version=692673bafa1e94785ab6012d7a3c8dc4"; |
|
|
|
const GOLD_BLOCK = "https://gamepedia.cursecdn.com/minecraft_gamepedia/7/72/Block_of_Gold_JE6_BE3.png?version=9d1a63c717df80feffa9ec93ebceb014"; |
|
|
|
const DIAMOND_BLOCK = "https://gamepedia.cursecdn.com/minecraft_gamepedia/6/6b/Block_of_Diamond_JE6_BE3.png?version=117daf438c2ddfff59bab05d5715f6d2"; |
|
|
|
const GOLD_BLOCK = "https://gamepedia.cursecdn.com/minecraft_gamepedia/archive/7/72/20190429060628%21Block_of_Gold_JE6_BE3.png?version=448d791eb688910a0cc215181312b715"; |
|
|
|
const DIAMOND_BLOCK = "https://gamepedia.cursecdn.com/minecraft_gamepedia/archive/6/6b/20190502005227%21Block_of_Diamond_JE6_BE3.png?version=721888d830050c06303696cf79695eb9"; |
|
|
|
|
|
|
|
var nextHalvingHeight = 630000; |
|
|
|
const HALVING_PERIOD = 210000; |
|
|
|
|
|
|
|
var curTipBlock = null; |
|
|
|
var recentBlocks = null; |
|
|
|
|
|
|
|
function getCurTipBlock() { |
|
|
|
return recentBlocks[0]; |
|
|
|
} |
|
|
|
|
|
|
|
function doApiReq(endpoint, cb) { |
|
|
|
let xhr = new XMLHttpRequest(); |
|
|
|
|
|
|
@@ -39,12 +42,25 @@ function doGetRecentBlocks(cb) { |
|
|
|
} |
|
|
|
|
|
|
|
function doGetBlockCoinBaseTx(blockhash, cb) { |
|
|
|
doApiReq("/block/" + blockhash + "/txs", function(resp) { |
|
|
|
let reqSuffix = "/block/" + blockhash + "/txs"; |
|
|
|
let internalCb = function(resp) { |
|
|
|
if (resp != null) { |
|
|
|
cb(resp[0]); |
|
|
|
} else { |
|
|
|
cb(null); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
doApiReq(reqSuffix, function(resp) { |
|
|
|
if (resp != null) { |
|
|
|
internalCb(resp); |
|
|
|
} else { |
|
|
|
// Sometimes the data hasn't been fully processed yet by the time we |
|
|
|
// make the call so wait a bit and then try again. |
|
|
|
setTimeout(function() { |
|
|
|
doApiReq(reqSuffix, internalCb); |
|
|
|
}, 1000) |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
@@ -63,7 +79,11 @@ function calcRenderedSatQty(sats, decimals) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const HALVING_PERIOD = 210000; |
|
|
|
function calcNextHalvingHeight() { |
|
|
|
let height = recentBlocks[0].height; |
|
|
|
let epoch = Math.floor(height / HALVING_PERIOD); |
|
|
|
return (epoch + 1) * HALVING_PERIOD; |
|
|
|
} |
|
|
|
|
|
|
|
function calcRewardAtHeight(height) { |
|
|
|
let epoch = Math.floor(height / HALVING_PERIOD); |
|
|
@@ -101,6 +121,10 @@ function formatDate(date) { |
|
|
|
return datePart + " " + timePart; |
|
|
|
} |
|
|
|
|
|
|
|
function isHalvingHeight(height) { |
|
|
|
return height % HALVING_PERIOD == 0; |
|
|
|
} |
|
|
|
|
|
|
|
function makeBlockElem(block, prevBlock) { |
|
|
|
let entry = document.createElement("div"); |
|
|
|
|
|
|
@@ -127,8 +151,9 @@ function makeBlockElem(block, prevBlock) { |
|
|
|
let iconElem = document.createElement("img"); |
|
|
|
iconElem.classList.add("blbicon"); |
|
|
|
iconCtr.appendChild(iconElem); |
|
|
|
if (block.height % HALVING_PERIOD == 0) { |
|
|
|
if (isHalvingHeight(block.height)) { |
|
|
|
iconElem.src = DIAMOND_BLOCK; |
|
|
|
entry.classList.add("halvingblockentry"); |
|
|
|
} else { |
|
|
|
iconElem.src = GOLD_BLOCK; |
|
|
|
} |
|
|
@@ -253,6 +278,9 @@ var blocksLeftElem = null; |
|
|
|
var timeLeftElem = null; |
|
|
|
var halfTimeElem = null; |
|
|
|
|
|
|
|
const TARGET_BLOCKTIME = 10 * 60; |
|
|
|
var blocktimeAvgSecs = TARGET_BLOCKTIME; |
|
|
|
|
|
|
|
function updateRemainingCount(block) { |
|
|
|
if (blocksLeftElem == null) { |
|
|
|
blocksLeftElem = document.getElementById("blocksleft"); |
|
|
@@ -266,10 +294,11 @@ function updateRemainingCount(block) { |
|
|
|
halfTimeElem = document.getElementById("halftime"); |
|
|
|
} |
|
|
|
|
|
|
|
let blocksLeft = nextHalvingHeight - curTipBlock.height; |
|
|
|
let nextHalvingHeight = calcNextHalvingHeight(); |
|
|
|
let blocksLeft = nextHalvingHeight - getCurTipBlock().height; |
|
|
|
blocksLeftElem.innerHTML = blocksLeft.toString() |
|
|
|
|
|
|
|
if (blocksLeft < 1) { |
|
|
|
if (blocksLeft <= 1) { |
|
|
|
timeLeftElem.innerHTML = "Halving imminent!"; |
|
|
|
|
|
|
|
// Hide the expected time. |
|
|
@@ -280,7 +309,7 @@ function updateRemainingCount(block) { |
|
|
|
let nowUnix = Date.now() / 1000; // wtf??? |
|
|
|
|
|
|
|
let sinceLastBlock = nowUnix - block.timestamp; |
|
|
|
let secsLeft = ((blocksLeft * 10 * 60) - sinceLastBlock)|0; |
|
|
|
let secsLeft = ((blocksLeft * blocktimeAvgSecs) - sinceLastBlock)|0; |
|
|
|
|
|
|
|
let secsPart = secsLeft % 60; |
|
|
|
let minLeft = (secsLeft - secsPart) / 60; |
|
|
@@ -309,8 +338,9 @@ function updateRemainingCount(block) { |
|
|
|
|
|
|
|
function addNewBlock(block) { |
|
|
|
|
|
|
|
let prev = recentBlocks[0]; |
|
|
|
let prev = getCurTipBlock(); |
|
|
|
recentBlocks = [block].concat(recentBlocks); |
|
|
|
//updateBlocktimeAvg(); |
|
|
|
let elem = makeBlockElem(block, prev); |
|
|
|
|
|
|
|
elem.classList.add("newblock"); |
|
|
@@ -328,8 +358,7 @@ function populateRecentBlocks(blocks) { |
|
|
|
let blocklist = document.getElementById("blocklist"); |
|
|
|
let loadingElem = document.getElementById("blocklistloading"); |
|
|
|
|
|
|
|
curTipBlock = blocks[0]; |
|
|
|
updateRemainingCount(curTipBlock.height); |
|
|
|
updateRemainingCount(getCurTipBlock()); |
|
|
|
|
|
|
|
for (let i = 0; i < blocks.length; i++) { |
|
|
|
let block = blocks[i]; |
|
|
@@ -354,12 +383,12 @@ function populateRecentBlocks(blocks) { |
|
|
|
} |
|
|
|
|
|
|
|
loadingElem.style.display = "none"; |
|
|
|
updateRemainingCount(curTipBlock); |
|
|
|
//updateRemainingCount(curTipBlock); |
|
|
|
} |
|
|
|
|
|
|
|
function getPollDelayAtHeight(height) { |
|
|
|
let blocksUntilHalving = HALVING_PERIOD - (height % HALVING_PERIOD); |
|
|
|
if (blocksUntilHalving == 1) { |
|
|
|
if (blocksUntilHalving <= 1) { |
|
|
|
return 1000; |
|
|
|
} else if (blocksUntilHalving == 2) { |
|
|
|
return 2500; |
|
|
@@ -376,8 +405,10 @@ function checkNewBlocks() { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let curTip = getCurTipBlock(); |
|
|
|
|
|
|
|
// Find the index of the newest known block. |
|
|
|
let knownHeight = recentBlocks[0].height; |
|
|
|
let knownHeight = curTip.height; |
|
|
|
let newestKnownIndex = -1; |
|
|
|
for (let i = 0; i < blocks.length; i++) { |
|
|
|
if (blocks[i].height == knownHeight) { |
|
|
@@ -415,6 +446,7 @@ function init() { |
|
|
|
} |
|
|
|
|
|
|
|
recentBlocks = blocks; |
|
|
|
//updateBlocktimeAvg(); |
|
|
|
|
|
|
|
populateRecentBlocks(blocks); |
|
|
|
setTimeout(checkNewBlocks, 5000); |