diff options
| author | Adam Soltys <[email protected]> | 2020-10-12 00:39:45 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2020-10-12 00:39:45 -0700 |
| commit | a90d6cc97470696ade30f237b050b8b329858a17 (patch) | |
| tree | d2b0144a6076d799aa779a731f61e7c9c864f6a7 /routes | |
| parent | d7e5d530bd37f611beb1884c0587593fb9fb5880 (diff) | |
| download | coinos-server-a90d6cc97470696ade30f237b050b8b329858a17.tar.gz coinos-server-a90d6cc97470696ade30f237b050b8b329858a17.zip | |
javascript address generation
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/bitcoin/receive.js | 5 | ||||
| -rw-r--r-- | routes/invoices.js | 2 | ||||
| -rw-r--r-- | routes/payments.js | 14 | ||||
| -rw-r--r-- | routes/users.js | 113 |
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 } } |
