feat(transaction): Added transaction endpoint to REST and JSON

This commit is contained in:
Chris Troutner
2021-07-16 10:51:47 -07:00
parent ed82c1102e
commit 7035e1777b
5 changed files with 185 additions and 3 deletions
+43 -1
View File
@@ -44,7 +44,7 @@ class BCHRPC {
// console.log('fulcrumRouter rpcData: ', rpcData)
endpoint = rpcData.payload.params.endpoint
let user
// let user
// Route the call based on the value of the method property.
switch (endpoint) {
@@ -63,6 +63,10 @@ class BCHRPC {
case 'broadcast':
await this.rateLimit.limiter(rpcData.from)
return await this.broadcast(rpcData)
case 'transaction':
await this.rateLimit.limiter(rpcData.from)
return await this.transaction(rpcData)
}
} catch (err) {
console.error('Error in BCHRPC/rpcRouter()')
@@ -231,6 +235,44 @@ class BCHRPC {
}
}
}
/**
* @api {JSON} /bch Transaction
* @apiPermission public
* @apiName Transaction
* @apiGroup JSON BCH
* @apiDescription Get data about a specific transaction.
*
* @apiExample Example usage:
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "transaction", "hex": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"}}
*
*/
async transaction (rpcData) {
try {
// console.log('createUser rpcData: ', rpcData)
const txid = rpcData.payload.params.txid
const data = await this.bchjs.Transaction.get(txid)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
const retObj = data
retObj.status = 200
return retObj
} catch (err) {
// console.error('Error in createUser()')
// throw err
// Return an error response
return {
success: false,
status: 422,
message: err.message,
endpoint: 'transaction'
}
}
}
}
module.exports = BCHRPC
@@ -182,6 +182,44 @@ class BCHRESTController {
}
}
/**
* @api {post} /bch/transaction Transaction
* @apiName Transaction
* @apiGroup REST BCH
* @apiDescription Get data about a specific transaction.
*
* @apiExample Example usage:
* curl -H "Content-Type: application/json" -X POST -d '{ "txid": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098" }' localhost:5001/bch/transaction
*
* @apiSuccessExample {json} Success-Response:
* HTTP/1.1 200 OK
* {
* success:true,
* data: <data>
* }
*
* @apiError UnprocessableEntity Missing required parameters
*
* @apiErrorExample {json} Error-Response:
* HTTP/1.1 422 Unprocessable Entity
* {
* "status": 422,
* "error": "Unprocessable Entity"
* }
*/
async transaction (ctx) {
try {
const txid = ctx.request.body.txid
const data = await _this.bchjs.Transaction.get(txid)
// console.log(`utxos: ${JSON.stringify(utxos, null, 2)}`)
ctx.body = data
} catch (err) {
_this.handleError(ctx, err)
}
}
// DRY error handler
handleError (ctx, err) {
// If an HTTP status is specified by the buisiness logic, use that.
+1
View File
@@ -49,6 +49,7 @@ class BCHRouter {
this.router.post('/balance', this.bchRESTController.balance)
this.router.post('/utxos', this.bchRESTController.utxos)
this.router.post('/broadcast', this.bchRESTController.broadcast)
this.router.post('/transaction', this.bchRESTController.transaction)
// Attach the Controller routes to the Koa app.
app.use(this.router.routes())
@@ -137,6 +137,25 @@ describe('#BCHRPC', () => {
assert.equal(result, true)
})
it('should route to the transaction method', async () => {
// Mock dependencies
sandbox.stub(uut, 'transaction').resolves(true)
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'transaction'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
rpcData.from = 'Origin request'
const result = await uut.bchRouter(rpcData)
assert.equal(result, true)
})
it('should return 500 status on routing issue', async () => {
// Mock dependencies
sandbox.stub(uut, 'transactions').rejects(new Error('test error'))
@@ -316,7 +335,7 @@ describe('#BCHRPC', () => {
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'broadcast',
addresses: 'testData'
hex: 'testData'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
@@ -339,7 +358,7 @@ describe('#BCHRPC', () => {
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'broadcast',
addresses: 'testHex'
hex: 'testHex'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
@@ -353,4 +372,52 @@ describe('#BCHRPC', () => {
assert.equal(response.endpoint, 'broadcast')
})
})
describe('#transaction', () => {
it('should return data from bchjs', async () => {
// Mock dependencies
sandbox.stub(uut.bchjs.Transaction, 'get').resolves({ success: true })
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'transaction',
txid: 'testData'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transaction(rpcData)
// console.log('response: ', response)
assert.equal(response.success, true)
assert.equal(response.status, 200)
})
it('should return an error for invalid input', async () => {
// Force an error
sandbox
.stub(uut.bchjs.Transaction, 'get')
.rejects(new Error('Invalid data'))
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'transaction',
txid: 'testTxid'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transaction(rpcData)
// console.log('response: ', response)
assert.equal(response.success, false)
assert.equal(response.status, 422)
assert.equal(response.message, 'Invalid data')
assert.equal(response.endpoint, 'transaction')
})
})
})
@@ -199,6 +199,40 @@ describe('#BCH-REST-Router', () => {
})
})
describe('#transaction', () => {
it('should return data from bchjs', async () => {
// Mock dependencies
sandbox.stub(uut.bchjs.Transaction, 'get').resolves({ success: true })
ctx.request.body = {
txid: 'testData'
}
await uut.transaction(ctx)
// console.log('ctx.body: ', ctx.body)
assert.equal(ctx.body.success, true)
})
it('should catch and throw an error', async () => {
try {
// Force an error
sandbox
.stub(uut.bchjs.Transaction, 'get')
.rejects(new Error('test error'))
ctx.request.body = {
txid: 'testData'
}
await uut.transaction(ctx)
} catch (err) {
// console.log('err: ', err)
assert.include(err.message, 'test error')
}
})
})
describe('#handleError', () => {
it('should pass an error message', () => {
try {