aboutsummaryrefslogtreecommitdiffstats
path: root/sendCoins.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2019-09-15 23:05:26 -0700
committerAdam Soltys <[email protected]>2019-09-15 23:05:26 -0700
commit765c6a42135b9334b616c26b22c816edd06e382a (patch)
tree05da4f343358fb5e9a9083e348783f0fab973dd8 /sendCoins.js
parent087fdd27f3683a1deb9376b7a72aa608e6fd8e6a (diff)
downloadcoinos-server-765c6a42135b9334b616c26b22c816edd06e382a.tar.gz
coinos-server-765c6a42135b9334b616c26b22c816edd06e382a.zip
refactor
Diffstat (limited to 'sendCoins.js')
-rw-r--r--sendCoins.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/sendCoins.js b/sendCoins.js
new file mode 100644
index 00000000..31d12c26
--- /dev/null
+++ b/sendCoins.js
@@ -0,0 +1,82 @@
+const bitcoin = require("bitcoinjs-lib");
+const config = require("./config");
+const reverse = require("buffer-reverse");
+
+const l = console.log;
+
+module.exports = (app, bc, db, emit) => async (req, res) => {
+ const MINFEE = 3000;
+
+ let { address, amount } = req.body;
+
+ l("sending coins", req.user.username, amount, address);
+
+ if (amount === req.user.balance) {
+ amount = req.user.balance - MINFEE;
+ }
+
+ try {
+ await db.transaction(async transaction => {
+ let { balance } = await db.User.findOne(
+ {
+ where: {
+ username: req.user.username
+ }
+ },
+ { transaction }
+ );
+
+ if (amount > balance) {
+ l("amount exceeds balance", amount, balance);
+ throw new Error("insufficient funds");
+ }
+
+ req.user.balance -= parseInt(amount) + 10000;
+ await req.user.save({ transaction });
+ });
+ } catch (e) {
+ return res.status(500).send("Not enough satoshis");
+ }
+
+ try {
+ if (config.bitcoin.walletpass)
+ await bc.walletPassphrase(config.bitcoin.walletpass, 300);
+
+ let txid = await bc.sendToAddress(address, (amount / 100000000).toFixed(8));
+
+ let txhex = await bc.getRawTransaction(txid);
+ let tx = bitcoin.Transaction.fromHex(txhex);
+
+ let inputTotal = await tx.ins.reduce(async (a, input) => {
+ let h = await bc.getRawTransaction(reverse(input.hash).toString("hex"));
+ return a + bitcoin.Transaction.fromHex(h).outs[input.index].value;
+ }, 0);
+ let outputTotal = tx.outs.reduce((a, b) => a + b.value, 0);
+
+ let fees = inputTotal - outputTotal;
+ let total = Math.min(parseInt(amount) + fees, req.user.balance);
+ req.user.balance += 10000 - fees;
+ if (req.user.balance < 0) req.user.balance = 0;
+
+ await db.transaction(async transaction => {
+ await req.user.save({ transaction });
+ emit(req.user.username, "user", req.user);
+
+ await db.Payment.create(
+ {
+ amount: -total,
+ user_id: req.user.id,
+ hash: txid,
+ rate: app.get("rates").ask,
+ currency: "CAD"
+ },
+ { transaction }
+ );
+ });
+
+ res.send({ txid, tx, amount, fees });
+ } catch (e) {
+ l(e);
+ res.status(500).send(e.message);
+ }
+};