aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-09-30 15:07:30 -0700
committerAdam Soltys <[email protected]>2022-09-30 15:09:55 -0700
commitc3efae9d1720c6f9eb6f826c4f1c6d5f3e259407 (patch)
tree2ac3b89ba3c0febe7d45e25eb4515d42e7a27188 /lib
parent6dee51ad1c2a74bfb0b57417dae9bce6931cd9f1 (diff)
downloadcoinos-server-c3efae9d1720c6f9eb6f826c4f1c6d5f3e259407.tar.gz
coinos-server-c3efae9d1720c6f9eb6f826c4f1c6d5f3e259407.zip
derive address/payreq server side
Diffstat (limited to 'lib')
-rw-r--r--lib/send.js32
-rw-r--r--lib/utils.js84
2 files changed, 97 insertions, 19 deletions
diff --git a/lib/send.js b/lib/send.js
index f20185e5..e7255219 100644
--- a/lib/send.js
+++ b/lib/send.js
@@ -66,10 +66,11 @@ export default async (amount, memo, hash, user) => {
});
conversionFeeDeduction = Math.min(account.lightning_credits, conversionFee);
+ total = amount + conversionFee - conversionFeeDeduction;
if (
!account ||
- account.balance < amount + conversionFee - conversionFeeDeduction
+ account.balance < total
) {
warn(
"user attempting to send more than they have",
@@ -81,12 +82,12 @@ export default async (amount, memo, hash, user) => {
}
await account.decrement(
- { balance: amount, lightning_credits: conversionFeeDeduction },
+ { balance: total, lightning_credits: conversionFeeDeduction },
{ transaction }
);
await account.reload({ transaction });
- l("debited account", account.id);
+ l("debited account", account.id, total);
let tokens;
if (!payreq.satoshis) tokens = amount;
@@ -100,26 +101,22 @@ export default async (amount, memo, hash, user) => {
if (!m) throw new Error(`lightning payment failed ${amount} ${hash}`);
if (m.payment_error) throw new Error(m.payment_error);
- ({ fee, secret: preimage, tokens: total } = m);
+ ({ fee, secret, tokens: total } = m);
+ preimage = secret.toString("hex");
} else {
- m = await ln.pay(hash, tokens ? `${tokens}sats` : undefined);
- let sent;
- ({
- msatoshi: total,
- msatoshi_sent: sent,
- payment_preimage: preimage
- } = m);
-
- fee = parseInt((sent - total) / 1000);
- total = parseInt(total / 1000);
+ let { msatoshi, msatoshi_sent, payment_preimage } = await ln.pay(hash, tokens ? `${tokens}sats` : undefined);
+ preimage = payment_preimage;
+ fee = parseInt((msatoshi_sent - msatoshi) / 1000);
+ total = parseInt(msatoshi / 1000);
}
- preimage = preimage.toString("hex");
-
if (store.seen.includes(preimage)) {
warn("duplicate payment detected", preimage);
throw new Error("Duplicate payment detected");
}
+
+ store.seen.push(preimage);
+ store.seen.push(hash);
});
await db.transaction(async transaction => {
@@ -226,9 +223,6 @@ export default async (amount, memo, hash, user) => {
emit(user.username, "account", payment.account);
emit(user.username, "payment", payment);
- store.seen.push(preimage);
- store.seen.push(hash);
-
l("sent lightning", user.username, total - fee, fee);
});
diff --git a/lib/utils.js b/lib/utils.js
index 1ff24c67..036ccd6d 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -1,5 +1,13 @@
+import config from "$config";
import db from "$db";
import sequelize from "@sequelize/core";
+import { fromBase58 } from "bip32";
+import { payments as bcPayments, networks as bcNetworks } from "bitcoinjs-lib";
+import { payments as lqPayments, networks as lqNetworks } from "liquidjs-lib";
+import { createInvoice } from "lightning";
+import lnd from "$lib/lnd";
+import ln from "$lib/ln";
+
const { Op } = sequelize;
export const getUser = async (username, transaction) => {
@@ -90,3 +98,79 @@ export const getBlockHeight = message => {
readUInt32();
return readUInt32();
};
+
+export const deriveAddress = async (account, type) => {
+ let { index, pubkey, path, network } = account;
+ let n = { bitcoin: bcNetworks, liquid: lqNetworks }[network][
+ prod ? "bitcoin" : "regtest"
+ ];
+ let p = { bitcoin: bcPayments, liquid: lqPayments }[network];
+ let root = fromBase58(pubkey, n);
+ let parts = path.split("/");
+ let hd = root.derive(parseInt(parts[parts.length - 1]));
+
+ type = {
+ bech32: "p2wpkh",
+ "p2sh-segwit": "p2sh",
+ legacy: "p2pkh"
+ }[type];
+
+ console.log("TYPE", type);
+
+ let r;
+ if (type !== "p2sh") {
+ r = p[type]({
+ pubkey: hd.publicKey,
+ network: n
+ });
+ } else {
+ r = p[type]({
+ redeem: p.p2wpkh({
+ pubkey: hd.publicKey,
+ network: n
+ }),
+ network: n
+ });
+ }
+
+ index++;
+ account.index = index;
+ account.address = r.address;
+ await account.save();
+
+ return r;
+};
+
+export const bip21 = ({ address, amount, memo, tip, network }, { asset }) => {
+ if (network === "liquid") network = "liquidnetwork";
+
+ let url = amount || memo ? `${network}:${address}?` : address;
+ if (amount)
+ url += `amount=${((amount + tip) / SATS).toFixed(8)}${memo ? "&" : ""}`;
+ if (memo) url += `message=${memo}`;
+
+ if (network === "liquidnetwork" && amount) {
+ url += `&asset=${asset}`;
+ }
+
+ return url;
+};
+
+export const derivePayRequest = async ({ amount, memo, tip }) => {
+ if (!tip) tip = 0;
+ let value = amount + tip;
+
+ if (config.lna.clightning) {
+ if (!memo) memo = "coinos";
+ return (await ln.invoice(value ? `${value}sat` : "any", new Date(), memo, 360))
+ .bolt11;
+ } else {
+ return (
+ await createInvoice({
+ lnd,
+ tokens: value,
+ description: memo
+ })
+ ).request;
+ }
+};