FIX: properly locked payments
This commit is contained in:
parent
afb07aa9ba
commit
8f2d98774b
@ -2,14 +2,15 @@ var crypto = require('crypto');
|
||||
var lightningPayReq = require('bolt11');
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
|
||||
export class Paym {
|
||||
export class Payment {
|
||||
constructor(redis, bitcoindrpc, lightning) {
|
||||
this._redis = redis;
|
||||
this._bitcoindrpc = bitcoindrpc;
|
||||
this._lightning = lightning;
|
||||
this._decoded = false;
|
||||
}
|
||||
|
||||
async decodePayReq(invoice) {
|
||||
async decodePayReqViaRpc(invoice) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
this._lightning.decodePayReq({ pay_req: invoice }, function(err, info) {
|
||||
if (err) return reject(err);
|
||||
@ -17,4 +18,8 @@ export class Paym {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
decodePayReq(payReq) {
|
||||
this._decoded = lightningPayReq.decode(payReq);
|
||||
}
|
||||
}
|
||||
|
@ -153,6 +153,13 @@ export class User {
|
||||
calculatedBalance -= +tx.value;
|
||||
}
|
||||
}
|
||||
|
||||
let lockedPayments = await this.getLockedPayments();
|
||||
for (let paym of lockedPayments) {
|
||||
// TODO: check if payment in determined state and actually evict it from this list
|
||||
calculatedBalance -= +paym.amount;
|
||||
}
|
||||
|
||||
return calculatedBalance;
|
||||
}
|
||||
|
||||
@ -386,6 +393,59 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds invoice to a list of user's locked payments.
|
||||
* Used to calculate balance till the lock is lifted (payment is in
|
||||
* determined state - succeded or failed).
|
||||
*
|
||||
* @param {String} pay_req
|
||||
* @param {Object} decodedInvoice
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async lockFunds(pay_req, decodedInvoice) {
|
||||
let doc = {
|
||||
pay_req,
|
||||
amount: +decodedInvoice.num_satoshis,
|
||||
timestamp: Math.floor(+new Date() / 1000),
|
||||
};
|
||||
|
||||
return this._redis.rpush('locked_payments_for_' + this._userid, JSON.stringify(doc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips specific payreq from the list of locked payments
|
||||
* @param pay_req
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async unlockFunds(pay_req) {
|
||||
let payments = await this.getLockedPayments();
|
||||
let saveBack = [];
|
||||
for (let paym of payments) {
|
||||
if (paym.pay_req !== pay_req) {
|
||||
saveBack.push(paym);
|
||||
}
|
||||
}
|
||||
|
||||
await this._redis.del('locked_payments_for_' + this._userid);
|
||||
for (let doc of saveBack) {
|
||||
await this._redis.rpush('locked_payments_for_' + this._userid, JSON.stringify(doc));
|
||||
}
|
||||
}
|
||||
|
||||
async getLockedPayments() {
|
||||
let payments = await this._redis.lrange('locked_payments_for_' + this._userid, 0, -1);
|
||||
let result = [];
|
||||
for (let paym of payments) {
|
||||
let json;
|
||||
try {
|
||||
json = JSON.parse(paym);
|
||||
result.push(json);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
_hash(string) {
|
||||
return crypto
|
||||
.createHash('sha256')
|
||||
|
@ -185,6 +185,7 @@ router.post('/payinvoice', async function(req, res) {
|
||||
var call = lightning.sendPayment();
|
||||
call.on('data', async function(payment) {
|
||||
// payment callback
|
||||
await u.unlockFunds(req.body.invoice);
|
||||
if (payment && payment.payment_route && payment.payment_route.total_amt_msat) {
|
||||
userBalance -= +payment.payment_route.total_fees + +payment.payment_route.total_amt;
|
||||
u.saveBalance(userBalance);
|
||||
@ -206,6 +207,7 @@ router.post('/payinvoice', async function(req, res) {
|
||||
}
|
||||
let inv = { payment_request: req.body.invoice, amt: info.num_satoshis }; // amt is used only for 'tip' invoices
|
||||
try {
|
||||
await u.lockFunds(req.body.invoice, info);
|
||||
call.write(inv);
|
||||
} catch (Err) {
|
||||
await lock.releaseLock();
|
||||
|
@ -20,6 +20,8 @@ User storage schema
|
||||
* bitcoin_address_for_{userid} = {address}
|
||||
* balance_for_{userid} = {int}
|
||||
* txs_for_{userid} = [] `serialized paid lnd invoices in a list`
|
||||
* locked_invoices_for_{userod} = [] `serialized attempts to pay invoice. used in calculating user's balance`
|
||||
: {pay_req:..., amount:666, timestamp:666}
|
||||
* imported_txids_for_{userid} = [] `list of txids processed for this user`
|
||||
* metadata_for_{userid}= {serialized json}
|
||||
* userinvoices_for_{userid} = []
|
||||
|
Loading…
x
Reference in New Issue
Block a user