aboutsummaryrefslogtreecommitdiffstats
path: root/routes/bitcoin/send.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2020-03-11 15:10:40 -0700
committerAdam Soltys <[email protected]>2020-03-11 15:10:40 -0700
commitc0888fab024cc9f7c99812bfabf9d7774312dbf7 (patch)
treecad95683af97432f6092a2c2bae10fbb7a588db5 /routes/bitcoin/send.js
parentbf2b51f0c2ae9b8f0f330dde6411e45fc0da8a25 (diff)
downloadcoinos-server-c0888fab024cc9f7c99812bfabf9d7774312dbf7.tar.gz
coinos-server-c0888fab024cc9f7c99812bfabf9d7774312dbf7.zip
refactor
Diffstat (limited to 'routes/bitcoin/send.js')
-rw-r--r--routes/bitcoin/send.js93
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);
+ }
+};