diff options
| author | Adam Soltys <[email protected]> | 2020-03-11 15:10:40 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2020-03-11 15:10:40 -0700 |
| commit | c0888fab024cc9f7c99812bfabf9d7774312dbf7 (patch) | |
| tree | cad95683af97432f6092a2c2bae10fbb7a588db5 /routes/bitcoin/send.js | |
| parent | bf2b51f0c2ae9b8f0f330dde6411e45fc0da8a25 (diff) | |
| download | coinos-server-c0888fab024cc9f7c99812bfabf9d7774312dbf7.tar.gz coinos-server-c0888fab024cc9f7c99812bfabf9d7774312dbf7.zip | |
refactor
Diffstat (limited to 'routes/bitcoin/send.js')
| -rw-r--r-- | routes/bitcoin/send.js | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/routes/bitcoin/send.js b/routes/bitcoin/send.js new file mode 100644 index 00000000..3c545178 --- /dev/null +++ b/routes/bitcoin/send.js @@ -0,0 +1,93 @@ +const bitcoin = require("bitcoinjs-lib"); +const reverse = require("buffer-reverse"); + +module.exports = async (req, res) => { + let { user } = req; + let { address, tx } = req.body; + let { hex } = tx; + + let fee = toSats(tx.fee); + + const isChange = async address => + !((await bc.getAddressInfo(address)).ismine) || + !Object.keys(addresses).includes(address) || + address === user.address; + + tx = await bc.decodeRawTransaction(hex); + + let total = 0; + let change = 0; + + for (let i = 0; i < tx.vout.length; i++) { + let o = tx.vout[i]; + total += toSats(o.value); + + if (o.scriptPubKey.addresses) { + if ((await isChange(o.scriptPubKey.addresses[0]))) { + change += toSats(o.value); + } + } + } + + total = (total - change) + fee; + let amount = total - fee; + + try { + await db.transaction(async transaction => { + let { balance } = await db.User.findOne({ + where: { + username: user.username + }, + lock: transaction.LOCK.UPDATE, + transaction + }); + + if (amount !== balance && total > balance) { + l.error("amount exceeds balance", amount, fee, balance); + throw new Error("insufficient funds"); + } + + user.balance -= total; + await user.save({ transaction }); + }); + } catch (e) { + l.warn("insufficient funds for bitcoin payment", e); + return res.status(500).send("Not enough satoshis"); + } + + try { + if (config.bitcoin.walletpass) + await bc.walletPassphrase(config.bitcoin.walletpass, 300); + + hex = (await bc.signRawTransactionWithWallet(hex)).hex; + let txid = await bc.sendRawTransaction(hex); + + await db.transaction(async transaction => { + await user.save({ transaction }); + emit(user.username, "user", user); + + const payment = await db.Payment.create( + { + amount: -total, + fee, + user_id: user.id, + hash: txid, + rate: app.get("rates")[user.currency], + currency: user.currency, + address, + confirmed: true, + received: false, + asset: "BTC" + }, + { transaction } + ); + + l.info("sent bitcoin", user.username, total); + emit(user.username, "payment", payment); + res.send(payment); + }); + } catch (e) { + l.error("error sending bitcoin", e); + return res.status(500).send(e.message); + } +}; |
