aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
Diffstat (limited to 'routes')
-rw-r--r--routes/ecash.ts143
-rw-r--r--routes/info.ts4
-rw-r--r--routes/payments.ts2
3 files changed, 21 insertions, 128 deletions
diff --git a/routes/ecash.ts b/routes/ecash.ts
index 4a1806a3..d089ed15 100644
--- a/routes/ecash.ts
+++ b/routes/ecash.ts
@@ -1,31 +1,10 @@
-import { db, g, s } from "$lib/db";
-import { check, claim, get, mint } from "$lib/ecash";
-import { err, l } from "$lib/logging";
-import { credit, debit } from "$lib/payments";
-import { emit } from "$lib/sockets";
-import { bail, fail, getInvoice } from "$lib/utils";
+import { s } from "$lib/db";
+import { check, get, redeem } from "$lib/ecash";
+import { err } from "$lib/logging";
+import { bail, fail, getInvoice, getUser } from "$lib/utils";
import { getEncodedToken } from "@cashu/cashu-ts";
import { v4 } from "uuid";
-import { PaymentType } from "$lib/types";
-const { ecash: type } = PaymentType;
-
-Error.stackTraceLimit = 100; // Set this to the desired limit
-
-const sendCash = async ({ amount, user }) => {
- const id = v4();
- const hash = v4();
-
- const p = await debit({ hash, amount, user, type });
- const token = await mint(parseInt(amount));
- p.memo = id;
- const { id: pid } = p;
- await s(`payment:${pid}`, p);
- s(`cash:${id}`, token);
-
- return { id, token, pid };
-};
-
export default {
async save(req, res) {
const {
@@ -47,6 +26,7 @@ export default {
} = req;
try {
const token = await get(id);
+ if (!token) fail("Ecash not found");
const status = await check(token);
res.send({ token, status });
} catch (e) {
@@ -61,114 +41,31 @@ export default {
user,
} = req;
try {
- const amount = await claim(token);
-
- let memo;
- const hash = v4();
- const { currency, id: uid } = user;
- const rates = await g("rates");
- await s(`invoice:${hash}`, {
- currency,
- id: hash,
- hash,
- rate: rates[currency],
- uid,
- received: 0,
- });
-
- await credit({ hash, amount, memo, ref: user.id, type });
-
- res.send({ ok: true });
+ const amount = await redeem({ token, user });
+ res.send({ ok: true, amount });
} catch (e) {
err(e.message);
bail(res, e.message);
}
},
- async mint(req, res) {
- const { body, user } = req;
- const amount = parseInt(body.amount);
- fail("disabled");
- res.send(await sendCash({ amount, user }));
- },
-
- async melt(req, res) {
- let {
- body: { amount, bolt11: hash, preimage },
- user,
- } = req;
- try {
- const ref = preimage;
- const { lightning: type } = PaymentType;
- if (user.username !== "mint") fail("unauthorized");
-
- amount = Math.round(amount / 1000);
- // A negative (or NaN) amount here is a direct ledger-inflation primitive:
- // db.debit subtracts it, so -N ADDS N to the balance, and the stored
- // record gets amount: -(-N). The caller gate above limits this to the
- // mint service account, but that account is not a trust boundary we want
- // the ledger's integrity resting on — mirror the check debit() makes in
- // lib/payments.ts before any balance write.
- if (!Number.isFinite(amount) || amount <= 0)
- fail("Amount must be greater than zero");
- const { id: uid, currency } = user;
- const ourfee = await db.debit(
- `balance:${uid}`,
- `credit:${type}:${uid}`,
- "Insufficient funds",
- amount || 0,
- 0,
- 0,
- 0,
- 0
- );
-
- const rates = await g("rates");
- const rate = rates[currency];
-
- if (ourfee.err) fail(ourfee.err);
-
- const id = v4();
- const p = {
- id,
- amount: -amount,
- hash,
- ourfee,
- uid,
- confirmed: true,
- rate,
- currency,
- type,
- ref,
- created: Date.now(),
- };
-
- await s(`payment:${hash}`, id);
- await s(`payment:${id}`, p);
- await db.lPush(`${uid}:payments`, id);
-
- l(user.username, "sent", type, amount);
- emit(user.id, "payment", p);
-
- res.send(p);
- } catch (e) {
- bail(res, e.message);
- }
- },
-
+ // NUT-18 payment-request transport: a wallet POSTs proofs for one of our
+ // ecash-type invoices, which are melted into a Lightning invoice for the
+ // invoice's owner under the same id.
async receive(req, res) {
try {
const { id, proofs, mint, memo } = req.body;
- const { uid: ref } = await getInvoice(id);
-
- const amount = await claim(
- getEncodedToken({
- mint,
- proofs,
- }),
- );
+ const invoice = await getInvoice(id);
+ if (!invoice) fail("Invoice not found");
+ const user = await getUser(invoice.uid);
+ if (!user) fail("User not found");
- await credit({ hash: id, amount, memo, ref, type });
+ await redeem({
+ token: getEncodedToken({ mint, proofs }),
+ user,
+ invoice,
+ memo,
+ });
res.send({ id });
} catch (e) {
diff --git a/routes/info.ts b/routes/info.ts
index aae130bf..4ab11872 100644
--- a/routes/info.ts
+++ b/routes/info.ts
@@ -2,7 +2,6 @@ import { archive } from "$lib/db";
import { db } from "$lib/db";
import { getHealthStatus } from "$lib/health";
import ln from "$lib/ln";
-import { pool } from "$lib/ecash";
export default {
async health(_, res) {
@@ -28,10 +27,7 @@ export default {
);
const lnwallet = parseInt(funds.outputs.reduce((a, b) => a + b.value, 0));
- const cash = (await pool()).reduce((a, b) => a + b.amount, 0);
-
const info = {
- cash,
lnchannel,
lnwallet,
};
diff --git a/routes/payments.ts b/routes/payments.ts
index accb09fd..cf0248fa 100644
--- a/routes/payments.ts
+++ b/routes/payments.ts
@@ -66,7 +66,7 @@ export default {
const invoice = await getInvoice(payreq || hash);
const recipient = invoice ? await getUser(invoice.uid) : undefined;
if (payreq) {
- if (invoice && recipient.username !== "mint") {
+ if (invoice) {
if (invoice.aid === user.id) fail("Cannot send to self");
hash = payreq;
if (!amount) ({ amount } = invoice);