WIP
This commit is contained in:
parent
340ad2b518
commit
b7a93b89f5
5 changed files with 159 additions and 77 deletions
|
|
@ -11,7 +11,6 @@ exports.makeChange = function makeChange (cartridges, amount) {
|
||||||
// since they're all integers, well within JS number range,
|
// since they're all integers, well within JS number range,
|
||||||
// and this is way more efficient in a tight loop.
|
// and this is way more efficient in a tight loop.
|
||||||
|
|
||||||
console.log('DEBUG777: %j', cartridges)
|
|
||||||
const small = cartridges[0]
|
const small = cartridges[0]
|
||||||
const large = cartridges[1]
|
const large = cartridges[1]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,15 +36,15 @@ function plugins (settings, deviceId) {
|
||||||
const cryptoCodes = config.cryptoCurrencies
|
const cryptoCodes = config.cryptoCurrencies
|
||||||
const cashOut = config.cashOutEnabled
|
const cashOut = config.cashOutEnabled
|
||||||
|
|
||||||
const cashInCommission = BN(1).minus(BN(config.cashInCommission).div(100))
|
|
||||||
const cashOutCommission = cashOut && BN(1).plus(BN(config.cashOutCommission).div(100))
|
|
||||||
|
|
||||||
const rates = {}
|
const rates = {}
|
||||||
|
|
||||||
console.log('DEBUG444: %j', tickers)
|
|
||||||
console.log('DEBUG445: %j', [config.cashOutCommission, cashOutCommission])
|
|
||||||
cryptoCodes.forEach((cryptoCode, i) => {
|
cryptoCodes.forEach((cryptoCode, i) => {
|
||||||
|
const cryptoConfig = configManager.scoped(cryptoCode, deviceId, settings.config)
|
||||||
const rateRec = tickers[i]
|
const rateRec = tickers[i]
|
||||||
|
|
||||||
|
const cashInCommission = BN(1).minus(BN(cryptoConfig.cashInCommission).div(100))
|
||||||
|
const cashOutCommission = cashOut && BN(1).plus(BN(cryptoConfig.cashOutCommission).div(100))
|
||||||
|
|
||||||
if (Date.now() - rateRec.timestamp > STALE_TICKER) return logger.warn('Stale rate for ' + cryptoCode)
|
if (Date.now() - rateRec.timestamp > STALE_TICKER) return logger.warn('Stale rate for ' + cryptoCode)
|
||||||
const rate = rateRec.rates
|
const rate = rateRec.rates
|
||||||
rates[cryptoCode] = {
|
rates[cryptoCode] = {
|
||||||
|
|
@ -83,19 +83,39 @@ function plugins (settings, deviceId) {
|
||||||
const virtualCartridges = [config.virtualCashOutDenomination]
|
const virtualCartridges = [config.virtualCashOutDenomination]
|
||||||
|
|
||||||
return dbm.cartridgeCounts(deviceId)
|
return dbm.cartridgeCounts(deviceId)
|
||||||
.then(rec => ({
|
.then(rec => {
|
||||||
cartridges: [
|
if (argv.cassettes) {
|
||||||
{
|
const counts = argv.cassettes.split(',')
|
||||||
denomination: parseInt(cartridges[0], 10),
|
|
||||||
count: parseInt(rec.counts[0], 10)
|
return {
|
||||||
},
|
cartridges: [
|
||||||
{
|
{
|
||||||
denomination: parseInt(cartridges[1], 10),
|
denomination: parseInt(cartridges[0], 10),
|
||||||
count: parseInt(rec.counts[1], 10)
|
count: parseInt(counts[0], 10)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
denomination: parseInt(cartridges[1], 10),
|
||||||
|
count: parseInt(counts[1], 10)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
virtualCartridges
|
||||||
}
|
}
|
||||||
],
|
}
|
||||||
virtualCartridges
|
|
||||||
}))
|
return {
|
||||||
|
cartridges: [
|
||||||
|
{
|
||||||
|
denomination: parseInt(cartridges[0], 10),
|
||||||
|
count: parseInt(rec.counts[0], 10)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
denomination: parseInt(cartridges[1], 10),
|
||||||
|
count: parseInt(rec.counts[1], 10)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
virtualCartridges
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchCurrentConfigVersion () {
|
function fetchCurrentConfigVersion () {
|
||||||
|
|
@ -200,7 +220,8 @@ function plugins (settings, deviceId) {
|
||||||
|
|
||||||
function fiatBalance (fiatCode, cryptoCode) {
|
function fiatBalance (fiatCode, cryptoCode) {
|
||||||
const config = configManager.scoped(cryptoCode, deviceId, settings.config)
|
const config = configManager.scoped(cryptoCode, deviceId, settings.config)
|
||||||
|
console.log('DEBUG222: %j', config)
|
||||||
|
console.log('DEBUG223: %j', [cryptoCode, deviceId])
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
ticker.getRates(settings, fiatCode, cryptoCode),
|
ticker.getRates(settings, fiatCode, cryptoCode),
|
||||||
wallet.balance(settings, cryptoCode)
|
wallet.balance(settings, cryptoCode)
|
||||||
|
|
@ -221,7 +242,6 @@ function plugins (settings, deviceId) {
|
||||||
const unitScale = BN(10).pow(coins[cryptoCode].unitScale)
|
const unitScale = BN(10).pow(coins[cryptoCode].unitScale)
|
||||||
const fiatTransferBalance = balance.mul(rate.div(unitScale)).div(lowBalanceMargin)
|
const fiatTransferBalance = balance.mul(rate.div(unitScale)).div(lowBalanceMargin)
|
||||||
|
|
||||||
console.log('DEBUG444: %s', fiatTransferBalance)
|
|
||||||
return {timestamp: balanceRec.timestamp, balance: fiatTransferBalance.truncated().toString()}
|
return {timestamp: balanceRec.timestamp, balance: fiatTransferBalance.truncated().toString()}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,15 +72,12 @@ function fetchPhoneTx (phone) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchStatusTx (txId, status) {
|
function fetchStatusTx (txId, status) {
|
||||||
console.log('DEBUG444')
|
|
||||||
const sql = 'select * from cash_out_txs where id=$1'
|
const sql = 'select * from cash_out_txs where id=$1'
|
||||||
|
|
||||||
return db.oneOrNone(sql, [txId])
|
return db.oneOrNone(sql, [txId])
|
||||||
.then(toObj)
|
.then(toObj)
|
||||||
.then(tx => {
|
.then(tx => {
|
||||||
console.log('DEBUG445')
|
|
||||||
if (!tx) throw httpError('No transaction', 404)
|
if (!tx) throw httpError('No transaction', 404)
|
||||||
console.log('DEBUG446')
|
|
||||||
if (tx.status === status) throw httpError('Not Modified', 304)
|
if (tx.status === status) throw httpError('Not Modified', 304)
|
||||||
return tx
|
return tx
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -6,68 +6,27 @@ const argv = require('minimist')(process.argv.slice(2))
|
||||||
const pify = require('pify')
|
const pify = require('pify')
|
||||||
|
|
||||||
const db = require('./db')
|
const db = require('./db')
|
||||||
const schema = require('../lamassu-schema.json')
|
|
||||||
|
|
||||||
const mapWithKey = _.map.convert({cap: false})
|
|
||||||
|
|
||||||
let settingsCache
|
let settingsCache
|
||||||
|
|
||||||
function expandFixture (fixture) {
|
|
||||||
const deviceId = argv.machine
|
|
||||||
|
|
||||||
function findField (code) {
|
|
||||||
const field = _.find(_.matchesProperty('code', code), schema.fields)
|
|
||||||
const group = _.find(r => _.includes(code, r.fields), schema.groups)
|
|
||||||
|
|
||||||
if (!field || !group) {
|
|
||||||
throw new Error('No such field from fixture: ' + code)
|
|
||||||
}
|
|
||||||
|
|
||||||
return _.merge({cryptoScope: group.cryptoScope, machineScope: group.machineScope}, field)
|
|
||||||
}
|
|
||||||
|
|
||||||
function expand (value, code) {
|
|
||||||
const field = findField(code)
|
|
||||||
|
|
||||||
const machine = field.machineScope === 'specific'
|
|
||||||
? deviceId
|
|
||||||
: 'global'
|
|
||||||
|
|
||||||
const crypto = field.cryptoScope === 'specific'
|
|
||||||
? 'BTC'
|
|
||||||
: 'global'
|
|
||||||
|
|
||||||
return {
|
|
||||||
fieldLocator: {
|
|
||||||
fieldScope: {crypto, machine},
|
|
||||||
code,
|
|
||||||
fieldType: field.fieldType,
|
|
||||||
fieldClass: field.fieldClass
|
|
||||||
},
|
|
||||||
fieldValue: {
|
|
||||||
fieldType: field.fieldType,
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapWithKey(expand, fixture)
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadFixture () {
|
function loadFixture () {
|
||||||
const fixture = argv.fixture
|
const fixture = argv.fixture
|
||||||
const deviceId = argv.machine
|
const machine = argv.machine
|
||||||
|
|
||||||
if (fixture && !deviceId) throw new Error('Missing --machine parameter for --fixture')
|
if (fixture && !machine) throw new Error('Missing --machine parameter for --fixture')
|
||||||
|
|
||||||
const fixturePath = fixture => path.resolve(__dirname, '..', 'test', 'fixtures', fixture + '.json')
|
const fixturePath = fixture => path.resolve(__dirname, '..', 'test', 'fixtures', fixture + '.json')
|
||||||
|
|
||||||
const promise = fixture
|
const promise = fixture
|
||||||
? pify(fs.readFile)(fixturePath(fixture)).then(JSON.parse)
|
? pify(fs.readFile)(fixturePath(fixture)).then(JSON.parse)
|
||||||
: Promise.resolve({})
|
: Promise.resolve([])
|
||||||
|
|
||||||
return promise
|
return promise
|
||||||
.then(expandFixture)
|
.then(values => _.map(v => {
|
||||||
|
return (v.fieldLocator.fieldScope.machine === 'machine')
|
||||||
|
? _.set('fieldLocator.fieldScope.machine', machine, v)
|
||||||
|
: v
|
||||||
|
}, values))
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEquivalentField (a, b) {
|
function isEquivalentField (a, b) {
|
||||||
|
|
@ -112,13 +71,15 @@ function loadConfig (versionId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadLatestConfig () {
|
function loadLatestConfig () {
|
||||||
|
if (argv.fixture) return loadFixture()
|
||||||
|
|
||||||
const sql = `select data
|
const sql = `select data
|
||||||
from user_config
|
from user_config
|
||||||
where type=$1
|
where type=$1
|
||||||
order by id desc
|
order by id desc
|
||||||
limit 1`
|
limit 1`
|
||||||
|
|
||||||
return db.oneOrNone(sql, ['config'])
|
db.oneOrNone(sql, ['config'])
|
||||||
.then(row => row ? row.data.config : [])
|
.then(row => row ? row.data.config : [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
113
test/fixtures/two-way-btc.json
vendored
113
test/fixtures/two-way-btc.json
vendored
|
|
@ -2,8 +2,8 @@
|
||||||
{
|
{
|
||||||
"fieldLocator": {
|
"fieldLocator": {
|
||||||
"fieldScope": {
|
"fieldScope": {
|
||||||
"crypto": "BTC",
|
"crypto": "global",
|
||||||
"machine": "machine"
|
"machine": "global"
|
||||||
},
|
},
|
||||||
"code": "cashInCommission",
|
"code": "cashInCommission",
|
||||||
"fieldType": "percentage",
|
"fieldType": "percentage",
|
||||||
|
|
@ -17,8 +17,23 @@
|
||||||
{
|
{
|
||||||
"fieldLocator": {
|
"fieldLocator": {
|
||||||
"fieldScope": {
|
"fieldScope": {
|
||||||
"crypto": "BTC",
|
"crypto": "global",
|
||||||
"machine": "machine"
|
"machine": "global"
|
||||||
|
},
|
||||||
|
"code": "cashOutCommission",
|
||||||
|
"fieldType": "percentage",
|
||||||
|
"fieldClass": null
|
||||||
|
},
|
||||||
|
"fieldValue": {
|
||||||
|
"fieldType": "percentage",
|
||||||
|
"value": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldLocator": {
|
||||||
|
"fieldScope": {
|
||||||
|
"crypto": "global",
|
||||||
|
"machine": "global"
|
||||||
},
|
},
|
||||||
"code": "lowBalanceMargin",
|
"code": "lowBalanceMargin",
|
||||||
"fieldType": "percentage",
|
"fieldType": "percentage",
|
||||||
|
|
@ -242,5 +257,95 @@
|
||||||
"fieldType": "integer",
|
"fieldType": "integer",
|
||||||
"value": 100
|
"value": 100
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldLocator": {
|
||||||
|
"fieldScope": {
|
||||||
|
"crypto": "global",
|
||||||
|
"machine": "global"
|
||||||
|
},
|
||||||
|
"code": "topCashOutDenomination",
|
||||||
|
"fieldType": "integer",
|
||||||
|
"fieldClass": null
|
||||||
|
},
|
||||||
|
"fieldValue": {
|
||||||
|
"fieldType": "integer",
|
||||||
|
"value": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldLocator": {
|
||||||
|
"fieldScope": {
|
||||||
|
"crypto": "global",
|
||||||
|
"machine": "global"
|
||||||
|
},
|
||||||
|
"code": "bottomCashOutDenomination",
|
||||||
|
"fieldType": "integer",
|
||||||
|
"fieldClass": null
|
||||||
|
},
|
||||||
|
"fieldValue": {
|
||||||
|
"fieldType": "integer",
|
||||||
|
"value": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldLocator": {
|
||||||
|
"fieldScope": {
|
||||||
|
"crypto": "global",
|
||||||
|
"machine": "global"
|
||||||
|
},
|
||||||
|
"code": "virtualCashOutDenomination",
|
||||||
|
"fieldType": "integer",
|
||||||
|
"fieldClass": null
|
||||||
|
},
|
||||||
|
"fieldValue": {
|
||||||
|
"fieldType": "integer",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldLocator": {
|
||||||
|
"fieldScope": {
|
||||||
|
"crypto": "global",
|
||||||
|
"machine": "global"
|
||||||
|
},
|
||||||
|
"code": "cashOutTransactionLimit",
|
||||||
|
"fieldType": "integer",
|
||||||
|
"fieldClass": null
|
||||||
|
},
|
||||||
|
"fieldValue": {
|
||||||
|
"fieldType": "integer",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldLocator": {
|
||||||
|
"fieldScope": {
|
||||||
|
"crypto": "global",
|
||||||
|
"machine": "global"
|
||||||
|
},
|
||||||
|
"code": "zeroConfLimit",
|
||||||
|
"fieldType": "integer",
|
||||||
|
"fieldClass": null
|
||||||
|
},
|
||||||
|
"fieldValue": {
|
||||||
|
"fieldType": "integer",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldLocator": {
|
||||||
|
"fieldScope": {
|
||||||
|
"crypto": "global",
|
||||||
|
"machine": "global"
|
||||||
|
},
|
||||||
|
"code": "sms",
|
||||||
|
"fieldType": "account",
|
||||||
|
"fieldClass": "sms"
|
||||||
|
},
|
||||||
|
"fieldValue": {
|
||||||
|
"fieldType": "account",
|
||||||
|
"value": "mock-sms"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue