diff --git a/.gitignore b/.gitignore index c46e8f2..7bae1b2 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,5 @@ node_modules *.swp out/ db/* +multilevel/db/* diff --git a/app.js b/app.js index c13a39e..b55071e 100644 --- a/app.js +++ b/app.js @@ -2,18 +2,16 @@ var ExpressApp = require('./lib/expressapp'); var WsApp = require('./lib/wsapp'); +var config = require('./config'); -var basePath = process.env.BWS_BASE_PATH || '/bws/api'; var port = process.env.BWS_PORT || 3001; -var app = ExpressApp.start({ - basePath: basePath, -}); +var app = ExpressApp.start(config); //app.listen(port); var server = require('http').Server(app); -var ws = WsApp.start(server); +var ws = WsApp.start(server, config); server.listen(port); diff --git a/config.js b/config.js new file mode 100644 index 0000000..c13db93 --- /dev/null +++ b/config.js @@ -0,0 +1,26 @@ +var config = { + basePath: '/bws/api', + disableLogs: false, + BlockchainMonitor: { + livenet: { + name: 'insight', + url: 'https://insight.bitpay.com:443', + }, + testnet: { + name: 'insight', + url: 'https://test-insight.bitpay.com:443', + }, + }, + WalletService: { + storageOpts: { + dbPath: './db', + /* To use multilevel, uncomment this: + multiLevel: { + host: 'localhost', + port: 3002, + }, + */ + }, + }, +}; +module.exports = config; diff --git a/lib/blockchainexplorer.js b/lib/blockchainexplorer.js index 388f3c4..e66f670 100644 --- a/lib/blockchainexplorer.js +++ b/lib/blockchainexplorer.js @@ -14,19 +14,13 @@ function BlockChainExplorer(opts) { $.checkArgument(opts); var provider = opts.provider || 'insight'; var network = opts.network || 'livenet'; + var dfltUrl = network == 'livenet' ? 'https://insight.bitpay.com:443' : + 'https://test-insight.bitpay.com:443'; + var url = opts.url || dfltUrl; var url; switch (provider) { case 'insight': - switch (network) { - default: - case 'livenet': - url = 'https://insight.bitpay.com:443'; - break; - case 'testnet': - url = 'https://test-insight.bitpay.com:443' - break; - } var explorer = new Explorers.Insight(url, network); explorer.getTransactions = _.bind(getTransactionsInsight, explorer, url); explorer.getAddressActivity = _.bind(getAddressActivityInsight, explorer, url); diff --git a/lib/blockchainmonitor.js b/lib/blockchainmonitor.js index 2947e72..4135a05 100644 --- a/lib/blockchainmonitor.js +++ b/lib/blockchainmonitor.js @@ -17,12 +17,16 @@ var BlockchainExplorer = require('./blockchainexplorer'); var Notification = require('./model/notification'); -function BlockchainMonitor() { +function BlockchainMonitor(opts) { + opts = opts || {}; var self = this; this.subscriptions = {}; this.subscriber = {}; - this.subscriber['livenet'] = self._getAddressSubscriber('insight', 'livenet'); - this.subscriber['testnet'] = self._getAddressSubscriber('insight', 'testnet'); + _.each(['livenet', 'testnet'], function(network) { + opts[network] = opts[network] || {}; + self.subscriber[network] = self._getAddressSubscriber( + opts[network].name, network, opts[network].url); + }); }; nodeutil.inherits(BlockchainMonitor, events.EventEmitter); diff --git a/lib/server.js b/lib/server.js index 23cad98..d181d4b 100644 --- a/lib/server.js +++ b/lib/server.js @@ -52,7 +52,7 @@ WalletService.onNotification = function(func) { */ WalletService.initialize = function(opts) { opts = opts || {}; - storage = opts.storage ||  new Storage(); + storage = opts.storage ||  new Storage(opts.storageOpts); blockchainExplorer = opts.blockchainExplorer; initialized = true; }; diff --git a/lib/storage.js b/lib/storage.js index 37db926..32583c8 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -2,6 +2,8 @@ var _ = require('lodash'); var levelup = require('levelup'); +var multilevel = require('multilevel'); +var net = require('net'); var async = require('async'); var $ = require('preconditions').singleton(); var log = require('npmlog'); @@ -16,9 +18,20 @@ var Notification = require('./model/notification'); var Storage = function(opts) { opts = opts || {}; - this.db = opts.db || levelup(opts.dbPath || './db/bws.db', { - valueEncoding: 'json' - }); + this.db = opts.db; + + if (!this.db) { + if (opts.multiLevel) { + this.db = multilevel.client(); + var con = net.connect(opts.multiLevel); + con.pipe(this.db.createRpcStream()).pipe(con); + console.log('Connected to multilevel server at:', opts.multiLevel); + } else { + this.db = levelup(opts.dbPath || './db/bws.db', { + valueEncoding: 'json' + }); + } + } }; var zeroPad = function(x, length) { @@ -134,9 +147,9 @@ Storage.prototype.fetchPendingTxs = function(walletId, cb) { var txs = []; var key = KEY.PENDING_TXP(walletId); this.db.createReadStream({ - gte: key, - lt: key + '~' - }) + gte: key, + lt: key + '~' + }) .on('data', function(data) { txs.push(TxProposal.fromObj(data.value)); }) @@ -170,11 +183,11 @@ Storage.prototype.fetchTxs = function(walletId, opts, cb) { var endkey = KEY.TXP(walletId, opts.maxTs); this.db.createReadStream({ - gt: key, - lt: endkey + '~', - reverse: true, - limit: opts.limit, - }) + gt: key, + lt: endkey + '~', + reverse: true, + limit: opts.limit, + }) .on('data', function(data) { txs.push(TxProposal.fromObj(data.value)); }) @@ -207,11 +220,11 @@ Storage.prototype.fetchNotifications = function(walletId, opts, cb) { var endkey = KEY.NOTIFICATION(walletId, opts.maxTs); this.db.createReadStream({ - gt: key, - lt: endkey + '~', - reverse: opts.reverse, - limit: opts.limit, - }) + gt: key, + lt: endkey + '~', + reverse: opts.reverse, + limit: opts.limit, + }) .on('data', function(data) { txs.push(Notification.fromObj(data.value)); }) @@ -271,9 +284,9 @@ Storage.prototype._delByKey = function(key, cb) { var self = this; var keys = []; this.db.createKeyStream({ - gte: key, - lt: key + '~', - }) + gte: key, + lt: key + '~', + }) .on('data', function(key) { keys.push(key); }) @@ -328,9 +341,9 @@ Storage.prototype.fetchAddresses = function(walletId, cb) { var addresses = []; var key = KEY.ADDRESS(walletId); this.db.createReadStream({ - gte: key, - lt: key + '~' - }) + gte: key, + lt: key + '~' + }) .on('data', function(data) { addresses.push(Address.fromObj(data.value)); }) diff --git a/lib/wsapp.js b/lib/wsapp.js index 2a56a38..200bbf3 100644 --- a/lib/wsapp.js +++ b/lib/wsapp.js @@ -32,10 +32,9 @@ WsApp.handleNotification = function(service, notification) { io.to(notification.walletId).emit('notification', notification); }; -WsApp.start = function(server) { +WsApp.start = function(server, config) { io = require('socket.io')(server); - - bcMonitor = new BlockchainMonitor(); + bcMonitor = new BlockchainMonitor(config.BlockchainMonitor); function handleNotification(notification) { if (notification.type == 'NewAddress') { diff --git a/multilevel/start.js b/multilevel/start.js new file mode 100755 index 0000000..591ccd2 --- /dev/null +++ b/multilevel/start.js @@ -0,0 +1,14 @@ +var multilevel = require('multilevel'); +var net = require('net'); +var level = require('levelup'); + +var db = level('./db', { + valueEncoding: 'json' +}); +var PORT = 3002; + + +console.log('Server started at port ' + PORT + '...'); +net.createServer(function(con) { + con.pipe(multilevel.server(db)).pipe(con); +}).listen(PORT); diff --git a/package.json b/package.json index c40eca6..dffaa0d 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "lodash": "^3.3.1", "mocha-lcov-reporter": "0.0.1", "morgan": "*", + "multilevel": "^6.1.0", "npmlog": "^0.1.1", "preconditions": "^1.0.7", "read": "^1.0.5",