aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/lightning.js33
-rw-r--r--lib/payments.js132
-rw-r--r--lib/utils.js2
3 files changed, 135 insertions, 32 deletions
diff --git a/lib/lightning.js b/lib/lightning.js
index 86dfdb2b..c8daf8c8 100644
--- a/lib/lightning.js
+++ b/lib/lightning.js
@@ -5,6 +5,7 @@ import { callWebhook } from "$lib/webhooks";
import ln from "$lib/ln";
import { l, err, warn } from "$lib/logging";
import { g, s, t, db } from "$lib/db";
+import { credit, types } from "$lib/payments";
export async function listenForLightning() {
let {
@@ -33,37 +34,7 @@ export async function listenForLightning() {
let amount = parseInt(received) - tip;
if (amount < 0) throw new Error("amount out of range");
- let user = await g(`user:${uid}`);
-
- let payment = {
- amount,
- created: Date.now(),
- currency,
- fee: 0,
- hash,
- memo,
- preimage,
- rate,
- tip,
- type: "lightning",
- uid
- };
-
- invoice.status = "paid";
- invoice.received += received;
-
- await s(`invoice:${hash}`, invoice);
- await db.incrBy(`balance:${uid}`, received);
- payment.invoice = invoice;
- await s(`payment:${hash}`, payment);
- await db.lPush(`${uid}:payments`, hash);
-
- callWebhook(invoice, payment);
-
- emit(uid, "payment", payment);
- notify(user, `Received ${received} SAT`);
-
- l("lightning payment received", user.username, payment.amount, payment.tip);
+ await credit(hash, amount, memo, preimage, types.lightning);
} catch (e) {
console.log(e);
err("problem receiving lightning payment", e.message);
diff --git a/lib/payments.js b/lib/payments.js
new file mode 100644
index 00000000..e12f7858
--- /dev/null
+++ b/lib/payments.js
@@ -0,0 +1,132 @@
+import config from "$config";
+import store from "$lib/store";
+import { emit } from "$lib/sockets";
+import { v4 } from "uuid";
+import { notify } from "$lib/notifications";
+import { db, g, s, t } from "$lib/db";
+import { l, err } from "$lib/logging";
+import { fail } from "$lib/utils";
+import { callWebhook } from "$lib/webhooks";
+
+export const types = {
+ internal: "internal",
+ bitcoin: "bitcoin",
+ lightning: "lightning",
+ pot: "pot"
+};
+
+export let debit = async (
+ user,
+ amount,
+ memo,
+ to,
+ type = types.internal,
+ id = v4()
+) => {
+ let { id: uid, currency, username } = user;
+ to = to && to.id;
+
+ amount = parseInt(amount);
+
+ 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;
+ });
+
+ let fee = 0;
+
+ let p = {
+ id,
+ amount: -amount,
+ memo,
+ uid,
+ rate: store.rates[currency],
+ currency,
+ type,
+ to,
+ created: Date.now()
+ };
+
+ if (!to) delete p.to;
+
+ await s(`payment:${hash}`, p);
+ await db.lPush(`${uid}:payments`, hash);
+
+ l("sent internal", user.username, amount);
+ emit(user.id, "payment", p);
+
+ return p;
+};
+
+export let credit = async (hash, amount, memo, from, type = "internal") => {
+ amount = parseInt(amount);
+ let invoice = await g(`invoice:${hash}`);
+ if (!invoice) return;
+
+ let user = await g(`user:${invoice.uid}`);
+
+ let { id: uid, currency, username } = user;
+
+ let p = {
+ hash,
+ amount,
+ uid,
+ rate: store.rates[currency],
+ currency,
+ memo,
+ from,
+ type,
+ confirmed: true,
+ created: Date.now()
+ };
+
+ let { tip } = invoice;
+ if (tip) {
+ p.tip = tip;
+ p.amount -= tip;
+ }
+
+ invoice.received += amount;
+
+ let balance = "balance";
+ if (type === types.bitcoin) {
+ let [txid, vout] = from.split(":").slice(-2);
+ p.id = `${txid}:${vout}`;
+ p.confirmed = false;
+ balance = "pending";
+ } else {
+ p.id = hash;
+ }
+
+ await db
+ .multi()
+ .set(`invoice:${hash}`, JSON.stringify(invoice))
+ .set(`payment:${p.id}`, JSON.stringify(p))
+ .lPush(`${uid}:payments`, p.id)
+ .incrBy(`${balance}:${uid}`, amount)
+ .exec();
+
+ l("received internal", username, amount);
+ emit(uid, "payment", p);
+ notify(user, `Received ${amount} sats`);
+ callWebhook(invoice, p);
+
+ return p;
+};
+
+export let confirm = async (address, txid, vout) => {
+ let id = `payment:${txid}:${vout}`;
+ let p = await g(id);
+ p.confirmed = true;
+ console.log("P", p);
+
+ await db
+ .multi()
+ .set(id, JSON.stringify(p))
+ .decrBy(`pending:${p.uid}`, p.amount)
+ .incrBy(`balance:${p.uid}`, p.amount)
+ .exec();
+};
diff --git a/lib/utils.js b/lib/utils.js
index e653f235..b65f179a 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -23,7 +23,7 @@ export const fail = msg => {
};
export const SATS = 100000000;
-export const toSats = n => Math.round(n * SATS);
+export const sats = n => Math.round(n * SATS);
export const uniq = (a, k) => [...new Map(a.map(x => [k(x), x])).values()];
export const pick = (O, K) =>