diff options
| author | Adam Soltys <[email protected]> | 2020-08-31 15:39:50 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2020-08-31 15:39:50 -0700 |
| commit | 5e6e9e32e512ef3e65ecff1db33d10376fdafffc (patch) | |
| tree | cc9adf371fd612586b9fd4158ea764359d9af5ff /routes | |
| parent | f17fb75a9fa222a63df84a5a7a9ff911bb5f9765 (diff) | |
| download | coinos-server-tdex.tar.gz coinos-server-tdex.zip | |
tdex wiptdex
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/assets.js | 2 | ||||
| -rw-r--r-- | routes/swaps.js | 799 |
2 files changed, 486 insertions, 315 deletions
diff --git a/routes/assets.js b/routes/assets.js index 35177d6c..66a4526c 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -2,6 +2,7 @@ const axios = require("axios"); const crypto = require("crypto"); app.get("/assets", ah(async (req, res) => { + l.info("hello"); try { const { data: assets } = await axios.get( "https://assets.blockstream.info/" @@ -69,7 +70,6 @@ app.post("/assets", auth, ah(async (req, res) => { params.asset_amount = asset_amount / (SATS / 10 ** precision); - l.info("asset_amount", params.asset_amount); if (token_amount) { params.token_amount = token_amount; params.token_address = token_address; diff --git a/routes/swaps.js b/routes/swaps.js index 71c35733..9632d321 100644 --- a/routes/swaps.js +++ b/routes/swaps.js @@ -5,15 +5,31 @@ const fs = require("fs"); const { spawn } = require("child_process"); const leveldb = level("leveldb"); const getAccount = require("../lib/account"); +const { Swap, WatchOnlyWallet, fetchUtxos, networks } = require("tdex-sdk"); +const liquid = require("liquidjs-lib"); +const network = prod ? networks["liquid"] : networks["regtest"]; const assets = { b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23: "bitcoin", - "4eebe36eb0819e6daa5dd3c97733251ff4eb728c810d949365d6dacaad5ef6e8": "tether", + "4eebe36eb0819e6daa5dd3c97733251ff4eb728c810d949365d6dacaad5ef6e8": "tether" }; -const swapsdir = 'swaps/'; -if (!fs.existsSync(swapsdir)){ - fs.mkdirSync(swapsdir); +const swapsdir = "swaps/"; +if (!fs.existsSync(swapsdir)) { + fs.mkdirSync(swapsdir); +} + +function writeBinary(path, data) { + return new Promise((resolve, reject) => { + try { + const stream = fs.createWriteStream(path); + stream.write(data); + stream.end(); + resolve(); + } catch (err) { + reject(err); + } + }); } const timeout = 20000; @@ -37,15 +53,15 @@ const createProposal = (a1, v1, a2, v2) => ); const proc = cli("propose", a1, v1, a2, v2); - proc.stdout.on("data", (data) => { + proc.stdout.on("data", data => { resolve(data.toString()); }); - proc.stderr.on("error", (err) => { + proc.stderr.on("error", err => { l.error("proposal error", err.toString()); reject(err.toString()); }); - + proc.on("close", (code, signal) => { let msg = (code && code.toString()) || (signal && signal.toString()); reject(new Error(`Liquid swap tool process closed unexpectedly: ${msg}`)); @@ -56,18 +72,21 @@ const createProposal = (a1, v1, a2, v2) => reject(new Error(`Liquid swap tool process exited unexpectedly: ${msg}`)); }); - setTimeout(() => reject(new Error("Liquid swap tool timed out"), proc), timeout); + setTimeout( + () => reject(new Error("Liquid swap tool timed out"), proc), + timeout + ); }); -const getInfo = (filename) => +const getInfo = filename => new Promise((resolve, reject) => { const proc = cli("info", swapsdir + filename); - proc.stdout.on("data", (data) => { + proc.stdout.on("data", data => { resolve(data.toString()); }); - proc.stderr.on("data", (err) => { + proc.stderr.on("data", err => { l.error("info error", err.toString()); reject(err.toString()); }); @@ -82,324 +101,466 @@ const getInfo = (filename) => reject(new Error(`Liquid swap tool process exited unexpectedly: ${msg}`)); }); - setTimeout(() => reject(new Error("Liquid swap tool timed out"), proc), timeout); - }); - -app.delete("/proposal/:id", auth, ah(async (req, res) => { - const { id } = req.params; - await db.Proposal.destroy({ - where: { - id, - user_id: req.user.id, - }, + setTimeout( + () => reject(new Error("Liquid swap tool timed out"), proc), + timeout + ); }); - res.end(); -})); - -app.get("/proposal", auth, ah(async (req, res) => { - try { - const { user } = req; - const { a1, v1, a2, v2 } = req.query; - const b = await lq.getBalance(); - Object.keys(b).map((asset) => { - assets[asset] = asset; - }); - assets["ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"] = "tether"; - assets["6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d"] = "bitcoin"; - assets["a0c358a0f6947864af3a06f3f6a2aeb304df7fd95c922f2f22d7412399ce7691"] = "adamcoin"; - - if (!assets[a1]) throw new Error("unsupported asset"); - if (v1 > b[assets[a1]]) throw new Error("insufficient server funds"); - const account = await db.Account.findOne({ +app.delete( + "/proposal/:id", + auth, + ah(async (req, res) => { + const { id } = req.params; + await db.Proposal.destroy({ where: { - user_id: user.id, - asset: a1, - }, + id, + user_id: req.user.id + } }); - if (v1 > account.balance) throw new Error("insufficient funds"); + res.end(); + }) +); - l.info( - `proposal requested to swap ${v1} ${assets[a1]} for ${v2} ${assets[a2]}` - ); +app.get( + "/proposal", + auth, + ah(async (req, res) => { + try { + const { user } = req; + const { a1, v1, a2, v2 } = req.query; + const b = await lq.getBalance(); - let text = await createProposal(a1, v1, a2, v2); - text = text.replace(/\s+/g, "").trim(); + Object.keys(b).map(asset => { + assets[asset] = asset; + }); + assets[ + "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2" + ] = "tether"; + assets[config.liquid.btcasset] = "bitcoin"; + assets[ + "a0c358a0f6947864af3a06f3f6a2aeb304df7fd95c922f2f22d7412399ce7691" + ] = "adamcoin"; - const proposal = await db.Proposal.create({ - a1, - a2, - v1: Math.round(v1 * SATS), - v2: Math.round(v2 * SATS), - user_id: user.id, - text, - }); + l.info("a1", a1, assets); + if (!assets[a1]) throw new Error("unsupported asset"); + if (v1 > b[assets[a1]]) throw new Error("insufficient server funds"); + const account = await db.Account.findOne({ + where: { + user_id: user.id, + asset: a1 + } + }); + if (v1 > account.balance) throw new Error("insufficient funds"); - res.send({ proposal }); - } catch (e) { - l.error(e.message); - res.status(500).send({ error: e.message }); - } -})); + l.info( + `proposal requested to swap ${v1} ${assets[a1]} for ${v2} ${assets[a2]}` + ); -app.post("/accept", optionalAuth, ah(async (req, res) => { - try { - const { id, text } = req.body; + /* + let text = await createProposal(a1, v1, a2, v2); + text = text.replace(/\s+/g, "").trim(); + */ - const proposal = await db.Proposal.findOne({ - where: { - id, - accepted: false, - }, - include: { - model: db.User, - as: "user", - }, - }); + const woWallet = new WatchOnlyWallet({ + address: (await lq.getAddressInfo(await lq.getNewAddress("", "bech32"))) + .unconfidential, + network + }); - if (!proposal) throw new Error("Proposal not found"); + let utxos = ( + await lq.listUnspent(0, 9999999, [], false, { asset: a1 }) + ).map(({ txid, vout, amount, asset }) => ({ + txid, + vout, + value: Math.round(amount * SATS), + asset + })); - const filename = `proposal-${id}.txt`; + const emptyPsbt = WatchOnlyWallet.createTx(); + let psbtBase64 = woWallet.updateTx( + emptyPsbt, + utxos, + Math.round(v1 * SATS), + Math.round(v2 * SATS), + a1, + a2 + ); - fs.writeFileSync(swapsdir + filename, proposal.text); - let info = JSON.parse(await getInfo(filename)); + let { Psbt } = liquid; + let psbtObj = Psbt.fromBase64(psbtBase64); + console.log(psbtBase64); + console.log("data", psbtObj.data); + psbtObj.data.outputs.map(o => { + console.log("output", o); + }); - const { user } = req; + const swap = new Swap(); + const text = swap.request({ + psbtBase64, + amountToBeSent: Math.round(v1 * SATS), + amountToReceive: Math.round(v2 * SATS), + assetToBeSent: a1, + assetToReceive: a2 + }); - if (user) { - let [fee, rate, asset] = parse(info); - const leg1 = info.legs.find((leg) => !leg.incoming && leg.funded); - const leg2 = info.legs.find((leg) => leg.incoming && !leg.funded); - await db.transaction(async (transaction) => { - const l1a1 = await getAccount(leg1.asset, user); - const l1a2 = await getAccount(leg1.asset, proposal.user); + let filename = swapsdir + "swap_request.bin"; + fs.writeFileSync(filename, text); - let amount = Math.round(leg1.amount * SATS); - if (amount > l1a2.balance) - throw new Error(`Proposer has insufficient funds: ${amount}, ${l1a2.balance}`); + const proposal = await db.Proposal.create({ + a1, + a2, + v1: Math.round(v1 * SATS), + v2: Math.round(v2 * SATS), + user_id: user.id, + text: text.toString() + }); - l1a1.balance += amount; - l1a2.balance -= amount; + let swapRequest, + serializedSwapRequest, + walletInstance, + swapAccept, + swapAcceptFile; - let l1a1p = await db.Payment.create({ - hash: "Internal Transfer", - amount, - account_id: l1a1.id, - memo: "Atomic Swap", - user_id: user.id, - currency: user.currency, - rate, - confirmed: true, - received: true, - network: "COINOS", - }); + serializedSwapRequest = await fs.readFileSync(filename); + const json = Swap.parse({ + message: serializedSwapRequest, + type: "SwapRequest" + }); + swapRequest = JSON.parse(json); + console.log( + `SwapRequest message: ${JSON.stringify(swapRequest, undefined, 2)}` + ); - let l1a2p = await db.Payment.create({ - hash: "Internal Transfer", - amount: -amount, - account_id: l1a2.id, - memo: "Atomic Swap", - user_id: proposal.user_id, - currency: proposal.user.currency, - rate, - confirmed: true, - received: false, - network: "COINOS", - }); + const toWallet = new WatchOnlyWallet({ + address: (await lq.getAddressInfo(await lq.getNewAddress("", "bech32"))) + .unconfidential, + network + }); - const l2a1 = await getAccount(leg2.asset, user); - const l2a2 = await getAccount(leg2.asset, proposal.user); + utxos = (await lq.listUnspent(0, 9999999, [], false, { asset: a2 })).map( + ({ txid, vout, amount, asset }) => ({ + txid, + vout, + value: Math.round(amount * SATS), + asset + }) + ); - amount = Math.round(leg2.amount * SATS); - if (amount > l2a1.balance) throw new Error("Insufficient funds"); + psbtBase64 = toWallet.updateTx( + swapRequest.transaction, + utxos, + Math.round(v2 * SATS), + Math.round(v1 * SATS), + a2, + a1 + ); - l2a1.balance -= amount; - l2a2.balance += amount; + const { btcasset: btc } = config.liquid; - let l2a1p = await db.Payment.create({ - hash: "Internal Transfer", - amount: -amount, - account_id: l2a1.id, - memo: "Atomic Swap", - user_id: user.id, - currency: user.currency, - rate, - confirmed: true, - received: false, - network: "COINOS", - }); + psbtObj = Psbt.fromBase64(swapRequest.transaction); + console.log("data", psbtObj.data); + psbtObj.data.outputs.map(o => { + console.log("output", o); + }); + psbtObj.addOutput({ + asset: btc, + script: Buffer.alloc(0), + value: 1000, + nonce: Buffer.alloc(1, 0) + }); - let l2a2p = await db.Payment.create({ - hash: "Internal Transfer", - amount, - account_id: l2a2.id, - memo: "Atomic Swap", - user_id: proposal.user_id, - currency: proposal.user.currency, - rate, - confirmed: true, - received: true, - network: "COINOS", - }); + let { psbt } = await lq.walletSignPsbt(psbtObj.toBase64()); + let tx = await lq.finalizePsbt(psbt); + console.log(tx); + await lq.sendRawTransaction(tx.hex); - await l1a1.save({ transaction }); - await l1a2.save({ transaction }); - await l2a1.save({ transaction }); - await l2a2.save({ transaction }); + // toWallet.sign(psbtBase64); - proposal.accepted = true; - await proposal.save({ transaction }); + throw new Error("boo"); - l1a1p = l1a1p.get({ plain: true }); - l1a1p.account = l1a1.get({ plain: true }); - l1a2p = l1a2p.get({ plain: true }); - l1a2p.account = l1a2.get({ plain: true }); - l2a1p = l2a1p.get({ plain: true }); - l2a1p.account = l2a1.get({ plain: true }); - l2a2p = l2a2p.get({ plain: true }); - l2a2p.account = l2a2.get({ plain: true }); + res.send({ proposal }); + } catch (e) { + l.error(e.message); + throw e; + res.status(500).send({ error: e.message }); + } + }) +); + +app.post( + "/accept", + optionalAuth, + ah(async (req, res) => { + try { + const { id, text } = req.body; - emit(user.username, "account", l1a1); - emit(user.username, "account", l2a1); - emit(proposal.user.username, "account", l1a2); - emit(proposal.user.username, "account", l2a2); - emit(user.username, "payment", l1a1p); - emit(user.username, "payment", l2a1p); - emit(proposal.user.username, "payment", l1a2p); - emit(proposal.user.username, "payment", l2a2p); - emit(user.username, "proposal", proposal); - emit(proposal.user.username, "proposal", proposal); + const proposal = await db.Proposal.findOne({ + where: { + id, + accepted: false + }, + include: { + model: db.User, + as: "user" + } }); - } else if (text) { - const filename = `acceptance-${id}.txt`; - fs.writeFileSync(swapsdir + filename, text); - info = JSON.parse(await getInfo(filename)); - let [fee, rate, asset] = parse(info); - let { tx, u_address_p, u_address_r } = JSON.parse( - Buffer.from(text, "base64").toString() - ); - const sha256 = crypto.createHash("sha256"); - sha256.update(tx); - const hash = sha256.digest("hex"); + if (!proposal) throw new Error("Proposal not found"); - const leg1 = info.legs.find((leg) => !leg.incoming); - const leg2 = info.legs.find((leg) => leg.incoming); + const filename = `proposal-${id}.txt`; - const l1a2 = await getAccount(leg1.asset, proposal.user); - const btc = await getAccount(config.liquid.btcasset, proposal.user); + fs.writeFileSync(swapsdir + filename, proposal.text); + let info = JSON.parse(await getInfo(filename)); - await db.transaction(async (transaction) => { + const { user } = req; - let amount = Math.round(leg1.amount * SATS); - fee = Math.round(fee * SATS); + if (user) { + let [fee, rate, asset] = parse(info); + const leg1 = info.legs.find(leg => !leg.incoming && leg.funded); + const leg2 = info.legs.find(leg => leg.incoming && !leg.funded); + await db.transaction(async transaction => { + const l1a1 = await getAccount(leg1.asset, user); + const l1a2 = await getAccount(leg1.asset, proposal.user); - if (amount > l1a2.balance) - throw new Error(`Proposer has insufficient funds: ${amount}, ${l1a2.balance}`); + let amount = Math.round(leg1.amount * SATS); + if (amount > l1a2.balance) + throw new Error( + `Proposer has insufficient funds: ${amount}, ${l1a2.balance}` + ); - if (fee > btc.balance) - throw new Error(`Proposer has insufficient funds for fee: ${fee}, ${btc.balance}`); + l1a1.balance += amount; + l1a2.balance -= amount; - l1a2.balance -= amount; - btc.balance -= fee; + let l1a1p = await db.Payment.create({ + hash: "Internal Transfer", + amount, + account_id: l1a1.id, + memo: "Atomic Swap", + user_id: user.id, + currency: user.currency, + rate, + confirmed: true, + received: true, + network: "COINOS" + }); - let payment = await db.Payment.create({ - hash, - amount: -amount, - account_id: l1a2.id, - fee, - memo: "Atomic Swap", - user_id: proposal.user_id, - currency: proposal.user.currency, - rate, - address: u_address_r, - confirmed: true, - received: false, - network: "LBTC", - }); + let l1a2p = await db.Payment.create({ + hash: "Internal Transfer", + amount: -amount, + account_id: l1a2.id, + memo: "Atomic Swap", + user_id: proposal.user_id, + currency: proposal.user.currency, + rate, + confirmed: true, + received: false, + network: "COINOS" + }); - amount = Math.round(leg2.amount * SATS); + const l2a1 = await getAccount(leg2.asset, user); + const l2a2 = await getAccount(leg2.asset, proposal.user); - await db.Invoice.create({ - user_id: proposal.user_id, - text: u_address_p, - currency: proposal.user.currency, - memo: "Atomic Swap", - rate, - amount, - tip: 0, - network: "LBTC", - }); + amount = Math.round(leg2.amount * SATS); + if (amount > l2a1.balance) throw new Error("Insufficient funds"); - addresses[u_address_p] = proposal.user.username; + l2a1.balance -= amount; + l2a2.balance += amount; - await finalize(filename); - await l1a2.save({ transaction }); - await btc.save({ transaction }); + let l2a1p = await db.Payment.create({ + hash: "Internal Transfer", + amount: -amount, + account_id: l2a1.id, + memo: "Atomic Swap", + user_id: user.id, + currency: user.currency, + rate, + confirmed: true, + received: false, + network: "COINOS" + }); - proposal.accepted = true; - await proposal.save({ transaction }); + let l2a2p = await db.Payment.create({ + hash: "Internal Transfer", + amount, + account_id: l2a2.id, + memo: "Atomic Swap", + user_id: proposal.user_id, + currency: proposal.user.currency, + rate, + confirmed: true, + received: true, + network: "COINOS" + }); - payment = payment.get({ plain: true }); - payment.account = l1a2.get({ plain: true }); + await l1a1.save({ transaction }); + await l1a2.save({ transaction }); + await l2a1.save({ transaction }); + await l2a2.save({ transaction }); - emit(proposal.user.username, "payment", payment); - emit(proposal.user.username, "account", l1a2); - emit(proposal.user.username, "account", btc); - emit(proposal.user.username, "proposal", proposal); - }); - } else { - throw new Error("no acceptance provided"); - } + proposal.accepted = true; + await proposal.save({ transaction }); - res.send(info); - } catch (e) { - l.error(e.message); - res.status(500).send(e.message); - } -})); + l1a1p = l1a1p.get({ plain: true }); + l1a1p.account = l1a1.get({ plain: true }); + l1a2p = l1a2p.get({ plain: true }); + l1a2p.account = l1a2.get({ plain: true }); + l2a1p = l2a1p.get({ plain: true }); + l2a1p.account = l2a1.get({ plain: true }); + l2a2p = l2a2p.get({ plain: true }); + l2a2p.account = l2a2.get({ plain: true }); -app.post("/acceptance", ah(async (req, res) => { - const { acceptance: text } = req.body; - l.info("acceptance received"); + emit(user.username, "account", l1a1); + emit(user.username, "account", l2a1); + emit(proposal.user.username, "account", l1a2); + emit(proposal.user.username, "account", l2a2); + emit(user.username, "payment", l1a1p); + emit(user.username, "payment", l2a1p); + emit(proposal.user.username, "payment", l1a2p); + emit(proposal.user.username, "payment", l2a2p); + emit(user.username, "proposal", proposal); + emit(proposal.user.username, "proposal", proposal); + }); + } else if (text) { + const filename = `acceptance-${id}.txt`; + fs.writeFileSync(swapsdir + filename, text); - fs.writeFile(swapsdir + "accepted.txt", text, async (err) => { - if (err) { - return res.status(500).send(err); - } + info = JSON.parse(await getInfo(filename)); + let [fee, rate, asset] = parse(info); + let { tx, u_address_p, u_address_r } = JSON.parse( + Buffer.from(text, "base64").toString() + ); + const sha256 = crypto.createHash("sha256"); + sha256.update(tx); + const hash = sha256.digest("hex"); - try { - let info = JSON.parse( - await new Promise((resolve, reject) => { - const proc = cli("info", swapsdir + "accepted.txt"); + const leg1 = info.legs.find(leg => !leg.incoming); + const leg2 = info.legs.find(leg => leg.incoming); + + const l1a2 = await getAccount(leg1.asset, proposal.user); + const btc = await getAccount(config.liquid.btcasset, proposal.user); + + await db.transaction(async transaction => { + let amount = Math.round(leg1.amount * SATS); + fee = Math.round(fee * SATS); + + if (amount > l1a2.balance) + throw new Error( + `Proposer has insufficient funds: ${amount}, ${l1a2.balance}` + ); + + if (fee > btc.balance) + throw new Error( + `Proposer has insufficient funds for fee: ${fee}, ${btc.balance}` + ); + + l1a2.balance -= amount; + btc.balance -= fee; - proc.stdout.on("data", (data) => { - resolve(data.toString()); + let payment = await db.Payment.create({ + hash, + amount: -amount, + account_id: l1a2.id, + fee, + memo: "Atomic Swap", + user_id: proposal.user_id, + currency: proposal.user.currency, + rate, + address: u_address_r, + confirmed: true, + received: false, + network: "LBTC" }); - proc.stderr.on("data", (err) => { - reject(err.toString()); + amount = Math.round(leg2.amount * SATS); + + await db.Invoice.create({ + user_id: proposal.user_id, + text: u_address_p, + currency: proposal.user.currency, + memo: "Atomic Swap", + rate, + amount, + tip: 0, + network: "LBTC" }); - setTimeout(() => reject(new Error("Liquid swap tool timed out"), proc), timeout); - }) - ); + addresses[u_address_p] = proposal.user.username; + + await finalize(filename); + await l1a2.save({ transaction }); + await btc.save({ transaction }); - const time = Math.floor(new Date()).toString(); - const [fee, rate, asset] = parse(info); - if (!asset) throw new Error("unsupported asset"); - l.info("accepted", info, rate, asset); + proposal.accepted = true; + await proposal.save({ transaction }); - leveldb.put(time, JSON.stringify({ text, info, rate, asset })); - l.info({ text, info, rate, asset }); + payment = payment.get({ plain: true }); + payment.account = l1a2.get({ plain: true }); + + emit(proposal.user.username, "payment", payment); + emit(proposal.user.username, "account", l1a2); + emit(proposal.user.username, "account", btc); + emit(proposal.user.username, "proposal", proposal); + }); + } else { + throw new Error("no acceptance provided"); + } - res.send({ info, rate }); + res.send(info); } catch (e) { - l.error(e); - res.status(500).send({ error: e }); + l.error(e.message); + res.status(500).send(e.message); } - }); -})); + }) +); + +app.post( + "/acceptance", + ah(async (req, res) => { + const { acceptance: text } = req.body; + l.info("acceptance received"); + + fs.writeFile(swapsdir + "accepted.txt", text, async err => { + if (err) { + return res.status(500).send(err); + } + + try { + let info = JSON.parse( + await new Promise((resolve, reject) => { + const proc = cli("info", swapsdir + "accepted.txt"); + + proc.stdout.on("data", data => { + resolve(data.toString()); + }); + + proc.stderr.on("data", err => { + reject(err.toString()); + }); + + setTimeout( + () => reject(new Error("Liquid swap tool timed out"), proc), + timeout + ); + }) + ); + + const time = Math.floor(new Date()).toString(); + const [fee, rate, asset] = parse(info); + if (!asset) throw new Error("unsupported asset"); + l.info("accepted", info, rate, asset); + + leveldb.put(time, JSON.stringify({ text, info, rate, asset })); + l.info({ text, info, rate, asset }); + + res.send({ info, rate }); + } catch (e) { + l.error(e); + res.status(500).send({ error: e }); + } + }); + }) +); checkQueue = async () => { const ws = app.get("ws"); @@ -407,32 +568,32 @@ checkQueue = async () => { leveldb .createReadStream() - .on("data", async function (data) { + .on("data", async function(data) { txs.push({ ...JSON.parse(data.value), key: data.key }); }) - .on("end", async function (data) { + .on("end", async function(data) { const rate = (a, b) => a.rate - b.rate; const time = (a, b) => b.time - a.time; - const pending = txs.filter((tx) => !tx.id); - const completed = txs.filter((tx) => tx.id).sort(time); + const pending = txs.filter(tx => !tx.id); + const completed = txs.filter(tx => tx.id).sort(time); const bitcoin = pending - .filter((tx) => tx.asset === "bitcoin") + .filter(tx => tx.asset === "bitcoin") .sort(rate) .reverse(); const tether = pending - .filter((tx) => tx.asset === "tether") + .filter(tx => tx.asset === "tether") .sort(rate) .reverse(); - const strip = (a) => + const strip = a => a.map(({ id, key, info, rate, time }) => ({ id, key, info, rate, - time, + time })); ws && @@ -440,7 +601,7 @@ checkQueue = async () => { JSON.stringify({ completed: strip(completed.slice(0, 3)), bitcoin: strip(bitcoin.slice(0, 3)), - tether: strip(tether.slice(0, 3)), + tether: strip(tether.slice(0, 3)) }) ); @@ -469,12 +630,12 @@ checkQueue = async () => { }); }; -const parse = (info) => { +const parse = info => { const fee = info.legs[0].fee; return [ fee, (info.legs[1].amount / (info.legs[0].amount + fee)).toFixed(8), - assets[info.legs[0].asset], + assets[info.legs[0].asset] ]; }; @@ -484,11 +645,11 @@ const finalize = (filename = "finalized.txt", text) => { return new Promise((resolve, reject) => { const proc = cli("finalize", swapsdir + filename, "-s"); - proc.stdout.on("data", (data) => { + proc.stdout.on("data", data => { resolve(data.toString()); }); - proc.stderr.on("data", (err) => { + proc.stderr.on("data", err => { reject(new Error(err.toString())); }); @@ -502,39 +663,49 @@ const finalize = (filename = "finalized.txt", text) => { reject(new Error(`Liquid swap tool process exited unexpectedly: ${msg}`)); }); - setTimeout(() => reject(new Error("Liquid swap tool timed out"), proc), timeout); + setTimeout( + () => reject(new Error("Liquid swap tool timed out"), proc), + timeout + ); }); }; -app.get("/proposals", optionalAuth, ah(async (req, res) => { - try { - if (req.user) { - res.send(await db.Proposal.findAll()); - } else { - res.send( - await db.Proposal.findAll({ - attributes: { exclude: ["user_id"] }, - where: { - accepted: false, - }, - }) - ); +app.get( + "/proposals", + optionalAuth, + ah(async (req, res) => { + try { + if (req.user) { + res.send(await db.Proposal.findAll()); + } else { + res.send( + await db.Proposal.findAll({ + attributes: { exclude: ["user_id"] }, + where: { + accepted: false + } + }) + ); + } + } catch (e) { + res.status(500).send(e.message); } - } catch (e) { - res.status(500).send(e.message); - } -})); - -app.post("/publish", auth, ah(async (req, res) => { - try { - const { id } = req.body; - await db.Proposal.update( - { public: true }, - { where: { id, user_id: req.user.id } } - ); - res.end(); - } catch (e) { - res.status(500).send(e.message); - } -})); + }) +); +app.post( + "/publish", + auth, + ah(async (req, res) => { + try { + const { id } = req.body; + await db.Proposal.update( + { public: true }, + { where: { id, user_id: req.user.id } } + ); + res.end(); + } catch (e) { + res.status(500).send(e.message); + } + }) +); |
