Files
bch-api/dist/app.js
T

235 lines
8.5 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var express = require("express");
// Middleware
var route_ratelimit_1 = require("./middleware/route-ratelimit");
var path = require("path");
var logger = require("morgan");
var wlogger = require("./util/winston-logging");
var cookieParser = require("cookie-parser");
var bodyParser = require("body-parser");
var basicAuth = require("express-basic-auth");
var helmet = require("helmet");
var debug = require("debug")("rest-cloud:server");
var http = require("http");
var cors = require("cors");
var AuthMW = require("./middleware/auth");
var BitcoinCashZMQDecoder = require("bitcoincash-zmq-decoder");
var zmq = require("zeromq");
var sock = zmq.socket("sub");
var swStats = require("swagger-stats");
var apiSpec;
if (process.env.NETWORK === "mainnet") {
apiSpec = require("./public/bitcoin-com-mainnet-rest-v2.json");
}
else {
apiSpec = require("./public/bitcoin-com-testnet-rest-v2.json");
}
// v1
var indexV1 = require("./routes/v1/index");
var healthCheckV1 = require("./routes/v1/health-check");
var addressV1 = require("./routes/v1/address");
var blockV1 = require("./routes/v1/block");
var blockchainV1 = require("./routes/v1/blockchain");
var controlV1 = require("./routes/v1/control");
var generatingV1 = require("./routes/v1/generating");
var miningV1 = require("./routes/v1/mining");
var networkV1 = require("./routes/v1/network");
var rawtransactionsV1 = require("./routes/v1/rawtransactions");
var transactionV1 = require("./routes/v1/transaction");
var utilV1 = require("./routes/v1/util");
var dataRetrievalV1 = require("./routes/v1/dataRetrieval");
var payloadCreationV1 = require("./routes/v1/payloadCreation");
var slpV1 = require("./routes/v1/slp");
// v2
var indexV2 = require("./routes/v2/index");
var healthCheckV2 = require("./routes/v2/health-check");
var addressV2 = require("./routes/v2/address");
var blockV2 = require("./routes/v2/block");
var blockchainV2 = require("./routes/v2/blockchain");
var controlV2 = require("./routes/v2/control");
var generatingV2 = require("./routes/v2/generating");
var miningV2 = require("./routes/v2/mining");
var networkV2 = require("./routes/v2/network");
var rawtransactionsV2 = require("./routes/v2/rawtransactions");
var transactionV2 = require("./routes/v2/transaction");
var utilV2 = require("./routes/v2/util");
var slpV2 = require("./routes/v2/slp");
require("dotenv").config();
var app = express();
app.locals.env = process.env;
app.use(swStats.getMiddleware({ swaggerSpec: apiSpec }));
app.use(helmet());
app.use(cors());
app.enable("trust proxy");
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");
app.use("/public", express.static(__dirname + "/public"));
app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
// Make io accessible to our router
app.use(function (req, res, next) {
req.io = io;
next();
});
var v1prefix = "v1";
var v2prefix = "v2";
app.use("/", indexV1);
app.use("/" + v1prefix + "/" + "health-check", healthCheckV1);
app.use("/" + v1prefix + "/" + "address", addressV1);
app.use("/" + v1prefix + "/" + "blockchain", blockchainV1);
app.use("/" + v1prefix + "/" + "block", blockV1);
app.use("/" + v1prefix + "/" + "control", controlV1);
app.use("/" + v1prefix + "/" + "generating", generatingV1);
app.use("/" + v1prefix + "/" + "mining", miningV1);
app.use("/" + v1prefix + "/" + "network", networkV1);
app.use("/" + v1prefix + "/" + "rawtransactions", rawtransactionsV1);
app.use("/" + v1prefix + "/" + "transaction", transactionV1);
app.use("/" + v1prefix + "/" + "util", utilV1);
app.use("/" + v1prefix + "/" + "dataRetrieval", dataRetrievalV1);
app.use("/" + v1prefix + "/" + "payloadCreation", payloadCreationV1);
app.use("/" + v1prefix + "/" + "slp", slpV1);
// Instantiate the authorization middleware, used to implement pro-tier rate limiting.
var auth = new AuthMW();
app.use("/" + v2prefix + "/", auth.mw());
// Rate limit on all v2 routes
app.use("/" + v2prefix + "/", route_ratelimit_1.routeRateLimit);
app.use("/", indexV2);
app.use("/" + v2prefix + "/" + "health-check", healthCheckV2);
app.use("/" + v2prefix + "/" + "address", addressV2.router);
app.use("/" + v2prefix + "/" + "blockchain", blockchainV2.router);
app.use("/" + v2prefix + "/" + "block", blockV2.router);
app.use("/" + v2prefix + "/" + "control", controlV2.router);
app.use("/" + v2prefix + "/" + "generating", generatingV2);
app.use("/" + v2prefix + "/" + "mining", miningV2.router);
app.use("/" + v2prefix + "/" + "network", networkV2);
app.use("/" + v2prefix + "/" + "rawtransactions", rawtransactionsV2.router);
app.use("/" + v2prefix + "/" + "transaction", transactionV2.router);
app.use("/" + v2prefix + "/" + "util", utilV2.router);
app.use("/" + v2prefix + "/" + "slp", slpV2.router);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = {
message: "Not Found",
status: 404
};
next(err);
});
// error handler
app.use(function (err, req, res, next) {
var status = err.status || 500;
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(status);
res.json({
status: status,
message: err.message
});
});
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || "3000");
app.set("port", port);
console.log("rest.bitcoin.com started on port " + port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
var io = require("socket.io").listen(server);
io.on("connection", function (socket) {
console.log("Socket Connected");
socket.on("disconnect", function () {
console.log("Socket Disconnected");
});
});
/**
* Setup ZMQ connections if ZMQ URL and port provided
*/
if (process.env.ZEROMQ_URL && process.env.ZEROMQ_PORT) {
console.log("Connecting to BCH ZMQ at " + process.env.ZEROMQ_URL + ":" + process.env.ZEROMQ_PORT);
var bitcoincashZmqDecoder_1 = new BitcoinCashZMQDecoder(process.env.NETWORK);
sock.connect("tcp://" + process.env.ZEROMQ_URL + ":" + process.env.ZEROMQ_PORT);
sock.subscribe("raw");
sock.on("message", function (topic, message) {
try {
var decoded = topic.toString("ascii");
if (decoded === "rawtx") {
var txd = bitcoincashZmqDecoder_1.decodeTransaction(message);
io.emit("transactions", JSON.stringify(txd, null, 2));
}
else if (decoded === "rawblock") {
var blck = bitcoincashZmqDecoder_1.decodeBlock(message);
io.emit("blocks", JSON.stringify(blck, null, 2));
}
}
catch (error) {
var errorMessage = 'Error processing ZMQ message';
console.log(errorMessage, error);
wlogger.error(errorMessage, error);
}
});
}
else {
console.log("ZEROMQ_URL and ZEROMQ_PORT env vars missing. Skipping ZMQ connection.");
}
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on("error", onError);
server.on("listening", onListening);
// Set the time before a timeout error is generated. This impacts testing and
// the handling of timeout errors. Is 10 seconds too agressive?
server.setTimeout(30 * 1000);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== "listen")
throw error;
var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case "EACCES":
console.error(bind + " requires elevated privileges");
process.exit(1);
break;
case "EADDRINUSE":
console.error(bind + " is already in use");
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
debug("Listening on " + bind);
}