From 3601a6ec125eb2161fe3382a6f7b77b2ffc30f7e Mon Sep 17 00:00:00 2001 From: Josh Harvey Date: Fri, 4 Jul 2014 16:29:54 -0400 Subject: [PATCH] api and backwards compat work --- lib/api_response.js | 44 +++++++++++++++++++++++++++++++ lib/routes.js | 63 ++++++++++++++++++++++++--------------------- lib/trader.js | 2 +- 3 files changed, 79 insertions(+), 30 deletions(-) create mode 100644 lib/api_response.js diff --git a/lib/api_response.js b/lib/api_response.js new file mode 100644 index 00000000..1ebcf4a5 --- /dev/null +++ b/lib/api_response.js @@ -0,0 +1,44 @@ +'use strict'; + +var ApiResponse = function(config) { + this.config = config; + this.reponse = config.response; + this.targetVersion = config.targetVersion; + this.version = config.version; +}; + +ApiResponse.factory = function factory(config) { + return new ApiResponse(config); +}; + +module.exports = ApiResponse; + +ApiResponse.prototype.respond = function respond(err, res, statusCodeOpt) { + var statusCode = statusCodeOpt || 200; + if (err) return this.response.json(statusCode, this._buildErr(err)); + this.response.json(statusCode, this._buildResponse(res)); +}; + +ApiResponse.prototype._buildErr = function _buildErr(err) { + // Handle err as either string or error type + var message = err.message || err; + var name = err.name || null; + + if (this.targetVersion < 1) return {err: message, errType: name}; + return {err: { + name: name, + message: message, + version: this.version + } + }; +}; + +ApiResponse.prototype._buildResponse = function _buildResponse(res) { + if (this.targetVersion < 1) { + var fullRes = res; + fullRes = fullRes || {}; + fullRes.err = null; + return fullRes; + } + return {err: null, result: res || null, version: this.version}; +}; \ No newline at end of file diff --git a/lib/routes.js b/lib/routes.js index 86d231c0..76343b1f 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -3,6 +3,7 @@ var _trader; var _lamassuConfig; var logger = require('./logger'); +var ApiResponse = require('./api_response'); // Make sure these are higher than polling interval // or there will be a lot of errors @@ -11,45 +12,43 @@ var STALE_BALANCE = 180000; var API_VERSION = 1; -Error.prototype.toJSON = function () { - var self = this; - var ret = {}; - Object.getOwnPropertyNames(self).forEach(function (key) { - ret[key] = self[key]; +function prepareApi(req, res) { + return ApiResponse.factory({ + response: res, + targetVersion: req.body.version || 0, + version: API_VERSION }); - return ret; -}; +} var poll = function(req, res) { var rateRec = _trader.rate(); var balanceRec = _trader.balance; var fingerprint = req.connection.getPeerCertificate().fingerprint; + var api = prepareApi(req, res); logger.debug('poll request from: %s', fingerprint); // `rateRec` and `balanceRec` are both objects, so there's no danger // of misinterpreting rate or balance === 0 as 'Server initializing'. if (!rateRec || !balanceRec) { - return res.json({err: 'Server initializing'}); + return api.respond('Server initializing'); } var now = Date.now(); if (now - rateRec.timestamp > STALE_TICKER) { - return res.json({err: 'Stale ticker'}); + return api.respond('Stale ticker'); } if (now - balanceRec.timestamp > STALE_BALANCE) { - return res.json({err: 'Stale balance'}); + return api.respond('Stale balance'); } var rate = rateRec.rate; - if (rate === null) return res.json({err: 'No rate available'}); + if (rate === null) return api.respond('No rate available'); var fiatBalance = _trader.fiatBalance(fingerprint); - if (fiatBalance === null) return res.json({err: 'No balance available'}); + if (fiatBalance === null) return api.respond('No balance available'); - res.json({ - err: null, - version: API_VERSION, + api.respond(null, { rate: rate * _trader.config.exchanges.settings.commission, fiat: fiatBalance, locale: _trader.config.brain.locale, @@ -59,28 +58,36 @@ var poll = function(req, res) { var trade = function (req, res) { var fingerprint = req.connection.getPeerCertificate().fingerprint; + var api = prepareApi(req, res); _trader.trade(req.body, fingerprint); - res.json({err: null}); + api.respond(); }; -var event = function (req, res) { +var deviceEvent = function deviceEvent(req, res) { var fingerprint = req.connection.getPeerCertificate().fingerprint; + var api = prepareApi(req, res); _trader.event(req.body, fingerprint); - res.json({err: null}); + api.respond(); +}; + +var idVerify = function idVerify(req, res) { + var fingerprint = req.connection.getPeerCertificate().fingerprint; + var api = prepareApi(req, res); + _idVerifier.idVerify(req.body, fingerprint, function (err, idResult) { + api.respond(err, idResult); + }); }; var send = function(req, res) { var fingerprint = req.connection.getPeerCertificate().fingerprint; + var api = prepareApi(req, res); _trader.sendBitcoins(fingerprint, req.body, function(err, txHash) { - res.json({ - err: err && err.message, - txHash: txHash, - errType: err && err.name - }); + api.respond(err, {txHash: txHash}); }); }; var pair = function(req, res) { + var api = prepareApi(req, res); var token = req.body.token; var name = req.body.name; @@ -89,11 +96,8 @@ var pair = function(req, res) { req.connection.getPeerCertificate().fingerprint, name, function(err) { - if (err) { - return res.json(500, { err: err.message }); - } - - res.json(200); + if (err) return api.respond(err, null, 500); + api.respond(); } ); }; @@ -105,7 +109,8 @@ exports.init = function(app, config, trader, authMiddleware) { app.get('/poll', authMiddleware, poll); app.post('/send', authMiddleware, send); app.post('/trade', authMiddleware, trade); - app.post('/event', authMiddleware, event); + app.post('/event', authMiddleware, deviceEvent); + app.post('/id_verify', authMiddleware, idVerify); app.post('/pair', pair); return app; diff --git a/lib/trader.js b/lib/trader.js index a099dae0..d8d13a70 100644 --- a/lib/trader.js +++ b/lib/trader.js @@ -195,7 +195,7 @@ Trader.prototype.sendBitcoins = function (deviceFingerprint, tx, cb) { }); }; -Trader.prototype.event = function (rec, deviceFingerprint) { +Trader.prototype.deviceEvent = function deviceEvent(rec, deviceFingerprint) { this.db.recordDeviceEvent(deviceFingerprint, rec, function (err) { if (err) logger.error(err); });