aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-09-02 22:12:24 -0700
committerAdam Soltys <[email protected]>2022-09-02 22:12:24 -0700
commit13352f9b30eed52d2e7d0970d3cbd76f401d6de0 (patch)
treee745685b2d7373ad391431323b0bdf5ff373b55a
parentd1cc66d1a02b75f90fbf0c05910777c76228259a (diff)
downloadcoinos-server-13352f9b30eed52d2e7d0970d3cbd76f401d6de0.tar.gz
coinos-server-13352f9b30eed52d2e7d0970d3cbd76f401d6de0.zip
es6 migration
-rw-r--r--index.js86
-rw-r--r--lib/account.js2
-rw-r--r--lib/binance.js17
-rw-r--r--lib/mail.js2
-rw-r--r--lib/passport.js2
-rw-r--r--lib/rates.js5
-rw-r--r--lib/send.js6
-rw-r--r--lib/sockets.js47
-rw-r--r--lib/store.js34
-rw-r--r--lib/sync.js15
-rw-r--r--lib/wretch.js3
-rw-r--r--routes/admin.js2
-rw-r--r--routes/assets.js45
-rw-r--r--routes/bitcoin/broadcast.js4
-rw-r--r--routes/bitcoin/receive.js8
-rw-r--r--routes/bitcoin/send.js11
-rw-r--r--routes/info.js1
-rw-r--r--routes/invoices.js9
-rw-r--r--routes/lightning/receive.js6
-rw-r--r--routes/liquid/broadcast.js4
-rw-r--r--routes/liquid/receive.js15
-rw-r--r--routes/liquid/send.js9
-rw-r--r--routes/lnurl.js10
-rw-r--r--routes/payments.js6
-rw-r--r--routes/referrals.js6
-rw-r--r--routes/send.js20
-rw-r--r--routes/swaps.js23
-rw-r--r--routes/users.js1189
28 files changed, 736 insertions, 851 deletions
diff --git a/index.js b/index.js
index 3b742116..10cbddc0 100644
--- a/index.js
+++ b/index.js
@@ -1,67 +1,32 @@
import app from "./app.js";
-import axios from "axios";
-import bodyParser from "body-parser";
-import compression from "compression";
-import cookieParser from "cookie-parser";
-import cors from "cors";
-import express from "express";
-import { Op } from "@sequelize/core";
import persist from "./lib/persist.js";
import config from "./config/index.js";
-import { networks } from "./lib/store.js";
+import store from "./lib/store.js";
+import { l } from "./lib/logging.js";
-// app = express();
-// app.enable("trust proxy");
-// app.use(bodyParser.urlencoded({ extended: true });
-// app.use(bodyParser.json());
+import "./lib/sockets.js";
+// import "./lib/webhooks.js";
+// import "./lib/passport.js";
+// import "./lib/register.js";
+// import "./lib/upload.js";
+// import "./lib/send.js";
+// import "./lib/sync.js";
+// import "./routes/assets.js";
+// import "./routes/info.js";
+// import "./routes/users.js";
+// if (config.bitcoin) store.networks.push("bitcoin");
+// if (config.liquid) store.networks.push("liquid");
+// if (config.lna) store.networks.push("lightning");
//
-// app.use((err, req, res, next) => {
-// const details = {
-// path: req.path,
-// body: req.body,
-// msg: err.message,
-// stack: err.stack
-// };
+// import "./lib/rates.js";
+// import "./lib/notifications.js";
//
-// if (req.user) details.username = req.user.username;
+// if (config.imap) import("./lib/mail.js");
+// if (config.lnurl) import("./routes/lnurl.js");
+// if (config.mailgun) import("./routes/funding.js");
//
-// err("JSON Error: ", JSON.stringify(details));
-// res.status(500);
-// res.set({
-// "Cache-Control": "no-cache"
-// });
-// res.send(err.message);
-// return res.end();
-// });
-// app.use(cookieParser());
-// app.use(cors({ credentials: true, origin: "*" });
-// app.use(compression());
-
-import "./lib/logging.js";
-import "./lib/utils.js";
-import "./lib/sockets.js";
-import "./lib/webhooks.js";
-import "./lib/passport.js";
-import "./lib/register.js";
-import "./lib/upload.js";
-import "./lib/send.js";
-import "./lib/sync.js";
-import "./routes/assets.js";
-import "./routes/info.js";
-import "./routes/users.js";
-if (config.bitcoin) networks.push("bitcoin");
-if (config.liquid) networks.push("liquid");
-if (config.lna) networks.push("lightning");
-
-import "./lib/rates.js";
-import "./lib/notifications.js";
-
-if (config.imap) import("./lib/mail.js");
-if (config.lnurl) import("./routes/lnurl.js");
-if (config.mailgun) import ("./routes/funding.js");
-
-import "./routes/invoices.js";
-import "./routes/payments.js";
+// import "./routes/invoices.js";
+// import "./routes/payments.js";
// import "./routes/swaps.js";
// Scope based Route Handling
@@ -107,13 +72,16 @@ app.post("/email", async (req, res) => {
}
});
-app.listen(process.env.PORT || 3119, "0.0.0.0", function(err, address) {
+app.listen({ port: process.env.PORT || 3119, host: "0.0.0.0" }, function(
+ err,
+ address
+) {
if (err) {
console.log(err);
app.log.error(err);
process.exit(1);
}
- app.log.info(`CoinOS Server listening on ${address}`);
+ l(`CoinOS Server listening on ${address}`);
});
process.on("SIGINT", process.exit);
diff --git a/lib/account.js b/lib/account.js
index c4cda1a4..a1f20dc7 100644
--- a/lib/account.js
+++ b/lib/account.js
@@ -22,7 +22,7 @@ export default async (asset, user, transaction) => {
let ticker = asset.substr(0, 3).toUpperCase();
let precision = 8;
- const assets = app.get("assets");
+ const assets = assets;
if (assets[asset]) {
({ domain, ticker, precision, name } = assets[asset]);
diff --git a/lib/binance.js b/lib/binance.js
index 3e25e277..1dc1facd 100644
--- a/lib/binance.js
+++ b/lib/binance.js
@@ -1,7 +1,7 @@
import app from "../app.js";
import WebSocket from "ws";
import { err } from "./logging.js";
-import { rates } from "./store.js";
+import store from "./store.js";
export default () => {
const binance = new WebSocket(
@@ -12,18 +12,15 @@ export default () => {
try {
let msg = JSON.parse(event.data);
- let fx = app.get("fx");
- if (!fx) return;
- let rates = {};
+ if (!store.fx) return;
- Object.keys(fx).map(symbol => {
- rates[symbol] = msg.c * fx[symbol];
+ Object.keys(store.fx).map(symbol => {
+ store.rates[symbol] = msg.c * store.fx[symbol];
});
- app.set("ask", msg.a);
- app.set("bid", msg.b);
- app.set("last", msg.c);
- app.set("rates", rates);
+ // app.set("ask", msg.a);
+ // app.set("bid", msg.b);
+ last = msg.c;
} catch (e) {
err("binance message error", e.message);
}
diff --git a/lib/mail.js b/lib/mail.js
index d1b67c37..d826b845 100644
--- a/lib/mail.js
+++ b/lib/mail.js
@@ -86,7 +86,7 @@ imap.once("ready", function() {
let { user } = account;
- let rate = rates["CAD"] * 1.02;
+ let rate = store.rates["CAD"] * 1.02;
let amount = Math.round((cad / rate) * 100000000);
await account.increment({ balance: amount }, { transaction });
diff --git a/lib/passport.js b/lib/passport.js
index 5f987014..36057ade 100644
--- a/lib/passport.js
+++ b/lib/passport.js
@@ -9,7 +9,7 @@ import fs from "fs";
import path from "path";
app.register(fastifySecureSession, {
- key: fs.readFileSync(config.jwt)
+ key: config.jwt
});
app.register(fastifyPassport.initialize());
diff --git a/lib/rates.js b/lib/rates.js
index 5f0c3c42..5e24cff0 100644
--- a/lib/rates.js
+++ b/lib/rates.js
@@ -3,6 +3,7 @@ import axios from "axios";
import fs from "fs";
import binanceFactory from "./binance.js";
import { broadcast } from "./sockets.js";
+import store from "./store.js";
const binance = binanceFactory();
@@ -45,7 +46,7 @@ let fetchRates;
}
}
- app.set("fx", fx);
+ store.fx = fx;
setTimeout(fetchRates, 7200000);
})();
@@ -55,7 +56,7 @@ app.get("/rates", async (req, res, next) => {
});
setInterval(() => {
- broadcast("rate", app.get("last"));
+ broadcast("rate", store.last);
}, 1000);
setInterval(() => {
diff --git a/lib/send.js b/lib/send.js
index 15855d55..dbc39325 100644
--- a/lib/send.js
+++ b/lib/send.js
@@ -1,4 +1,4 @@
-import { rates } from "./store.js";
+import store from "./store.js";
import bolt11 from 'bolt11';
import { Op } from '@sequelize/core';
import { computeConversionFee, conversionFeeReceiver } from '../routes/lightning/conversionFee.js';
@@ -175,7 +175,7 @@ export const send = async (amount, memo, hash, user) => {
memo: "Lightning conversion fee",
account_id: receiverAccount.id,
user_id: receiverAccount.user_id,
- rate: rates[receiverAccount.user.currency],
+ rate: store.rates[receiverAccount.user.currency],
currency: receiverAccount.user.currency,
confirmed: true,
received: true,
@@ -194,7 +194,7 @@ export const send = async (amount, memo, hash, user) => {
hash,
memo,
preimage,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
confirmed: true,
network: "lightning",
diff --git a/lib/sockets.js b/lib/sockets.js
index 6ea369c0..de6986b1 100644
--- a/lib/sockets.js
+++ b/lib/sockets.js
@@ -1,7 +1,7 @@
-import { sockets } from "./store.js";
+import store from "./store.js";
import app from "../app.js";
import jwt from "jsonwebtoken";
-import { v4 as uuidv4 } from "uuid";
+import { v4 } from "uuid";
import WebSocket from "ws";
import { differenceInSeconds, subSeconds } from "date-fns";
import fastifyWs from "@fastify/websocket";
@@ -35,18 +35,18 @@ export const emit = (username, type, data) => {
}
}
- if (!sockets[username]) return;
- for (id in sockets[username]) {
- const ws = sockets[username][id];
+ if (!store.sockets[username]) return;
+ for (id in store.sockets[username]) {
+ const ws = store.sockets[username][id];
ws.send(JSON.stringify({ type, data }));
}
};
export const broadcast = (type, data) => {
const sent = [];
- for (const username in sockets) {
- for (const id in sockets[username]) {
- const ws = sockets[username][id];
+ for (const username in store.sockets) {
+ for (const id in store.sockets[username]) {
+ const ws = store.sockets[username][id];
ws.send(JSON.stringify({ type, data }));
sent.push(ws.id);
}
@@ -60,7 +60,7 @@ export const broadcast = (type, data) => {
app.register(fastifyWs);
app.register(async function(app) {
app.get("/ws", { websocket: true }, ({ socket: ws }, req) => {
- const id = uuidv4();
+ const id = v4();
ws.id = id;
ws.beats = 0;
ws.send(JSON.stringify({ type: "connected", data: id }));
@@ -92,17 +92,17 @@ app.register(async function(app) {
const username = jwt.decode(token).username;
if (!username) throw new Error("Invalid JWT token");
- if (!sockets[username]) sockets[username] = {};
- const existing = Object.keys(sockets[username]);
+ if (!store.sockets[username]) store.sockets[username] = {};
+ const existing = Object.keys(store.sockets[username]);
if (existing.length > 4) {
const p = existing.find(sid => sid !== id);
- sockets[username][p].send(JSON.stringify({ type: "logout" }));
+ store.sockets[username][p].send(JSON.stringify({ type: "logout" }));
setTimeout(() => {
- if (sockets[username][p])
- sockets[username][p].close(code, "too many sockets");
+ if (store.sockets[username][p])
+ store.sockets[username][p].close(code, "too many sockets");
}, 5000);
}
- sockets[username][id] = ws;
+ store.sockets[username][id] = ws;
names[id] = username;
let user = await getUser(username);
@@ -187,8 +187,8 @@ app.register(async function(app) {
// if (reason) console.log("closing socket", reason);
try {
const username = names[id];
- if (sockets[username] && sockets[username][id]) {
- delete sockets[username][id];
+ if (store.sockets[username] && store.sockets[username][id]) {
+ delete store.sockets[username][id];
}
if (all[id]) delete all[id];
@@ -199,19 +199,12 @@ app.register(async function(app) {
});
});
-app.listen({ port: 3000 }, err => {
- if (err) {
- fastify.log.error(err);
- process.exit(1);
- }
-});
-
const names = {};
setInterval(() => {
- for (const username in sockets) {
- for (const id in sockets[username]) {
- let ws = sockets[username][id];
+ for (const username in store.sockets) {
+ for (const id in store.sockets[username]) {
+ let ws = store.sockets[username][id];
ws.beats++;
if (ws.beats > 10) ws.close(code, `${username} ${id} lost heartbeat`);
}
diff --git a/lib/store.js b/lib/store.js
index f32ad101..5667474a 100644
--- a/lib/store.js
+++ b/lib/store.js
@@ -1,15 +1,23 @@
import persist from "./persist.js";
-export const addresses = {};
-export const challenge = {};
-export const change = [];
-export const exceptions = [];
-export const issuances = {};
-export const logins = {};
-export const seen = [];
-export const sessions = {};
-export const sockets = {};
-export const unaccounted = [];
-export const networks = [];
-export const convert = persist("data/conversions.json");
-export const fx;
+export default {
+ addresses: {},
+ challenge: {},
+ change: [],
+ exceptions: [],
+ issuances: {},
+ logins: {},
+ seen: [],
+ sessions: {},
+ sockets: {},
+ unaccounted: [],
+ networks: [],
+ convert: persist("data/conversions.json"),
+ rates: {},
+ fx: {},
+ assets: {},
+ bcAddressIndex: 0,
+ lqAddressIndex: 0,
+ last: {},
+ payments: []
+};
diff --git a/lib/sync.js b/lib/sync.js
index 6fcf8a10..f1d28421 100644
--- a/lib/sync.js
+++ b/lib/sync.js
@@ -4,11 +4,12 @@ import { differenceInDays } from "date-fns";
import fs from "fs";
import read from "../lib/read.js";
import { Op } from "@sequelize/core";
-import { addresses, exceptions } from "./store.js";
+import store from "./store.js";
+import { err } from "./logging.js";
const init = async () => {
try {
- read(fs.createReadStream("exceptions"), data => exceptions.push(data));
+ read(fs.createReadStream("exceptions"), data => store.exceptions.push(data));
} catch (e) {
warn("couldn't read exceptions file", e.message);
}
@@ -29,14 +30,14 @@ const init = async () => {
}
})
).map(({ address, user, unconfidential }) => {
- if (address && user) addresses[address] = user.username;
- if (unconfidential && user) addresses[unconfidential] = user.username;
+ if (address && user) store.addresses[address] = user.username;
+ if (unconfidential && user) store.addresses[unconfidential] = user.username;
});
} catch (e) {
console.log(e);
}
- payments = (
+ store.payments = (
await db.Payment.findAll({
attributes: ["hash"]
})
@@ -206,7 +207,7 @@ const sync = async () => {
transactions.map(tx => {
if (
!payments.find(p => p.hash === tx.txid) &&
- !exceptions.includes(tx.txid) &&
+ !store.exceptions.includes(tx.txid) &&
!unaccounted.find(a => a.txid === tx.txid) &&
new Date(tx.blocktime * 1000) >= twoWeeksAgo
) {
@@ -276,7 +277,7 @@ const sync = async () => {
try {
await db.transaction(async transaction => {
l("found pending transaction", user.username, amount, hash);
- payments.push(hash);
+ store.payments.push(hash);
let p = await db.Payment.create(
{
account_id,
diff --git a/lib/wretch.js b/lib/wretch.js
index e4427760..67e28b88 100644
--- a/lib/wretch.js
+++ b/lib/wretch.js
@@ -1,3 +1,4 @@
import wretch from "wretch";
import fetch from 'node-fetch';
-export default wretch().polyfills({ fetch });
+wretch().polyfills({ fetch });
+export default wretch;
diff --git a/routes/admin.js b/routes/admin.js
index bf8a112a..f63c64b3 100644
--- a/routes/admin.js
+++ b/routes/admin.js
@@ -5,8 +5,6 @@ import * as parseInput from '../scripts/apiParse.js';
import Sequelize from '@sequelize/core';
const Op = Sequelize.Op;
-import { v4 as uuidv4 } from 'uuid';
-
/**
* @api {get} /users Retrieve user list
* @apiName getUsers
diff --git a/routes/assets.js b/routes/assets.js
index 451f8b6a..320c2f3b 100644
--- a/routes/assets.js
+++ b/routes/assets.js
@@ -1,4 +1,4 @@
-import { rates } from "../lib/store.js";
+import store from "../lib/store.js";
import app from "../app.js";
import { auth } from "../lib/passport.js";
import axios from 'axios';
@@ -8,10 +8,11 @@ import fs from 'fs';
let fetchAssets;
(fetchAssets = async () => {
try {
- const { data: assets } = await axios.get(
+ const { data } = await axios.get(
"https://assets.blockstream.info/"
);
- app.set("assets", assets);
+
+ store.assets = data;
} catch (e) {
var liquid_assets = require("./../assets.json");
if (liquid_assets) {
@@ -29,30 +30,28 @@ let fetchAssets;
app.get(
"/assets",
async (req, res) => {
- if (app.get("assets")) {
- const assets = app.get("assets");
-
+ if (store.assets) {
const accounts = await db.Account.findAll({
// group: ["asset"]
});
- Object.keys(assets).map(a => {
- assets[a].registered = true;
- if (!assets[a].asset) assets[a].asset = assets[a].asset_id;
+ Object.keys(store.assets).map(a => {
+ store.assets[a].registered = true;
+ if (!store.assets[a].asset) store.assets[a].asset = store.assets[a].asset_id;
if (
- (assets[a].ticker === "BTC" &&
- assets[a].asset !== config.liquid.btcasset) ||
- (assets[a].ticker === "EUR" &&
- assets[a].asset !== config.liquid.eurasset) ||
- (assets[a].ticker === "CAD" &&
- assets[a].asset !== config.liquid.cadasset) ||
- (assets[a].ticker === "USDt" &&
- assets[a].asset !== config.liquid.usdtasset)
+ (store.assets[a].ticker === "BTC" &&
+ store.assets[a].asset !== config.liquid.btcasset) ||
+ (store.assets[a].ticker === "EUR" &&
+ store.assets[a].asset !== config.liquid.eurasset) ||
+ (store.assets[a].ticker === "CAD" &&
+ store.assets[a].asset !== config.liquid.cadasset) ||
+ (store.assets[a].ticker === "USDt" &&
+ store.assets[a].asset !== config.liquid.usdtasset)
)
- delete assets[a];
+ delete store.assets[a];
});
accounts.map(({ asset, name, domain, ticker, precision }) => {
- if (!assets[asset])
- assets[asset] = {
+ if (!store.assets[asset])
+ store.assets[asset] = {
asset,
name,
domain,
@@ -61,7 +60,7 @@ app.get(
};
});
- res.send(assets);
+ res.send(store.assets);
} else {
console.log("error getting blockstream assets");
res.status(500).send("Problem fetching blockstream asset registry data");
@@ -378,7 +377,7 @@ app.post(
let ticker = asset.substr(0, 3).toUpperCase();
let precision = 8;
- const assets = app.get("assets");
+ const assets = assets;
if (assets[asset]) {
({ domain, ticker, precision, name } = assets[asset]);
@@ -409,7 +408,7 @@ app.post(
amount: -amount,
account_id: account.id,
user_id: user.id,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
confirmed: true,
hash: `Loaded Faucet - ${a2.ticker}`,
diff --git a/routes/bitcoin/broadcast.js b/routes/bitcoin/broadcast.js
index 4eb16d3d..185db283 100644
--- a/routes/bitcoin/broadcast.js
+++ b/routes/bitcoin/broadcast.js
@@ -1,4 +1,4 @@
-import { rates } from "../../lib/store.js";
+import store from "../../lib/store.js";
export default async (req, res) => {
try {
const { user } = req;
@@ -21,7 +21,7 @@ export default async (req, res) => {
tip: 0,
account_id: account.id,
user_id: user.id,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
confirmed: true,
received: false,
diff --git a/routes/bitcoin/receive.js b/routes/bitcoin/receive.js
index 1d12bd9b..c5baa76e 100644
--- a/routes/bitcoin/receive.js
+++ b/routes/bitcoin/receive.js
@@ -1,8 +1,8 @@
import { rates } from "../../lib/store.js";
-import { notify } from "../lib/notifications.js";
-import { callWebhook } from "../lib/webhooks.js";
+import { notify } from "../../lib/notifications.js";
+import { callWebhook } from "../../lib/webhooks.js";
import reverse from 'buffer-reverse';
-import zmq from 'zeromq/v5-compat';
+import zmq from 'zeromq/v5-compat.js';
import { Op } from '@sequelize/core';
import { fromBase58 } from 'bip32';
import bitcoin from 'bitcoinjs-lib';
@@ -78,7 +78,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
const currency = invoice ? invoice.currency : user.currency;
const rate = invoice
? invoice.rate
- : rates[user.currency];
+ : store.rates[user.currency];
const tip = invoice ? invoice.tip : 0;
const memo = invoice ? invoice.memo : "";
diff --git a/routes/bitcoin/send.js b/routes/bitcoin/send.js
index 6b991519..5cecde32 100644
--- a/routes/bitcoin/send.js
+++ b/routes/bitcoin/send.js
@@ -1,5 +1,4 @@
-import { rates } from "../../lib/store.js";
-import { addresses } from "../../lib/store.js";
+import store from "../../lib/store.js";
import config from "../../config/index.js";
const btc = config.liquid.btcasset;
import {
@@ -17,7 +16,7 @@ export default async (req, res) => {
const isChange = async ({ address }) =>
(await bc.getAddressInfo(address)).ismine &&
- !Object.keys(addresses).includes(address);
+ !Object.keys(store.addresses).includes(address);
tx = await bc.decodeRawTransaction(hex);
@@ -123,7 +122,7 @@ export default async (req, res) => {
memo: "Bitcoin conversion fee",
account_id: receiverAccount.id,
user_id: receiverAccount.user_id,
- rate: rates[receiverAccount.user.currency],
+ rate: store.rates[receiverAccount.user.currency],
currency: receiverAccount.user.currency,
confirmed: true,
received: true,
@@ -141,7 +140,7 @@ export default async (req, res) => {
memo,
account_id: account.id,
user_id: user.id,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
address,
confirmed: true,
@@ -165,7 +164,7 @@ export default async (req, res) => {
emit(user.username, "payment", payment);
res.send(payment);
- payments.push(params.hash);
+ store.payments.push(params.hash);
l("sent bitcoin", user.username, total);
});
} catch (e) {
diff --git a/routes/info.js b/routes/info.js
index 2da1807c..970cbb2a 100644
--- a/routes/info.js
+++ b/routes/info.js
@@ -15,7 +15,6 @@ app.get("/info", async (req, res, next) => {
const { clientVersion } = config;
const info = {
- fx: app.get("fx"),
nodes: networks,
clientVersion,
};
diff --git a/routes/invoices.js b/routes/invoices.js
index d4a003be..814363b0 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -1,5 +1,4 @@
-import { rates } from "../lib/store.js";
-import { addresses } from "../lib/store.js";
+import store from "../lib/store.js";
import app from "../app.js";
import { optionalAuth } from "../lib/passport.js";
import { Op } from "@sequelize/core";
@@ -52,7 +51,7 @@ app.post("/invoice", optionalAuth, async (req, res, next) => {
}
if (!user) throw new Error("user not provided");
if (!invoice.currency) invoice.currency = user.currency;
- if (!invoice.rate) invoice.rate = rates[invoice.currency];
+ if (!invoice.rate) invoice.rate = store.rates[invoice.currency];
if (invoice.tip > invoice.amount || invoice.tip > 1000000)
throw new Error("tip is too large");
if (invoice.tip < 0 || invoice.amount < 0)
@@ -87,9 +86,9 @@ app.post("/invoice", optionalAuth, async (req, res, next) => {
invoice = exists
? await exists.update(invoice)
: await db.Invoice.create(invoice);
- addresses[invoice.address] = user.username;
+ store.addresses[invoice.address] = user.username;
if (invoice.unconfidential) {
- addresses[invoice.unconfidential] = user.username;
+ store.addresses[invoice.unconfidential] = user.username;
if (blindkey) await lq.importBlindingKey(invoice.address, blindkey);
}
diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js
index e35d91ec..f013efd7 100644
--- a/routes/lightning/receive.js
+++ b/routes/lightning/receive.js
@@ -1,7 +1,9 @@
+import config from "../../config/index.js";
import { notify } from "../../lib/notifications.js";
import { callWebhook } from "../../lib/webhooks.js";
import { computeConversionFee } from './conversionFee.js';
import { sendLiquid } from "../liquid/send.js";
+import ln from "../../lib/ln.js";
const handlePayment = async (msg) => {
l("incoming lightning payment", msg.value, msg.payment_request, msg.settled);
@@ -147,8 +149,8 @@ if (config.lna.clightning) {
wait(Math.max(...invoices.map((i) => i.pay_index).filter((n) => n)));
};
- poll(lna);
+ poll(ln);
} else {
- const invoices = lna.subscribeInvoices({});
+ const invoices = ln.subscribeInvoices({});
invoices.on("data", handlePayment);
}
diff --git a/routes/liquid/broadcast.js b/routes/liquid/broadcast.js
index 1a44cd2b..5deb846f 100644
--- a/routes/liquid/broadcast.js
+++ b/routes/liquid/broadcast.js
@@ -1,4 +1,4 @@
-import { rates } from "../../lib/store.js";
+import store from "../../lib/store.js";
export default async (req, res) => {
try {
const { user } = req;
@@ -22,7 +22,7 @@ export default async (req, res) => {
tip: 0,
account_id: account.id,
user_id: user.id,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
confirmed: true,
received: false,
diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js
index 380fe4f4..5f61bc73 100644
--- a/routes/liquid/receive.js
+++ b/routes/liquid/receive.js
@@ -1,14 +1,13 @@
-import { rates } from "../../lib/store.js";
-import { addresses } from "../../lib/store.js";
+import store from "../../lib/store.js";
import { sendLiquid } from "./send.js";
import { notify } from "../../lib/notifications.js";
import { callWebhook } from "../../lib/webhooks.js";
import reverse from 'buffer-reverse';
-import zmq from 'zeromq/v5-compat';
+import zmq from 'zeromq/v5-compat.js';
import { Op } from '@sequelize/core';
import { fromBase58 } from 'bip32';
import bitcoin from 'bitcoinjs-lib';
-// import { Block, networks, Transaction } from 'liquidjs-lib';
+import { Block, networks, Transaction } from 'liquidjs-lib';
const network =
networks[
@@ -51,7 +50,7 @@ const getAccount = async (params, transaction) => {
params.seed = nc.seed;
}
- const assets = app.get("assets");
+ const assets = assets;
if (assets[asset]) {
({ domain, ticker, precision, name } = assets[asset]);
@@ -117,11 +116,11 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
const address = o.scriptPubKey.addresses[0];
if (
- Object.keys(addresses).includes(address) &&
+ Object.keys(store.addresses).includes(address) &&
!change.includes(address)
) {
await db.transaction(async transaction => {
- let user = await getUser(addresses[address], transaction);
+ let user = await getUser(store.addresses[address], transaction);
let invoice = await db.Invoice.findOne({
where: {
@@ -172,7 +171,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
const currency = invoice ? invoice.currency : user.currency;
const rate = invoice
? invoice.rate
- : rates[user.currency];
+ : store.rates[user.currency];
const tip = invoice ? invoice.tip : 0;
const memo = invoice ? invoice.memo : "";
diff --git a/routes/liquid/send.js b/routes/liquid/send.js
index 674b93f2..5b4db184 100644
--- a/routes/liquid/send.js
+++ b/routes/liquid/send.js
@@ -1,5 +1,4 @@
-import { rates } from "../../lib/store.js";
-import { addresses } from "../../lib/store.js";
+import store from "../../lib/store.js";
import config from "../../config/index.js";
const btc = config.liquid.btcasset;
const lcad = config.liquid.cadasset;
@@ -25,7 +24,7 @@ export const sendLiquid = async ({ asset, amount, user, address, memo, tx, limit
const isChange = async address =>
(await lq.getAddressInfo(address)).ismine &&
- !Object.keys(addresses).includes(address);
+ !Object.keys(store.addresses).includes(address);
let totals = {};
let change = {};
@@ -184,7 +183,7 @@ export const sendLiquid = async ({ asset, amount, user, address, memo, tx, limit
memo: "Liquid conversion fee",
account_id: receiverAccount.id,
user_id: receiverAccount.user_id,
- rate: rates[receiverAccount.user.currency],
+ rate: store.rates[receiverAccount.user.currency],
currency: receiverAccount.user.currency,
confirmed: true,
received: true,
@@ -202,7 +201,7 @@ export const sendLiquid = async ({ asset, amount, user, address, memo, tx, limit
fee,
memo,
user_id: user.id,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
address,
confirmed: true,
diff --git a/routes/lnurl.js b/routes/lnurl.js
index 82420734..3e5b0fd8 100644
--- a/routes/lnurl.js
+++ b/routes/lnurl.js
@@ -1,4 +1,4 @@
-import { rates } from "../lib/store.js";
+import store from "../lib/store.js";
import app from "../app.js";
import config from "../config/index.js";
import axios from "axios";
@@ -87,7 +87,7 @@ app.post("/withdraw", auth, async (req, res, next) => {
await db.Invoice.create({
user_id: user.id,
text: pr,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
amount: value,
tip: 0,
@@ -271,7 +271,7 @@ lnurlServer.on("payRequest:action:processed", async function(event) {
let i = await db.Invoice.create({
user_id: recipient.id,
text: invoice,
- rate: rates[recipient.currency],
+ rate: store.rates[recipient.currency],
currency: recipient.currency,
amount: payreq.satoshis,
tip: 0,
@@ -422,7 +422,7 @@ lnurlServer.bindToHook(
memo: "Bitcoin conversion fee",
account_id: receiverAccount.id,
user_id: receiverAccount.user_id,
- rate: rates[receiverAccount.user.currency],
+ rate: store.rates[receiverAccount.user.currency],
currency: receiverAccount.user.currency,
confirmed: true,
received: true,
@@ -439,7 +439,7 @@ lnurlServer.bindToHook(
account_id: account.id,
user_id: user.id,
hash: pr,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
confirmed: true,
network: "lightning",
diff --git a/routes/payments.js b/routes/payments.js
index f947350b..f6e28f18 100644
--- a/routes/payments.js
+++ b/routes/payments.js
@@ -1,3 +1,4 @@
+import store from "../lib/store.js";
import bc from "../lib/bitcoin.js";
import app from "../app.js";
import config from "../config/index.js";
@@ -6,6 +7,7 @@ import fs from "fs";
import { join } from "path";
import { Op } from "@sequelize/core";
import send from "./send.js";
+import { warn } from "../lib/logging.js";
import btcRoutes from "./bitcoin/index.js";
import lnRoutes from "./lightning/index.js";
@@ -71,7 +73,7 @@ if (config.bitcoin) {
const address = await bc.getNewAddress();
const { hdkeypath } = await bc.getAddressInfo(address);
const parts = hdkeypath.split("/");
- app.set("bcAddressIndex", parts[parts.length - 1].replace("'", ""));
+ store.bcAddressIndex = parts[parts.length - 1].replace("'", "");
} catch (e) {
console.error(e);
}
@@ -91,7 +93,7 @@ if (config.liquid) {
const address = await lq.getNewAddress();
const { hdkeypath } = await lq.getAddressInfo(address);
const parts = hdkeypath.split("/");
- app.set("lqAddressIndex", parts[parts.length - 1].slice(0, -1));
+ store.lqAddressIndex = parts[parts.length - 1].slice(0, -1);
} catch (e) {
warn("Problem getting liquid address index", e.message);
}
diff --git a/routes/referrals.js b/routes/referrals.js
index 5711532f..87cef102 100644
--- a/routes/referrals.js
+++ b/routes/referrals.js
@@ -1,7 +1,7 @@
import express from 'express';
var router = express.Router();
-import { v4 as uuidv4 } from 'uuid';
+import { v4 } from 'uuid';
router.get('/', function(req, res, next) {
res.send('list of referrals...');
@@ -44,7 +44,7 @@ router.post(
auth,
async (req, res) => {
const {sponsor_id, expiry} = req.body
- var token = uuidv4()
+ var token = v4()
var ref = await knex.table('referrals')
.insert({
@@ -84,7 +84,7 @@ router.get(
auth,
async (req, res) => {
const {sponsor_id, expiry} = req.query
- var token = uuidv4()
+ var token = v4()
var ref = await knex.table('referrals')
.insert({
diff --git a/routes/send.js b/routes/send.js
index b0f8accb..778d3534 100644
--- a/routes/send.js
+++ b/routes/send.js
@@ -1,7 +1,7 @@
-import { rates } from "../lib/store.js";
+import store from "../lib/store.js";
import { callWebhook } from "../lib/webhooks.js";
import axios from "axios";
-import { v4 as uuidv4 } from "uuid";
+import { v4 } from "uuid";
import { notify } from "../lib/notifications.js";
import { sendLiquid } from "./liquid/send.js";
@@ -61,10 +61,10 @@ export default async (req, res, next) => {
account_id: account.id,
memo,
user_id: user.id,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
currency: user.currency,
confirmed: true,
- hash: `#${uuidv4().substr(0, 6)} ${
+ hash: `#${v4().substr(0, 6)} ${
username ? `Payment to ${username}` : "Internal Transfer"
}`,
network: "COINOS"
@@ -72,7 +72,7 @@ export default async (req, res, next) => {
if (!username) {
l("creating redeemable payment");
- params.redeemcode = uuidv4();
+ params.redeemcode = v4();
params.hash = `${req.get("origin")}/redeem/${params.redeemcode}`;
}
@@ -132,10 +132,8 @@ export default async (req, res, next) => {
let ticker = asset.substr(0, 3).toUpperCase();
let precision = 8;
- const assets = app.get("assets");
-
- if (assets[asset]) {
- ({ domain, ticker, precision, name } = assets[asset]);
+ if (store.assets[asset]) {
+ ({ domain, ticker, precision, name } = store.assets[asset]);
} else {
const existing = await db.Account.findOne({
where: {
@@ -166,10 +164,10 @@ export default async (req, res, next) => {
amount,
account_id: a2.id,
user_id: recipient.id,
- rate: rates[recipient.currency] * spread,
+ rate: store.rates[recipient.currency] * spread,
currency: recipient.currency,
confirmed: true,
- hash: `#${uuidv4().substr(0, 6)} Payment from ${user.username}`,
+ hash: `#${v4().substr(0, 6)} Payment from ${user.username}`,
memo,
network: "COINOS",
received: true
diff --git a/routes/swaps.js b/routes/swaps.js
index f1bdcbc8..89cc2188 100644
--- a/routes/swaps.js
+++ b/routes/swaps.js
@@ -4,7 +4,6 @@ import crypto from 'crypto';
import fs from 'fs';
import getAccount from '../lib/account.js';
import { Op, col } from '@sequelize/core';
-import { v4 as uuidv4 } from 'uuid';
import { rates } from "../lib/store.js";
const shallow = a => {
@@ -65,7 +64,7 @@ const swap = async (user, { a1, a2, v1, v2 }) => {
account_id: a1acc.id,
user_id: user.id,
currency: user.currency,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
confirmed: true,
received: false,
network: "COINOS"
@@ -134,7 +133,7 @@ const swap = async (user, { a1, a2, v1, v2 }) => {
account_id: a1acc.id,
user_id: user.id,
currency: user.currency,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
confirmed: true,
received: true,
network: "COINOS"
@@ -159,7 +158,7 @@ const swap = async (user, { a1, a2, v1, v2 }) => {
account_id: btc.id,
user_id: order.user_id,
currency: order.user.currency,
- rate: rates[order.user.currency],
+ rate: store.rates[order.user.currency],
confirmed: true,
received: true,
network: "COINOS"
@@ -198,7 +197,7 @@ const swap = async (user, { a1, a2, v1, v2 }) => {
account_id: a2acc.id,
user_id: user.id,
currency: user.currency,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
confirmed: true,
received: true,
network: "COINOS"
@@ -219,7 +218,7 @@ const swap = async (user, { a1, a2, v1, v2 }) => {
account_id: order.a2_id,
user_id: order.user_id,
currency: order.user.currency,
- rate: rates[order.user.currency],
+ rate: store.rates[order.user.currency],
confirmed: true,
received: true,
network: "COINOS"
@@ -292,7 +291,7 @@ const cancel = async (user, id) => {
account_id: account.id,
user_id: user.id,
currency: user.currency,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
confirmed: true,
received: true,
network: "COINOS"
@@ -313,7 +312,7 @@ const cancel = async (user, id) => {
account_id: btc.id,
user_id: user.id,
currency: user.currency,
- rate: rates[user.currency],
+ rate: store.rates[user.currency],
confirmed: true,
received: true,
network: "COINOS"
@@ -445,8 +444,8 @@ if (config.maker) {
v2: Math.round(
amount *
SATS *
- (((app.get("ask") * rates[currency]) /
- rates["USD"]) *
+ (((app.get("ask") * store.rates[currency]) /
+ store.rates["USD"]) *
askMultiplier)
)
};
@@ -528,8 +527,8 @@ if (config.maker) {
v1: Math.round(
amount *
SATS *
- ((app.get("bid") * rates[currency]) /
- rates["USD"]) *
+ ((app.get("bid") * store.rates[currency]) /
+ store.rates["USD"]) *
bidMultiplier
),
v2: amount * SATS
diff --git a/routes/users.js b/routes/users.js
index d9ab92d5..2222741f 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -1,20 +1,21 @@
+import app from "../app.js";
+import { auth, optionalAuth } from "../lib/passport.js";
import { getUser } from "../lib/utils.js";
-import axios from 'axios';
-import bcrypt from 'bcrypt';
-import jwt from 'jsonwebtoken';
-import { authenticator } from 'otplib';
-import getAccount from '../lib/account.js';
-import Sequelize from '@sequelize/core';
-import bitcoin from 'bitcoinjs-lib';
+import axios from "axios";
+import bcrypt from "bcrypt";
+import jwt from "jsonwebtoken";
+import { authenticator } from "otplib";
+import getAccount from "../lib/account.js";
+import Sequelize from "@sequelize/core";
+import bitcoin from "bitcoinjs-lib";
// import liquid from 'liquidjs-lib';
-import { fromBase58, fromPrivateKey } from 'bip32';
-import { Mutex } from 'async-mutex';
-import bip32 from 'bip32';
+import { fromBase58, fromPrivateKey } from "bip32";
+import { Mutex } from "async-mutex";
+import bip32 from "bip32";
import whitelist from "../lib/whitelist.js";
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
-/*
const twofa = (req, res, next) => {
let {
user,
@@ -27,293 +28,255 @@ const twofa = (req, res, next) => {
) {
return res.status(401).send("2fa required");
} else next();
-}
+};
-app.get(
- "/me",
- auth,
- async (req, res) => {
- let user = req.user.get({ plain: true });
- let payments = await req.user.getPayments({
- where: {
- account_id: user.account_id
+app.get("/me", auth, async (req, res) => {
+ let user = req.user.get({ plain: true });
+ let payments = await req.user.getPayments({
+ where: {
+ account_id: user.account_id
+ },
+ order: [["id", "DESC"]],
+ limit: 12,
+ include: [
+ {
+ model: db.Account,
+ as: "account"
},
- order: [["id", "DESC"]],
- limit: 12,
- include: [
- {
- model: db.Account,
- as: "account"
- },
- {
- model: db.Payment,
- as: "fee_payment"
- }
- ]
- });
- user.accounts = await req.user.getAccounts();
- user.payments = payments;
- res.send(user);
- })
+ {
+ model: db.Payment,
+ as: "fee_payment"
+ }
+ ]
+ });
+ user.accounts = await req.user.getAccounts();
+ user.payments = payments;
+ res.send(user);
+});
-app.get(
- "/users/:username",
- async (req, res) => {
- const { username } = req.params;
+app.get("/users/:username", async (req, res) => {
+ const { username } = req.params;
- const user = await db.User.findOne({
- attributes: ["username"],
- where: Sequelize.where(
- Sequelize.fn("lower", Sequelize.col("username")),
- username.toLowerCase()
- )
- });
+ const user = await db.User.findOne({
+ attributes: ["username"],
+ where: Sequelize.where(
+ Sequelize.fn("lower", Sequelize.col("username")),
+ username.toLowerCase()
+ )
+ });
- if (user) res.send(user);
- else res.status(500).send("User not found");
- })
+ if (user) res.send(user);
+ else res.status(500).send("User not found");
+});
-app.post(
- "/register",
- async (req, res) => {
- try {
- const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
- const user = await register(req.body.user, ip, false);
- res.send(pick(user, ...whitelist));
- } catch (e) {
- res.status(500).send(e.message);
- }
- })
+app.post("/register", async (req, res) => {
+ try {
+ const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
+ const user = await register(req.body.user, ip, false);
+ res.send(pick(user, ...whitelist));
+ } catch (e) {
+ res.status(500).send(e.message);
+ }
+});
-app.post(
- "/disable2fa",
- auth,
- twofa,
- async (req, res) => {
- let { user } = req;
- user.twofa = false;
- await user.save();
- emit(user.username, "user", user);
- emit(user.username, "otpsecret", user.otpsecret);
- l("disabled 2fa", user.username);
- res.send({});
- })
+app.post("/disable2fa", auth, twofa, async (req, res) => {
+ let { user } = req;
+ user.twofa = false;
+ await user.save();
+ emit(user.username, "user", user);
+ emit(user.username, "otpsecret", user.otpsecret);
+ l("disabled 2fa", user.username);
+ res.send({});
+});
-app.get(
- "/otpsecret",
- auth,
- twofa,
- async (req, res) => {
- let { user } = req;
- emit(user.username, "otpsecret", user.otpsecret);
- res.end();
- })
+app.get("/otpsecret", auth, twofa, async (req, res) => {
+ let { user } = req;
+ emit(user.username, "otpsecret", user.otpsecret);
+ res.end();
+});
-app.post(
- "/2fa",
- auth,
- async (req, res) => {
- let { user } = req;
- try {
- const isValid = authenticator.check(req.body.token, req.user.otpsecret);
- if (isValid) {
- user.twofa = true;
- user.save();
- emit(user.username, "user", req.user);
- } else {
- return res.status(500).send("Invalid token");
- }
- } catch (e) {
- err("error setting up 2fa", e);
+app.post("/2fa", auth, async (req, res) => {
+ let { user } = req;
+ try {
+ const isValid = authenticator.check(req.body.token, req.user.otpsecret);
+ if (isValid) {
+ user.twofa = true;
+ user.save();
+ emit(user.username, "user", req.user);
+ } else {
+ return res.status(500).send("Invalid token");
}
+ } catch (e) {
+ err("error setting up 2fa", e);
+ }
- l("enabled 2fa", user.username);
- res.send({});
- })
-
-app.get(
- "/exists",
- async (req, res) => {
- let exists = await db.User.findOne({
- where: { username: req.query.username }
- });
+ l("enabled 2fa", user.username);
+ res.send({});
+});
- res.send(!!exists);
- })
+app.get("/exists", async (req, res) => {
+ let exists = await db.User.findOne({
+ where: { username: req.query.username }
+ });
-app.post(
- "/user",
- auth,
- async (req, res) => {
- try {
- let { user } = req;
- let {
- address,
- confirm,
- currencies,
- currency,
- email,
- fiat,
- password,
- pin,
- seed,
- tokens,
- twofa,
- unit,
- username
- } = req.body;
+ res.send(!!exists);
+});
- let exists = await db.User.findOne({
- where: { username }
- });
+app.post("/user", auth, async (req, res) => {
+ try {
+ let { user } = req;
+ let {
+ address,
+ confirm,
+ currencies,
+ currency,
+ email,
+ fiat,
+ password,
+ pin,
+ seed,
+ tokens,
+ twofa,
+ unit,
+ username
+ } = req.body;
- let token;
- if (user.username !== username && exists) {
- err("username taken", username, user.username, exists.username);
- return res.status(500).send("Username taken");
- } else {
- sockets[username] = sockets[user.username];
- if (user.username !== username)
- l("changing username", user.username, username);
- user.username = username;
+ let exists = await db.User.findOne({
+ where: { username }
+ });
- token = jwt.sign({ username }, config.jwt);
- res.cookie("token", token, {
- expires: new Date(Date.now() + 432000000)
- });
- }
+ let token;
+ if (user.username !== username && exists) {
+ err("username taken", username, user.username, exists.username);
+ return res.status(500).send("Username taken");
+ } else {
+ sockets[username] = sockets[user.username];
+ if (user.username !== username)
+ l("changing username", user.username, username);
+ user.username = username;
- if (unit) user.unit = unit;
- user.currency = currency;
- user.currencies = currencies;
+ token = jwt.sign({ username }, config.jwt);
+ res.cookie("token", token, {
+ expires: new Date(Date.now() + 432000000)
+ });
+ }
- user.tokens = tokens;
- user.twofa = twofa;
- user.pin = pin;
- user.seed = seed;
- user.fiat = fiat;
- user.email = email;
- user.address = address;
+ if (unit) user.unit = unit;
+ user.currency = currency;
+ user.currencies = currencies;
- if (password && password === confirm) {
- user.password = await bcrypt.hash(password, 1);
- }
+ user.tokens = tokens;
+ user.twofa = twofa;
+ user.pin = pin;
+ user.seed = seed;
+ user.fiat = fiat;
+ user.email = email;
+ user.address = address;
- await user.save();
- emit(user.username, "user", user);
- res.send({ user, token });
- } catch (e) {
- err("error updating user", e.message);
+ if (password && password === confirm) {
+ user.password = await bcrypt.hash(password, 1);
}
- })
-app.post(
- "/keys",
- auth,
- async (req, res) => {
- const { key: hex } = req.body;
- const key = await db.Key.create({
- user_id: req.user.id,
- hex
- });
- emit(req.user.username, "key", key);
- res.send(key);
- })
+ await user.save();
+ emit(user.username, "user", user);
+ res.send({ user, token });
+ } catch (e) {
+ err("error updating user", e.message);
+ }
+});
-app.post(
- "/keys/delete",
- auth,
- async (req, res) => {
- const { hex } = req.body;
- (
- await db.Key.findOne({
- where: {
- user_id: req.user.id,
- hex
- }
- })
- ).destroy();
- })
+app.post("/keys", auth, async (req, res) => {
+ const { key: hex } = req.body;
+ const key = await db.Key.create({
+ user_id: req.user.id,
+ hex
+ });
+ emit(req.user.username, "key", key);
+ res.send(key);
+});
-app.post(
- "/updateSeeds",
- auth,
- async (req, res) => {
- let { user } = req;
- let { seeds } = req.body;
- let keys = Object.keys(seeds);
+app.post("/keys/delete", auth, async (req, res) => {
+ const { hex } = req.body;
+ (
+ await db.Key.findOne({
+ where: {
+ user_id: req.user.id,
+ hex
+ }
+ })
+ ).destroy();
+});
- for (let i = 0; i < keys.length; i++) {
- let id = keys[i];
- let seed = seeds[id];
- await db.Account.update(
- { seed },
- {
- where: { id, user_id: user.id }
- }
- );
+app.post("/updateSeeds", auth, async (req, res) => {
+ let { user } = req;
+ let { seeds } = req.body;
+ let keys = Object.keys(seeds);
- const account = await db.Account.findOne({
- where: { id }
- });
+ for (let i = 0; i < keys.length; i++) {
+ let id = keys[i];
+ let seed = seeds[id];
+ await db.Account.update(
+ { seed },
+ {
+ where: { id, user_id: user.id }
+ }
+ );
- emit(user.username, "account", account);
- }
+ const account = await db.Account.findOne({
+ where: { id }
+ });
- res.end();
- })
+ emit(user.username, "account", account);
+ }
-app.post(
- "/accounts/delete",
- auth,
- async (req, res) => {
- const { id } = req.body;
- const account = await db.Account.findOne({ where: { id } });
- if (account) await account.destroy();
- res.end();
- })
+ res.end();
+});
-app.post(
- "/accounts",
- auth,
- async (req, res) => {
- const {
- name,
- seed,
- pubkey,
- ticker,
- precision,
- path,
- privkey,
- network
- } = req.body;
- const { user } = req;
+app.post("/accounts/delete", auth, async (req, res) => {
+ const { id } = req.body;
+ const account = await db.Account.findOne({ where: { id } });
+ if (account) await account.destroy();
+ res.end();
+});
- let account = await db.Account.create({
- user_id: user.id,
- asset: config.liquid.btcasset,
- balance: 0,
- pending: 0,
- name,
- ticker,
- precision,
- pubkey,
- privkey,
- seed,
- path,
- network
- });
+app.post("/accounts", auth, async (req, res) => {
+ const {
+ name,
+ seed,
+ pubkey,
+ ticker,
+ precision,
+ path,
+ privkey,
+ network
+ } = req.body;
+ const { user } = req;
- emit(user.username, "account", account);
+ let account = await db.Account.create({
+ user_id: user.id,
+ asset: config.liquid.btcasset,
+ balance: 0,
+ pending: 0,
+ name,
+ ticker,
+ precision,
+ pubkey,
+ privkey,
+ seed,
+ path,
+ network
+ });
- if (pubkey) user.index++;
- user.account_id = account.id;
- await user.save();
- user.account = account;
- emit(user.username, "user", user);
+ emit(user.username, "account", account);
+
+ if (pubkey) user.index++;
+ user.account_id = account.id;
+ await user.save();
+ user.account = account;
+ emit(user.username, "user", user);
- res.send(account);
- })
+ res.send(account);
+});
let login = async (req, res) => {
try {
@@ -372,453 +335,413 @@ let login = async (req, res) => {
err("login error", e.message, req.connection.remoteAddress);
res.status(401).end();
}
+};
app.post("/login", login);
app.post("/taboggan", login);
app.post("/doggin", login);
-app.post(
- "/logout",
- optionalAuth,
- async (req, res) => {
- let { subscription } = req.body;
- if (!subscription) return res.end();
+app.post("/logout", optionalAuth, async (req, res) => {
+ let { subscription } = req.body;
+ if (!subscription) return res.end();
- const { username } = req.user;
+ const { username } = req.user;
- if (username) {
- l("logging out", username);
- let i = req.user.subscriptions.findIndex(
- s => JSON.stringify(s) === subscription
- );
- if (i > -1) {
- req.user.subscriptions.splice(i, 1);
- }
- await req.user.save();
- Object.keys(logins).map(
- k => logins[k]["username"] === username && delete logins[k]
- );
+ if (username) {
+ l("logging out", username);
+ let i = req.user.subscriptions.findIndex(
+ s => JSON.stringify(s) === subscription
+ );
+ if (i > -1) {
+ req.user.subscriptions.splice(i, 1);
}
+ await req.user.save();
+ Object.keys(logins).map(
+ k => logins[k]["username"] === username && delete logins[k]
+ );
+ }
- res.end();
- })
+ res.end();
+});
-app.get(
- "/address",
- async (req, res) => {
- let { network, type } = req.query;
- let address, confidentialAddress;
+app.get("/address", async (req, res) => {
+ let { network, type } = req.query;
+ let address, confidentialAddress;
- let paymentType = {
- bech32: "p2wpkh",
- "p2sh-segwit": "p2sh",
- legacy: "p2pkh"
- }[type];
- if (!paymentType) paymentType = "p2wpkh";
+ let paymentType = {
+ bech32: "p2wpkh",
+ "p2sh-segwit": "p2sh",
+ legacy: "p2pkh"
+ }[type];
+ if (!paymentType) paymentType = "p2wpkh";
- let hd, i, p, n;
- const mutex = new Mutex();
- const release = await mutex.acquire();
- try {
- if (network === "bitcoin") {
- if (!config.bitcoin)
- return res.status(500).send("Bitcoin not configured");
+ let hd, i, p, n;
+ const mutex = new Mutex();
+ const release = await mutex.acquire();
+ try {
+ if (network === "bitcoin") {
+ if (!config.bitcoin)
+ return res.status(500).send("Bitcoin not configured");
- address = await bc.getNewAddress("", type);
- app.set("bcAddressIndex", i + 1);
- return res.send({ address });
+ address = await bc.getNewAddress("", type);
+ bcAddressIndex = i + 1;
+ return res.send({ address });
- p = bitcoin.payments;
- n = prod ? bitcoin.networks["bitcoin"] : bitcoin.networks["regtest"];
+ p = bitcoin.payments;
+ n = prod ? bitcoin.networks["bitcoin"] : bitcoin.networks["regtest"];
- i = parseInt(app.get("bcAddressIndex"));
- hd = fromBase58(config.bitcoin.masterkey, n).derivePath(
- `m/0'/0'/${i}'`
- );
+ i = parseInt(app.get("bcAddressIndex"));
+ hd = fromBase58(config.bitcoin.masterkey, n).derivePath(`m/0'/0'/${i}'`);
- // async request to node to bump its internal index but don't use result
- bc.getNewAddress().catch(console.error);
- res.send({ address, confidentialAddress });
+ // async request to node to bump its internal index but don't use result
+ bc.getNewAddress().catch(console.error);
+ res.send({ address, confidentialAddress });
- app.set("bcAddressIndex", i + 1);
- } else if (network === "liquid") {
- p = liquid.payments;
- n =
- liquid.networks[
- config.liquid.network === "mainnet"
- ? "liquid"
- : config.liquid.network
- ];
- paymentType = "p2sh";
+ bcAddressIndex = i + 1;
+ } else if (network === "liquid") {
+ p = liquid.payments;
+ n =
+ liquid.networks[
+ config.liquid.network === "mainnet" ? "liquid" : config.liquid.network
+ ];
+ paymentType = "p2sh";
- // async request to node to bump its internal index but don't use result
- lq.getNewAddress().catch(e =>
- warn("Problem bumping liquid address index", e.message)
- );
+ // async request to node to bump its internal index but don't use result
+ lq.getNewAddress().catch(e =>
+ warn("Problem bumping liquid address index", e.message)
+ );
- i = parseInt(app.get("lqAddressIndex"));
+ i = parseInt(app.get("lqAddressIndex"));
- if (!i) {
- const { hdkeypath } = await lq.getAddressInfo(
- await lq.getNewAddress()
- );
- const parts = hdkeypath.split("/");
- i = parseInt(parts[parts.length - 1].slice(0, -1));
- }
+ if (!i) {
+ const { hdkeypath } = await lq.getAddressInfo(await lq.getNewAddress());
+ const parts = hdkeypath.split("/");
+ i = parseInt(parts[parts.length - 1].slice(0, -1));
+ }
- l("liquid address index", i);
- if (!i) throw new Error("Problem generating address");
+ l("liquid address index", i);
+ if (!i) throw new Error("Problem generating address");
- hd = fromBase58(config.liquid.masterkey, n).derivePath(`m/0'/0'/${i}'`);
- app.set("lqAddressIndex", i + 1);
- } else {
- throw new Error("Unsupported network");
- }
- } finally {
- release();
+ hd = fromBase58(config.liquid.masterkey, n).derivePath(`m/0'/0'/${i}'`);
+ lqAddressIndex = i + 1;
+ } else {
+ throw new Error("Unsupported network");
}
+ } finally {
+ release();
+ }
- if (paymentType !== "p2sh") {
- ({ address } = p[paymentType]({
+ if (paymentType !== "p2sh") {
+ ({ address } = p[paymentType]({
+ pubkey: hd.publicKey,
+ network: n
+ }));
+ } else {
+ if (network === "liquid") {
+ const p2wpkh = p.p2wpkh({
pubkey: hd.publicKey,
network: n
- }));
- } else {
- if (network === "liquid") {
- const p2wpkh = p.p2wpkh({
- pubkey: hd.publicKey,
- network: n
- });
+ });
- const blindkey = fromPrivateKey(
- Buffer.from(config.liquid.blindkey, "hex"),
- hd.chainCode,
- n
- );
+ const blindkey = fromPrivateKey(
+ Buffer.from(config.liquid.blindkey, "hex"),
+ hd.chainCode,
+ n
+ );
- ({ address, confidentialAddress } = p[paymentType]({
- redeem: p2wpkh,
- network: n,
- blindkey: blindkey.publicKey
- }));
+ ({ address, confidentialAddress } = p[paymentType]({
+ redeem: p2wpkh,
+ network: n,
+ blindkey: blindkey.publicKey
+ }));
- lq.importBlindingKey(
- confidentialAddress,
- blindkey.privateKey.toString("hex")
- );
- } else {
- ({ address } = p[paymentType]({
- redeem: p.p2wpkh({
- pubkey: hd.publicKey,
- network: n
- }),
+ lq.importBlindingKey(
+ confidentialAddress,
+ blindkey.privateKey.toString("hex")
+ );
+ } else {
+ ({ address } = p[paymentType]({
+ redeem: p.p2wpkh({
+ pubkey: hd.publicKey,
network: n
- }));
- }
+ }),
+ network: n
+ }));
}
+ }
- res.send({ address, confidentialAddress });
- })
-
-app.post(
- "/account",
- auth,
- async (req, res) => {
- const { user } = req;
- const {
- id,
- name,
- ticker,
- precision,
- domain,
- seed,
- pubkey,
- privkey,
- path,
- hide,
- index
- } = req.body;
+ res.send({ address, confidentialAddress });
+});
- try {
- await db.transaction(async transaction => {
- let account = await db.Account.findOne({
- where: { id, user_id: user.id },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
+app.post("/account", auth, async (req, res) => {
+ const { user } = req;
+ const {
+ id,
+ name,
+ ticker,
+ precision,
+ domain,
+ seed,
+ pubkey,
+ privkey,
+ path,
+ hide,
+ index
+ } = req.body;
- let params = {
- name,
- ticker,
- precision,
- domain,
- seed,
- pubkey,
- path,
- hide,
- index,
- privkey
- };
+ try {
+ await db.transaction(async transaction => {
+ let account = await db.Account.findOne({
+ where: { id, user_id: user.id },
+ lock: transaction.LOCK.UPDATE,
+ transaction
+ });
- if (!account || (account.pubkey && !pubkey)) delete params.pubkey;
+ let params = {
+ name,
+ ticker,
+ precision,
+ domain,
+ seed,
+ pubkey,
+ path,
+ hide,
+ index,
+ privkey
+ };
- await db.Account.update(params, {
- where: { id, user_id: user.id },
- transaction
- });
+ if (!account || (account.pubkey && !pubkey)) delete params.pubkey;
- await account.reload({ transaction });
- emit(user.username, "account", account);
- res.end();
+ await db.Account.update(params, {
+ where: { id, user_id: user.id },
+ transaction
});
- } catch (e) {
- err("problem updating account", e.message);
- return res.status(500).send("There was a problem updating the account");
- }
- })
-app.post(
- "/shiftAccount",
- auth,
- async (req, res) => {
- let { user } = req;
- let { id } = req.body;
+ await account.reload({ transaction });
+ emit(user.username, "account", account);
+ res.end();
+ });
+ } catch (e) {
+ err("problem updating account", e.message);
+ return res.status(500).send("There was a problem updating the account");
+ }
+});
- try {
- const account = await db.Account.findOne({
- where: { id }
- });
+app.post("/shiftAccount", auth, async (req, res) => {
+ let { user } = req;
+ let { id } = req.body;
- if (account.user_id !== user.id)
- return res.status(500).send("Failed to open wallet");
+ try {
+ const account = await db.Account.findOne({
+ where: { id }
+ });
- user.account_id = account.id;
- await user.save();
- let payments = await db.Payment.findAll({
- where: {
- account_id: id
- },
- order: [["id", "DESC"]],
- limit: 12,
- include: {
- model: db.Account,
- as: "account"
- }
- });
+ if (account.user_id !== user.id)
+ return res.status(500).send("Failed to open wallet");
- user = user.get({ plain: true });
- user.payments = payments;
- user.account = account.get({ plain: true });
+ user.account_id = account.id;
+ await user.save();
+ let payments = await db.Payment.findAll({
+ where: {
+ account_id: id
+ },
+ order: [["id", "DESC"]],
+ limit: 12,
+ include: {
+ model: db.Account,
+ as: "account"
+ }
+ });
- emit(user.username, "account", user.account);
- emit(user.username, "user", user);
+ user = user.get({ plain: true });
+ user.payments = payments;
+ user.account = account.get({ plain: true });
- res.send(user);
- } catch (e) {
- err("problem switching account", e.message);
- return res.status(500).send("There was a problem switching accounts");
- }
- })
+ emit(user.username, "account", user.account);
+ emit(user.username, "user", user);
+
+ res.send(user);
+ } catch (e) {
+ err("problem switching account", e.message);
+ return res.status(500).send("There was a problem switching accounts");
+ }
+});
app.get("/vapidPublicKey", function(req, res) {
res.send(config.vapid.publicKey);
});
-app.post(
- "/subscribe",
- auth,
- async function(req, res) {
- let { subscriptions } = req.user;
- let { subscription } = req.body;
- if (!subscriptions) subscriptions = [];
- if (
- !subscriptions.find(
- s => JSON.stringify(s) === JSON.stringify(subscription)
- )
- )
- subscriptions.push(subscription);
- req.user.subscriptions = subscriptions;
- l("subscribing", req.user.username);
- await req.user.save();
- res.sendStatus(201);
- })
+app.post("/subscribe", auth, async function(req, res) {
+ let { subscriptions } = req.user;
+ let { subscription } = req.body;
+ if (!subscriptions) subscriptions = [];
+ if (
+ !subscriptions.find(s => JSON.stringify(s) === JSON.stringify(subscription))
+ )
+ subscriptions.push(subscription);
+ req.user.subscriptions = subscriptions;
+ l("subscribing", req.user.username);
+ await req.user.save();
+ res.sendStatus(201);
+});
let redeeming = {};
-app.post(
- "/redeem",
- optionalAuth,
- async function(req, res) {
- const { redeemcode } = req.body;
- try {
- await db.transaction(async transaction => {
- if (redeeming[redeemcode]) fail("redemption in progress");
- redeeming[redeemcode] = true;
- if (!redeemcode) fail("no code provided");
+app.post("/redeem", optionalAuth, async function(req, res) {
+ const { redeemcode } = req.body;
+ try {
+ await db.transaction(async transaction => {
+ if (redeeming[redeemcode]) fail("redemption in progress");
+ redeeming[redeemcode] = true;
+ if (!redeemcode) fail("no code provided");
- let { user } = req;
+ let { user } = req;
- const source = await db.Payment.findOne({
- where: {
- redeemcode: req.body.redeemcode
- },
- include: {
- model: db.Account,
- as: "account"
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
+ const source = await db.Payment.findOne({
+ where: {
+ redeemcode: req.body.redeemcode
+ },
+ include: {
+ model: db.Account,
+ as: "account"
+ },
+ lock: transaction.LOCK.UPDATE,
+ transaction
+ });
- l("redeeming", redeemcode);
+ l("redeeming", redeemcode);
- if (!source) fail("Invalid code");
- if (source.redeemed) fail("Voucher has already been redeemed");
- let { amount } = source;
- amount = -amount;
+ if (!source) fail("Invalid code");
+ if (source.redeemed) fail("Voucher has already been redeemed");
+ let { amount } = source;
+ amount = -amount;
- if (!user) {
- const ip =
- req.headers["x-forwarded-for"] || req.connection.remoteAddress;
+ if (!user) {
+ const ip =
+ req.headers["x-forwarded-for"] || req.connection.remoteAddress;
- user = await register(
- {
- username: redeemcode.substr(0, 8),
- password: ""
- },
- ip,
- false
- );
+ user = await register(
+ {
+ username: redeemcode.substr(0, 8),
+ password: ""
+ },
+ ip,
+ false
+ );
- let payload = { username: user.username };
- let token = jwt.sign(payload, config.jwt);
- res.cookie("token", token, {
- expires: new Date(Date.now() + 432000000)
- });
+ let payload = { username: user.username };
+ let token = jwt.sign(payload, config.jwt);
+ res.cookie("token", token, {
+ expires: new Date(Date.now() + 432000000)
+ });
- delete redeeming[redeemcode];
- return res.send({ user });
- }
+ delete redeeming[redeemcode];
+ return res.send({ user });
+ }
- let account = await getAccount(source.account.asset, user, transaction);
- let { hash, memo, confirmed, fee, network } = source;
+ let account = await getAccount(source.account.asset, user, transaction);
+ let { hash, memo, confirmed, fee, network } = source;
- source.redeemed = true;
- await source.save({ transaction });
+ source.redeemed = true;
+ await source.save({ transaction });
- let payment = await db.Payment.create(
- {
- amount,
- account_id: account.id,
- user_id: user.id,
- hash: "Voucher " + redeemcode,
- memo,
- rate: rates[user.currency],
- currency: user.currency,
- confirmed,
- network,
- received: true,
- fee
- },
- { transaction }
- );
+ let payment = await db.Payment.create(
+ {
+ amount,
+ account_id: account.id,
+ user_id: user.id,
+ hash: "Voucher " + redeemcode,
+ memo,
+ rate: store.rates[user.currency],
+ currency: user.currency,
+ confirmed,
+ network,
+ received: true,
+ fee
+ },
+ { transaction }
+ );
- await account.increment({ balance: amount }, { transaction });
- await account.reload({ transaction });
+ await account.increment({ balance: amount }, { transaction });
+ await account.reload({ transaction });
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- emit(user.username, "payment", payment);
- emit(user.username, "account", account);
+ payment = payment.get({ plain: true });
+ payment.account = account.get({ plain: true });
+ emit(user.username, "payment", payment);
+ emit(user.username, "account", account);
- res.send({ payment });
- });
- } catch (e) {
- delete redeeming[redeemcode];
- err("problem redeeming", e.message);
- return res.status(500).send("There was a problem redeeming the voucher");
- }
- })
+ res.send({ payment });
+ });
+ } catch (e) {
+ delete redeeming[redeemcode];
+ err("problem redeeming", e.message);
+ return res.status(500).send("There was a problem redeeming the voucher");
+ }
+});
-app.post(
- "/checkRedeemCode",
- auth,
- async function(req, res) {
- const { redeemcode } = req.body;
+app.post("/checkRedeemCode", auth, async function(req, res) {
+ const { redeemcode } = req.body;
- const payment = await db.Payment.findOne({ where: { redeemcode } });
- res.send(payment);
- })
+ const payment = await db.Payment.findOne({ where: { redeemcode } });
+ res.send(payment);
+});
-app.post(
- "/password",
- auth,
- async function(req, res) {
- const { user } = req;
- const { password } = req.body;
+app.post("/password", auth, async function(req, res) {
+ const { user } = req;
+ const { password } = req.body;
- if (!user.password) return res.send(true);
- res.send(await bcrypt.compare(password, user.password));
- })
+ if (!user.password) return res.send(true);
+ res.send(await bcrypt.compare(password, user.password));
+});
-app.get(
- "/isInternal",
- auth,
- async function(req, res) {
- let { user } = req;
- let { address } = req.query;
- if (!address) throw new Error("Address not provided");
+app.get("/isInternal", auth, async function(req, res) {
+ let { user } = req;
+ let { address } = req.query;
+ if (!address) throw new Error("Address not provided");
- let invoice = await db.Invoice.findOne({
- where: { address },
- include: {
- attributes: ["username"],
- model: db.User,
- as: "user"
- }
- });
+ let invoice = await db.Invoice.findOne({
+ where: { address },
+ include: {
+ attributes: ["username"],
+ model: db.User,
+ as: "user"
+ }
+ });
- if (invoice) {
- let info;
- try {
- info = await bc.getAddressInfo(address);
- } catch (e) {
- info = await lq.getAddressInfo(address);
- }
- if (info.ismine) {
- emit(user.username, "to", invoice.user);
- return res.send(true);
- }
+ if (invoice) {
+ let info;
+ try {
+ info = await bc.getAddressInfo(address);
+ } catch (e) {
+ info = await lq.getAddressInfo(address);
+ }
+ if (info.ismine) {
+ emit(user.username, "to", invoice.user);
+ return res.send(true);
}
+ }
- res.send(false);
- })
+ res.send(false);
+});
-app.get(
- "/invoices",
- auth,
- async function(req, res) {
- let invoices = await db.Invoice.findAll({
- where: { user_id: req.user.id }
- });
- res.send(invoices);
+app.get("/invoices", auth, async function(req, res) {
+ let invoices = await db.Invoice.findAll({
+ where: { user_id: req.user.id }
});
+ res.send(invoices);
+});
-app.post(
- "/signMessage",
- auth,
- async function(req, res) {
- let { address, message } = req.body;
+app.post("/signMessage", auth, async function(req, res) {
+ let { address, message } = req.body;
- let invoices = await db.Invoice.findAll({
- where: { user_id: req.user.id }
- });
+ let invoices = await db.Invoice.findAll({
+ where: { user_id: req.user.id }
+ });
- if (invoices.find(i => i.address === address)) {
- if (config.bitcoin.walletpass)
- await bc.walletPassphrase(config.bitcoin.walletpass, 300);
- return res.send(await bc.signMessage(address, message));
- }
+ if (invoices.find(i => i.address === address)) {
+ if (config.bitcoin.walletpass)
+ await bc.walletPassphrase(config.bitcoin.walletpass, 300);
+ return res.send(await bc.signMessage(address, message));
+ }
- res.status(500).send("Address not found for user");
- })
- */
+ res.status(500).send("Address not found for user");
+});