aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-09-30 15:07:30 -0700
committerAdam Soltys <[email protected]>2022-09-30 15:07:30 -0700
commit4ee46fee0cbf23f51228c7c4895ee1e0565b074f (patch)
tree803dc7399926ff508114f6e7e315b72ada399b87 /routes
parenta8aaef0abb75cf00e28cd3bd5f747246cf83049a (diff)
downloadcoinos-server-4ee46fee0cbf23f51228c7c4895ee1e0565b074f.tar.gz
coinos-server-4ee46fee0cbf23f51228c7c4895ee1e0565b074f.zip
derive address/payreq server side
Diffstat (limited to 'routes')
-rw-r--r--routes/invoices.js86
-rw-r--r--routes/payments.js1
-rw-r--r--routes/users.js108
3 files changed, 55 insertions, 140 deletions
diff --git a/routes/invoices.js b/routes/invoices.js
index b5926fec..9f93180d 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -5,6 +5,9 @@ import { optionalAuth } from "$lib/passport";
import { Op } from "@sequelize/core";
import axios from "axios";
import { err, l } from "$lib/logging";
+import bc from "$lib/bitcoin";
+import lq from "$lib/liquid";
+import { SATS, bip21, deriveAddress, derivePayRequest } from "$lib/utils";
app.get("/invoice", async (req, res, next) => {
try {
@@ -27,15 +30,12 @@ app.get("/invoice", async (req, res, next) => {
app.post("/invoice", optionalAuth, async (req, res, next) => {
try {
- let { liquidAddress, id, invoice, user, tx } = req.body;
- let { blindkey } = invoice;
+ let { type = "bech32", liquidAddress, id, invoice, user, tx } = req.body;
+ let { blindkey, currency, tip, amount, rate, network } = invoice;
+ let address, unconfidential, text;
- if (invoice.amount < 0) throw new Error("amount out of range");
- if (
- invoice.tip > invoice.amount ||
- invoice.tip > 1000000 ||
- invoice.tip < 0
- )
+ if (amount < 0) throw new Error("amount out of range");
+ if (tip > amount || tip > 1000000 || tip < 0)
throw new Error("tip amount out of range");
if (liquidAddress) {
@@ -48,18 +48,56 @@ app.post("/invoice", optionalAuth, async (req, res, next) => {
user = await db.User.findOne({
where: {
username: user.username
+ },
+ include: {
+ model: db.Account,
+ as: "account"
}
});
}
if (!user) throw new Error("user not provided");
- if (!invoice.currency) invoice.currency = user.currency;
- if (!invoice.rate) invoice.rate = store.rates[invoice.currency];
- if (invoice.tip > invoice.amount || invoice.tip > 1000000)
- throw new Error("tip is too large");
- if (invoice.tip < 0 || invoice.amount < 0)
- throw new Error("invalid amount");
- invoice.user_id = user.id;
- invoice.account_id = user.account_id;
+ if (!currency) currency = user.currency;
+ if (!rate) rate = store.rates[currency];
+ if (tip > amount || tip > 1000000) throw new Error("tip is too large");
+ if (tip < 0 || amount < 0) throw new Error("invalid amount");
+
+ if (user.account.pubkey) {
+ let { address, confidentialAddress } = await deriveAddress(
+ user.account,
+ type
+ );
+ if (confidentialAddress) {
+ address = confidentialAddress;
+ unconfidential = address;
+ } else {
+ address = address;
+ }
+ } else if (network !== "lightning") {
+ console.log(network, { bitcoin: bc, liquid: lq }[network])
+ address = await { bitcoin: bc, liquid: lq }[network].getNewAddress();
+ if (network === "liquid")
+ ({ unconfidential } = await lq.getAddressInfo(address));
+ }
+
+ invoice = {
+ ...invoice,
+ account_id: user.account.id,
+ address,
+ amount,
+ currency,
+ rate,
+ tip,
+ unconfidential,
+ user_id: user.id
+ };
+
+ if (network === "lightning") {
+ invoice.text = await derivePayRequest(invoice);
+ } else {
+ invoice.text = bip21(invoice, user.account);
+ }
+
+ console.log("TEXT", invoice.text)
l(
"creating invoice",
@@ -73,21 +111,7 @@ app.post("/invoice", optionalAuth, async (req, res, next) => {
if (!invoice.tip) invoice.tip = 0;
- const exists =
- invoice.text &&
- (await db.Invoice.findOne({
- where: {
- [Op.or]: {
- address: invoice.address || "",
- unconfidential: invoice.unconfidential || "",
- text: invoice.text
- }
- }
- }));
-
- invoice = exists
- ? await exists.update(invoice)
- : await db.Invoice.create(invoice);
+ invoice = await db.Invoice.create(invoice);
store.addresses[invoice.address] = user.username;
if (invoice.unconfidential) {
store.addresses[invoice.unconfidential] = user.username;
diff --git a/routes/payments.js b/routes/payments.js
index 298309e0..8b91d9fb 100644
--- a/routes/payments.js
+++ b/routes/payments.js
@@ -58,7 +58,6 @@ app.get("/except", adminAuth, (req, res) => {
});
app.post("/lightning/channel", lnRoutes.channel);
-app.post("/lightning/invoice", lnRoutes.invoice);
app.post("/lightning/query", auth, lnRoutes.query);
app.post("/lightning/send", auth, lnRoutes.send);
diff --git a/routes/users.js b/routes/users.js
index 61d5d33a..3063758d 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -360,114 +360,6 @@ app.post("/logout", optionalAuth, async (req, res) => {
res.send({});
});
-app.get("/address", async (req, res) => {
- let { network, type } = req.query;
- let address, confidentialAddress;
-
- let paymentType = {
- bech32: "p2wpkh",
- "p2sh-segwit": "p2sh",
- legacy: "p2pkh",
- }[type];
- if (!paymentType) paymentType = "p2wpkh";
-
- let hd, i, p, n;
- const mutex = new Mutex();
- const release = await mutex.acquire();
- try {
- if (network === "bitcoin") {
- if (!config.bitcoin) return res.code(500).send("Bitcoin not configured");
-
- address = await bc.getNewAddress("", type);
- store.bcAddressIndex = i + 1;
- return res.send({ address });
-
- p = bitcoin.payments;
- n = prod ? bitcoin.networks["bitcoin"] : bitcoin.networks["regtest"];
-
- i = parseInt(store.bcAddressIndex);
- hd = fromBase58(config.bitcoin.masterkey, n).derivePath(`m/0'/0'/${i}'`);
-
- // async request to node to bump its internal index but don't use result
- bc.getNewAddress().catch(console.error);
- res.send({ address, confidentialAddress });
-
- store.bcAddressIndex = i + 1;
- } else if (network === "liquid") {
- p = liquid.payments;
- n =
- liquid.networks[
- config.liquid.network === "mainnet" ? "liquid" : config.liquid.network
- ];
- paymentType = "p2sh";
-
- // async request to node to bump its internal index but don't use result
- lq.getNewAddress().catch((e) =>
- warn("Problem bumping liquid address index", e.message)
- );
-
- i = parseInt(store.lqAddressIndex);
-
- if (!i) {
- const { hdkeypath } = await lq.getAddressInfo(await lq.getNewAddress());
- const parts = hdkeypath.split("/");
- i = parseInt(parts[parts.length - 1].slice(0, -1));
- }
-
- l("liquid address index", i);
- if (!i) throw new Error("Problem generating address");
-
- hd = fromBase58(config.liquid.masterkey, n).derivePath(`m/0'/0'/${i}'`);
- store.lqAddressIndex = i + 1;
- } else {
- throw new Error("Unsupported network");
- }
- } finally {
- release();
- }
-
- if (paymentType !== "p2sh") {
- ({ address } = p[paymentType]({
- pubkey: hd.publicKey,
- network: n,
- }));
- } else {
- if (network === "liquid") {
- const p2wpkh = p.p2wpkh({
- pubkey: hd.publicKey,
- network: n,
- });
-
- const blindkey = fromPrivateKey(
- Buffer.from(config.liquid.blindkey, "hex"),
- hd.chainCode,
- n
- );
-
- ({ address, confidentialAddress } = p[paymentType]({
- redeem: p2wpkh,
- network: n,
- blindkey: blindkey.publicKey,
- }));
-
- lq.importBlindingKey(
- confidentialAddress,
- blindkey.privateKey.toString("hex")
- );
- } else {
- ({ address } = p[paymentType]({
- redeem: p.p2wpkh({
- pubkey: hd.publicKey,
- network: n,
- }),
- network: n,
- }));
- }
- }
-
- res.send({ address, confidentialAddress });
-});
-
app.post("/account", auth, async (req, res) => {
const { user } = req;
const {