diff options
| author | Adam Soltys <[email protected]> | 2019-09-15 23:05:26 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2019-09-15 23:05:26 -0700 |
| commit | 765c6a42135b9334b616c26b22c816edd06e382a (patch) | |
| tree | 05da4f343358fb5e9a9083e348783f0fab973dd8 /bitcoinPayments.js | |
| parent | 087fdd27f3683a1deb9376b7a72aa608e6fd8e6a (diff) | |
| download | coinos-server-765c6a42135b9334b616c26b22c816edd06e382a.tar.gz coinos-server-765c6a42135b9334b616c26b22c816edd06e382a.zip | |
refactor
Diffstat (limited to 'bitcoinPayments.js')
| -rw-r--r-- | bitcoinPayments.js | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/bitcoinPayments.js b/bitcoinPayments.js new file mode 100644 index 00000000..479298b8 --- /dev/null +++ b/bitcoinPayments.js @@ -0,0 +1,131 @@ +const reverse = require("buffer-reverse"); +const zmq = require("zeromq"); +const config = require("./config"); +const Sequelize = require("sequelize"); + +const bitcoin = require("bitcoinjs-lib"); +const l = console.log; + +const zmqRawBlock = zmq.socket("sub"); +zmqRawBlock.connect(config.bitcoin.zmqrawblock); +zmqRawBlock.subscribe("rawblock"); + +const zmqRawTx = zmq.socket("sub"); +zmqRawTx.connect(config.bitcoin.zmqrawtx); +zmqRawTx.subscribe("rawtx"); + +module.exports = (app, bc, db, addresses, payments, emit) => { + zmqRawTx.on("message", (topic, message, sequence) => { + message = message.toString("hex"); + + let tx = bitcoin.Transaction.fromHex(message); + let hash = reverse(tx.getHash()).toString("hex"); + + if (payments.includes(hash)) return; + + Promise.all( + tx.outs.map(async o => { + let network = config.bitcoin.network; + if (network === "mainnet") { + network = "bitcoin"; + } + + let address; + try { + address = bitcoin.address.fromOutputScript( + o.script, + bitcoin.networks[network] + ); + } catch (e) { + return; + } + + if (Object.keys(addresses).includes(address)) { + payments.push(hash); + + let user = await db.User.findOne({ + where: { + username: addresses[address] + } + }); + + let invoices = await db.Payment.findAll({ + limit: 1, + where: { + hash: address, + received: null, + amount: { + [Sequelize.Op.gt]: 0 + } + }, + order: [["createdAt", "DESC"]] + }); + + let tip = null; + if (invoices.length) tip = invoices[0].tip; + + let confirmed = false; + + if (user.friend) { + user.balance += o.value; + confirmed = true; + } else { + user.pending += o.value; + } + + await user.save(); + emit(user.username, "user", user); + + await db.Payment.create({ + user_id: user.id, + hash, + amount: o.value, + currency: "CAD", + rate: app.get("rates").ask, + received: true, + tip, + confirmed + }); + + l("tx", message); + emit(user.username, "tx", message); + } + }) + ); + }); + + zmqRawBlock.on("message", async (topic, message, sequence) => { + topic = topic.toString("utf8"); + message = message.toString("hex"); + + switch (topic) { + case "rawblock": { + let block = bitcoin.Block.fromHex(message); + l("block", block.getHash().toString("hex")); + + const processPayment = async p => { + if ((await bc.getRawTransaction(p.hash, true)).confirmations > 0) { + let user = await db.User.findByPk(p.user_id); + l(user.pending); + p.confirmed = true; + user.balance += p.amount; + user.pending -= p.amount; + await user.save(); + await p.save(); + emit(user.username, "user", user); + emit(user.username, "block", message); + } + }; + + await db.Payment.findAll({ + where: { confirmed: false } + }).reduce(async (prev, payment) => { + const result = await prev; + return [...result, await processPayment(payment)]; + }, Promise.resolve([])); + + break; + } + } + }); +}; |
