ADD: create invoice, pay internal invoice

This commit is contained in:
igor 2018-12-10 15:11:16 +00:00
parent 1aa9827e1c
commit fbd605b4cc
5 changed files with 510 additions and 249 deletions

View File

@ -1,4 +1,5 @@
var crypto = require('crypto');
var lightningPayReq = require('bolt11');
import { BigNumber } from 'bignumber.js';
export class User {
@ -121,6 +122,63 @@ export class User {
return await this._redis.rpush('txs_for_' + this._userid, JSON.stringify(doc));
}
async saveUserInvoice(doc) {
let decoded = lightningPayReq.decode(doc.payment_request);
let payment_hash;
for (let tag of decoded.tags) {
if (tag.tagName === 'payment_hash') {
payment_hash = tag.data;
}
}
await this._redis.set('payment_hash_' + payment_hash, this._userid);
return await this._redis.rpush('userinvoices_for_' + this._userid, JSON.stringify(doc));
}
/**
* Doent belong here, FIXME
*/
async getUseridByPaymentHash(payment_hash) {
return await this._redis.get('payment_hash_' + payment_hash);
}
/**
* Doent belong here, FIXME
*/
async setPaymentHashPaid(payment_hash) {
return await this._redis.set('ispaid_' + payment_hash, 1);
}
/**
* Doent belong here, FIXME
*/
async getPaymentHashPaid(payment_hash) {
return await this._redis.get('ispaid_' + payment_hash);
}
async getUserInvoices() {
let range = await this._redis.lrange('userinvoices_for_' + this._userid, 0, -1);
let result = [];
for (let invoice of range) {
invoice = JSON.parse(invoice);
let decoded = lightningPayReq.decode(invoice.payment_request);
invoice.description = '';
for (let tag of decoded.tags) {
if (tag.tagName === 'description') {
invoice.description += decodeURIComponent(tag.data);
}
if (tag.tagName === 'payment_hash') {
invoice.payment_hash = tag.data;
}
}
invoice.ispaid = !!(await this.getPaymentHashPaid(invoice.payment_hash));
invoice.amt = decoded.satoshis;
result.push(invoice);
}
return result;
}
async addAddress(address) {
await this._redis.set('bitcoin_address_for_' + this._userid, address);
}

View File

@ -15,7 +15,7 @@ redis.monitor(function(err, monitor) {
let bitcoinclient = require('../bitcoin');
let lightning = require('../lightning');
let identity_pubkey = false;
// ###################### SMOKE TESTS ########################
bitcoinclient.request('getblockchaininfo', false, function(err, info) {
@ -40,6 +40,7 @@ lightning.getInfo({}, function(err, info) {
console.error('lnd not synced');
process.exit(4);
}
identity_pubkey = info.identity_pubkey;
}
});
@ -83,6 +84,25 @@ router.post('/auth', async function(req, res) {
}
});
router.post('/addinvoice', async function(req, res) {
let u = new User(redis);
if (!(await u.loadByAuthorization(req.headers.authorization))) {
return errorBadAuth(res);
}
assert.ok(req.body.amt);
lightning.addInvoice({ memo: req.body.memo, value: req.body.amt }, async function(err, info) {
if (err) return errorLnd(res);
info.pay_req = info.payment_request; // client backwards compatibility
console.log(info);
await u.saveUserInvoice(info);
res.send(info);
});
});
router.post('/payinvoice', async function(req, res) {
let u = new User(redis);
if (!(await u.loadByAuthorization(req.headers.authorization))) {
@ -92,11 +112,34 @@ router.post('/payinvoice', async function(req, res) {
let userBalance = await u.getBalance();
lightning.decodePayReq({ pay_req: req.body.invoice }, function(err, info) {
lightning.decodePayReq({ pay_req: req.body.invoice }, async function(err, info) {
if (err) return errorNotAValidInvoice(res);
if (userBalance > info.num_satoshis) {
if (userBalance >= info.num_satoshis) {
// got enough balance
console.log('infoinfoinfoinfoinfoinfoinfoinfoinfoinfo', info);
if (identity_pubkey === info.destination) {
// this is internal invoice
// now, receiver add balance
let userid_payee = await u.getUseridByPaymentHash(info.payment_hash);
if (!userid_payee) return errorGeneralServerError(res);
let UserPayee = new User(redis);
UserPayee._userid = userid_payee; // hacky, fixme
let payee_balance = await UserPayee.getBalance();
payee_balance += info.num_satoshis * 1;
await UserPayee.saveBalance(payee_balance);
// sender spent his balance:
userBalance -= info.num_satoshis * 1;
await u.saveBalance(userBalance);
await u.setPaymentHashPaid(info.payment_hash);
return res.send(info);
}
var call = lightning.sendPayment();
call.on('data', function(payment) {
// payment callback
@ -173,6 +216,16 @@ router.get('/gettxs', async function(req, res) {
res.send(txs);
});
router.get('/getuserinvoices', async function(req, res) {
let u = new User(redis, bitcoinclient, lightning);
if (!(await u.loadByAuthorization(req.headers.authorization))) {
return errorBadAuth(res);
}
let invoices = await u.getUserInvoices();
res.send(invoices);
});
router.get('/getpending', async function(req, res) {
let u = new User(redis, bitcoinclient, lightning);
if (!(await u.loadByAuthorization(req.headers.authorization))) {

View File

@ -20,5 +20,8 @@ User storage schema
* txs_for_{userid} = [] `serialized paid lnd invoices in a list`
* imported_txids_for_{userid} = [] `list of txids processed for this user`
* metadata_for_{userid}= {serialized json}
* userinvoices_for_{userid} = []
* payment_hash_{payment_hash} = {userid}
* ispaid_{payment_hash} = 1

638
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
"babel-register": "^6.26.0",
"bignumber.js": "^8.0.1",
"bitcoinjs-lib": "^4.0.2",
"bolt11": "https://github.com/bitcoinjs/bolt11",
"eslint": "^5.9.0",
"eslint-config-prettier": "^3.3.0",
"eslint-plugin-prettier": "^3.0.0",