aboutsummaryrefslogtreecommitdiffstats
path: root/lib/payments.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-01-31 14:35:52 -0800
committerAdam Soltys <[email protected]>2024-01-31 14:35:52 -0800
commit25d57b726f158f7eb142b109c3a51e2c84bad210 (patch)
tree5a1e18122f5322f2cd17475b2ba564a91735fe75 /lib/payments.js
parent0c223a4835711a287f17835af959b47f72ea68c9 (diff)
downloadcoinos-server-25d57b726f158f7eb142b109c3a51e2c84bad210.tar.gz
coinos-server-25d57b726f158f7eb142b109c3a51e2c84bad210.zip
withdrawal emails
Diffstat (limited to 'lib/payments.js')
-rw-r--r--lib/payments.js78
1 files changed, 48 insertions, 30 deletions
diff --git a/lib/payments.js b/lib/payments.js
index ee030a5e..7f83f09a 100644
--- a/lib/payments.js
+++ b/lib/payments.js
@@ -1,3 +1,4 @@
+import locales from "$lib/locales/index";
import config from "$config";
import store from "$lib/store";
import { emit } from "$lib/sockets";
@@ -15,6 +16,8 @@ import lq from "$lib/liquid";
import bc from "$lib/bitcoin";
import ln from "$lib/ln";
+let { URL } = process.env;
+
let api = {
bitcoin: "https://mempool.space/api/v1",
liquid: "https://liquid.network/api/v1",
@@ -158,11 +161,11 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => {
if ([types.bitcoin, types.liquid].includes(type)) inv.pending += amount;
else inv.received += amount;
- let balance = "balance";
+ let balanceKey = "balance";
if ([types.bitcoin, types.liquid].includes(type)) {
let [txid, vout] = ref.split(":").slice(-2);
p.confirmed = false;
- balance = "pending";
+ balanceKey = "pending";
await s(`payment:${txid}:${vout}`, id);
} else {
await s(`payment:${hash}`, id);
@@ -176,7 +179,7 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => {
m.set(`invoice:${inv.iid}`, JSON.stringify(inv))
.set(`payment:${p.id}`, JSON.stringify(p))
.lPush(`${uid}:payments`, p.id)
- .incrBy(`${balance}:${uid}`, amount)
+ .incrBy(`${balanceKey}:${uid}`, amount)
.exec();
emit(uid, "payment", p);
@@ -184,18 +187,6 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => {
callWebhook(inv, p);
l(username, "received", type, amount);
- if (user.verified && user.notify) {
- mail(user, "Payment received", templates.paymentReceived, {
- username,
- sats:
- "⚡️" +
- new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(
- p.amount,
- ),
- link: `${process.env.URL}/payment/${p.id}`,
- });
- }
-
if (config.mqtt1) {
mqtt1.publish(
username,
@@ -210,22 +201,47 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => {
);
}
- if (p.confirmed) autowithdraw(user);
-
+ await completePayment(p, user);
return p;
};
-export let autowithdraw = async (user) => {
- let { username, autowithdraw, id, destination, threshold, reserve } = user;
- try {
+let fmt = (sats) =>
+ "⚡️" +
+ new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(sats);
+
+export let completePayment = async (p, user) => {
+ let { id, autowithdraw, threshold, reserve, destination, username } = user;
+ let link = (id) => `${URL}/payment/${id}`;
+ if (p.confirmed) {
+ let withdrawal;
if (autowithdraw) {
- let to = destination.trim();
- let balance = await g(`balance:${id}`);
- let amount = balance - reserve;
- if (balance > threshold) await pay({ amount, to, user });
+ try {
+ let to = destination.trim();
+ let balance = await g(`balance:${id}`);
+ let amount = balance - reserve;
+ if (balance > threshold) {
+ l("initiating autowithdrawal", amount, to, balance, threshold);
+ let w = await pay({ amount, to, user });
+ withdrawal = {
+ amount: fmt(-w.amount),
+ link: link(w.id),
+ };
+ }
+ } catch (e) {
+ withdrawal = { failed: true };
+ warn(username, "autowithdraw failed", e.message);
+ }
+ }
+
+ let t = locales[user.language || "en"];
+ if (user.verified && user.notify) {
+ mail(user, t.paymentReceived, templates.paymentReceived, {
+ ...t,
+ username,
+ payment: { amount: fmt(p.amount), link: link(p.id) },
+ withdrawal,
+ });
}
- } catch (e) {
- warn(username, "autowithdraw failed", e);
}
};
@@ -251,8 +267,9 @@ let pay = async ({ amount, to, user }) => {
pr = to;
}
- if (pr) await sendLightning({ user, pr, amount, maxfee });
- else await sendOnchain({ amount, address: to, user, subtract: true });
+ return pr
+ ? await sendLightning({ user, pr, amount, maxfee })
+ : await sendOnchain({ amount, address: to, user, subtract: true });
};
let decode = async (hex) => {
@@ -338,7 +355,7 @@ export let sendOnchain = async (params) => {
let amount = total - change;
- await debit({
+ let p = await debit({
hash: txid,
amount,
fee,
@@ -347,7 +364,8 @@ export let sendOnchain = async (params) => {
type,
});
- return node.sendRawTransaction(signed);
+ await node.sendRawTransaction(signed);
+ return p;
};
let getMaxFee = (n) =>