This commit is contained in:
Josh Harvey 2016-04-05 02:48:21 +01:00
parent 22c2acfe61
commit e462359299
5 changed files with 52 additions and 104 deletions

View file

@ -16,6 +16,13 @@ var POLLING_RATE = 60 * 1000 // poll each minute
var REAP_RATE = 2 * 1000 var REAP_RATE = 2 * 1000
var PENDING_TIMEOUT = 70 * 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 if (argv.timeout) PENDING_TIMEOUT = argv.timeout / 1000
// TODO: might have to update this if user is allowed to extend monitoring time // 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, function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCoin, currency,
onChangeCallback) { onChangeCallback) {
if (!cryptoCoin) cryptoCoin = 'any' var cryptoCode = cryptoCoin ? cryptoCoin.unitCode : 'any'
var currentName = cryptoCoin === 'any' || cryptoCoin === 'BTC'
? cachedConfig.exchanges.plugins.current[pluginType]
: cachedConfig.exchanges.plugins.current[cryptoCoin][pluginType]
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 if (!currentName) pluginHandle = null
else { // some plugins may be disabled else { // some plugins may be disabled
@ -130,9 +138,9 @@ function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCoin, currency,
if (pluginHandle && !pluginChanged) pluginHandle.config(pluginConfig) if (pluginHandle && !pluginChanged) pluginHandle.config(pluginConfig)
else { else {
pluginHandle = loadPlugin(currentName, pluginConfig) pluginHandle = loadPlugin(currentName, pluginConfig)
currentlyUsedPlugins[cryptoCoin] = currentlyUsedPlugins[cryptoCoin] || {} currentlyUsedPlugins[cryptoCode] = currentlyUsedPlugins[cryptoCode] || {}
currentlyUsedPlugins[cryptoCoin][pluginType] = currentName currentlyUsedPlugins[cryptoCode][pluginType] = currentName
logger.debug('[%s] plugin(%s) loaded: %s', cryptoCoin, pluginType, pluginHandle.NAME || logger.debug('[%s] plugin(%s) loaded: %s', cryptoCode, pluginType, pluginHandle.NAME ||
currentName) currentName)
} }
} }
@ -149,29 +157,30 @@ exports.configure = function configure (config) {
cachedConfig = config cachedConfig = config
deviceCurrency = config.exchanges.settings.currency deviceCurrency = config.exchanges.settings.currency
cryptoCoins = config.exchanges.settings.coins || ['BTC'] cryptoCoins = config.exchanges.settings.coins || [BTC_COIN]
cryptoCoins.forEach(function (cryptoCoin) { cryptoCoins.forEach(function (cryptoCoin) {
// TICKER [required] configure (or load) // TICKER [required] configure (or load)
var cryptoCode = cryptoCoin.unitCode
loadOrConfigPlugin( loadOrConfigPlugin(
tickerPlugins[cryptoCoin], tickerPlugins[cryptoCode],
'ticker', 'ticker',
cryptoCoin, cryptoCoin,
deviceCurrency, // device currency deviceCurrency, // device currency
function onTickerChange (newTicker) { function onTickerChange (newTicker) {
tickerPlugins[cryptoCoin] = newTicker tickerPlugins[cryptoCode] = newTicker
pollRate(cryptoCoin) pollRate(cryptoCoin)
} }
) )
// WALLET [required] configure (or load) // WALLET [required] configure (or load)
loadOrConfigPlugin( loadOrConfigPlugin(
walletPlugins[cryptoCoin], walletPlugins[cryptoCode],
'transfer', 'transfer',
cryptoCoin, cryptoCoin,
null, null,
function onWalletChange (newWallet) { function onWalletChange (newWallet) {
walletPlugins[cryptoCoin] = newWallet walletPlugins[cryptoCode] = newWallet
pollBalance(cryptoCoin) pollBalance(cryptoCoin)
} }
) )
@ -240,9 +249,10 @@ exports.pollQueries = function pollQueries (session, cb) {
} }
function _sendCoins (toAddress, cryptoUnits, cryptoCoin, 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 var transactionFee = cachedConfig.exchanges.settings.transactionFee
if (cryptoCoin === 'BTC') { if (cryptoCode === 'BTC') {
walletPlugin.sendBitcoins(toAddress, cryptoUnits, transactionFee, cb) walletPlugin.sendBitcoins(toAddress, cryptoUnits, transactionFee, cb)
} else { } else {
walletPlugin.sendCoins(toAddress, cryptoUnits, cryptoCoin, transactionFee, cb) walletPlugin.sendCoins(toAddress, cryptoUnits, cryptoCoin, transactionFee, cb)
@ -350,11 +360,10 @@ exports.cashOut = function cashOut (session, tx, cb) {
account: 'deposit' account: 'deposit'
} }
var cryptoCoin = tx.coin var cryptoCoin = tx.coin || BTC_COIN
? tx.coin.unitCode var cryptoCode = cryptoCoin.unitCode
: 'BTC'
var walletPlugin = walletPlugins[cryptoCoin] var walletPlugin = walletPlugins[cryptoCode]
walletPlugin.newAddress(tmpInfo, function (err, address) { walletPlugin.newAddress(tmpInfo, function (err, address) {
if (err) return cb(err) if (err) return cb(err)
@ -372,9 +381,10 @@ exports.dispenseAck = function dispenseAck (session, rec) {
} }
exports.fiatBalance = function fiatBalance (cryptoCoin) { exports.fiatBalance = function fiatBalance (cryptoCoin) {
var cryptoCode = cryptoCoin.unitCode
var rawRate = exports.getDeviceRate(cryptoCoin).rates.ask var rawRate = exports.getDeviceRate(cryptoCoin).rates.ask
var commission = cachedConfig.exchanges.settings.commission var commission = cachedConfig.exchanges.settings.commission
var lastBalance = lastBalances[cryptoCoin] var lastBalance = lastBalances[cryptoCode]
if (!rawRate || !lastBalance) return null if (!rawRate || !lastBalance) return null
@ -432,9 +442,10 @@ function stopTrader () {
} }
function pollBalance (cryptoCoin, cb) { 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) { walletPlugin.balance(function (err, balance) {
if (err) { if (err) {
@ -442,22 +453,23 @@ function pollBalance (cryptoCoin, cb) {
return cb && cb(err) return cb && cb(err)
} }
logger.debug('[%s] Balance update:', cryptoCoin, balance) logger.debug('[%s] Balance update:', cryptoCode, balance)
balance.timestamp = Date.now() balance.timestamp = Date.now()
lastBalances[cryptoCoin] = balance lastBalances[cryptoCode] = balance
return cb && cb(null, lastBalances) return cb && cb(null, lastBalances)
}) })
} }
function pollRate (cryptoCoin, cb) { function pollRate (cryptoCoin, cb) {
logger.debug('[%s] polling for rates (%s)', cryptoCoin, tickerPlugin.NAME) var cryptoCode = cryptoCoin.unitCode
var tickerPlugin = tickerPlugins[cryptoCoin] logger.debug('[%s] polling for rates (%s)', cryptoCode, tickerPlugin.NAME)
var tickerPlugin = tickerPlugins[cryptoCode]
var currencies = deviceCurrency var currencies = deviceCurrency
if (typeof currencies === 'string') currencies = [currencies] if (typeof currencies === 'string') currencies = [currencies]
var tickerF = cryptoCoin === 'BTC' var tickerF = cryptoCode === 'BTC'
? async.apply(tickerPlugin.ticker, currencies) ? async.apply(tickerPlugin.ticker, currencies)
: async.apply(tickerPlugin.ticker, currencies, cryptoCoin) : async.apply(tickerPlugin.ticker, currencies, cryptoCoin)
@ -469,7 +481,7 @@ function pollRate (cryptoCoin, cb) {
logger.debug('got rates: %j', resRates) logger.debug('got rates: %j', resRates)
resRates.timestamp = new Date() resRates.timestamp = new Date()
lastRates[cryptoCoin] = resRates lastRates[cryptoCode] = resRates
return cb && cb(null, lastRates) return cb && cb(null, lastRates)
}) })
@ -480,16 +492,18 @@ function pollRate (cryptoCoin, cb) {
*/ */
exports.getDeviceRate = function getDeviceRate (cryptoCoin) { 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 if (!lastRate) return null
return lastRate[deviceCurrency] return lastRate[deviceCurrency]
} }
exports.getBalance = function getBalance (cryptoCoin) { exports.getBalance = function getBalance (cryptoCoin) {
var lastBalance = lastBalances[cryptoCoin] var cryptoCode = cryptoCoin.unitCode
var lastBalance = lastBalances[cryptoCode]
if (!lastBalance) return null if (!lastBalance) return null
return lastBalance.transferBalance return lastBalance.transferBalance

View file

@ -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))
})

View file

@ -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')
}

View file

@ -32,8 +32,9 @@ function buildRates () {
var rates = {} var rates = {}
cryptoCoins.forEach(function (coin) { cryptoCoins.forEach(function (coin) {
var cryptoCode = coin.unitCode
var rate = plugins.getDeviceRate(coin).rates var rate = plugins.getDeviceRate(coin).rates
rates[coin] = { rates[cryptoCode] = {
cashIn: rate.ask.times(cashInCommission), cashIn: rate.ask.times(cashInCommission),
cashOut: rate.bid.div(cashOutCommission) cashOut: rate.bid.div(cashOutCommission)
} }

5
todo.txt Normal file
View file

@ -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