Merge branch 'master' of github.com:BlueWallet/LndHub
This commit is contained in:
@@ -9,7 +9,7 @@ var Redis = require('ioredis');
|
||||
var redis = new Redis(config.redis);
|
||||
redis.monitor(function(err, monitor) {
|
||||
monitor.on('monitor', function(time, args, source, database) {
|
||||
console.log('REDIS', JSON.stringify(args));
|
||||
// console.log('REDIS', JSON.stringify(args));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ router.post('/create', async function(req, res) {
|
||||
logger.log('/create', [req.id]);
|
||||
if (!(req.body.partnerid && req.body.partnerid === 'bluewallet' && req.body.accounttype)) return errorBadArguments(res);
|
||||
|
||||
let u = new User(redis);
|
||||
let u = new User(redis, bitcoinclient, lightning);
|
||||
await u.create();
|
||||
await u.saveMetadata({ partnerid: req.body.partnerid, accounttype: req.body.accounttype, created_at: new Date().toISOString() });
|
||||
res.send({ login: u.getLogin(), password: u.getPassword() });
|
||||
@@ -68,7 +68,7 @@ router.post('/auth', async function(req, res) {
|
||||
logger.log('/auth', [req.id]);
|
||||
if (!((req.body.login && req.body.password) || req.body.refresh_token)) return errorBadArguments(res);
|
||||
|
||||
let u = new User(redis);
|
||||
let u = new User(redis, bitcoinclient, lightning);
|
||||
|
||||
if (req.body.refresh_token) {
|
||||
// need to refresh token
|
||||
@@ -87,7 +87,7 @@ router.post('/auth', async function(req, res) {
|
||||
|
||||
router.post('/addinvoice', async function(req, res) {
|
||||
logger.log('/addinvoice', [req.id]);
|
||||
let u = new User(redis);
|
||||
let u = new User(redis, bitcoinclient, lightning);
|
||||
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
||||
return errorBadAuth(res);
|
||||
}
|
||||
@@ -105,15 +105,19 @@ router.post('/addinvoice', async function(req, res) {
|
||||
});
|
||||
|
||||
router.post('/payinvoice', async function(req, res) {
|
||||
logger.log('/payinvoice', [req.id]);
|
||||
let u = new User(redis);
|
||||
let u = new User(redis, bitcoinclient, lightning);
|
||||
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
||||
return errorBadAuth(res);
|
||||
}
|
||||
|
||||
logger.log('/payinvoice', [req.id, 'userid: ' + u.getUserId(), 'invoice: ' + req.body.invoice]);
|
||||
|
||||
if (!req.body.invoice) return errorBadArguments(res);
|
||||
let freeAmount = false;
|
||||
if (req.body.amount) freeAmount = parseInt(req.body.amount);
|
||||
if (req.body.amount) {
|
||||
freeAmount = parseInt(req.body.amount);
|
||||
if (freeAmount <= 0) return errorBadArguments(res);
|
||||
}
|
||||
|
||||
// obtaining a lock
|
||||
let lock = new Lock(redis, 'invoice_paying_for_' + u.getUserId());
|
||||
@@ -121,7 +125,7 @@ router.post('/payinvoice', async function(req, res) {
|
||||
return errorTryAgainLater(res);
|
||||
}
|
||||
|
||||
let userBalance = await u.getBalance();
|
||||
let userBalance = await u.getCalculatedBalance();
|
||||
|
||||
lightning.decodePayReq({ pay_req: req.body.invoice }, async function(err, info) {
|
||||
if (err) {
|
||||
@@ -134,8 +138,10 @@ router.post('/payinvoice', async function(req, res) {
|
||||
info.num_satoshis = freeAmount;
|
||||
}
|
||||
|
||||
if (userBalance >= info.num_satoshis) {
|
||||
// got enough balance
|
||||
logger.log('/payinvoice', [req.id, 'userBalance: ' + userBalance, 'num_satoshis: ' + info.num_satoshis]);
|
||||
|
||||
if (userBalance >= +info.num_satoshis + Math.floor(info.num_satoshis * 0.01)) {
|
||||
// got enough balance, including 1% of payment amount - reserve for fees
|
||||
|
||||
if (identity_pubkey === info.destination) {
|
||||
// this is internal invoice
|
||||
@@ -152,7 +158,7 @@ router.post('/payinvoice', async function(req, res) {
|
||||
return errorLnd(res);
|
||||
}
|
||||
|
||||
let UserPayee = new User(redis);
|
||||
let UserPayee = new User(redis, bitcoinclient, lightning);
|
||||
UserPayee._userid = userid_payee; // hacky, fixme
|
||||
let payee_balance = await UserPayee.getBalance();
|
||||
payee_balance += info.num_satoshis * 1;
|
||||
@@ -164,8 +170,8 @@ router.post('/payinvoice', async function(req, res) {
|
||||
await u.savePaidLndInvoice({
|
||||
timestamp: parseInt(+new Date() / 1000),
|
||||
type: 'paid_invoice',
|
||||
value: info.num_satoshis * 1,
|
||||
fee: 0, // internal invoices are free
|
||||
value: +info.num_satoshis + Math.floor(info.num_satoshis * 0.01),
|
||||
fee: Math.floor(info.num_satoshis * 0.01),
|
||||
memo: decodeURIComponent(info.description),
|
||||
});
|
||||
|
||||
@@ -178,14 +184,16 @@ router.post('/payinvoice', async function(req, res) {
|
||||
// else - regular lightning network payment:
|
||||
|
||||
var call = lightning.sendPayment();
|
||||
call.on('data', function(payment) {
|
||||
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) {
|
||||
payment.payment_route.total_fees += Math.floor(+payment.payment_route.total_amt * 0.01);
|
||||
userBalance -= +payment.payment_route.total_fees + +payment.payment_route.total_amt;
|
||||
u.saveBalance(userBalance);
|
||||
payment.pay_req = req.body.invoice;
|
||||
payment.decoded = info;
|
||||
u.savePaidLndInvoice(payment);
|
||||
await u.savePaidLndInvoice(payment);
|
||||
lock.releaseLock();
|
||||
res.send(payment);
|
||||
} else {
|
||||
@@ -199,12 +207,15 @@ router.post('/payinvoice', async function(req, res) {
|
||||
await lock.releaseLock();
|
||||
return errorBadArguments(res);
|
||||
}
|
||||
let inv = { payment_request: req.body.invoice, amt: info.num_satoshis }; // amt is used only for 'tip' invoices
|
||||
let inv = {
|
||||
payment_request: req.body.invoice,
|
||||
amt: info.num_satoshis, // amt is used only for 'tip' invoices
|
||||
fee_limit: { fixed: Math.floor(info.num_satoshis * 0.005) },
|
||||
};
|
||||
try {
|
||||
logger.log('/payinvoice', [req.id, 'before write', JSON.stringify(inv)]);
|
||||
await u.lockFunds(req.body.invoice, info);
|
||||
call.write(inv);
|
||||
} catch (Err) {
|
||||
logger.log('/payinvoice', [req.id, 'exception', JSON.stringify(Err)]);
|
||||
await lock.releaseLock();
|
||||
return errorLnd(res);
|
||||
}
|
||||
@@ -243,12 +254,13 @@ router.get('/balance', async function(req, res) {
|
||||
if (!(await u.getAddress())) await u.generateAddress(); // onchain address needed further
|
||||
u.accountForPosibleTxids();
|
||||
let balance = await u.getBalance();
|
||||
if (balance < 0) balance = 0;
|
||||
res.send({ BTC: { AvailableBalance: balance } });
|
||||
});
|
||||
|
||||
router.get('/getinfo', async function(req, res) {
|
||||
logger.log('/getinfo', [req.id]);
|
||||
let u = new User(redis);
|
||||
let u = new User(redis, bitcoinclient, lightning);
|
||||
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
||||
return errorBadAuth(res);
|
||||
}
|
||||
@@ -272,7 +284,7 @@ router.get('/gettxs', async function(req, res) {
|
||||
let txs = await u.getTxs();
|
||||
res.send(txs);
|
||||
} catch (Err) {
|
||||
console.log(Err);
|
||||
logger.log('', [req.id, 'error:', Err]);
|
||||
res.send([]);
|
||||
}
|
||||
});
|
||||
@@ -292,7 +304,7 @@ router.get('/getuserinvoices', async function(req, res) {
|
||||
res.send(invoices);
|
||||
}
|
||||
} catch (Err) {
|
||||
console.log(Err);
|
||||
logger.log('', [req.id, 'error:', Err]);
|
||||
res.send([]);
|
||||
}
|
||||
});
|
||||
@@ -312,7 +324,7 @@ router.get('/getpending', async function(req, res) {
|
||||
|
||||
router.get('/decodeinvoice', async function(req, res) {
|
||||
logger.log('/decodeinvoice', [req.id]);
|
||||
let u = new User(redis, bitcoinclient);
|
||||
let u = new User(redis, bitcoinclient, lightning);
|
||||
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
||||
return errorBadAuth(res);
|
||||
}
|
||||
@@ -327,7 +339,7 @@ router.get('/decodeinvoice', async function(req, res) {
|
||||
|
||||
router.get('/checkrouteinvoice', async function(req, res) {
|
||||
logger.log('/checkrouteinvoice', [req.id]);
|
||||
let u = new User(redis, bitcoinclient);
|
||||
let u = new User(redis, bitcoinclient, lightning);
|
||||
if (!(await u.loadByAuthorization(req.headers.authorization))) {
|
||||
return errorBadAuth(res);
|
||||
}
|
||||
@@ -398,6 +410,6 @@ function errorTryAgainLater(res) {
|
||||
return res.send({
|
||||
error: true,
|
||||
code: 9,
|
||||
message: 'Try again later',
|
||||
message: 'Your previous payment is in transit. Try again in 5 minutes',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,14 +12,15 @@ function updateLightning() {
|
||||
try {
|
||||
lightning.getInfo({}, function(err, info) {
|
||||
if (err) {
|
||||
console.error('lnd failure');
|
||||
console.error('lnd failure:', err);
|
||||
}
|
||||
lightningGetInfo = info;
|
||||
});
|
||||
|
||||
lightning.listChannels({}, function(err, response) {
|
||||
if (err) {
|
||||
console.error('lnd failure');
|
||||
console.error('lnd failure:', err);
|
||||
return;
|
||||
}
|
||||
lightningListChannels = response;
|
||||
let channels = [];
|
||||
@@ -44,6 +45,7 @@ function updateLightning() {
|
||||
} catch (Err) {
|
||||
console.log(Err);
|
||||
}
|
||||
console.log('updated');
|
||||
}
|
||||
updateLightning();
|
||||
setInterval(updateLightning, 60000);
|
||||
@@ -61,6 +63,11 @@ const pubkey2name = {
|
||||
'024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca': 'satoshis.place',
|
||||
'03c2abfa93eacec04721c019644584424aab2ba4dff3ac9bdab4e9c97007491dda': 'tippin.me',
|
||||
'022c699df736064b51a33017abfc4d577d133f7124ac117d3d9f9633b6297a3b6a': 'globee.com',
|
||||
'0237fefbe8626bf888de0cad8c73630e32746a22a2c4faa91c1d9877a3826e1174': '1.ln.aantonop.com',
|
||||
'036a54f02d2186de192e4bcec3f7b47adb43b1fa965793387cd2471990ce1d236b': 'capacity.network',
|
||||
'026c7d28784791a4b31a64eb34d9ab01552055b795919165e6ae886de637632efb': 'LivingRoomOfSatoshi.com_LND_1',
|
||||
'02816caed43171d3c9854e3b0ab2cf0c42be086ff1bd4005acc2a5f7db70d83774': 'ln.pizza',
|
||||
'024a2e265cd66066b78a788ae615acdc84b5b0dec9efac36d7ac87513015eaf6ed': 'Bitrefill.com/lightning',
|
||||
};
|
||||
|
||||
router.get('/', function(req, res) {
|
||||
|
||||
Reference in New Issue
Block a user