aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-12-02 12:53:19 -0800
committerAdam Soltys <[email protected]>2024-12-02 12:53:19 -0800
commit501e2ba1942911a98278a95121a7553da19795d2 (patch)
tree5d55f8e88a95fbf708d47c0afc86ad559ccfaf18
parentd16675345757dc7bf180f4aa51ccb0d124ea7e12 (diff)
downloadcoinos-server-501e2ba1942911a98278a95121a7553da19795d2.tar.gz
coinos-server-501e2ba1942911a98278a95121a7553da19795d2.zip
keysend
-rw-r--r--lib/nwc.ts27
-rw-r--r--lib/payments.ts41
-rw-r--r--routes/payments.ts10
3 files changed, 67 insertions, 11 deletions
diff --git a/lib/nwc.ts b/lib/nwc.ts
index 1c0c0eb6..3f6f24e7 100644
--- a/lib/nwc.ts
+++ b/lib/nwc.ts
@@ -4,7 +4,7 @@ import { generate } from "$lib/invoices";
import ln from "$lib/ln";
import { err } from "$lib/logging";
import { handleZap, serverPubkey } from "$lib/nostr";
-import { sendInternal, sendLightning } from "$lib/payments";
+import { sendInternal, sendKeysend, sendLightning } from "$lib/payments";
import { getInvoice, sleep } from "$lib/utils";
import { Relay } from "nostr";
import { finalizeEvent, nip04, nip19 } from "nostr-tools";
@@ -122,7 +122,7 @@ const handle = (method, params, user) =>
}
await sendLightning({
amount,
- maxfee: Math.max(5, Math.round(amount * 0.005)),
+ fee: Math.max(5, Math.round(amount * 0.005)),
user,
pr,
});
@@ -140,6 +140,29 @@ const handle = (method, params, user) =>
return error({ code: "INTERNAL", message: "Payment timed out" });
},
+ async pay_keysend() {
+ const { amount, pubkey } = params;
+
+ await sendKeysend({
+ amount,
+ pubkey,
+ fee: Math.max(5, Math.round(amount * 0.005)),
+ user,
+ });
+
+ for (let i = 0; i < 10; i++) {
+ const { pays } = await ln.listpays(pr);
+ const p = pays.find((p) => p.status === "complete");
+ if (p) {
+ const { preimage } = p;
+ return result({ preimage });
+ }
+ await sleep(2000);
+ }
+
+ return error({ code: "INTERNAL", message: "Payment timed out" });
+ },
+
async get_info() {
const { alias, blockheight, color } = await ln.getinfo();
return result({
diff --git a/lib/payments.ts b/lib/payments.ts
index fb394550..2b344817 100644
--- a/lib/payments.ts
+++ b/lib/payments.ts
@@ -281,18 +281,18 @@ const pay = async ({ aid = undefined, amount, to, user }) => {
).toString();
}
- const maxfee = Math.max(5, Math.round(amount * 0.005));
+ const fee = Math.max(5, Math.round(amount * 0.005));
if (lnurl) {
- amount -= maxfee;
+ amount -= fee;
const { callback } = (await got(lnurl).json()) as any;
({ pr } = (await got(`${callback}?amount=${amount * 1000}`).json()) as any);
} else if (to.startsWith("ln")) {
- amount -= maxfee;
+ amount -= fee;
pr = to;
}
return pr
- ? await sendLightning({ user, pr, amount, maxfee })
+ ? await sendLightning({ user, pr, amount, fee })
: await sendOnchain({ aid, amount, address: to, user, subtract: true });
};
@@ -415,6 +415,39 @@ export const sendOnchain = async (params) => {
}
};
+export const sendKeysend = async ({
+ amount,
+ pubkey,
+ fee,
+ memo = undefined,
+ user,
+}) => {
+ let p = await debit({
+ hash: pubkey,
+ amount,
+ fee,
+ memo,
+ user,
+ type: types.lightning,
+ });
+
+ fee = Math.max(parseInt(fee || 0), 5);
+ if (fee < 0) fail("Fee cannot be negative");
+
+ const r = await ln.keysend({
+ pubkey,
+ amount_msat: amount * 1000,
+ maxfee: fee * 1000,
+ retry_for: 10,
+ });
+
+ try {
+ if (r.status === "complete") p = await finalize(r, p);
+ } catch (e) {
+ warn("failed to process payment", p.id);
+ }
+};
+
export const sendLightning = async ({
user,
pr,
diff --git a/routes/payments.ts b/routes/payments.ts
index 46728578..0c022632 100644
--- a/routes/payments.ts
+++ b/routes/payments.ts
@@ -38,7 +38,7 @@ export default {
async create(req, res) {
const { body, user } = req;
- let { amount, hash, maxfee, fund, memo, payreq } = body;
+ let { amount, hash, fee, fund, memo, payreq } = body;
const balance = await g(`balance:${user.id}`);
try {
@@ -62,7 +62,7 @@ export default {
hash = payreq;
if (!amount) ({ amount } = invoice);
} else {
- p = await sendLightning({ user, pr: payreq, amount, maxfee, memo });
+ p = await sendLightning({ user, pr: payreq, amount, fee, memo });
}
}
@@ -93,7 +93,7 @@ export default {
} = req;
if (!aid || aid === "undefined") aid = id;
- if (limit) limit = parseInt(limit);
+ limit = parseInt(limit) || 25;
offset = parseInt(offset) || 0;
const range = start || end ? -1 : limit - 1;
@@ -439,7 +439,7 @@ export default {
async lnaddress(req, res) {
let {
- params: { lnaddress, amount, maxfee = 5000 },
+ params: { lnaddress, amount, fee = 5000 },
body,
user,
} = req;
@@ -467,7 +467,7 @@ export default {
if (payee === id) {
p = await debit({ hash: pr, amount, memo, user });
await credit({ hash: pr, amount, memo, ref: user.id });
- } else p = await sendLightning({ user, pr, amount, maxfee, memo });
+ } else p = await sendLightning({ user, pr, amount, fee, memo });
res.send(p);
} catch (e) {