mirror of
https://github.com/fullstack-cash/bch-api.git
synced 2026-09-22 17:22:04 -07:00
571 lines
21 KiB
JavaScript
571 lines
21 KiB
JavaScript
'use strict'
|
|
|
|
const express = require('express')
|
|
const router = express.Router()
|
|
const axios = require('axios')
|
|
|
|
const RouteUtils = require('../../../util/route-utils')
|
|
const routeUtils = new RouteUtils()
|
|
|
|
const wlogger = require('../../../util/winston-logging')
|
|
|
|
// Used to convert error messages to strings, to safely pass to users.
|
|
const util = require('util')
|
|
util.inspect.defaultOptions = { depth: 1 }
|
|
|
|
let _this
|
|
class RawTransactions {
|
|
constructor () {
|
|
_this = this
|
|
|
|
// Encapsulate external dependencies.
|
|
this.axios = axios
|
|
this.routeUtils = routeUtils
|
|
|
|
// Define Express routes.
|
|
this.router = router
|
|
this.router.get('/', this.root)
|
|
this.router.get(
|
|
'/decodeRawTransaction/:hex',
|
|
this.decodeRawTransactionSingle
|
|
)
|
|
this.router.post('/decodeRawTransaction', this.decodeRawTransactionBulk)
|
|
this.router.get('/decodeScript/:hex', this.decodeScriptSingle)
|
|
this.router.post('/decodeScript', this.decodeScriptBulk)
|
|
this.router.post('/getRawTransaction', this.getRawTransactionBulk)
|
|
this.router.get('/getRawTransaction/:txid', this.getRawTransactionSingle)
|
|
this.router.post('/sendRawTransaction', this.sendRawTransactionBulk)
|
|
this.router.get('/sendRawTransaction/:hex', this.sendRawTransactionSingle)
|
|
}
|
|
|
|
root (req, res, next) {
|
|
return res.json({ status: 'rawtransactions' })
|
|
}
|
|
|
|
// DRY error handler.
|
|
errorHandler (err, res) {
|
|
// Attempt to decode the error message.
|
|
const { msg, status } = _this.routeUtils.decodeError(err)
|
|
if (msg) {
|
|
res.status(status)
|
|
return res.json({ error: msg })
|
|
}
|
|
|
|
res.status(500)
|
|
return res.json({ error: util.inspect(err) })
|
|
}
|
|
|
|
// Decode transaction hex into a JSON object.
|
|
// GET
|
|
/**
|
|
* @api {get} /rawtransactions/decodeRawTransaction/{hex} Decode Single Raw Transaction.
|
|
* @apiName Decode Single Raw Transaction
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription Return a JSON object representing the serialized, hex-encoded transaction.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -X GET "https://api.fullstack.cash/v3/rawtransactions/decodeRawTransaction/02000000010e991f7ccec410f27d333f737f149b5d3be6728687da81072e638aed0063a176010000006b483045022100cd20443b0af090053450bc4ab00d563d4ac5955bb36e0135b00b8a96a19f233302205047f2c70a08c6ef4b76f2d198b33a31d17edfaa7e1e9e865894da0d396009354121024d4e7f522f67105b7bf5f9dbe557e7b2244613fdfcd6fe09304f93877328f6beffffffff02a0860100000000001976a9140ee020c07f39526ac5505c54fa1ab98490979b8388acb5f0f70b000000001976a9143a9b2b0c12fe722fcf653b6ef5dcc38732d6ff5188ac00000000" -H "accept: application/json"
|
|
*/
|
|
async decodeRawTransactionSingle (req, res, next) {
|
|
try {
|
|
const hex = req.params.hex
|
|
|
|
// Throw an error if hex is empty.
|
|
if (!hex || hex === '') {
|
|
res.status(400)
|
|
return res.json({ error: 'hex can not be empty' })
|
|
}
|
|
const options = _this.routeUtils.getAxiosOptions()
|
|
|
|
options.data.id = 'decoderawtransaction'
|
|
options.data.method = 'decoderawtransaction'
|
|
options.data.params = [hex]
|
|
|
|
const response = await _this.axios.request(options)
|
|
return res.json(response.data.result)
|
|
} catch (err) {
|
|
// Write out error to error log.
|
|
// logger.error(`Error in rawtransactions/decodeRawTransaction: `, err)
|
|
wlogger.error(
|
|
'Error in rawtransactions.ts/decodeRawTransactionSingle().',
|
|
err
|
|
)
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @api {post} /rawtransactions/decodeRawTransaction Decode Bulk Raw Transactions.
|
|
* @apiName Decode Bulk Raw Transactions
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription Return bulk hex encoded transaction.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -X POST "https://api.fullstack.cash/v3/rawtransactions/decodeRawTransaction" -H "accept: application/json" -H "Content-Type: application/json" -d '{"hexes":["01000000013ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000006a4730440220540986d1c58d6e76f8f05501c520c38ce55393d0ed7ed3c3a82c69af04221232022058ea43ed6c05fec0eccce749a63332ed4525460105346f11108b9c26df93cd72012103083dfc5a0254613941ddc91af39ff90cd711cdcde03a87b144b883b524660c39ffffffff01807c814a000000001976a914d7e7c4e0b70eaa67ceff9d2823d1bbb9f6df9a5188ac00000000","01000000013ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000006a4730440220540986d1c58d6e76f8f05501c520c38ce55393d0ed7ed3c3a82c69af04221232022058ea43ed6c05fec0eccce749a63332ed4525460105346f11108b9c26df93cd72012103083dfc5a0254613941ddc91af39ff90cd711cdcde03a87b144b883b524660c39ffffffff01807c814a000000001976a914d7e7c4e0b70eaa67ceff9d2823d1bbb9f6df9a5188ac00000000"]}'
|
|
*
|
|
*
|
|
*/
|
|
async decodeRawTransactionBulk (req, res, next) {
|
|
try {
|
|
const hexes = req.body.hexes
|
|
|
|
if (!Array.isArray(hexes)) {
|
|
res.status(400)
|
|
return res.json({ error: 'hexes must be an array' })
|
|
}
|
|
|
|
// Enforce array size rate limits
|
|
if (!_this.routeUtils.validateArraySize(req, hexes)) {
|
|
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
|
return res.json({
|
|
error: 'Array too large.'
|
|
})
|
|
}
|
|
|
|
// const results = []
|
|
|
|
// Validate each element in the address array.
|
|
for (let i = 0; i < hexes.length; i++) {
|
|
const thisHex = hexes[i]
|
|
|
|
// Reject if id is empty
|
|
if (!thisHex || thisHex === '') {
|
|
res.status(400)
|
|
return res.json({ error: 'Encountered empty hex' })
|
|
}
|
|
}
|
|
|
|
const options = _this.routeUtils.getAxiosOptions()
|
|
|
|
// Loop through each height and creates an array of requests to call in parallel
|
|
const promises = hexes.map(async hex => {
|
|
options.data.id = 'decoderawtransaction'
|
|
options.data.method = 'decoderawtransaction'
|
|
options.data.params = [hex]
|
|
|
|
return _this.axios.request(options)
|
|
})
|
|
|
|
// Wait for all parallel Insight requests to return.
|
|
const axiosResult = await _this.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) {
|
|
// Write out error to error log.
|
|
// logger.error(`Error in rawtransactions/getRawTransaction: `, err)
|
|
wlogger.error(
|
|
'Error in rawtransactions.ts/decodeRawTransactionBulk().',
|
|
err
|
|
)
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
|
|
// Decode a raw transaction from hex to assembly.
|
|
// GET single
|
|
/**
|
|
* @api {get} /rawtransactions/decodeScript/{hex} Decode Single Script.
|
|
* @apiName Decode Single Script
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription Decode a hex-encoded script.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -X GET "https://api.fullstack.cash/v3/rawtransactions/decodeScript/4830450221009a51e00ec3524a7389592bc27bea4af5104a59510f5f0cfafa64bbd5c164ca2e02206c2a8bbb47eabdeed52f17d7df668d521600286406930426e3a9415fe10ed592012102e6e1423f7abde8b70bca3e78a7d030e5efabd3eb35c19302542b5fe7879c1a16" -H "accept: application/json"
|
|
*
|
|
*
|
|
*/
|
|
async decodeScriptSingle (req, res, next) {
|
|
try {
|
|
const hex = req.params.hex
|
|
|
|
// Throw an error if hex is empty.
|
|
if (!hex || hex === '') {
|
|
res.status(400)
|
|
return res.json({ error: 'hex can not be empty' })
|
|
}
|
|
|
|
const options = _this.routeUtils.getAxiosOptions()
|
|
|
|
options.data.id = 'decodescript'
|
|
options.data.method = 'decodescript'
|
|
options.data.params = [hex]
|
|
|
|
const response = await _this.axios.request(options)
|
|
return res.json(response.data.result)
|
|
} catch (err) {
|
|
// Write out error to error log.
|
|
// logger.error(`Error in rawtransactions/decodeScript: `, err)
|
|
wlogger.error('Error in rawtransactions.ts/decodeScriptSingle().', err)
|
|
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
|
|
// Decode a raw transaction from hex to assembly.
|
|
// POST bulk
|
|
/**
|
|
* @api {post} /rawtransactions/decodeScript Bulk Decode Script.
|
|
* @apiName Bulk Decode Script
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription Decode multiple hex-encoded scripts.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
*curl -X POST "https://api.fullstack.cash/v3/rawtransactions/decodeScript" -H "accept:" -H "Content-Type: application/json" -d '{"hexes":["01000000013ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000006a4730440220540986d1c58d6e76f8f05501c520c38ce55393d0ed7ed3c3a82c69af04221232022058ea43ed6c05fec0eccce749a63332ed4525460105346f11108b9c26df93cd72012103083dfc5a0254613941ddc91af39ff90cd711cdcde03a87b144b883b524660c39ffffffff01807c814a000000001976a914d7e7c4e0b70eaa67ceff9d2823d1bbb9f6df9a5188ac00000000","01000000013ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000006a4730440220540986d1c58d6e76f8f05501c520c38ce55393d0ed7ed3c3a82c69af04221232022058ea43ed6c05fec0eccce749a63332ed4525460105346f11108b9c26df93cd72012103083dfc5a0254613941ddc91af39ff90cd711cdcde03a87b144b883b524660c39ffffffff01807c814a000000001976a914d7e7c4e0b70eaa67ceff9d2823d1bbb9f6df9a5188ac00000000"]}'
|
|
*
|
|
*
|
|
*/
|
|
async decodeScriptBulk (req, res, next) {
|
|
try {
|
|
const hexes = req.body.hexes
|
|
|
|
// Validation
|
|
if (!Array.isArray(hexes)) {
|
|
res.status(400)
|
|
return res.json({ error: 'hexes must be an array' })
|
|
}
|
|
|
|
// Enforce array size rate limits
|
|
if (!_this.routeUtils.validateArraySize(req, hexes)) {
|
|
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
|
return res.json({
|
|
error: 'Array too large.'
|
|
})
|
|
}
|
|
|
|
// Validate each hex in the array
|
|
for (let i = 0; i < hexes.length; i++) {
|
|
const hex = hexes[i]
|
|
|
|
// Throw an error if hex is empty.
|
|
if (!hex || hex === '') {
|
|
res.status(400)
|
|
return res.json({ error: 'Encountered empty hex' })
|
|
}
|
|
}
|
|
|
|
const options = _this.routeUtils.getAxiosOptions()
|
|
|
|
// Loop through each hex and create an array of promises
|
|
const promises = hexes.map(async hex => {
|
|
options.data.id = 'decodescript'
|
|
options.data.method = 'decodescript'
|
|
options.data.params = [hex]
|
|
|
|
const response = await _this.axios.request(options)
|
|
return response
|
|
})
|
|
|
|
// Wait for all parallel promises to return.
|
|
const resolved = await Promise.all(promises)
|
|
|
|
// Retrieve the data from each resolved promise.
|
|
const result = resolved.map(x => x.data.result)
|
|
|
|
res.status(200)
|
|
return res.json(result)
|
|
} catch (err) {
|
|
// Write out error to error log.
|
|
// logger.error(`Error in rawtransactions/decodeScript: `, err)
|
|
wlogger.error('Error in rawtransactions.ts/decodeScriptBulk().', err)
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
|
|
// Retrieve raw transactions details from the full node.
|
|
|
|
async getRawTransactionsFromNode (txid, verbose) {
|
|
try {
|
|
const options = _this.routeUtils.getAxiosOptions()
|
|
|
|
options.data.id = 'getrawtransaction'
|
|
options.data.method = 'getrawtransaction'
|
|
options.data.params = [txid, verbose]
|
|
|
|
const response = await _this.axios.request(options)
|
|
|
|
return response.data.result
|
|
} catch (err) {
|
|
wlogger.error('Error in rawtransactions.ts/getRawTransactionsFromNode().')
|
|
throw err
|
|
}
|
|
}
|
|
|
|
// Get a JSON object breakdown of transaction details.
|
|
// POST
|
|
/**
|
|
* @api {post} /rawtransactions/getRawTransaction Get Bulk Raw Transactions.
|
|
* @apiName Get Bulk Raw Transactions.
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription Return the raw transaction data for multiple transactions. If verbose is 'true', returns an Object with information about 'txid'. If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -X POST "https://api.fullstack.cash/v3/rawtransactions/getRawTransaction" -H "accept: application/json" -H "Content-Type: application/json" -d '{"txids":["a5f972572ee1753e2fd2457dd61ce5f40fa2f8a30173d417e49feef7542c96a1","5165dc531aad05d1149bb0f0d9b7bda99c73e2f05e314bcfb5b4bb9ca5e1af5e"],"verbose":true}'
|
|
*
|
|
*/
|
|
async getRawTransactionBulk (req, res, next) {
|
|
try {
|
|
let verbose = 0
|
|
if (req.body.verbose) verbose = 1
|
|
|
|
const txids = req.body.txids
|
|
if (!Array.isArray(txids)) {
|
|
res.status(400)
|
|
return res.json({ error: 'txids must be an array' })
|
|
}
|
|
|
|
// Enforce array size rate limits
|
|
if (!_this.routeUtils.validateArraySize(req, txids)) {
|
|
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
|
return res.json({
|
|
error: 'Array too large.'
|
|
})
|
|
}
|
|
|
|
// stub response object
|
|
// const returnResponse = {
|
|
// status: 100,
|
|
// json: {
|
|
// error: ''
|
|
// }
|
|
// }
|
|
|
|
// Validate each txid in the array.
|
|
for (let i = 0; i < txids.length; i++) {
|
|
const txid = txids[i]
|
|
|
|
if (!txid || txid === '') {
|
|
res.status(400)
|
|
return res.json({ error: 'Encountered empty TXID' })
|
|
}
|
|
|
|
if (txid.length !== 64) {
|
|
res.status(400)
|
|
return res.json({
|
|
error: `parameter 1 must be of length 64 (not ${txid.length})`
|
|
})
|
|
}
|
|
}
|
|
|
|
// Loop through each txid and create an array of promises
|
|
const promises = txids.map(async txid =>
|
|
_this.getRawTransactionsFromNode(txid, verbose)
|
|
)
|
|
|
|
// Wait for all parallel promises to return.
|
|
const axiosResult = await _this.axios.all(promises)
|
|
|
|
res.status(200)
|
|
return res.json(axiosResult)
|
|
} catch (err) {
|
|
// Write out error to error log.
|
|
// logger.error(`Error in rawtransactions/getRawTransaction: `, err)
|
|
wlogger.error('Error in rawtransactions.ts/getRawTransactionBulk().', err)
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
|
|
// Get a JSON object breakdown of transaction details.
|
|
// GET
|
|
/**
|
|
* @api {get} /rawtransactions/getRawTransaction/{txid} Return the raw transaction data.
|
|
* @apiName Get Raw Transaction
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription return the raw transaction data. If verbose is 'true', returns an Object with information about 'txid'. If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -X GET "https://api.fullstack.cash/v3/rawtransactions/getRawTransaction/fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33?verbose=true" -H "accept: application/json"
|
|
*
|
|
*
|
|
*/
|
|
async getRawTransactionSingle (req, res, next) {
|
|
try {
|
|
let verbose = 0
|
|
if (req.query.verbose === 'true') verbose = 1
|
|
|
|
const txid = req.params.txid
|
|
if (!txid || txid === '') {
|
|
res.status(400)
|
|
return res.json({ error: 'txid can not be empty' })
|
|
}
|
|
|
|
if (txid.length !== 64) {
|
|
res.status(400)
|
|
return res.json({
|
|
error: `parameter 1 must be of length 64 (not ${txid.length})`
|
|
})
|
|
}
|
|
|
|
const data = await _this.getRawTransactionsFromNode(txid, verbose)
|
|
|
|
return res.json(data)
|
|
} catch (err) {
|
|
// Write out error to error log.
|
|
// logger.error(`Error in rawtransactions/getRawTransaction: `, err)
|
|
wlogger.error(
|
|
'Error in rawtransactions.ts/getRawTransactionSingle().',
|
|
err
|
|
)
|
|
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
|
|
// Transmit a raw transaction to the BCH network.
|
|
/**
|
|
* @api {post} /rawtransactions/sendRawTransaction Send Bulk Raw Transactions.
|
|
* @apiName Send Bulk Raw Transactions
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription Submits multiple raw transaction (serialized, hex-encoded) to local node and network.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -X POST "https://api.fullstack.cash/v3/rawtransactions/sendRawTransaction" -H "accept:application/json" -H "Content-Type: application/json" -d '{"hexes":["01000000013ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000006a4730440220540986d1c58d6e76f8f05501c520c38ce55393d0ed7ed3c3a82c69af04221232022058ea43ed6c05fec0eccce749a63332ed4525460105346f11108b9c26df93cd72012103083dfc5a0254613941ddc91af39ff90cd711cdcde03a87b144b883b524660c39ffffffff01807c814a000000001976a914d7e7c4e0b70eaa67ceff9d2823d1bbb9f6df9a5188ac00000000","01000000013ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000006a4730440220540986d1c58d6e76f8f05501c520c38ce55393d0ed7ed3c3a82c69af04221232022058ea43ed6c05fec0eccce749a63332ed4525460105346f11108b9c26df93cd72012103083dfc5a0254613941ddc91af39ff90cd711cdcde03a87b144b883b524660c39ffffffff01807c814a000000001976a914d7e7c4e0b70eaa67ceff9d2823d1bbb9f6df9a5188ac00000000"]}'
|
|
*
|
|
*
|
|
*/
|
|
async sendRawTransactionBulk (req, res, next) {
|
|
try {
|
|
// Validation
|
|
const hexes = req.body.hexes
|
|
|
|
// Reject if input is not an array
|
|
if (!Array.isArray(hexes)) {
|
|
res.status(400)
|
|
return res.json({ error: 'hex must be an array' })
|
|
}
|
|
|
|
const options = _this.routeUtils.getAxiosOptions()
|
|
|
|
// Enforce array size rate limits
|
|
if (!_this.routeUtils.validateArraySize(req, hexes)) {
|
|
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
|
return res.json({
|
|
error: 'Array too large.'
|
|
})
|
|
}
|
|
|
|
// Validate each element
|
|
for (let i = 0; i < hexes.length; i++) {
|
|
const hex = hexes[i]
|
|
|
|
if (hex === '') {
|
|
res.status(400)
|
|
return res.json({
|
|
error: 'Encountered empty hex'
|
|
})
|
|
}
|
|
}
|
|
|
|
// Dev Note CT 1/31/2019:
|
|
// Sending the 'sendrawtrnasaction' RPC call to a full node in parallel will
|
|
// not work. Testing showed that the full node will return the same TXID for
|
|
// different TX hexes. I believe this is by design, to prevent double spends.
|
|
// In parallel, we are essentially asking the node to broadcast a new TX before
|
|
// it's finished broadcast the previous one. Serial execution is required.
|
|
|
|
// How to send TX hexes in parallel the WRONG WAY:
|
|
/*
|
|
// Collect an array of promises.
|
|
const promises = hexes.map(async (hex: any) => {
|
|
requestConfig.data.id = "sendrawtransaction"
|
|
requestConfig.data.method = "sendrawtransaction"
|
|
requestConfig.data.params = [hex]
|
|
return await BitboxHTTP(requestConfig)
|
|
})
|
|
// Wait for all parallel Insight requests to return.
|
|
const axiosResult: Array<any> = await axios.all(promises)
|
|
// Retrieve the data part of the result.
|
|
const result = axiosResult.map(x => x.data.result)
|
|
*/
|
|
|
|
// Sending them serially.
|
|
const result = []
|
|
for (let i = 0; i < hexes.length; i++) {
|
|
const hex = hexes[i]
|
|
|
|
options.data.id = 'sendrawtransaction'
|
|
options.data.method = 'sendrawtransaction'
|
|
options.data.params = [hex]
|
|
|
|
const rpcResult = await _this.axios.request(options)
|
|
|
|
result.push(rpcResult.data.result)
|
|
}
|
|
|
|
res.status(200)
|
|
return res.json(result)
|
|
} catch (err) {
|
|
wlogger.error(
|
|
'Error in rawtransactions.ts/sendRawTransactionBulk().',
|
|
err
|
|
)
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
|
|
// Transmit a raw transaction to the BCH network.
|
|
/**
|
|
* @api {get} /rawtransactions/sendRawTransaction/{hex} Send Single Raw Transaction.
|
|
* @apiName Send Single Raw Transaction
|
|
* @apiGroup Raw Transaction
|
|
* @apiDescription Submits single raw transaction (serialized, hex-encoded) to local node and network.
|
|
*
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -X GET "https://api.fullstack.cash/v3/rawtransactions/sendRawTransaction/01000000013ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000006a4730440220540986d1c58d6e76f8f05501c520c38ce55393d0ed7ed3c3a82c69af04221232022058ea43ed6c05fec0eccce749a63332ed4525460105346f11108b9c26df93cd72012103083dfc5a0254613941ddc91af39ff90cd711cdcde03a87b144b883b524660c39ffffffff01807c814a000000001976a914d7e7c4e0b70eaa67ceff9d2823d1bbb9f6df9a5188ac00000000" -H "accept: "
|
|
*
|
|
*
|
|
*/
|
|
async sendRawTransactionSingle (req, res, next) {
|
|
try {
|
|
const hex = req.params.hex // URL parameter
|
|
|
|
// Reject if input is not an array or a string
|
|
if (typeof hex !== 'string') {
|
|
res.status(400)
|
|
return res.json({ error: 'hex must be a string' })
|
|
}
|
|
|
|
// Validation
|
|
if (hex === '') {
|
|
res.status(400)
|
|
return res.json({
|
|
error: 'Encountered empty hex'
|
|
})
|
|
}
|
|
|
|
const options = _this.routeUtils.getAxiosOptions()
|
|
|
|
// RPC call
|
|
options.data.id = 'sendrawtransaction'
|
|
options.data.method = 'sendrawtransaction'
|
|
options.data.params = [hex]
|
|
|
|
const rpcResult = await _this.axios.request(options)
|
|
|
|
const result = rpcResult.data.result
|
|
|
|
res.status(200)
|
|
return res.json(result)
|
|
} catch (err) {
|
|
wlogger.error(
|
|
'Error in rawtransactions.ts/sendRawTransactionSingle().',
|
|
err
|
|
)
|
|
return _this.errorHandler(err, res)
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = RawTransactions
|