From 30ba103cddd1a20a14128140da131851480796a8 Mon Sep 17 00:00:00 2001 From: Dan Janosik Date: Sun, 23 Sep 2018 15:15:51 -0400 Subject: [PATCH] Misc: - improved electrum connection code - support for address "Fun" items - inclusion of "Satoshi Nakamoto" brainwallet address fun item --- app.js | 18 +++++++++-- app/api/electrumApi.js | 39 ++++++++++++++++++----- app/coins/btc.js | 8 +++++ routes/baseActionsRouter.js | 3 ++ views/address.pug | 39 +++++++++++++++++++++-- views/fun.pug | 6 ++-- views/includes/transaction-io-details.pug | 25 +++++++++++---- 7 files changed, 117 insertions(+), 21 deletions(-) diff --git a/app.js b/app.js index 9c6e434..aebcca9 100755 --- a/app.js +++ b/app.js @@ -111,6 +111,10 @@ app.runOnStartup = function() { global.specialBlocks = {}; global.specialAddresses = {}; + if (config.donationAddresses && config.donationAddresses[coinConfig.ticker]) { + global.specialAddresses[config.donationAddresses[coinConfig.ticker].address] = {type:"donation"}; + } + if (global.coinConfig.historicalData) { global.coinConfig.historicalData.forEach(function(item) { if (item.type == "blockheight") { @@ -118,14 +122,22 @@ app.runOnStartup = function() { } else if (item.type == "tx") { global.specialTransactions[item.txid] = item; + + } else if (item.type == "address") { + global.specialAddresses[item.address] = {type:"fun", addressInfo:item}; } }); } if (config.electrumXServers && config.electrumXServers.length > 0) { - electrumApi.connectToServers(); + electrumApi.connectToServers().then(function() { + console.log("Live with ElectrumX API"); - global.electrumApi = electrumApi; + global.electrumApi = electrumApi; + + }).catch(function(err) { + console.log("Error 31207ugf4e0fed: " + err + ", while initializing ElectrumX API"); + }); } if (global.coinConfig.miningPoolsConfigUrls) { @@ -157,7 +169,7 @@ app.runOnStartup = function() { for (var i = 0; i < global.miningPoolsConfigs.length; i++) { for (var x in global.miningPoolsConfigs[i].payout_addresses) { if (global.miningPoolsConfigs[i].payout_addresses.hasOwnProperty(x)) { - global.specialAddresses[x] = global.miningPoolsConfigs[i].payout_addresses[x]; + global.specialAddresses[x] = {type:"minerPayout", minerInfo:global.miningPoolsConfigs[i].payout_addresses[x]}; } } } diff --git a/app/api/electrumApi.js b/app/api/electrumApi.js index 80db745..0e5eef4 100644 --- a/app/api/electrumApi.js +++ b/app/api/electrumApi.js @@ -9,20 +9,43 @@ const ElectrumClient = require('electrum-client'); var electrumClients = []; function connectToServers() { - for (var i = 0; i < config.electrumXServers.length; i++) { - connectToServer(config.electrumXServers[i].host, config.electrumXServers[i].port); - } + return new Promise(function(resolve, reject) { + var promises = []; + + for (var i = 0; i < config.electrumXServers.length; i++) { + promises.push(connectToServer(config.electrumXServers[i].host, config.electrumXServers[i].port)); + } + + Promise.all(promises).then(function() { + resolve(); + + }).catch(function(err) { + console.log("Error 120387rygxx231gwe40: " + err); + + reject(err); + }); + }); } function connectToServer(host, port) { - console.log("Connecting to ElectrumX Server: " + host + ":" + port); + return new Promise(function(resolve, reject) { + console.log("Connecting to ElectrumX Server: " + host + ":" + port); + + var electrumClient = new ElectrumClient(port, host, 'tls'); + electrumClient.initElectrum({client:"btc-rpc-explorer-v1.1", version:"1.2"}).then(function(res) { + console.log("Connected to ElectrumX Server: " + host + ":" + port + ", versions: " + res); + + electrumClients.push(electrumClient); - var electrumClient = new ElectrumClient(port, host, 'tls'); - electrumClient.initElectrum({client:"btc-rpc-explorer-v1.1", version:"1.2"}).then(function(res) { - console.log("Connected to ElectrumX Server: " + host + ":" + port + ", versions: " + res); + resolve(); - electrumClients.push(electrumClient); + }).catch(function(err) { + console.log("Error 137rg023xx7gerfwdd: " + err + ", when trying to connect to ElectrumX server at " + host + ":" + port); + + reject(err); + }); }); + } function runOnServer(electrumClient, f) { diff --git a/app/coins/btc.js b/app/coins/btc.js index 982e7e8..18c4df7 100644 --- a/app/coins/btc.js +++ b/app/coins/btc.js @@ -177,6 +177,14 @@ module.exports = { summary: "Block reward lost", alertBodyHtml: "This coinbase transaction completely fails to collect the block's mining reward. 12.5 BTC were lost.", referenceUrl: "https://bitcoin.stackexchange.com/a/67012/3397" + }, + { + type:"address", + date:"2011-12-03", + address:"1JryTePceSiWVpoNBU8SbwiT7J4ghzijzW", + summary:"Brainwallet address for 'Satoshi Nakamoto'", + referenceUrl:"https://twitter.com/MrHodl/status/1041448002005741568", + alertBodyHtml:"This address was generated from the SHA256 hash of 'Satoshi Nakamoto' as example of the 'brainwallet' concept." } ], exchangeRateData:{ diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index 4d3ccae..d7da695 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -538,6 +538,7 @@ router.get("/address/:address", function(req, res) { res.locals.offset = offset; res.locals.sort = sort; res.locals.paginationBaseUrl = ("/address/" + address + "?sort=" + sort); + res.locals.transactions = []; res.locals.result = {}; @@ -563,6 +564,8 @@ router.get("/address/:address", function(req, res) { } } + res.locals.advancedFunctionality = (global.electrumApi != null); + coreApi.getAddress(address).then(function(validateaddressResult) { res.locals.result.validateaddress = validateaddressResult; diff --git a/views/address.pug b/views/address.pug index 44fffc2..8351038 100644 --- a/views/address.pug +++ b/views/address.pug @@ -37,6 +37,41 @@ block content span (see the configuration a(href=coinConfig.miningPoolsConfigUrls[0]) here span ) + else if (global.specialAddresses[address] && global.specialAddresses[address].type == "donation") + div(class="alert alert-primary", style="padding-bottom: 0;") + div(class="float-left", style="width: 50px; height: 50px; font-size: 18px;") + i(class="fas fa-certificate fa-2x", style="margin-top: 10px;") + + h4(class="alert-heading h6 font-weight-bold") #{coinConfig.name} Fun + + p + span This is the #{coinConfig.ticker} donation address to support development of this tool. All support is appreciated! + + else if (global.specialAddresses[address] && global.specialAddresses[address].type == "fun") + div(class="alert alert-primary", style="padding-bottom: 0;") + div(class="float-left", style="width: 50px; height: 50px; font-size: 18px;") + i(class="fas fa-certificate fa-2x", style="margin-top: 10px;") + + h4(class="alert-heading h6 font-weight-bold") #{coinConfig.name} Fun + + // special address info + - var saInfo = global.specialAddresses[address].addressInfo; + if (saInfo.alertBodyHtml) + p + span !{saInfo.alertBodyHtml} + + if (saInfo.referenceUrl && saInfo.referenceUrl.trim().length > 0 && saInfo.alertBodyHtml.indexOf(saInfo.referenceUrl) == -1) + span + a(href=saInfo.referenceUrl) Read more + + else + p + span #{saInfo.summary} + + if (saInfo.referenceUrl && saInfo.referenceUrl.trim().length > 0) + span + a(href=saInfo.referenceUrl) Read more + if (false) pre @@ -211,7 +246,7 @@ block content else span Transactions - if (!crawlerBot && txids && txids.length > 0) + if (!crawlerBot && txids && txids.length > 1) div(class="float-right") a(href="#", class="pull-right dropdown-toggle", data-toggle="dropdown", aria-haspopup="true", aria-expanded="false") if (sort == "desc") @@ -240,7 +275,7 @@ block content span(class="font-weight-bold") #{electrumHistory.server} - if (transactions) + if (advancedFunctionality) if (transactions.length == 0) span No transactions found diff --git a/views/fun.pug b/views/fun.pug index a74571d..1361ec0 100644 --- a/views/fun.pug +++ b/views/fun.pug @@ -25,11 +25,13 @@ block content td(class="data-cell monospace") if (item.type == "tx") - a(href=("/tx/" + item.txid)) Tx #{item.txid.substring(0, 23)}... + a(href=("/tx/" + item.txid), title=item.txid, data-toggle="tooltip") Tx #{item.txid.substring(0, 23)}... else if (item.type == "block") - a(href=("/block/" + item.blockHash)) Block #{item.blockHash.substring(0, 20)}... + a(href=("/block/" + item.blockHash), title="Block #{item.blockHash}", data-toggle="tooltip") Block #{item.blockHash.substring(0, 20)}... else if (item.type == "blockheight") a(href=("/block/" + item.blockHash)) Block ##{item.blockHeight} + else if (item.type == "address") + a(href=("/address/" + item.address), title=item.address, data-toggle="tooltip") Address #{item.address.substring(0, 18)}... else if (item.type == "link") a(href=item.url) #{item.url.substring(0, 20)}... diff --git a/views/includes/transaction-io-details.pug b/views/includes/transaction-io-details.pug index 7fe769f..21a3a55 100644 --- a/views/includes/transaction-io-details.pug +++ b/views/includes/transaction-io-details.pug @@ -34,9 +34,16 @@ div(class="row monospace") div(style="word-break: break-word;") a(href=("/address/" + vout.scriptPubKey.addresses[0])) #{vout.scriptPubKey.addresses[0]} if (global.specialAddresses[vout.scriptPubKey.addresses[0]]) - span - a(data-toggle="tooltip", title=("Miner payout address: " + global.specialAddresses[vout.scriptPubKey.addresses[0]].name)) - i(class="fas fa-certificate text-primary") + - var specialAddressInfo = global.specialAddresses[vout.scriptPubKey.addresses[0]]; + if (specialAddressInfo.type == "minerPayout") + span + a(data-toggle="tooltip", title=("Miner payout address: " + specialAddressInfo.minerInfo.name)) + i(class="fas fa-certificate text-primary") + else if (specialAddressInfo.type == "donation") + span + a(data-toggle="tooltip", title=("Development donation address. All support is appreciated!")) + i(class="fas fa-certificate text-primary") + span(class="small") via a(href=("/tx/" + txInput.txid + "#output-" + txVin.vout)) #{txInput.txid.substring(0, 20)}...[#{txVin.vout}] @@ -82,9 +89,15 @@ div(class="row monospace") span(class="monospace", style="word-break: break-word;") #{vout.scriptPubKey.addresses[0]} if (global.specialAddresses[vout.scriptPubKey.addresses[0]]) - span - a(data-toggle="tooltip", title=("Miner payout address: " + global.specialAddresses[vout.scriptPubKey.addresses[0]].name)) - i(class="fas fa-certificate text-primary") + - var specialAddressInfo = global.specialAddresses[vout.scriptPubKey.addresses[0]]; + if (specialAddressInfo.type == "minerPayout") + span + a(data-toggle="tooltip", title=("Miner payout address: " + specialAddressInfo.minerInfo.name)) + i(class="fas fa-certificate text-primary") + else if (specialAddressInfo.type == "donation") + span + a(data-toggle="tooltip", title=("Development donation address. All support is appreciated!")) + i(class="fas fa-certificate text-primary") else if (vout.scriptPubKey.hex && vout.scriptPubKey.hex.startsWith('6a24aa21a9ed')) span(class="monospace") Segregated Witness committment