From 8dbc5c3e40f811948f89a97984904818baae7114 Mon Sep 17 00:00:00 2001 From: ethan Date: Thu, 28 Oct 2021 18:25:14 +1100 Subject: [PATCH 1/3] Added a getCurrencyInfo endpoint to v4 and v5 routes --- src/routes/v4/util.js | 50 +++++++++++++++++++++++++++++++++++++++++++ src/routes/v5/util.js | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/src/routes/v4/util.js b/src/routes/v4/util.js index e3d20a72..aa824e2e 100644 --- a/src/routes/v4/util.js +++ b/src/routes/v4/util.js @@ -59,6 +59,7 @@ class UtilRoute { this.router.get('/validateAddress/:address', this.validateAddressSingle) this.router.post('/validateAddress', this.validateAddressBulk) this.router.post('/sweep', this.sweepWif) + this.router.get('/getCurrencyInfo', this.getCurrencyInfo) _this = this } @@ -67,6 +68,55 @@ class UtilRoute { return res.json({ status: 'util' }) } + /** + * @api {get} /util/getCurrencyInfo Get information about the currency. + * @apiName getCurrencyInfo + * @apiGroup Util + * @apiDescription Returns an object containing information about the currency. + * + * + * @apiExample Example usage: + * curl -X GET "https://api.fullstack.cash/v4/util/getCurrencyInfo" -H "accept: application/json" + * + * + */ + async getCurrencyInfo (req, res, next) { + try { + + const { + BitboxHTTP, + // username, + // password, + requestConfig + } = routeUtils.setEnvVars() + + requestConfig.data.id = 'getcurrencyinfo' + requestConfig.data.method = 'getcurrencyinfo' + + const response = await BitboxHTTP(requestConfig) + + if (response.data.result.satoshisperunit === 100) { + response.data.result.ecash = 1; + } else { + response.data.result.ecash = 0; + } + + return res.json(response.data.result) + } catch (err) { + // Attempt to decode the error message. + const { msg, status } = routeUtils.decodeError(err) + if (msg) { + res.status(status) + return res.json({ error: msg }) + } + + wlogger.error('Error in util.ts/getCurrencyInfo().', err) + + res.status(500) + return res.json({ error: util.inspect(err) }) + } + } + /** * @api {get} /util/validateAddress/{address} Get information about single bitcoin cash address. * @apiName Information about single bitcoin cash address diff --git a/src/routes/v5/util.js b/src/routes/v5/util.js index 82b15357..039e781d 100644 --- a/src/routes/v5/util.js +++ b/src/routes/v5/util.js @@ -39,6 +39,7 @@ class UtilRoute { this.router.get('/', this.root) this.router.get('/validateAddress/:address', this.validateAddressSingle) this.router.post('/validateAddress', this.validateAddressBulk) + this.router.get('/getCurrencyInfo', this.getCurrencyInfo) // this.router.post('/sweep', this.sweepWif) // _this = this @@ -48,6 +49,55 @@ class UtilRoute { return res.json({ status: 'util' }) } + /** + * @api {get} /util/getCurrencyInfo Get information about the currency. + * @apiName getCurrencyInfo + * @apiGroup Util + * @apiDescription Returns an object containing information about the currency. + * + * + * @apiExample Example usage: + * curl -X GET "https://api.fullstack.cash/v5/util/getCurrencyInfo" -H "accept: application/json" + * + * + */ + async getCurrencyInfo (req, res, next) { + try { + + const { + BitboxHTTP, + // username, + // password, + requestConfig + } = routeUtils.setEnvVars() + + requestConfig.data.id = 'getcurrencyinfo' + requestConfig.data.method = 'getcurrencyinfo' + + const response = await BitboxHTTP(requestConfig) + + if (response.data.result.satoshisperunit === 100) { + response.data.result.ecash = 1; + } else { + response.data.result.ecash = 0; + } + + return res.json(response.data.result) + } catch (err) { + // Attempt to decode the error message. + const { msg, status } = routeUtils.decodeError(err) + if (msg) { + res.status(status) + return res.json({ error: msg }) + } + + wlogger.error('Error in util.ts/getCurrencyInfo().', err) + + res.status(500) + return res.json({ error: util.inspect(err) }) + } + } + /** * @api {get} /util/validateAddress/{address} Get information about single bitcoin cash address. * @apiName Information about single bitcoin cash address From 45887fb24b218bfebfc983f0f55e15d7688d441b Mon Sep 17 00:00:00 2001 From: ethan Date: Thu, 28 Oct 2021 18:25:14 +1100 Subject: [PATCH 2/3] Added a getCurrencyInfo endpoint to v4 and v5 routes --- src/routes/v4/util.js | 44 +++++++++++++++++++++++++++++++++++++++++++ src/routes/v5/util.js | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/src/routes/v4/util.js b/src/routes/v4/util.js index e3d20a72..bd266374 100644 --- a/src/routes/v4/util.js +++ b/src/routes/v4/util.js @@ -59,6 +59,7 @@ class UtilRoute { this.router.get('/validateAddress/:address', this.validateAddressSingle) this.router.post('/validateAddress', this.validateAddressBulk) this.router.post('/sweep', this.sweepWif) + this.router.get('/getCurrencyInfo', this.getCurrencyInfo) _this = this } @@ -67,6 +68,49 @@ class UtilRoute { return res.json({ status: 'util' }) } + /** + * @api {get} /util/getCurrencyInfo Get information about the currency. + * @apiName getCurrencyInfo + * @apiGroup Util + * @apiDescription Returns an object containing information about the currency. + * + * + * @apiExample Example usage: + * curl -X GET "https://api.fullstack.cash/v4/util/getCurrencyInfo" -H "accept: application/json" + * + * + */ + async getCurrencyInfo (req, res, next) { + try { + + const { + BitboxHTTP, + // username, + // password, + requestConfig + } = routeUtils.setEnvVars() + + requestConfig.data.id = 'getcurrencyinfo' + requestConfig.data.method = 'getcurrencyinfo' + + const response = await BitboxHTTP(requestConfig) + + return res.json(response.data.result) + } catch (err) { + // Attempt to decode the error message. + const { msg, status } = routeUtils.decodeError(err) + if (msg) { + res.status(status) + return res.json({ error: msg }) + } + + wlogger.error('Error in util.ts/getCurrencyInfo().', err) + + res.status(500) + return res.json({ error: util.inspect(err) }) + } + } + /** * @api {get} /util/validateAddress/{address} Get information about single bitcoin cash address. * @apiName Information about single bitcoin cash address diff --git a/src/routes/v5/util.js b/src/routes/v5/util.js index 82b15357..48c58978 100644 --- a/src/routes/v5/util.js +++ b/src/routes/v5/util.js @@ -39,6 +39,7 @@ class UtilRoute { this.router.get('/', this.root) this.router.get('/validateAddress/:address', this.validateAddressSingle) this.router.post('/validateAddress', this.validateAddressBulk) + this.router.get('/getCurrencyInfo', this.getCurrencyInfo) // this.router.post('/sweep', this.sweepWif) // _this = this @@ -48,6 +49,49 @@ class UtilRoute { return res.json({ status: 'util' }) } + /** + * @api {get} /util/getCurrencyInfo Get information about the currency. + * @apiName getCurrencyInfo + * @apiGroup Util + * @apiDescription Returns an object containing information about the currency. + * + * + * @apiExample Example usage: + * curl -X GET "https://api.fullstack.cash/v5/util/getCurrencyInfo" -H "accept: application/json" + * + * + */ + async getCurrencyInfo (req, res, next) { + try { + + const { + BitboxHTTP, + // username, + // password, + requestConfig + } = routeUtils.setEnvVars() + + requestConfig.data.id = 'getcurrencyinfo' + requestConfig.data.method = 'getcurrencyinfo' + + const response = await BitboxHTTP(requestConfig) + + return res.json(response.data.result) + } catch (err) { + // Attempt to decode the error message. + const { msg, status } = routeUtils.decodeError(err) + if (msg) { + res.status(status) + return res.json({ error: msg }) + } + + wlogger.error('Error in util.ts/getCurrencyInfo().', err) + + res.status(500) + return res.json({ error: util.inspect(err) }) + } + } + /** * @api {get} /util/validateAddress/{address} Get information about single bitcoin cash address. * @apiName Information about single bitcoin cash address From 0c737b119e0f4514b59e1ce82717055003b55b72 Mon Sep 17 00:00:00 2001 From: ethan Date: Mon, 1 Nov 2021 14:13:16 +1100 Subject: [PATCH 3/3] moved endpoint to price library plus unit/integrationt tests --- src/routes/v4/util.js | 44 ------------------------------------ src/routes/v5/price.js | 36 +++++++++++++++++++++++++++++ src/routes/v5/util.js | 44 ------------------------------------ test/v5/integration/price.js | 11 ++++++++- test/v5/mocks/price-mock.js | 7 ++++++ test/v5/price.js | 41 ++++++++++++++++++++++++++++++++- 6 files changed, 93 insertions(+), 90 deletions(-) diff --git a/src/routes/v4/util.js b/src/routes/v4/util.js index bd266374..e3d20a72 100644 --- a/src/routes/v4/util.js +++ b/src/routes/v4/util.js @@ -59,7 +59,6 @@ class UtilRoute { this.router.get('/validateAddress/:address', this.validateAddressSingle) this.router.post('/validateAddress', this.validateAddressBulk) this.router.post('/sweep', this.sweepWif) - this.router.get('/getCurrencyInfo', this.getCurrencyInfo) _this = this } @@ -68,49 +67,6 @@ class UtilRoute { return res.json({ status: 'util' }) } - /** - * @api {get} /util/getCurrencyInfo Get information about the currency. - * @apiName getCurrencyInfo - * @apiGroup Util - * @apiDescription Returns an object containing information about the currency. - * - * - * @apiExample Example usage: - * curl -X GET "https://api.fullstack.cash/v4/util/getCurrencyInfo" -H "accept: application/json" - * - * - */ - async getCurrencyInfo (req, res, next) { - try { - - const { - BitboxHTTP, - // username, - // password, - requestConfig - } = routeUtils.setEnvVars() - - requestConfig.data.id = 'getcurrencyinfo' - requestConfig.data.method = 'getcurrencyinfo' - - const response = await BitboxHTTP(requestConfig) - - return res.json(response.data.result) - } catch (err) { - // Attempt to decode the error message. - const { msg, status } = routeUtils.decodeError(err) - if (msg) { - res.status(status) - return res.json({ error: msg }) - } - - wlogger.error('Error in util.ts/getCurrencyInfo().', err) - - res.status(500) - return res.json({ error: util.inspect(err) }) - } - } - /** * @api {get} /util/validateAddress/{address} Get information about single bitcoin cash address. * @apiName Information about single bitcoin cash address diff --git a/src/routes/v5/price.js b/src/routes/v5/price.js index 8053eee0..7e93c732 100644 --- a/src/routes/v5/price.js +++ b/src/routes/v5/price.js @@ -36,6 +36,7 @@ class Price { this.router.get('/rates', _this.getBCHRate) this.router.get('/bchausd', _this.getBCHAUSD) this.router.get('/bchusd', _this.getBCHUSD) + this.router.get('/getcurrencyinfo', this.getCurrencyInfo) } // DRY error handler. @@ -56,6 +57,41 @@ class Price { return res.json({ status: 'price' }) } + /** + * @api {get} /price/getcurrencyinfo Get information about the currency. + * @apiName getcurrencyinfo + * @apiGroup Price + * @apiDescription Returns an object containing the currency's ticker, satoshisperunit and decimals. + * + * + * @apiExample Example usage: + * curl -X GET "https://api.fullstack.cash/v5/price/getcurrencyinfo" -H "accept: application/json" + * + * + */ + async getCurrencyInfo (req, res, next) { + try { + const { + BitboxHTTP, + // username, + // password, + requestConfig + } = routeUtils.setEnvVars() + + requestConfig.data.id = 'getcurrencyinfo' + requestConfig.data.method = 'getcurrencyinfo' + + const response = await BitboxHTTP(requestConfig) + + return res.json(response.data.result) + } catch (err) { + // Write out error to error log. + wlogger.error('Error in price.js/getCurrencyInfo().', err) + + return _this.errorHandler(err, res) + } + } + /** * @api {get} /price/usd Get the USD price of BCH * @apiName Get the USD price of BCH diff --git a/src/routes/v5/util.js b/src/routes/v5/util.js index 48c58978..82b15357 100644 --- a/src/routes/v5/util.js +++ b/src/routes/v5/util.js @@ -39,7 +39,6 @@ class UtilRoute { this.router.get('/', this.root) this.router.get('/validateAddress/:address', this.validateAddressSingle) this.router.post('/validateAddress', this.validateAddressBulk) - this.router.get('/getCurrencyInfo', this.getCurrencyInfo) // this.router.post('/sweep', this.sweepWif) // _this = this @@ -49,49 +48,6 @@ class UtilRoute { return res.json({ status: 'util' }) } - /** - * @api {get} /util/getCurrencyInfo Get information about the currency. - * @apiName getCurrencyInfo - * @apiGroup Util - * @apiDescription Returns an object containing information about the currency. - * - * - * @apiExample Example usage: - * curl -X GET "https://api.fullstack.cash/v5/util/getCurrencyInfo" -H "accept: application/json" - * - * - */ - async getCurrencyInfo (req, res, next) { - try { - - const { - BitboxHTTP, - // username, - // password, - requestConfig - } = routeUtils.setEnvVars() - - requestConfig.data.id = 'getcurrencyinfo' - requestConfig.data.method = 'getcurrencyinfo' - - const response = await BitboxHTTP(requestConfig) - - return res.json(response.data.result) - } catch (err) { - // Attempt to decode the error message. - const { msg, status } = routeUtils.decodeError(err) - if (msg) { - res.status(status) - return res.json({ error: msg }) - } - - wlogger.error('Error in util.ts/getCurrencyInfo().', err) - - res.status(500) - return res.json({ error: util.inspect(err) }) - } - } - /** * @api {get} /util/validateAddress/{address} Get information about single bitcoin cash address. * @apiName Information about single bitcoin cash address diff --git a/test/v5/integration/price.js b/test/v5/integration/price.js index 0b969881..5e5ce43c 100644 --- a/test/v5/integration/price.js +++ b/test/v5/integration/price.js @@ -11,7 +11,7 @@ const assert = require('chai').assert const util = require('util') util.inspect.defaultOptions = { depth: 1 } -const Price = require('../../../src/routes/v4/price') +const Price = require('../../../src/routes/v5/price') const price = new Price() const { mockReq, mockRes } = require('../mocks/express-mocks') @@ -50,4 +50,13 @@ describe('#price', () => { assert.isNumber(result.usd) }) }) + describe('#getCurrencyInfo', () => { + it('should get the full node currency settings', async () => { + const result = await price.getCurrencyInfo(req, res) + console.log(`result: ${util.inspect(result)}`) + + assert.isNumber(result.satoshisperunit) + assert.isNumber(result.decimals) + }) + }) }) diff --git a/test/v5/mocks/price-mock.js b/test/v5/mocks/price-mock.js index 5bf35690..874b0a18 100644 --- a/test/v5/mocks/price-mock.js +++ b/test/v5/mocks/price-mock.js @@ -235,7 +235,14 @@ const mockCoinexFeed = { message: 'OK' } +const mockCurrencyInfo = { + ticker: 'BCHA', + satoshisperunit: 100000000, + decimals: 8 +} + module.exports = { mockCoinbaseFeed, + mockCurrencyInfo, mockCoinexFeed } diff --git a/test/v5/price.js b/test/v5/price.js index 1e795f98..1ffbca33 100644 --- a/test/v5/price.js +++ b/test/v5/price.js @@ -12,8 +12,9 @@ const chai = require('chai') const assert = chai.assert const sinon = require('sinon') - +const nock = require('nock') // HTTP mocking const Price = require('../../src/routes/v5/price') + let uut // Mocking data. @@ -31,6 +32,7 @@ describe('#PriceRouter', () => { before(() => { // Set default environment variables for unit tests. if (!process.env.TEST) process.env.TEST = 'unit' + process.env.RPC_BASEURL = 'http://fakenode:fakeport' }) // Setup the mocks before each test. @@ -44,12 +46,19 @@ describe('#PriceRouter', () => { req.body = {} req.query = {} + // Activate nock if it's inactive. + if (!nock.isActive()) nock.activate() + sandbox = sinon.createSandbox() uut = new Price() }) afterEach(() => { + // Clean up HTTP mocks. + nock.cleanAll() // clear interceptor list. + nock.restore() + // Restore Sandbox sandbox.restore() }) @@ -343,4 +352,34 @@ describe('#PriceRouter', () => { assert.isNumber(result.usd) }) }) + + describe('#getCurrencyInfo', async () => { + it('should throw 500 when network issues', async () => { + await uut.getCurrencyInfo(req, res) + + assert.isAbove( + res.statusCode, + 499, + 'HTTP status code 500 or greater expected.' + ) + // console.log(res) + assert.include( + res.output.error, + 'Network error: Could not communicate with full node or other external service' + ) + }) + + it('should get the currency settings of the full node', async () => { + // Mock the RPC call for unit tests. + if (process.env.TEST === 'unit') { + // intercept the RPC_BASEURL parameter + nock(`${process.env.RPC_BASEURL}`) + .post((uri) => uri.includes('/')) + .reply(200, { result: mockData.mockCurrencyInfo }) + } + + const result = await uut.getCurrencyInfo(req, res) + assert.hasAllKeys(result, ['ticker', 'satoshisperunit', 'decimals']) + }) + }) })