aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-13 20:27:18 -0800
committerAdam Soltys <[email protected]>2023-01-13 20:27:18 -0800
commit8a114c50efaac41767042766f05390aa906da157 (patch)
treeeb65bc1e9adf3614cb30798210328f7e83e0a0ce /routes
parentc3565838644123e77881ff4f8536792f074047b9 (diff)
downloadcoinos-server-8a114c50efaac41767042766f05390aa906da157.tar.gz
coinos-server-8a114c50efaac41767042766f05390aa906da157.zip
migrating to redis
Diffstat (limited to 'routes')
-rw-r--r--routes/invoices.js49
-rw-r--r--routes/lightning/receive.js161
-rw-r--r--routes/users.js26
3 files changed, 88 insertions, 148 deletions
diff --git a/routes/invoices.js b/routes/invoices.js
index ddd840ec..f7ab78cf 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -1,76 +1,67 @@
import app from "$app";
import store from "$lib/store";
import { optionalAuth } from "$lib/passport";
-import { err, l } from "$lib/logging";
-import { SATS, derivePayRequest } from "$lib/utils";
+import { l } from "$lib/logging";
import { emit } from "$lib/sockets";
-import { v4 } from "uuid";
import { rd, g, s } from "$lib/redis";
+import ln from "$lib/ln";
app.get("/invoice", async ({ query: { id } }, res) => {
let invoice = await g(`invoice:${id}`);
invoice.user = await g(`user:${invoice.user_id}`);
+ console.log("INV", invoice)
res.send(invoice);
});
app.post(
"/invoice",
optionalAuth,
- async (
- {
- body: { type = "bech32", liquidAddress, id, invoice, user, tx },
- user: me
- },
- res
- ) => {
- let {
- blindkey,
- currency,
- tip,
- amount,
- rate,
- network,
- request_id
- } = invoice;
- let text;
+ async ({ body: { invoice, user }, user: me }, res) => {
+ let { currency, tip, amount, rate, request_id } = invoice;
if (amount < 0) throw new Error("amount out of range");
if (tip > 5 * amount || tip < 0) throw new Error("tip amount out of range");
tip = tip || 0;
if (!user) user = me;
- if (!user) throw new Error("user not provided");
+ let user_id = await g(`user:${user.username}`);
+ user = await g(`user:${user_id}`);
- user = await g(`user:${user.id}`);
+ if (!user) throw new Error("user not provided");
if (!currency) currency = user.currency;
if (!rate) rate = store.rates[currency];
if (amount < 0) throw new Error("invalid amount");
+ let { payment_hash: id, bolt11: text } = await ln.invoice(
+ amount ? `${amount + tip}sat` : "any",
+ new Date(),
+ "",
+ 3600
+ );
+
invoice = {
...invoice,
- id: v4(),
+ id,
amount,
currency,
rate,
tip,
- unconfidential,
- user_id: user.id
+ user_id,
+ text
};
- invoice.text = await derivePayRequest(invoice);
-
l(
"creating invoice",
user.username,
- network,
amount,
tip,
currency,
`${text.substr(0, 8)}..${text.substr(-6)}`
);
- await rd.lPush(`${id}:invoices`, invoice.id);
+ await s(`invoice:${id}`, invoice);
+ await rd.lPush(`${user.id}:invoices`, id);
if (request_id) {
let request = await g(`request:${request_id}`);
diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js
index a778271b..a37dc716 100644
--- a/routes/lightning/receive.js
+++ b/routes/lightning/receive.js
@@ -6,132 +6,79 @@ import { callWebhook } from "$lib/webhooks";
import { computeConversionFee } from "./conversionFee";
import ln from "$lib/ln";
import { l, err, warn } from "$lib/logging";
+import { g, s, rd } from "$lib/redis";
-const handlePayment = async msg => {
- try {
- l("incoming lightning payment", msg.received);
-
- if (!msg.secret) return;
- let account, total, user;
-
- const invoice = await db.Invoice.findOne({
- where: {
- text: msg.request
- }
- });
+let handle = async () => {
+ let {
+ payment_hash,
+ bolt11: request,
+ pay_index,
+ status,
+ msatoshi_received,
+ payment_preimage: secret
+ } = await ln.waitanyinvoice(await g("pay_index"));
- if (!invoice)
- return warn("received lightning with no invoice", msg.request);
+ await s("pay_index", pay_index);
- await db.transaction(async transaction => {
- const { text: hash, currency, memo, rate, tip, user_id } = invoice;
- const amount = parseInt(msg.received) - tip;
- if (amount < 0) throw new Error("amount out of range");
+ let received = Math.round(msatoshi_received / 1000);
- account = await db.Account.findOne({
- where: {
- user_id,
- asset: config.liquid.btcasset,
- pubkey: null
- },
- include: {
- model: db.User,
- as: "user"
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
+ try {
+ l("incoming lightning payment", received);
- ({ user } = account);
+ if (!secret) return;
+ let account, total, user;
- let preimage = msg.secret;
+ let invoice = await g(`invoice:${payment_hash}`);
+ if (!invoice) return warn("received lightning with no invoice", request);
- let payment = await db.Payment.create(
- {
- account_id: account.id,
- user_id,
- hash,
- memo,
- amount,
- currency,
- preimage,
- rate,
- received: true,
- confirmed: true,
- network: "lightning",
- tip,
- invoice_id: invoice.id
- },
- { transaction }
- );
+ let { text: hash, currency, memo, rate, tip, user_id } = invoice;
+ let amount = parseInt(received) - tip;
+ if (amount < 0) throw new Error("amount out of range");
- total = amount + tip;
+ let payment = {
+ user_id,
+ hash,
+ memo,
+ amount,
+ currency,
+ secret,
+ rate,
+ tip,
+ invoice_id: invoice.id
+ };
- invoice.status = "paid";
- await invoice.save({ transaction });
+ total = amount + tip;
- await invoice.increment({ received: total }, { transaction });
- await account.increment({ balance: total }, { transaction });
- // get the # of fee credits you would need to pay off this amount of bitcoin
- await account.increment(
- { lightning_credits: computeConversionFee(total) },
- { transaction }
- );
- await account.reload({ transaction });
- await invoice.reload({ transaction });
- await payment.save({ transaction });
- store.payments.push(msg.request);
+ invoice.status = "paid";
+ invoice.received += total;
+ await s(`invoice:${payment_hash}`, invoice);
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- payment.invoice = invoice.get({ plain: true });
+ let t = async () => {
+ await rd.watch(`user:${user_id}`);
+ user = await g(`user:${user_id}`);
+ user.balance += total;
+ let m = await rd.multi();
+ await s(`user:${user.id}`, user);
+ if (!(await m.exec())) t();
+ };
+ await t();
- callWebhook(invoice, payment);
+ payment.invoice = invoice;
+ callWebhook(invoice, payment);
- emit(user.username, "payment", payment);
- emit(user.username, "account", payment.account);
- notify(user, `Received ${total} SAT`);
+ emit(user.username, "payment", payment);
+ notify(user, `Received ${total} SAT`);
- l(
- "lightning payment received",
- user.username,
- payment.amount,
- payment.tip
- );
- });
+ l("lightning payment received", user.username, payment.amount, payment.tip);
} catch (e) {
console.log(e);
err("problem receiving lightning payment", e.message);
}
};
-const poll = async ln => {
- try {
- const wait = async i => {
- const {
- bolt11: request,
- pay_index,
- status,
- msatoshi_received,
- payment_preimage: secret
- } = await ln.waitanyinvoice(i);
-
- let settled = status === "paid";
- let received = parseInt(msatoshi_received / 1000);
-
- await handlePayment({
- request,
- received,
- secret
- });
- await wait(pay_index);
- };
-
- const { invoices } = await ln.listinvoices();
- await wait(Math.max(...invoices.map(i => i.pay_index).filter(n => n)));
- } catch (e) {
- err("problem waiting for c-lightning invoice", e.message);
- }
+let listen = async () => {
+ await handle();
+ listen();
};
-poll(ln);
+listen();
diff --git a/routes/users.js b/routes/users.js
index 8f0b9106..97ff9dd4 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -3,7 +3,7 @@ import { g, s } from "$lib/redis";
import config from "$config";
import store from "$lib/store";
import { auth, optionalAuth } from "$lib/passport";
-import { getUser, nada, uniq, wait } from "$lib/utils";
+import { nada, pick, uniq, wait } from "$lib/utils";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { authenticator } from "otplib";
@@ -14,11 +14,9 @@ import register from "$lib/register";
import { requirePin } from "$lib/utils";
import got from "got";
-const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
-
app.get("/me", auth, async (req, res) => {
try {
- res.send(pick(req.user, ...whitelist));
+ res.send(pick(req.user, whitelist));
} catch (e) {
console.log("problem fetching user", e);
res.code(500).send(e.message);
@@ -32,6 +30,9 @@ app.get("/users/:key", async ({ params: { key } }, res) => {
}
let user = await g(`user:${key}`);
+ if (typeof user === "string") {
+ user = await g(`user:${user}`);
+ }
if (!user && key.length === 64) {
user = {
@@ -41,7 +42,6 @@ app.get("/users/:key", async ({ params: { key } }, res) => {
};
}
- console.log(user)
if (!user) return res.code(500).send("User not found");
let whitelist = [
@@ -53,10 +53,10 @@ app.get("/users/:key", async ({ params: { key } }, res) => {
"pubkey",
"display",
"prompt",
- "uuid"
+ "id"
];
- res.send(pick(user, ...whitelist));
+ res.send(pick(user, whitelist));
} catch (e) {
console.log(e);
res.code(500).send(e.message);
@@ -78,7 +78,7 @@ app.post("/register", async (req, res) => {
user = await register(user, ip, false);
l("registered new user", username);
- res.send(pick(user, ...whitelist));
+ res.send(pick(user, whitelist));
} catch (e) {
res.code(500).send(e.message);
}
@@ -308,7 +308,8 @@ let login = async (req, res) => {
return;
}
- let user = await getUser(username);
+ let id = await g(`user:${username}`);
+ let user = await g(`user:${id}`);
if (
!user ||
@@ -332,10 +333,11 @@ let login = async (req, res) => {
req.headers["x-forwarded-for"] || req.socket.remoteAddress
);
- let payload = { username, uuid: user.uuid };
+ let payload = { username, id: user.id };
let token = jwt.sign(payload, config.jwt);
res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
- user = pick(user, ...whitelist);
+ user = pick(user, whitelist);
+ console.log("SENDING", user, token)
res.send({ user, token });
} catch (e) {
console.log(e);
@@ -413,7 +415,7 @@ app.post("/otpsecret", auth, async function(req, res) {
});
app.get("/contacts", auth, async function({ user: { uuid } }, res) {
- let payments = await g(`${uuid}:payments`) || [];
+ let payments = (await g(`${uuid}:payments`)) || [];
res.send(
Promise.all(
[...new Set(payments.map(p => p.with_id))].map(id => g(`user:${id}`))