From a7168a10f45c305a45d2e56db6fbfeef210f1b9b Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 2 Aug 2021 02:05:28 -0700 Subject: silhouettes --- routes/assets.js | 7 ++--- routes/liquid/taxi.js | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ routes/payments.js | 1 + 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 routes/liquid/taxi.js diff --git a/routes/assets.js b/routes/assets.js index f99301ae..2494ee94 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -111,7 +111,7 @@ app.post( if (filename) contract.filename = filename; - l.info("attempting issuance", req.user.username, contract); + l.info("attempting issuance", req.user.username, contract, "address", address, "pubkey", pubkey); sha256.update(JSON.stringify(contract)); const hash = sha256.digest("hex"); @@ -149,7 +149,7 @@ app.post( const srt = await lq.signRawTransactionWithWallet(brt); const allowed = (await lq.testMempoolAccept([srt.hex]))[0].allowed; fs.writeFileSync('tx', srt.hex); - if (!allowed) throw new Error(); + if (!allowed) throw new Error("issuance rejected by mempool"); const txid = await lq.sendRawTransaction(srt.hex); await db.transaction(async transaction => { @@ -185,6 +185,7 @@ app.post( await account.reload({ transaction }); emit(user.username, "account", account); + if (address) return; account = await db.Account.create( { asset, @@ -271,7 +272,7 @@ app.post( res.send(issuances[txid]); } catch (e) { - l.error("asset issuance failed", e.message); + l.error("asset issuance failed", e.message, e.stack); res.status(500).send(e.message); } }) diff --git a/routes/liquid/taxi.js b/routes/liquid/taxi.js new file mode 100644 index 00000000..3f450752 --- /dev/null +++ b/routes/liquid/taxi.js @@ -0,0 +1,74 @@ +const { ECPair, Psbt, payments, networks } = require("@asoltys/liquidjs-lib"); +const wretch = require("wretch"); +const fetch = require("node-fetch"); +wretch().polyfills({ fetch }); +const url = prod + ? "https://blockstream.info/liquid/api" + : "http://localhost:3002"; +const electrs = wretch().url(url); +const network = networks.regtest; + +module.exports = ah(async (req, res) => { + let { user } = req; + let { psbt } = req.body; + + let utxos = await electrs + .url(`/address/XLDLqkbbNKvgS9vhj3fQWPv1Y3UNoHEneZ/utxo`) + .get() + .json(); + let tx = utxos.find(tx => tx.value >= 150); + let hex = await electrs + .url(`/tx/${tx.txid}/hex/`) + .get() + .text(); + + let redeemScript = payments.p2wpkh({ + pubkey: Buffer.from( + "03c42e2b536630da346d8f225797406eb86700239d627101a61e26e6d544db072e", + "hex" + ), + network + }).output; + + let p = Psbt.fromBase64(psbt) + .addInput({ + hash: tx.txid, + index: tx.vout, + redeemScript, + nonWitnessUtxo: Buffer.from(hex, "hex") + }) + .addOutput({ + asset: network.assetHash, + nonce: Buffer.alloc(1, 0), + script: Buffer.alloc(0), + value: 150 + }) + .addOutput({ + asset, + nonce: Buffer.alloc(1), + script: Address.toOutputScript( + "XLDLqkbbNKvgS9vhj3fQWPv1Y3UNoHEneZ", + network + ), + value: tx.value - 150 + }) + .signInput( + 1, + ECPair.fromPrivateKey( + Buffer.from( + "6802b8dfed3733e3b147582810c431150444c026066796b808c36f7089d02773", + "hex" + ) + ) + ); + + try { + if ((user.username = "silhouettes")) { + res.send({ psbt: p.toBase64() }); + } else { + throw new Error("taxi service only available to select customers"); + } + } catch (e) { + return res.status(500).send(e); + } +}); diff --git a/routes/payments.js b/routes/payments.js index a4bae562..a749e333 100644 --- a/routes/payments.js +++ b/routes/payments.js @@ -142,6 +142,7 @@ ah(async () => { app.get("/liquid/generate", auth, require("./liquid/generate")); app.post("/liquid/fee", auth, require("./liquid/fee")); app.post("/liquid/send", auth, require("./liquid/send")); + app.post("/taxi", auth, require("./liquid/taxi")); require("./liquid/receive"); setTimeout(async () => { -- cgit v1.2.3