diff --git a/src/controllers/json-rpc/fulcrum/index.js b/src/controllers/json-rpc/fulcrum/index.js index b5a16ed..7e0829d 100644 --- a/src/controllers/json-rpc/fulcrum/index.js +++ b/src/controllers/json-rpc/fulcrum/index.js @@ -123,6 +123,44 @@ class FulcrumRPC { } } + /** + * @api {JSON} /fulcrum Balance + * @apiPermission public + * @apiName Balance + * @apiGroup JSON Fulcrum + * @apiDescription This endpoint wraps the bchjs.Electrumx.balance([]) function. + * + * @apiExample Example usage: + * {"jsonrpc":"2.0","id":"555","method":"fulcrum","params":{ "endpoint": "balance", "addresses": ["bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj"]}} + * + */ + async balance (rpcData) { + try { + // console.log('createUser rpcData: ', rpcData) + + const addrs = rpcData.payload.params.addresses + + const data = await this.bchjs.Electrumx.balance(addrs) + // 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: 'balance' + } + } + } + // TODO create deleteUser() } diff --git a/src/controllers/rest-api/fulcrum/controller.js b/src/controllers/rest-api/fulcrum/controller.js index db67e1c..8a5839f 100644 --- a/src/controllers/rest-api/fulcrum/controller.js +++ b/src/controllers/rest-api/fulcrum/controller.js @@ -66,6 +66,44 @@ class FulcrumRESTController { } } + /** + * @api {post} /fulcrum/balance Balance + * @apiName Balance + * @apiGroup REST Fulcrum + * @apiDescription This endpoint returns the balance in BCH for an address. + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "addresses": ["bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj"] }' localhost:5001/fulcrum/balance + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * success:true, + * data: + * } + * + * @apiError UnprocessableEntity Missing required parameters + * + * @apiErrorExample {json} Error-Response: + * HTTP/1.1 422 Unprocessable Entity + * { + * "status": 422, + * "error": "Unprocessable Entity" + * } + */ + async balance (ctx) { + try { + const addrs = ctx.request.body.addresses + + const data = await _this.bchjs.Electrumx.balance(addrs) + // console.log(`data: ${JSON.stringify(data, 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. diff --git a/test/unit/controllers/json-rpc/fulcrum.json-rpc.controller.unit.js b/test/unit/controllers/json-rpc/fulcrum.json-rpc.controller.unit.js index 99d33df..eb962b9 100644 --- a/test/unit/controllers/json-rpc/fulcrum.json-rpc.controller.unit.js +++ b/test/unit/controllers/json-rpc/fulcrum.json-rpc.controller.unit.js @@ -144,7 +144,7 @@ describe('#FulcrumRPC', () => { const rpcData = jsonrpc.parse(jsonStr) const response = await uut.transactions(rpcData) - console.log('response: ', response) + // console.log('response: ', response) assert.equal(response.success, false) assert.equal(response.status, 422) @@ -153,96 +153,51 @@ describe('#FulcrumRPC', () => { }) }) - // describe('#authUser', () => { - // it('should return a JWT token if user successfully authenticates', async () => { - // // Generate the parsed data that the main router would pass to this - // // endpoint. - // const id = uid() - // const authCall = jsonrpc.request(id, 'auth', { - // endpoint: 'authUser', - // login: 'test543@test.com', - // password: 'password' - // }) - // const jsonStr = JSON.stringify(authCall, null, 2) - // const rpcData = jsonrpc.parse(jsonStr) - // - // const response = await uut.authUser(rpcData) - // // console.log('response: ', response) - // - // assert.equal(response.endpoint, 'authUser') - // assert.property(response, 'userId') - // // assert.equal(response.userType, 'user') - // assert.property(response, 'userName') - // assert.property(response, 'userEmail') - // assert.property(response, 'apiToken') - // assert.equal(response.status, 200) - // assert.equal(response.success, true) - // assert.property(response, 'message') - // }) - // - // it('should return an error for invalid credentials', async () => { - // // Generate the parsed data that the main router would pass to this - // // endpoint. - // const id = uid() - // const authCall = jsonrpc.request(id, 'auth', { - // endpoint: 'authUser', - // login: 'test543@test.com', - // password: 'badpassword' - // }) - // const jsonStr = JSON.stringify(authCall, null, 2) - // const rpcData = jsonrpc.parse(jsonStr) - // - // // Force an error. - // sandbox - // .stub(uut.userLib, 'authUser') - // .rejects(new Error('Login credential do not match')) - // - // const response = await uut.authUser(rpcData) - // // console.log('response: ', response) - // - // assert.equal(response.success, false) - // assert.equal(response.status, 422) - // assert.equal(response.message, 'Login credential do not match') - // assert.equal(response.endpoint, 'authUser') - // }) - // - // it('should throw an error if login is not provided', async () => { - // // Generate the parsed data that the main router would pass to this - // // endpoint. - // const id = uid() - // const authCall = jsonrpc.request(id, 'auth', { - // endpoint: 'authUser' - // }) - // const jsonStr = JSON.stringify(authCall, null, 2) - // const rpcData = jsonrpc.parse(jsonStr) - // - // const response = await uut.authUser(rpcData) - // // console.log('response: ', response) - // - // assert.equal(response.success, false) - // assert.equal(response.status, 422) - // assert.equal(response.message, 'login must be specified') - // assert.equal(response.endpoint, 'authUser') - // }) - // - // it('should throw an error if password is not provided', async () => { - // // Generate the parsed data that the main router would pass to this - // // endpoint. - // const id = uid() - // const authCall = jsonrpc.request(id, 'auth', { - // endpoint: 'authUser', - // login: 'test543@test.com' - // }) - // const jsonStr = JSON.stringify(authCall, null, 2) - // const rpcData = jsonrpc.parse(jsonStr) - // - // const response = await uut.authUser(rpcData) - // // console.log('response: ', response) - // - // assert.equal(response.success, false) - // assert.equal(response.status, 422) - // assert.equal(response.message, 'password must be specified') - // assert.equal(response.endpoint, 'authUser') - // }) - // }) + describe('#balance', () => { + it('should return data from bchjs', async () => { + // Mock dependencies + sandbox.stub(uut.bchjs.Electrumx, 'balance').resolves({ success: true }) + + // Generate the parsed data that the main router would pass to this + // endpoint. + const id = uid() + const rpcCall = jsonrpc.request(id, 'fulcrum', { + endpoint: 'balance', + addresses: 'testAddr' + }) + const jsonStr = JSON.stringify(rpcCall, null, 2) + const rpcData = jsonrpc.parse(jsonStr) + + const response = await uut.balance(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.Electrumx, 'balance') + .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, 'fulcrum', { + endpoint: 'balance', + addresses: 'testAddr' + }) + const jsonStr = JSON.stringify(rpcCall, null, 2) + const rpcData = jsonrpc.parse(jsonStr) + + const response = await uut.balance(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, 'balance') + }) + }) }) diff --git a/test/unit/controllers/rest-api/fulcrum/fulcrum.rest.controller.unit.js b/test/unit/controllers/rest-api/fulcrum/fulcrum.rest.controller.unit.js index e027740..12aae96 100644 --- a/test/unit/controllers/rest-api/fulcrum/fulcrum.rest.controller.unit.js +++ b/test/unit/controllers/rest-api/fulcrum/fulcrum.rest.controller.unit.js @@ -97,6 +97,40 @@ describe('#Fulcrum-REST-Router', () => { }) }) + describe('#balance', () => { + it('should return data from bchjs', async () => { + // Mock dependencies + sandbox.stub(uut.bchjs.Electrumx, 'balance').resolves({ success: true }) + + ctx.request.body = { + addresses: 'testAddr' + } + + await uut.balance(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.Electrumx, 'balance') + .rejects(new Error('test error')) + + ctx.request.body = { + addresses: 'testAddr' + } + + await uut.balance(ctx) + } catch (err) { + // console.log('err: ', err) + assert.include(err.message, 'test error') + } + }) + }) + describe('#handleError', () => { it('should pass an error message', () => { try {