ADD: create invoice, pay internal invoice
This commit is contained in:
parent
1aa9827e1c
commit
fbd605b4cc
@ -1,4 +1,5 @@
|
|||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
|
var lightningPayReq = require('bolt11');
|
||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
|
|
||||||
export class User {
|
export class User {
|
||||||
@ -121,6 +122,63 @@ export class User {
|
|||||||
return await this._redis.rpush('txs_for_' + this._userid, JSON.stringify(doc));
|
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) {
|
async addAddress(address) {
|
||||||
await this._redis.set('bitcoin_address_for_' + this._userid, address);
|
await this._redis.set('bitcoin_address_for_' + this._userid, address);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ redis.monitor(function(err, monitor) {
|
|||||||
|
|
||||||
let bitcoinclient = require('../bitcoin');
|
let bitcoinclient = require('../bitcoin');
|
||||||
let lightning = require('../lightning');
|
let lightning = require('../lightning');
|
||||||
|
let identity_pubkey = false;
|
||||||
// ###################### SMOKE TESTS ########################
|
// ###################### SMOKE TESTS ########################
|
||||||
|
|
||||||
bitcoinclient.request('getblockchaininfo', false, function(err, info) {
|
bitcoinclient.request('getblockchaininfo', false, function(err, info) {
|
||||||
@ -40,6 +40,7 @@ lightning.getInfo({}, function(err, info) {
|
|||||||
console.error('lnd not synced');
|
console.error('lnd not synced');
|
||||||
process.exit(4);
|
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) {
|
router.post('/payinvoice', async function(req, res) {
|
||||||
let u = new User(redis);
|
let u = new User(redis);
|
||||||
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
||||||
@ -92,11 +112,34 @@ router.post('/payinvoice', async function(req, res) {
|
|||||||
|
|
||||||
let userBalance = await u.getBalance();
|
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 (err) return errorNotAValidInvoice(res);
|
||||||
|
|
||||||
if (userBalance > info.num_satoshis) {
|
if (userBalance >= info.num_satoshis) {
|
||||||
// got enough balance
|
// 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();
|
var call = lightning.sendPayment();
|
||||||
call.on('data', function(payment) {
|
call.on('data', function(payment) {
|
||||||
// payment callback
|
// payment callback
|
||||||
@ -173,6 +216,16 @@ router.get('/gettxs', async function(req, res) {
|
|||||||
res.send(txs);
|
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) {
|
router.get('/getpending', async function(req, res) {
|
||||||
let u = new User(redis, bitcoinclient, lightning);
|
let u = new User(redis, bitcoinclient, lightning);
|
||||||
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
||||||
|
@ -20,5 +20,8 @@ User storage schema
|
|||||||
* txs_for_{userid} = [] `serialized paid lnd invoices in a list`
|
* txs_for_{userid} = [] `serialized paid lnd invoices in a list`
|
||||||
* imported_txids_for_{userid} = [] `list of txids processed for this user`
|
* imported_txids_for_{userid} = [] `list of txids processed for this user`
|
||||||
* metadata_for_{userid}= {serialized json}
|
* metadata_for_{userid}= {serialized json}
|
||||||
|
* userinvoices_for_{userid} = []
|
||||||
|
* payment_hash_{payment_hash} = {userid}
|
||||||
|
* ispaid_{payment_hash} = 1
|
||||||
|
|
||||||
|
|
638
package-lock.json
generated
638
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,7 @@
|
|||||||
"babel-register": "^6.26.0",
|
"babel-register": "^6.26.0",
|
||||||
"bignumber.js": "^8.0.1",
|
"bignumber.js": "^8.0.1",
|
||||||
"bitcoinjs-lib": "^4.0.2",
|
"bitcoinjs-lib": "^4.0.2",
|
||||||
|
"bolt11": "https://github.com/bitcoinjs/bolt11",
|
||||||
"eslint": "^5.9.0",
|
"eslint": "^5.9.0",
|
||||||
"eslint-config-prettier": "^3.3.0",
|
"eslint-config-prettier": "^3.3.0",
|
||||||
"eslint-plugin-prettier": "^3.0.0",
|
"eslint-plugin-prettier": "^3.0.0",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user