mirror of
https://github.com/fullstack-cash/bch-api.git
synced 2026-09-22 09:12:05 -07:00
Refactored routes back to JavaScript
This commit is contained in:
+32
-75
@@ -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,13 @@ 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,14 +45,9 @@ 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
|
||||
|
||||
@@ -103,38 +79,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 +109,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 +146,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 +159,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 +180,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 +207,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 +226,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 }
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user