mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-service.git
synced 2026-09-21 16:52:03 -07:00
feat(utxos): Added utxos endpoing to REST and JSON RPC
This commit is contained in:
@@ -52,10 +52,13 @@ class BCHRPC {
|
||||
await this.rateLimit.limiter(rpcData.from)
|
||||
return await this.transactions(rpcData)
|
||||
|
||||
// case 'getAllUsers':
|
||||
// await this.validators.ensureUser(rpcData)
|
||||
// await this.rateLimit.limiter(rpcData.from)
|
||||
// return await this.getAll(rpcData)
|
||||
case 'balance':
|
||||
await this.rateLimit.limiter(rpcData.from)
|
||||
return await this.balance(rpcData)
|
||||
|
||||
case 'utxos':
|
||||
await this.rateLimit.limiter(rpcData.from)
|
||||
return await this.utxos(rpcData)
|
||||
//
|
||||
// case 'getUser':
|
||||
// user = await this.validators.ensureUser(rpcData)
|
||||
@@ -161,6 +164,46 @@ class BCHRPC {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {JSON} /bch UTXOs
|
||||
* @apiPermission public
|
||||
* @apiName UTXOs
|
||||
* @apiGroup JSON BCH
|
||||
* @apiDescription This endpoint wraps the bchjs.Utxos.get() function. This
|
||||
* endpoint returns UTXOs held at an address, hydrated
|
||||
* with token information.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "utxos", "address": "bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj"}}
|
||||
*
|
||||
*/
|
||||
async utxos (rpcData) {
|
||||
try {
|
||||
// console.log('createUser rpcData: ', rpcData)
|
||||
|
||||
const addr = rpcData.payload.params.address
|
||||
|
||||
const data = await this.bchjs.Utxo.get(addr)
|
||||
// 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: 'utxos'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO create deleteUser()
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,45 @@ class BCHRESTController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /bch/utxos Balance
|
||||
* @apiName Utxos
|
||||
* @apiGroup REST BCH
|
||||
* @apiDescription This endpoint returns UTXOs held at an address, hydrated
|
||||
* with token information.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* curl -H "Content-Type: application/json" -X POST -d '{ "address": "bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj" }' localhost:5001/bch/utxos
|
||||
*
|
||||
* @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 utxos (ctx) {
|
||||
try {
|
||||
const address = ctx.request.body.address
|
||||
|
||||
const utxos = await _this.bchjs.Utxo.get(address)
|
||||
// console.log(`utxos: ${JSON.stringify(utxos, null, 2)}`)
|
||||
|
||||
ctx.body = utxos
|
||||
} catch (err) {
|
||||
_this.handleError(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
// DRY error handler
|
||||
handleError (ctx, err) {
|
||||
// If an HTTP status is specified by the buisiness logic, use that.
|
||||
|
||||
@@ -47,6 +47,7 @@ class BCHRouter {
|
||||
// Define the routes and attach the controller.
|
||||
this.router.post('/transactions', this.bchRESTController.transactions)
|
||||
this.router.post('/balance', this.bchRESTController.balance)
|
||||
this.router.post('/utxos', this.bchRESTController.utxos)
|
||||
|
||||
// Attach the Controller routes to the Koa app.
|
||||
app.use(this.router.routes())
|
||||
|
||||
@@ -80,6 +80,44 @@ describe('#BCHRPC', () => {
|
||||
assert.equal(result, true)
|
||||
})
|
||||
|
||||
it('should route to the balance method', async () => {
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut, 'balance').resolves(true)
|
||||
|
||||
// Generate the parsed data that the main router would pass to this
|
||||
// endpoint.
|
||||
const id = uid()
|
||||
const txCall = jsonrpc.request(id, 'bch', {
|
||||
endpoint: 'balance'
|
||||
})
|
||||
const jsonStr = JSON.stringify(txCall, null, 2)
|
||||
const rpcData = jsonrpc.parse(jsonStr)
|
||||
rpcData.from = 'Origin request'
|
||||
|
||||
const result = await uut.bchRouter(rpcData)
|
||||
|
||||
assert.equal(result, true)
|
||||
})
|
||||
|
||||
it('should route to the utxos method', async () => {
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut, 'utxos').resolves(true)
|
||||
|
||||
// Generate the parsed data that the main router would pass to this
|
||||
// endpoint.
|
||||
const id = uid()
|
||||
const txCall = jsonrpc.request(id, 'bch', {
|
||||
endpoint: 'utxos'
|
||||
})
|
||||
const jsonStr = JSON.stringify(txCall, 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'))
|
||||
@@ -200,4 +238,50 @@ describe('#BCHRPC', () => {
|
||||
assert.equal(response.endpoint, 'balance')
|
||||
})
|
||||
})
|
||||
|
||||
describe('#utxos', () => {
|
||||
it('should return data from bchjs', async () => {
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.bchjs.Utxo, '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: 'utxos',
|
||||
addresses: 'testAddr'
|
||||
})
|
||||
const jsonStr = JSON.stringify(rpcCall, null, 2)
|
||||
const rpcData = jsonrpc.parse(jsonStr)
|
||||
|
||||
const response = await uut.utxos(rpcData)
|
||||
// console.log('response: ', response)
|
||||
|
||||
assert.equal(response.success, true)
|
||||
assert.equal(response.status, 200)
|
||||
})
|
||||
|
||||
it('should return an error for invalid address', async () => {
|
||||
// Force an error
|
||||
sandbox.stub(uut.bchjs.Utxo, 'get').rejects(new Error('Invalid address'))
|
||||
|
||||
// Generate the parsed data that the main router would pass to this
|
||||
// endpoint.
|
||||
const id = uid()
|
||||
const rpcCall = jsonrpc.request(id, 'bch', {
|
||||
endpoint: 'utxos',
|
||||
addresses: 'testAddr'
|
||||
})
|
||||
const jsonStr = JSON.stringify(rpcCall, null, 2)
|
||||
const rpcData = jsonrpc.parse(jsonStr)
|
||||
|
||||
const response = await uut.utxos(rpcData)
|
||||
// console.log('response: ', response)
|
||||
|
||||
assert.equal(response.success, false)
|
||||
assert.equal(response.status, 422)
|
||||
assert.equal(response.message, 'Invalid address')
|
||||
assert.equal(response.endpoint, 'utxos')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -131,6 +131,38 @@ describe('#BCH-REST-Router', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('#utxos', () => {
|
||||
it('should return data from bchjs', async () => {
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.bchjs.Utxo, 'get').resolves({ success: true })
|
||||
|
||||
ctx.request.body = {
|
||||
addresses: 'testAddr'
|
||||
}
|
||||
|
||||
await uut.utxos(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.Utxo, 'get').rejects(new Error('test error'))
|
||||
|
||||
ctx.request.body = {
|
||||
addresses: 'testAddr'
|
||||
}
|
||||
|
||||
await uut.utxos(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