fix up crypto services

This commit is contained in:
Josh Harvey 2016-12-09 00:10:18 +02:00
parent e24da06a1b
commit 1b89ed5c76
9 changed files with 82 additions and 46 deletions

View file

@ -32,7 +32,7 @@ function runOnce () {
const app = express()
const localApp = express()
return settingsLoader.load()
return settingsLoader.loadLatest()
.then(settings => {
poller.start(settings)

View file

@ -1,5 +1,4 @@
const configManager = require('./config-manager')
const settingsLoader = require('./settings-loader')
function noExchangeError (cryptoCode) {
const err = new Error('No exchange plugin defined for: ' + cryptoCode)
@ -8,15 +7,13 @@ function noExchangeError (cryptoCode) {
return err
}
function lookupExchange (cryptoCode) {
const settings = settingsLoader.settings()
function lookupExchange (settings, cryptoCode) {
return configManager.cryptoScoped(cryptoCode, settings.config).exchange
}
function fetchExchange (cryptoCode) {
function fetchExchange (settings, cryptoCode) {
return Promise.resolve()
.then(() => {
const settings = settingsLoader.settings()
const plugin = lookupExchange(cryptoCode)
if (!plugin) throw noExchangeError(cryptoCode)
const account = settings.accounts[plugin]
@ -26,18 +23,18 @@ function fetchExchange (cryptoCode) {
})
}
function buy (cryptoAtoms, fiatCode, cryptoCode) {
return fetchExchange(cryptoCode)
function buy (settings, cryptoAtoms, fiatCode, cryptoCode) {
return fetchExchange(settings, cryptoCode)
.then(r => r.exchange.buy(r.account, cryptoAtoms, fiatCode, cryptoCode))
}
function sell (cryptoAtoms, fiatCode, cryptoCode) {
return fetchExchange(cryptoCode)
function sell (settings, cryptoAtoms, fiatCode, cryptoCode) {
return fetchExchange(settings, cryptoCode)
.then(r => r.exchange.sell(r.account, cryptoAtoms, fiatCode, cryptoCode))
}
function active (fiatCode, cryptoCode) {
return !!lookupExchange(cryptoCode)
function active (settings, fiatCode, cryptoCode) {
return !!lookupExchange(settings, cryptoCode)
}
module.exports = {

View file

@ -87,6 +87,15 @@ function plugins (settings) {
}
}
function fetchCurrentConfigVersion () {
const sql = `select id from config_users
where type=$1
order by id desc
limit 1`
return db.one(sql, ['config'])
}
function pollQueries (deviceTime, deviceId, deviceRec) {
const config = configManager.machineScoped(deviceId, settings.config)
const fiatCode = config.fiatCurrency
@ -95,22 +104,29 @@ function plugins (settings) {
config.bottomCashOutDenomination ]
const virtualCartridges = [config.virtualCashOutDenomination]
const tickerPromises = cryptoCodes.map(c => ticker.getRates(fiatCode, c))
const balancePromises = cryptoCodes.map(wallet.balance)
const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
const balancePromises = cryptoCodes.map(c => wallet.balance(settings, c))
const pingPromise = recordPing(deviceId, deviceTime, deviceRec)
const currentConfigVersionPromise = fetchCurrentConfigVersion()
const promises = [dbm.cartridgeCounts(deviceId), pingPromise].concat(tickerPromises, balancePromises)
const promises = [
dbm.cartridgeCounts(deviceId),
pingPromise,
currentConfigVersionPromise
].concat(tickerPromises, balancePromises)
return Promise.all(promises)
.then(arr => {
const cartridgeCounts = arr[0]
const tickers = arr.slice(2, cryptoCodes.length + 2)
const balances = arr.slice(cryptoCodes.length + 2)
const currentConfigVersion = arr[2]
const tickers = arr.slice(3, cryptoCodes.length + 3)
const balances = arr.slice(cryptoCodes.length + 3)
return {
cartridges: buildCartridges(cartridges, virtualCartridges, cartridgeCounts),
rates: buildRates(deviceId, tickers),
balances: buildBalances(deviceId, balances)
balances: buildBalances(deviceId, balances),
currentConfigVersion
}
})
}
@ -119,7 +135,7 @@ function plugins (settings) {
// a dbm unique dbm record in the table already.
function executeTx (deviceId, tx) {
return dbm.addOutgoingTx(deviceId, tx)
.then(() => wallet.sendCoins(tx.toAddress, tx.cryptoAtoms, tx.cryptoCode))
.then(() => wallet.sendCoins(settings, tx.toAddress, tx.cryptoAtoms, tx.cryptoCode))
.then(txHash => {
const fee = null // Need to fill this out in plugins
const toSend = {cryptoAtoms: tx.cryptoAtoms, fiat: tx.fiat}
@ -144,7 +160,7 @@ function plugins (settings) {
.then(() => {
const market = [fiatCode, cryptoCode].join('')
if (!exchange.active(cryptoCode)) return
if (!exchange.active(settings, cryptoCode)) return
logger.debug('[%s] Pushing trade: %d', market, cryptoAtoms)
if (!tradesQueues[market]) tradesQueues[market] = []
@ -187,7 +203,7 @@ function plugins (settings) {
serialNumber
}
return wallet.newAddress(cryptoCode, info)
return wallet.newAddress(settings, cryptoCode, info)
.then(address => {
const newTx = R.assoc('toAddress', address, tx)
@ -208,7 +224,10 @@ function plugins (settings) {
function fiatBalance (fiatCode, cryptoCode, deviceId) {
const config = configManager.scoped(cryptoCode, deviceId, settings.config)
return Promise.all([ticker.getRates(fiatCode, cryptoCode), wallet.balance(cryptoCode)])
return Promise.all([
ticker.getRates(settings, fiatCode, cryptoCode),
wallet.balance(settings, cryptoCode)
])
.then(([rates, balanceRec]) => {
const rawRate = rates.rates.ask
const commission = (new BigNumber(config.cashInCommission).div(100)).plus(1)
@ -231,7 +250,7 @@ function plugins (settings) {
}
function processTxStatus (tx) {
return wallet.getStatus(tx.toAddress, tx.cryptoAtoms, tx.cryptoCode)
return wallet.getStatus(settings, tx.toAddress, tx.cryptoAtoms, tx.cryptoCode)
.then(res => dbm.updateTxStatus(tx, res.status))
}
@ -355,7 +374,7 @@ function plugins (settings) {
}
function executeTradesForMarket (settings, fiatCode, cryptoCode) {
if (!exchange.active(cryptoCode)) return
if (!exchange.active(settings, cryptoCode)) return
const market = [fiatCode, cryptoCode].join('')
logger.debug('[%s] checking for trades', market)
@ -370,7 +389,7 @@ function plugins (settings) {
logger.debug('[%s] making a trade: %d', market, tradeEntry.cryptoAtoms.toString())
return exchange.buy(tradeEntry.cryptoAtoms, tradeEntry.fiatCode, tradeEntry.cryptoCode)
return exchange.buy(settings, tradeEntry.cryptoAtoms, tradeEntry.fiatCode, tradeEntry.cryptoCode)
.then(() => logger.debug('[%s] Successful trade.', market))
.catch(err => {
tradesQueues[market].push(tradeEntry)
@ -444,7 +463,7 @@ function plugins (settings) {
function sweepHD (row) {
const cryptoCode = row.crypto_code
return wallet.sweep(row.hd_serial)
return wallet.sweep(settings, row.hd_serial)
.then(txHash => {
if (txHash) {
logger.debug('[%s] Swept address with tx: %s', cryptoCode, txHash)

View file

@ -1,5 +1,6 @@
const R = require('ramda')
const db = require('./db')
const dbm = require('./postgresql_interface')
const T = require('./time')
const TRANSACTION_EXPIRATION = 2 * T.days
@ -32,4 +33,8 @@ function fetchPhoneTx (phone) {
})
}
module.exports = {stateChange, fetchPhoneTx}
function updateDeviceConfigVersion (versionId) {
return db.none('update devices set user_config_id=$1', [versionId])
}
module.exports = {stateChange, fetchPhoneTx, updateDeviceConfigVersion}

View file

@ -62,7 +62,8 @@ function poll (req, res, next) {
reboot,
rates: results.rates,
balances: results.balances,
coins: config.cryptoCurrencies
coins: config.cryptoCurrencies,
configVersion: results.currentConfigVersion
}
if (response.idVerificationEnabled) {
@ -421,13 +422,14 @@ function populateDeviceId (req, res, next) {
}
function populateSettings (req, res, next) {
const versionId = req.headers['config-version-id']
const versionId = req.headers['config-version']
if (!versionId) {
logger.debug('No config-version-id header')
logger.debug('No config-version header')
return res.sendStatus(400)
}
settingsLoader.log(versionId)
.then(settings => { req.settings = settings })
.then(() => helpers.updateDeviceConfigVersion(versionId))
.catch(next)
}

View file

@ -5,6 +5,8 @@ const db = require('./db')
let settingsCache
function load (versionId) {
if (!versionId) throw new Error('versionId is required')
return Promise.all([loadConfig(versionId), loadAccounts()])
.then(([config, accounts]) => ({
config,
@ -23,7 +25,7 @@ function loadLatest (versionId) {
function loadConfig (versionId) {
const sql = `select data
from user_config
where versionId=$1 and type=$2`
where id=$1 and type=$2`
return db.oneOrNone(sql, [versionId, 'config'])
.then(row => row ? row.data.config : [])
@ -33,7 +35,7 @@ function loadLatestConfig () {
const sql = `select data
from user_config
where type=$1
order by versionId desc
order by id desc
limit 1`
return db.oneOrNone(sql, ['config'])

View file

@ -1,12 +1,10 @@
const mem = require('mem')
const configManager = require('./config-manager')
const settingsLoader = require('./settings-loader')
const FETCH_INTERVAL = 10000
function getRates (fiatCode, cryptoCode) {
function getRates (settings, fiatCode, cryptoCode) {
return Promise.resolve()
.then(() => {
const settings = settingsLoader.settings()
const config = settings.config
const plugin = configManager.cryptoScoped(cryptoCode, config).ticker

View file

@ -1,13 +1,11 @@
const mem = require('mem')
const configManager = require('./config-manager')
const settingsLoader = require('./settings-loader')
const FETCH_INTERVAL = 5000
function fetchWallet (cryptoCode) {
function fetchWallet (settings, cryptoCode) {
return Promise.resolve()
.then(() => {
const settings = settingsLoader.settings()
const plugin = configManager.cryptoScoped(cryptoCode, settings.config).wallet
const account = settings.accounts[plugin]
const wallet = require('lamassu-' + plugin)
@ -16,14 +14,14 @@ function fetchWallet (cryptoCode) {
})
}
function balance (cryptoCode) {
return fetchWallet(cryptoCode)
function balance (settings, cryptoCode) {
return fetchWallet(settings, cryptoCode)
.then(r => r.wallet.balance(r.account, cryptoCode))
.then(balance => ({balance, timestamp: Date.now()}))
}
function sendCoins (toAddress, cryptoAtoms, cryptoCode) {
return fetchWallet(cryptoCode)
function sendCoins (settings, toAddress, cryptoAtoms, cryptoCode) {
return fetchWallet(settings, cryptoCode)
.then(r => {
return r.wallet.sendCoins(r.account, toAddress, cryptoAtoms, cryptoCode)
.then(res => {
@ -33,13 +31,13 @@ function sendCoins (toAddress, cryptoAtoms, cryptoCode) {
})
}
function newAddress (cryptoCode, info) {
return fetchWallet(cryptoCode)
function newAddress (settings, cryptoCode, info) {
return fetchWallet(settings, cryptoCode)
.then(r => r.wallet.newAddress(r.account, cryptoCode, info))
}
function getStatus (toAddress, cryptoAtoms, cryptoCode) {
return fetchWallet(cryptoCode)
function getStatus (settings, toAddress, cryptoAtoms, cryptoCode) {
return fetchWallet(settings, cryptoCode)
.then(r => r.wallet.getStatus(r.account, toAddress, cryptoAtoms, cryptoCode))
}

View file

@ -0,0 +1,15 @@
var db = require('./db')
exports.up = function (next) {
var sql = [
'alter table devices add column user_config_id int',
`ALTER TABLE devices ADD CONSTRAINT user_config_id
FOREIGN KEY (user_config_id)
REFERENCES user_config (id)`
]
db.multi(sql, next)
}
exports.down = function (next) {
next()
}