aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-18 19:45:14 -0800
committerAdam Soltys <[email protected]>2023-01-18 19:45:14 -0800
commit963aa2d12683ad3cf9ab2927efa5361945a8bc58 (patch)
treeecddd30b2120675818d6356e6f9278209ce244e0
parentd62cc3b3db7d96ec48b71bb4adff99d134f934d7 (diff)
downloadcoinos-server-963aa2d12683ad3cf9ab2927efa5361945a8bc58.tar.gz
coinos-server-963aa2d12683ad3cf9ab2927efa5361945a8bc58.zip
pots
-rw-r--r--index.js2
-rw-r--r--routes/payments.js176
-rw-r--r--routes/users.js1
3 files changed, 119 insertions, 60 deletions
diff --git a/index.js b/index.js
index fd365e1a..1ade59d8 100644
--- a/index.js
+++ b/index.js
@@ -48,6 +48,8 @@ app.post("/send", auth, payments.send);
app.get("/payments", auth, payments.list);
app.get("/payments/:hash", auth, payments.get);
app.post("/lightning/send", auth, payments.sendLightning);
+app.get("/pot/:name", payments.pot);
+app.post("/withdraw", auth, payments.withdraw);
app.get("/voucher/:id", payments.voucher);
app.post("/redeem", optional, payments.redeem);
diff --git a/routes/payments.js b/routes/payments.js
index 27c8c5de..50831a7c 100644
--- a/routes/payments.js
+++ b/routes/payments.js
@@ -12,80 +12,104 @@ import { callWebhook } from "$lib/webhooks";
const { HOSTNAME: hostname } = process.env;
-export default {
- async send({ body, user }, res) {
- let { amount, hash, memo, tip } = body;
- await requirePin({ body, user });
- if (!hash) fail("invoice hash required");
+let debit = async (user, amount, memo, to) => {
+ let { id: uid, currency, username } = user;
+ to = to && to.id;
- let { id: uid } = user;
- amount = parseInt(amount);
+ amount = parseInt(amount);
- if (!amount || amount < 0) fail("Amount must be greater than zero");
+ if (!amount || amount < 0) fail("Amount must be greater than zero");
- await t(`balance:${uid}`, async (balance) => {
- await new Promise(r => setTimeout(r, 100));
- if (balance < amount) fail("Insufficient funds");
- return balance - amount;
- });
+ await t(`balance:${uid}`, async balance => {
+ await new Promise(r => setTimeout(r, 100));
+ if (balance < amount) fail("Insufficient funds");
+ return balance - amount;
+ });
+
+ let fee = 0;
- let fee = 0;
- let invoice = await g(`invoice:${hash}`);
- user = await g(`user:${uid}`);
+ let hash = v4();
- await s(`user:${uid}`, user);
+ let p = {
+ hash,
+ amount: -amount,
+ memo,
+ uid,
+ rate: store.rates[currency],
+ currency,
+ type: "internal",
+ to,
+ created: Date.now()
+ };
- let p1 = {
- hash,
- amount: -amount,
- memo,
- uid,
- rate: store.rates[user.currency],
- currency: user.currency,
- type: "internal",
- created: Date.now()
- };
+ if (!to) delete p.to;
- await s(`payment:${hash}`, p1);
- await db.lPush(`${uid}:payments`, hash);
+ await s(`payment:${hash}`, p);
+ await db.lPush(`${uid}:payments`, hash);
- l("sent internal", user.username, -p1.amount);
- emit(user.id, "payment", p1);
+ l("sent internal", user.username, amount);
+ emit(user.id, "payment", p);
+
+ return p;
+};
- ({ uid } = invoice);
- if (uid !== user.id) {
- let recipient = await g(`user:${uid}`);
+let credit = async (hash, amount, memo, from) => {
+ let invoice = await g(`invoice:${hash}`);
+ let user = await g(`user:${invoice.uid}`);
- let p2 = {
- hash,
- amount,
- uid: recipient.id,
- rate: store.rates[recipient.currency],
- currency: recipient.currency,
- memo,
- type: "internal",
- with_id: user.id,
- created: Date.now()
- };
+ let { id: uid, currency, username } = user;
+ from = from.id;
- let { tip } = invoice;
- if (tip) {
- p2.tip = tip;
- p2.amount -= tip;
- }
+ let p = {
+ hash,
+ amount,
+ uid,
+ rate: store.rates[currency],
+ currency,
+ memo,
+ type: memo === "pot" ? "pot" : "internal",
+ from,
+ created: Date.now()
+ };
- invoice.received += amount;
- await s(`invoice:${hash}`, invoice);
- await s(`payment:${hash}`, p2);
- await db.lPush(`${recipient.id}:payments`, hash);
+ let { tip } = invoice;
+ if (tip) {
+ p.tip = tip;
+ p.amount -= tip;
+ }
+
+ invoice.received += amount;
+ await s(`invoice:${hash}`, invoice);
+ await s(`payment:${hash}`, p);
+ await db.lPush(`${uid}:payments`, hash);
+
+ l("received internal", username, amount);
+ emit(username, "payment", p);
+ notify(user, `Received ${amount} sats`);
+ callWebhook(invoice, p);
+
+ return p;
+};
+
+export default {
+ async send({ body, user }, res) {
+ let { amount, hash, name, memo, tip } = body;
+ await requirePin({ body, user });
- l("received internal", recipient.username, amount);
- emit(recipient.username, "payment", p2);
- notify(recipient, `Received ${amount} sats`);
- callWebhook(invoice, p2);
+ let invoice, recipient;
+
+ let p = await debit(user, amount, memo, recipient);
+
+ if (hash) {
+ await credit(hash, amount, memo, user);
+ } else {
+ let pot = name || v4();
+ await db.incrBy(`pot:${pot}`, amount);
+ await db.lPush(`pot:${pot}:payments`, p.hash);
+ l("funded pot", pot);
}
- res.send(p1);
+ res.send(p);
},
async list({ user: { id }, query: { start, end, limit, offset } }, res) {
@@ -225,5 +249,39 @@ export default {
let alias = node ? node.alias : payee.substr(0, 12);
res.send({ alias, amount: Math.round(msatoshi / 1000) });
+ },
+
+ async pot({ params: { name } }, res) {
+ let amount = await g(`pot:${name}`);
+ let payments = (await db.lRange(`pot:${name}:payments`, 0, -1)) || [];
+ payments = await Promise.all(payments.map(hash => g(`payment:${hash}`)));
+
+ await Promise.all(
+ payments.map(async p => (p.user = await g(`user:${p.uid}`)))
+ );
+
+ payments = payments.filter(p => p);
+ res.send({ amount, payments });
+ },
+
+ async withdraw({ body: { name, amount }, user }, res) {
+ amount = parseInt(amount)
+ await t(`pot:${name}`, async balance => {
+ await new Promise(r => setTimeout(r, 100));
+ console.log("BAL", balance, amount)
+ if (balance < amount) fail("Insufficient funds");
+ return balance - amount;
+ });
+
+ let hash = v4();
+ await s(`invoice:${hash}`, {
+ uid: user.id,
+ received: 0
+ });
+
+ let payment = await credit(hash, amount, "pot", { id: name });
+ await db.lPush(`pot:${name}:payments`, hash);
+
+ res.send({ payment });
}
};
diff --git a/routes/users.js b/routes/users.js
index 57a423b8..49aeebd7 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -19,7 +19,6 @@ export default {
async me({ user }, res) {
try {
user.balance = await g(`balance:${user.id}`);
- console.log("USER BAL", user.id, user.balance)
res.send(pick(user, whitelist));
} catch (e) {
console.log("problem fetching user", e);