bitcore-wallet-service/lib/expressapp.js

787 lines
22 KiB
JavaScript
Raw Normal View History

2015-02-19 06:00:14 -08:00
'use strict';
var _ = require('lodash');
var async = require('async');
var log = require('npmlog');
2015-04-18 02:55:24 -07:00
2015-02-19 06:00:14 -08:00
var express = require('express');
2016-08-09 11:16:45 -07:00
var bodyParser = require('body-parser');
var compression = require('compression');
2016-11-30 05:53:33 -08:00
var RateLimit = require('express-rate-limit');
2015-02-19 06:00:14 -08:00
2016-08-24 04:50:26 -07:00
var Common = require('./common');
var Defaults = Common.Defaults;
2015-02-20 12:32:19 -08:00
var WalletService = require('./server');
2015-05-26 10:59:55 -07:00
var Stats = require('./stats');
2015-02-19 06:00:14 -08:00
2015-04-18 02:55:24 -07:00
log.disableColor();
2015-02-19 06:00:14 -08:00
log.debug = log.verbose;
2017-11-01 07:43:47 -07:00
log.level = 'verbose';
2015-02-19 06:00:14 -08:00
2015-05-07 12:45:17 -07:00
var ExpressApp = function() {
this.app = express();
};
2015-02-19 06:00:14 -08:00
2015-02-21 22:46:47 -08:00
/**
* start
*
* @param opts.WalletService options for WalletService class
* @param opts.basePath
* @param opts.disableLogs
2015-04-21 10:43:35 -07:00
* @param {Callback} cb
2015-02-21 22:46:47 -08:00
*/
2015-05-07 12:45:17 -07:00
ExpressApp.prototype.start = function(opts, cb) {
2015-02-19 06:00:14 -08:00
opts = opts || {};
2016-08-09 11:16:45 -07:00
this.app.use(compression());
2015-05-07 12:45:17 -07:00
this.app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
2015-02-19 06:00:14 -08:00
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'x-signature,x-identity,x-session,x-client-version,x-wallet-id,X-Requested-With,Content-Type,Authorization');
2015-10-19 07:18:26 -07:00
res.setHeader('x-service-version', WalletService.getServiceVersion());
2015-02-19 06:00:14 -08:00
next();
});
var allowCORS = function(req, res, next) {
if ('OPTIONS' == req.method) {
2015-03-06 15:11:28 -08:00
res.sendStatus(200);
2015-02-19 06:00:14 -08:00
res.end();
2015-03-06 15:11:28 -08:00
return;
2015-02-19 06:00:14 -08:00
}
2015-03-06 15:11:28 -08:00
next();
2015-02-19 06:00:14 -08:00
}
2015-05-07 12:45:17 -07:00
this.app.use(allowCORS);
this.app.enable('trust proxy');
2015-02-19 06:00:14 -08:00
2017-04-05 08:02:36 -07:00
// handle `abort` https://nodejs.org/api/http.html#http_event_abort
2017-05-18 07:28:23 -07:00
this.app.use(function(req, res, next) {
2017-04-05 08:02:36 -07:00
req.on('abort', function() {
log.warn('Request aborted by the client');
});
next();
});
2015-02-19 06:00:14 -08:00
var POST_LIMIT = 1024 * 100 /* Max POST 100 kb */ ;
2015-05-07 12:45:17 -07:00
this.app.use(bodyParser.json({
2015-02-19 06:00:14 -08:00
limit: POST_LIMIT
}));
2015-04-18 09:32:21 -07:00
if (opts.disableLogs) {
log.level = 'silent';
} else {
2015-09-29 06:54:06 -07:00
var morgan = require('morgan');
morgan.token('walletId', function getId(req) {
2017-11-01 07:43:47 -07:00
return req.walletId ? '<' + req.walletId + '>' : '<>';
2015-09-29 06:54:06 -07:00
});
2017-11-01 07:43:47 -07:00
var logFormat = ':walletId :remote-addr :date[iso] ":method :url" :status :res[content-length] :response-time ":user-agent" ';
2016-08-02 07:37:43 -07:00
var logOpts = {
skip: function(req, res) {
if (res.statusCode != 200) return false;
return req.path.indexOf('/notifications/') >= 0;
}
};
this.app.use(morgan(logFormat, logOpts));
2015-02-21 22:46:47 -08:00
}
2015-02-19 06:00:14 -08:00
var router = express.Router();
2016-11-30 05:53:33 -08:00
2015-02-19 06:00:14 -08:00
function returnError(err, res, req) {
2015-02-20 12:32:19 -08:00
if (err instanceof WalletService.ClientError) {
2015-02-19 06:00:14 -08:00
2015-08-03 12:11:09 -07:00
var status = (err.code == 'NOT_AUTHORIZED') ? 401 : 400;
2015-02-21 22:46:47 -08:00
if (!opts.disableLogs)
2017-06-27 11:56:09 -07:00
log.info('Client Err: ' + status + ' ' + req.url + ' ' + JSON.stringify(err));
2015-02-21 22:46:47 -08:00
2015-02-19 06:00:14 -08:00
res.status(status).json({
code: err.code,
2015-02-23 09:09:04 -08:00
message: err.message,
2015-02-19 06:00:14 -08:00
}).end();
} else {
2015-10-15 12:30:14 -07:00
var code = 500,
message;
2015-02-19 06:00:14 -08:00
if (_.isObject(err)) {
code = err.code || err.statusCode;
message = err.message || err.body;
2015-02-19 06:00:14 -08:00
}
2015-09-07 20:57:59 -07:00
2015-02-19 06:00:14 -08:00
var m = message || err.toString();
2015-02-21 22:46:47 -08:00
if (!opts.disableLogs)
2015-09-07 20:57:59 -07:00
log.error(req.url + ' :' + code + ':' + m);
2015-02-21 22:46:47 -08:00
2015-02-19 06:00:14 -08:00
res.status(code || 500).json({
error: m,
}).end();
}
};
2016-07-15 08:05:32 -07:00
function logDeprecated(req) {
log.warn('DEPRECATED', req.method, req.url, '(' + req.header('x-client-version') + ')');
};
2015-02-19 06:00:14 -08:00
function getCredentials(req) {
var identity = req.header('x-identity');
if (!identity) return;
return {
copayerId: identity,
signature: req.header('x-signature'),
session: req.header('x-session'),
2015-02-19 06:00:14 -08:00
};
};
2016-01-12 06:45:46 -08:00
function getServer(req, res) {
2017-11-01 07:43:47 -07:00
log.heading = '<>';
2015-06-29 08:20:24 -07:00
var opts = {
clientVersion: req.header('x-client-version'),
};
return WalletService.getInstance(opts);
};
function getServerWithAuth(req, res, opts, cb) {
if (_.isFunction(opts)) {
cb = opts;
opts = {};
}
opts = opts || {};
2015-02-19 06:00:14 -08:00
var credentials = getCredentials(req);
2015-02-19 07:32:10 -08:00
if (!credentials)
2015-02-20 12:32:19 -08:00
return returnError(new WalletService.ClientError({
2015-08-03 12:11:09 -07:00
code: 'NOT_AUTHORIZED'
2015-02-19 07:32:10 -08:00
}), res, req);
2015-02-19 06:00:14 -08:00
var auth = {
copayerId: credentials.copayerId,
message: req.method.toLowerCase() + '|' + req.url + '|' + JSON.stringify(req.body),
signature: credentials.signature,
2015-06-29 08:20:24 -07:00
clientVersion: req.header('x-client-version'),
walletId: req.header('x-wallet-id'),
2015-02-19 06:00:14 -08:00
};
if (opts.allowSession) {
auth.session = credentials.session;
}
2015-02-20 12:32:19 -08:00
WalletService.getInstanceWithAuth(auth, function(err, server) {
2015-02-19 06:00:14 -08:00
if (err) return returnError(err, res, req);
2015-09-29 06:54:06 -07:00
if (opts.onlySupportStaff && !server.copayerIsSupportStaff) {
return returnError(new WalletService.ClientError({
code: 'NOT_AUTHORIZED'
}), res, req);
}
2015-09-29 06:54:06 -07:00
// For logging
req.walletId = server.walletId;
req.copayerId = server.copayerId;
2017-11-01 07:43:47 -07:00
log.heading = '<' + req.walletId + '>';
2015-02-19 06:00:14 -08:00
return cb(server);
});
};
2016-11-30 05:53:33 -08:00
2016-12-01 07:42:35 -08:00
var createWalletLimiter;
2016-11-30 05:53:33 -08:00
2017-03-15 11:37:32 -07:00
if (Defaults.RateLimit.createWallet && !opts.ignoreRateLimiter) {
2016-11-30 05:53:33 -08:00
log.info('', 'Limiting wallet creation per IP: %d req/h', (Defaults.RateLimit.createWallet.max / Defaults.RateLimit.createWallet.windowMs * 60 * 60 * 1000).toFixed(2))
2016-12-01 07:42:35 -08:00
createWalletLimiter = new RateLimit(Defaults.RateLimit.createWallet);
// router.use(/\/v\d+\/wallets\/$/, createWalletLimiter)
} else {
createWalletLimiter = function(req, res, next) {
next()
};
2016-11-30 05:53:33 -08:00
}
2015-09-07 13:18:32 -07:00
// DEPRECATED
2016-12-01 07:42:35 -08:00
router.post('/v1/wallets/', createWalletLimiter, function(req, res) {
2016-07-15 08:05:32 -07:00
logDeprecated(req);
2016-07-13 13:20:55 -07:00
var server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
2015-09-07 13:18:32 -07:00
req.body.supportBIP44AndP2PKH = false;
2015-09-04 20:56:37 -07:00
server.createWallet(req.body, function(err, walletId) {
if (err) return returnError(err, res, req);
res.json({
walletId: walletId,
});
});
});
2016-12-01 07:42:35 -08:00
router.post('/v2/wallets/', createWalletLimiter, function(req, res) {
2016-07-13 13:20:55 -07:00
var server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
2015-02-19 06:00:14 -08:00
server.createWallet(req.body, function(err, walletId) {
if (err) return returnError(err, res, req);
res.json({
walletId: walletId,
});
});
});
2015-08-05 13:25:44 -07:00
router.put('/v1/copayers/:id/', function(req, res) {
req.body.copayerId = req.params['id'];
2016-07-13 13:20:55 -07:00
var server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
2015-08-05 12:54:35 -07:00
server.addAccess(req.body, function(err, result) {
if (err) return returnError(err, res, req);
res.json(result);
});
});
2015-09-07 13:18:32 -07:00
// DEPRECATED
2015-02-19 06:00:14 -08:00
router.post('/v1/wallets/:id/copayers/', function(req, res) {
2016-07-15 08:05:32 -07:00
logDeprecated(req);
2015-02-19 06:00:14 -08:00
req.body.walletId = req.params['id'];
2015-09-10 10:53:21 -07:00
req.body.supportBIP44AndP2PKH = false;
2016-07-13 13:20:55 -07:00
var server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
2015-02-19 06:00:14 -08:00
server.joinWallet(req.body, function(err, result) {
if (err) return returnError(err, res, req);
res.json(result);
});
});
2015-09-07 13:18:32 -07:00
router.post('/v2/wallets/:id/copayers/', function(req, res) {
2015-02-19 06:00:14 -08:00
req.body.walletId = req.params['id'];
2016-07-13 13:20:55 -07:00
var server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
2015-02-19 06:00:14 -08:00
server.joinWallet(req.body, function(err, result) {
if (err) return returnError(err, res, req);
res.json(result);
});
});
2015-08-18 14:23:35 -07:00
// DEPRECATED
2015-02-19 06:00:14 -08:00
router.get('/v1/wallets/', function(req, res) {
2016-07-15 08:05:32 -07:00
logDeprecated(req);
2015-02-19 06:00:14 -08:00
getServerWithAuth(req, res, function(server) {
2015-08-18 14:23:35 -07:00
server.getStatus({
includeExtendedInfo: true
}, function(err, status) {
2015-02-19 06:00:14 -08:00
if (err) return returnError(err, res, req);
2015-08-18 14:23:35 -07:00
res.json(status);
});
});
});
router.get('/v2/wallets/', function(req, res) {
getServerWithAuth(req, res, function(server) {
2015-08-25 14:33:23 -07:00
var opts = {};
if (req.query.includeExtendedInfo == '1') opts.includeExtendedInfo = true;
if (req.query.twoStep == '1') opts.twoStep = true;
2015-09-29 06:54:06 -07:00
2015-08-25 14:33:23 -07:00
server.getStatus(opts, function(err, status) {
2015-08-18 14:23:35 -07:00
if (err) return returnError(err, res, req);
res.json(status);
2015-02-19 06:00:14 -08:00
});
});
});
router.get('/v1/wallets/:identifier/', function(req, res) {
getServerWithAuth(req, res, {
onlySupportStaff: true
}, function(server) {
var opts = {
2017-06-27 11:56:09 -07:00
identifier: req.params['identifier'],
};
server.getWalletFromIdentifier(opts, function(err, wallet) {
if (err) return returnError(err, res, req);
if (!wallet) return res.end();
server.walletId = wallet.id;
var opts = {};
if (req.query.includeExtendedInfo == '1') opts.includeExtendedInfo = true;
if (req.query.twoStep == '1') opts.twoStep = true;
server.getStatus(opts, function(err, status) {
if (err) return returnError(err, res, req);
res.json(status);
});
});
});
});
2015-05-14 08:43:12 -07:00
router.get('/v1/preferences/', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.getPreferences({}, function(err, preferences) {
if (err) return returnError(err, res, req);
res.json(preferences);
});
});
});
router.put('/v1/preferences', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.savePreferences(req.body, function(err, result) {
if (err) return returnError(err, res, req);
res.json(result);
});
});
});
2015-02-19 06:00:14 -08:00
router.get('/v1/txproposals/', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.getPendingTxs({}, function(err, pendings) {
if (err) return returnError(err, res, req);
res.json(pendings);
});
});
});
2016-08-18 09:16:44 -07:00
router.post('/v1/txproposals/', function(req, res) {
var Errors = require('./errors/errordefinitions');
var err = Errors.UPGRADE_NEEDED;
return returnError(err, res, req);
});
2015-11-26 07:52:51 -08:00
router.post('/v2/txproposals/', function(req, res) {
2015-02-19 06:00:14 -08:00
getServerWithAuth(req, res, function(server) {
server.createTx(req.body, function(err, txp) {
if (err) return returnError(err, res, req);
res.json(txp);
});
});
});
2015-10-29 11:28:11 -07:00
// DEPRECATED
2015-02-19 06:00:14 -08:00
router.post('/v1/addresses/', function(req, res) {
2016-07-15 08:05:32 -07:00
logDeprecated(req);
2015-10-29 11:28:11 -07:00
getServerWithAuth(req, res, function(server) {
server.createAddress({
ignoreMaxGap: true
}, function(err, address) {
if (err) return returnError(err, res, req);
res.json(address);
});
});
});
2015-12-09 06:02:50 -08:00
// DEPRECATED
2015-10-29 11:28:11 -07:00
router.post('/v2/addresses/', function(req, res) {
2016-07-15 08:05:32 -07:00
logDeprecated(req);
2015-12-09 06:02:50 -08:00
getServerWithAuth(req, res, function(server) {
server.createAddress({
ignoreMaxGap: true
}, function(err, address) {
if (err) return returnError(err, res, req);
res.json(address);
});
});
});
router.post('/v3/addresses/', function(req, res) {
2015-02-19 06:00:14 -08:00
getServerWithAuth(req, res, function(server) {
server.createAddress(req.body, function(err, address) {
if (err) return returnError(err, res, req);
res.json(address);
});
});
});
router.get('/v1/addresses/', function(req, res) {
getServerWithAuth(req, res, function(server) {
2015-11-04 07:36:39 -08:00
var opts = {};
if (req.query.limit) opts.limit = +req.query.limit;
opts.reverse = (req.query.reverse == '1');
server.getMainAddresses(opts, function(err, addresses) {
2015-02-19 06:00:14 -08:00
if (err) return returnError(err, res, req);
res.json(addresses);
});
});
});
router.get('/v1/balance/', function(req, res) {
getServerWithAuth(req, res, function(server) {
var opts = {};
2017-09-01 07:45:19 -07:00
if (req.query.coin) opts.coin = req.query.coin;
if (req.query.twoStep == '1') opts.twoStep = true;
server.getBalance(opts, function(err, balance) {
2015-12-10 07:45:37 -08:00
if (err) return returnError(err, res, req);
res.json(balance);
});
});
});
2017-10-19 10:52:53 -07:00
var estimateFeeLimiter;
if (Defaults.RateLimit.estimateFee && !opts.ignoreRateLimiter) {
log.info('', 'Limiting estimate fee per IP: %d req/h', (Defaults.RateLimit.estimateFee.max / Defaults.RateLimit.estimateFee.windowMs * 60 * 60 * 1000).toFixed(2))
estimateFeeLimiter = new RateLimit(Defaults.RateLimit.estimateFee);
// router.use(/\/v\d+\/wallets\/$/, createWalletLimiter)
} else {
estimateFeeLimiter = function(req, res, next) {
next()
};
}
// DEPRECATED
2017-10-19 10:52:53 -07:00
router.get('/v1/feelevels/', estimateFeeLimiter, function(req, res) {
2016-07-15 08:05:32 -07:00
logDeprecated(req);
var opts = {};
if (req.query.network) opts.network = req.query.network;
2016-07-13 13:20:55 -07:00
var server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
server.getFeeLevels(opts, function(err, feeLevels) {
if (err) return returnError(err, res, req);
2015-09-10 07:04:49 -07:00
_.each(feeLevels, function(feeLevel) {
feeLevel.feePerKB = feeLevel.feePerKb;
delete feeLevel.feePerKb;
});
res.json(feeLevels);
});
});
2017-10-19 10:52:53 -07:00
router.get('/v2/feelevels/', estimateFeeLimiter, function(req, res) {
2015-07-17 06:32:48 -07:00
var opts = {};
2017-08-27 16:54:43 -07:00
if (req.query.coin) opts.coin = req.query.coin;
2015-07-17 06:32:48 -07:00
if (req.query.network) opts.network = req.query.network;
2017-08-27 16:54:43 -07:00
2016-07-13 13:20:55 -07:00
var server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
2015-07-17 06:32:48 -07:00
server.getFeeLevels(opts, function(err, feeLevels) {
if (err) return returnError(err, res, req);
res.json(feeLevels);
});
});
2016-03-16 12:42:39 -07:00
router.get('/v1/sendmaxinfo/', function(req, res) {
getServerWithAuth(req, res, function(server) {
2016-08-23 10:55:58 -07:00
var q = req.query;
2016-03-16 12:42:39 -07:00
var opts = {};
2016-08-23 10:55:58 -07:00
if (q.feePerKb) opts.feePerKb = +q.feePerKb;
if (q.feeLevel) opts.feeLevel = q.feeLevel;
if (q.excludeUnconfirmedUtxos == '1') opts.excludeUnconfirmedUtxos = true;
if (q.returnInputs == '1') opts.returnInputs = true;
2016-03-16 12:42:39 -07:00
server.getSendMaxInfo(opts, function(err, info) {
if (err) return returnError(err, res, req);
res.json(info);
});
});
});
2015-07-18 02:10:49 -07:00
router.get('/v1/utxos/', function(req, res) {
2015-08-13 10:23:06 -07:00
var opts = {};
var addresses = req.query.addresses;
if (addresses && _.isString(addresses)) opts.addresses = req.query.addresses.split(',');
2015-07-18 02:10:49 -07:00
getServerWithAuth(req, res, function(server) {
2015-08-13 10:23:06 -07:00
server.getUtxos(opts, function(err, utxos) {
2015-07-18 02:10:49 -07:00
if (err) return returnError(err, res, req);
res.json(utxos);
});
});
});
2015-08-13 12:08:27 -07:00
router.post('/v1/broadcast_raw/', function(req, res) {
getServerWithAuth(req, res, function(server) {
2015-08-13 14:13:34 -07:00
server.broadcastRawTx(req.body, function(err, txid) {
2015-08-13 12:08:27 -07:00
if (err) return returnError(err, res, req);
2015-08-13 14:13:34 -07:00
res.json(txid);
2015-08-13 12:08:27 -07:00
res.end();
});
});
});
2015-02-19 06:00:14 -08:00
router.post('/v1/txproposals/:id/signatures/', function(req, res) {
getServerWithAuth(req, res, function(server) {
req.body.txProposalId = req.params['id'];
server.signTx(req.body, function(err, txp) {
if (err) return returnError(err, res, req);
res.json(txp);
res.end();
});
});
});
2015-12-08 07:01:49 -08:00
router.post('/v1/txproposals/:id/publish/', function(req, res) {
2015-11-26 10:18:48 -08:00
getServerWithAuth(req, res, function(server) {
req.body.txProposalId = req.params['id'];
2015-12-08 07:01:49 -08:00
server.publishTx(req.body, function(err, txp) {
2015-11-26 10:18:48 -08:00
if (err) return returnError(err, res, req);
res.json(txp);
res.end();
});
});
});
2015-02-19 06:00:14 -08:00
// TODO Check HTTP verb and URL name
router.post('/v1/txproposals/:id/broadcast/', function(req, res) {
getServerWithAuth(req, res, function(server) {
req.body.txProposalId = req.params['id'];
server.broadcastTx(req.body, function(err, txp) {
if (err) return returnError(err, res, req);
res.json(txp);
res.end();
});
});
});
router.post('/v1/txproposals/:id/rejections', function(req, res) {
getServerWithAuth(req, res, function(server) {
req.body.txProposalId = req.params['id'];
server.rejectTx(req.body, function(err, txp) {
if (err) return returnError(err, res, req);
res.json(txp);
res.end();
});
});
});
router.delete('/v1/txproposals/:id/', function(req, res) {
getServerWithAuth(req, res, function(server) {
req.body.txProposalId = req.params['id'];
server.removePendingTx(req.body, function(err) {
if (err) return returnError(err, res, req);
2015-04-13 06:02:26 -07:00
res.json({
success: true
});
2015-02-19 06:00:14 -08:00
res.end();
});
});
});
2015-04-10 08:37:01 -07:00
router.get('/v1/txproposals/:id/', function(req, res) {
getServerWithAuth(req, res, function(server) {
req.body.txProposalId = req.params['id'];
server.getTx(req.body, function(err, tx) {
if (err) return returnError(err, res, req);
res.json(tx);
res.end();
});
});
});
2015-02-21 19:12:05 -08:00
router.get('/v1/txhistory/', function(req, res) {
getServerWithAuth(req, res, function(server) {
2015-03-17 09:52:49 -07:00
var opts = {};
if (req.query.skip) opts.skip = +req.query.skip;
2015-03-17 16:02:13 -07:00
if (req.query.limit) opts.limit = +req.query.limit;
2016-05-03 08:42:04 -07:00
if (req.query.includeExtendedInfo == '1') opts.includeExtendedInfo = true;
2015-03-17 09:52:49 -07:00
server.getTxHistory(opts, function(err, txs) {
2015-02-21 19:12:05 -08:00
if (err) return returnError(err, res, req);
res.json(txs);
2015-02-22 18:26:21 -08:00
res.end();
2015-02-21 19:12:05 -08:00
});
});
});
2015-04-02 07:28:16 -07:00
router.post('/v1/addresses/scan/', function(req, res) {
getServerWithAuth(req, res, function(server) {
2015-04-04 09:03:19 -07:00
server.startScan(req.body, function(err, started) {
2015-04-02 07:28:16 -07:00
if (err) return returnError(err, res, req);
2015-04-04 09:03:19 -07:00
res.json(started);
2015-04-02 07:28:16 -07:00
res.end();
});
});
});
2015-05-26 10:59:55 -07:00
router.get('/v1/stats/', function(req, res) {
2015-05-07 13:07:29 -07:00
var opts = {};
2015-05-26 10:59:55 -07:00
if (req.query.network) opts.network = req.query.network;
if (req.query.from) opts.from = req.query.from;
if (req.query.to) opts.to = req.query.to;
var stats = new Stats(opts);
stats.run(function(err, data) {
2015-05-04 13:36:49 -07:00
if (err) return returnError(err, res, req);
res.json(data);
res.end();
});
});
router.get('/v1/version/', function(req, res) {
2015-10-15 12:30:14 -07:00
res.json({
2015-10-19 07:18:26 -07:00
serviceVersion: WalletService.getServiceVersion(),
2015-10-15 12:30:14 -07:00
});
res.end();
});
2016-08-10 15:39:08 -07:00
router.post('/v1/login/', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.login({}, function(err, session) {
if (err) return returnError(err, res, req);
res.json(session);
});
});
});
router.post('/v1/logout/', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.logout({}, function(err) {
if (err) return returnError(err, res, req);
res.end();
});
});
});
2015-10-15 12:30:14 -07:00
router.get('/v1/notifications/', function(req, res) {
getServerWithAuth(req, res, {
allowSession: true,
}, function(server) {
2016-08-24 04:50:26 -07:00
var timeSpan = req.query.timeSpan ? Math.min(+req.query.timeSpan || 0, Defaults.MAX_NOTIFICATIONS_TIMESPAN) : Defaults.NOTIFICATIONS_TIMESPAN;
2015-10-15 12:30:14 -07:00
var opts = {
minTs: +Date.now() - (timeSpan * 1000),
2015-10-15 12:30:14 -07:00
notificationId: req.query.notificationId,
};
2016-08-24 04:50:26 -07:00
2015-10-15 12:30:14 -07:00
server.getNotifications(opts, function(err, notifications) {
if (err) return returnError(err, res, req);
res.json(notifications);
});
});
});
2016-06-01 04:44:42 -07:00
router.get('/v1/txnotes/:txid', function(req, res) {
getServerWithAuth(req, res, function(server) {
var opts = {
txid: req.params['txid'],
};
server.getTxNote(opts, function(err, note) {
if (err) return returnError(err, res, req);
res.json(note);
});
});
});
2016-05-17 12:01:32 -07:00
router.put('/v1/txnotes/:txid/', function(req, res) {
req.body.txid = req.params['txid'];
getServerWithAuth(req, res, function(server) {
2016-10-11 12:12:23 -07:00
server.editTxNote(req.body, function(err, note) {
2016-05-17 12:01:32 -07:00
if (err) return returnError(err, res, req);
2016-10-11 12:12:23 -07:00
res.json(note);
2016-05-17 12:01:32 -07:00
});
});
});
2016-05-23 05:55:14 -07:00
router.get('/v1/txnotes/', function(req, res) {
getServerWithAuth(req, res, function(server) {
var opts = {};
if (_.isNumber(+req.query.minTs)) {
opts.minTs = +req.query.minTs;
}
server.getTxNotes(opts, function(err, notes) {
if (err) return returnError(err, res, req);
res.json(notes);
});
});
});
2016-01-07 07:29:47 -08:00
router.get('/v1/fiatrates/:code/', function(req, res) {
var server;
var opts = {
code: req.params['code'],
provider: req.query.provider,
ts: +req.query.ts,
};
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
server.getFiatRate(opts, function(err, rates) {
if (err) return returnError(err, res, req);
res.json(rates);
2016-01-07 07:29:47 -08:00
});
});
router.post('/v1/pushnotifications/subscriptions/', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.pushNotificationsSubscribe(req.body, function(err, response) {
if (err) return returnError(err, res, req);
res.json(response);
});
});
});
2017-02-03 09:35:05 -08:00
// DEPRECATED
2016-01-18 12:37:40 -08:00
router.delete('/v1/pushnotifications/subscriptions/', function(req, res) {
2017-02-03 09:35:05 -08:00
logDeprecated(req);
getServerWithAuth(req, res, function(server) {
server.pushNotificationsUnsubscribe({
token: 'dummy'
}, function(err, response) {
if (err) return returnError(err, res, req);
res.json(response);
});
});
});
router.delete('/v2/pushnotifications/subscriptions/:token', function(req, res) {
var opts = {
token: req.params['token'],
};
getServerWithAuth(req, res, function(server) {
2017-02-03 09:35:05 -08:00
server.pushNotificationsUnsubscribe(opts, function(err, response) {
if (err) return returnError(err, res, req);
res.json(response);
});
});
});
2016-01-07 07:29:47 -08:00
2017-05-18 07:28:23 -07:00
router.post('/v1/txconfirmations/', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.txConfirmationSubscribe(req.body, function(err, response) {
if (err) return returnError(err, res, req);
res.json(response);
});
});
});
router.delete('/v1/txconfirmations/:txid', function(req, res) {
var opts = {
txid: req.params['txid'],
};
getServerWithAuth(req, res, function(server) {
server.txConfirmationUnsubscribe(opts, function(err, response) {
if (err) return returnError(err, res, req);
res.json(response);
});
});
});
2015-05-07 12:45:17 -07:00
this.app.use(opts.basePath || '/bws/api', router);
2015-04-21 10:43:35 -07:00
2015-05-07 12:45:17 -07:00
WalletService.initialize(opts, cb);
2015-05-04 13:36:49 -07:00
2015-02-19 06:00:14 -08:00
};
module.exports = ExpressApp;