aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2020-01-13 16:06:56 -0800
committerAdam Soltys <[email protected]>2020-01-13 16:06:56 -0800
commit9c2a909dc707c3f2baad8f86cbeea54606dbea41 (patch)
treeff23f0f8dba4338e1f19ae7b1048e52f00dc7780
parenta5a96f451f559f4f7f27529d2e5f44b0bb84d0e5 (diff)
downloadcoinos-server-9c2a909dc707c3f2baad8f86cbeea54606dbea41.tar.gz
coinos-server-9c2a909dc707c3f2baad8f86cbeea54606dbea41.zip
liquid receiving support
-rw-r--r--index.js3
-rw-r--r--liquidPayments.js134
-rw-r--r--models/users.js18
-rw-r--r--payments.js1
-rw-r--r--users.js11
5 files changed, 162 insertions, 5 deletions
diff --git a/index.js b/index.js
index f13e666a..aab88b93 100644
--- a/index.js
+++ b/index.js
@@ -35,9 +35,10 @@ const l = console.log;
const seen = [];
const addresses = {};
await db.User.findAll({
- attributes: ["username", "address"]
+ attributes: ["username", "address", "liquid"]
}).map(u => {
addresses[u.address] = u.username;
+ if (u.liquid) addresses[u.liquid] = u.username;
});
const payments = (await db.Payment.findAll({
diff --git a/liquidPayments.js b/liquidPayments.js
new file mode 100644
index 00000000..62be1243
--- /dev/null
+++ b/liquidPayments.js
@@ -0,0 +1,134 @@
+const reverse = require("buffer-reverse");
+const zmq = require("zeromq");
+const config = require("./config");
+const Sequelize = require("sequelize");
+const BitcoinCore = require("bitcoin-core");
+const bitcoin = require("bitcoinjs-lib");
+const l = console.log;
+
+const zmqRawBlock = zmq.socket("sub");
+zmqRawBlock.connect(config.liquid.zmqrawblock);
+zmqRawBlock.subscribe("rawblock");
+
+const zmqRawTx = zmq.socket("sub");
+zmqRawTx.connect("tcp://127.0.0.1:18603");
+zmqRawTx.subscribe("rawtx");
+
+let NETWORK = bitcoin.networks[config.bitcoin.network === "mainnet" ? "bitcoin" : config.bitcoin.network];
+const bc = new BitcoinCore(config.liquid);
+
+module.exports = (app, db, addresses, payments, emit) => {
+ zmqRawTx.on("message", async (topic, message, sequence) => {
+ const tx = await bc.decodeRawTransaction(message.toString("hex"));
+
+ Promise.all(
+ tx.vout.map(async o => {
+ if (!(o.scriptPubKey && o.scriptPubKey.addresses)) return;
+ const address = o.scriptPubKey.addresses[0];
+
+ 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: {
+ address,
+ received: null,
+ amount: {
+ [Sequelize.Op.gt]: 0
+ }
+ },
+ order: [["id", "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);
+
+ const payment = await db.Payment.create({
+ user_id: user.id,
+ hash,
+ amount: o.value,
+ currency: "CAD",
+ rate: app.get("ask"),
+ received: true,
+ tip,
+ confirmed,
+ address
+ });
+
+ emit(user.username, "payment", payment);
+ emit(user.username, "tx", message);
+ }
+ })
+ );
+ });
+
+ let queue = {};
+
+ zmqRawBlock.on("message", async (topic, message, sequence) => {
+ /*
+ const payments = await db.Payment.findAll({
+ where: { confirmed: false }
+ });
+
+ const hashes = payments.map(p => p.hash);
+
+ let block = bitcoin.Block.fromHex(message.toString("hex"));
+ block.transactions.map(tx => {
+ let hash = reverse(tx.getHash()).toString("hex");
+ if (hashes.includes(hash)) queue[hash] = 1;
+ });
+ */
+ });
+
+ /*
+ setInterval(async () => {
+ let arr = Object.keys(queue);
+ for (let i = 0; i < arr.length; i++) {
+ let hash = arr[i];
+
+ let p = await db.Payment.findOne({
+ include: [{ model: db.User, as: "user" }],
+ where: { hash, confirmed: 0 }
+ })
+
+ p.confirmed = 1;
+
+ let user = await p.getUser();
+ user.balance += p.amount;
+ user.pending -= p.amount;
+ emit(user.username, "user", user);
+
+ await user.save();
+ await p.save();
+
+ let payments = await db.Payment.findAll({
+ where: { user_id: user.id },
+ order: [['id', 'DESC']],
+ limit: 20
+ });
+
+ emit(user.username, "payments", payments);
+ delete queue[hash];
+ }
+ }, 1000);
+ */
+};
diff --git a/models/users.js b/models/users.js
index 09ba8660..40eb00f5 100644
--- a/models/users.js
+++ b/models/users.js
@@ -40,6 +40,24 @@ module.exports = sequelize => {
comment: null,
field: "email"
},
+ liquid: {
+ type: DataTypes.STRING(255),
+ allowNull: true,
+ defaultValue: null,
+ primaryKey: false,
+ autoIncrement: false,
+ comment: null,
+ field: "liquid"
+ },
+ confidential: {
+ type: DataTypes.STRING(255),
+ allowNull: true,
+ defaultValue: null,
+ primaryKey: false,
+ autoIncrement: false,
+ comment: null,
+ field: "confidential"
+ },
address: {
type: DataTypes.STRING(255),
allowNull: true,
diff --git a/payments.js b/payments.js
index b9b932dd..3f2a8d17 100644
--- a/payments.js
+++ b/payments.js
@@ -6,6 +6,7 @@ module.exports = async (app, auth, addresses, bc, db, emit, seen, payments) => {
const lnb = await createLnrpc(config.lnb);
require("./bitcoinPayments")(app, bc, db, addresses, payments, emit);
+ require("./liquidPayments")(app, bc, db, addresses, payments, emit);
require("./lightningPayments")(app, db, lna, lnb, emit, payments);
app.post(
diff --git a/users.js b/users.js
index 4442c785..68624b76 100644
--- a/users.js
+++ b/users.js
@@ -4,12 +4,13 @@ const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const mailgun = require("mailgun-js");
const uuidv4 = require("uuid/v4");
-
+const BitcoinCore = require("bitcoin-core");
const authyVerify = require("./authy");
const config = require("./config");
const authy = new Client({ key: config.authy.key });
const whitelist = require("./whitelist");
const fb = "https://graph.facebook.com/";
+const liquid = new BitcoinCore(config.liquid);
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
@@ -24,6 +25,8 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
if (exists) return err("Username taken");
user.address = await bc.getNewAddress("", "bech32");
+ user.confidential = await liquid.getNewAddress();
+ user.liquid = (await liquid.getAddressInfo(user.confidential)).unconfidential;
user.password = await bcrypt.hash(user.password, 1);
user.name = user.username;
user.currency = "USD";
@@ -91,7 +94,6 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
phone,
twofa,
pin,
- pinconfirm,
password,
passconfirm
} = req.body;
@@ -112,13 +114,12 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
user.email = email;
user.phone = phone;
user.twofa = twofa;
+ user.pin = pin;
if (password && password === passconfirm) {
user.password = await bcrypt.hash(password, 1);
}
- if (pin && pin === pinconfirm) user.pin = await bcrypt.hash(pin, 1);
-
if (twofa && !user.authyId && user.phoneVerified) {
try {
let r = await authy.registerUser({ countryCode: "CA", email, phone });
@@ -244,6 +245,8 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
user.username = userID;
user.name = (await axios.get(`${fb}/me?access_token=${accessToken}`)).data.name;
user.address = await bc.getNewAddress("", "bech32");
+ user.confidential = await liquid.getNewAddress();
+ user.liquid = (await liquid.getAddressInfo(user.confidential)).unconfidential;
user.password = await bcrypt.hash(accessToken, 1);
user.balance = 0;
user.pending = 0;