Reserve notes for redeem

This commit is contained in:
Josh Harvey 2017-05-04 21:27:12 +03:00
parent 1488a60a60
commit 67e12b19cb
6 changed files with 235 additions and 93 deletions

View file

@ -15,6 +15,7 @@ const wallet = require('./wallet')
const exchange = require('./exchange')
const sms = require('./sms')
const email = require('./email')
const cashOutHelper = require('./cash-out-helper')
const mapValuesWithKey = _.mapValues.convert({cap: false})
@ -71,47 +72,83 @@ function plugins (settings, deviceId) {
return balances
}
function buildCassettes () {
function isZeroConf (tx) {
const config = configManager.scoped(tx.cryptoCode, deviceId, settings.config)
const zeroConfLimit = config.zeroConfLimit
return tx.fiat.lte(zeroConfLimit)
}
function computeAvailableCassettes (cassettes, redeemableTxs) {
if (_.isEmpty(redeemableTxs)) return cassettes
const sumTxs = (sum, tx) => {
const bills = tx.bills
const sameDenominations = a => a[0].denomination === a[1].denomination
const doDenominationsMatch = _.every(sameDenominations, _.zip(cassettes, bills))
if (!doDenominationsMatch) {
throw new Error('Denominations don\'t add up, cassettes were changed.')
}
return _.map(r => r[0] + r[1].provisioned, _.zip(sum, tx.bills))
}
const provisioned = _.reduce(sumTxs, [0, 0], redeemableTxs)
const zipped = _.zip(_.map('count', cassettes), provisioned)
const counts = _.map(r => r[0] - r[1], zipped)
if (_.some(_.lt(_, 0), counts)) {
throw new Error('Negative note count: %j', counts)
}
return [
{
denomination: cassettes[0].denomination,
count: counts[0]
},
{
denomination: cassettes[1].denomination,
count: counts[1]
}
]
}
function buildAvailableCassettes (excludeTxId) {
const config = configManager.machineScoped(deviceId, settings.config)
if (!config.cashOutEnabled) return Promise.resolve()
const cassettes = [ config.topCashOutDenomination,
const denominations = [ config.topCashOutDenomination,
config.bottomCashOutDenomination ]
const virtualCassettes = [config.virtualCashOutDenomination]
return dbm.cassetteCounts(deviceId)
.then(rec => {
if (argv.cassettes) {
const counts = argv.cassettes.split(',')
return Promise.all([dbm.cassetteCounts(deviceId), cashOutHelper.redeemableTxs(deviceId, excludeTxId)])
.then(([rec, _redeemableTxs]) => {
const redeemableTxs = _.reject(_.matchesProperty('id', excludeTxId), _redeemableTxs)
const counts = argv.cassettes
? argv.cassettes.split(',')
: rec.counts
const cassettes = [
{
denomination: parseInt(denominations[0], 10),
count: parseInt(counts[0], 10)
},
{
denomination: parseInt(denominations[1], 10),
count: parseInt(counts[1], 10)
}
]
try {
return {
cassettes: [
{
denomination: parseInt(cassettes[0], 10),
count: parseInt(counts[0], 10)
},
{
denomination: parseInt(cassettes[1], 10),
count: parseInt(counts[1], 10)
}
],
cassettes: computeAvailableCassettes(cassettes, redeemableTxs),
virtualCassettes
}
}
return {
cassettes: [
{
denomination: parseInt(cassettes[0], 10),
count: parseInt(rec.counts[0], 10)
},
{
denomination: parseInt(cassettes[1], 10),
count: parseInt(rec.counts[1], 10)
}
],
virtualCassettes
} catch (err) {
logger.error(err)
return {cassettes, virtualCassettes}
}
})
}
@ -138,7 +175,7 @@ function plugins (settings, deviceId) {
const currentConfigVersionPromise = fetchCurrentConfigVersion()
const promises = [
buildCassettes(),
buildAvailableCassettes(),
pingPromise,
currentConfigVersionPromise
].concat(tickerPromises, balancePromises)
@ -512,6 +549,7 @@ function plugins (settings, deviceId) {
sendCoins,
newAddress,
isHd,
isZeroConf,
getStatus,
dispenseAck,
getPhoneCode,
@ -522,7 +560,7 @@ function plugins (settings, deviceId) {
sweepHd,
sendMessage,
checkBalances,
buildCassettes,
buildAvailableCassettes,
buy,
sell
}