mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-service.git
synced 2026-09-21 16:52:03 -07:00
feat(transaction): Added transaction endpoint to REST and JSON
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user