diff --git a/lib/plugins.js b/lib/plugins.js index 92050280..53fa3a91 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -16,6 +16,13 @@ var POLLING_RATE = 60 * 1000 // poll each minute var REAP_RATE = 2 * 1000 var PENDING_TIMEOUT = 70 * 1000 +var BTC_COIN = { + unitCode: 'BTC', + displayCode: 'mBTC', + unitScale: 8, + displayScale: 5 +} + if (argv.timeout) PENDING_TIMEOUT = argv.timeout / 1000 // TODO: might have to update this if user is allowed to extend monitoring time @@ -114,12 +121,13 @@ function loadPlugin (name, config) { function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCoin, currency, onChangeCallback) { - if (!cryptoCoin) cryptoCoin = 'any' - var currentName = cryptoCoin === 'any' || cryptoCoin === 'BTC' - ? cachedConfig.exchanges.plugins.current[pluginType] - : cachedConfig.exchanges.plugins.current[cryptoCoin][pluginType] + var cryptoCode = cryptoCoin ? cryptoCoin.unitCode : 'any' - var pluginChanged = currentlyUsedPlugins[cryptoCoin][pluginType] !== currentName + var currentName = cryptoCode === 'any' || cryptoCode === 'BTC' + ? cachedConfig.exchanges.plugins.current[pluginType] + : cachedConfig.exchanges.plugins.current[cryptoCode][pluginType] + + var pluginChanged = currentlyUsedPlugins[cryptoCode][pluginType] !== currentName if (!currentName) pluginHandle = null else { // some plugins may be disabled @@ -130,9 +138,9 @@ function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCoin, currency, if (pluginHandle && !pluginChanged) pluginHandle.config(pluginConfig) else { pluginHandle = loadPlugin(currentName, pluginConfig) - currentlyUsedPlugins[cryptoCoin] = currentlyUsedPlugins[cryptoCoin] || {} - currentlyUsedPlugins[cryptoCoin][pluginType] = currentName - logger.debug('[%s] plugin(%s) loaded: %s', cryptoCoin, pluginType, pluginHandle.NAME || + currentlyUsedPlugins[cryptoCode] = currentlyUsedPlugins[cryptoCode] || {} + currentlyUsedPlugins[cryptoCode][pluginType] = currentName + logger.debug('[%s] plugin(%s) loaded: %s', cryptoCode, pluginType, pluginHandle.NAME || currentName) } } @@ -149,29 +157,30 @@ exports.configure = function configure (config) { cachedConfig = config deviceCurrency = config.exchanges.settings.currency - cryptoCoins = config.exchanges.settings.coins || ['BTC'] + cryptoCoins = config.exchanges.settings.coins || [BTC_COIN] cryptoCoins.forEach(function (cryptoCoin) { // TICKER [required] configure (or load) + var cryptoCode = cryptoCoin.unitCode loadOrConfigPlugin( - tickerPlugins[cryptoCoin], + tickerPlugins[cryptoCode], 'ticker', cryptoCoin, deviceCurrency, // device currency function onTickerChange (newTicker) { - tickerPlugins[cryptoCoin] = newTicker + tickerPlugins[cryptoCode] = newTicker pollRate(cryptoCoin) } ) // WALLET [required] configure (or load) loadOrConfigPlugin( - walletPlugins[cryptoCoin], + walletPlugins[cryptoCode], 'transfer', cryptoCoin, null, function onWalletChange (newWallet) { - walletPlugins[cryptoCoin] = newWallet + walletPlugins[cryptoCode] = newWallet pollBalance(cryptoCoin) } ) @@ -240,9 +249,10 @@ exports.pollQueries = function pollQueries (session, cb) { } function _sendCoins (toAddress, cryptoUnits, cryptoCoin, cb) { - var walletPlugin = walletPlugins[cryptoCoin] + var cryptoCode = cryptoCoin.unitCode + var walletPlugin = walletPlugins[cryptoCode] var transactionFee = cachedConfig.exchanges.settings.transactionFee - if (cryptoCoin === 'BTC') { + if (cryptoCode === 'BTC') { walletPlugin.sendBitcoins(toAddress, cryptoUnits, transactionFee, cb) } else { walletPlugin.sendCoins(toAddress, cryptoUnits, cryptoCoin, transactionFee, cb) @@ -350,11 +360,10 @@ exports.cashOut = function cashOut (session, tx, cb) { account: 'deposit' } - var cryptoCoin = tx.coin - ? tx.coin.unitCode - : 'BTC' + var cryptoCoin = tx.coin || BTC_COIN + var cryptoCode = cryptoCoin.unitCode - var walletPlugin = walletPlugins[cryptoCoin] + var walletPlugin = walletPlugins[cryptoCode] walletPlugin.newAddress(tmpInfo, function (err, address) { if (err) return cb(err) @@ -372,9 +381,10 @@ exports.dispenseAck = function dispenseAck (session, rec) { } exports.fiatBalance = function fiatBalance (cryptoCoin) { + var cryptoCode = cryptoCoin.unitCode var rawRate = exports.getDeviceRate(cryptoCoin).rates.ask var commission = cachedConfig.exchanges.settings.commission - var lastBalance = lastBalances[cryptoCoin] + var lastBalance = lastBalances[cryptoCode] if (!rawRate || !lastBalance) return null @@ -432,9 +442,10 @@ function stopTrader () { } function pollBalance (cryptoCoin, cb) { - logger.debug('[%s] collecting balance', cryptoCoin) + var cryptoCode = cryptoCoin.unitCode + logger.debug('[%s] collecting balance', cryptoCode) - var walletPlugin = walletPlugins[cryptoCoin] + var walletPlugin = walletPlugins[cryptoCode] walletPlugin.balance(function (err, balance) { if (err) { @@ -442,22 +453,23 @@ function pollBalance (cryptoCoin, cb) { return cb && cb(err) } - logger.debug('[%s] Balance update:', cryptoCoin, balance) + logger.debug('[%s] Balance update:', cryptoCode, balance) balance.timestamp = Date.now() - lastBalances[cryptoCoin] = balance + lastBalances[cryptoCode] = balance return cb && cb(null, lastBalances) }) } function pollRate (cryptoCoin, cb) { - logger.debug('[%s] polling for rates (%s)', cryptoCoin, tickerPlugin.NAME) - var tickerPlugin = tickerPlugins[cryptoCoin] + var cryptoCode = cryptoCoin.unitCode + logger.debug('[%s] polling for rates (%s)', cryptoCode, tickerPlugin.NAME) + var tickerPlugin = tickerPlugins[cryptoCode] var currencies = deviceCurrency if (typeof currencies === 'string') currencies = [currencies] - var tickerF = cryptoCoin === 'BTC' + var tickerF = cryptoCode === 'BTC' ? async.apply(tickerPlugin.ticker, currencies) : async.apply(tickerPlugin.ticker, currencies, cryptoCoin) @@ -469,7 +481,7 @@ function pollRate (cryptoCoin, cb) { logger.debug('got rates: %j', resRates) resRates.timestamp = new Date() - lastRates[cryptoCoin] = resRates + lastRates[cryptoCode] = resRates return cb && cb(null, lastRates) }) @@ -480,16 +492,18 @@ function pollRate (cryptoCoin, cb) { */ exports.getDeviceRate = function getDeviceRate (cryptoCoin) { - if (!lastRates[cryptoCoin]) return null + var cryptoCode = cryptoCoin.unitCode + if (!lastRates[cryptoCode]) return null - var lastRate = lastRates[cryptoCoin] + var lastRate = lastRates[cryptoCode] if (!lastRate) return null return lastRate[deviceCurrency] } exports.getBalance = function getBalance (cryptoCoin) { - var lastBalance = lastBalances[cryptoCoin] + var cryptoCode = cryptoCoin.unitCode + var lastBalance = lastBalances[cryptoCode] if (!lastBalance) return null return lastBalance.transferBalance diff --git a/lib/plugins/kraken.js b/lib/plugins/kraken.js deleted file mode 100644 index a843af62..00000000 --- a/lib/plugins/kraken.js +++ /dev/null @@ -1,47 +0,0 @@ -require('es6-promise').polyfill() -var axios = require('axios') -var _ = require('lodash') - -var BigNumber = require('bignumber.js') -BigNumber.config({DECIMAL_PLACES: 40}) - -exports.NAME = 'Kraken' -exports.SUPPORTED_MODULES = ['ticker'] - -exports.config = function config (localConfig) { -} - -function findCurrency (fxRates, currency) { - return new BigNumber(_.find(fxRates, function (r) { return r.code === currency }).rate) -} - -exports.ticker = function ticker (currencies, cryptoCoin, callback) { - return axios.get('https://bitpay.com/api/rates') - .then(function (response) { - var fxRates = response.data - - return axios.get('https://api.kraken.com/0/public/Ticker?pair=ETHUSD') - .then(function (response2) { - var usdRate = findCurrency(fxRates, 'USD') - var rates = response2.data.result.XETHZUSD - var res = {} - var cryptoCoinFactor = new BigNumber(10).pow(cryptoCoin.unitScale) - - currencies.forEach(function (currency) { - var fxRate = findCurrency(fxRates, currency).div(usdRate) - res[currency] = { - ask: fxRate.times(rates.a[0]).div(cryptoCoinFactor), - bid: fxRate.times(rates.b[0]).div(cryptoCoinFactor) - } - }) - - callback(null, res) - }) - }) - .catch(callback) -} - -exports.ticker(['USD', 'ILS', 'EUR'], {unitScale: 18}, function (err, res) { - if (err) return console.log(err.stack) - console.log(JSON.stringify(res, null, 2)) -}) diff --git a/lib/plugins/web3.js b/lib/plugins/web3.js deleted file mode 100644 index b4a970f2..00000000 --- a/lib/plugins/web3.js +++ /dev/null @@ -1,25 +0,0 @@ -var Web3 = require('web3') - -var web3 = new Web3() - -if (!web3.isConnected()) { - web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')) -} - -// Note: it's still called sendBitcoins for backwards compatibility, but this -// is for any currency -exports.sendBitcoins = function sendBitcoins (address, satoshis, fee, callback) { - web3.eth.sendTransaction({ - to: address, - value: satoshis - }, callback) -} - -exports.balance = function balance (cb) { - var coinbase = web3.eth.coinbase - web3.eth.getBalance(coinbase, 'pending', cb) -} - -exports.newAddress = function newAddress (info, callback) { - throw new Error('Not implemented') -} diff --git a/lib/routes.js b/lib/routes.js index b03cae4d..fa4dfd7b 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -32,8 +32,9 @@ function buildRates () { var rates = {} cryptoCoins.forEach(function (coin) { + var cryptoCode = coin.unitCode var rate = plugins.getDeviceRate(coin).rates - rates[coin] = { + rates[cryptoCode] = { cashIn: rate.ask.times(cashInCommission), cashOut: rate.bid.div(cashOutCommission) } diff --git a/todo.txt b/todo.txt new file mode 100644 index 00000000..d4a1eb1b --- /dev/null +++ b/todo.txt @@ -0,0 +1,5 @@ +- specify crypto and fiat for trades +- make sure ticker is in full coins +- rethink scale names: is unit satoshi or btc? +- cryptoCoin is record, not code +- getDeviceRate should return bignumber