aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2020-10-12 00:39:45 -0700
committerAdam Soltys <[email protected]>2020-10-12 00:39:45 -0700
commita90d6cc97470696ade30f237b050b8b329858a17 (patch)
treed2b0144a6076d799aa779a731f61e7c9c864f6a7 /routes
parentd7e5d530bd37f611beb1884c0587593fb9fb5880 (diff)
downloadcoinos-server-a90d6cc97470696ade30f237b050b8b329858a17.tar.gz
coinos-server-a90d6cc97470696ade30f237b050b8b329858a17.zip
javascript address generation
Diffstat (limited to 'routes')
-rw-r--r--routes/bitcoin/receive.js5
-rw-r--r--routes/invoices.js2
-rw-r--r--routes/payments.js14
-rw-r--r--routes/users.js113
4 files changed, 114 insertions, 20 deletions
diff --git a/routes/bitcoin/receive.js b/routes/bitcoin/receive.js
index 12eb760e..e0e3828b 100644
--- a/routes/bitcoin/receive.js
+++ b/routes/bitcoin/receive.js
@@ -77,11 +77,6 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
if (config.bitcoin.walletpass)
await bc.walletPassphrase(config.bitcoin.walletpass, 300);
- user.address = await bc.getNewAddress("", "bech32");
- await user.save();
-
- addresses[user.address] = user.username;
-
let totalOutputs = tx.outs.reduce((a, b) => a + b.value, 0);
let totalInputs = 0;
for (let i = 0; i < tx.ins.length; i++) {
diff --git a/routes/invoices.js b/routes/invoices.js
index f084b4c3..443c1565 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -62,7 +62,7 @@ app.post("/invoice", ah(async (req, res, next) => {
addresses[invoice.address] = user.username;
if (invoice.unconfidential) {
addresses[invoice.unconfidential] = user.username;
- await lq.importBlindingKey(invoice.address, blindkey);
+ if (blindkey) await lq.importBlindingKey(invoice.address, blindkey);
}
res.send(invoice);
} catch(e) {
diff --git a/routes/payments.js b/routes/payments.js
index 11242667..cf9e1d00 100644
--- a/routes/payments.js
+++ b/routes/payments.js
@@ -113,6 +113,13 @@ ah(async () => {
app.post("/bitcoin/fee", auth, require("./bitcoin/fee"));
app.post("/bitcoin/send", auth, require("./bitcoin/send"));
require("./bitcoin/receive");
+
+ setTimeout(async () => {
+ const address = await bc.getNewAddress();
+ const { hdkeypath } = await bc.getAddressInfo(address);
+ const parts = hdkeypath.split('/');
+ app.set("bcAddressIndex", parts[parts.length - 1].slice(0, -1));
+ }, 50);
}
if (config.liquid) {
@@ -126,6 +133,13 @@ ah(async () => {
app.post("/liquid/fee", auth, require("./liquid/fee"));
app.post("/liquid/send", auth, require("./liquid/send"));
require("./liquid/receive");
+
+ setTimeout(async () => {
+ const address = await lq.getNewAddress();
+ const { hdkeypath } = await lq.getAddressInfo(address);
+ const parts = hdkeypath.split('/');
+ app.set("lqAddressIndex", parts[parts.length - 1].slice(0, -1));
+ }, 50);
}
app.get(
diff --git a/routes/users.js b/routes/users.js
index d40ad5a8..6e9678fe 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -6,6 +6,11 @@ const textToImage = require("text-to-image");
const randomWord = require("random-words");
const getAccount = require("../lib/account");
const Sequelize = require("sequelize");
+const bitcoin = require("bitcoinjs-lib");
+const liquid = require("liquidjs-lib");
+const { fromBase58, fromPrivateKey } = require("bip32");
+const { Mutex } = require("async-mutex");
+const bip32 = require("bip32");
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
require("../lib/whitelist");
@@ -259,7 +264,16 @@ app.post(
"/accounts",
auth,
ah(async (req, res) => {
- const { name, seed, pubkey, ticker, precision, path, privkey, network } = req.body;
+ const {
+ name,
+ seed,
+ pubkey,
+ ticker,
+ precision,
+ path,
+ privkey,
+ network
+ } = req.body;
const { user } = req;
let account = await db.Account.create({
@@ -384,24 +398,84 @@ app.post(
app.get(
"/address",
ah(async (req, res) => {
- const { network, type } = req.query;
+ let { network, type } = req.query;
let address;
- if (network === "bitcoin") {
- if (!config.bitcoin)
- return res.status(500).send("Bitcoin not configured");
+ type = {
+ bech32: "p2wpkh",
+ "p2sh-segwit": "p2sh",
+ legacy: "p2pkh"
+ }[type];
- if (config.bitcoin.walletpass)
- await bc.walletPassphrase(config.bitcoin.walletpass, 300);
+ let hd, i, p, n;
+ const mutex = new Mutex();
+ const release = await mutex.acquire();
+ try {
+ if (network === "bitcoin") {
+ if (!config.bitcoin)
+ return res.status(500).send("Bitcoin not configured");
+ p = bitcoin.payments;
+ n = prod ? bitcoin.networks["bitcoin"] : bitcoin.networks["regtest"];
- address = await bc.getNewAddress("", type || "bech32");
- } else if (network === "liquid") {
- if (!config.liquid) return res.status(500).send("Liquid not configured");
+ i = parseInt(app.get("bcAddressIndex"));
+ hd = fromBase58(config.bitcoin.masterkey, n).derivePath(
+ `m/0'/0'/${i}'`
+ );
+ app.set("bcAddressIndex", i + 1);
+ } else if (network === "liquid") {
+ p = liquid.payments;
+ n =
+ liquid.networks[
+ config.liquid.network === "mainnet"
+ ? "liquid"
+ : config.liquid.network
+ ];
+ type = "p2sh";
- if (config.liquid.walletpass)
- await lq.walletPassphrase(config.liquid.walletpass, 300);
+ i = parseInt(app.get("lqAddressIndex"));
+ hd = fromBase58(config.liquid.masterkey, n).derivePath(`m/0'/0'/${i}'`);
+ app.set("lqAddressIndex", i + 1);
+ } else {
+ throw new Error("Unsupported network");
+ }
+ } finally {
+ release();
+ }
+
+ if (type !== "p2sh") {
+ ({ address } = p[type]({
+ 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
+ );
+
+ ({ confidentialAddress: address } = p[type]({
+ redeem: p2wpkh,
+ network: n,
+ blindkey: blindkey.publicKey
+ }));
- address = await lq.getNewAddress("", type || "bech32");
+ lq.importBlindingKey(address, blindkey.privateKey.toString('hex'));
+ } else {
+ ({ address } = p[type]({
+ redeem: p.p2wpkh({
+ pubkey: hd.publicKey,
+ network: n
+ }),
+ network: n
+ }));
+ }
}
res.send(address);
@@ -429,7 +503,18 @@ app.post(
try {
await db.Account.update(
- { name, ticker, precision, domain, seed, pubkey, path, hide, index, privkey },
+ {
+ name,
+ ticker,
+ precision,
+ domain,
+ seed,
+ pubkey,
+ path,
+ hide,
+ index,
+ privkey
+ },
{
where: { id, user_id: user.id }
}