aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2020-04-28 22:09:22 -0700
committerAdam Soltys <[email protected]>2020-04-28 22:33:02 -0700
commit63c18105e6c66b3b4698c398f356bef1b496816f (patch)
treee7ee85e7c3502ed81954448a76be028143990948
parent994dd93f6c45c590ae59a699cbf425d96518da1e (diff)
downloadcoinos-server-63c18105e6c66b3b4698c398f356bef1b496816f.tar.gz
coinos-server-63c18105e6c66b3b4698c398f356bef1b496816f.zip
include account in emitted payments objects
-rw-r--r--lib/utils.js12
-rw-r--r--routes/bitcoin/receive.js11
-rw-r--r--routes/bitcoin/send.js82
-rw-r--r--routes/lightning/receive.js4
-rw-r--r--routes/lightning/send.js8
-rw-r--r--routes/liquid/fee.js2
-rw-r--r--routes/liquid/receive.js21
-rw-r--r--routes/liquid/send.js105
-rw-r--r--routes/users.js8
9 files changed, 143 insertions, 110 deletions
diff --git a/lib/utils.js b/lib/utils.js
index 98409efc..a861f8b7 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -30,7 +30,11 @@ getUser = async username => {
}
}
},
- limit: 12
+ limit: 12,
+ include: {
+ model: db.Account,
+ as: "account"
+ }
});
return user;
@@ -65,7 +69,11 @@ getUserById = async id => {
}
}
},
- limit: 12
+ limit: 12,
+ include: {
+ model: db.Account,
+ as: "account"
+ }
});
return user;
diff --git a/routes/bitcoin/receive.js b/routes/bitcoin/receive.js
index acc80b09..deded625 100644
--- a/routes/bitcoin/receive.js
+++ b/routes/bitcoin/receive.js
@@ -70,12 +70,10 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
user.address = await bc.getNewAddress("", "bech32");
await user.save();
- user = await getUser(user.username);
- emit(user.username, "user", user);
addresses[user.address] = user.username;
- const payment = await db.Payment.create({
+ let payment = await db.Payment.create({
account_id: account.id,
user_id: user.id,
hash,
@@ -88,9 +86,13 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
address,
network: "BTC"
});
+ payment = payment.get({ plain: true });
+ payment.account = account.get({ plain: true });
- l.info("bitcoin detected", user.username, o.value);
+ user = await getUser(user.username);
emit(user.username, "payment", payment);
+ emit(user.username, "user", user);
+ l.info("bitcoin detected", user.username, o.value);
}
})
);
@@ -135,6 +137,7 @@ setInterval(async () => {
let user = await getUserById(p.user_id);
emit(user.username, "user", user);
+ emit(user.username, "payment", p);
l.info("bitcoin confirmed", user.username, p.amount, p.tip);
delete queue[hash];
} else {
diff --git a/routes/bitcoin/send.js b/routes/bitcoin/send.js
index e7cba943..42027f71 100644
--- a/routes/bitcoin/send.js
+++ b/routes/bitcoin/send.js
@@ -8,10 +8,9 @@ module.exports = async (req, res) => {
let fee = toSats(tx.fee);
- const isChange = async address =>
- (await bc.getAddressInfo(address)).ismine && (
- !Object.keys(addresses).includes(address) ||
- address === user.address);
+ const isChange = async address =>
+ (await bc.getAddressInfo(address)).ismine &&
+ (!Object.keys(addresses).includes(address) || address === user.address);
tx = await bc.decodeRawTransaction(hex);
@@ -21,40 +20,55 @@ module.exports = async (req, res) => {
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]))) {
+ if (await isChange(o.scriptPubKey.addresses[0])) {
change += toSats(o.value);
}
}
- }
+ }
- total = (total - change) + fee;
+ total = total - change + fee;
let amount = total - fee;
- l.info("attempting bitcoin payment", user.username, amount, fee);
+ l.info("attempting bitcoin payment", user.username, total, change, amount, fee);
+ let account, params;
try {
await db.transaction(async transaction => {
- let { balance } = await db.User.findOne({
+ account = await db.Account.findOne({
where: {
- username: user.username
+ user_id: user.id,
+ asset: config.liquid.btcasset
},
lock: transaction.LOCK.UPDATE,
transaction
});
- if (amount !== balance && total > balance) {
+ if (total > account.balance) {
l.error("amount exceeds balance", amount, fee, balance);
throw new Error("insufficient funds");
}
- user.balance -= total;
- await user.save({ transaction });
+ account.balance -= total;
+ await account.save({ transaction });
+
+ params = {
+ amount: -total,
+ fee,
+ account_id: account.id,
+ user_id: user.id,
+ rate: app.get("rates")[user.currency],
+ currency: user.currency,
+ address,
+ confirmed: true,
+ received: false,
+ network: "BTC"
+ };
});
} catch (e) {
- l.warn("insufficient funds for bitcoin payment", user.username);
- return res.status(500).send("Not enough satoshis");
+ l.error("problem creating bitcoin payment", user.username, e.message);
+ return res.status(500).send(e.message);
}
try {
@@ -62,37 +76,17 @@ module.exports = async (req, res) => {
await bc.walletPassphrase(config.bitcoin.walletpass, 300);
hex = (await bc.signRawTransactionWithWallet(hex)).hex;
- let txid = await bc.sendRawTransaction(hex);
+ params.hash = await bc.sendRawTransaction(hex);
- await db.transaction(async transaction => {
- await user.save({ transaction });
- user = await getUser(user.username);
+ let payment = await db.Payment.create(params);
- const payment = await db.Payment.create(
- {
- amount: -total,
- fee,
- account_id: user.account.id,
- user_id: user.id,
- hash: txid,
- rate: app.get("rates")[user.currency],
- currency: user.currency,
- address,
- confirmed: true,
- received: false,
- network: "BTC"
- },
- { transaction }
- );
-
- user = await getUser(user.username);
- emit(user.username, "payment", payment);
- emit(user.username, "user", user);
+ user = await getUser(user.username);
+ emit(user.username, "user", user);
- res.send(payment);
-
- l.info("sent bitcoin", user.username, total);
- });
+ payment = payment.get({ plain: true });
+ payment.account = account.get({ plain: true });
+ res.send(payment);
+ l.info("sent bitcoin", user.username, total);
} catch (e) {
l.error("error sending bitcoin", e.message);
return res.status(500).send(e.message);
diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js
index 0805c878..97fe07dc 100644
--- a/routes/lightning/receive.js
+++ b/routes/lightning/receive.js
@@ -21,7 +21,7 @@ const handlePayment = async msg => {
}
});
- const payment = await db.Payment.create({
+ let payment = await db.Payment.create({
account_id: account.id,
user_id,
hash,
@@ -44,6 +44,8 @@ const handlePayment = async msg => {
let user = await getUserById(user_id)
+ payment = payment.get({ plain: true });
+ payment.account = account.get({ plain: true });
emit(user.username, "payment", payment);
emit(user.username, "user", user);
diff --git a/routes/lightning/send.js b/routes/lightning/send.js
index 02149aa8..6f21cc9b 100644
--- a/routes/lightning/send.js
+++ b/routes/lightning/send.js
@@ -67,7 +67,7 @@ module.exports = async (req, res) => {
account.balance -= total - payreq.satoshis;
await account.save()
- const payment = await db.Payment.create({
+ let payment = await db.Payment.create({
amount: -total,
account_id: account.id,
user_id: user.id,
@@ -78,11 +78,13 @@ module.exports = async (req, res) => {
network: "LNBTC"
});
+ payment = payment.get({ plain: true });
+ payment.account = account.get({ plain: true });
+
seen.push(m.payment_preimage);
l.info("sent lightning", user.username, -payment.amount, m);
user = await getUser(user.username);
- emit(user.username, "payment", payment);
emit(user.username, "user", user);
if (payreq.payeeNodeKey === config.lnb.id) {
@@ -99,7 +101,7 @@ module.exports = async (req, res) => {
seen.push(hash);
res.send(payment);
} catch (e) {
- l.info("error sending lightning", e);
+ l.info("error sending lightning", e.message);
return res.status(500).send(e);
}
};
diff --git a/routes/liquid/fee.js b/routes/liquid/fee.js
index 7a53a9b5..56ec7aa1 100644
--- a/routes/liquid/fee.js
+++ b/routes/liquid/fee.js
@@ -34,6 +34,8 @@ module.exports = async (req, res) => {
decoded = await lq.decodeRawTransaction(signed.hex);
feeRate = Math.round((tx.fee * SATS * 1000) / decoded.vsize);
+ l.info("estimated", asset);
+
res.send({ feeRate, tx });
} catch (e) {
l.error("error estimating liquid fee", e);
diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js
index 858cc0ed..fd280eb9 100644
--- a/routes/liquid/receive.js
+++ b/routes/liquid/receive.js
@@ -2,7 +2,7 @@ const axios = require("axios");
const reverse = require("buffer-reverse");
const zmq = require("zeromq");
const { Op } = require("sequelize");
-const bitcoin = require("elementsjs-lib");
+const elements = require("elementsjs-lib");
const zmqRawBlock = zmq.socket("sub");
zmqRawBlock.connect(config.liquid.zmqrawblock);
@@ -42,7 +42,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
asset
};
- const account = await db.Account.findOne({
+ let account = await db.Account.findOne({
where: params
});
@@ -51,7 +51,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
await account.save();
} else {
let name = asset.substr(0, 6);
- let ticker = asset.substr(0, 3);
+ let ticker = asset.substr(0, 3).toUpperCase();
let precision = 8;
const assets = await axios.get("https://assets.blockstream.info/");
@@ -72,13 +72,9 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
)).unconfidential;
await user.save();
- user = await getUser(user.username);
- emit(user.username, "user", user);
addresses[user.liquid] = user.username;
- l.info("account", account.id);
-
let invoice;
if (asset === config.liquid.btcasset) {
invoice = await db.Invoice.findOne({
@@ -94,7 +90,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
const rate = invoice ? invoice.rate : app.get("rates")[user.currency];
const tip = invoice ? invoice.tip : null;
- const payment = await db.Payment.create({
+ let payment = await db.Payment.create({
account_id: account.id,
user_id: user.id,
hash: blinded.txid,
@@ -109,9 +105,13 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
});
payments.push(blinded.txid);
+ payment = payment.get({ plain: true });
+ payment.account = account.get({ plain: true });
- l.info("liquid detected", user.username, asset, value);
+ user = await getUser(user.username);
emit(user.username, "payment", payment);
+ emit(user.username, "user", user);
+ l.info("liquid detected", user.username, asset, value);
}
})
);
@@ -126,7 +126,7 @@ zmqRawBlock.on("message", async (topic, message, sequence) => {
const hashes = payments.map(p => p.hash);
- const block = bitcoin.Block.fromHex(message.toString("hex"), true);
+ const block = elements.Block.fromHex(message.toString("hex"), true);
const hash = await lq.getBlockHash(block.height);
const json = await lq.getBlock(hash, 2);
@@ -158,6 +158,7 @@ setInterval(async () => {
let user = await getUserById(p.user_id);
emit(user.username, "user", user);
+ emit(user.username, "payment", p);
l.info("liquid confirmed", user.username, p.asset, p.amount, p.tip);
delete queue[hash];
diff --git a/routes/liquid/send.js b/routes/liquid/send.js
index 461b0c0a..4d8b8d4c 100644
--- a/routes/liquid/send.js
+++ b/routes/liquid/send.js
@@ -25,27 +25,32 @@ module.exports = async (req, res) => {
scriptPubKey: { type, addresses }
} = tx.vout[i];
- if (!totals[asset]) totals[asset] = change[asset] = 0;
- totals[asset] += toSats(value);
if (type === "fee") fee = toSats(value);
+ else {
+ if (!totals[asset]) totals[asset] = change[asset] = 0;
+ totals[asset] += toSats(value);
- if (addresses) {
- if (await isChange(addresses[0])) {
- change[asset] += toSats(value);
+ if (addresses) {
+ if (await isChange(addresses[0])) {
+ change[asset] += toSats(value);
+ }
}
}
}
- let assets = Object.keys(totals);
- for (let i = 0; i < assets.length; i++) {
- let asset = assets[i];
- let total = totals[asset];
- if (change[asset]) total -= change[asset];
+ const assets = Object.keys(totals);
+ const payments = [];
+
+ try {
+ await db.transaction(async transaction => {
+ for (let i = 0; i < assets.length; i++) {
+ let asset = assets[i];
+ let total = totals[asset];
+ if (change[asset]) total -= change[asset];
+ if (asset === config.liquid.btcasset) total += fee;
- l.info("attempting liquid payment", user.username, asset, total, fee);
+ l.info("creating liquid payment", user.username, asset, total, fee);
- try {
- await db.transaction(async transaction => {
let account = await db.Account.findOne({
where: {
user_id: user.id,
@@ -67,41 +72,53 @@ module.exports = async (req, res) => {
account.balance -= total;
await account.save({ transaction });
- try {
- if (config.liquid.walletpass)
- await lq.walletPassphrase(config.liquid.walletpass, 300);
+ let payment = {
+ amount: -total,
+ account_id: account.id,
+ fee,
+ user_id: user.id,
+ rate: app.get("rates")[user.currency],
+ currency: user.currency,
+ address,
+ confirmed: true,
+ received: false,
+ network: "LBTC"
+ };
- hex = await lq.blindRawTransaction(hex);
- rawtx = (await lq.signRawTransactionWithWallet(hex)).hex;
- let txid = await lq.sendRawTransaction(rawtx);
+ payment.account = account;
+ payments.push(payment);
+ }
+ });
+ } catch (e) {
+ l.error("problem creating liquid payment", user.username, e.message);
+ return res.status(500).send(e.message);
+ }
- const payment = await db.Payment.create({
- amount: -total,
- account_id: account.id,
- fee,
- user_id: user.id,
- hash: txid,
- rate: app.get("rates")[user.currency],
- currency: user.currency,
- address,
- confirmed: true,
- received: false,
- network: "LBTC"
- }, { transaction });
+ try {
+ if (config.liquid.walletpass)
+ await lq.walletPassphrase(config.liquid.walletpass, 300);
- payment.account = account;
+ hex = await lq.blindRawTransaction(hex);
+ rawtx = (await lq.signRawTransactionWithWallet(hex)).hex;
+ let txid = await lq.sendRawTransaction(rawtx);
- user = await getUser(user.username);
- emit(user.username, "user", user);
- res.send(payment);
- } catch (e) {
- l.error("liquid send failed", e);
- return res.status(500).send(e.message);
- }
- });
- } catch (e) {
- l.warn("insufficient funds for liquid payment", user.username, e.message);
- return res.status(500).send("Not enough satoshis");
+ let main;
+ for (let i = 0; i < assets.length; i++) {
+ p = payments[i];
+ let { account } = p;
+ p.hash = txid;
+ p = await db.Payment.create(p);
+ if (account.ticker !== "BTC" || !main) {
+ main = p.get({ plain: true });
+ main.account = account.get({ plain: true });
+ }
}
+
+ user = await getUser(user.username);
+ emit(user.username, "user", user);
+ res.send(main);
+ } catch (e) {
+ l.error("problem sending liquid", user.username, e.message);
+ return res.status(500).send(e.message);
}
};
diff --git a/routes/users.js b/routes/users.js
index d77cd8a0..9e2700b0 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -124,6 +124,9 @@ app.post("/register", async (req, res) => {
asset: config.liquid.btcasset,
balance: 0,
pending: 0,
+ name: 'Bitcoin',
+ ticker: 'BTC',
+ precision: 8,
});
user.accounts = [account];
@@ -131,9 +134,10 @@ app.post("/register", async (req, res) => {
user.account_id = account.id;
await user.save();
-
- l.info("new user", user.username);
+ user = await getUser(user.username);
res.send(pick(user, ...whitelist));
+ emit(user.username, "user", user);
+ l.info("new user", user.username);
});
app.post("/disable2fa", auth, twofa, async (req, res) => {