mirror of
https://github.com/fullstack-cash/bch-api.git
synced 2026-09-22 01:02:05 -07:00
Merge pull request #1 from christroutner/unstable
Refactoring all code from TypeScript back to JavaScript
This commit is contained in:
+1
-1
@@ -17,6 +17,7 @@
|
||||
"no-extra-label": ["error"],
|
||||
"no-floating-decimal": ["error"],
|
||||
"no-implicit-coercion": ["error", { "allow": ["!!"] }],
|
||||
"no-lonely-if": ["off"],
|
||||
"wrap-iife": ["error", "inside"],
|
||||
"strict": ["error", "global"],
|
||||
"func-call-spacing": ["error", "never"],
|
||||
@@ -24,7 +25,6 @@
|
||||
"keyword-spacing": ["error"],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"new-parens": ["error"],
|
||||
"no-lonely-if": ["error"],
|
||||
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1 }],
|
||||
"no-whitespace-before-property": ["error"],
|
||||
"semi": ["error", "never"],
|
||||
|
||||
Vendored
-234
@@ -1,234 +0,0 @@
|
||||
"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);
|
||||
}
|
||||
Vendored
-78
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
Handle authorization for bypassing rate limits.
|
||||
|
||||
This file uses the passport npm library to check the header of each REST API
|
||||
call for the prescence of a Basic authorization header:
|
||||
https://en.wikipedia.org/wiki/Basic_access_authentication
|
||||
|
||||
If the header is found and validated, the req.locals.proLimit Boolean value
|
||||
is set and passed to the route-ratelimits.ts middleware.
|
||||
*/
|
||||
"use strict";
|
||||
var passport = require("passport");
|
||||
var BasicStrategy = require("passport-http").BasicStrategy;
|
||||
var AnonymousStrategy = require("passport-anonymous");
|
||||
var wlogger = require("../util/winston-logging");
|
||||
// Used for debugging and iterrogating JS objects.
|
||||
var util = require("util");
|
||||
util.inspect.defaultOptions = { depth: 1 };
|
||||
var _this;
|
||||
// Set default rate limit value for testing
|
||||
var PRO_PASSes = process.env.PRO_PASS ? process.env.PRO_PASS : "BITBOX";
|
||||
// Convert the pro-tier password string into an array split by ':'.
|
||||
var PRO_PASS = PRO_PASSes.split(":");
|
||||
//wlogger.verbose(`PRO_PASS set to: ${PRO_PASS}`)
|
||||
// Auth Middleware
|
||||
var AuthMW = /** @class */ (function () {
|
||||
function AuthMW() {
|
||||
_this = this;
|
||||
// Initialize passport for 'anonymous' authentication.
|
||||
/*
|
||||
passport.use(
|
||||
new AnonymousStrategy({ passReqToCallback: true }, function(
|
||||
req,
|
||||
username,
|
||||
password,
|
||||
done
|
||||
) {
|
||||
console.log(`anonymous auth handler triggered.`)
|
||||
})
|
||||
)
|
||||
*/
|
||||
passport.use(new AnonymousStrategy());
|
||||
// Initialize passport for 'basic' authentication.
|
||||
passport.use(new BasicStrategy({ passReqToCallback: true }, function (req, username, password, done) {
|
||||
//console.log(`req: ${util.inspect(req)}`)
|
||||
//console.log(`username: ${username}`)
|
||||
//console.log(`password: ${password}`)
|
||||
// Create the req.locals property if it does not yet exist.
|
||||
if (!req.locals)
|
||||
req.locals = {};
|
||||
// Set pro-tier rate limit to flag to false by default.
|
||||
req.locals.proLimit = false;
|
||||
// Evaluate the username and password and set the rate limit accordingly.
|
||||
//if (username === "BITBOX" && password === PRO_PASS) {
|
||||
if (username === "BITBOX") {
|
||||
for (var i = 0; i < PRO_PASS.length; i++) {
|
||||
var thisPass = PRO_PASS[i];
|
||||
if (password === thisPass) {
|
||||
wlogger.verbose(req.url + " called by " + password.slice(0, 6));
|
||||
// Success
|
||||
req.locals.proLimit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log(`req.locals: ${util.inspect(req.locals)}`)
|
||||
return done(null, true);
|
||||
}));
|
||||
}
|
||||
// Middleware called by the route.
|
||||
AuthMW.prototype.mw = function () {
|
||||
return passport.authenticate(["basic", "anonymous"], {
|
||||
session: false
|
||||
});
|
||||
};
|
||||
return AuthMW;
|
||||
}());
|
||||
module.exports = AuthMW;
|
||||
Vendored
-81
@@ -1,81 +0,0 @@
|
||||
"use strict";
|
||||
/*
|
||||
This file controls the request-per-minute (RPM) rate limits.
|
||||
|
||||
It is assumed that this middleware is run AFTER the auth.js middleware which
|
||||
checks for Basic auth. If the user adds the correct Basic auth to the header
|
||||
of their API request, they will get pro-tier rate limits. By default, the
|
||||
freemium rate limits apply.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var RateLimit = require("express-rate-limit");
|
||||
// Set max requests per minute
|
||||
var maxRequests = process.env.RATE_LIMIT_MAX_REQUESTS
|
||||
? parseInt(process.env.RATE_LIMIT_MAX_REQUESTS)
|
||||
: 60;
|
||||
// Pro-tier rate limits are 10x the freemium limits.
|
||||
var PRO_RPM = 10 * maxRequests;
|
||||
// Unique route mapped to its rate limit
|
||||
var uniqueRateLimits = {};
|
||||
var routeRateLimit = function (req, res, next) {
|
||||
// Create a res.locals object if not passed in.
|
||||
if (!req.locals)
|
||||
req.locals = {};
|
||||
// Disable rate limiting if 0 passed from RATE_LIMIT_MAX_REQUESTS
|
||||
if (maxRequests === 0)
|
||||
return next();
|
||||
// Current route
|
||||
var rateLimitTier = req.locals.proLimit ? "PRO" : "BASIC";
|
||||
var path = req.baseUrl + req.path;
|
||||
var route = rateLimitTier +
|
||||
req.method +
|
||||
path
|
||||
.split("/")
|
||||
.slice(0, 4)
|
||||
.join("/");
|
||||
// This boolean value is passed from the auth.js middleware.
|
||||
var proRateLimits = req.locals.proLimit;
|
||||
// Pro level rate limits
|
||||
if (proRateLimits) {
|
||||
// TODO: replace the console.logs with calls to our logging system.
|
||||
//console.log(`applying pro-rate limits`)
|
||||
// Create new RateLimit if none exists for this route
|
||||
if (!uniqueRateLimits[route]) {
|
||||
uniqueRateLimits[route] = new RateLimit({
|
||||
windowMs: 60 * 1000,
|
||||
delayMs: 0,
|
||||
max: PRO_RPM,
|
||||
handler: function (req, res /*next*/) {
|
||||
//console.log(`pro-tier rate-handler triggered.`)
|
||||
res.status(429); // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
||||
return res.json({
|
||||
error: "Too many requests. Limits are " + PRO_RPM + " requests per minute."
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// Freemium level rate limits
|
||||
}
|
||||
else {
|
||||
// TODO: replace the console.logs with calls to our logging system.
|
||||
//console.log(`applying freemium limits`)
|
||||
// Create new RateLimit if none exists for this route
|
||||
if (!uniqueRateLimits[route]) {
|
||||
uniqueRateLimits[route] = new RateLimit({
|
||||
windowMs: 60 * 1000,
|
||||
delayMs: 0,
|
||||
max: maxRequests,
|
||||
handler: function (req, res /*next*/) {
|
||||
//console.log(`freemium rate-handler triggered.`)
|
||||
res.status(429); // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
||||
return res.json({
|
||||
error: "Too many requests. Limits are " + maxRequests + " requests per minute."
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Call rate limit for this route
|
||||
uniqueRateLimits[route](req, res, next);
|
||||
};
|
||||
exports.routeRateLimit = routeRateLimit;
|
||||
-3099
File diff suppressed because it is too large
Load Diff
Vendored
-4181
File diff suppressed because it is too large
Load Diff
-3099
File diff suppressed because it is too large
Load Diff
Vendored
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 4.3 KiB |
Vendored
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB |
Vendored
-16468
File diff suppressed because one or more lines are too long
-5524
File diff suppressed because one or more lines are too long
Vendored
-1726
File diff suppressed because it is too large
Load Diff
Vendored
-3
File diff suppressed because one or more lines are too long
Vendored
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Instantiates and configures the Winston logging library. This utitlity library
|
||||
can be called by other parts of the application to conveniently tap into the
|
||||
logging library.
|
||||
*/
|
||||
"use strict";
|
||||
var winston = require("winston");
|
||||
require("winston-daily-rotate-file");
|
||||
var NETWORK = process.env.NETWORK;
|
||||
// Configure daily-rotation transport.
|
||||
var transport = new winston.transports.DailyRotateFile({
|
||||
filename: __dirname + "/../../logs/rest-" + NETWORK + "-%DATE%.log",
|
||||
datePattern: "YYYY-MM-DD",
|
||||
zippedArchive: false,
|
||||
maxSize: "1m",
|
||||
maxFiles: "5d",
|
||||
format: winston.format.combine(winston.format.timestamp(), winston.format.json())
|
||||
});
|
||||
transport.on("rotate", function (oldFilename, newFilename) {
|
||||
wlogger.info("Rotating log files");
|
||||
});
|
||||
// This controls what goes into the log FILES
|
||||
var wlogger = winston.createLogger({
|
||||
level: "verbose",
|
||||
format: winston.format.json(),
|
||||
transports: [
|
||||
//
|
||||
// - Write to all logs with level `info` and below to `combined.log`
|
||||
// - Write all logs error (and below) to `error.log`.
|
||||
//
|
||||
// new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
|
||||
// new winston.transports.File({ filename: 'logs/combined.log' })
|
||||
transport
|
||||
]
|
||||
});
|
||||
// This controls the logs to CONSOLE
|
||||
/*
|
||||
wlogger.add(
|
||||
new winston.transports.Console({
|
||||
format: winston.format.simple(),
|
||||
level: "info"
|
||||
})
|
||||
)
|
||||
*/
|
||||
module.exports = wlogger;
|
||||
Vendored
-64
@@ -1,64 +0,0 @@
|
||||
doctype html
|
||||
// HTML for static distribution bundle build
|
||||
html(lang='en')
|
||||
head
|
||||
// Global site tag (gtag.js) - Google Analytics
|
||||
script(async='', src='https://www.googletagmanager.com/gtag/js?id=UA-115463658-5')
|
||||
script.
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-115463658-5');
|
||||
|
||||
meta(charset='UTF-8')
|
||||
title REST V2 by Bitcoin.com - BCH RPC over HTTP
|
||||
link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700', rel='stylesheet')
|
||||
link(rel='stylesheet', type='text/css', href='../../public/swagger-ui-v2.css')
|
||||
link(rel='icon', type='image/png', href='../public/favicon.png', sizes='32x32')
|
||||
style.
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
body
|
||||
#swagger-ui
|
||||
script(src='../public/swagger-ui-bundle.js')
|
||||
script(src='../public/swagger-ui-standalone-preset.js')
|
||||
script.
|
||||
window.onload = function() {
|
||||
let network = "#{env.NETWORK}"
|
||||
let path;
|
||||
if(network === 'mainnet') {
|
||||
path = "../public/bitcoin-com-mainnet-rest-v2.json"
|
||||
} else {
|
||||
path = "../public/bitcoin-com-testnet-rest-v2.json"
|
||||
}
|
||||
const ui = SwaggerUIBundle({
|
||||
|
||||
url: path,
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
window.ui = ui
|
||||
}
|
||||
Vendored
-57
@@ -1,57 +0,0 @@
|
||||
doctype html
|
||||
// HTML for static distribution bundle build
|
||||
html(lang='en')
|
||||
head
|
||||
// Global site tag (gtag.js) - Google Analytics
|
||||
script(async='', src='https://www.googletagmanager.com/gtag/js?id=UA-115463658-5')
|
||||
script.
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-115463658-5');
|
||||
|
||||
meta(charset='UTF-8')
|
||||
title REST by Bitcoin.com - BCH RPC over HTTP
|
||||
link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700', rel='stylesheet')
|
||||
link(rel='stylesheet', type='text/css', href='../public/swagger-ui.css')
|
||||
link(rel='icon', type='image/png', href='../public/favicon.png', sizes='32x32')
|
||||
style.
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
body
|
||||
#swagger-ui
|
||||
script(src='../public/swagger-ui-bundle.js')
|
||||
script(src='../public/swagger-ui-standalone-preset.js')
|
||||
script.
|
||||
window.onload = function() {
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "../public/bitcoin-com-rest-v1.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
window.ui = ui
|
||||
}
|
||||
+2
-4
@@ -8,11 +8,9 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "npm run build && node ./dist/app.js",
|
||||
"build": "node ./node_modules/gulp/bin/gulp.js build && ./node_modules/typescript/bin/tsc",
|
||||
"start": "node ./src/app.js",
|
||||
"dev": "nodemon ./dist/app.js",
|
||||
"test": "npm run test-v2",
|
||||
"test-v1": "npm run build && nyc --reporter=text mocha --require babel-core/register --timeout 15000 test/v1/",
|
||||
"test": "export NETWORK=testnet && nyc --reporter=text mocha --timeout 25000 test/v2/",
|
||||
"test-v2": "export NETWORK=testnet && npm run build && nyc --reporter=text mocha --require babel-core/register --timeout 25000 test/v2/",
|
||||
"test-v2-no-build": "export NETWORK=testnet && nyc --reporter=text mocha --require babel-core/register --timeout 25000 test/v2/",
|
||||
"test-all": "TEST=integration nyc --reporter=text mocha --require babel-core/register --timeout 15000 test/v1/ test/v2/",
|
||||
|
||||
+35
-77
@@ -1,10 +1,10 @@
|
||||
"use strict"
|
||||
import { Socket } from "net"
|
||||
const { Socket } = require("net")
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
|
||||
// Middleware
|
||||
import { routeRateLimit } from "./middleware/route-ratelimit"
|
||||
const { routeRateLimit } = require("./middleware/route-ratelimit")
|
||||
|
||||
const path = require("path")
|
||||
const logger = require("morgan")
|
||||
@@ -22,32 +22,14 @@ const BitcoinCashZMQDecoder = require("bitcoincash-zmq-decoder")
|
||||
|
||||
const zmq = require("zeromq")
|
||||
|
||||
const sock: any = zmq.socket("sub")
|
||||
|
||||
const sock = zmq.socket("sub")
|
||||
/*
|
||||
const swStats = require("swagger-stats")
|
||||
let apiSpec
|
||||
if (process.env.NETWORK === "mainnet") {
|
||||
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
|
||||
const indexV1 = require("./routes/v1/index")
|
||||
const healthCheckV1 = require("./routes/v1/health-check")
|
||||
const addressV1 = require("./routes/v1/address")
|
||||
const blockV1 = require("./routes/v1/block")
|
||||
const blockchainV1 = require("./routes/v1/blockchain")
|
||||
const controlV1 = require("./routes/v1/control")
|
||||
const generatingV1 = require("./routes/v1/generating")
|
||||
const miningV1 = require("./routes/v1/mining")
|
||||
const networkV1 = require("./routes/v1/network")
|
||||
const rawtransactionsV1 = require("./routes/v1/rawtransactions")
|
||||
const transactionV1 = require("./routes/v1/transaction")
|
||||
const utilV1 = require("./routes/v1/util")
|
||||
const dataRetrievalV1 = require("./routes/v1/dataRetrieval")
|
||||
const payloadCreationV1 = require("./routes/v1/payloadCreation")
|
||||
const slpV1 = require("./routes/v1/slp")
|
||||
else apiSpec = require("./public/bitcoin-com-testnet-rest-v2.json")
|
||||
*/
|
||||
|
||||
// v2
|
||||
const indexV2 = require("./routes/v2/index")
|
||||
@@ -64,18 +46,13 @@ const transactionV2 = require("./routes/v2/transaction")
|
||||
const utilV2 = require("./routes/v2/util")
|
||||
const slpV2 = require("./routes/v2/slp")
|
||||
|
||||
interface IError {
|
||||
message: string
|
||||
status: number
|
||||
}
|
||||
|
||||
require("dotenv").config()
|
||||
|
||||
const app: express.Application = express()
|
||||
const app = express()
|
||||
|
||||
app.locals.env = process.env
|
||||
|
||||
app.use(swStats.getMiddleware({ swaggerSpec: apiSpec }))
|
||||
//app.use(swStats.getMiddleware({ swaggerSpec: apiSpec }))
|
||||
|
||||
app.use(helmet())
|
||||
|
||||
@@ -103,38 +80,15 @@ app.use(express.static(path.join(__dirname, "public")))
|
||||
// }
|
||||
// ));
|
||||
|
||||
interface ICustomRequest extends express.Request {
|
||||
io: any
|
||||
}
|
||||
|
||||
// Make io accessible to our router
|
||||
app.use(
|
||||
(req: ICustomRequest, res: express.Response, next: express.NextFunction) => {
|
||||
req.io = io
|
||||
app.use((req, res, next) => {
|
||||
req.io = io
|
||||
|
||||
next()
|
||||
}
|
||||
)
|
||||
next()
|
||||
})
|
||||
|
||||
const v1prefix = "v1"
|
||||
const 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.
|
||||
const auth = new AuthMW()
|
||||
app.use(`/${v2prefix}/`, auth.mw())
|
||||
@@ -156,19 +110,17 @@ app.use(`/${v2prefix}/` + `util`, utilV2.router)
|
||||
app.use(`/${v2prefix}/` + `slp`, slpV2.router)
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
app.use(
|
||||
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
const err: IError = {
|
||||
message: "Not Found",
|
||||
status: 404
|
||||
}
|
||||
|
||||
next(err)
|
||||
app.use((req, res, next) => {
|
||||
const err = {
|
||||
message: "Not Found",
|
||||
status: 404
|
||||
}
|
||||
)
|
||||
|
||||
next(err)
|
||||
})
|
||||
|
||||
// error handler
|
||||
app.use((err: IError, req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
app.use((err, req, res, next) => {
|
||||
const status = err.status || 500
|
||||
|
||||
// set locals, only providing error in development
|
||||
@@ -195,7 +147,7 @@ console.log(`rest.bitcoin.com started on port ${port}`)
|
||||
*/
|
||||
const server = http.createServer(app)
|
||||
const io = require("socket.io").listen(server)
|
||||
io.on("connection", (socket: Socket) => {
|
||||
io.on("connection", socket => {
|
||||
console.log("Socket Connected")
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
@@ -208,13 +160,17 @@ io.on("connection", (socket: Socket) => {
|
||||
*/
|
||||
|
||||
if (process.env.ZEROMQ_URL && process.env.ZEROMQ_PORT) {
|
||||
console.log(`Connecting to BCH ZMQ at ${process.env.ZEROMQ_URL}:${process.env.ZEROMQ_PORT}`)
|
||||
console.log(
|
||||
`Connecting to BCH ZMQ at ${process.env.ZEROMQ_URL}:${
|
||||
process.env.ZEROMQ_PORT
|
||||
}`
|
||||
)
|
||||
const bitcoincashZmqDecoder = new BitcoinCashZMQDecoder(process.env.NETWORK)
|
||||
|
||||
sock.connect(`tcp://${process.env.ZEROMQ_URL}:${process.env.ZEROMQ_PORT}`)
|
||||
sock.subscribe("raw")
|
||||
|
||||
sock.on("message", (topic: any, message: string) => {
|
||||
sock.on("message", (topic, message) => {
|
||||
try {
|
||||
const decoded = topic.toString("ascii")
|
||||
if (decoded === "rawtx") {
|
||||
@@ -225,13 +181,15 @@ if (process.env.ZEROMQ_URL && process.env.ZEROMQ_PORT) {
|
||||
io.emit("blocks", JSON.stringify(blck, null, 2))
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = 'Error processing ZMQ message'
|
||||
const 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.")
|
||||
console.log(
|
||||
"ZEROMQ_URL and ZEROMQ_PORT env vars missing. Skipping ZMQ connection."
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +208,7 @@ server.setTimeout(30 * 1000)
|
||||
* Normalize a port into a number, string, or false.
|
||||
*/
|
||||
|
||||
function normalizePort(val: string) {
|
||||
function normalizePort(val) {
|
||||
const port = parseInt(val, 10)
|
||||
|
||||
if (isNaN(port)) {
|
||||
@@ -269,7 +227,7 @@ function normalizePort(val: string) {
|
||||
/**
|
||||
* Event listener for HTTP server "error" event.
|
||||
*/
|
||||
function onError(error: any) {
|
||||
function onError(error) {
|
||||
if (error.syscall !== "listen") throw error
|
||||
|
||||
const bind = typeof port === "string" ? `Pipe ${port}` : `Port ${port}`
|
||||
@@ -7,7 +7,9 @@
|
||||
freemium rate limits apply.
|
||||
*/
|
||||
|
||||
import * as express from "express"
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
// Set max requests per minute
|
||||
@@ -19,25 +21,12 @@ const maxRequests = process.env.RATE_LIMIT_MAX_REQUESTS
|
||||
const PRO_RPM = 10 * maxRequests
|
||||
|
||||
// Unique route mapped to its rate limit
|
||||
const uniqueRateLimits: any = {}
|
||||
const uniqueRateLimits = {}
|
||||
|
||||
// Add the 'locals' property to the express.Request interface.
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
locals: any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const routeRateLimit = function(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
const routeRateLimit = function(req, res, next) {
|
||||
// Create a res.locals object if not passed in.
|
||||
if(!req.locals) req.locals = {}
|
||||
|
||||
if (!req.locals) req.locals = {}
|
||||
|
||||
// Disable rate limiting if 0 passed from RATE_LIMIT_MAX_REQUESTS
|
||||
if (maxRequests === 0) return next()
|
||||
|
||||
@@ -66,10 +55,7 @@ const routeRateLimit = function(
|
||||
windowMs: 60 * 1000, // 1 minute window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: PRO_RPM, // start blocking after this many requests per minute
|
||||
handler: function(
|
||||
req: express.Request,
|
||||
res: express.Response /*next*/
|
||||
) {
|
||||
handler: function(req, res) {
|
||||
//console.log(`pro-tier rate-handler triggered.`)
|
||||
|
||||
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
||||
@@ -91,10 +77,7 @@ const routeRateLimit = function(
|
||||
windowMs: 60 * 1000, // 1 minute window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: maxRequests, // start blocking after maxRequests
|
||||
handler: function(
|
||||
req: express.Request,
|
||||
res: express.Response /*next*/
|
||||
) {
|
||||
handler: function(req, res) {
|
||||
//console.log(`freemium rate-handler triggered.`)
|
||||
|
||||
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
||||
@@ -110,4 +93,4 @@ const routeRateLimit = function(
|
||||
uniqueRateLimits[route](req, res, next)
|
||||
}
|
||||
|
||||
export { routeRateLimit }
|
||||
module.exports = { routeRateLimit }
|
||||
@@ -1,318 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default
|
||||
const BITBOX = new BITBOXCli()
|
||||
|
||||
const util = require("util")
|
||||
util.inspect.defaultOptions = { depth: 1 }
|
||||
|
||||
const config = {
|
||||
addressRateLimit1: undefined,
|
||||
addressRateLimit2: undefined,
|
||||
addressRateLimit3: undefined,
|
||||
addressRateLimit4: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 6) {
|
||||
config[`addressRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
router.get("/", config.addressRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "address" })
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/details/:address",
|
||||
config.addressRateLimit2,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
let addresses = JSON.parse(req.params.address)
|
||||
|
||||
// Enforce no more than 20 addresses.
|
||||
if (addresses.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 addresses"
|
||||
})
|
||||
}
|
||||
|
||||
const result = []
|
||||
addresses = addresses.map(address => {
|
||||
const path = `${
|
||||
process.env.BITCOINCOM_BASEURL
|
||||
}addr/${BITBOX.Address.toLegacyAddress(address)}`
|
||||
return axios.get(path) // Returns a promise.
|
||||
})
|
||||
|
||||
axios.all(addresses).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data
|
||||
parsed.legacyAddress = BITBOX.Address.toLegacyAddress(
|
||||
parsed.addrStr
|
||||
)
|
||||
parsed.cashAddress = BITBOX.Address.toCashAddress(parsed.addrStr)
|
||||
delete parsed.addrStr
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
let path = `${
|
||||
process.env.BITCOINCOM_BASEURL
|
||||
}addr/${BITBOX.Address.toLegacyAddress(req.params.address)}`
|
||||
if (req.query.from && req.query.to)
|
||||
path = `${path}?from=${req.query.from}&to=${req.query.to}`
|
||||
|
||||
axios
|
||||
.get(path)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
delete parsed.addrStr
|
||||
parsed.legacyAddress = BITBOX.Address.toLegacyAddress(
|
||||
req.params.address
|
||||
)
|
||||
parsed.cashAddress = BITBOX.Address.toCashAddress(req.params.address)
|
||||
res.json(parsed)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/utxo/:address",
|
||||
config.addressRateLimit3,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
let addresses = JSON.parse(req.params.address)
|
||||
if (addresses.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 addresses"
|
||||
})
|
||||
}
|
||||
|
||||
addresses = addresses.map(address =>
|
||||
BITBOX.Address.toLegacyAddress(address)
|
||||
)
|
||||
const final = []
|
||||
addresses.forEach(address => {
|
||||
final.push([])
|
||||
})
|
||||
axios
|
||||
.get(`${process.env.BITCOINCOM_BASEURL}addrs/${addresses}/utxo`)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
parsed.forEach(data => {
|
||||
data.legacyAddress = BITBOX.Address.toLegacyAddress(data.address)
|
||||
data.cashAddress = BITBOX.Address.toCashAddress(data.address)
|
||||
delete data.address
|
||||
addresses.forEach((address, index) => {
|
||||
if (addresses[index] === data.legacyAddress)
|
||||
final[index].push(data)
|
||||
})
|
||||
})
|
||||
res.json(final)
|
||||
})
|
||||
.catch(error => {
|
||||
//res.send(error.response.data.error.message)
|
||||
// console.log(`Error: `, error)
|
||||
})
|
||||
} catch (error) {
|
||||
axios
|
||||
.get(
|
||||
`${
|
||||
process.env.BITCOINCOM_BASEURL
|
||||
}addr/${BITBOX.Address.toLegacyAddress(req.params.address)}/utxo`
|
||||
)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
parsed.forEach(data => {
|
||||
delete data.address
|
||||
data.legacyAddress = BITBOX.Address.toLegacyAddress(
|
||||
req.params.address
|
||||
)
|
||||
data.cashAddress = BITBOX.Address.toCashAddress(req.params.address)
|
||||
})
|
||||
res.json(parsed)
|
||||
})
|
||||
.catch(error => {
|
||||
//res.send(error.response.data.error.message)
|
||||
// console.log(`Error: `, error)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/unconfirmed/:address",
|
||||
config.addressRateLimit4,
|
||||
(req, res, next) => {
|
||||
try {
|
||||
let addresses = JSON.parse(req.params.address)
|
||||
if (addresses.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 addresses"
|
||||
})
|
||||
}
|
||||
addresses = addresses.map(address =>
|
||||
BITBOX.Address.toLegacyAddress(address)
|
||||
)
|
||||
const final = []
|
||||
addresses.forEach(address => {
|
||||
final.push([])
|
||||
})
|
||||
axios
|
||||
.get(`${process.env.BITCOINCOM_BASEURL}addrs/${addresses}/utxo`)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
parsed.forEach(data => {
|
||||
data.legacyAddress = BITBOX.Address.toLegacyAddress(data.address)
|
||||
data.cashAddress = BITBOX.Address.toCashAddress(data.address)
|
||||
delete data.address
|
||||
if (data.confirmations === 0) {
|
||||
addresses.forEach((address, index) => {
|
||||
if (addresses[index] === data.legacyAddress)
|
||||
final[index].push(data)
|
||||
})
|
||||
}
|
||||
})
|
||||
res.json(final)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
} catch (error) {
|
||||
axios
|
||||
.get(
|
||||
`${
|
||||
process.env.BITCOINCOM_BASEURL
|
||||
}addr/${BITBOX.Address.toLegacyAddress(req.params.address)}/utxo`
|
||||
)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
const unconfirmed = []
|
||||
parsed.forEach(data => {
|
||||
data.legacyAddress = BITBOX.Address.toLegacyAddress(data.address)
|
||||
data.cashAddress = BITBOX.Address.toCashAddress(data.address)
|
||||
delete data.address
|
||||
if (data.confirmations === 0) unconfirmed.push(data)
|
||||
})
|
||||
res.json(unconfirmed)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/unconfirmed/:address",
|
||||
config.addressRateLimit4,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
let addresses = JSON.parse(req.params.address)
|
||||
if (addresses.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 addresses"
|
||||
})
|
||||
}
|
||||
addresses = addresses.map(address =>
|
||||
BITBOX.Address.toLegacyAddress(address)
|
||||
)
|
||||
const final = []
|
||||
addresses.forEach(address => {
|
||||
final.push([])
|
||||
})
|
||||
axios
|
||||
.get(`${process.env.BITCOINCOM_BASEURL}txs/?address=${addresses}`)
|
||||
.then(response => {
|
||||
res.json(response.data)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
} catch (error) {
|
||||
axios
|
||||
.get(
|
||||
`${
|
||||
process.env.BITCOINCOM_BASEURL
|
||||
}txs/?address=${BITBOX.Address.toLegacyAddress(req.params.address)}`
|
||||
)
|
||||
.then(response => {
|
||||
res.json(response.data)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/transactions/:address",
|
||||
config.addressRateLimit5,
|
||||
(req, res, next) => {
|
||||
try {
|
||||
let addresses = JSON.parse(req.params.address)
|
||||
if (addresses.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 addresses"
|
||||
})
|
||||
}
|
||||
addresses = addresses.map(address =>
|
||||
BITBOX.Address.toLegacyAddress(address)
|
||||
)
|
||||
const final = []
|
||||
addresses.forEach(address => {
|
||||
final.push([])
|
||||
})
|
||||
axios
|
||||
.get(`${process.env.BITCOINCOM_BASEURL}txs/?address=${addresses}`)
|
||||
.then(response => {
|
||||
res.json(response.data)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
} catch (error) {
|
||||
axios
|
||||
.get(
|
||||
`${
|
||||
process.env.BITCOINCOM_BASEURL
|
||||
}txs/?address=${BITBOX.Address.toLegacyAddress(req.params.address)}`
|
||||
)
|
||||
.then(response => {
|
||||
res.json(response.data)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,90 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const config = {
|
||||
blockRateLimit1: undefined,
|
||||
blockRateLimit2: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 3) {
|
||||
config[`blockRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
router.get("/", config.blockRateLimit1, (req, res, next) => {
|
||||
res.json({ status: "block" })
|
||||
})
|
||||
|
||||
router.get("/details/:id", config.blockRateLimit2, (req, res, next) => {
|
||||
if (req.params.id.length !== 64) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getblockhash",
|
||||
method: "getblockhash",
|
||||
params: [parseInt(req.params.id)]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
axios
|
||||
.get(`${process.env.BITCOINCOM_BASEURL}block/${response.data.result}`)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
res.json(parsed)
|
||||
})
|
||||
.catch(error => {
|
||||
//res.send(error.response.data.error.message)
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
//res.send(error.response.data.error.message)
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
})
|
||||
} else {
|
||||
axios
|
||||
.get(`${process.env.BITCOINCOM_BASEURL}block/${req.params.id}`)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
res.json(parsed)
|
||||
})
|
||||
.catch(error => {
|
||||
//res.send(error.response.data.error.message)
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@@ -1,721 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const config = {
|
||||
blockchainRateLimit1: undefined,
|
||||
blockchainRateLimit2: undefined,
|
||||
blockchainRateLimit3: undefined,
|
||||
blockchainRateLimit4: undefined,
|
||||
blockchainRateLimit5: undefined,
|
||||
blockchainRateLimit6: undefined,
|
||||
blockchainRateLimit7: undefined,
|
||||
blockchainRateLimit8: undefined,
|
||||
blockchainRateLimit9: undefined,
|
||||
blockchainRateLimit10: undefined,
|
||||
blockchainRateLimit11: undefined,
|
||||
blockchainRateLimit12: undefined,
|
||||
blockchainRateLimit13: undefined,
|
||||
blockchainRateLimit14: undefined,
|
||||
blockchainRateLimit15: undefined,
|
||||
blockchainRateLimit16: undefined,
|
||||
blockchainRateLimit17: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 18) {
|
||||
config[`blockchainRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", config.blockchainRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "blockchain" })
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/getBestBlockHash",
|
||||
config.blockchainRateLimit2,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getbestblockhash"
|
||||
requestConfig.data.method = "getbestblockhash"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getBlock/:hash",
|
||||
config.blockchainRateLimit3,
|
||||
async (req, res, next) => {
|
||||
let verbose = false
|
||||
if (req.query.verbose && req.query.verbose === "true") verbose = true
|
||||
|
||||
let showTxs = true
|
||||
if (req.query.txs && req.query.txs === "false") showTxs = false
|
||||
|
||||
requestConfig.data.id = "getblock"
|
||||
requestConfig.data.method = "getblock"
|
||||
requestConfig.data.params = [req.params.hash, verbose]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
if (!showTxs) delete response.data.result.tx
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getBlockchainInfo",
|
||||
config.blockchainRateLimit4,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getblockchaininfo"
|
||||
requestConfig.data.method = "getblockchaininfo"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getBlockCount",
|
||||
config.blockchainRateLimit5,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getblockcount"
|
||||
requestConfig.data.method = "getblockcount"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getBlockHash/:height",
|
||||
config.blockchainRateLimit6,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
let heights = JSON.parse(req.params.height)
|
||||
if (heights.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 heights"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
heights = heights.map(height =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getblockhash",
|
||||
method: "getblockhash",
|
||||
params: [height]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(heights).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getblockhash",
|
||||
method: "getblockhash",
|
||||
params: [parseInt(req.params.height)]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getBlockHeader/:hash",
|
||||
config.blockchainRateLimit7,
|
||||
async (req, res, next) => {
|
||||
let verbose = false
|
||||
if (req.query.verbose && req.query.verbose === "true") verbose = true
|
||||
|
||||
try {
|
||||
let hashes = JSON.parse(req.params.hash)
|
||||
if (hashes.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 hashes"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
hashes = hashes.map(hash =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getblockheader",
|
||||
method: "getblockheader",
|
||||
params: [hash, verbose]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(hashes).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getblockheader",
|
||||
method: "getblockheader",
|
||||
params: [req.params.hash, verbose]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getChainTips",
|
||||
config.blockchainRateLimit8,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getchaintips"
|
||||
requestConfig.data.method = "getchaintips"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getDifficulty",
|
||||
config.blockchainRateLimit9,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getdifficulty"
|
||||
requestConfig.data.method = "getdifficulty"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getMempoolAncestors/:txid",
|
||||
config.blockchainRateLimit10,
|
||||
async (req, res, next) => {
|
||||
let verbose = false
|
||||
if (req.query.verbose && req.query.verbose === "true") verbose = true
|
||||
|
||||
try {
|
||||
let txids = JSON.parse(req.params.txid)
|
||||
if (txids.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 txids"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
txids = txids.map(txid =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getmempoolancestors",
|
||||
method: "getmempoolancestors",
|
||||
params: [txid, verbose]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(txids).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getmempoolancestors",
|
||||
method: "getmempoolancestors",
|
||||
params: [req.params.txid, verbose]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getMempoolDescendants/:txid",
|
||||
config.blockchainRateLimit11,
|
||||
async (req, res, next) => {
|
||||
let verbose = false
|
||||
if (req.query.verbose && req.query.verbose === "true") verbose = true
|
||||
|
||||
try {
|
||||
let txids = JSON.parse(req.params.txid)
|
||||
if (txids.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 txids"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
txids = txids.map(txid =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getmempooldescendants",
|
||||
method: "getmempooldescendants",
|
||||
params: [txid, verbose]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(txids).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getmempooldescendants",
|
||||
method: "getmempooldescendants",
|
||||
params: [req.params.txid, verbose]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getMempoolEntry/:txid",
|
||||
config.blockchainRateLimit12,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
let txids = JSON.parse(req.params.txid)
|
||||
if (txids.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 txids"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
txids = txids.map(txid =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getmempoolentry",
|
||||
method: "getmempoolentry",
|
||||
params: [txid]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(txids).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getmempoolentry",
|
||||
method: "getmempoolentry",
|
||||
params: [req.params.txid]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getMempoolInfo",
|
||||
config.blockchainRateLimit13,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getmempoolinfo"
|
||||
requestConfig.data.method = "getmempoolinfo"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getRawMempool",
|
||||
config.blockchainRateLimit14,
|
||||
async (req, res, next) => {
|
||||
let verbose = false
|
||||
if (req.query.verbose && req.query.verbose === true) verbose = true
|
||||
|
||||
requestConfig.data.id = "getrawmempool"
|
||||
requestConfig.data.method = "getrawmempool"
|
||||
requestConfig.data.params = [verbose]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getTxOut/:txid/:n",
|
||||
config.blockchainRateLimit15,
|
||||
async (req, res, next) => {
|
||||
let include_mempool = false
|
||||
if (req.query.include_mempool && req.query.include_mempool === "true")
|
||||
include_mempool = true
|
||||
|
||||
requestConfig.data.id = "gettxout"
|
||||
requestConfig.data.method = "gettxout"
|
||||
requestConfig.data.params = [
|
||||
req.params.txid,
|
||||
parseInt(req.params.n),
|
||||
include_mempool
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getTxOutProof/:txids",
|
||||
config.blockchainRateLimit16,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "gettxoutproof"
|
||||
requestConfig.data.method = "gettxoutproof"
|
||||
requestConfig.data.params = [req.params.txids]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
//
|
||||
// router.get('/preciousBlock/:hash', async (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"preciousblock",
|
||||
// method: "preciousblock",
|
||||
// params: [
|
||||
// req.params.hash
|
||||
// ]
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(JSON.stringify(response.data.result));
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.post('/pruneBlockchain/:height', async (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"pruneblockchain",
|
||||
// method: "pruneblockchain",
|
||||
// params: [
|
||||
// req.params.height
|
||||
// ]
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/verifyChain', async (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"verifychain",
|
||||
// method: "verifychain"
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
|
||||
router.get(
|
||||
"/verifyTxOutProof/:proof",
|
||||
config.blockchainRateLimit17,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "verifytxoutproof"
|
||||
requestConfig.data.method = "verifytxoutproof"
|
||||
requestConfig.data.params = [req.params.proof]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,106 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
//const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default;
|
||||
//const BITBOX = new BITBOXCli();
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const config = {
|
||||
controlRateLimit1: undefined,
|
||||
controlRateLimit2: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 3) {
|
||||
config[`controlRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", config.controlRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "control" })
|
||||
})
|
||||
|
||||
router.get("/getInfo", config.controlRateLimit2, async (req, res, next) => {
|
||||
requestConfig.data.id = "getinfo"
|
||||
requestConfig.data.method = "getinfo"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
})
|
||||
|
||||
// router.get('/getMemoryInfo', (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"getmemoryinfo",
|
||||
// method: "getmemoryinfo"
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/help', (req, res, next) => {
|
||||
// BITBOX.Control.help()
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.post('/stop', (req, res, next) => {
|
||||
// BITBOX.Control.stop()
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
|
||||
module.exports = router
|
||||
@@ -1,529 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default
|
||||
const BITBOX = new BITBOXCli()
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const config = {
|
||||
dataRetrievalRateLimit1: undefined,
|
||||
dataRetrievalRateLimit2: undefined,
|
||||
dataRetrievalRateLimit3: undefined,
|
||||
dataRetrievalRateLimit4: undefined,
|
||||
dataRetrievalRateLimit5: undefined,
|
||||
dataRetrievalRateLimit6: undefined,
|
||||
dataRetrievalRateLimit7: undefined,
|
||||
dataRetrievalRateLimit8: undefined,
|
||||
dataRetrievalRateLimit9: undefined,
|
||||
dataRetrievalRateLimit10: undefined,
|
||||
dataRetrievalRateLimit11: undefined,
|
||||
dataRetrievalRateLimit12: undefined,
|
||||
dataRetrievalRateLimit13: undefined,
|
||||
dataRetrievalRateLimit14: undefined,
|
||||
dataRetrievalRateLimit15: undefined,
|
||||
dataRetrievalRateLimit16: undefined,
|
||||
dataRetrievalRateLimit17: undefined,
|
||||
dataRetrievalRateLimit18: undefined,
|
||||
dataRetrievalRateLimit19: undefined,
|
||||
dataRetrievalRateLimit20: undefined,
|
||||
dataRetrievalRateLimit21: undefined,
|
||||
dataRetrievalRateLimit22: undefined,
|
||||
dataRetrievalRateLimit23: undefined,
|
||||
dataRetrievalRateLimit24: undefined,
|
||||
dataRetrievalRateLimit25: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 26) {
|
||||
config[`dataRetrievalRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", config.dataRetrievalRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "dataRetrieval" })
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/balancesForAddress/:address",
|
||||
config.dataRetrievalRateLimit2,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getallbalancesforaddress"
|
||||
requestConfig.data.method = "whc_getallbalancesforaddress"
|
||||
requestConfig.data.params = [req.params.address]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
// Check for no balance error
|
||||
if (
|
||||
error &&
|
||||
error.response &&
|
||||
error.response.data &&
|
||||
error.response.data.error &&
|
||||
error.response.data.error.code === -8 &&
|
||||
error.response.data.error.message === "Address not found"
|
||||
)
|
||||
res.json([])
|
||||
else res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/balancesForId/:propertyId",
|
||||
config.dataRetrievalRateLimit2,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getallbalancesforid"
|
||||
requestConfig.data.method = "whc_getallbalancesforid"
|
||||
requestConfig.data.params = [parseInt(req.params.propertyId)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
//res.status(500).send(error.response.data.error)
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/balance/:address/:propertyId",
|
||||
config.dataRetrievalRateLimit3,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getbalance"
|
||||
requestConfig.data.method = "whc_getbalance"
|
||||
requestConfig.data.params = [
|
||||
req.params.address,
|
||||
parseInt(req.params.propertyId)
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/balancesHash/:propertyId",
|
||||
config.dataRetrievalRateLimit4,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getbalanceshash"
|
||||
requestConfig.data.method = "whc_getbalanceshash"
|
||||
requestConfig.data.params = [parseInt(req.params.propertyId)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/crowdSale/:propertyId",
|
||||
config.dataRetrievalRateLimit5,
|
||||
async (req, res, next) => {
|
||||
let verbose = false
|
||||
if (req.query.verbose && req.query.verbose === "true") verbose = true
|
||||
|
||||
requestConfig.data.id = "whc_getcrowdsale"
|
||||
requestConfig.data.method = "whc_getcrowdsale"
|
||||
requestConfig.data.params = [parseInt(req.params.propertyId), verbose]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
//res.status(500).send(error.response.data.error);
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/currentConsensusHash",
|
||||
config.dataRetrievalRateLimit6,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getcurrentconsensushash"
|
||||
requestConfig.data.method = "whc_getcurrentconsensushash"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/grants/:propertyId",
|
||||
config.dataRetrievalRateLimit8,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getgrants"
|
||||
requestConfig.data.method = "whc_getgrants"
|
||||
requestConfig.data.params = [parseInt(req.params.propertyId)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
//res.status(500).send(error.response.data.error);
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get("/info", config.dataRetrievalRateLimit9, async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getinfo"
|
||||
requestConfig.data.method = "whc_getinfo"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/payload/:txid",
|
||||
config.dataRetrievalRateLimit10,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getpayload"
|
||||
requestConfig.data.method = "whc_getpayload"
|
||||
requestConfig.data.params = [req.params.txid]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/property/:propertyId",
|
||||
config.dataRetrievalRateLimit11,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getproperty"
|
||||
requestConfig.data.method = "whc_getproperty"
|
||||
requestConfig.data.params = [parseInt(req.params.propertyId)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/seedBlocks/:startBlock/:endBlock",
|
||||
config.dataRetrievalRateLimit12,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getseedblocks"
|
||||
requestConfig.data.method = "whc_getseedblocks"
|
||||
requestConfig.data.params = [
|
||||
parseInt(req.params.startBlock),
|
||||
parseInt(req.params.endBlock)
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/STO/:txid/:recipientFilter",
|
||||
config.dataRetrievalRateLimit13,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_getsto"
|
||||
requestConfig.data.method = "whc_getsto"
|
||||
requestConfig.data.params = [req.params.txid, req.params.recipientFilter]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/transaction/:txid",
|
||||
config.dataRetrievalRateLimit14,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_gettransaction"
|
||||
requestConfig.data.method = "whc_gettransaction"
|
||||
requestConfig.data.params = [req.params.txid]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
//res.status(500).send(error.response.data.error);
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/blockTransactions/:index",
|
||||
config.dataRetrievalRateLimit15,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_listblocktransactions"
|
||||
requestConfig.data.method = "whc_listblocktransactions"
|
||||
requestConfig.data.params = [parseInt(req.params.index)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/pendingTransactions",
|
||||
config.dataRetrievalRateLimit16,
|
||||
async (req, res, next) => {
|
||||
const params = []
|
||||
if (req.query.address) params.push(req.query.address)
|
||||
|
||||
requestConfig.data.id = "whc_listpendingtransactions"
|
||||
requestConfig.data.method = "whc_listpendingtransactions"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
//res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/properties",
|
||||
config.dataRetrievalRateLimit17,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_listproperties"
|
||||
requestConfig.data.method = "whc_listproperties"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/frozenBalance/:address/:propertyId",
|
||||
config.dataRetrievalRateLimit18,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
BITBOX.Address.toCashAddress(req.params.address),
|
||||
parseInt(req.params.propertyId)
|
||||
]
|
||||
requestConfig.data.id = "whc_getfrozenbalance"
|
||||
requestConfig.data.method = "whc_getfrozenbalance"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/frozenBalanceForAddress/:address",
|
||||
config.dataRetrievalRateLimit19,
|
||||
async (req, res, next) => {
|
||||
const params = [BITBOX.Address.toCashAddress(req.params.address)]
|
||||
requestConfig.data.id = "whc_getfrozenbalanceforaddress"
|
||||
requestConfig.data.method = "whc_getfrozenbalanceforaddress"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/frozenBalanceForId/:propertyId",
|
||||
config.dataRetrievalRateLimit20,
|
||||
async (req, res, next) => {
|
||||
const params = [parseInt(req.params.propertyId)]
|
||||
requestConfig.data.id = "whc_getfrozenbalanceforid"
|
||||
requestConfig.data.method = "whc_getfrozenbalanceforid"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/ERC721AddressTokens/:address/:propertyId",
|
||||
config.dataRetrievalRateLimit21,
|
||||
async (req, res, next) => {
|
||||
const params = [req.params.address, req.params.propertyId]
|
||||
requestConfig.data.id = "whc_getERC721AddressTokens"
|
||||
requestConfig.data.method = "whc_getERC721AddressTokens"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/ERC721PropertyDestroyTokens/:propertyId",
|
||||
config.dataRetrievalRateLimit22,
|
||||
async (req, res, next) => {
|
||||
const params = [req.params.propertyId]
|
||||
requestConfig.data.id = "whc_getERC721PropertyDestroyTokens"
|
||||
requestConfig.data.method = "whc_getERC721PropertyDestroyTokens"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/ERC721PropertyNews/:propertyId",
|
||||
config.dataRetrievalRateLimit23,
|
||||
async (req, res, next) => {
|
||||
const params = [req.params.propertyId]
|
||||
requestConfig.data.id = "whc_getERC721PropertyNews"
|
||||
requestConfig.data.method = "whc_getERC721PropertyNews"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/ERC721TokenNews/:propertyId/:tokenId",
|
||||
config.dataRetrievalRateLimit24,
|
||||
async (req, res, next) => {
|
||||
const params = [req.params.propertyId, req.params.tokenId]
|
||||
requestConfig.data.id = "whc_getERC721TokenNews"
|
||||
requestConfig.data.method = "whc_getERC721TokenNews"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/ownerOfERC721Token/:propertyId/:tokenId/:address",
|
||||
config.dataRetrievalRateLimit25,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
req.params.propertyId,
|
||||
req.params.tokenId,
|
||||
req.params.address
|
||||
]
|
||||
requestConfig.data.id = "whc_ownerOfERC721Token"
|
||||
requestConfig.data.method = "whc_ownerOfERC721Token"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,75 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
//const axios = require("axios");
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
//const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default;
|
||||
//const BITBOX = new BITBOXCli();
|
||||
|
||||
//const BitboxHTTP = axios.create({
|
||||
// baseURL: process.env.RPC_BASEURL,
|
||||
//});
|
||||
//const username = process.env.RPC_USERNAME;
|
||||
//const password = process.env.RPC_PASSWORD;
|
||||
|
||||
const config = {
|
||||
generatingRateLimit1: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 2) {
|
||||
config[`generatingRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
router.get("/", config.generatingRateLimit1, (req, res, next) => {
|
||||
res.json({ status: "generating" })
|
||||
})
|
||||
//
|
||||
// router.post('/generateToAddress/:nblocks/:address', (req, res, next) => {
|
||||
// let maxtries = 1000000;
|
||||
// if(req.query.maxtries) {
|
||||
// maxtries = parseInt(req.query.maxtries);
|
||||
// }
|
||||
//
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"generatetoaddress",
|
||||
// method: "generatetoaddress",
|
||||
// params: [
|
||||
// req.params.nblocks,
|
||||
// req.params.address,
|
||||
// maxtries
|
||||
// ]
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
|
||||
module.exports = router
|
||||
@@ -1,27 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const healthCheckRateLimit = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/* GET home page. */
|
||||
router.get("/", healthCheckRateLimit, (req, res, next) => {
|
||||
res.json({ status: "winning" })
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@@ -1,35 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const config = {
|
||||
indexRateLimit1: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 2) {
|
||||
config[`indexRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
/* GET home page. */
|
||||
router.get("/v1", config.indexRateLimit1, (req, res, next) => {
|
||||
res.render("swagger")
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@@ -1,145 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
//const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default;
|
||||
//const BITBOX = new BITBOXCli();
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const config = {
|
||||
miningRateLimit1: undefined,
|
||||
miningRateLimit2: undefined,
|
||||
miningRateLimit3: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 4) {
|
||||
config[`miningRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", config.miningRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "mining" })
|
||||
})
|
||||
//
|
||||
// router.get('/getBlockTemplate/:templateRequest', (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"getblocktemplate",
|
||||
// method: "getblocktemplate",
|
||||
// params: [
|
||||
// req.params.templateRequest
|
||||
// ]
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
|
||||
router.get(
|
||||
"/getMiningInfo",
|
||||
config.miningRateLimit2,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getmininginfo"
|
||||
requestConfig.data.method = "getmininginfo"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getNetworkHashps",
|
||||
config.miningRateLimit3,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "getnetworkhashps"
|
||||
requestConfig.data.method = "getnetworkhashps"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
//
|
||||
// router.post('/submitBlock/:hex', (req, res, next) => {
|
||||
// let parameters = '';
|
||||
// if(req.query.parameters && req.query.parameters !== '') {
|
||||
// parameters = true;
|
||||
// }
|
||||
//
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"submitblock",
|
||||
// method: "submitblock",
|
||||
// params: [
|
||||
// req.params.hex,
|
||||
// parameters
|
||||
// ]
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
|
||||
module.exports = router
|
||||
@@ -1,202 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
//const axios = require("axios");
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
//const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default;
|
||||
//const BITBOX = new BITBOXCli();
|
||||
|
||||
//const BitboxHTTP = axios.create({
|
||||
// baseURL: process.env.RPC_BASEURL,
|
||||
//});
|
||||
//const username = process.env.RPC_USERNAME;
|
||||
//const password = process.env.RPC_PASSWORD;
|
||||
|
||||
const config = {
|
||||
networkRateLimit1: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 2) {
|
||||
config[`networkRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
router.get("/", config.networkRateLimit1, (req, res, next) => {
|
||||
res.json({ status: "network" })
|
||||
})
|
||||
|
||||
// router.post('/addNode/:node/:command', (req, res, next) => {
|
||||
// BITBOX.Network.addNode(req.params.node, req.params.command)
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.post('/clearBanned', (req, res, next) => {
|
||||
// BITBOX.Network.clearBanned()
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.post('/disconnectNode/:address/:nodeid', (req, res, next) => {
|
||||
// BITBOX.Network.disconnectNode(req.params.address, req.params.nodeid)
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/getAddedNodeInfo/:node', (req, res, next) => {
|
||||
// BITBOX.Network.getAddedNodeInfo(req.params.node)
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/getConnectionCount', (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"getconnectioncount",
|
||||
// method: "getconnectioncount"
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/getNetTotals', (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"getnettotals",
|
||||
// method: "getnettotals"
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/getNetworkInfo', (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"getnetworkinfo",
|
||||
// method: "getnetworkinfo"
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/getPeerInfo', (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"getpeerinfo",
|
||||
// method: "getpeerinfo"
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(response.data.result);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.get('/ping', (req, res, next) => {
|
||||
// BitboxHTTP({
|
||||
// method: 'post',
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// id:"ping",
|
||||
// method: "ping"
|
||||
// }
|
||||
// })
|
||||
// .then((response) => {
|
||||
// res.json(JSON.stringify(response.data.result));
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// res.send(error.response.data.error.message);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.post('/setBan/:subnet/:command', (req, res, next) => {
|
||||
// // TODO finish this
|
||||
// BITBOX.Network.getConnectionCount(req.params.subnet, req.params.command)
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// router.post('/setNetworkActive/:state', (req, res, next) => {
|
||||
// let state = true;
|
||||
// if(req.params.state && req.params.state === 'false') {
|
||||
// state = false;
|
||||
// }
|
||||
// BITBOX.Network.getConnectionCount(state)
|
||||
// .then((result) => {
|
||||
// res.json(result);
|
||||
// }, (err) => { console.log(err);
|
||||
// });
|
||||
// });
|
||||
|
||||
module.exports = router
|
||||
@@ -1,480 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default
|
||||
const BITBOX = new BITBOXCli()
|
||||
|
||||
const config = {
|
||||
payloadCreationRateLimit1: undefined,
|
||||
payloadCreationRateLimit2: undefined,
|
||||
payloadCreationRateLimit3: undefined,
|
||||
payloadCreationRateLimit4: undefined,
|
||||
payloadCreationRateLimit5: undefined,
|
||||
payloadCreationRateLimit6: undefined,
|
||||
payloadCreationRateLimit7: undefined,
|
||||
payloadCreationRateLimit8: undefined,
|
||||
payloadCreationRateLimit9: undefined,
|
||||
payloadCreationRateLimit10: undefined,
|
||||
payloadCreationRateLimit11: undefined,
|
||||
payloadCreationRateLimit12: undefined,
|
||||
payloadCreationRateLimit13: undefined,
|
||||
payloadCreationRateLimit14: undefined,
|
||||
payloadCreationRateLimit15: undefined,
|
||||
payloadCreationRateLimit16: undefined,
|
||||
payloadCreationRateLimit17: undefined,
|
||||
payloadCreationRateLimit18: undefined,
|
||||
payloadCreationRateLimit19: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 20) {
|
||||
config[`payloadCreationRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", config.payloadCreationRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "payloadCreation" })
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/burnBCH",
|
||||
config.payloadCreationRateLimit2,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_burnbch"
|
||||
requestConfig.data.method = "whc_createpayload_burnbch"
|
||||
requestConfig.data.params = []
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/changeIssuer/:propertyId",
|
||||
config.payloadCreationRateLimit2,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_changeissuer"
|
||||
requestConfig.data.method = "whc_createpayload_changeissuer"
|
||||
requestConfig.data.params = [parseInt(req.params.propertyId)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/closeCrowdSale/:propertyId",
|
||||
config.payloadCreationRateLimit3,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_closecrowdsale"
|
||||
requestConfig.data.method = "whc_createpayload_closecrowdsale"
|
||||
requestConfig.data.params = [parseInt(req.params.propertyId)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/grant/:propertyId/:amount",
|
||||
config.payloadCreationRateLimit4,
|
||||
async (req, res, next) => {
|
||||
const params = [parseInt(req.params.propertyId), req.params.amount]
|
||||
if (req.query.memo) params.push(req.query.memo)
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_grant"
|
||||
requestConfig.data.method = "whc_createpayload_grant"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
//res.status(500).send(error.response.data.error);
|
||||
res.status(500)
|
||||
return res.send(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/crowdsale/:ecosystem/:propertyPrecision/:previousId/:category/:subcategory/:name/:url/:data/:propertyIdDesired/:tokensPerUnit/:deadline/:earlyBonus/:undefine/:totalNumber",
|
||||
config.payloadCreationRateLimit6,
|
||||
async (req, res, next) => {
|
||||
// Validate deadline
|
||||
const now = new Date()
|
||||
const OneHundredYears = 1000 * 60 * 60 * 24 * 365 * 100
|
||||
const OneHundredYearsFromNow = now.getTime() + OneHundredYears
|
||||
const OneHundredYearsFromNowUnixTimestamp = Math.floor(
|
||||
OneHundredYearsFromNow / 1000
|
||||
)
|
||||
if (req.params.deadline > OneHundredYearsFromNowUnixTimestamp) {
|
||||
res.status(422)
|
||||
res.send(
|
||||
"Invalid deadline. Unix timestamp should be less than 100 years from now. Unix timestamp === JavaScript getTime()/1000"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_issuancecrowdsale"
|
||||
requestConfig.data.method = "whc_createpayload_issuancecrowdsale"
|
||||
requestConfig.data.params = [
|
||||
parseInt(req.params.ecosystem),
|
||||
parseInt(req.params.propertyPrecision),
|
||||
parseInt(req.params.previousId),
|
||||
req.params.category,
|
||||
req.params.subcategory,
|
||||
req.params.name,
|
||||
req.params.url,
|
||||
req.params.data,
|
||||
parseInt(req.params.propertyIdDesired),
|
||||
req.params.tokensPerUnit,
|
||||
parseInt(req.params.deadline),
|
||||
parseInt(req.params.earlyBonus),
|
||||
parseInt(req.params.undefine),
|
||||
req.params.totalNumber
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/fixed/:ecosystem/:propertyPrecision/:previousId/:category/:subcategory/:name/:url/:data/:amount",
|
||||
config.payloadCreationRateLimit7,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_issuancefixed"
|
||||
requestConfig.data.method = "whc_createpayload_issuancefixed"
|
||||
requestConfig.data.params = [
|
||||
parseInt(req.params.ecosystem),
|
||||
parseInt(req.params.propertyPrecision),
|
||||
parseInt(req.params.previousId),
|
||||
req.params.category,
|
||||
req.params.subcategory,
|
||||
req.params.name,
|
||||
req.params.url,
|
||||
req.params.data,
|
||||
req.params.amount
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/managed/:ecosystem/:propertyPrecision/:previousId/:category/:subcategory/:name/:url/:data",
|
||||
config.payloadCreationRateLimit8,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_issuancemanaged"
|
||||
requestConfig.data.method = "whc_createpayload_issuancemanaged"
|
||||
requestConfig.data.params = [
|
||||
parseInt(req.params.ecosystem),
|
||||
parseInt(req.params.propertyPrecision),
|
||||
parseInt(req.params.previousId),
|
||||
req.params.category,
|
||||
req.params.subcategory,
|
||||
req.params.name,
|
||||
req.params.url,
|
||||
req.params.data
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/participateCrowdSale/:amount",
|
||||
config.payloadCreationRateLimit9,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_particrowdsale"
|
||||
requestConfig.data.method = "whc_createpayload_particrowdsale"
|
||||
requestConfig.data.params = [req.params.amount]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/revoke/:propertyId/:amount",
|
||||
config.payloadCreationRateLimit10,
|
||||
async (req, res, next) => {
|
||||
const params = [parseInt(req.params.propertyId), req.params.amount]
|
||||
if (req.query.memo) params.push(req.query.memo)
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_revoke"
|
||||
requestConfig.data.method = "whc_createpayload_revoke"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/sendAll/:ecosystem",
|
||||
config.payloadCreationRateLimit11,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_sendall"
|
||||
requestConfig.data.method = "whc_createpayload_sendall"
|
||||
requestConfig.data.params = [parseInt(req.params.ecosystem)]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/simpleSend/:propertyId/:amount",
|
||||
config.payloadCreationRateLimit12,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createpayload_simplesend"
|
||||
requestConfig.data.method = "whc_createpayload_simplesend"
|
||||
requestConfig.data.params = [
|
||||
parseInt(req.params.propertyId),
|
||||
req.params.amount
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/STO/:propertyId/:amount",
|
||||
config.payloadCreationRateLimit13,
|
||||
async (req, res, next) => {
|
||||
const params = [parseInt(req.params.propertyId), req.params.amount]
|
||||
if (req.query.distributionProperty)
|
||||
params.push(parseInt(req.query.distributionProperty))
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_sto"
|
||||
requestConfig.data.method = "whc_createpayload_sto"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/freeze/:toAddress/:propertyId",
|
||||
config.payloadCreationRateLimit14,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
BITBOX.Address.toCashAddress(req.params.toAddress),
|
||||
parseInt(req.params.propertyId),
|
||||
"100"
|
||||
]
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_freeze"
|
||||
requestConfig.data.method = "whc_createpayload_freeze"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/unfreeze/:toAddress/:propertyId",
|
||||
config.payloadCreationRateLimit15,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
BITBOX.Address.toCashAddress(req.params.toAddress),
|
||||
parseInt(req.params.propertyId),
|
||||
"100"
|
||||
]
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_unfreeze"
|
||||
requestConfig.data.method = "whc_createpayload_unfreeze"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/issueERC721Property/:name/:symbol/:data/:url/:totalNumber",
|
||||
config.payloadCreationRateLimit16,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
req.params.name,
|
||||
req.params.symbol,
|
||||
req.params.data,
|
||||
req.params.url,
|
||||
req.params.totalNumber
|
||||
]
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_issueERC721property"
|
||||
requestConfig.data.method = "whc_createpayload_issueERC721property"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/issueERC721Token/:propertyId/:tokenId/:attributes/:url",
|
||||
config.payloadCreationRateLimit17,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
req.params.propertyId,
|
||||
req.params.tokenId,
|
||||
req.params.attributes,
|
||||
req.params.url
|
||||
]
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_issueERC721token"
|
||||
requestConfig.data.method = "whc_createpayload_issueERC721token"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/transferERC721Token/:owner/:receiver/:propertyId",
|
||||
config.payloadCreationRateLimit18,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
req.params.owner,
|
||||
req.params.receiver,
|
||||
req.params.propertyId
|
||||
]
|
||||
if (req.query.tokenId) params.push(req.query.tokenId)
|
||||
|
||||
requestConfig.data.id = "whc_transferERC721Token"
|
||||
requestConfig.data.method = "whc_transferERC721Token"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/destroyERC721Token/:propertyId",
|
||||
config.payloadCreationRateLimit19,
|
||||
async (req, res, next) => {
|
||||
const params = [req.params.propertyId]
|
||||
if (req.query.tokenId) params.push(req.query.tokenId)
|
||||
|
||||
requestConfig.data.id = "whc_createpayload_destroyERC721token"
|
||||
requestConfig.data.method = "whc_createpayload_destroyERC721token"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,511 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
//const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default;
|
||||
//const BITBOX = new BITBOXCli();
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const config = {
|
||||
rawTransactionsRateLimit1: undefined,
|
||||
rawTransactionsRateLimit2: undefined,
|
||||
rawTransactionsRateLimit3: undefined,
|
||||
rawTransactionsRateLimit4: undefined,
|
||||
rawTransactionsRateLimit5: undefined,
|
||||
rawTransactionsRateLimit6: undefined,
|
||||
rawTransactionsRateLimit7: undefined,
|
||||
rawTransactionsRateLimit8: undefined,
|
||||
rawTransactionsRateLimit9: undefined,
|
||||
rawTransactionsRateLimit10: undefined,
|
||||
rawTransactionsRateLimit11: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
|
||||
while (i < 12) {
|
||||
config[`rawTransactionsRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
//const requestConfig = {
|
||||
// method: "post",
|
||||
// auth: {
|
||||
// username: username,
|
||||
// password: password,
|
||||
// },
|
||||
// data: {
|
||||
// jsonrpc: "1.0",
|
||||
// },
|
||||
//};
|
||||
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", config.rawTransactionsRateLimit1, (req, res, next) => {
|
||||
res.json({ status: "rawtransactions" })
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/decodeRawTransaction/:hex",
|
||||
config.rawTransactionsRateLimit2,
|
||||
(req, res, next) => {
|
||||
try {
|
||||
let transactions = JSON.parse(req.params.hex)
|
||||
if (transactions.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 transactions"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
transactions = transactions.map(transaction =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "decoderawtransaction",
|
||||
method: "decoderawtransaction",
|
||||
params: [transaction]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(transactions).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "decoderawtransaction",
|
||||
method: "decoderawtransaction",
|
||||
params: [req.params.hex]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/decodeScript/:script",
|
||||
config.rawTransactionsRateLimit3,
|
||||
(req, res, next) => {
|
||||
try {
|
||||
let scripts = JSON.parse(req.params.script)
|
||||
if (scripts.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 scripts"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
scripts = scripts.map(script =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "decodescript",
|
||||
method: "decodescript",
|
||||
params: [script]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(scripts).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "decodescript",
|
||||
method: "decodescript",
|
||||
params: [req.params.script]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/getRawTransaction/:txid",
|
||||
config.rawTransactionsRateLimit4,
|
||||
(req, res, next) => {
|
||||
let verbose = 0
|
||||
if (req.query.verbose && req.query.verbose === "true") verbose = 1
|
||||
|
||||
try {
|
||||
let txids = JSON.parse(req.params.txid)
|
||||
if (txids.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 txids"
|
||||
})
|
||||
}
|
||||
const result = []
|
||||
txids = txids.map(txid =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getrawtransaction",
|
||||
method: "getrawtransaction",
|
||||
params: [txid, verbose]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(txids).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "getrawtransaction",
|
||||
method: "getrawtransaction",
|
||||
params: [req.params.txid, verbose]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/sendRawTransaction/:hex",
|
||||
config.rawTransactionsRateLimit5,
|
||||
(req, res, next) => {
|
||||
try {
|
||||
let transactions = JSON.parse(req.params.hex)
|
||||
if (transactions.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 transactions"
|
||||
})
|
||||
}
|
||||
|
||||
const result = []
|
||||
transactions = transactions.map(transaction =>
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "sendrawtransaction",
|
||||
method: "sendrawtransaction",
|
||||
params: [transaction]
|
||||
}
|
||||
}).catch(error => {
|
||||
try {
|
||||
return {
|
||||
data: {
|
||||
result: error.response.data.error.message
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
return {
|
||||
data: {
|
||||
result: "unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
axios.all(transactions).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data.result
|
||||
result.push(parsed)
|
||||
}
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
BitboxHTTP({
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: "sendrawtransaction",
|
||||
method: "sendrawtransaction",
|
||||
params: [req.params.hex]
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
res.json(response.data.result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/change/:rawtx/:prevTxs/:destination/:fee",
|
||||
config.rawTransactionsRateLimit6,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const params = [
|
||||
req.params.rawtx,
|
||||
JSON.parse(req.params.prevTxs),
|
||||
req.params.destination,
|
||||
parseFloat(req.params.fee)
|
||||
]
|
||||
if (req.query.position) params.push(parseInt(req.query.position))
|
||||
|
||||
requestConfig.data.id = "whc_createrawtx_change"
|
||||
requestConfig.data.method = "whc_createrawtx_change"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
} catch (err) {
|
||||
// console.log(`Error in /change: `)
|
||||
res.status(500)
|
||||
res.send(`Error in /change: ${err.message}`)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/input/:rawTx/:txid/:n",
|
||||
config.rawTransactionsRateLimit7,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createrawtx_input"
|
||||
requestConfig.data.method = "whc_createrawtx_input"
|
||||
requestConfig.data.params = [
|
||||
req.params.rawTx,
|
||||
req.params.txid,
|
||||
parseInt(req.params.n)
|
||||
]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/opReturn/:rawTx/:payload",
|
||||
config.rawTransactionsRateLimit8,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "whc_createrawtx_opreturn"
|
||||
requestConfig.data.method = "whc_createrawtx_opreturn"
|
||||
requestConfig.data.params = [req.params.rawTx, req.params.payload]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/reference/:rawTx/:destination",
|
||||
config.rawTransactionsRateLimit9,
|
||||
async (req, res, next) => {
|
||||
const params = [req.params.rawTx, req.params.destination]
|
||||
if (req.query.amount) params.push(req.query.amount)
|
||||
|
||||
requestConfig.data.id = "whc_createrawtx_reference"
|
||||
requestConfig.data.method = "whc_createrawtx_reference"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/decodeTransaction/:rawTx",
|
||||
config.rawTransactionsRateLimit10,
|
||||
async (req, res, next) => {
|
||||
const params = [req.params.rawTx]
|
||||
if (req.query.prevTxs) params.push(JSON.parse(req.query.prevTxs))
|
||||
|
||||
if (req.query.height) params.push(req.query.height)
|
||||
|
||||
requestConfig.data.id = "whc_decodetransaction"
|
||||
requestConfig.data.method = "whc_decodetransaction"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error.message)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/create/:inputs/:outputs",
|
||||
config.rawTransactionsRateLimit11,
|
||||
async (req, res, next) => {
|
||||
const params = [
|
||||
JSON.parse(req.params.inputs),
|
||||
JSON.parse(req.params.outputs)
|
||||
]
|
||||
if (req.query.locktime) params.push(req.query.locktime)
|
||||
|
||||
requestConfig.data.id = "createrawtransaction"
|
||||
requestConfig.data.method = "createrawtransaction"
|
||||
requestConfig.data.params = params
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error.message)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,213 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
const bitdbToken = process.env.BITDB_TOKEN
|
||||
const bitboxproxy = require("slpjs").bitbox
|
||||
const utils = require("slpjs").utils
|
||||
|
||||
const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default
|
||||
const BITBOX = new BITBOXCli()
|
||||
|
||||
const config = {
|
||||
slpRateLimit1: undefined,
|
||||
slpRateLimit2: undefined,
|
||||
slpRateLimit3: undefined,
|
||||
slpRateLimit4: undefined,
|
||||
slpRateLimit5: undefined,
|
||||
slpRateLimit6: undefined,
|
||||
slpRateLimit7: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 8) {
|
||||
config[`slpRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
router.get("/", config.slpRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "slp" })
|
||||
})
|
||||
|
||||
router.get("/list", config.slpRateLimit2, async (req, res, next) => {
|
||||
try {
|
||||
const query = {
|
||||
v: 3,
|
||||
q: {
|
||||
find: { "out.h1": "534c5000", "out.s3": "GENESIS" },
|
||||
limit: 1000
|
||||
},
|
||||
r: {
|
||||
f:
|
||||
'[ .[] | { id: .tx.h, timestamp: (.blk.t | strftime("%Y-%m-%d %H:%M")), symbol: .out[0].s4, name: .out[0].s5, document: .out[0].s6 } ]'
|
||||
}
|
||||
}
|
||||
|
||||
const s = JSON.stringify(query)
|
||||
const b64 = Buffer.from(s).toString("base64")
|
||||
const url = `https://bitdb.network/q/${b64}`
|
||||
const header = {
|
||||
headers: { key: bitdbToken }
|
||||
}
|
||||
|
||||
const tokenRes = await axios.get(url, header)
|
||||
const tokens = tokenRes.data.c
|
||||
if (tokenRes.data.u && tokenRes.data.u.length) tokens.concat(tokenRes.u)
|
||||
res.json(tokens.reverse())
|
||||
|
||||
return tokens
|
||||
} catch (err) {
|
||||
res.status(500).send(err.response.data.error)
|
||||
}
|
||||
})
|
||||
|
||||
router.get("/list/:tokenId", config.slpRateLimit3, async (req, res, next) => {
|
||||
try {
|
||||
const query = {
|
||||
v: 3,
|
||||
q: {
|
||||
find: { "out.h1": "534c5000", "out.s3": "GENESIS" },
|
||||
limit: 1000
|
||||
},
|
||||
r: {
|
||||
f:
|
||||
'[ .[] | { id: .tx.h, timestamp: (.blk.t | strftime("%Y-%m-%d %H:%M")), symbol: .out[0].s4, name: .out[0].s5, document: .out[0].s6 } ]'
|
||||
}
|
||||
}
|
||||
|
||||
const s = JSON.stringify(query)
|
||||
const b64 = Buffer.from(s).toString("base64")
|
||||
const url = `https://bitdb.network/q/${b64}`
|
||||
const header = {
|
||||
headers: { key: bitdbToken }
|
||||
}
|
||||
|
||||
const tokenRes = await axios.get(url, header)
|
||||
const tokens = tokenRes.data.c
|
||||
if (tokenRes.data.u && tokenRes.data.u.length) tokens.concat(tokenRes.u)
|
||||
|
||||
tokens.forEach(token => {
|
||||
if (token.id === req.params.tokenId) return res.json(token)
|
||||
})
|
||||
} catch (err) {
|
||||
res.status(500).send(err.response.data.error)
|
||||
}
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/balancesForAddress/:address",
|
||||
config.slpRateLimit4,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const slpAddr = utils.toSlpAddress(req.params.address)
|
||||
const balances = await bitboxproxy.getAllTokenBalances(slpAddr)
|
||||
balances.slpAddress = slpAddr
|
||||
balances.cashAddress = utils.toCashAddress(slpAddr)
|
||||
balances.legacyAddress = BITBOX.Address.toLegacyAddress(
|
||||
balances.cashAddress
|
||||
)
|
||||
return res.json(balances)
|
||||
} catch (err) {
|
||||
res.status(500).send(err.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/balance/:address/:tokenId",
|
||||
config.slpRateLimit5,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const slpAddr = utils.toSlpAddress(req.params.address)
|
||||
const balances = await bitboxproxy.getAllTokenBalances(slpAddr)
|
||||
const query = {
|
||||
v: 3,
|
||||
q: {
|
||||
find: { "out.h1": "534c5000", "out.s3": "GENESIS" },
|
||||
limit: 1000
|
||||
},
|
||||
r: {
|
||||
f:
|
||||
'[ .[] | { id: .tx.h, timestamp: (.blk.t | strftime("%Y-%m-%d %H:%M")), symbol: .out[0].s4, name: .out[0].s5, document: .out[0].s6 } ]'
|
||||
}
|
||||
}
|
||||
|
||||
const s = JSON.stringify(query)
|
||||
const b64 = Buffer.from(s).toString("base64")
|
||||
const url = `https://bitdb.network/q/${b64}`
|
||||
const header = {
|
||||
headers: { key: bitdbToken }
|
||||
}
|
||||
|
||||
const tokenRes = await axios.get(url, header)
|
||||
const tokens = tokenRes.data.c
|
||||
if (tokenRes.data.u && tokenRes.data.u.length) tokens.concat(tokenRes.u)
|
||||
|
||||
let t
|
||||
tokens.forEach(token => {
|
||||
if (token.id === req.params.tokenId) t = token
|
||||
})
|
||||
|
||||
const obj = {}
|
||||
obj.id = t.id
|
||||
obj.timestamp = t.timestamp
|
||||
obj.symbol = t.symbol
|
||||
obj.name = t.name
|
||||
obj.document = t.document
|
||||
obj.balance = balances[req.params.tokenId]
|
||||
obj.slpAddress = slpAddr
|
||||
obj.cashAddress = utils.toCashAddress(slpAddr)
|
||||
obj.legacyAddress = BITBOX.Address.toLegacyAddress(obj.cashAddress)
|
||||
return res.json(obj)
|
||||
} catch (err) {
|
||||
res.status(500).send(err.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/address/convert/:address",
|
||||
config.slpRateLimit6,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const slpAddr = utils.toSlpAddress(req.params.address)
|
||||
const obj = {}
|
||||
obj.slpAddress = slpAddr
|
||||
obj.cashAddress = utils.toCashAddress(slpAddr)
|
||||
obj.legacyAddress = BITBOX.Address.toLegacyAddress(obj.cashAddress)
|
||||
return res.json(obj)
|
||||
} catch (err) {
|
||||
res.status(500).send(err.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
router.get(
|
||||
"/balancesForToken/:tokenId",
|
||||
config.slpRateLimit7,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const balances = "use v2"
|
||||
return res.json(balances)
|
||||
} catch (err) {
|
||||
res.status(500).send(err.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,93 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const BITBOXCli = require("bitbox-sdk/lib/bitbox-sdk").default
|
||||
const BITBOX = new BITBOXCli()
|
||||
|
||||
const config = {
|
||||
transactionRateLimit1: undefined,
|
||||
transactionRateLimit2: undefined
|
||||
}
|
||||
|
||||
const processInputs = tx => {
|
||||
if (tx.vin) {
|
||||
tx.vin.forEach(vin => {
|
||||
if (!vin.coinbase) {
|
||||
const address = vin.addr
|
||||
vin.legacyAddress = BITBOX.Address.toLegacyAddress(address)
|
||||
vin.cashAddress = BITBOX.Address.toCashAddress(address)
|
||||
vin.value = vin.valueSat
|
||||
delete vin.addr
|
||||
delete vin.valueSat
|
||||
delete vin.doubleSpentTxID
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 6) {
|
||||
config[`transactionRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
router.get("/", config.transactionRateLimit1, (req, res, next) => {
|
||||
res.json({ status: "transaction" })
|
||||
})
|
||||
|
||||
router.get("/details/:txid", config.transactionRateLimit1, (req, res, next) => {
|
||||
try {
|
||||
let txs = JSON.parse(req.params.txid)
|
||||
if (txs.length > 20) {
|
||||
res.json({
|
||||
error: "Array too large. Max 20 txids"
|
||||
})
|
||||
}
|
||||
|
||||
const result = []
|
||||
txs = txs.map(tx => axios.get(`${process.env.BITCOINCOM_BASEURL}tx/${tx}`))
|
||||
axios.all(txs).then(
|
||||
axios.spread((...args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const parsed = args[i].data
|
||||
result.push(parsed)
|
||||
}
|
||||
result.forEach(tx => {
|
||||
processInputs(tx)
|
||||
})
|
||||
res.json(result)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
axios
|
||||
.get(`${process.env.BITCOINCOM_BASEURL}tx/${req.params.txid}`)
|
||||
.then(response => {
|
||||
const parsed = response.data
|
||||
if (parsed) processInputs(parsed)
|
||||
|
||||
res.json(parsed)
|
||||
})
|
||||
.catch(error => {
|
||||
res.send(error.response.data.error.message)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@@ -1,70 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const axios = require("axios")
|
||||
const RateLimit = require("express-rate-limit")
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const config = {
|
||||
utilRateLimit1: undefined,
|
||||
utilRateLimit2: undefined
|
||||
}
|
||||
|
||||
let i = 1
|
||||
while (i < 3) {
|
||||
config[`utilRateLimit${i}`] = new RateLimit({
|
||||
windowMs: 60000, // 1 hour window
|
||||
delayMs: 0, // disable delaying - full speed until the max limit is reached
|
||||
max: 60, // start blocking after 60 requests
|
||||
handler: function(req, res /*next*/) {
|
||||
res.format({
|
||||
json: function() {
|
||||
res.status(500).json({
|
||||
error: "Too many requests. Limits are 60 requests per minute."
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
i++
|
||||
}
|
||||
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", config.utilRateLimit1, async (req, res, next) => {
|
||||
res.json({ status: "util" })
|
||||
})
|
||||
|
||||
router.get(
|
||||
"/validateAddress/:address",
|
||||
config.utilRateLimit2,
|
||||
async (req, res, next) => {
|
||||
requestConfig.data.id = "validateaddress"
|
||||
requestConfig.data.method = "validateaddress"
|
||||
requestConfig.data.params = [req.params.address]
|
||||
|
||||
try {
|
||||
const response = await BitboxHTTP(requestConfig)
|
||||
res.json(response.data.result)
|
||||
} catch (error) {
|
||||
res.status(500).send(error.response.data.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -4,16 +4,15 @@
|
||||
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
import * as requestUtils from "./services/requestUtils"
|
||||
import { IResponse } from "./interfaces/IResponse"
|
||||
import axios from "axios"
|
||||
const express = require("express")
|
||||
const requestUtils = require("./services/requestUtils")
|
||||
const axios = require("axios")
|
||||
const logger = require("./logging.js")
|
||||
const routeUtils = require("./route-utils")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
|
||||
//const router = express.Router()
|
||||
const router: express.Router = express.Router()
|
||||
const router = express.Router()
|
||||
|
||||
// Used for processing error messages before sending them to the user.
|
||||
const util = require("util")
|
||||
@@ -39,29 +38,20 @@ router.post("/transactions", transactionsBulk)
|
||||
router.get("/fromXPub/:xpub", fromXPubSingle)
|
||||
|
||||
// Root API endpoint. Simply acknowledges that it exists.
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "address" })
|
||||
}
|
||||
|
||||
// Query the Insight API for details on a single BCH address.
|
||||
// Returns a Promise.
|
||||
async function detailsFromInsight(
|
||||
thisAddress: string,
|
||||
currentPage: number = 0
|
||||
) {
|
||||
async function detailsFromInsight(thisAddress, currentPage = 0) {
|
||||
try {
|
||||
let addr: string
|
||||
let addr
|
||||
if (
|
||||
process.env.BITCOINCOM_BASEURL === "https://bch-insight.bitpay.com/api/"
|
||||
) {
|
||||
)
|
||||
addr = BITBOX.Address.toCashAddress(thisAddress)
|
||||
} else {
|
||||
addr = BITBOX.Address.toLegacyAddress(thisAddress)
|
||||
}
|
||||
else addr = BITBOX.Address.toLegacyAddress(thisAddress)
|
||||
|
||||
let path = `${process.env.BITCOINCOM_BASEURL}addr/${addr}`
|
||||
|
||||
@@ -99,11 +89,7 @@ async function detailsFromInsight(
|
||||
// POST handler for bulk queries on address details
|
||||
// curl -d '{"addresses": ["bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr", "bchtest:qp6hgvevf4gzz6l7pgcte3gaaud9km0l459fa23dul"]}' -H "Content-Type: application/json" http://localhost:3000/v2/address/details
|
||||
// curl -d '{"addresses": ["bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr", "bchtest:qp6hgvevf4gzz6l7pgcte3gaaud9km0l459fa23dul"], "from": 1, "to": 5}' -H "Content-Type: application/json" http://localhost:3000/v2/address/details
|
||||
async function detailsBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsBulk(req, res, next) {
|
||||
try {
|
||||
let addresses = req.body.addresses
|
||||
const currentPage = req.body.page ? parseInt(req.body.page, 10) : 0
|
||||
@@ -153,12 +139,12 @@ async function detailsBulk(
|
||||
|
||||
// Loops through each address and creates an array of Promises, querying
|
||||
// Insight API in parallel.
|
||||
addresses = addresses.map(async (address: any, index: number) => {
|
||||
return detailsFromInsight(address, currentPage)
|
||||
})
|
||||
addresses = addresses.map(async (address, index) =>
|
||||
detailsFromInsight(address, currentPage)
|
||||
)
|
||||
|
||||
// Wait for all parallel Insight requests to return.
|
||||
let result: Array<any> = await axios.all(addresses)
|
||||
const result = await axios.all(addresses)
|
||||
|
||||
// Return the array of retrieved address information.
|
||||
res.status(200)
|
||||
@@ -180,11 +166,7 @@ async function detailsBulk(
|
||||
}
|
||||
|
||||
// GET handler for single address details
|
||||
async function detailsSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsSingle(req, res, next) {
|
||||
try {
|
||||
const address = req.params.address
|
||||
const currentPage = req.query.page ? parseInt(req.query.page, 10) : 0
|
||||
@@ -228,7 +210,7 @@ async function detailsSingle(
|
||||
}
|
||||
|
||||
// Query the Insight API.
|
||||
let retData: any = await detailsFromInsight(address, currentPage)
|
||||
const retData = await detailsFromInsight(address, currentPage)
|
||||
|
||||
// Return the retrieved address information.
|
||||
res.status(200)
|
||||
@@ -251,16 +233,14 @@ async function detailsSingle(
|
||||
}
|
||||
|
||||
// Retrieve UTXO data from the Insight API
|
||||
async function utxoFromInsight(thisAddress: string) {
|
||||
async function utxoFromInsight(thisAddress) {
|
||||
try {
|
||||
let addr: string
|
||||
let addr
|
||||
if (
|
||||
process.env.BITCOINCOM_BASEURL === "https://bch-insight.bitpay.com/api/"
|
||||
) {
|
||||
)
|
||||
addr = BITBOX.Address.toCashAddress(thisAddress)
|
||||
} else {
|
||||
addr = BITBOX.Address.toLegacyAddress(thisAddress)
|
||||
}
|
||||
else addr = BITBOX.Address.toLegacyAddress(thisAddress)
|
||||
|
||||
const path = `${process.env.BITCOINCOM_BASEURL}addr/${addr}/utxo`
|
||||
|
||||
@@ -275,12 +255,12 @@ async function utxoFromInsight(thisAddress: string) {
|
||||
scriptPubKey: String
|
||||
}
|
||||
if (response.data.length && response.data[0].scriptPubKey) {
|
||||
let spk = response.data[0].scriptPubKey
|
||||
const spk = response.data[0].scriptPubKey
|
||||
retData.scriptPubKey = spk
|
||||
}
|
||||
retData.legacyAddress = BITBOX.Address.toLegacyAddress(thisAddress)
|
||||
retData.cashAddress = BITBOX.Address.toCashAddress(thisAddress)
|
||||
retData.utxos = response.data.map((utxo: any) => {
|
||||
retData.utxos = response.data.map(utxo => {
|
||||
delete utxo.address
|
||||
delete utxo.scriptPubKey
|
||||
return utxo
|
||||
@@ -296,11 +276,7 @@ async function utxoFromInsight(thisAddress: string) {
|
||||
}
|
||||
|
||||
// Retrieve UTXO information for an address.
|
||||
async function utxoBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function utxoBulk(req, res, next) {
|
||||
try {
|
||||
let addresses = req.body.addresses
|
||||
|
||||
@@ -351,12 +327,12 @@ async function utxoBulk(
|
||||
|
||||
// Loops through each address and creates an array of Promises, querying
|
||||
// Insight API in parallel.
|
||||
addresses = addresses.map(async (address: any, index: number) => {
|
||||
return utxoFromInsight(address)
|
||||
})
|
||||
addresses = addresses.map(async (address, index) =>
|
||||
utxoFromInsight(address)
|
||||
)
|
||||
|
||||
// Wait for all parallel Insight requests to return.
|
||||
let result: Array<any> = await axios.all(addresses)
|
||||
const result = await axios.all(addresses)
|
||||
|
||||
res.status(200)
|
||||
return res.json(result)
|
||||
@@ -378,11 +354,7 @@ async function utxoBulk(
|
||||
}
|
||||
|
||||
// GET handler for single address details
|
||||
async function utxoSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function utxoSingle(req, res, next) {
|
||||
try {
|
||||
const address = req.params.address
|
||||
if (!address || address === "") {
|
||||
@@ -444,13 +416,9 @@ async function utxoSingle(
|
||||
}
|
||||
|
||||
// Retrieve any unconfirmed TX information for a given address.
|
||||
async function unconfirmedBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function unconfirmedBulk(req, res, next) {
|
||||
try {
|
||||
let addresses = req.body.addresses
|
||||
const addresses = req.body.addresses
|
||||
|
||||
// Reject if address is not an array.
|
||||
if (!Array.isArray(addresses)) {
|
||||
@@ -497,16 +465,16 @@ async function unconfirmedBulk(
|
||||
const promises = addresses.map(address => utxoFromInsight(address))
|
||||
|
||||
// Wait for all parallel Insight requests to return.
|
||||
let result: Array<any> = await axios.all(promises)
|
||||
const result = await axios.all(promises)
|
||||
|
||||
// Loop through each result
|
||||
const finalResult = result.map(elem => {
|
||||
//console.log(`elem: ${util.inspect(elem)}`)
|
||||
|
||||
// Filter out confirmed transactions.
|
||||
const unconfirmedUtxos = elem.utxos.filter((utxo: any) => {
|
||||
return utxo.confirmations === 0
|
||||
})
|
||||
const unconfirmedUtxos = elem.utxos.filter(
|
||||
utxo => utxo.confirmations === 0
|
||||
)
|
||||
|
||||
elem.utxos = unconfirmedUtxos
|
||||
|
||||
@@ -534,11 +502,7 @@ async function unconfirmedBulk(
|
||||
}
|
||||
|
||||
// GET handler. Retrieve any unconfirmed TX information for a given address.
|
||||
async function unconfirmedSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function unconfirmedSingle(req, res, next) {
|
||||
try {
|
||||
const address = req.params.address
|
||||
if (!address || address === "") {
|
||||
@@ -576,25 +540,14 @@ async function unconfirmedSingle(
|
||||
})
|
||||
}
|
||||
|
||||
interface Iutxo {
|
||||
address: String
|
||||
txid: String
|
||||
vout: Number
|
||||
scriptPubKey: String
|
||||
amount: Number
|
||||
satoshis: Number
|
||||
height: Number
|
||||
confirmations: Number
|
||||
}
|
||||
|
||||
// Query the Insight API.
|
||||
const retData: any = await utxoFromInsight(address)
|
||||
const retData = await utxoFromInsight(address)
|
||||
//console.log(`retData: ${JSON.stringify(retData,null,2)}`)
|
||||
|
||||
// Loop through each returned UTXO.
|
||||
const unconfirmedUTXOs = []
|
||||
for (let j = 0; j < retData.utxos.length; j++) {
|
||||
const thisUtxo: Iutxo = retData.utxos[j]
|
||||
const thisUtxo = retData.utxos[j]
|
||||
|
||||
// Only interested in UTXOs with no confirmations.
|
||||
if (thisUtxo.confirmations === 0) unconfirmedUTXOs.push(thisUtxo)
|
||||
@@ -623,10 +576,7 @@ async function unconfirmedSingle(
|
||||
}
|
||||
|
||||
// Retrieve transaction data from the Insight API
|
||||
async function transactionsFromInsight(
|
||||
thisAddress: string,
|
||||
currentPage: number = 0
|
||||
) {
|
||||
async function transactionsFromInsight(thisAddress, currentPage = 0) {
|
||||
try {
|
||||
const path = `${
|
||||
process.env.BITCOINCOM_BASEURL
|
||||
@@ -650,11 +600,7 @@ async function transactionsFromInsight(
|
||||
}
|
||||
|
||||
// Get an array of TX information for a given address.
|
||||
async function transactionsBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function transactionsBulk(req, res, next) {
|
||||
try {
|
||||
let addresses = req.body.addresses
|
||||
const currentPage = req.body.page ? parseInt(req.body.page, 10) : 0
|
||||
@@ -701,12 +647,12 @@ async function transactionsBulk(
|
||||
}
|
||||
|
||||
// Loop through each address and collect an array of promises.
|
||||
addresses = addresses.map(async (address: any, index: number) => {
|
||||
return transactionsFromInsight(address, currentPage)
|
||||
})
|
||||
addresses = addresses.map(async (address, index) =>
|
||||
transactionsFromInsight(address, currentPage)
|
||||
)
|
||||
|
||||
// Wait for all parallel Insight requests to return.
|
||||
let result: Array<any> = await axios.all(addresses)
|
||||
const result = await axios.all(addresses)
|
||||
|
||||
// Return the array of retrieved address information.
|
||||
res.status(200)
|
||||
@@ -729,11 +675,7 @@ async function transactionsBulk(
|
||||
}
|
||||
|
||||
// GET handler. Retrieve any unconfirmed TX information for a given address.
|
||||
async function transactionsSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function transactionsSingle(req, res, next) {
|
||||
try {
|
||||
const address = req.params.address
|
||||
const currentPage = req.query.page ? parseInt(req.query.page, 10) : 0
|
||||
@@ -803,11 +745,7 @@ async function transactionsSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function fromXPubSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function fromXPubSingle(req, res, next) {
|
||||
try {
|
||||
const xpub = req.params.xpub
|
||||
const hdPath = req.query.hdPath ? req.query.hdPath : "0"
|
||||
@@ -828,8 +766,8 @@ async function fromXPubSingle(
|
||||
logger.debug(`Executing address/fromXPub with this xpub: `, xpub)
|
||||
wlogger.debug(`Executing address/fromXPub with this xpub: `, xpub)
|
||||
|
||||
let cashAddr = BITBOX.Address.fromXPub(xpub, hdPath)
|
||||
let legacyAddr = BITBOX.Address.toLegacyAddress(cashAddr)
|
||||
const cashAddr = BITBOX.Address.fromXPub(xpub, hdPath)
|
||||
const legacyAddr = BITBOX.Address.toLegacyAddress(cashAddr)
|
||||
res.status(200)
|
||||
return res.json({
|
||||
cashAddress: cashAddr,
|
||||
@@ -1,18 +1,19 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
import * as requestUtils from "./services/requestUtils"
|
||||
import * as bitbox from "./services/bitbox"
|
||||
const express = require("express")
|
||||
const requestUtils = require("./services/requestUtils")
|
||||
const axios = require("axios")
|
||||
const bitbox = require("./services/bitbox")
|
||||
const logger = require("./logging.js")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
import axios from "axios"
|
||||
|
||||
const routeUtils = require("./route-utils")
|
||||
|
||||
// Used for processing error messages before sending them to the user.
|
||||
const util = require("util")
|
||||
util.inspect.defaultOptions = { depth: 3 }
|
||||
|
||||
const router: express.Router = express.Router()
|
||||
const router = express.Router()
|
||||
//const BitboxHTTP = bitbox.getInstance()
|
||||
|
||||
router.get("/", root)
|
||||
@@ -21,20 +22,12 @@ router.post("/detailsByHash", detailsByHashBulk)
|
||||
router.get("/detailsByHeight/:height", detailsByHeightSingle)
|
||||
router.post("/detailsByHeight", detailsByHeightBulk)
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "block" })
|
||||
}
|
||||
|
||||
// Call the insight server to get block details based on the hash.
|
||||
async function detailsByHashSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsByHashSingle(req, res, next) {
|
||||
try {
|
||||
const hash = req.params.hash
|
||||
|
||||
@@ -75,11 +68,7 @@ async function detailsByHashSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function detailsByHashBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsByHashBulk(req, res, next) {
|
||||
try {
|
||||
const hashes = req.body.hashes
|
||||
|
||||
@@ -112,12 +101,12 @@ async function detailsByHashBulk(
|
||||
}
|
||||
|
||||
// Loop through each hash and creates an array of promises
|
||||
const axiosPromises = hashes.map(async (hash: any) => {
|
||||
return axios.get(`${process.env.BITCOINCOM_BASEURL}block/${hash}`)
|
||||
})
|
||||
const axiosPromises = hashes.map(async hash =>
|
||||
axios.get(`${process.env.BITCOINCOM_BASEURL}block/${hash}`)
|
||||
)
|
||||
|
||||
// Wait for all parallel promises to return.
|
||||
const axiosResult: Array<any> = await axios.all(axiosPromises)
|
||||
const axiosResult = await axios.all(axiosPromises)
|
||||
|
||||
// Extract the data component from the axios response.
|
||||
const result = axiosResult.map(x => x.data)
|
||||
@@ -149,11 +138,7 @@ async function detailsByHashBulk(
|
||||
|
||||
// Call the Full Node to get block hash based on height, then call the Insight
|
||||
// server to get details from that hash.
|
||||
async function detailsByHeightSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsByHeightSingle(req, res, next) {
|
||||
try {
|
||||
const height = req.params.height
|
||||
|
||||
@@ -183,7 +168,6 @@ async function detailsByHeightSingle(
|
||||
req.params.hash = hash
|
||||
return detailsByHashSingle(req, res, next)
|
||||
} catch (err) {
|
||||
|
||||
// Attempt to decode the error message.
|
||||
const { msg, status } = routeUtils.decodeError(err)
|
||||
if (msg) {
|
||||
@@ -200,13 +184,9 @@ async function detailsByHeightSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function detailsByHeightBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsByHeightBulk(req, res, next) {
|
||||
try {
|
||||
let heights = req.body.heights
|
||||
const heights = req.body.heights
|
||||
|
||||
// Reject if heights is not an array.
|
||||
if (!Array.isArray(heights)) {
|
||||
@@ -245,7 +225,7 @@ async function detailsByHeightBulk(
|
||||
} = routeUtils.setEnvVars()
|
||||
|
||||
// Loop through each height and creates an array of requests to call in parallel
|
||||
const promises = heights.map(async (height: any) => {
|
||||
const promises = heights.map(async height => {
|
||||
requestConfig.data.id = "getblockhash"
|
||||
requestConfig.data.method = "getblockhash"
|
||||
requestConfig.data.params = [parseInt(height)]
|
||||
@@ -262,7 +242,7 @@ async function detailsByHeightBulk(
|
||||
})
|
||||
|
||||
// Wait for all parallel Insight requests to return.
|
||||
let result: Array<any> = await axios.all(promises)
|
||||
const result = await axios.all(promises)
|
||||
|
||||
res.status(200)
|
||||
return res.json(result)
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
import axios from "axios"
|
||||
import { IRequestConfig } from "./interfaces/IRequestConfig"
|
||||
const axios = require("axios")
|
||||
|
||||
const routeUtils = require("./route-utils")
|
||||
const logger = require("./logging.js")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
@@ -39,20 +39,12 @@ router.post("/getTxOutProof", getTxOutProofBulk)
|
||||
router.get("/verifyTxOutProof/:proof", verifyTxOutProofSingle)
|
||||
router.post("/verifyTxOutProof", verifyTxOutProofBulk)
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "blockchain" })
|
||||
}
|
||||
|
||||
// Returns the hash of the best (tip) block in the longest block chain.
|
||||
async function getBestBlockHash(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getBestBlockHash(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -84,11 +76,7 @@ async function getBestBlockHash(
|
||||
}
|
||||
}
|
||||
|
||||
async function getBlockchainInfo(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getBlockchainInfo(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -121,11 +109,7 @@ async function getBlockchainInfo(
|
||||
}
|
||||
}
|
||||
|
||||
async function getBlockCount(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getBlockCount(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -157,11 +141,7 @@ async function getBlockCount(
|
||||
}
|
||||
}
|
||||
|
||||
async function getBlockHeaderSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getBlockHeaderSingle(req, res, next) {
|
||||
try {
|
||||
let verbose = false
|
||||
if (req.query.verbose && req.query.verbose.toString() === "true")
|
||||
@@ -204,13 +184,9 @@ async function getBlockHeaderSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function getBlockHeaderBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getBlockHeaderBulk(req, res, next) {
|
||||
try {
|
||||
let hashes = req.body.hashes
|
||||
const hashes = req.body.hashes
|
||||
const verbose = req.body.verbose ? req.body.verbose : false
|
||||
|
||||
if (!Array.isArray(hashes)) {
|
||||
@@ -251,7 +227,7 @@ async function getBlockHeaderBulk(
|
||||
} = routeUtils.setEnvVars()
|
||||
|
||||
// Loop through each hash and creates an array of requests to call in parallel
|
||||
const promises = hashes.map(async (hash: any) => {
|
||||
const promises = hashes.map(async hash => {
|
||||
requestConfig.data.id = "getblockheader"
|
||||
requestConfig.data.method = "getblockheader"
|
||||
requestConfig.data.params = [hash, verbose]
|
||||
@@ -259,7 +235,7 @@ async function getBlockHeaderBulk(
|
||||
return await BitboxHTTP(requestConfig)
|
||||
})
|
||||
|
||||
const axiosResult: Array<any> = await axios.all(promises)
|
||||
const axiosResult = await axios.all(promises)
|
||||
|
||||
// Extract the data component from the axios response.
|
||||
const result = axiosResult.map(x => x.data.result)
|
||||
@@ -283,11 +259,7 @@ async function getBlockHeaderBulk(
|
||||
}
|
||||
}
|
||||
|
||||
async function getChainTips(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getChainTips(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -320,11 +292,7 @@ async function getChainTips(
|
||||
}
|
||||
|
||||
// Get the current difficulty value, used to regulate mining power on the network.
|
||||
async function getDifficulty(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getDifficulty(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -358,11 +326,7 @@ async function getDifficulty(
|
||||
}
|
||||
|
||||
// Returns mempool data for given transaction. TXID must be in mempool (unconfirmed)
|
||||
async function getMempoolEntrySingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getMempoolEntrySingle(req, res, next) {
|
||||
try {
|
||||
// Validate input parameter
|
||||
const txid = req.params.txid
|
||||
@@ -402,13 +366,9 @@ async function getMempoolEntrySingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function getMempoolEntryBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getMempoolEntryBulk(req, res, next) {
|
||||
try {
|
||||
let txids = req.body.txids
|
||||
const txids = req.body.txids
|
||||
|
||||
if (!Array.isArray(txids)) {
|
||||
res.status(400)
|
||||
@@ -448,7 +408,7 @@ async function getMempoolEntryBulk(
|
||||
} = routeUtils.setEnvVars()
|
||||
|
||||
// Loop through each txid and creates an array of requests to call in parallel
|
||||
const promises = txids.map(async (txid: any) => {
|
||||
const promises = txids.map(async txid => {
|
||||
requestConfig.data.id = "getmempoolentry"
|
||||
requestConfig.data.method = "getmempoolentry"
|
||||
requestConfig.data.params = [txid]
|
||||
@@ -456,7 +416,7 @@ async function getMempoolEntryBulk(
|
||||
return await BitboxHTTP(requestConfig)
|
||||
})
|
||||
|
||||
const axiosResult: Array<any> = await axios.all(promises)
|
||||
const axiosResult = await axios.all(promises)
|
||||
|
||||
// Extract the data component from the axios response.
|
||||
const result = axiosResult.map(x => x.data.result)
|
||||
@@ -480,11 +440,7 @@ async function getMempoolEntryBulk(
|
||||
}
|
||||
}
|
||||
|
||||
async function getMempoolInfo(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getMempoolInfo(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -516,11 +472,7 @@ async function getMempoolInfo(
|
||||
}
|
||||
}
|
||||
|
||||
async function getRawMempool(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getRawMempool(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -557,11 +509,7 @@ async function getRawMempool(
|
||||
}
|
||||
|
||||
// Returns details about an unspent transaction output.
|
||||
async function getTxOut(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getTxOut(req, res, next) {
|
||||
try {
|
||||
// Validate input parameter
|
||||
const txid = req.params.txid
|
||||
@@ -613,11 +561,7 @@ async function getTxOut(
|
||||
}
|
||||
|
||||
// Returns a hex-encoded proof that 'txid' was included in a block.
|
||||
async function getTxOutProofSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getTxOutProofSingle(req, res, next) {
|
||||
try {
|
||||
// Validate input parameter
|
||||
const txid = req.params.txid
|
||||
@@ -658,13 +602,9 @@ async function getTxOutProofSingle(
|
||||
}
|
||||
|
||||
// Returns a hex-encoded proof that 'txid' was included in a block.
|
||||
async function getTxOutProofBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getTxOutProofBulk(req, res, next) {
|
||||
try {
|
||||
let txids = req.body.txids
|
||||
const txids = req.body.txids
|
||||
|
||||
// Reject if txids is not an array.
|
||||
if (!Array.isArray(txids)) {
|
||||
@@ -704,7 +644,7 @@ async function getTxOutProofBulk(
|
||||
logger.debug(`Executing blockchain/getTxOutProof with these txids: `, txids)
|
||||
|
||||
// Loop through each txid and creates an array of requests to call in parallel
|
||||
const promises = txids.map(async (txid: any) => {
|
||||
const promises = txids.map(async txid => {
|
||||
requestConfig.data.id = "gettxoutproof"
|
||||
requestConfig.data.method = "gettxoutproof"
|
||||
requestConfig.data.params = [[txid]]
|
||||
@@ -713,7 +653,7 @@ async function getTxOutProofBulk(
|
||||
})
|
||||
|
||||
// Wait for all parallel promisses to resolve.
|
||||
const axiosResult: Array<any> = await axios.all(promises)
|
||||
const axiosResult = await axios.all(promises)
|
||||
|
||||
// Extract the data component from the axios response.
|
||||
const result = axiosResult.map(x => x.data.result)
|
||||
@@ -809,11 +749,7 @@ async function getTxOutProofBulk(
|
||||
// });
|
||||
*/
|
||||
|
||||
async function verifyTxOutProofSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function verifyTxOutProofSingle(req, res, next) {
|
||||
try {
|
||||
// Validate input parameter
|
||||
const proof = req.params.proof
|
||||
@@ -853,13 +789,9 @@ async function verifyTxOutProofSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyTxOutProofBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function verifyTxOutProofBulk(req, res, next) {
|
||||
try {
|
||||
let proofs = req.body.proofs
|
||||
const proofs = req.body.proofs
|
||||
|
||||
// Reject if proofs is not an array.
|
||||
if (!Array.isArray(proofs)) {
|
||||
@@ -900,7 +832,7 @@ async function verifyTxOutProofBulk(
|
||||
)
|
||||
|
||||
// Loop through each proof and creates an array of requests to call in parallel
|
||||
const promises = proofs.map(async (proof: any) => {
|
||||
const promises = proofs.map(async proof => {
|
||||
requestConfig.data.id = "verifytxoutproof"
|
||||
requestConfig.data.method = "verifytxoutproof"
|
||||
requestConfig.data.params = [proof]
|
||||
@@ -909,7 +841,7 @@ async function verifyTxOutProofBulk(
|
||||
})
|
||||
|
||||
// Wait for all parallel promisses to resolve.
|
||||
const axiosResult: Array<any> = await axios.all(promises)
|
||||
const axiosResult = await axios.all(promises)
|
||||
|
||||
// Extract the data component from the axios response.
|
||||
const result = axiosResult.map(x => x.data.result[0])
|
||||
@@ -1,9 +1,9 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
import axios from "axios"
|
||||
import { IRequestConfig } from "./interfaces/IRequestConfig"
|
||||
const axios = require("axios")
|
||||
|
||||
const logger = require("./logging.js")
|
||||
const routeUtils = require("./route-utils")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
@@ -15,21 +15,18 @@ util.inspect.defaultOptions = { depth: 1 }
|
||||
router.get("/", root)
|
||||
router.get("/getInfo", getInfo)
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "control" })
|
||||
}
|
||||
|
||||
// Execute the RPC getinfo call.
|
||||
async function getInfo(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
const {BitboxHTTP, username, password, requestConfig} = routeUtils.setEnvVars()
|
||||
async function getInfo(req, res, next) {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
username,
|
||||
password,
|
||||
requestConfig
|
||||
} = routeUtils.setEnvVars()
|
||||
|
||||
requestConfig.data.id = "getinfo"
|
||||
requestConfig.data.method = "getinfo"
|
||||
@@ -1,13 +0,0 @@
|
||||
export interface IRequestConfig {
|
||||
method: string
|
||||
auth: {
|
||||
username: string
|
||||
password: string
|
||||
}
|
||||
data: {
|
||||
jsonrpc: string
|
||||
id?: any
|
||||
method?: any
|
||||
params?: any
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export interface IResponse {
|
||||
status: number
|
||||
json: {
|
||||
error: string
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
import axios from "axios"
|
||||
import { IRequestConfig } from "./interfaces/IRequestConfig"
|
||||
const axios = require("axios")
|
||||
|
||||
const routeUtils = require("./route-utils")
|
||||
const logger = require("./logging.js")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
@@ -18,7 +18,7 @@ const BitboxHTTP = axios.create({
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const requestConfig: IRequestConfig = {
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
@@ -33,11 +33,7 @@ router.get("/", root)
|
||||
router.get("/getMiningInfo", getMiningInfo)
|
||||
router.get("/getNetworkHashps", getNetworkHashPS)
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "mining" })
|
||||
}
|
||||
|
||||
@@ -66,11 +62,7 @@ function root(
|
||||
// });
|
||||
// });
|
||||
|
||||
async function getMiningInfo(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getMiningInfo(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -101,11 +93,7 @@ async function getMiningInfo(
|
||||
}
|
||||
}
|
||||
|
||||
async function getNetworkHashPS(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getNetworkHashPS(req, res, next) {
|
||||
try {
|
||||
let nblocks = 120 // Default
|
||||
let height = -1 // Default
|
||||
@@ -1,18 +1,11 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
async (
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) => {
|
||||
res.json({ status: "network" })
|
||||
}
|
||||
)
|
||||
router.get("/", async (req, res, next) => {
|
||||
res.json({ status: "network" })
|
||||
})
|
||||
|
||||
// router.post('/addNode/:node/:command', (req, res, next) => {
|
||||
// BITBOX.Network.addNode(req.params.node, req.params.command)
|
||||
@@ -1,10 +1,9 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
import axios from "axios"
|
||||
import { IRequestConfig } from "./interfaces/IRequestConfig"
|
||||
import { IResponse } from "./interfaces/IResponse"
|
||||
const axios = require("axios")
|
||||
|
||||
const routeUtils = require("./route-utils")
|
||||
const logger = require("./logging.js")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
@@ -19,7 +18,7 @@ const BitboxHTTP = axios.create({
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const requestConfig: IRequestConfig = {
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
@@ -40,21 +39,13 @@ router.get("/getRawTransaction/:txid", getRawTransactionSingle)
|
||||
router.post("/sendRawTransaction", sendRawTransactionBulk)
|
||||
router.get("/sendRawTransaction/:hex", sendRawTransactionSingle)
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "rawtransactions" })
|
||||
}
|
||||
|
||||
// Decode transaction hex into a JSON object.
|
||||
// GET
|
||||
async function decodeRawTransactionSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function decodeRawTransactionSingle(req, res, next) {
|
||||
try {
|
||||
const hex = req.params.hex
|
||||
|
||||
@@ -97,13 +88,9 @@ async function decodeRawTransactionSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function decodeRawTransactionBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function decodeRawTransactionBulk(req, res, next) {
|
||||
try {
|
||||
let hexes = req.body.hexes
|
||||
const hexes = req.body.hexes
|
||||
|
||||
if (!Array.isArray(hexes)) {
|
||||
res.status(400)
|
||||
@@ -139,7 +126,7 @@ async function decodeRawTransactionBulk(
|
||||
} = routeUtils.setEnvVars()
|
||||
|
||||
// Loop through each height and creates an array of requests to call in parallel
|
||||
const promises = hexes.map(async (hex: any) => {
|
||||
const promises = hexes.map(async hex => {
|
||||
requestConfig.data.id = "decoderawtransaction"
|
||||
requestConfig.data.method = "decoderawtransaction"
|
||||
requestConfig.data.params = [hex]
|
||||
@@ -148,7 +135,7 @@ async function decodeRawTransactionBulk(
|
||||
})
|
||||
|
||||
// Wait for all parallel Insight requests to return.
|
||||
const axiosResult: Array<any> = await axios.all(promises)
|
||||
const axiosResult = await axios.all(promises)
|
||||
|
||||
// Retrieve the data part of the result.
|
||||
const result = axiosResult.map(x => x.data.result)
|
||||
@@ -213,11 +200,7 @@ async function decodeRawTransactionBulk(
|
||||
|
||||
// Decode a raw transaction from hex to assembly.
|
||||
// GET single
|
||||
async function decodeScriptSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function decodeScriptSingle(req, res, next) {
|
||||
try {
|
||||
const hex = req.params.hex
|
||||
|
||||
@@ -259,11 +242,7 @@ async function decodeScriptSingle(
|
||||
|
||||
// Decode a raw transaction from hex to assembly.
|
||||
// POST bulk
|
||||
async function decodeScriptBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function decodeScriptBulk(req, res, next) {
|
||||
try {
|
||||
const hexes = req.body.hexes
|
||||
|
||||
@@ -300,7 +279,7 @@ async function decodeScriptBulk(
|
||||
} = routeUtils.setEnvVars()
|
||||
|
||||
// Loop through each hex and create an array of promises
|
||||
const promises = hexes.map(async (hex: any) => {
|
||||
const promises = hexes.map(async hex => {
|
||||
requestConfig.data.id = "decodescript"
|
||||
requestConfig.data.method = "decodescript"
|
||||
requestConfig.data.params = [hex]
|
||||
@@ -310,7 +289,7 @@ async function decodeScriptBulk(
|
||||
})
|
||||
|
||||
// Wait for all parallel promises to return.
|
||||
const resolved: Array<any> = await Promise.all(promises)
|
||||
const resolved = await Promise.all(promises)
|
||||
|
||||
// Retrieve the data from each resolved promise.
|
||||
const result = resolved.map(x => x.data.result)
|
||||
@@ -335,7 +314,7 @@ async function decodeScriptBulk(
|
||||
}
|
||||
|
||||
// Retrieve raw transactions details from the full node.
|
||||
async function getRawTransactionsFromNode(txid: string, verbose: number) {
|
||||
async function getRawTransactionsFromNode(txid, verbose) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -359,16 +338,12 @@ async function getRawTransactionsFromNode(txid: string, verbose: number) {
|
||||
|
||||
// Get a JSON object breakdown of transaction details.
|
||||
// POST
|
||||
async function getRawTransactionBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getRawTransactionBulk(req, res, next) {
|
||||
try {
|
||||
let verbose = 0
|
||||
if (req.body.verbose) verbose = 1
|
||||
|
||||
let txids = req.body.txids
|
||||
const txids = req.body.txids
|
||||
if (!Array.isArray(txids)) {
|
||||
res.status(400)
|
||||
return res.json({ error: "txids must be an array" })
|
||||
@@ -383,7 +358,7 @@ async function getRawTransactionBulk(
|
||||
}
|
||||
|
||||
// stub response object
|
||||
let returnResponse: IResponse = {
|
||||
const returnResponse = {
|
||||
status: 100,
|
||||
json: {
|
||||
error: ""
|
||||
@@ -408,12 +383,12 @@ async function getRawTransactionBulk(
|
||||
}
|
||||
|
||||
// Loop through each txid and create an array of promises
|
||||
const promises = txids.map(async (txid: any) => {
|
||||
return getRawTransactionsFromNode(txid, verbose)
|
||||
})
|
||||
const promises = txids.map(async txid =>
|
||||
getRawTransactionsFromNode(txid, verbose)
|
||||
)
|
||||
|
||||
// Wait for all parallel promises to return.
|
||||
const axiosResult: Array<any> = await axios.all(promises)
|
||||
const axiosResult = await axios.all(promises)
|
||||
|
||||
res.status(200)
|
||||
return res.json(axiosResult)
|
||||
@@ -436,11 +411,7 @@ async function getRawTransactionBulk(
|
||||
|
||||
// Get a JSON object breakdown of transaction details.
|
||||
// GET
|
||||
async function getRawTransactionSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function getRawTransactionSingle(req, res, next) {
|
||||
try {
|
||||
let verbose = 0
|
||||
if (req.query.verbose === "true") verbose = 1
|
||||
@@ -472,11 +443,7 @@ async function getRawTransactionSingle(
|
||||
}
|
||||
|
||||
// Transmit a raw transaction to the BCH network.
|
||||
async function sendRawTransactionBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function sendRawTransactionBulk(req, res, next) {
|
||||
try {
|
||||
// Validation
|
||||
const hexes = req.body.hexes
|
||||
@@ -571,11 +538,7 @@ async function sendRawTransactionBulk(
|
||||
}
|
||||
|
||||
// Transmit a raw transaction to the BCH network.
|
||||
async function sendRawTransactionSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function sendRawTransactionSingle(req, res, next) {
|
||||
try {
|
||||
const hex = req.params.hex // URL parameter
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
"use strict"
|
||||
|
||||
const axios = require("axios")
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
|
||||
const getInstance = () => BitboxHTTP
|
||||
|
||||
module.exports = getInstance
|
||||
@@ -1,7 +0,0 @@
|
||||
import axios from "axios"
|
||||
|
||||
const BitboxHTTP = axios.create({
|
||||
baseURL: process.env.RPC_BASEURL
|
||||
})
|
||||
|
||||
export const getInstance = () => BitboxHTTP
|
||||
@@ -0,0 +1,20 @@
|
||||
"use strict"
|
||||
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const getRequestConfig = (method, params) => ({
|
||||
method: "post",
|
||||
auth: {
|
||||
username,
|
||||
password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: method,
|
||||
method,
|
||||
params
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = getRequestConfig
|
||||
@@ -1,25 +0,0 @@
|
||||
import { IRequestConfig } from "../interfaces/IRequestConfig"
|
||||
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
type RPCMethod = "getblockhash"
|
||||
|
||||
export const getRequestConfig = (
|
||||
method: RPCMethod,
|
||||
params: (string | number)[]
|
||||
): IRequestConfig => {
|
||||
return {
|
||||
method: "post",
|
||||
auth: {
|
||||
username,
|
||||
password
|
||||
},
|
||||
data: {
|
||||
jsonrpc: "1.0",
|
||||
id: method,
|
||||
method,
|
||||
params
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
import axios from "axios"
|
||||
import { IRequestConfig } from "./interfaces/IRequestConfig"
|
||||
const axios = require("axios")
|
||||
|
||||
const routeUtils = require("./route-utils")
|
||||
const logger = require("./logging.js")
|
||||
const strftime = require("strftime")
|
||||
@@ -79,7 +79,7 @@ if (process.env.NON_JS_FRAMEWORK && process.env.NON_JS_FRAMEWORK === "true") {
|
||||
// Retrieve raw transactions details from the full node.
|
||||
// TODO: move this function to a separate support library.
|
||||
// TODO: Add unit tests for this function.
|
||||
async function getRawTransactionsFromNode(txids: string[]) {
|
||||
async function getRawTransactionsFromNode(txids) {
|
||||
try {
|
||||
const {
|
||||
BitboxHTTP,
|
||||
@@ -106,9 +106,7 @@ async function getRawTransactionsFromNode(txids: string[]) {
|
||||
|
||||
// Insert to slpTxDb
|
||||
try {
|
||||
if (slpTxDb.isOpen()) {
|
||||
await slpTxDb.put(txid, result)
|
||||
}
|
||||
if (slpTxDb.isOpen()) await slpTxDb.put(txid, result)
|
||||
} catch (err) {
|
||||
// console.log("Error inserting to slpTxDb", err)
|
||||
}
|
||||
@@ -125,16 +123,14 @@ async function getRawTransactionsFromNode(txids: string[]) {
|
||||
}
|
||||
|
||||
// Create a validator for validating SLP transactions.
|
||||
function createValidator(network: string, getRawTransactions: any = null): any {
|
||||
let tmpSLP: any
|
||||
function createValidator(network, getRawTransactions = null) {
|
||||
let tmpSLP
|
||||
|
||||
if (network === "mainnet") {
|
||||
if (network === "mainnet")
|
||||
tmpSLP = new SLPSDK({ restURL: process.env.REST_URL })
|
||||
} else {
|
||||
tmpSLP = new SLPSDK({ restURL: process.env.TREST_URL })
|
||||
}
|
||||
else tmpSLP = new SLPSDK({ restURL: process.env.TREST_URL })
|
||||
|
||||
const slpValidator: any = new slp.LocalValidator(
|
||||
const slpValidator = new slp.LocalValidator(
|
||||
tmpSLP,
|
||||
getRawTransactions
|
||||
? getRawTransactions
|
||||
@@ -153,7 +149,7 @@ const slpValidator = createValidator(
|
||||
// Instantiate the bitboxproxy class in SLPJS.
|
||||
const bitboxproxy = new slp.BitboxNetwork(SLP, slpValidator)
|
||||
|
||||
const requestConfig: IRequestConfig = {
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
@@ -199,19 +195,11 @@ function formatTokenOutput(token) {
|
||||
return token
|
||||
}
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "slp" })
|
||||
}
|
||||
|
||||
async function list(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function list(req, res, next) {
|
||||
try {
|
||||
const query = {
|
||||
v: 3,
|
||||
@@ -233,10 +221,10 @@ async function list(
|
||||
// Get data from SLPDB.
|
||||
const tokenRes = await axios.get(url)
|
||||
|
||||
let formattedTokens: Array<any> = []
|
||||
const formattedTokens = []
|
||||
|
||||
if (tokenRes.data.t.length) {
|
||||
tokenRes.data.t.forEach((token: any) => {
|
||||
tokenRes.data.t.forEach(token => {
|
||||
token = formatTokenOutput(token)
|
||||
formattedTokens.push(token.tokenDetails)
|
||||
})
|
||||
@@ -257,13 +245,9 @@ async function list(
|
||||
}
|
||||
}
|
||||
|
||||
async function listSingleToken(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function listSingleToken(req, res, next) {
|
||||
try {
|
||||
let tokenId = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
@@ -287,13 +271,9 @@ async function listSingleToken(
|
||||
}
|
||||
}
|
||||
|
||||
async function listBulkToken(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function listBulkToken(req, res, next) {
|
||||
try {
|
||||
let tokenIds = req.body.tokenIds
|
||||
const tokenIds = req.body.tokenIds
|
||||
|
||||
// Reject if tokenIds is not an array.
|
||||
if (!Array.isArray(tokenIds)) {
|
||||
@@ -332,18 +312,18 @@ async function listBulkToken(
|
||||
|
||||
const tokenRes = await axios.get(url)
|
||||
|
||||
let formattedTokens: Array<any> = []
|
||||
let txids: Array<any> = []
|
||||
const formattedTokens = []
|
||||
const txids = []
|
||||
|
||||
if (tokenRes.data.t.length) {
|
||||
tokenRes.data.t.forEach((token: any) => {
|
||||
tokenRes.data.t.forEach(token => {
|
||||
txids.push(token.tokenDetails.tokenIdHex)
|
||||
token = formatTokenOutput(token)
|
||||
formattedTokens.push(token.tokenDetails)
|
||||
})
|
||||
}
|
||||
|
||||
tokenIds.forEach((tokenId: string) => {
|
||||
tokenIds.forEach(tokenId => {
|
||||
if (!txids.includes(tokenId)) {
|
||||
formattedTokens.push({
|
||||
id: tokenId,
|
||||
@@ -391,17 +371,17 @@ async function lookupToken(tokenId) {
|
||||
//console.log(`tokenRes.data: ${util.inspect(tokenRes.data,null,2)}`)
|
||||
//console.log(`tokenRes.data.t[0]: ${util.inspect(tokenRes.data.t[0],null,2)}`)
|
||||
|
||||
let formattedTokens: Array<any> = []
|
||||
const formattedTokens = []
|
||||
|
||||
if (tokenRes.data.t.length) {
|
||||
tokenRes.data.t.forEach((token: any) => {
|
||||
tokenRes.data.t.forEach(token => {
|
||||
token = formatTokenOutput(token)
|
||||
formattedTokens.push(token.tokenDetails)
|
||||
})
|
||||
}
|
||||
|
||||
let t
|
||||
formattedTokens.forEach((token: any) => {
|
||||
formattedTokens.forEach(token => {
|
||||
if (token.id === tokenId) t = token
|
||||
})
|
||||
|
||||
@@ -421,14 +401,10 @@ async function lookupToken(tokenId) {
|
||||
}
|
||||
|
||||
// Retrieve token balances for all tokens for a single address.
|
||||
async function balancesForAddress(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function balancesForAddress(req, res, next) {
|
||||
try {
|
||||
// Validate the input data.
|
||||
let address = req.params.address
|
||||
const address = req.params.address
|
||||
if (!address || address === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "address can not be empty" })
|
||||
@@ -436,7 +412,7 @@ async function balancesForAddress(
|
||||
|
||||
// Ensure the input is a valid BCH address.
|
||||
try {
|
||||
let cash = utils.toCashAddress(address)
|
||||
const cash = utils.toCashAddress(address)
|
||||
} catch (err) {
|
||||
res.status(400)
|
||||
return res.json({
|
||||
@@ -445,7 +421,7 @@ async function balancesForAddress(
|
||||
}
|
||||
|
||||
// Prevent a common user error. Ensure they are using the correct network address.
|
||||
let cashAddr = utils.toCashAddress(address)
|
||||
const cashAddr = utils.toCashAddress(address)
|
||||
const networkIsValid = routeUtils.validateNetwork(cashAddr)
|
||||
if (!networkIsValid) {
|
||||
res.status(400)
|
||||
@@ -472,7 +448,7 @@ async function balancesForAddress(
|
||||
|
||||
const tokenRes = await axios.get(url)
|
||||
|
||||
let tokenIds: string[] = []
|
||||
const tokenIds = []
|
||||
if (tokenRes.data.a.length > 0) {
|
||||
tokenRes.data.a = tokenRes.data.a.map(token => {
|
||||
token.tokenId = token.tokenDetails.tokenIdHex
|
||||
@@ -521,17 +497,15 @@ async function balancesForAddress(
|
||||
const details = await axios.all(promises)
|
||||
tokenRes.data.a = tokenRes.data.a.map(token => {
|
||||
details.forEach(detail => {
|
||||
if (detail.t[0].tokenDetails.tokenIdHex === token.tokenId) {
|
||||
if (detail.t[0].tokenDetails.tokenIdHex === token.tokenId)
|
||||
token.decimalCount = detail.t[0].tokenDetails.decimals
|
||||
}
|
||||
})
|
||||
return token
|
||||
})
|
||||
|
||||
return res.json(tokenRes.data.a)
|
||||
} else {
|
||||
return res.json("No balance for this address")
|
||||
}
|
||||
return res.json("No balance for this address")
|
||||
} catch (err) {
|
||||
wlogger.error(`Error in slp.ts/balancesForAddress().`, err)
|
||||
|
||||
@@ -550,14 +524,10 @@ async function balancesForAddress(
|
||||
}
|
||||
|
||||
// Retrieve token balances for all addresses by single tokenId.
|
||||
async function balancesForTokenSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function balancesForTokenSingle(req, res, next) {
|
||||
try {
|
||||
// Validate the input data.
|
||||
let tokenId = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
@@ -581,7 +551,7 @@ async function balancesForTokenSingle(
|
||||
|
||||
// Get data from SLPDB.
|
||||
const tokenRes = await axios.get(url)
|
||||
let resBalances: any[] = tokenRes.data.a.map((addy, index) => {
|
||||
const resBalances = tokenRes.data.a.map((addy, index) => {
|
||||
delete addy.satoshis_balance
|
||||
addy.tokenBalance = parseFloat(addy.token_balance)
|
||||
addy.slpAddress = addy.address
|
||||
@@ -609,20 +579,16 @@ async function balancesForTokenSingle(
|
||||
}
|
||||
|
||||
// Retrieve token balances for a single token class, for a single address.
|
||||
async function balancesForAddressByTokenID(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function balancesForAddressByTokenID(req, res, next) {
|
||||
try {
|
||||
// Validate input data.
|
||||
let address: string = req.params.address
|
||||
const address = req.params.address
|
||||
if (!address || address === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "address can not be empty" })
|
||||
}
|
||||
|
||||
let tokenId: string = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
@@ -630,7 +596,7 @@ async function balancesForAddressByTokenID(
|
||||
|
||||
// Ensure the input is a valid BCH address.
|
||||
try {
|
||||
let cash = utils.toCashAddress(address)
|
||||
const cash = utils.toCashAddress(address)
|
||||
} catch (err) {
|
||||
res.status(400)
|
||||
return res.json({
|
||||
@@ -639,7 +605,7 @@ async function balancesForAddressByTokenID(
|
||||
}
|
||||
|
||||
// Prevent a common user error. Ensure they are using the correct network address.
|
||||
let cashAddr = utils.toCashAddress(address)
|
||||
const cashAddr = utils.toCashAddress(address)
|
||||
const networkIsValid = routeUtils.validateNetwork(cashAddr)
|
||||
if (!networkIsValid) {
|
||||
res.status(400)
|
||||
@@ -669,7 +635,7 @@ async function balancesForAddressByTokenID(
|
||||
|
||||
// Get data from SLPDB.
|
||||
const tokenRes = await axios.get(url)
|
||||
let resVal: any
|
||||
let resVal
|
||||
res.status(200)
|
||||
if (tokenRes.data.a.length > 0) {
|
||||
tokenRes.data.a.forEach(async token => {
|
||||
@@ -740,13 +706,9 @@ async function balancesForAddressByTokenID(
|
||||
}
|
||||
}
|
||||
|
||||
async function convertAddressSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function convertAddressSingle(req, res, next) {
|
||||
try {
|
||||
let address = req.params.address
|
||||
const address = req.params.address
|
||||
|
||||
// Validate input
|
||||
if (!address || address === "") {
|
||||
@@ -756,11 +718,7 @@ async function convertAddressSingle(
|
||||
|
||||
const slpAddr = SLP.Address.toSLPAddress(address)
|
||||
|
||||
const obj: {
|
||||
[slpAddress: string]: any
|
||||
cashAddress: any
|
||||
legacyAddress: any
|
||||
} = {
|
||||
const obj = {
|
||||
slpAddress: "",
|
||||
cashAddress: "",
|
||||
legacyAddress: ""
|
||||
@@ -786,12 +744,8 @@ async function convertAddressSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function convertAddressBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
let addresses = req.body.addresses
|
||||
async function convertAddressBulk(req, res, next) {
|
||||
const addresses = req.body.addresses
|
||||
|
||||
// Reject if hashes is not an array.
|
||||
if (!Array.isArray(addresses)) {
|
||||
@@ -822,11 +776,7 @@ async function convertAddressBulk(
|
||||
|
||||
const slpAddr = SLP.Address.toSLPAddress(address)
|
||||
|
||||
const obj: {
|
||||
[slpAddress: string]: any
|
||||
cashAddress: any
|
||||
legacyAddress: any
|
||||
} = {
|
||||
const obj = {
|
||||
slpAddress: "",
|
||||
cashAddress: "",
|
||||
legacyAddress: ""
|
||||
@@ -842,11 +792,7 @@ async function convertAddressBulk(
|
||||
return res.json(convertedAddresses)
|
||||
}
|
||||
|
||||
async function validateBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function validateBulk(req, res, next) {
|
||||
try {
|
||||
const txids = req.body.txids
|
||||
|
||||
@@ -874,7 +820,7 @@ async function validateBulk(
|
||||
txid
|
||||
)
|
||||
|
||||
let tmp: any = {
|
||||
const tmp = {
|
||||
txid: txid,
|
||||
valid: isValid ? true : false
|
||||
}
|
||||
@@ -907,11 +853,7 @@ async function validateBulk(
|
||||
}
|
||||
}
|
||||
|
||||
async function validateSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function validateSingle(req, res, next) {
|
||||
try {
|
||||
const txid = req.params.txid
|
||||
|
||||
@@ -927,7 +869,7 @@ async function validateSingle(
|
||||
// Dev note: must call module.exports to allow stubs in unit tests.
|
||||
const isValid = await module.exports.testableComponents.isValidSlpTxid(txid)
|
||||
|
||||
let tmp: any = {
|
||||
const tmp = {
|
||||
txid: txid,
|
||||
valid: isValid ? true : false
|
||||
}
|
||||
@@ -950,7 +892,7 @@ async function validateSingle(
|
||||
}
|
||||
|
||||
// Returns a Boolean if the input TXID is a valid SLP TXID.
|
||||
async function isValidSlpTxid(txid: string): Promise<boolean> {
|
||||
async function isValidSlpTxid(txid) {
|
||||
const isValid = await slpValidator.isValidSlpTxid(txid)
|
||||
return isValid
|
||||
}
|
||||
@@ -958,78 +900,74 @@ async function isValidSlpTxid(txid: string): Promise<boolean> {
|
||||
// Below are functions which are enabled for teams not using our javascript SDKs which still need to create txs
|
||||
// These should never be enabled on our public REST API
|
||||
|
||||
async function createTokenType1(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
let fundingAddress = req.params.fundingAddress
|
||||
async function createTokenType1(req, res, next) {
|
||||
const fundingAddress = req.params.fundingAddress
|
||||
if (!fundingAddress || fundingAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingAddress can not be empty" })
|
||||
}
|
||||
|
||||
let fundingWif = req.params.fundingWif
|
||||
const fundingWif = req.params.fundingWif
|
||||
if (!fundingWif || fundingWif === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingWif can not be empty" })
|
||||
}
|
||||
|
||||
let tokenReceiverAddress = req.params.tokenReceiverAddress
|
||||
const tokenReceiverAddress = req.params.tokenReceiverAddress
|
||||
if (!tokenReceiverAddress || tokenReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let batonReceiverAddress = req.params.batonReceiverAddress
|
||||
const batonReceiverAddress = req.params.batonReceiverAddress
|
||||
if (!batonReceiverAddress || batonReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "batonReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
const bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
if (!bchChangeReceiverAddress || bchChangeReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "bchChangeReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let decimals = req.params.decimals
|
||||
const decimals = req.params.decimals
|
||||
if (!decimals || decimals === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "decimals can not be empty" })
|
||||
}
|
||||
|
||||
let name = req.params.name
|
||||
const name = req.params.name
|
||||
if (!name || name === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "name can not be empty" })
|
||||
}
|
||||
|
||||
let symbol = req.params.symbol
|
||||
const symbol = req.params.symbol
|
||||
if (!symbol || symbol === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "symbol can not be empty" })
|
||||
}
|
||||
|
||||
let documentUri = req.params.documentUri
|
||||
const documentUri = req.params.documentUri
|
||||
if (!documentUri || documentUri === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "documentUri can not be empty" })
|
||||
}
|
||||
|
||||
let documentHash = req.params.documentHash
|
||||
const documentHash = req.params.documentHash
|
||||
if (!documentHash || documentHash === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "documentHash can not be empty" })
|
||||
}
|
||||
|
||||
let initialTokenQty = req.params.initialTokenQty
|
||||
const initialTokenQty = req.params.initialTokenQty
|
||||
if (!initialTokenQty || initialTokenQty === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "initialTokenQty can not be empty" })
|
||||
}
|
||||
|
||||
let token = await SLP.TokenType1.create({
|
||||
const token = await SLP.TokenType1.create({
|
||||
fundingAddress: fundingAddress,
|
||||
fundingWif: fundingWif,
|
||||
tokenReceiverAddress: tokenReceiverAddress,
|
||||
@@ -1047,54 +985,50 @@ async function createTokenType1(
|
||||
return res.json(token)
|
||||
}
|
||||
|
||||
async function mintTokenType1(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
let fundingAddress = req.params.fundingAddress
|
||||
async function mintTokenType1(req, res, next) {
|
||||
const fundingAddress = req.params.fundingAddress
|
||||
if (!fundingAddress || fundingAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingAddress can not be empty" })
|
||||
}
|
||||
|
||||
let fundingWif = req.params.fundingWif
|
||||
const fundingWif = req.params.fundingWif
|
||||
if (!fundingWif || fundingWif === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingWif can not be empty" })
|
||||
}
|
||||
|
||||
let tokenReceiverAddress = req.params.tokenReceiverAddress
|
||||
const tokenReceiverAddress = req.params.tokenReceiverAddress
|
||||
if (!tokenReceiverAddress || tokenReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let batonReceiverAddress = req.params.batonReceiverAddress
|
||||
const batonReceiverAddress = req.params.batonReceiverAddress
|
||||
if (!batonReceiverAddress || batonReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "batonReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
const bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
if (!bchChangeReceiverAddress || bchChangeReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "bchChangeReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let tokenId = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
}
|
||||
|
||||
let additionalTokenQty = req.params.additionalTokenQty
|
||||
const additionalTokenQty = req.params.additionalTokenQty
|
||||
if (!additionalTokenQty || additionalTokenQty === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "additionalTokenQty can not be empty" })
|
||||
}
|
||||
|
||||
let mint = await SLP.TokenType1.mint({
|
||||
const mint = await SLP.TokenType1.mint({
|
||||
fundingAddress: fundingAddress,
|
||||
fundingWif: fundingWif,
|
||||
tokenReceiverAddress: tokenReceiverAddress,
|
||||
@@ -1108,47 +1042,43 @@ async function mintTokenType1(
|
||||
return res.json(mint)
|
||||
}
|
||||
|
||||
async function sendTokenType1(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
let fundingAddress = req.params.fundingAddress
|
||||
async function sendTokenType1(req, res, next) {
|
||||
const fundingAddress = req.params.fundingAddress
|
||||
if (!fundingAddress || fundingAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingAddress can not be empty" })
|
||||
}
|
||||
|
||||
let fundingWif = req.params.fundingWif
|
||||
const fundingWif = req.params.fundingWif
|
||||
if (!fundingWif || fundingWif === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingWif can not be empty" })
|
||||
}
|
||||
|
||||
let tokenReceiverAddress = req.params.tokenReceiverAddress
|
||||
const tokenReceiverAddress = req.params.tokenReceiverAddress
|
||||
if (!tokenReceiverAddress || tokenReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
const bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
if (!bchChangeReceiverAddress || bchChangeReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "bchChangeReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let tokenId = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
}
|
||||
|
||||
let amount = req.params.amount
|
||||
const amount = req.params.amount
|
||||
if (!amount || amount === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "amount can not be empty" })
|
||||
}
|
||||
let send = await SLP.TokenType1.send({
|
||||
const send = await SLP.TokenType1.send({
|
||||
fundingAddress: fundingAddress,
|
||||
fundingWif: fundingWif,
|
||||
tokenReceiverAddress: tokenReceiverAddress,
|
||||
@@ -1161,42 +1091,38 @@ async function sendTokenType1(
|
||||
return res.json(send)
|
||||
}
|
||||
|
||||
async function burnTokenType1(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
let fundingAddress = req.params.fundingAddress
|
||||
async function burnTokenType1(req, res, next) {
|
||||
const fundingAddress = req.params.fundingAddress
|
||||
if (!fundingAddress || fundingAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingAddress can not be empty" })
|
||||
}
|
||||
|
||||
let fundingWif = req.params.fundingWif
|
||||
const fundingWif = req.params.fundingWif
|
||||
if (!fundingWif || fundingWif === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingWif can not be empty" })
|
||||
}
|
||||
|
||||
let bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
const bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
if (!bchChangeReceiverAddress || bchChangeReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "bchChangeReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let tokenId = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
}
|
||||
|
||||
let amount = req.params.amount
|
||||
const amount = req.params.amount
|
||||
if (!amount || amount === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "amount can not be empty" })
|
||||
}
|
||||
|
||||
let burn = await SLP.TokenType1.burn({
|
||||
const burn = await SLP.TokenType1.burn({
|
||||
fundingAddress: fundingAddress,
|
||||
fundingWif: fundingWif,
|
||||
tokenId: tokenId,
|
||||
@@ -1208,36 +1134,32 @@ async function burnTokenType1(
|
||||
return res.json(burn)
|
||||
}
|
||||
|
||||
async function burnAllTokenType1(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
let fundingAddress = req.params.fundingAddress
|
||||
async function burnAllTokenType1(req, res, next) {
|
||||
const fundingAddress = req.params.fundingAddress
|
||||
if (!fundingAddress || fundingAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingAddress can not be empty" })
|
||||
}
|
||||
|
||||
let fundingWif = req.params.fundingWif
|
||||
const fundingWif = req.params.fundingWif
|
||||
if (!fundingWif || fundingWif === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "fundingWif can not be empty" })
|
||||
}
|
||||
|
||||
let bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
const bchChangeReceiverAddress = req.params.bchChangeReceiverAddress
|
||||
if (!bchChangeReceiverAddress || bchChangeReceiverAddress === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "bchChangeReceiverAddress can not be empty" })
|
||||
}
|
||||
|
||||
let tokenId = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
}
|
||||
|
||||
let burnAll = await SLP.TokenType1.burnAll({
|
||||
const burnAll = await SLP.TokenType1.burnAll({
|
||||
fundingAddress: fundingAddress,
|
||||
fundingWif: fundingWif,
|
||||
tokenId: tokenId,
|
||||
@@ -1248,11 +1170,7 @@ async function burnAllTokenType1(
|
||||
return res.json(burnAll)
|
||||
}
|
||||
|
||||
async function txDetails(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function txDetails(req, res, next) {
|
||||
try {
|
||||
// Validate input parameter
|
||||
const txid = req.params.txid
|
||||
@@ -1272,11 +1190,13 @@ async function txDetails(
|
||||
else tmpSLP = new SLPSDK({ restURL: process.env.REST_URL })
|
||||
|
||||
const tmpbitboxNetwork = new slp.BitboxNetwork(tmpSLP, slpValidator)
|
||||
console.log(`tmpbitboxNetwork: ${JSON.stringify(tmpbitboxNetwork,null,2)}`)
|
||||
//console.log(
|
||||
// `tmpbitboxNetwork: ${JSON.stringify(tmpbitboxNetwork, null, 2)}`
|
||||
//)
|
||||
|
||||
// Get TX info + token info
|
||||
const result = await tmpbitboxNetwork.getTransactionDetails(txid)
|
||||
console.log(`result: ${JSON.stringify(result,null,2)}`)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
res.status(200)
|
||||
return res.json(result)
|
||||
@@ -1301,12 +1221,8 @@ async function txDetails(
|
||||
}
|
||||
}
|
||||
|
||||
async function tokenStats(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
let tokenId: string = req.params.tokenId
|
||||
async function tokenStats(req, res, next) {
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
@@ -1334,10 +1250,10 @@ async function tokenStats(
|
||||
// Get data from BitDB.
|
||||
const tokenRes = await axios.get(url)
|
||||
|
||||
let formattedTokens: Array<any> = []
|
||||
const formattedTokens = []
|
||||
|
||||
if (tokenRes.data.t.length) {
|
||||
tokenRes.data.t.forEach((token: any) => {
|
||||
tokenRes.data.t.forEach(token => {
|
||||
token = formatTokenOutput(token)
|
||||
formattedTokens.push(token.tokenDetails)
|
||||
})
|
||||
@@ -1359,20 +1275,16 @@ async function tokenStats(
|
||||
}
|
||||
|
||||
// Retrieve transactions by tokenId and address.
|
||||
async function txsTokenIdAddressSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function txsTokenIdAddressSingle(req, res, next) {
|
||||
try {
|
||||
// Validate the input data.
|
||||
let tokenId = req.params.tokenId
|
||||
const tokenId = req.params.tokenId
|
||||
if (!tokenId || tokenId === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "tokenId can not be empty" })
|
||||
}
|
||||
|
||||
let address = req.params.address
|
||||
const address = req.params.address
|
||||
if (!address || address === "") {
|
||||
res.status(400)
|
||||
return res.json({ error: "address can not be empty" })
|
||||
@@ -1,9 +1,9 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
import axios from "axios"
|
||||
import { IRequestConfig } from "./interfaces/IRequestConfig"
|
||||
const axios = require("axios")
|
||||
|
||||
const routeUtils = require("./route-utils")
|
||||
const logger = require("./logging.js")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
@@ -16,10 +16,10 @@ const util = require("util")
|
||||
util.inspect.defaultOptions = { depth: 3 }
|
||||
|
||||
// Manipulates and formats the raw data comming from Insight API.
|
||||
const processInputs = (tx: any) => {
|
||||
const processInputs = tx => {
|
||||
// Add legacy and cashaddr to tx vin
|
||||
if (tx.vin) {
|
||||
tx.vin.forEach((vin: any) => {
|
||||
tx.vin.forEach(vin => {
|
||||
if (!vin.coinbase) {
|
||||
vin.value = vin.valueSat
|
||||
const address = vin.addr
|
||||
@@ -36,14 +36,14 @@ const processInputs = (tx: any) => {
|
||||
|
||||
// Add legacy and cashaddr to tx vout
|
||||
if (tx.vout) {
|
||||
tx.vout.forEach((vout: any) => {
|
||||
tx.vout.forEach(vout => {
|
||||
// Overwrite value string with value in satoshis
|
||||
//vout.value = parseFloat(vout.value) * 100000000
|
||||
|
||||
if (vout.scriptPubKey) {
|
||||
if (vout.scriptPubKey.addresses) {
|
||||
const cashAddrs = []
|
||||
vout.scriptPubKey.addresses.forEach((addr: any) => {
|
||||
vout.scriptPubKey.addresses.forEach(addr => {
|
||||
const cashAddr = BITBOX.Address.toCashAddress(addr)
|
||||
cashAddrs.push(cashAddr)
|
||||
})
|
||||
@@ -58,19 +58,15 @@ router.get("/", root)
|
||||
router.post("/details", detailsBulk)
|
||||
router.get("/details/:txid", detailsSingle)
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "transaction" })
|
||||
}
|
||||
|
||||
// Retrieve transaction data from the Insight API
|
||||
// This function is also used by the SLP route library.
|
||||
async function transactionsFromInsight(txid: string) {
|
||||
async function transactionsFromInsight(txid) {
|
||||
try {
|
||||
let path = `${process.env.BITCOINCOM_BASEURL}tx/${txid}`
|
||||
const path = `${process.env.BITCOINCOM_BASEURL}tx/${txid}`
|
||||
|
||||
// Query the Insight server.
|
||||
const response = await axios.get(path)
|
||||
@@ -88,11 +84,7 @@ async function transactionsFromInsight(txid: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function detailsBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsBulk(req, res, next) {
|
||||
try {
|
||||
const txids = req.body.txids
|
||||
|
||||
@@ -113,12 +105,12 @@ async function detailsBulk(
|
||||
logger.debug(`Executing transaction/details with these txids: `, txids)
|
||||
|
||||
// Collect an array of promises
|
||||
const promises = txids.map(async (txid: any) => {
|
||||
return await transactionsFromInsight(txid)
|
||||
})
|
||||
const promises = txids.map(
|
||||
async txid => await transactionsFromInsight(txid)
|
||||
)
|
||||
|
||||
// Wait for all parallel promises to return.
|
||||
const result: Array<any> = await Promise.all(promises)
|
||||
const result = await Promise.all(promises)
|
||||
|
||||
// Return the array of retrieved transaction information.
|
||||
res.status(200)
|
||||
@@ -140,11 +132,7 @@ async function detailsBulk(
|
||||
}
|
||||
|
||||
// GET handler. Retrieve any unconfirmed TX information for a given address.
|
||||
async function detailsSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function detailsSingle(req, res, next) {
|
||||
try {
|
||||
const txid = req.params.txid
|
||||
if (!txid || txid === "") {
|
||||
@@ -1,9 +1,9 @@
|
||||
"use strict"
|
||||
|
||||
import * as express from "express"
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
import axios from "axios"
|
||||
import { IRequestConfig } from "./interfaces/IRequestConfig"
|
||||
const axios = require("axios")
|
||||
|
||||
const routeUtils = require("./route-utils")
|
||||
const logger = require("./logging.js")
|
||||
const wlogger = require("../../util/winston-logging")
|
||||
@@ -22,7 +22,7 @@ const BitboxHTTP = axios.create({
|
||||
const username = process.env.RPC_USERNAME
|
||||
const password = process.env.RPC_PASSWORD
|
||||
|
||||
const requestConfig: IRequestConfig = {
|
||||
const requestConfig = {
|
||||
method: "post",
|
||||
auth: {
|
||||
username: username,
|
||||
@@ -34,25 +34,14 @@ const requestConfig: IRequestConfig = {
|
||||
}
|
||||
|
||||
router.get("/", root)
|
||||
router.get(
|
||||
"/validateAddress/:address",
|
||||
validateAddressSingle
|
||||
)
|
||||
router.get("/validateAddress/:address", validateAddressSingle)
|
||||
router.post("/validateAddress", validateAddressBulk)
|
||||
|
||||
function root(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
function root(req, res, next) {
|
||||
return res.json({ status: "util" })
|
||||
}
|
||||
|
||||
async function validateAddressSingle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function validateAddressSingle(req, res, next) {
|
||||
try {
|
||||
const address = req.params.address
|
||||
if (!address || address === "") {
|
||||
@@ -89,13 +78,9 @@ async function validateAddressSingle(
|
||||
}
|
||||
}
|
||||
|
||||
async function validateAddressBulk(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction
|
||||
) {
|
||||
async function validateAddressBulk(req, res, next) {
|
||||
try {
|
||||
let addresses = req.body.addresses
|
||||
const addresses = req.body.addresses
|
||||
|
||||
// Reject if addresses is not an array.
|
||||
if (!Array.isArray(addresses)) {
|
||||
@@ -114,7 +99,7 @@ async function validateAddressBulk(
|
||||
}
|
||||
|
||||
// Validate each element in the array.
|
||||
for(let i=0; i < addresses.length; i++) {
|
||||
for (let i = 0; i < addresses.length; i++) {
|
||||
const address = addresses[i]
|
||||
|
||||
// Ensure the input is a valid BCH address.
|
||||
@@ -147,8 +132,7 @@ async function validateAddressBulk(
|
||||
} = routeUtils.setEnvVars()
|
||||
|
||||
// Loop through each address and creates an array of requests to call in parallel
|
||||
const promises = addresses.map(async (address: any) => {
|
||||
|
||||
const promises = addresses.map(async address => {
|
||||
requestConfig.data.id = "validateaddress"
|
||||
requestConfig.data.method = "validateaddress"
|
||||
requestConfig.data.params = [address]
|
||||
@@ -157,14 +141,13 @@ async function validateAddressBulk(
|
||||
})
|
||||
|
||||
// Wait for all parallel Insight requests to return.
|
||||
const axiosResult: Array<any> = await axios.all(promises)
|
||||
const axiosResult = await axios.all(promises)
|
||||
|
||||
// Retrieve the data part of the result.
|
||||
const result = axiosResult.map(x => x.data.result)
|
||||
|
||||
res.status(200)
|
||||
return res.json(result)
|
||||
|
||||
} catch (err) {
|
||||
// Attempt to decode the error message.
|
||||
const { msg, status } = routeUtils.decodeError(err)
|
||||
@@ -1,287 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const rawTransactionsRoute = require("../../dist/routes/v1/rawtransactions")
|
||||
|
||||
// Used for debugging.
|
||||
const util = require("util")
|
||||
util.inspect.defaultOptions = {
|
||||
showHidden: true,
|
||||
colors: true
|
||||
}
|
||||
|
||||
describe("#RawTransactionsRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'rawtransactions' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "rawtransactions"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#DecodeRawTransaction", () => {
|
||||
it("should GET /decodeRawTransaction/:hex", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/decodeRawTransaction/["0200000001d0ba1330194111747e0b1784ab62126871c87acad3b6dc3a339b261ad974e940010000006b483045022100a284b4ac5ed55ac0e2baa02b6bdabbf06f98d2bf6b3fdcea1aea50f55766afd002206181c8e60f738116ba6e16177f3d408e8da2c463c69b27c2531fab84b63a63b24121022d426ef365d6480b127b4980afa4b9415cad5e6f0a9e11b1536d3523597197f3ffffffff02011d0000000000001976a91479d3297d1823149f4ec61df31d19f2fad5390c0288ac0000000000000000116a0f23424348466f7245766572796f6e6500000000"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
//console.log(`actualResponseBody: ${util.inspect(actualResponseBody)}`)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"txid",
|
||||
"hash",
|
||||
"size",
|
||||
"version",
|
||||
"locktime",
|
||||
"vin",
|
||||
"vout"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#DecodeScript", () => {
|
||||
it("should GET /decodeScript/:script", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/decodeScript/["4830450221009a51e00ec3524a7389592bc27bea4af5104a59510f5f0cfafa64bbd5c164ca2e02206c2a8bbb47eabdeed52f17d7df668d521600286406930426e3a9415fe10ed592012102e6e1423f7abde8b70bca3e78a7d030e5efabd3eb35c19302542b5fe7879c1a16"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, ["asm", "type", "p2sh"])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#GetRawTransaction", () => {
|
||||
it("should GET /getRawTransaction/:txid", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getRawTransaction/["0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#SendRawTransaction", () => {
|
||||
it("should POST /sendRawTransaction/:hex single tx hex", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
'/sendRawTransaction/["01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
assert.equal(actualResponseBody, "transaction already in block chain")
|
||||
done()
|
||||
})
|
||||
})
|
||||
//
|
||||
// it("should POST /sendRawTransaction/:hex array", (done) => {
|
||||
// let hex1 = '020000000148735fcdac94c51459f7d8f787cf363c618125bc0f9092092ed2ebccd0f5557e0000000069463043021f4e3dd1fadb3e8fabdbd94b125d7e97932f72bb08118407e49cf505e7f5f63b022062eee3c5d94b4bc6b68ab0018876e9661b257f1e8487173876faccf7d3a2220541210313299e9ec7a9e62789094b850ab6f71df7c39af7c03568027c24d0bc9eda930dffffffff017b140000000000001976a914e11ed7fd6416d8f5c58a1cb3e1b0005c3cab092f88ac00000000';
|
||||
// let hex2 = '0200000001a1b5849a5026642d5e28abdb4e98aa483adc20daab44c39e2f41acf72aa8c845000000006b483045022100994ab28c7df64852057c3ab965148ef2b5456233c12774087e88a62bbc27d4230220504d1096ac52915d32d2356ba5ae82f202543b88c24b4643800919e85da333984121039c48c06ce551810a2eeedf516c77995a922ca65c4e9e9a0a07288a6fae149eb2ffffffff013b1e0000000000001976a9140377597dd75d41398259c36d05a5a68ba0af782d88ac00000000';
|
||||
// let arr = [hex1, hex2];
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "POST",
|
||||
// url: '/sendRawTransaction/' + arr
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// rawTransactionsRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = mockResponse._getData();
|
||||
// assert.equal(actualResponseBody, 'transaction already in block chain');
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
})
|
||||
|
||||
/*
|
||||
describe("#change", () => {
|
||||
it("should POST /change/:rawtx/:prevTxs/:destination/:fee", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
'/change/0100000001b15ee60431ef57ec682790dec5a3c0d83a0c360633ea8308fbf6d5fc10a779670400000000ffffffff025c0d00000000000047512102f3e471222bb57a7d416c82bf81c627bfcd2bdc47f36e763ae69935bba4601ece21021580b888ff56feb27f17f08802ebed26258c23697d6a462d43fc13b565fda2dd52aeaa0a0000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000/[{"txid":"6779a710fcd5f6fb0883ea3306360c3ad8c0a3c5de902768ec57ef3104e65eb1","vout":4,"scriptPubKey":"76a9147b25205fd98d462880a3e5b0541235831ae959e588ac","value":0.00068257}]/bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg/0.00003500'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0100000001b15ee60431ef57ec682790dec5a3c0d83a0c360633ea8308fbf6d5fc10a779670400000000ffffffff03efe40000000000001976a9141522a025f2365eebee65cd8a8b8a38180dbcd59588ac5c0d00000000000047512102f3e471222bb57a7d416c82bf81c627bfcd2bdc47f36e763ae69935bba4601ece21021580b888ff56feb27f17f08802ebed26258c23697d6a462d43fc13b565fda2dd52aeaa0a0000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
describe("#input", () => {
|
||||
it("should POST /input/:rawTx/:txid/:n", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
"/input/01000000000000000000/b006729017df05eda586df9ad3f8ccfee5be340aadf88155b784d1fc0e8342ee/0"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0100000001ee42830efcd184b75581f8ad0a34bee5feccf8d39adf86a5ed05df17907206b00000000000ffffffff0000000000"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#opReturn", () => {
|
||||
it("should POST /opReturn/:rawTx/:payload", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url: "/opReturn/01000000000000000000/00000000000000020000000006dac2c0"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0100000000010000000000000000166a140877686300000000000000020000000006dac2c000000000"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
describe("#reference", () => {
|
||||
it("should POST /reference/:rawTx/:destination", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
"/reference/0100000001a7a9402ecd77f3c9f745793c9ec805bfa2e14b89877581c734c774864247e6f50400000000ffffffff03aa0a0000000000001976a9146d18edfe073d53f84dd491dae1379f8fb0dfe5d488ac5c0d0000000000004751210252ce4bdd3ce38b4ebbc5a6e1343608230da508ff12d23d85b58c964204c4cef3210294cc195fc096f87d0f813a337ae7e5f961b1c8a18f1f8604a909b3a5121f065b52aeaa0a0000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000/bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg?amount=0.005"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0100000001a7a9402ecd77f3c9f745793c9ec805bfa2e14b89877581c734c774864247e6f50400000000ffffffff04aa0a0000000000001976a9146d18edfe073d53f84dd491dae1379f8fb0dfe5d488ac5c0d0000000000004751210252ce4bdd3ce38b4ebbc5a6e1343608230da508ff12d23d85b58c964204c4cef3210294cc195fc096f87d0f813a337ae7e5f961b1c8a18f1f8604a909b3a5121f065b52aeaa0a0000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac20a10700000000001976a9141522a025f2365eebee65cd8a8b8a38180dbcd59588ac00000000"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
/*
|
||||
describe("#decodeTransaction", () => {
|
||||
it("should POST /decodeTransaction/:rawTx", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
'/decodeTransaction/010000000163af14ce6d477e1c793507e32a5b7696288fa89705c0d02a3f66beb3c5b8afee0100000000ffffffff02ac020000000000004751210261ea979f6a06f9dafe00fb1263ea0aca959875a7073556a088cdfadcd494b3752102a3fd0a8a067e06941e066f78d930bfc47746f097fcd3f7ab27db8ddf37168b6b52ae22020000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000?prevTxs=[{"txid":"eeafb8c5b3be663f2ad0c00597a88f2896765b2ae30735791c7e476dce14af63","vout":1,"scriptPubKey":"76a9149084c0bd89289bc025d0264f7f23148fb683d56c88ac","value":0.0001123}]'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
assert.equal(actualResponseBody, "Not a Master Protocol transaction")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
describe("#create", () => {
|
||||
it("should POST /create/:inputs/:outputs", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
'/create/ [{"txid":"eeafb8c5b3be663f2ad0c00597a88f2896765b2ae30735791c7e476dce14af63","vout":1}]/{}'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
rawTransactionsRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"020000000163af14ce6d477e1c793507e32a5b7696288fa89705c0d02a3f66beb3c5b8afee0100000000ffffffff0000000000"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,203 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const addressRoute = require("../../dist/routes/v1/address")
|
||||
|
||||
const util = require("util")
|
||||
util.inspect.defaultOptions = {
|
||||
showHidden: true,
|
||||
colors: true
|
||||
}
|
||||
|
||||
describe("#AddressRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'address' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
addressRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "address"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#AddressDetails", () => {
|
||||
it("should GET /details/:address single address", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: '/details/["qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
addressRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"balance",
|
||||
"balanceSat",
|
||||
"totalReceived",
|
||||
"totalReceivedSat",
|
||||
"totalSent",
|
||||
"totalSentSat",
|
||||
"unconfirmedBalance",
|
||||
"unconfirmedBalanceSat",
|
||||
"unconfirmedTxAppearances",
|
||||
"txAppearances",
|
||||
"transactions",
|
||||
"legacyAddress",
|
||||
"cashAddress"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /details/:address array of addresses", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/details/["qql6r7khtjgwy3ufnjtsczvaf925hyw49cudht57tr", "qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
addressRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"balance",
|
||||
"balanceSat",
|
||||
"totalReceived",
|
||||
"totalReceivedSat",
|
||||
"totalSent",
|
||||
"totalSentSat",
|
||||
"unconfirmedBalance",
|
||||
"unconfirmedBalanceSat",
|
||||
"unconfirmedTxAppearances",
|
||||
"txAppearances",
|
||||
"transactions",
|
||||
"legacyAddress",
|
||||
"cashAddress"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#AddressUtxo", () => {
|
||||
it("should GET /utxo/:address single address", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: '/utxo/["qpk4hk3wuxe2uqtqc97n8atzrrr6r5mleczf9sur4h"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
addressRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0][0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"txid",
|
||||
"vout",
|
||||
"scriptPubKey",
|
||||
"amount",
|
||||
"satoshis",
|
||||
"height",
|
||||
"confirmations",
|
||||
"legacyAddress",
|
||||
"cashAddress"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /utxo/:address array of addresses", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/utxo/["qz4q7h2jxmfhg3l7r7zeumzgeh7gyp6shuqmq5h6np", "qzqlp044n3qn7kntlc0mr5tp2a0ee0vvyq9yyyyjh0"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
addressRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[1][0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"txid",
|
||||
"vout",
|
||||
"scriptPubKey",
|
||||
"amount",
|
||||
"satoshis",
|
||||
"height",
|
||||
"confirmations",
|
||||
"legacyAddress",
|
||||
"cashAddress"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#AddressUnconfirmed", () => {
|
||||
it("should GET /unconfirmed/:address single address", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: '/unconfirmed/["qql6r7khtjgwy3ufnjtsczvaf925hyw49cudht57tr"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
addressRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [])
|
||||
// assert.deepEqual(actualResponseBody, [ 'txid', 'vout', 'scriptPubKey', 'amount', 'satoshis', 'height', 'confirmations', 'legacyAddress', 'cashAddress']);
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /unconfirmed/:address array of addresses", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/unconfirmed/["qql6r7khtjgwy3ufnjtsczvaf925hyw49cudht57tr", "qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
addressRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [])
|
||||
// assert.deepEqual(actualResponseBody, [ 'txid', 'vout', 'scriptPubKey', 'amount', 'satoshis', 'height', 'confirmations', 'legacyAddress', 'cashAddress']);
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,101 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const blockRoute = require("../../dist/routes/v1/block")
|
||||
|
||||
describe("#BlockRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'block' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
blockRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "block"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockDetails", () => {
|
||||
it("should GET /details/:id height", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/details/549608"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockRoute(mockRequest, mockResponse)
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"hash",
|
||||
"size",
|
||||
"height",
|
||||
"version",
|
||||
"merkleroot",
|
||||
"tx",
|
||||
"time",
|
||||
"nonce",
|
||||
"bits",
|
||||
"difficulty",
|
||||
"chainwork",
|
||||
"confirmations",
|
||||
"previousblockhash",
|
||||
"nextblockhash",
|
||||
"reward",
|
||||
"isMainChain",
|
||||
"poolInfo"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /details/:id hash", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/details/00000000000000000182bf5782f3d43b1a8fceccb50253eb61e58cba7b240edc"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"hash",
|
||||
"size",
|
||||
"height",
|
||||
"version",
|
||||
"merkleroot",
|
||||
"tx",
|
||||
"time",
|
||||
"nonce",
|
||||
"bits",
|
||||
"difficulty",
|
||||
"chainwork",
|
||||
"confirmations",
|
||||
"previousblockhash",
|
||||
"nextblockhash",
|
||||
"reward",
|
||||
"isMainChain",
|
||||
"poolInfo"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,593 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const blockchainRoute = require("../../dist/routes/v1/blockchain")
|
||||
|
||||
describe("#BlockchainRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'blockchain' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "blockchain"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetBestBlockHash", () => {
|
||||
it("should GET /getBestBlockHash ", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getBestBlockHash"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(actualResponseBody.length, 64)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetBlock", () => {
|
||||
it("should GET /getBlock/:id w/ verbose=true", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/getblock/00000000000000000182bf5782f3d43b1a8fceccb50253eb61e58cba7b240edc?verbose=true"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"hash",
|
||||
"confirmations",
|
||||
"size",
|
||||
"height",
|
||||
"version",
|
||||
"versionHex",
|
||||
"merkleroot",
|
||||
"tx",
|
||||
"time",
|
||||
"mediantime",
|
||||
"nonce",
|
||||
"bits",
|
||||
"difficulty",
|
||||
"chainwork",
|
||||
"previousblockhash",
|
||||
"nextblockhash"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /getBlock/:id w/ verbose=false", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/getblock/00000000000000000182bf5782f3d43b1a8fceccb50253eb61e58cba7b240edc?verbose=false"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
assert.equal(actualResponseBody.length, 34638)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
// TODO - Why is this test failing?
|
||||
// describe("#BlockchainGetBlockchainInfo", () => {
|
||||
// it("should GET /getBlockchainInfo ", done => {
|
||||
// const mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/getBlockchainInfo"
|
||||
// })
|
||||
// const mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require("events").EventEmitter
|
||||
// })
|
||||
// blockchainRoute(mockRequest, mockResponse)
|
||||
//
|
||||
// mockResponse.on("end", () => {
|
||||
// const actualResponseBody = Object.keys(
|
||||
// JSON.parse(mockResponse._getData())
|
||||
// )
|
||||
// assert.deepEqual(actualResponseBody, [
|
||||
// "chain",
|
||||
// "blocks",
|
||||
// "headers",
|
||||
// "bestblockhash",
|
||||
// "difficulty",
|
||||
// "mediantime",
|
||||
// "verificationprogress",
|
||||
// "chainwork",
|
||||
// "pruned",
|
||||
// "softforks",
|
||||
// "bip9_softforks"
|
||||
// ])
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
|
||||
describe("#BlockchainGetBlockCount", () => {
|
||||
it("should GET /getBlockCount ", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getBlockCount"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = parseInt(mockResponse._getData())
|
||||
assert.equal(typeof actualResponseBody, "number")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetBlockHash", () => {
|
||||
it("should GET /getBlockHash/:height ", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getBlockhash/[0, 1, 2, 3, 532646]"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetBlockHeader", () => {
|
||||
it("should GET /getBlockHeader/:hash w/ verbose=true", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getBlockHeader/["00000000000000000182bf5782f3d43b1a8fceccb50253eb61e58cba7b240edc"%5D?verbose=true'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"hash",
|
||||
"confirmations",
|
||||
"height",
|
||||
"version",
|
||||
"versionHex",
|
||||
"merkleroot",
|
||||
"time",
|
||||
"mediantime",
|
||||
"nonce",
|
||||
"bits",
|
||||
"difficulty",
|
||||
"chainwork",
|
||||
"previousblockhash",
|
||||
"nextblockhash"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /getBlockHeader/:hash w/ verbose=false", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getBlockHeader/00000000000000000182bf5782f3d43b1a8fceccb50253eb61e58cba7b240edc"%5D?verbose=false'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.deepEqual(actualResponseBody.length, 160)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetChainTips", () => {
|
||||
it("should GET /getChainTips ", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getChainTips"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"height",
|
||||
"hash",
|
||||
"branchlen",
|
||||
"status"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetDifficulty", () => {
|
||||
it("should GET /getDifficulty ", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getDifficulty"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = parseFloat(mockResponse._getData())
|
||||
assert.equal(typeof actualResponseBody, "number")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetMempoolAncestors", () => {
|
||||
it("should GET /getMempoolAncestors/:txid w/ verbose=true", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getMempoolAncestors/["53735a4ddb828825d6e3f52d045f4c151b2b3d51d631bc581e62f31184b151d6"%5D?verbose=true'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
assert.equal(actualResponseBody, "Transaction not in mempool")
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /getMempoolAncestors/:txid w/ verbose=false", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getMempoolAncestors/["53735a4ddb828825d6e3f52d045f4c151b2b3d51d631bc581e62f31184b151d6"%5D?verbose=false'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
assert.equal(actualResponseBody, "Transaction not in mempool")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetMempoolDescendants", () => {
|
||||
it("should GET /getMempoolDescendants/:txid w/ verbose=true", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getMempoolDescendants/["53735a4ddb828825d6e3f52d045f4c151b2b3d51d631bc581e62f31184b151d6"%5D?verbose=true'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
assert.equal(actualResponseBody, "Transaction not in mempool")
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /getMempoolDescendants/:txid w/ verbose=false", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getMempoolDescendants/["53735a4ddb828825d6e3f52d045f4c151b2b3d51d631bc581e62f31184b151d6"%5D?verbose=false'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
assert.equal(actualResponseBody, "Transaction not in mempool")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetMempoolEntry", () => {
|
||||
it("should GET /getMempoolEntry/:txid ", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/getMempoolEntry/["53735a4ddb828825d6e3f52d045f4c151b2b3d51d631bc581e62f31184b151d6"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
// TODO: create a tx send it to mempool. Then spend the utxo in another tx and call that enpoind w/ the 2nd txid.
|
||||
assert.equal(actualResponseBody, "Transaction not in mempool")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetMempoolInfo", () => {
|
||||
it("should GET /getMempoolInfo ", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getMempoolInfo"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"size",
|
||||
"bytes",
|
||||
"usage",
|
||||
"maxmempool",
|
||||
"mempoolminfee"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#BlockchainGetRawMempool", () => {
|
||||
it("should GET /getRawMempool w/ verbose=true", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getRawMempool?verbose=true"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert(actualResponseBody.length > 1)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /getRawMempool w/ verbose=false", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getRawMempool?verbose=false"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert(actualResponseBody.length > 1)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
// TODO - Why is this test failing?
|
||||
// describe("#BlockchainGetTxOut", () => {
|
||||
// it("should GET /getTxOut/:txid/:n w/ verbose=true", done => {
|
||||
// const mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url:
|
||||
// "/getTxOut/ac0e82ea84f93444602a99199dd80793f79a8ece5ac86156d2fff34f0bad44b2/0?verbose=true"
|
||||
// })
|
||||
// const mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require("events").EventEmitter
|
||||
// })
|
||||
// blockchainRoute(mockRequest, mockResponse)
|
||||
//
|
||||
// mockResponse.on("end", () => {
|
||||
// const actualResponseBody = Object.keys(
|
||||
// JSON.parse(mockResponse._getData())
|
||||
// )
|
||||
// assert.deepEqual(actualResponseBody, [
|
||||
// "bestblock",
|
||||
// "confirmations",
|
||||
// "value",
|
||||
// "scriptPubKey",
|
||||
// "coinbase"
|
||||
// ])
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
//
|
||||
// it("should GET /getTxOut/:txid/:n w/ verbose=false", done => {
|
||||
// const mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url:
|
||||
// "/getTxOut/ac0e82ea84f93444602a99199dd80793f79a8ece5ac86156d2fff34f0bad44b2/0?verbose=false"
|
||||
// })
|
||||
// const mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require("events").EventEmitter
|
||||
// })
|
||||
// blockchainRoute(mockRequest, mockResponse)
|
||||
//
|
||||
// mockResponse.on("end", () => {
|
||||
// const actualResponseBody = Object.keys(
|
||||
// JSON.parse(mockResponse._getData())
|
||||
// )
|
||||
// assert.deepEqual(actualResponseBody, [
|
||||
// "bestblock",
|
||||
// "confirmations",
|
||||
// "value",
|
||||
// "scriptPubKey",
|
||||
// "coinbase"
|
||||
// ])
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
|
||||
describe("#BlockchainGetTxOutProof", () => {
|
||||
it("should GET /getTxOutProof/:txid", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/getTxOutProof/53735a4ddb828825d6e3f52d045f4c151b2b3d51d631bc581e62f31184b151d6"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
assert.equal(
|
||||
actualResponseBody.message,
|
||||
"JSON value is not an array as expected"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
//
|
||||
// describe("#BlockchainPreciousBlock", () => {
|
||||
// it("should GET /preciousBlock/:hash", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/preciousBlock/00000000000000000108641af52e01a447b1f9d801571f93a0f20a8cbf80c236"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// blockchainRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = mockResponse._getData();
|
||||
// assert.equal(JSON.parse(actualResponseBody), "null" );
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe("#BlockchainPruneBlockchain", () => {
|
||||
// it("should POST /pruneBlockchain/:height ", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "POST",
|
||||
// url: "/pruneBlockchain/530384"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// blockchainRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = mockResponse._getData();
|
||||
// assert.equal(actualResponseBody, "Cannot prune blocks because node is not in prune mode." );
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe("#BlockchainVerifyChain", () => {
|
||||
// it("should GET /verifyChain", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/verifyChain"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// blockchainRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = JSON.parse(mockResponse._getData());
|
||||
// assert.equal(actualResponseBody, true);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
describe("#BlockchainVerifyTxOutProof", () => {
|
||||
it("should GET /verifyTxOutProof/:proof", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/verifyTxOutProof/53735a4ddb828825d6e3f52d045f4c151b2b3d51d631bc581e62f31184b151d6"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
blockchainRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
assert.equal(
|
||||
actualResponseBody.message,
|
||||
"CDataStream::read(): end of data: iostream error"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,64 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
//const expect = chai.expect;
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const controlRoute = require("../../dist/routes/v1/control")
|
||||
|
||||
describe("#ControlRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'control' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
controlRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "control"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
/*
|
||||
describe("#GetInfo", () => {
|
||||
it("should GET /getInfo", (done) => {
|
||||
let mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getInfo"
|
||||
});
|
||||
let mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require('events').EventEmitter
|
||||
});
|
||||
controlRoute(mockRequest, mockResponse);
|
||||
|
||||
mockResponse.on('end', () => {
|
||||
let actualResponseBody = Object.keys(JSON.parse(mockResponse._getData()));
|
||||
assert.deepEqual(actualResponseBody, [ 'version', 'protocolversion', 'blocks', 'timeoffset', 'connections', 'proxy', 'difficulty', 'testnet', 'paytxfee', 'relayfee', 'errors' ]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
//
|
||||
// describe("#GetMemoryInfo", () => {
|
||||
// it("should GET /getMemoryInfo ", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/getMemoryInfo"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// controlRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = Object.keys(JSON.parse(mockResponse._getData()).locked);
|
||||
// assert.deepEqual(actualResponseBody, [ 'used', 'free', 'total', 'locked', 'chunks_used', 'chunks_free' ]);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
*/
|
||||
})
|
||||
@@ -1,485 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const dataRetrieval = require("../../dist/routes/v1/dataRetrieval")
|
||||
|
||||
describe("#dataRetrievalRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'dataRetrieval' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "dataRetrieval"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#balancesForAddress", () => {
|
||||
it("should GET /balancesForAddress/:address", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/balancesForAddress/bitcoincash:qqnjqejdq77pjqhg2y009fck50wdzzh3mc667y7075"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.deepEqual(actualResponseBody[0], {
|
||||
propertyid: 189,
|
||||
balance: "1.0",
|
||||
reserved: "0.0"
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
/*
|
||||
describe("#balancesForId", () => {
|
||||
it("should GET /balancesForId/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/balancesForId/189"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())[0]
|
||||
//console.log(`actualResponseBody: ${JSON.stringify(actualResponseBody, null, 2)}`)
|
||||
|
||||
assert.deepEqual(actualResponseBody, {
|
||||
address: "bitcoincash:qzgvcvfkupltwn2k8c0y8hddhwffxg7p35s834qcuz",
|
||||
balance: "1.0",
|
||||
reserved: "0.0"
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
*/
|
||||
describe("#balanceAddressAndPropertyId", () => {
|
||||
it("should GET /balance/:address/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/balance/bitcoincash:qqnjqejdq77pjqhg2y009fck50wdzzh3mc667y7075/189"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.deepEqual(actualResponseBody, {
|
||||
balance: "1.0",
|
||||
reserved: "0.0"
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#balancesHash", () => {
|
||||
it("should GET /balancesHash/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/balancesHash/127"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"block",
|
||||
"blockhash",
|
||||
"propertyid",
|
||||
"balanceshash"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#crowdSale", () => {
|
||||
it("should GET /crowdSale/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/crowdSale/190"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"propertyid",
|
||||
"name",
|
||||
"active",
|
||||
"issuer",
|
||||
"propertyiddesired",
|
||||
"precision",
|
||||
"tokensperunit",
|
||||
"earlybonus",
|
||||
"starttime",
|
||||
"deadline",
|
||||
"amountraised",
|
||||
"tokensissued",
|
||||
"addedissuertokens",
|
||||
"closedearly",
|
||||
"maxtokens",
|
||||
"endedtime",
|
||||
"closetx"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#currentConsensusHash", () => {
|
||||
it("should GET /currentConsensusHash", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/currentConsensusHash"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"block",
|
||||
"blockhash",
|
||||
"consensushash"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#grants", () => {
|
||||
it("should GET /grants/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/grants/189"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"propertyid",
|
||||
"name",
|
||||
"issuer",
|
||||
"creationtxid",
|
||||
"totaltokens",
|
||||
"issuances"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
/*
|
||||
describe("#info", () => {
|
||||
it("should GET /info", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/info"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"wormholeversion_int",
|
||||
"wormholeversion",
|
||||
"bitcoincoreversion",
|
||||
"block",
|
||||
"blocktime",
|
||||
"blocktransactions",
|
||||
"totaltrades",
|
||||
"totaltransactions",
|
||||
"alerts"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
*/
|
||||
describe("#payload", () => {
|
||||
it("should GET /payload/:txid", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/payload/709d1346a781e7e0064393c9b3f0e846ee445958946352b5928084e8d9a410cc"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, ["payload", "payloadsize"])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#property", () => {
|
||||
it("should GET /property/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/property/127"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"propertyid",
|
||||
"name",
|
||||
"category",
|
||||
"subcategory",
|
||||
"data",
|
||||
"url",
|
||||
"precision",
|
||||
"issuer",
|
||||
"creationtxid",
|
||||
"fixedissuance",
|
||||
"managedissuance",
|
||||
"totaltokens"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#seedBlocks", () => {
|
||||
it("should GET /seedBlocks/:startBlock/:endBlock", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/seedBlocks/290000/300000"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
/*
|
||||
describe("#STO", () => {
|
||||
it("should GET /STO/:txid", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
//url: "/STO/ac2df919be43fa793ff4955019195481878e0f0cab39834ad911124fdacfc603/*",
|
||||
url: "/STO/744b6b3c287d836814c615b532737c080d07ddb48d891f9b0159196ee910b45c/*",
|
||||
});
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter,
|
||||
});
|
||||
dataRetrieval(mockRequest, mockResponse);
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(JSON.parse(mockResponse._getData()));
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"txid",
|
||||
"fee",
|
||||
"sendingaddress",
|
||||
"ismine",
|
||||
"version",
|
||||
"type_int",
|
||||
"type",
|
||||
"propertyid",
|
||||
"precision",
|
||||
"ecosystem",
|
||||
"category",
|
||||
"subcategory",
|
||||
"propertyname",
|
||||
"data",
|
||||
"url",
|
||||
"amount",
|
||||
"valid",
|
||||
"blockhash",
|
||||
"blocktime",
|
||||
"positioninblock",
|
||||
"block",
|
||||
"confirmations",
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
*/
|
||||
describe("#transaction", () => {
|
||||
it("should GET /transaction/:txid", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
//url: "/transaction/ac2df919be43fa793ff4955019195481878e0f0cab39834ad911124fdacfc603",
|
||||
url:
|
||||
"/transaction/744b6b3c287d836814c615b532737c080d07ddb48d891f9b0159196ee910b45c"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"txid",
|
||||
"fee",
|
||||
"sendingaddress",
|
||||
"ismine",
|
||||
"version",
|
||||
"type_int",
|
||||
"type",
|
||||
"propertyid",
|
||||
"precision",
|
||||
//"ecosystem",
|
||||
//"category",
|
||||
//"subcategory",
|
||||
//"propertyname",
|
||||
//"data",
|
||||
//"url",
|
||||
//"amount",
|
||||
"valid",
|
||||
"blockhash",
|
||||
"blocktime",
|
||||
"positioninblock",
|
||||
"block",
|
||||
"confirmations"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#blockTransactions", () => {
|
||||
it("should GET /blockTransactions/:index", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/blockTransactions/279007"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#pendingTransactions", () => {
|
||||
it("should GET /pendingTransactions", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/pendingTransactions"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.equal(Array.isArray(actualResponseBody), true)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#properties", () => {
|
||||
it("should GET /properties", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/properties"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
dataRetrieval(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"propertyid",
|
||||
"name",
|
||||
"category",
|
||||
"subcategory",
|
||||
"data",
|
||||
"url",
|
||||
"precision"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,44 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
// const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
// const expect = chai.expect;
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const generatingRoute = require("../../dist/routes/v1/generating")
|
||||
|
||||
describe("#GeneratingRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'generating' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
generatingRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "generating"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
//
|
||||
// describe("#GeneratingGenerateToAddress", () => {
|
||||
// it("should POST /generateToAddress/:n/:address ", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "POST",
|
||||
// url: "/generateToAddress/1/qrff52mj0ml4scljzxrex7ses2gst42k9sfz2lftjq"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// generatingRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = mockResponse._getData();
|
||||
// assert.equal(actualResponseBody, "JSON value is not an integer as expected");
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
})
|
||||
@@ -1,24 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const healthCheckRoute = require("../../dist/routes/v1/health-check")
|
||||
|
||||
describe("#HealthCheckRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'winning' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
healthCheckRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "winning"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,114 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
//const expect = chai.expect;
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const miningRoute = require("../../dist/routes/v1/mining")
|
||||
|
||||
describe("#MiningRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'mining' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
miningRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "mining"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
//
|
||||
// describe("#MiningGetBlockTemplate", () => {
|
||||
// it("should GET /getBlockTemplate", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/getBlockTemplate/{}"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// miningRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = mockResponse._getData();
|
||||
// assert.equal(actualResponseBody, 'JSON value is not an object as expected');
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
describe("#MiningGetMiningInfo", () => {
|
||||
it("should GET /getMiningInfo", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getMiningInfo"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
miningRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"blocks",
|
||||
"currentblocksize",
|
||||
"currentblocktx",
|
||||
"difficulty",
|
||||
"blockprioritypercentage",
|
||||
"errors",
|
||||
"networkhashps",
|
||||
"pooledtx",
|
||||
"chain"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#MiningGetNetworkHashps", () => {
|
||||
it("should GET /getNetworkHashps", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/getNetworkHashps"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
miningRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = parseInt(mockResponse._getData())
|
||||
assert.equal(typeof actualResponseBody, "number")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
//
|
||||
// describe("#MiningSubmitBlock", () => {
|
||||
// it("should POST /SubmitBlock", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "POST",
|
||||
// url: "/submitBlock/000000000000000000df19ff517463e288aca3de261ece7d53f97da65f9b7b8d"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// miningRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = mockResponse._getData();
|
||||
// assert.equal(actualResponseBody, "Block decode failed");
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
})
|
||||
@@ -1,120 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
//const expect = chai.expect;
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const networkRoute = require("../../dist/routes/v1/network")
|
||||
|
||||
describe("#NetworkRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'network' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
networkRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "network"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
//
|
||||
// describe("#NetworkGetConnectionCount", () => {
|
||||
// it("should GET /getConnectionCount ", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/getConnectionCount"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// networkRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = parseInt(mockResponse._getData());
|
||||
// assert.equal(typeof actualResponseBody, "number");
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe("#NetworkGetNetTotals", () => {
|
||||
// it("should GET /getNetTotals ", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/getNetTotals"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// networkRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = Object.keys(JSON.parse(mockResponse._getData()));
|
||||
// assert.deepEqual(actualResponseBody, [ 'totalbytesrecv', 'totalbytessent', 'timemillis', 'uploadtarget' ]);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe("#NetworkGetNetworkInfo", () => {
|
||||
// it("should GET /getNetworkInfo", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/getNetworkInfo"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// networkRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = Object.keys(JSON.parse(mockResponse._getData()));
|
||||
// assert.deepEqual(actualResponseBody, [ 'version', 'subversion', 'protocolversion', 'localservices', 'localrelay', 'timeoffset', 'networkactive', 'connections', 'networks', 'relayfee', 'incrementalfee', 'localaddresses', 'warnings' ]);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe("#NetworkGetPeerInfo", () => {
|
||||
// it("should GET /getPeerInfo", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/getPeerInfo"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// networkRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = Object.keys(JSON.parse(mockResponse._getData())[0]);
|
||||
// assert.deepEqual(actualResponseBody, [ 'id', 'addr', 'addrlocal', 'services', 'relaytxes', 'lastsend', 'lastrecv', 'bytessent', 'bytesrecv', 'conntime', 'timeoffset', 'pingtime', 'minping', 'version', 'subver', 'inbound', 'addnode', 'startingheight', 'banscore', 'synced_headers', 'synced_blocks', 'inflight', 'whitelisted', 'bytessent_per_msg', 'bytesrecv_per_msg' ]);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe("#NetworkPing", () => {
|
||||
// it("should GET /ping", (done) => {
|
||||
// let mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url: "/ping"
|
||||
// });
|
||||
// let mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require('events').EventEmitter
|
||||
// });
|
||||
// networkRoute(mockRequest, mockResponse);
|
||||
//
|
||||
// mockResponse.on('end', () => {
|
||||
// let actualResponseBody = JSON.parse(mockResponse._getData());
|
||||
// assert.equal(actualResponseBody, 'null');
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
})
|
||||
@@ -1,308 +0,0 @@
|
||||
"use strict"
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const payloadCreation = require("../../dist/routes/v1/payloadCreation")
|
||||
|
||||
describe("#payloadCreationRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'payloadCreation' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "payloadCreation"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#burnBCH", () => {
|
||||
it("should GET /burnBCH", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/burnBCH"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(actualResponseBody, "00000044")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#changeIssuer", () => {
|
||||
it("should POST /changeIssuer/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url: "/changeIssuer/3"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(actualResponseBody, "0000004600000003")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#closeCrowdSale", () => {
|
||||
it("should POST /closeCrowdSale/:propertyId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url: "/closeCrowdSale/70"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(actualResponseBody, "0000003500000046")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#grant", () => {
|
||||
it("should POST /grant/:propertyId/:amount", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url: "/grant/189/7000"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
|
||||
assert.equal(actualResponseBody, "00000037000000bd000000000001117000")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#crowdsale", () => {
|
||||
// CT 10/25/18: This test is commented out because I can't figure out how to
|
||||
// test a thrown error with node-mocks-http. z
|
||||
/*
|
||||
it("should reject invalid date", done => {
|
||||
try {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
"/crowdsale/1/1/0/Companies/Bitcoin-Mining/Quantum-Miner/www.example.com/Quantum -Miner-Tokens/1/100/7308955112/30/0/192978657"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
console.log(
|
||||
`actualResponseBody: ${JSON.stringify(actualResponseBody, null, 2)}`
|
||||
)
|
||||
//assert.equal(
|
||||
// actualResponseBody,
|
||||
// "0000003301000100000000436f6d70616e69657300426974636f696e2d4d696e696e67005175616e74756d2d4d696e6572007777772e6578616d706c652e636f6d005175616e74756d202d4d696e65722d546f6b656e73000000000100000002540be40000000000586846801e0000000000730634ca"
|
||||
//)
|
||||
assert.equal(true, true)
|
||||
done()
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(`Error: ${JSON.stringify(err, null, 2)}`)
|
||||
assert.equal(true, true)
|
||||
done()
|
||||
}
|
||||
})
|
||||
*/
|
||||
|
||||
it("should POST /crowdsale/:ecosystem/:propertyPrecision/:previousId/:category/:subcategory/:name/:url/:data/:propertyIdDesired/:tokensPerUnit/:deadline/:earlyBonus/:undefine/:totalNumber", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
"/crowdsale/1/1/0/Companies/Bitcoin-Mining/Quantum-Miner/www.example.com/Quantum -Miner-Tokens/1/100/1483228800/30/0/192978657"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0000003301000100000000436f6d70616e69657300426974636f696e2d4d696e696e67005175616e74756d2d4d696e6572007777772e6578616d706c652e636f6d005175616e74756d202d4d696e65722d546f6b656e73000000000100000002540be40000000000586846801e0000000000730634ca"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#fixed", () => {
|
||||
it("should POST /fixed/:ecosystem/:propertyPrecision/:previousId/:category/:subcategory/:name/:url/:data/:amount", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
"/fixed/1/1/0/Companies/Bitcoin-Mining/Quantum-Miner/www.example.com/Quantum-Miner-Tokens/1000000"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0000003201000100000000436f6d70616e69657300426974636f696e2d4d696e696e67005175616e74756d2d4d696e6572007777772e6578616d706c652e636f6d005175616e74756d2d4d696e65722d546f6b656e73000000000000989680"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#managed", () => {
|
||||
it("should POST /managed/:ecosystem/:propertyPrecision/:previousId/:category/:subcategory/:name/:url/:data", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url:
|
||||
"/managed/1/1/0/Companies/Bitcoin-Mining/Quantum-Miner/www.example.com/Quantum-Miner-Tokens"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0000003601000100000000436f6d70616e69657300426974636f696e2d4d696e696e67005175616e74756d2d4d696e6572007777772e6578616d706c652e636f6d005175616e74756d2d4d696e65722d546f6b656e7300"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#participateCrowdSale", () => {
|
||||
it("should POST /participateCrowdSale/:amount", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url: "/participateCrowdSale/100.0"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(actualResponseBody, "000000010000000100000002540be400")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#revoke", () => {
|
||||
it("should POST /revoke/:propertyId/:amount", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
//url: "/revoke/3/100", // testnet
|
||||
url: "/revoke/189/100"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
//console.log(`actualResponseBody: ${JSON.stringify(actualResponseBody, null, 2)}`);
|
||||
|
||||
assert.equal(actualResponseBody, "00000038000000bd00000000000003e800")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#sendAll", () => {
|
||||
it("should POST /sendAll/:ecosystem", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
//url: "/sendAll/2", // testnet
|
||||
url: "/sendAll/1" // mainnet
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
//console.log(`actualResponseBody: ${JSON.stringify(actualResponseBody, null, 2)}`);
|
||||
|
||||
assert.equal(actualResponseBody, "0000000401")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#simpleSend", () => {
|
||||
it("should POST /simpleSend/:propertyId/:amount", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url: "/simpleSend/1/100.0"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(actualResponseBody, "000000000000000100000002540be400")
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#STO", () => {
|
||||
it("should POST /STO/:propertyId/:amount", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "POST",
|
||||
url: "/STO/3/5000"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
payloadCreation(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = JSON.parse(mockResponse._getData())
|
||||
assert.equal(
|
||||
actualResponseBody,
|
||||
"0000000300000003000000000000138800000003"
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
-191
@@ -1,191 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const slpRoute = require("../../dist/routes/v1/slp")
|
||||
|
||||
describe("#SlpRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'slp' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
slpRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "slp"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#listTokens", () => {
|
||||
it("should GET /list", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/list"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
slpRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"id",
|
||||
"timestamp",
|
||||
"symbol",
|
||||
"name",
|
||||
"document"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#listTokenById", () => {
|
||||
it("should GET /list/:tokenId", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/list/259908ae44f46ef585edef4bcc1e50dc06e4c391ac4be929fae27235b8158cf1"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
slpRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"id",
|
||||
"timestamp",
|
||||
"symbol",
|
||||
"name",
|
||||
"document"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#balancesForAddress", () => {
|
||||
it("should GET /balancesForAddress/:address", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/balancesForAddress/simpleledger:qz9tzs6d5097ejpg279rg0rnlhz546q4fsnck9wh5m"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
slpRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"satoshis_available",
|
||||
"satoshis_locked_in_minting_baton",
|
||||
"satoshis_locked_in_token",
|
||||
"1cda254d0a995c713b7955298ed246822bee487458cd9747a91d9e81d9d28125",
|
||||
"047918c612e94cce03876f1ad2bd6c9da43b586026811d9b0d02c3c3e910f972",
|
||||
"slpAddress",
|
||||
"cashAddress",
|
||||
"legacyAddress"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#balanceForAddressById", () => {
|
||||
it("should GET /balance/:address/:id", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/balance/simpleledger:qz9tzs6d5097ejpg279rg0rnlhz546q4fsnck9wh5m/1cda254d0a995c713b7955298ed246822bee487458cd9747a91d9e81d9d28125"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
slpRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"id",
|
||||
"timestamp",
|
||||
"symbol",
|
||||
"name",
|
||||
"document",
|
||||
"balance",
|
||||
"slpAddress",
|
||||
"cashAddress",
|
||||
"legacyAddress"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
//
|
||||
// describe("#balancesForToken", () => {
|
||||
// it("should GET /balancesForToken/:tokenId", done => {
|
||||
// const mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url:
|
||||
// "/balancesForToken/d7c32d972a21b664f60b5fc422900179d8883dec7bd61418434aa12b09b99c12"
|
||||
// })
|
||||
// const mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require("events").EventEmitter
|
||||
// })
|
||||
// slpRoute(mockRequest, mockResponse)
|
||||
//
|
||||
// mockResponse.on("end", () => {
|
||||
// const actualResponseBody = Object.keys(
|
||||
// JSON.parse(mockResponse._getData())[0]
|
||||
// )
|
||||
// assert.deepEqual(actualResponseBody, ["balance", "address"])
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
|
||||
// TODO: Why does this test time out?
|
||||
// describe("#addressConvert", () => {
|
||||
// it("should GET /address/convert/:address", done => {
|
||||
// const mockRequest = httpMocks.createRequest({
|
||||
// method: "GET",
|
||||
// url:
|
||||
// "/address/convert/simpleledger:qz9tzs6d5097ejpg279rg0rnlhz546q4fsnck9wh5m"
|
||||
// })
|
||||
// const mockResponse = httpMocks.createResponse({
|
||||
// eventEmitter: require("events").EventEmitter
|
||||
// })
|
||||
// slpRoute(mockRequest, mockResponse)
|
||||
//
|
||||
// mockResponse.on("end", () => {
|
||||
// const actualResponseBody = Object.keys(
|
||||
// JSON.parse(mockResponse._getData())
|
||||
// )
|
||||
// assert.deepEqual(actualResponseBody, [
|
||||
// "slpAddress",
|
||||
// "cashAddress",
|
||||
// "legacyAddress"
|
||||
// ])
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
})
|
||||
@@ -1,96 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const transactionRoute = require("../../dist/routes/v1/transaction")
|
||||
|
||||
describe("#TransactionRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'transaction' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
transactionRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "transaction"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#TransactionDetails", () => {
|
||||
it("should GET /details/:txid single txid", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/details/["78b5847f469f3e96b68c49097261d19c10ca5830c1e883333eb80e9252d9df86"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
transactionRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"txid",
|
||||
"version",
|
||||
"locktime",
|
||||
"vin",
|
||||
"vout",
|
||||
"blockhash",
|
||||
"blockheight",
|
||||
"confirmations",
|
||||
"time",
|
||||
"blocktime",
|
||||
"valueOut",
|
||||
"size",
|
||||
"valueIn",
|
||||
"fees"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("should GET /details/:txid array", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
'/details/["113f1fe1c454a56436d4f93c7c6e315d1ed985d111299e9c2a3e2d3d1e9f177f", "f813f112cadd8b32670486dedcf81b4c2242c967759c9b61dee20b7e0830bb85"%5D'
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
transactionRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())[0]
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"txid",
|
||||
"version",
|
||||
"locktime",
|
||||
"vin",
|
||||
"vout",
|
||||
"blockhash",
|
||||
"blockheight",
|
||||
"confirmations",
|
||||
"time",
|
||||
"blocktime",
|
||||
"valueOut",
|
||||
"size",
|
||||
"valueIn",
|
||||
"fees"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,53 +0,0 @@
|
||||
"use strict"
|
||||
|
||||
//const chai = require("chai");
|
||||
const assert = require("assert")
|
||||
const httpMocks = require("node-mocks-http")
|
||||
const utilRoute = require("../../dist/routes/v1/util")
|
||||
|
||||
describe("#UtilRouter", () => {
|
||||
describe("#root", () => {
|
||||
it("should return 'util' for GET /", () => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url: "/"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse()
|
||||
utilRoute(mockRequest, mockResponse)
|
||||
const actualResponseBody = mockResponse._getData()
|
||||
const expectedResponseBody = {
|
||||
status: "util"
|
||||
}
|
||||
assert.deepEqual(JSON.parse(actualResponseBody), expectedResponseBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#ValidateAddress", () => {
|
||||
it("should GET /validateAddress/:address", done => {
|
||||
const mockRequest = httpMocks.createRequest({
|
||||
method: "GET",
|
||||
url:
|
||||
"/validateAddress/bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c"
|
||||
})
|
||||
const mockResponse = httpMocks.createResponse({
|
||||
eventEmitter: require("events").EventEmitter
|
||||
})
|
||||
utilRoute(mockRequest, mockResponse)
|
||||
|
||||
mockResponse.on("end", () => {
|
||||
const actualResponseBody = Object.keys(
|
||||
JSON.parse(mockResponse._getData())
|
||||
)
|
||||
assert.deepEqual(actualResponseBody, [
|
||||
"isvalid",
|
||||
"address",
|
||||
"scriptPubKey",
|
||||
"ismine",
|
||||
"iswatchonly",
|
||||
"isscript"
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const addressRoute = require("../../dist/routes/v2/address")
|
||||
const addressRoute = require("../../src/routes/v2/address")
|
||||
const nock = require("nock") // HTTP mocking
|
||||
|
||||
let originalUrl // Used during transition from integration to unit tests.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
"use strict"
|
||||
|
||||
const blockRoute = require("../../dist/routes/v2/block")
|
||||
const blockRoute = require("../../src/routes/v2/block")
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const nock = require("nock") // HTTP mocking
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const nock = require("nock") // HTTP mocking
|
||||
const blockchainRoute = require("../../dist/routes/v2/blockchain")
|
||||
const blockchainRoute = require("../../src/routes/v2/blockchain")
|
||||
|
||||
const util = require("util")
|
||||
util.inspect.defaultOptions = { depth: 1 }
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const controlRoute = require("../../dist/routes/v2/control")
|
||||
const controlRoute = require("../../src/routes/v2/control")
|
||||
const nock = require("nock") // HTTP mocking
|
||||
|
||||
let originalEnvVars // Used during transition from integration to unit tests.
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const miningRoute = require("../../dist/routes/v2/mining")
|
||||
const miningRoute = require("../../src/routes/v2/mining")
|
||||
const nock = require("nock") // HTTP mocking
|
||||
|
||||
let originalEnvVars // Used during transition from integration to unit tests.
|
||||
|
||||
@@ -12,8 +12,8 @@ util.inspect.defaultOptions = { depth: 1 }
|
||||
const { mockReq, mockRes, mockNext } = require("./mocks/express-mocks")
|
||||
|
||||
// Libraries under test
|
||||
let rateLimitMiddleware = require("../../dist/middleware/route-ratelimit")
|
||||
const controlRoute = require("../../dist/routes/v2/control")
|
||||
const rateLimitMiddleware = require("../../src/middleware/route-ratelimit")
|
||||
const controlRoute = require("../../src/routes/v2/control")
|
||||
|
||||
let req, res, next
|
||||
let originalEnvVars // Used during transition from integration to unit tests.
|
||||
@@ -43,7 +43,7 @@ describe("#route-ratelimits", () => {
|
||||
})
|
||||
|
||||
describe("#routeRateLimit", () => {
|
||||
let routeRateLimit = rateLimitMiddleware.routeRateLimit
|
||||
const routeRateLimit = rateLimitMiddleware.routeRateLimit
|
||||
const getInfo = controlRoute.testableComponents.getInfo
|
||||
|
||||
it("should pass through rate-limit middleware", async () => {
|
||||
@@ -76,7 +76,7 @@ describe("#route-ratelimits", () => {
|
||||
`next should not be called if rate limit was triggered.`
|
||||
)
|
||||
})
|
||||
|
||||
/*
|
||||
it("should NOT trigger rate-limit handler for pro-tier at 65 RPM", async () => {
|
||||
// Clear the require cache before running this test.
|
||||
delete require.cache[
|
||||
@@ -148,6 +148,7 @@ describe("#route-ratelimits", () => {
|
||||
`next should NOT be called if rate limit was triggered.`
|
||||
)
|
||||
})
|
||||
*/
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const rawtransactions = require("../../dist/routes/v2/rawtransactions")
|
||||
const rawtransactions = require("../../src/routes/v2/rawtransactions")
|
||||
const nock = require("nock") // HTTP mocking
|
||||
|
||||
let originalEnvVars // Used during transition from integration to unit tests.
|
||||
|
||||
+3
-3
@@ -18,9 +18,9 @@ const sinon = require("sinon")
|
||||
const proxyquire = require("proxyquire").noPreserveCache()
|
||||
|
||||
// Prepare the slpRoute for stubbing dependcies on slpjs.
|
||||
const slpRoute = require("../../dist/routes/v2/slp")
|
||||
const slpRoute = require("../../src/routes/v2/slp")
|
||||
const pathStub = {} // Used to stub methods within slpjs.
|
||||
const slpRouteStub = proxyquire("../../dist/routes/v2/slp", { slpjs: pathStub })
|
||||
const slpRouteStub = proxyquire("../../src/routes/v2/slp", { slpjs: pathStub })
|
||||
|
||||
let originalEnvVars // Used during transition from integration to unit tests.
|
||||
|
||||
@@ -913,7 +913,7 @@ describe("#SLP", () => {
|
||||
"57b3082a2bf269b3d6f40fee7fb9c664e8256a88ca5ee2697c05b9457822d446"
|
||||
|
||||
const result = await txDetails(req, res)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.hasAnyKeys(result, ["tokenIsValid", "tokenInfo"])
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const transactionRoute = require("../../dist/routes/v2/transaction")
|
||||
const transactionRoute = require("../../src/routes/v2/transaction")
|
||||
const nock = require("nock") // HTTP mocking
|
||||
|
||||
let originalEnvVars // Used during transition from integration to unit tests.
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const utilRoute = require("../../dist/routes/v2/util")
|
||||
const utilRoute = require("../../src/routes/v2/util")
|
||||
const nock = require("nock") // HTTP mocking
|
||||
|
||||
let originalEnvVars // Used during transition from integration to unit tests.
|
||||
|
||||
Reference in New Issue
Block a user