aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-24 12:28:49 -0800
committerAdam Soltys <[email protected]>2023-01-24 12:28:49 -0800
commit692315c0d4259a274322ca579a7b6118d033bf7a (patch)
tree50dab3d2760130c5822b21f7293da3b34639579c /routes
parentf24aec1fb7dd4080d961c26ab5216fd2dfe5d971 (diff)
downloadcoinos-server-692315c0d4259a274322ca579a7b6118d033bf7a.tar.gz
coinos-server-692315c0d4259a274322ca579a7b6118d033bf7a.zip
lnurl
Diffstat (limited to 'routes')
-rw-r--r--routes/invoices.js75
-rw-r--r--routes/lnurl.js66
-rw-r--r--routes/payments.js46
3 files changed, 107 insertions, 80 deletions
diff --git a/routes/invoices.js b/routes/invoices.js
index 5da481e1..a4155d94 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -1,13 +1,5 @@
-import store from "$lib/store";
-import { l } from "$lib/logging";
-import { emit } from "$lib/sockets";
-import { db, g, s } from "$lib/db";
-import { bip21, fail } from "$lib/utils";
-import { types } from "$lib/payments";
-import { v4 } from "uuid";
-
-import bc from "$lib/bitcoin";
-import ln from "$lib/ln";
+import { g, s } from "$lib/db";
+import { invoice } from "$lib/invoices";
export default {
async get({ query: { hash } }, res) {
@@ -16,66 +8,7 @@ export default {
res.send(invoice);
},
- async create({ body: { invoice, user }, user: me }, res) {
- let { currency, tip, amount, rate, request_id, type } = invoice;
-
- if (amount < 0) fail("amount out of range");
- if (tip > 5 * amount || tip < 0) fail("tip amount out of range");
- tip = tip || 0;
-
- if (!user) user = me;
- let uid = await g(`user:${user.username}`);
- user = await g(`user:${uid}`);
-
- if (!user) fail("user not provided");
-
- if (!currency) currency = user.currency;
- if (!rate) rate = store.rates[currency];
- if (amount < 0) fail("invalid amount");
-
- let hash, text;
- if (type === types.lightning) {
- let amt = amount ? `${amount + tip}sat` : "any";
- let r = await ln.invoice(amt, new Date(), "", 3600);
-
- hash = r.payment_hash;
- text = r.bolt11;
- } else if (type === types.bitcoin) {
- hash = await bc.getNewAddress();
- text = bip21(hash, invoice);
- } else if (type === types.internal) {
- hash = v4();
- } else {
- fail("unrecognized type");
- }
-
- invoice = {
- ...invoice,
- amount,
- hash,
- text,
- currency,
- rate,
- tip,
- uid,
- received: 0,
- created: Date.now()
- };
-
- l("creating invoice", user.username, amount, tip, currency, invoice.hash);
-
- await s(`invoice:${hash}`, invoice);
- await db.lPush(`${uid}:invoices`, hash);
-
- if (request_id) {
- let request = await g(`request:${request_id}`);
- let { invoice_id: prev } = request;
- request.invoice_id = invoice.id;
- await s(`request:${request_id}`, request);
-
- if (!prev) emit(request.requester.username, "invoice", invoice);
- }
-
- res.send(invoice);
+ async create({ body: { invoice, user }, user: sender }, res) {
+ res.send(await invoice({ invoice, user, sender }));
}
};
diff --git a/routes/lnurl.js b/routes/lnurl.js
new file mode 100644
index 00000000..cb1b75c5
--- /dev/null
+++ b/routes/lnurl.js
@@ -0,0 +1,66 @@
+import { g, s } from "$lib/db";
+import { l } from "$lib/logging";
+import { fail } from "$lib/utils";
+import { v4 } from "uuid";
+import got from "got";
+import { invoice } from "$lib/invoices";
+import { bech32 } from "bech32";
+
+export default {
+ async encode({ query: { address } }, res) {
+ let [name, domain] = address.split("@");
+ let url = `https://${domain}/.well-known/lnurlp/${name}`;
+ let r = await got(url).json();
+ if (r.tag !== "payRequest") fail("not an ln address");
+ let enc = bech32.encode("lnurl", bech32.toWords(Buffer.from(url)), 20000);
+ res.send(enc);
+ },
+
+ async decode({ query: { text } }, res) {
+ let url = Buffer.from(
+ bech32.fromWords(bech32.decode(text, 20000).words)
+ ).toString();
+
+ res.send(await got(url).json());
+ },
+
+ async lnurlp({ params: { username } }, res) {
+ let uid = await g(`user:${username}`);
+ if (!uid) fail("user not found");
+
+ let id = v4();
+ await s(`lnurl:${id}`, uid);
+ let { URL } = process.env;
+ let host = URL.split("/").at(-1);
+
+ res.send({
+ metadata: [
+ ["text/plain", `Paying ${username}@${host}`],
+ ["text/identifier", `${username}@${host}`]
+ ],
+ callback: `${URL}/lnurl/${id}`,
+ tag: "payRequest"
+ });
+ },
+
+ async lnurl({ params: { id }, query: { amount } }, res) {
+ let pr = await g(`lnurlp:${id}`);
+
+ if (!pr) {
+ let uid = await g(`lnurl:${id}`);
+ let user = await g(`user:${uid}`);
+
+ ({ text: pr } = await invoice({
+ invoice: {
+ amount,
+ type: types.lightning
+ },
+ user
+ }));
+
+ await s(`lnurlp:${id}`, pr);
+ }
+
+ res.send({ pr });
+ }
+};
diff --git a/routes/payments.js b/routes/payments.js
index 53bb6e4d..b80d54f6 100644
--- a/routes/payments.js
+++ b/routes/payments.js
@@ -8,13 +8,12 @@ import { fail, btc, sats } from "$lib/utils";
import { requirePin } from "$lib/auth";
import { debit, credit, confirm, types } from "$lib/payments";
import { bech32 } from "bech32";
+import { invoice } from "$lib/invoices";
import got from "got";
import bc from "$lib/bitcoin";
import ln from "$lib/ln";
-const { HOSTNAME: hostname } = process.env;
-
export default {
async create({ body, user }, res) {
let { amount, hash, maxfee, name, memo, payreq, tip } = body;
@@ -227,7 +226,6 @@ export default {
let r = await got(url).json();
if (r.tag !== "payRequest") fail("not an ln address");
let enc = bech32.encode("lnurl", bech32.toWords(Buffer.from(url)), 20000);
- console.log(enc);
res.send(enc);
},
@@ -239,13 +237,43 @@ export default {
res.send(await got(url).json());
},
- async lnurl({ params: { code }, query: { amount } }, res) {
- let { uid } = await g(`code:${code}`);
+ async lnurlp({ params: { username } }, res) {
+ let uid = await g(`user:${username}`);
+ if (!uid) fail("user not found");
- let url = Buffer.from(
- bech32.fromWords(bech32.decode(text, 20000).words)
- ).toString();
+ let id = v4();
+ await s(`lnurl:${id}`, uid);
+ let { URL } = process.env;
+ let host = URL.split("/").at(-1);
- res.send(await got(url).json());
+ res.send({
+ metadata: [
+ ["text/plain", `Paying ${username}@${host}`],
+ ["text/identifier", `${username}@${host}`]
+ ],
+ callback: `${host}/lnurl/${id}`,
+ tag: "payRequest"
+ });
+ },
+
+ async lnurl({ params: { id }, query: { amount } }, res) {
+ let pr = await g(`lnurlp:${id}`);
+
+ if (!pr) {
+ let uid = await g(`lnurl:${id}`);
+ let user = await g(`user:${uid}`);
+
+ ({ text: pr } = await invoice({
+ invoice: {
+ amount,
+ type: types.lightning
+ },
+ user
+ }));
+
+ await s(`lnurlp:${id}`, pr);
+ }
+
+ res.send({ pr });
}
};