aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sync.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-02-06 16:48:13 -0800
committerAdam Soltys <[email protected]>2023-02-06 16:48:13 -0800
commit9c667055c6367e1b2e239686e72f52995679a47e (patch)
tree0b1d4aee51ec2d4e92d08a9d1404ba4e2ecd462a /lib/sync.js
parent15294844dbc8e73b4d1e92008a7eebc6b86b9ec5 (diff)
parent6f5602d112b68adb7452abf3047f20c32e7725b6 (diff)
downloadcoinos-server-9c667055c6367e1b2e239686e72f52995679a47e.tar.gz
coinos-server-9c667055c6367e1b2e239686e72f52995679a47e.zip
Merge branch 'master' into test
Diffstat (limited to 'lib/sync.js')
-rw-r--r--lib/sync.js384
1 files changed, 0 insertions, 384 deletions
diff --git a/lib/sync.js b/lib/sync.js
deleted file mode 100644
index 42291a94..00000000
--- a/lib/sync.js
+++ /dev/null
@@ -1,384 +0,0 @@
-import config from "$config";
-import { toSats } from "$lib/utils";
-import { emit } from "$lib/sockets";
-import db from "$db/db";
-import app from "$app";
-import { differenceInDays } from "date-fns";
-import fs from "fs";
-import read from "./read";
-import { Op } from "@sequelize/core";
-import store from "./store";
-import { l, err, warn } from "./logging";
-import ln from "./ln";
-import lnd from "./lnd";
-import bc from "./bitcoin";
-import lq from "./liquid";
-
-const init = async () => {
- try {
- read(fs.createReadStream("exceptions"), (data) =>
- store.exceptions.push(data)
- );
- } catch (e) {
- warn("couldn't read exceptions file", e.message);
- }
-
- try {
- const thirtyDays = new Date(new Date().setDate(new Date().getDate() - 30));
-
- (
- await db.Invoice.findAll({
- where: {
- createdAt: {
- [Op.gt]: thirtyDays,
- },
- },
- include: {
- model: db.User,
- as: "user",
- },
- })
- ).map(({ address, user, unconfidential }) => {
- if (address && user) store.addresses[address] = user.username;
- if (unconfidential && user)
- store.addresses[unconfidential] = user.username;
- });
- } catch (e) {
- console.log(e);
- }
-
- store.payments = (
- await db.Payment.findAll({
- attributes: ["hash"],
- })
- ).map((p) => p.hash);
-};
-
-init();
-
-const sync = async () => {
- const twoWeeksAgo = new Date(new Date().setDate(new Date().getDate() - 14));
-
- try {
- const payments = await db.Payment.findAll({
- attributes: ["hash", "confirmed", "preimage"],
- where: { createdAt: { [Op.gt]: twoWeeksAgo } },
- include: [
- {
- model: db.Account,
- as: "account",
- },
- {
- model: db.User,
- as: "user",
- },
- ],
- });
-
- let missed, invoices, recent;
- if (config.lnd) {
- ({ invoices } = await getInvoices({ lnd, limit: 1000 }));
-
- recent = invoices
- .filter(
- (i) =>
- i.is_confirmed &&
- differenceInDays(new Date(), new Date(i.created_at)) < 2
- )
- .map((i) => ({
- amount: parseInt(i.received),
- preimage: i.secret,
- pr: i.request,
- createdAt: new Date(i.created_at),
- }));
- } else {
- ({ invoices } = await ln.listinvoices());
-
- recent = invoices
- .filter(
- (i) =>
- i.status === "paid" &&
- Math.round(Date.now() / 1000) - i.paid_at < 60 * 60 * 48
- )
- .map((i) => ({
- amount: parseInt(Math.round(i.msatoshi_received / 1000)),
- preimage: i.payment_preimage,
- pr: i.bolt11,
- createdAt: new Date(i.paid_at * 1000),
- }));
- }
-
- await db.transaction(async (transaction) => {
- const twoDaysAgo = new Date(new Date().setDate(new Date().getDate() - 2));
- let settled = (
- await db.Payment.findAll(
- {
- where: {
- network: "lightning",
- createdAt: { [Op.gt]: twoDaysAgo },
- },
- attributes: ["preimage"],
- },
- transaction
- )
- ).map((p) => p.preimage);
-
- missed = recent.filter((i) => !settled.includes(i.preimage));
- for (let i = 0; i < missed.length; i++) {
- let { amount, preimage, pr: text, createdAt } = missed[i];
- if (!text || !text.length) continue;
-
- try {
- let invoice = await db.Invoice.findOne({
- where: { text },
- include: {
- model: db.User,
- as: "user",
- },
- transaction,
- });
-
- if (invoice && invoice.user_id) {
- let account = await db.Account.findOne({
- where: {
- user_id: invoice.user_id,
- asset: config.liquid.btcasset,
- pubkey: null,
- },
- transaction,
- });
-
- if (account) {
- let payment = await db.Payment.create({
- account_id: account.id,
- user_id: invoice.user_id,
- hash: text,
- amount,
- currency: invoice.currency,
- preimage,
- rate: invoice.rate,
- received: true,
- confirmed: true,
- network: "lightning",
- tip: invoice.tip,
- invoice_id: invoice.id,
- createdAt,
- updatedAt: createdAt,
- });
-
- await invoice.increment({ received: amount }, { transaction });
- await account.increment({ balance: amount }, { transaction });
-
- l("lightning missing from account", account.id, amount);
- }
- }
- } catch (e) {
- console.log(e);
- err("problem syncing lightning payment", JSON.stringify(missed[i]));
- }
- }
- });
-
- const unconfirmed = await db.Payment.findAll({
- where: {
- confirmed: 0,
- },
- include: [
- {
- model: db.Account,
- as: "account",
- },
- {
- model: db.Invoice,
- as: "invoice",
- },
- {
- model: db.User,
- as: "user",
- },
- ],
- });
-
- let hashes = unconfirmed.map((p) => p.hash);
-
- const transactions = [
- ...(await bc.listTransactions("*", 500)),
- ...(await lq.listTransactions("*", 500)),
- ].filter(
- (tx) =>
- ["send", "receive"].includes(tx.category) &&
- new Date(tx.time * 1000) > twoWeeksAgo
- );
-
- missed = transactions.filter(
- (tx) =>
- tx.category === "receive" &&
- tx.confirmations > 2 &&
- hashes.includes(tx.txid)
- );
-
- for (let i = 0; i < missed.length; i++) {
- let p = unconfirmed.find((p) => p.hash === missed[i].txid);
- p.confirmed = 1;
-
- try {
- await db.transaction(async (transaction) => {
- l("confirming payment", p.id, p.user_id, p.hash, p.address);
- await p.save({ transaction });
-
- if (p.invoice)
- await p.invoice.increment({ received: p.amount }, { transaction });
-
- await p.account.increment({ balance: p.amount }, { transaction });
- await p.account.decrement({ pending: p.amount }, { transaction });
- });
-
- emit(p.user.username, "account", p.account);
- emit(p.user.username, "payment", p);
- } catch (e) {
- err("problem confirming payment", p.id, e.message, e.stack);
- }
- }
-
- store.unaccounted = [];
-
- transactions.map((tx) => {
- if (
- !payments.find((p) => p.hash === tx.txid) &&
- !store.exceptions.includes(tx.txid) &&
- !store.unaccounted.find((a) => a.txid === tx.txid) &&
- new Date(tx.blocktime * 1000) >= twoWeeksAgo
- ) {
- store.unaccounted.push(tx);
- }
- });
-
- if (store.unaccounted.length)
- warn(
- "wallet transactions missing from database",
- store.unaccounted.map((tx) => tx.txid)
- );
-
- let receipts = store.unaccounted
- .filter(
- (tx) =>
- tx.category === "receive" &&
- (!tx.asset || tx.asset === config.liquid.btcasset)
- )
- .map((tx) => tx.address);
-
- invoices = await db.Invoice.findAll({
- where: {
- [Op.or]: {
- address: receipts,
- unconfidential: receipts,
- },
- },
- include: [
- {
- model: db.Account,
- as: "account",
- },
- {
- model: db.User,
- as: "user",
- },
- ],
- });
-
- for (let i = 0; i < invoices.length; i++) {
- let {
- address,
- unconfidential,
- account,
- account_id,
- currency,
- id: invoice_id,
- network,
- rate,
- tip,
- user,
- user_id,
- } = invoices[i];
-
- l("unaccounted", address);
-
- let pending = store.unaccounted.filter(
- (tx) => tx.address === address || tx.address === unconfidential
- );
-
- for (let i = 0; i < pending.length; i++) {
- let { amount, txid: hash } = pending[i];
-
- amount = toSats(amount);
-
- try {
- await db.transaction(async (transaction) => {
- l("found pending transaction", user.username, amount, hash);
- store.payments.push(hash);
- let p = await db.Payment.create(
- {
- account_id,
- address: address || unconfidential,
- amount,
- confirmed: false,
- currency,
- hash,
- invoice_id,
- network,
- rate,
- received: true,
- tip,
- user_id,
- },
- { transaction }
- );
-
- await account.increment({ pending: amount }, { transaction });
-
- emit(user.username, "account", account);
- emit(user.username, "payment", p);
- });
- } catch (e) {
- err("problem updating pending transaction", hash, e.message, e.stack);
- }
- }
- }
- } catch (e) {
- console.log(e);
- err("sync check failed", e.message, e.stack);
- }
-
- setTimeout(sync, 300000);
-};
-
-setTimeout(sync, 5000);
-
-app.get("/conversions", async (req, res) => {
- const transactions = [
- ...(await bc.listTransactions("*", 500)),
- ...(await lq.listTransactions("*", 500)),
- ].filter((tx) => ["receive"].includes(tx.category));
-
- const { addr } = req.query;
- const { invoices } = require("./invoices");
- const persist = require("./persist");
- let conversions = persist("data/conversions.json");
- const payments = (
- await db.Payment.findAll({
- attributes: ["hash"],
- })
- ).map((p) => p.hash);
- res.send(
- Object.keys(conversions)
- .filter((c) => conversions[c].address === addr)
- .filter((c) => {
- return (
- invoices.find(
- (i) => i.payment_request === c && i.state === "SETTLED"
- ) || transactions.find((tx) => tx.txid === c)
- );
- })
- .filter((c) => !payments.includes(c))
- );
-});