node-miner
Version:
With this miner you can easily mine cryptocurrencies [Monero (XMR)](https://getmonero.org/) and [Electroneum (ETN)](http://electroneum.com/) on any stratum pool from node.js with the highest hashrate on your hardware. To get maximum hashrate this package
282 lines (281 loc) • 11.7 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var EventEmitter = require("events");
var WebSocket = require("ws");
var url = require("url");
var http = require("http");
var https = require("https");
var defaults = require("../config/defaults");
var Connection_1 = require("./Connection");
var Miner_1 = require("./Miner");
var Donation_1 = require("./Donation");
var Proxy = /** @class */ (function (_super) {
__extends(Proxy, _super);
function Proxy(constructorOptions) {
if (constructorOptions === void 0) { constructorOptions = defaults; }
var _this = _super.call(this) || this;
_this.host = null;
_this.port = null;
_this.pass = null;
_this.ssl = null;
_this.address = null;
_this.user = null;
_this.diff = null;
_this.dynamicPool = false;
_this.maxMinersPerConnection = 100;
_this.donations = [];
_this.connections = {};
_this.wss = null;
_this.key = null;
_this.cert = null;
_this.path = null;
_this.server = null;
_this.credentials = null;
_this.online = false;
var options = Object.assign({}, defaults, constructorOptions);
_this.host = options.host;
_this.port = options.port;
_this.pass = options.pass;
_this.ssl = options.ssl;
_this.address = options.address;
_this.user = options.user;
_this.diff = options.diff;
_this.dynamicPool = options.dynamicPool;
_this.maxMinersPerConnection = options.maxMinersPerConnection;
_this.donations = options.donations;
_this.key = options.key;
_this.cert = options.cert;
_this.path = options.path;
_this.server = options.server;
_this.credentials = options.credentials;
_this.on("error", function (error) {
/* prevent unhandled proxy errors from stopping the proxy */
console.error("proxy error:", error.message);
});
return _this;
}
Proxy.prototype.listen = function (port, host, callback) {
var _this = this;
var version = require("../package").version;
if (this.online) {
this.kill();
}
// create server
var isHTTPS = !!(this.key && this.cert);
if (!this.server) {
var stats = function (req, res) {
if (_this.credentials) {
var auth = require("basic-auth")(req);
if (!auth || auth.name !== _this.credentials.user || auth.pass !== _this.credentials.pass) {
res.statusCode = 401;
res.setHeader("WWW-Authenticate", 'Basic realm="Access to stats"');
res.end("Access denied");
return;
}
}
var url = require("url").parse(req.url);
if (url.pathname === "/ping") {
res.statusCode = 200;
res.end();
return;
}
if (url.pathname === "/ready") {
res.statusCode = _this.online ? 200 : 503;
res.end();
return;
}
if (url.pathname === "/version") {
var body_1 = JSON.stringify({ version: version });
res.writeHead(200, {
"Access-Control-Allow-Origin": "*",
"Content-Length": Buffer.byteLength(body_1),
"Content-Type": "application/json",
});
res.end(body_1);
return;
}
var proxyStats = _this.getStats();
var body = JSON.stringify({
code: 404,
error: "Not Found"
});
if (url.pathname === "/stats") {
body = JSON.stringify({
miners: proxyStats.miners.length,
connections: proxyStats.connections.length
}, null, 2);
}
if (url.pathname === "/miners") {
body = JSON.stringify(proxyStats.miners, null, 2);
}
if (url.pathname === "/connections") {
body = JSON.stringify(proxyStats.connections, null, 2);
}
res.writeHead(200, {
"Access-Control-Allow-Origin": "*",
"Content-Length": Buffer.byteLength(body),
"Content-Type": "application/json"
});
res.end(body);
};
if (isHTTPS) {
var certificates = {
key: this.key,
cert: this.cert
};
this.server = https.createServer(certificates, stats);
}
else {
this.server = http.createServer(stats);
}
}
var wssOptions = {
server: this.server
};
if (this.path) {
wssOptions.path = this.path;
}
this.wss = new WebSocket.Server(wssOptions);
this.wss.on("connection", function (ws, req) {
var params = url.parse(req.url, true).query;
params.pool = params.id;
var host = _this.host;
var port = _this.port;
var pass = _this.pass;
if (params.pool && _this.dynamicPool) {
var split = params.pool.split(":");
host = split[0] || _this.host;
port = Number(split[1]) || _this.port;
pass = split[2] || _this.pass;
console.log("Miner connected to pool", host);
}
var connection = _this.getConnection(host, port);
var donations = _this.donations.map(function (donation) {
return new Donation_1.default({
address: donation.address,
host: donation.host,
port: donation.port,
pass: donation.pass,
percentage: donation.percentage,
connection: _this.getConnection(donation.host, donation.port, true)
});
});
var miner = new Miner_1.default({
connection: connection,
ws: ws,
address: _this.address,
user: _this.user,
diff: _this.diff,
pass: pass,
donations: donations
});
miner.on("open", function (data) { return _this.emit("open", data); });
miner.on("authed", function (data) { return _this.emit("authed", data); });
miner.on("job", function (data) { return _this.emit("job", data); });
miner.on("found", function (data) { return _this.emit("found", data); });
miner.on("accepted", function (data) { return _this.emit("accepted", data); });
miner.on("close", function (data) { return _this.emit("close", data); });
miner.on("error", function (data) { return _this.emit("error", data); });
miner.connect();
});
if (!host && !callback) {
this.server.listen(port);
}
else if (!host && callback) {
this.server.listen(port, callback);
}
else if (host && !callback) {
this.server.listen(port, host);
}
else {
this.server.listen(port, host, callback);
}
this.wss.on("listening", function () {
_this.online = true;
console.log("listening on port " + port + (isHTTPS ? ", using a secure connection" : ""));
console.log("miners per connection:", _this.maxMinersPerConnection);
if (wssOptions.path) {
console.log("path: " + wssOptions.path);
}
if (!_this.dynamicPool) {
console.log("host: " + _this.host);
console.log("port: " + _this.port);
console.log("pass: " + _this.pass);
}
});
};
Proxy.prototype.getConnection = function (host, port, donation) {
var _this = this;
if (donation === void 0) { donation = false; }
var connectionId = host + ":" + port;
if (!this.connections[connectionId]) {
this.connections[connectionId] = [];
}
var connections = this.connections[connectionId];
var availableConnections = connections.filter(function (connection) { return _this.isAvailable(connection); });
if (availableConnections.length === 0) {
var connection = new Connection_1.default({ host: host, port: port, ssl: this.ssl, donation: donation });
connection.connect();
connection.on("close", function () {
console.log("connection closed (" + connectionId + ")");
});
connection.on("error", function (error) {
console.log("connection error (" + connectionId + "):", error.message);
});
connections.push(connection);
return connection;
}
return availableConnections.pop();
};
Proxy.prototype.isAvailable = function (connection) {
return (connection.miners.length < this.maxMinersPerConnection &&
connection.donations.length < this.maxMinersPerConnection);
};
Proxy.prototype.isEmpty = function (connection) {
return connection.miners.length === 0 && connection.donations.length === 0;
};
Proxy.prototype.getStats = function () {
var _this = this;
return Object.keys(this.connections).reduce(function (stats, key) { return ({
miners: stats.miners.concat(_this.connections[key].reduce(function (miners, connection) { return miners.concat(connection.miners.map(function (miner) { return ({
id: miner.id,
login: miner.login,
hashes: miner.hashes
}); })); }, [])),
connections: stats.connections.concat(_this.connections[key].filter(function (connection) { return !connection.donation; }).map(function (connection) { return ({
id: connection.id,
host: connection.host,
port: connection.port,
miners: connection.miners.length
}); }))
}); }, {
miners: [],
connections: []
});
};
Proxy.prototype.kill = function () {
var _this = this;
Object.keys(this.connections).forEach(function (connectionId) {
var connections = _this.connections[connectionId];
connections.forEach(function (connection) {
connection.kill();
connection.miners.forEach(function (miner) { return miner.kill(); });
});
});
this.wss.close();
this.online = false;
console.log("\uD83D\uDC80");
};
return Proxy;
}(EventEmitter));
exports.default = Proxy;
;