1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
import reverse from "buffer-reverse";
import zmq from "zeromq";
import config from "./config";
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 = (bc, db, addresses, payments) => {
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) {
l(e);
return;
}
l(o);
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
});
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"));
await db.Payment.findAll({
include: { model: db.User, as: "user" },
where: { confirmed: false }
}).map(async p => {
if ((await bc.getRawTransaction(p.hash, true)).confirmations > 0) {
let user = p.user;
p.confirmed = true;
user.balance += p.amount;
user.pending -= p.amount;
await user.save();
await p.save();
emit(user.username, "user", user);
}
});
socket.emit("block", message);
break;
}
}
});
};
|