Skip to content

Connect link #16

@Jyrkivi

Description

@Jyrkivi

Can someone help me with this?
All other links works fine under ssl but when I click "Connect" link browser just flash correct page and then goes white page where is text "2024"?

config.json

{
"logging": {
"level": "info",
"enableConsoleLog": true,
"enableConsoleColors": true,
// Log file name (full log) - can be null in which case log events are written to console (stdout)
"logFile": "core.log",
// Log file name for API-requests - can be null in which case log events are written to either main logFile or console (stdout)
"apiLogFile": "api.log",
// Folder to store log file(s)
"logBaseDirectory": "/var/logs/miningcore", // or c:\path\to\logs on Windows
// If enabled, separate log file will be stored for each pool as .log
// in the above specific folder.
"perPoolLogFile": false
},
"banning": {
// "integrated" or "iptables" (linux only - not yet implemented)
"manager": "Integrated",
"banOnJunkReceive": true,
"banOnInvalidShares": false
},
"notifications": {
"enabled": false,
"email": {
"host": "smtp.example.com",
"port": 587,
"user": "user",
"password": "password",
"fromAddress": "info@yourpool.org",
"fromName": "pool support"
},
"admin": {
"enabled": false,
"emailAddress": "user@example.com",
"notifyBlockFound": true
}
},
// Where to persist shares and blocks to
"persistence": {
// Persist to postgresql database
"postgres": {
"host": "127.0.0.1",
"port": 5432,
"user": "miningcore",
"password": "atcg2hrq",
"database": "miningcore"
}
},
// Generate payouts for recorded shares and blocks
"paymentProcessing": {
"enabled": true,
// How often to process payouts, in milliseconds
"interval": 600,
// Path to a file used to backup shares under emergency conditions, such as
// database outage
"shareRecoveryFile": "recovered-shares.txt"
},
// API Settings
"api": {
"enabled": true,
// Binding address (Default: 127.0.0.1)
"listenAddress": "0.0.0.0",
// Binding port (Default: 4000)
"port": 5000,
// IP address whitelist for requests to Prometheus Metrics (default 127.0.0.1)
"metricsIpWhitelist": [],
// Limit rate of requests to API on a per-IP basis
"rateLimiting": {
"disabled": false, // disable rate-limiting all-together, be careful
// override default rate-limit rules, refer to https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware#defining-rate-limit-rules
"rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
}
],
// List of IP addresses excempt from rate-limiting (default: none)
"ipWhitelist": []
}
},
"pools": [
// Repeat the following section for multiple coins
{
// DON'T change the id after a production pool has begun collecting shares!
"id": "[censored]",
"enabled": true,
"coin": "[censored]",
// Address to where block rewards are given (pool wallet)
"address": "[censored]",
// Block rewards go to the configured pool wallet address to later be paid out
// to miners, except for a percentage that can go to, for examples,
// pool operator(s) as pool fees or or to donations address. Addresses or hashed
// public keys can be used. Here is an example of rewards going to the main pool
// "op"
"rewardRecipients": [
{
// Pool wallet
"address": "[censored]",
"percentage": 0.25
}
],
// How often to poll RPC daemons for new blocks, in milliseconds
"blockRefreshInterval": 400,
// Some miner apps will consider the pool dead/offline if it doesn't receive
// anything new jobs for around a minute, so every time we broadcast jobs,
// set a timeout to rebroadcast in this many seconds unless we find a new job.
// Set to zero to disable. (Default: 0)
"jobRebroadcastTimeout": 10,
// Remove workers that haven't been in contact for this many seconds.
// Some attackers will create thousands of workers that use up all available
// socket connections, usually the workers are zombies and don't submit shares
// after connecting. This features detects those and disconnects them.
"clientConnectionTimeout": 600,
// If a worker is submitting a high threshold of invalid shares, we can
// temporarily ban their IP to reduce system/network load.
"banning": {
"enabled": true,
// How many seconds to ban worker for
"time": 600,
// What percent of invalid shares triggers ban
"invalidPercent": 50,
// Check invalid percent when this many shares have been submitted
"checkThreshold": 50
},
// Each pool can have as many ports for your miners to connect to as you wish.
// Each port can be configured to use its own pool difficulty and variable
// difficulty settings. 'varDiff' is optional and will only be used for the ports
// you configure it for.
"ports": {
// Binding port for your miners to connect to
"3052": {
// Binding address (Default: 127.0.0.1)
"listenAddress": "0.0.0.0",
// Pool difficulty
"difficulty": 0.0001,
// TLS/SSL configuration
"tls": false,
"tlsPfxFile": "/var/lib/certs/mycert.pfx",
// Variable difficulty is a feature that will automatically adjust difficulty
// for individual miners based on their hash rate in order to lower
// networking overhead
"varDiff": {
// Minimum difficulty
"minDiff": 0.00001,
// Maximum difficulty. Network difficulty will be used if it is lower than
// this. Set to null to disable.
"maxDiff": null,
// Try to get 1 share per this many seconds
"targetTime": 15,
// Check to see if we should retarget every this many seconds
"retargetTime": 90,
// Allow time to very this % from target without retargeting
"variancePercent": 30,
// Do not alter difficulty by more than this during a single retarget in
// either direction
"maxDelta": 500
}
}
},
// Recommended to have at least two daemon instances running in case one drops
// out-of-sync or offline. For redundancy, all instances will be polled for
// block/transaction updates and be used for submitting blocks. Creating a backup
// daemon involves spawning a daemon using the "-datadir=/backup" argument which
// creates a new daemon instance with it's own RPC config. For more info on this,
// visit: https:// en.bitcoin.it/wiki/Data_directory and
// https:// en.bitcoin.it/wiki/Running_bitcoind
"daemons": [
{
"host": "127.0.0.1",
"port": [censored],
"user": "[censored]",
"password": "[censored]",
// Enable streaming Block Notifications via ZeroMQ messaging from Bitcoin
// Family daemons. Using this is highly recommended. The value of this option
// is a string that should match the value of the -zmqpubhashblock parameter
// passed to the coin daemon. If you enable this, you should lower
// 'blockRefreshInterval' to 1000 or 0 to disable polling entirely.
// "zmqBlockNotifySocket": "tcp://127.0.0.1:15101",
// Enable streaming Block Notifications via WebSocket messaging from Ethereum
// family Parity daemons. Using this is highly recommended. The value of this
// option is a string that should match the value of the --ws-port parameter
// passed to the parity coin daemon. When using --ws-port, you should also
// specify --ws-interface all and
// --jsonrpc-apis "eth,net,web3,personal,parity,parity_pubsub,rpc"
// If you enable this, you should lower 'blockRefreshInterval' to 1000 or 0
// to disable polling entirely.
// "portWs": 18545,
}
],
// Generate payouts for recorded shares
"paymentProcessing": {
"enabled": true,
// Minimum payment in pool-base-currency (ie. Bitcoin, NOT Satoshis)
"minimumPayment": 1,
"payoutScheme": "PPLNS",
"payoutSchemeConfig": {
"factor": 2.0
}
}
},
{
// DON'T change the id after a production pool has begun collecting shares!
"id": "[censored]",
"enabled": true,
"coin": "[censored[[SOLO]",
// Address to where block rewards are given (pool wallet)
"address": "F2pEky1bqeoGxHrUqaKQJfu1LpXgetx8uX",
// Block rewards go to the configured pool wallet address to later be paid out
// to miners, except for a percentage that can go to, for examples,
// pool operator(s) as pool fees or or to donations address. Addresses or hashed
// public keys can be used. Here is an example of rewards going to the main pool
// "op"
"rewardRecipients": [
{
// Pool wallet
"address": "[censored]",
"percentage": [censored]
}
],
// How often to poll RPC daemons for new blocks, in milliseconds
"blockRefreshInterval": 400,
// Some miner apps will consider the pool dead/offline if it doesn't receive
// anything new jobs for around a minute, so every time we broadcast jobs,
// set a timeout to rebroadcast in this many seconds unless we find a new job.
// Set to zero to disable. (Default: 0)
"jobRebroadcastTimeout": 10,
// Remove workers that haven't been in contact for this many seconds.
// Some attackers will create thousands of workers that use up all available
// socket connections, usually the workers are zombies and don't submit shares
// after connecting. This features detects those and disconnects them.
"clientConnectionTimeout": 600,
// If a worker is submitting a high threshold of invalid shares, we can
// temporarily ban their IP to reduce system/network load.
"banning": {
"enabled": true,
// How many seconds to ban worker for
"time": 600,
// What percent of invalid shares triggers ban
"invalidPercent": 50,
// Check invalid percent when this many shares have been submitted
"checkThreshold": 50
},
// Each pool can have as many ports for your miners to connect to as you wish.
// Each port can be configured to use its own pool difficulty and variable
// difficulty settings. 'varDiff' is optional and will only be used for the ports
// you configure it for.
"ports": {
// Binding port for your miners to connect to
"4052": {
// Binding address (Default: 127.0.0.1)
"listenAddress": "0.0.0.0",
// Pool difficulty
"difficulty": 0.0001,
// TLS/SSL configuration
"tls": false,
"tlsPfxFile": "/var/lib/certs/mycert.pfx",
// Variable difficulty is a feature that will automatically adjust difficulty
// for individual miners based on their hash rate in order to lower
// networking overhead
"varDiff": {
// Minimum difficulty
"minDiff": 0.0001,
// Maximum difficulty. Network difficulty will be used if it is lower than
// this. Set to null to disable.
"maxDiff": null,
// Try to get 1 share per this many seconds
"targetTime": 15,
// Check to see if we should retarget every this many seconds
"retargetTime": 90,
// Allow time to very this % from target without retargeting
"variancePercent": 30,
// Do not alter difficulty by more than this during a single retarget in
// either direction
"maxDelta": 500
}
}
},
// Recommended to have at least two daemon instances running in case one drops
// out-of-sync or offline. For redundancy, all instances will be polled for
// block/transaction updates and be used for submitting blocks. Creating a backup
// daemon involves spawning a daemon using the "-datadir=/backup" argument which
// creates a new daemon instance with it's own RPC config. For more info on this,
// visit: https:// en.bitcoin.it/wiki/Data_directory and
// https:// en.bitcoin.it/wiki/Running_bitcoind
"daemons": [
{
"host": "127.0.0.1",
"port": [censored],
"user": "[censored]",
"password": "[censored]",
// Enable streaming Block Notifications via ZeroMQ messaging from Bitcoin
// Family daemons. Using this is highly recommended. The value of this option
// is a string that should match the value of the -zmqpubhashblock parameter
// passed to the coin daemon. If you enable this, you should lower
// 'blockRefreshInterval' to 1000 or 0 to disable polling entirely.
// "zmqBlockNotifySocket": "tcp://127.0.0.1:15101",
// Enable streaming Block Notifications via WebSocket messaging from Ethereum
// family Parity daemons. Using this is highly recommended. The value of this
// option is a string that should match the value of the --ws-port parameter
// passed to the parity coin daemon. When using --ws-port, you should also
// specify --ws-interface all and
// --jsonrpc-apis "eth,net,web3,personal,parity,parity_pubsub,rpc"
// If you enable this, you should lower 'blockRefreshInterval' to 1000 or 0
// to disable polling entirely.
// "portWs": 18545,
}
],
// Generate payouts for recorded shares
"paymentProcessing": {
"enabled": true,
// Minimum payment in pool-base-currency (ie. Bitcoin, NOT Satoshis)
"minimumPayment": 1,
"payoutScheme": "SOLO",
"payoutSchemeConfig": {
"factor": 2.0
}
}
}
// This section ends here. Add , after } if this is not the last coin section
]
}

miningcore.js

/*!

// --------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------
// Current running domain (or ip address) url will be read from the browser url bar.
// You can check the result in you browser development view -> F12 -> Console
// -->> !! no need to change anything below here !! <<--
// --------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------

// read WebURL from current browser
var WebURL = "https://[censored]"; // Website URL is: https://domain.com/
// WebURL correction if not ends with /
if (WebURL.substring(WebURL.length-1) != "/")
{
WebURL = WebURL + "/";
console.log('Corrected WebURL, does not end with / -> New WebURL : ', WebURL);
}
var API = "https://[censored]:443/api/"; // API address is: https://domain.com/api/
// API correction if not ends with /
if (API.substring(API.length-1) != "/")
{
API = API + "/";
console.log('Corrected API, does not end with / -> New API : ', API);
}
var stratumAddress = "[censored]"; // Stratum address is: domain.com

// --------------------------------------------------------------------------------------------
// no need to change anything below here
// --------------------------------------------------------------------------------------------
console.log('MiningCore.WebUI : ', WebURL); // Returns website URL
console.log('API address used : ', API); // Returns API URL
console.log('Stratum address : ', "stratum+tcp://" + stratumAddress + ":"); // Returns Stratum URL
console.log('Page Load : ', window.location.href); // Returns full URL

currentPage = "index"

// check browser compatibility
var nua = navigator.userAgent;
//var is_android = ((nua.indexOf('Mozilla/5.0') > -1 && nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1) && !(nua.indexOf('Chrome') > -1));
var is_IE = ((nua.indexOf('Mozilla/5.0') > -1 && nua.indexOf('Trident') > -1) && !(nua.indexOf('Chrome') > -1));
if(is_IE) {
console.log('Running in IE browser is not supported - ', nua);
}

// Load INDEX Page content
function loadIndex() {
$("div[class^='page-").hide();

$(".page").hide();
//$(".page-header").show();
$(".page-wrapper").show();
$(".page-footer").show();

var hashList = window.location.hash.split(/[#/?=]/);
//var fullHash = document.URL.substr(document.URL.indexOf('#')+1); //IE
// example: #vtc/dashboard?address=VttsC2.....LXk9NJU
currentPool = hashList[1];
currentPage = hashList[2];
currentAddress = hashList[3];

if (currentPool && !currentPage)
{
currentPage ="stats"
}
else if(!currentPool && !currentPage)
{
currentPage ="index";
}
if (currentPool && currentPage) {
loadNavigation();
$(".main-index").hide();
$(".main-pool").show();
$(".page-" + currentPage).show();
$(".main-sidebar").show();
} else {
$(".main-index").show();
$(".main-pool").hide();
$(".page-index").show();
$(".main-sidebar").hide();
}

if (currentPool) {
$("li[class^='nav-']").removeClass("active");

switch (currentPage) {
  case "stats":
    console.log('Loading stats page content');
    $(".nav-stats").addClass("active");
    loadStatsPage();
    break;
  case "dashboard":
    console.log('Loading dashboard page content');
    $(".nav-dashboard").addClass("active");
	loadDashboardPage();
    break;
  case "miners":
    console.log('Loading miners page content');
    $(".nav-miners").addClass("active");
	loadMinersPage();
    break;
  case "blocks":
    console.log('Loading blocks page content');
    $(".nav-blocks").addClass("active");
    loadBlocksPage();
    break;
  case "payments":
    console.log('Loading payments page content');
    $(".nav-payments").addClass("active");
    loadPaymentsPage();
    break;
  case "connect":
    console.log('Loading connect page content');
    $(".nav-connect").addClass("active");
	loadConnectPage();
    break;
  case "faq":
    console.log('Loading faq page content');
    $(".nav-faq").addClass("active");
    break;
  case "support":
    console.log('Loading support page content');
    $(".nav-support").addClass("active");
    break;
  default:
  // default if nothing above fits
}

} else {
loadHomePage();
}
scrollPageTop();
}

// Load HOME page content
function loadHomePage() {
console.log('Loading home page content');
return $.ajax(API + "pools")
.done(function(data) {
const poolCoinCardTemplate = $(".index-coin-card-template").html();
//const poolCoinTableTemplate = ""; //$(".index-coin-table-template").html();

  var poolCoinTableTemplate = "";
	
  $.each(data.pools, function(index, value) {

    var coinLogo = "<img class='coinimg' src='img/coin/icon/" + value.coin.type.toLowerCase() + ".png' />";
	var coinName = value.coin.name;
	if (typeof coinName === "undefined" || coinName === null) {coinName = value.coin.type;} 
    		
	poolCoinTableTemplate += "<tr class='coin-table-row' href='#" + value.id + "'>";
	poolCoinTableTemplate += "<td class='coin'><a href='#" + value.id + "'<span>" + coinLogo + coinName + " (" + value.coin.type.toUpperCase() + ") </span></a></td>";
	poolCoinTableTemplate += "<td class='algo'>" + value.coin.algorithm + "</td>";
	poolCoinTableTemplate += "<td class='miners'>" + value.poolStats.connectedMiners + "</td>";
	poolCoinTableTemplate += "<td class='pool-hash'>" + _formatter(value.poolStats.poolHashrate, 5, "H/s") + "</td>";
	poolCoinTableTemplate += "<td class='fee'>" + value.poolFeePercent + " %</td>";
	poolCoinTableTemplate += "<td class='net-hash'>" + _formatter(value.networkStats.networkHashrate, 5, "H/s") + "</td>";
	poolCoinTableTemplate += "<td class='net-diff'>" + _formatter(value.networkStats.networkDifficulty, 5, "") + "</td>";
	poolCoinTableTemplate += "<td class='card-btn col-hide'>Go Mine " + coinLogo + coinName + "</td>";
	poolCoinTableTemplate += "</tr>";
  });

  //if (poolList.length > 0) {
   	$(".pool-coin-table").html(poolCoinTableTemplate);
  //}
  	  
  $(document).ready(function() {
    $('#pool-coins tr').click(function() {
      var href = $(this).find("a").attr("href");
      if(href) {
        window.location = href;
      }
    });
  });
  
})
.fail(function() {
  var poolCoinTableTemplate = "";
  
  poolCoinTableTemplate += "<tr><td colspan='8'> ";
  poolCoinTableTemplate += "<div class='alert alert-warning'>"
	poolCoinTableTemplate += "	<h4><i class='fas fa-exclamation-triangle'></i> Warning!</h4>";
	poolCoinTableTemplate += "	<hr>";
	poolCoinTableTemplate += "	<p>The pool is currently down for maintenance.</p>";
	poolCoinTableTemplate += "	<p>Please try again later.</p>";
  poolCoinTableTemplate += "</div>"
  poolCoinTableTemplate += "</td></tr>";
  
  $(".pool-coin-table").html(poolCoinTableTemplate);
  
});

}

// Load STATS page content
function loadStatsPage() {
//clearInterval();
setInterval(
(function load() {
loadStatsData();
return load;
})(),
60000
);
setInterval(
(function load() {
loadStatsChart();
return load;
})(),
600000
);
}

// Load DASHBOARD page content
function loadDashboardPage() {
function render() {
//clearInterval();
setInterval(
(function load() {
loadDashboardData($("#walletAddress").val());
loadDashboardWorkerList($("#walletAddress").val());
loadDashboardChart($("#walletAddress").val());
return load;
})(),
60000
);
}
var walletQueryString = window.location.hash.split(/[#/?]/)[3];
if (walletQueryString) {
var wallet = window.location.hash.split(/[#/?]/)[3].replace("address=", "");
if (wallet) {
$(walletAddress).val(wallet);
localStorage.setItem(currentPool + "-walletAddress", wallet);
render();
}
}
if (localStorage[currentPool + "-walletAddress"]) {
$("#walletAddress").val(localStorage[currentPool + "-walletAddress"]);
}
}

// Load MINERS page content
function loadMinersPage() {
return $.ajax(API + "pools/" + currentPool + "/miners?page=0&pagesize=20")
.done(function(data) {
var minerList = "";
if (data.length > 0) {
$.each(data, function(index, value) {
minerList += "";
//minerList += "" + value.miner + "";
minerList += '' + value.miner.substring(0, 12) + ' … ' + value.miner.substring(value.miner.length - 12) + '';
//minerList += '' + value.miner.substring(0, 12) + ' … ' + value.miner.substring(value.miner.length - 12) + '';
minerList += "" + _formatter(value.hashrate, 5, "H/s") + "";
minerList += "" + _formatter(value.sharesPerSecond, 5, "S/s") + "";
minerList += "";
});
} else {
minerList += 'No miner connected';
}
$("#minerList").html(minerList);
})
.fail(function() {
$.notify(
{
message: "Error: No response from API.
(loadMinersList)"
},
{
type: "danger",
timer: 3000
}
);
});
}

// Load BLOCKS page content
function loadBlocksPage() {
return $.ajax(API + "pools/" + currentPool + "/blocks?page=0&pageSize=100")
.done(function(data) {
var blockList = "";
if (data.length > 0) {
$.each(data, function(index, value) {
var createDate = convertLocalDateToUTCDate(new Date(value.created),false);
var effort = Math.round(value.effort * 100);
var effortClass = "";
if (effort < 30) {
effortClass = "effort1";
} else if (effort < 80) {
effortClass = "effort2";
} else if (effort < 110) {
effortClass = "effort3";
} else {
effortClass = "effort4";
}

      blockList += "<tr>";
      blockList += "<td>" + createDate + "</td>";
      blockList += "<td><a href='" + value.infoLink + "' target='_blank'>" + value.blockHeight + "</a></td>";
      if (typeof value.effort !== "undefined") {
        blockList += "<td class='" + effortClass + "'>" + effort + "%</td>";
      } else {
        blockList += "<td>n/a</td>";
      }
      var status = value.status;
      blockList += "<td>" + status + "</td>";
      blockList += "<td>" + _formatter(value.reward, 5, "") + "</td>";
      blockList += "<td><div class='c100 small p" + Math.round(value.confirmationProgress * 100) + "'><span>" + Math.round(value.confirmationProgress * 100) + "%</span><div class='slice'><div class='bar'></div><div class='fill'></div></div></div></td>";
      blockList += "</tr>";
    });
  } else {
    blockList += '<tr><td colspan="6">No blocks found yet</td></tr>';
  }

  $("#blockList").html(blockList);
})
.fail(function() {
  $.notify(
    {
      message: "Error: No response from API.<br>(loadBlocksList)"
    },
    {
      type: "danger",
      timer: 3000
    }
  );
});

}

// Load PAYMENTS page content
function loadPaymentsPage() {
return $.ajax(API + "pools/" + currentPool + "/payments?page=0&pageSize=500")
.done(function(data) {
var paymentList = "";
if (data.length > 0) {
$.each(data, function(index, value) {
var createDate = convertLocalDateToUTCDate(new Date(value.created),false);
paymentList += '';
paymentList += "" + createDate + "";
paymentList += '' + value.address.substring(0, 12) + ' … ' + value.address.substring(value.address.length - 12) + '';
paymentList += '' + _formatter(value.amount, 5, '') + '';
paymentList += '
' + value.transactionConfirmationData.substring(0, 16) + ' … ' + value.transactionConfirmationData.substring(value.transactionConfirmationData.length - 16) + ' ';
paymentList += '';
});
} else {
paymentList += 'No payments found yet';
}
$("#paymentList").html(paymentList);
})
.fail(function() {
$.notify(
{
message: "Error: No response from API.
(loadPaymentsList)"
},
{
type: "danger",
timer: 3000
}
);
});
}

// Load CONNECTION page content
function loadConnectPage() {
return $.ajax(API + "pools")
.done(function(data) {
var connectPoolConfig = "";
$.each(data.pools, function(index, value) {
if (currentPool === value.id) {

		defaultPort = Object.keys(value.ports)[0];
    	coinName = value.coin.name;
		coinType = value.coin.type.toLowerCase();
		algorithm = value.coin.algorithm;
		
		// Connect Pool config table
		connectPoolConfig += "<tr><td>Crypto Coin name</td><td>" + coinName + " (" + value.coin.type + ") </td></tr>";
		//connectPoolConfig += "<tr><td>Coin Family line </td><td>" + value.coin.family + "</td></tr>";
		connectPoolConfig += "<tr><td>Coin Algorithm</td><td>" + value.coin.algorithm + "</td></tr>";
		connectPoolConfig += '<tr><td>Pool Wallet</td><td><a href="' + value.addressInfoLink + '" target="_blank">' + value.address.substring(0, 12) + " &hellip; " + value.address.substring(value.address.length - 12) + "</a></td></tr>";
		connectPoolConfig += "<tr><td>Payout Scheme</td><td>" + value.paymentProcessing.payoutScheme + "</td></tr>";
		connectPoolConfig += "<tr><td>Minimum Payment</td><td>" + value.paymentProcessing.minimumPayment + " " + value.coin.type + "</td></tr>";
		if (typeof value.paymentProcessing.minimumPaymentToPaymentId !== "undefined") {
			connectPoolConfig += "<tr><td>Minimum Payout (to Exchange)</td><td>" + value.paymentProcessing.minimumPaymentToPaymentId + "</td></tr>";
		}
		connectPoolConfig += "<tr><td>Pool Fee</td><td>" + value.poolFeePercent + "%</td></tr>";
		$.each(value.ports, function(port, options) {
			connectPoolConfig += "<tr><td>stratum+tcp://" + coinType + "." + stratumAddress + ":" + port + "</td><td>";
			if (typeof options.varDiff !== "undefined" && options.varDiff != null) {
				connectPoolConfig += "Difficulty Variable / " + options.varDiff.minDiff + " &harr; ";
				if (typeof options.varDiff.maxDiff === "undefined" || options.varDiff.maxDiff == null) {
					connectPoolConfig += "&infin; ";
				} else {
					connectPoolConfig += options.varDiff.maxDiff;
				}
			} else {
				connectPoolConfig += "Difficulty Static / " + options.difficulty ;
			}
			connectPoolConfig += "</td></tr>";
		});

    }
  });
  connectPoolConfig += "</tbody>";
  $("#connectPoolConfig").html(connectPoolConfig);
  
  
  // Connect Miner config 
  $("#miner-config").html("");
  $("#miner-config").load("poolconfig/" + coinType + ".html",
    function( response, status, xhr ) {
      if ( status == "error" ) {
		$("#miner-config").load("poolconfig/default.html",
		  function(responseText){
			var config = $("#miner-config")
            .html()
			.replace(/{{ stratumAddress }}/g, coinType + "." + stratumAddress + ":" + defaultPort)
			.replace(/{{ coinName }}/g, coinName)
			.replace(/{{ aglorithm }}/g, algorithm);
			$(this).html(config);  
		  }
		);
	  } else {
		var config = $("#miner-config")
        .html()
        .replace(/{{ stratumAddress }}/g, coinType + "." + stratumAddress + ":" + defaultPort)
		.replace(/{{ coinName }}/g, coinName)
		.replace(/{{ aglorithm }}/g, algorithm);
        $(this).html(config);
	  }
    }
  );
})
.fail(function() {
  $.notify(
    {
      message: "Error: No response from API.<br>(loadConnectConfig)"
    },
    {
      type: "danger",
      timer: 3000
    }
  );
});

}

// Dashboard - load wallet stats
function loadWallet() {
console.log( 'Loading wallet address:',$("#walletAddress").val() );
if ($("#walletAddress").val().length > 0) {
localStorage.setItem(currentPool + "-walletAddress", $("#walletAddress").val() );
}
var coin = window.location.hash.split(/[#/?]/)[1];
var currentPage = window.location.hash.split(/[#/?]/)[2] || "stats";
window.location.href = "#" + currentPool + "/" + currentPage + "?address=" + $("#walletAddress").val();
}

// General formatter function
function _formatter(value, decimal, unit) {
if (value === 0) {
return "0 " + unit;
} else {
var si = [
{ value: 1, symbol: "" },
{ value: 1e3, symbol: "k" },
{ value: 1e6, symbol: "M" },
{ value: 1e9, symbol: "G" },
{ value: 1e12, symbol: "T" },
{ value: 1e15, symbol: "P" },
{ value: 1e18, symbol: "E" },
{ value: 1e21, symbol: "Z" },
{ value: 1e24, symbol: "Y" }
];
for (var i = si.length - 1; i > 0; i--) {
if (value >= si[i].value) {
break;
}
}
return ((value / si[i].value).toFixed(decimal).replace(/.0+$|(.[0-9]*[1-9])0+$/, "$1") + " " + si[i].symbol + unit);
}
}

// Time convert Local -> UTC
function convertLocalDateToUTCDate(date, toUTC) {
date = new Date(date);
//Local time converted to UTC
var localOffset = date.getTimezoneOffset() * 60000;
var localTime = date.getTime();
if (toUTC) {
date = localTime + localOffset;
} else {
date = localTime - localOffset;
}
newDate = new Date(date);
return newDate;
}

// Time convert UTC -> Local
function convertUTCDateToLocalDate(date) {
var newDate = new Date(date.getTime()+date.getTimezoneOffset()601000);
var localOffset = date.getTimezoneOffset() / 60;
var hours = date.getUTCHours();
newDate.setHours(hours - localOffset);
return newDate;
}

// Scroll to top off page
function scrollPageTop() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
var elmnt = document.getElementById("page-scroll-top");
elmnt.scrollIntoView();
}

// Check if file exits
function doesFileExist(urlToFile) {
var xhr = new XMLHttpRequest();
xhr.open('HEAD', urlToFile, false);
xhr.send();

if (xhr.status == "404") {
    return false;
} else {
    return true;
}

}

// STATS page data
function loadStatsData() {
return $.ajax(API + "pools")
.done(function(data) {
$.each(data.pools, function(index, value) {
if (currentPool === value.id) {

	  $("#blockchainHeight").text(value.networkStats.blockHeight);
	  $("#connectedPeers").text(value.networkStats.connectedPeers);
	  $("#minimumPayment").text(value.paymentProcessing.minimumPayment + " " + value.coin.type);
	  $("#payoutScheme").text(value.paymentProcessing.payoutScheme);
	  $("#poolFeePercent").text(value.poolFeePercent + " %");
	  
      $("#poolHashRate").text(_formatter(value.poolStats.poolHashrate, 5, "H/s"));
	  $("#poolMiners").text(value.poolStats.connectedMiners + " Miner(s)");
      
      $("#networkHashRate").text(_formatter(value.networkStats.networkHashrate, 5, "H/s"));
      $("#networkDifficulty").text(_formatter(value.networkStats.networkDifficulty, 5, ""));
    }
  });
})
.fail(function() {
  $.notify(
    {
      message: "Error: No response from API.<br>(loadStatsData)"
    },
    {
      type: "danger",
      timer: 3000
    }
  );
});

}

// STATS page charts
function loadStatsChart() {
return $.ajax(API + "pools/" + currentPool + "/performance")
.done(function(data) {
labels = [];

  poolHashRate = [];
  networkHashRate = [];
  networkDifficulty = [];
  connectedMiners = [];
  connectedWorkers = [];
  
  $.each(data.stats, function(index, value) {
    if (labels.length === 0 || (labels.length + 1) % 4 === 1) {
      var createDate = convertLocalDateToUTCDate(new Date(value.created),false);
      labels.push(createDate.getHours() + ":00");
    } else {
      labels.push("");
    }
	poolHashRate.push(value.poolHashrate);
    networkHashRate.push(value.networkHashrate);
	networkDifficulty.push(value.networkDifficulty);
    connectedMiners.push(value.connectedMiners);
    connectedWorkers.push(value.connectedWorkers);
  });
  
  var dataPoolHash          = {labels: labels,series: [poolHashRate]};
  var dataNetworkHash       = {labels: labels,series: [networkHashRate]};
  var dataNetworkDifficulty = {labels: labels,series: [networkDifficulty]};
  var dataMiners            = {labels: labels,series: [connectedMiners,connectedWorkers]};
  
  var options = {
	height: "200px",
    showArea: false,
    seriesBarDistance: 1,
    // low:Math.min.apply(null,networkHashRate)/1.1,
    axisX: {
      showGrid: false
    },
    axisY: {
      offset: 47,
      scale: "logcc",
      labelInterpolationFnc: function(value) {
        return _formatter(value, 1, "");
      }
    },
    lineSmooth: Chartist.Interpolation.simple({
      divisor: 2
    })
  };
  
  var responsiveOptions = [
    [
      "screen and (max-width: 320px)",
      {
        axisX: {
          labelInterpolationFnc: function(value) {
            return value[1];
          }
        }
      }
    ]
  ];
  Chartist.Line("#chartStatsHashRate", dataNetworkHash, options, responsiveOptions);
  Chartist.Line("#chartStatsHashRatePool",dataPoolHash,options,responsiveOptions);
  Chartist.Line("#chartStatsDiff", dataNetworkDifficulty, options, responsiveOptions);
  Chartist.Line("#chartStatsMiners", dataMiners, options, responsiveOptions);

})
.fail(function() {
  $.notify(
    {
      message: "Error: No response from API.<br>(loadStatsChart)"
    },
    {
      type: "danger",
      timer: 3000
    }
  );
});

}

// DASHBOARD page data
function loadDashboardData(walletAddress) {
return $.ajax(API + "pools/" + currentPool + "/miners/" + walletAddress)
.done(function(data) {
$("#pendingShares").text(_formatter(data.pendingShares, 0, ""));
var workerHashRate = 0;
if (data.performance) {
$.each(data.performance.workers, function(index, value) {
workerHashRate += value.hashrate;
});
}
$("#minerHashRate").text(_formatter(workerHashRate, 5, "H/s"));
$("#pendingBalance").text(_formatter(data.pendingBalance, 5, ""));
$("#paidBalance").text(_formatter(data.todayPaid, 5, ""));
$("#lifetimeBalance").text(_formatter(data.pendingBalance + data.totalPaid, 5, "")
);
})
.fail(function() {
$.notify(
{
message: "Error: No response from API.
(loadDashboardData)"
},
{
type: "danger",
timer: 3000
}
);
});
}

// DASHBOARD page Miner table
function loadDashboardWorkerList(walletAddress) {
return $.ajax(API + "pools/" + currentPool + "/miners/" + walletAddress)
.done(function(data) {
var workerList = "";
if (data.performance) {
var workerCount = 0;
$.each(data.performance.workers, function(index, value) {
workerCount++;
workerList += "";
workerList += "" + workerCount + "";
if (index.length === 0) {
workerList += "Unnamed";
} else {
workerList += "" + index + "";
}
workerList += "" + _formatter(value.hashrate, 5, "H/s") + "";
workerList +=
"" + _formatter(value.sharesPerSecond, 5, "S/s") + "";
workerList += "";
});
} else {
workerList += 'None';
}
$("#workerCount").text(workerCount);
$("#workerList").html(workerList);
})
.fail(function() {
$.notify(
{
message: "Error: No response from API.
(loadDashboardWorkerList)"
},
{
type: "danger",
timer: 3000
}
);
});
}

// DASHBOARD page chart
function loadDashboardChart(walletAddress) {
return $.ajax(API + "pools/" + currentPool + "/miners/" + walletAddress + "/performance")
.done(function(data) {

	labels = [];
    minerHashRate = [];
	
    $.each(data, function(index, value) {
      if (labels.length === 0 || (labels.length + 1) % 4 === 1) {
        var createDate = convertLocalDateToUTCDate(
          new Date(value.created),
          false
        );
        labels.push(createDate.getHours() + ":00");
      } else {
        labels.push("");
      }
      var workerHashRate = 0;
      $.each(value.workers, function(index2, value2) {workerHashRate += value2.hashrate;});
      minerHashRate.push(workerHashRate);
    });
    var data = {labels: labels,series: [minerHashRate]};
    var options = {
      height: "200px",
	  showArea: true,
	  seriesBarDistance: 1,
      axisX: {
        showGrid: false
      },
      axisY: {
        offset: 47,
        labelInterpolationFnc: function(value) {
          return _formatter(value, 1, "");
        }
      },
      lineSmooth: Chartist.Interpolation.simple({
        divisor: 2
      })
    };
    var responsiveOptions = [
      [
      "screen and (max-width: 320px)",
      {
        axisX: {
          labelInterpolationFnc: function(value) {
            return value[0];
          }
        }
      }
    ]
    ];
    Chartist.Line("#chartDashboardHashRate", data, options, responsiveOptions);

})
.fail(function() {
  $.notify(
    {
      message: "Error: No response from API.<br>(loadDashboardChart)"
    },
    {
      type: "danger",
      timer: 3000
    }
  );
});

}

// Generate Coin based sidebar
function loadNavigation() {
return $.ajax(API + "pools")
.done(function(data) {
var coinLogo = "";
var coinName = "";
var poolList = "

    ";
    $.each(data.pools, function(index, value) {
    poolList += "
  • ";
    poolList += " "
    poolList += " " + value.coin.type;
    poolList += "
    ";
    poolList += "
  • ";
    if (currentPool === value.id) {
    coinLogo = "";
    coinName = value.coin.name;
    if (typeof coinName === "undefined" || coinName === null) {
    coinName = value.coin.type;
    }
    }
    });
    poolList += "
";

  if (poolList.length > 0) {
    $(".coin-list-header").html(poolList);
  }
  
  var sidebarList = "";
  const sidebarTemplate = $(".sidebar-template").html();
  sidebarList += sidebarTemplate
	.replace(/{{ coinId }}/g, currentPool)
	.replace(/{{ coinLogo }}/g, coinLogo)
	.replace(/{{ coinName }}/g, coinName)
  $(".sidebar-wrapper").html(sidebarList);

  $("a.link").each(function() {
    if (localStorage[currentPool + "-walletAddress"] && this.href.indexOf("/dashboard") > 0)
    {
	  this.href = "#" + currentPool + "/dashboard?address=" + localStorage[currentPool + "-walletAddress"];
    } 
  });

})
.fail(function() {
  $.notify(
    {
      message: "Error: No response from API.<br>(loadNavigation)"
    },
    {
      type: "danger",
      timer: 3000
    }
  );
});

}

Nginx Config

server {
listen 80;
server_name [censored];

# Redirect all HTTP requests to HTTPS
location / {
    return 301 https://$server_name$request_uri;
}

}

server {
listen 443 ssl;
server_name [censored];

# SSL/TLS configuration
ssl_certificate /etc/letsencrypt/live/[sencored]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[sencored]/privkey.pem;

# Root directory and index files for the main site
root /var/www/html;
index index.html index.htm;

# Handle /api/ requests with proxy_pass
location /api/ {
    proxy_pass http://localhost:5000/api/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # Optional: set other proxy headers as needed
    # proxy_connect_timeout 1s;
    # proxy_send_timeout 30s;
    # proxy_read_timeout 30s;

    # Optional: enable buffering of responses from the proxied server
    # proxy_buffering on;
}

# Default location block for the main site
location / {
    # Serve static files directly from root
    try_files $uri $uri/ /index.html;
}

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions