aboutsummaryrefslogtreecommitdiffstats
path: root/routes/lnurl.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2020-08-03 21:38:29 -0700
committerAdam Soltys <[email protected]>2020-08-03 21:38:29 -0700
commit2bcd5e9cd2233934b6d78724a07172b187ceb0b0 (patch)
treedba0c6451c1fa962dda1c3aa848abaa36d7012ab /routes/lnurl.js
parent1f44dadfb24913d9a6835f3b18340ede580e886a (diff)
downloadcoinos-server-2bcd5e9cd2233934b6d78724a07172b187ceb0b0.tar.gz
coinos-server-2bcd5e9cd2233934b6d78724a07172b187ceb0b0.zip
user urls
Diffstat (limited to 'routes/lnurl.js')
-rw-r--r--routes/lnurl.js381
1 files changed, 203 insertions, 178 deletions
diff --git a/routes/lnurl.js b/routes/lnurl.js
index d8336709..44eb0fb9 100644
--- a/routes/lnurl.js
+++ b/routes/lnurl.js
@@ -17,186 +17,217 @@ var optionalAuth = function (req, res, next) {
})(req, res, next);
};
-app.get("/url", ah(async (req, res, next) => {
- try {
- const code = await db.Code.findOne({
- where: {
- code: req.query.code,
- },
- });
+app.get(
+ "/url",
+ ah(async (req, res, next) => {
+ try {
+ const code = await db.Code.findOne({
+ where: {
+ code: req.query.code,
+ },
+ });
- if (code) {
- res.send(code.text);
- } else {
- throw new Error("code not found");
+ if (code) {
+ res.send(code.text);
+ } else {
+ throw new Error("code not found");
+ }
+ } catch (e) {
+ l.error("couldn't find url", e.message);
}
- } catch (e) {
- l.error("couldn't find url", e.message);
- }
-}));
-
-app.get("/withdraw", auth, ah(async (req, res, next) => {
- const { min, max } = req.query;
- try {
- const result = await lnurlServer.generateNewUrl("withdrawRequest", {
- minWithdrawable: min * 1000,
- maxWithdrawable: max * 1000,
- defaultDescription: "coinos voucher",
- });
+ })
+);
- withdrawals[result.secret] = req.user;
+app.get(
+ "/withdraw",
+ auth,
+ ah(async (req, res, next) => {
+ const { min, max } = req.query;
+ try {
+ const result = await lnurlServer.generateNewUrl("withdrawRequest", {
+ minWithdrawable: min * 1000,
+ maxWithdrawable: max * 1000,
+ defaultDescription: "coinos voucher",
+ });
- res.send(result);
- } catch (e) {
- l.error("problem generating withdrawl url", e.message);
- res.status(500).send(e.message);
- }
-}));
+ withdrawals[result.secret] = req.user;
-app.post("/code", ah(async (req, res, next) => {
- try {
- const { encoded } = req.body.lnurl;
- const code = await db.Code.create({
- code: "lnurl:" + encoded.substr(-32),
- text: encoded,
- });
+ res.send(result);
+ } catch (e) {
+ l.error("problem generating withdrawl url", e.message);
+ res.status(500).send(e.message);
+ }
+ })
+);
- res.send(code);
- } catch (e) {
- res.status(500).send(e.message);
- }
-}));
+app.post(
+ "/code",
+ ah(async (req, res, next) => {
+ try {
+ const { encoded } = req.body.lnurl;
+ const code = await db.Code.create({
+ code: "lnurl:" + encoded.substr(-32),
+ text: encoded,
+ });
-app.post("/withdraw", auth, ah(async (req, res, next) => {
- const { user } = req;
- const {
- amount: value,
- params: { callback, k1 },
- } = req.body;
- const invoice = await lna.addInvoice({ value });
- const { payment_request: pr } = invoice;
- const url = `${callback}?k1=${k1}&pr=${pr}`;
+ res.send(code);
+ } catch (e) {
+ res.status(500).send(e.message);
+ }
+ })
+);
- await db.Invoice.create({
- user_id: user.id,
- text: pr,
- rate: app.get("rates")[user.currency],
- currency: user.currency,
- amount: value,
- tip: 0,
- network: "BTC",
- });
+app.post(
+ "/withdraw",
+ auth,
+ ah(async (req, res, next) => {
+ const { user } = req;
+ const {
+ amount: value,
+ params: { callback, k1 },
+ } = req.body;
+ const invoice = await lna.addInvoice({ value });
+ const { payment_request: pr } = invoice;
+ const url = `${callback}?k1=${k1}&pr=${pr}`;
- try {
- result = (await axios.get(url)).data;
- res.send(result);
- } catch (e) {
- l.error("failed to withdraw", e.message);
- res.status(500).send(e.message);
- }
-}));
+ await db.Invoice.create({
+ user_id: user.id,
+ text: pr,
+ rate: app.get("rates")[user.currency],
+ currency: user.currency,
+ amount: value,
+ tip: 0,
+ network: "BTC",
+ });
-const pay = async ({ amount, minSendable, maxSendable }, res, user) => {
- minSendable = minSendable || 1000;
- maxSendable = maxSendable || 1000000000;
- if (parseInt(amount)) minSendable = maxSendable = amount * 1000;
+ try {
+ result = (await axios.get(url)).data;
+ res.send(result);
+ } catch (e) {
+ l.error("failed to withdraw", e.message);
+ res.status(500).send(e.message);
+ }
+ })
+);
- try {
- const result = await lnurlServer.generateNewUrl("payRequest", {
- minSendable,
- maxSendable,
- metadata: JSON.stringify([["text/plain", `paying ${user.username}`]]),
+app.get(
+ "/pay/:username",
+ ah(async (req, res, next) => {
+ const { username } = req.params;
+ let user = await db.User.findOne({
+ where: {
+ username,
+ },
});
- recipients[result.secret] = user;
- l.info("recipient", user.username, result.secret);
- res.send(result);
- } catch (e) {
- l.error("problem generating payment url", e.message);
- res.status(500).send(e.message);
- }
-};
+ let { amount, minSendable, maxSendable } = req.query;
+ minSendable = minSendable || 1000;
+ maxSendable = maxSendable || 1000000000;
+ if (parseInt(amount)) minSendable = maxSendable = amount * 1000;
-app.get("/pay/:username", ah(async (req, res, next) => {
- const { username } = req.params;
- let user = await db.User.findOne({
- where: {
- username,
- },
- });
- pay(req.query, res, user);
-}));
+ let invoices = await db.Invoice.findAll({
+ where: {
+ amount,
+ },
+ order: [["id", "DESC"]],
+ limit: 1,
+ });
-app.get("/pay", auth, ah(async (req, res, next) => {
- const { user } = req;
- pay(req.query, res, user);
-}));
+ if (invoices.length) await invoices[0].destroy();
-app.post("/pay", auth, ah(async (req, res, next) => {
- const { user } = req;
- const {
- amount,
- params: { callback, k1 },
- } = req.body;
+ try {
+ const result = await lnurlServer.generateNewUrl("payRequest", {
+ minSendable,
+ maxSendable,
+ metadata: JSON.stringify([["text/plain", `paying ${user.username}`]]),
+ });
- const url = `${callback}?amount=${amount * 1000}`;
- l.info("url", url);
+ recipients[result.secret] = user;
+ l.info("recipient", user.username, result.secret);
+ res.send(result);
+ } catch (e) {
+ l.error("problem generating payment url", e.message);
+ res.status(500).send(e.message);
+ }
+ })
+);
- try {
- const parts = callback.split("/");
- const secret = parts[parts.length - 1];
- payments[secret] = user;
+app.post(
+ "/pay",
+ auth,
+ ah(async (req, res, next) => {
+ const { user } = req;
+ const {
+ amount,
+ params: { callback, k1 },
+ } = req.body;
- const result = (await axios.get(url)).data;
- res.send(await send(amount, '', result.pr, user));
- } catch (e) {
- l.error("failed to send payment", e.message);
- res.status(500).send(e.message);
- }
-}));
+ const url = `${callback}?amount=${amount * 1000}`;
-app.get("/login", optionalAuth, ah(async (req, res, next) => {
- try {
- const result = await lnurlServer.generateNewUrl("login");
+ try {
+ const parts = callback.split("/");
+ const secret = parts[parts.length - 1];
+ payments[secret] = user;
- if (req.user) {
- logins[result.secret] = req.user.username;
+ const result = (await axios.get(url)).data;
+ res.send(await send(amount, "", result.pr, user));
+ } catch (e) {
+ l.error("failed to send payment", e.message);
+ throw e;
+ res.status(500).send(e.message);
}
+ })
+);
- res.send(result);
- } catch (e) {
- l.error("problem generating login url", e.message);
- res.status(500).send(e.message);
- }
-}));
+app.get(
+ "/login",
+ optionalAuth,
+ ah(async (req, res, next) => {
+ try {
+ const result = await lnurlServer.generateNewUrl("login");
-app.get("/decode", ah(async (req, res, next) => {
- const { text } = req.query;
+ if (req.user) {
+ logins[result.secret] = req.user.username;
+ }
- try {
- const url = lnurl.decode(text);
- let spl = url.split("?");
- if (spl.length > 1 && qs.parse(spl[1]).tag === "login") {
- return res.send({
- tag: "login",
- k1: qs.parse(spl[1]).k1,
- callback: url,
- domain: url
- .split("://")[1]
- .split("/")[0]
- .split("@")
- .slice(-1)[0]
- .split(":")[0],
- });
+ res.send(result);
+ } catch (e) {
+ l.error("problem generating login url", e.message);
+ res.status(500).send(e.message);
}
+ })
+);
- const { data: params } = await axios.get(url);
- res.send(params);
- } catch (e) {
- l.error("problem decoding lnurl", e.message);
- res.status(500).send(e.message);
- }
-}));
+app.get(
+ "/decode",
+ ah(async (req, res, next) => {
+ const { text } = req.query;
+
+ try {
+ const url = lnurl.decode(text);
+ let spl = url.split("?");
+ if (spl.length > 1 && qs.parse(spl[1]).tag === "login") {
+ return res.send({
+ tag: "login",
+ k1: qs.parse(spl[1]).k1,
+ callback: url,
+ domain: url
+ .split("://")[1]
+ .split("/")[0]
+ .split("@")
+ .slice(-1)[0]
+ .split(":")[0],
+ });
+ }
+
+ const { data: params } = await axios.get(url);
+ res.send(params);
+ } catch (e) {
+ l.error("problem decoding lnurl", e.message);
+ res.status(500).send(e.message);
+ }
+ })
+);
lnurlServer.bindToHook(
"middleware:signedLnurl:afterCheckSignature",
@@ -221,36 +252,29 @@ lnurlServer.bindToHook(
if (account.balance < amount) {
throw new Error("Insufficient funds");
}
-
- l.info("lnurl payment", user.username, amount);
}
const recipient = recipients[secret];
if (recipient) {
- setTimeout(async () => {
- try {
- let { invoices } = await lnb.listInvoices({
- pending_only: true,
- num_max_invoices: 1,
- reversed: true,
- });
- let i = invoices.find((i) => parseInt(i.value) === amount);
- if (i) {
- await db.Invoice.create({
- user_id: recipient.id,
- text: i.payment_request,
- rate: app.get("rates")[recipient.currency],
- currency: recipient.currency,
- amount: Math.round(amount / 1000),
- tip: 0,
- network: "BTC",
- });
- }
- } catch (e) {
- l.error("problem trying to get create payment invoice", e);
- }
- }, 1000);
+ setTimeout(async () => {
+ let { invoices } = await lnb.listInvoices({
+ pending_only: true,
+ });
+
+ if (invoices.length) {
+ let invoice = await db.Invoice.create({
+ user_id: recipient.id,
+ text: invoices[invoices.length - 1].payment_request,
+ rate: app.get("rates")[recipient.currency],
+ currency: recipient.currency,
+ amount,
+ tip: 0,
+ network: "BTC",
+ });
+ l.info("invoice created", invoice.text, invoice.amount);
+ }
+ }, 100);
}
}
@@ -337,6 +361,7 @@ lnurlServer.bindToHook(
let p = payments.find((p) => p.payment_request === pr);
if (p) {
+ l.info("found payment", pr);
payment.fee = p.fee;
account.balance -= p.fee;
await account.save();