aboutsummaryrefslogtreecommitdiffstats
path: root/index.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2019-06-22 10:27:39 -0700
committerAdam Soltys <[email protected]>2019-06-22 10:27:39 -0700
commitcb30426a5053345396b6ec1705fbf239df16f4c3 (patch)
tree66f89b2e0fb309a4026ff7c6cfdc52519850da9d /index.js
parentf0dd12d6007ad49288ddd7f1872cb70d66da0fe3 (diff)
downloadcoinos-server-cb30426a5053345396b6ec1705fbf239df16f4c3.tar.gz
coinos-server-cb30426a5053345396b6ec1705fbf239df16f4c3.zip
use prettier and upstream bolt11
Diffstat (limited to 'index.js')
-rw-r--r--index.js1067
1 files changed, 533 insertions, 534 deletions
diff --git a/index.js b/index.js
index 62e6ce11..58bbf10a 100644
--- a/index.js
+++ b/index.js
@@ -1,195 +1,194 @@
-import { Client } from 'authy-client'
-import axios from 'axios'
-import bcrypt from 'bcrypt'
-import bodyParser from 'body-parser'
-import bolt11 from 'bolt11'
-import compression from 'compression'
-import cookieParser from 'cookie-parser'
-import BitcoinCore from 'bitcoin-core'
-import cors from 'cors'
-import express from 'express'
-import fb from 'fb'
-import graphqlHTTP from 'express-graphql'
-import io from 'socket.io'
-import jwt from 'jsonwebtoken'
-import morgan from 'morgan'
-import mailgun from 'mailgun-js'
-import uuidv4 from 'uuid/v4'
-import reverse from 'buffer-reverse'
-import Sequelize from 'sequelize'
-import zmq from 'zeromq'
+import { Client } from "authy-client";
+import axios from "axios";
+import bcrypt from "bcrypt";
+import bodyParser from "body-parser";
+import bolt11 from "bolt11";
+import compression from "compression";
+import cookieParser from "cookie-parser";
+import BitcoinCore from "bitcoin-core";
+import cors from "cors";
+import express from "express";
+import fb from "fb";
+import graphqlHTTP from "express-graphql";
+import io from "socket.io";
+import jwt from "jsonwebtoken";
+import morgan from "morgan";
+import mailgun from "mailgun-js";
+import uuidv4 from "uuid/v4";
+import reverse from "buffer-reverse";
+import Sequelize from "sequelize";
+import zmq from "zeromq";
-import authyVerify from './authy'
-import config from './config'
-import whitelist from './whitelist'
-import createLnrpc from './lib/createLnrpc'
+import authyVerify from "./authy";
+import config from "./config";
+import whitelist from "./whitelist";
+import createLnrpc from "./lib/createLnrpc";
-const bitcoin = require('bitcoinjs-lib')
-const l = console.log
+const bitcoin = require("bitcoinjs-lib");
+const l = console.log;
/* eslint-disable-next-line */
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
const authy = new Client({ key: config.authy.key });
(async () => {
- debugger;
- const lna = await createLnrpc(config.lna)
- const lnb = await createLnrpc(config.lnb)
- const bc = new BitcoinCore(config.bitcoin)
+ const lna = await createLnrpc(config.lna);
+ const lnb = await createLnrpc(config.lnb);
+ const bc = new BitcoinCore(config.bitcoin);
- const app = express()
- app.enable('trust proxy')
- app.use(bodyParser.urlencoded({ extended: true }))
- app.use(bodyParser.json())
- app.use(cookieParser())
- app.use(cors({ credentials: true, origin: 'http://*:*' }))
- app.use(compression())
- app.use(morgan('combined'))
+ const app = express();
+ app.enable("trust proxy");
+ app.use(bodyParser.urlencoded({ extended: true }));
+ app.use(bodyParser.json());
+ app.use(cookieParser());
+ app.use(cors({ credentials: true, origin: "http://*:*" }));
+ app.use(compression());
+ app.use(morgan("combined"));
- const server = require('http').Server(app)
- const socket = io(server, { origins: '*:*' })
- const db = await require('./db')(lna)
- const passport = require('./passport')(db)
- const auth = passport.authenticate('jwt', { session: false })
- const sids = {}
- const seen = []
+ const server = require("http").Server(app);
+ const socket = io(server, { origins: "*:*" });
+ const db = await require("./db")(lna);
+ const passport = require("./passport")(db);
+ const auth = passport.authenticate("jwt", { session: false });
+ const sids = {};
+ const seen = [];
- app.use(passport.initialize())
+ app.use(passport.initialize());
app.use(
- '/graphql',
+ "/graphql",
auth,
graphqlHTTP({
schema: db.gqlschema,
- graphiql: true,
+ graphiql: true
})
- )
+ );
socket.use((socket, next) => {
try {
- let token = socket.handshake.query.token
- let user = jwt.decode(token).username
- socket.request.user = user
- sids[user] ? sids[user].push(socket.id) : (sids[user] = [socket.id])
- sids[socket.id] = user
+ let token = socket.handshake.query.token;
+ let user = jwt.decode(token).username;
+ socket.request.user = user;
+ sids[user] ? sids[user].push(socket.id) : (sids[user] = [socket.id]);
+ sids[socket.id] = user;
} catch (e) {
- l(e)
+ l(e);
}
- next()
- })
+ next();
+ });
- socket.sockets.on('connect', async socket => {
- socket.emit('connected')
- if (app.get('rates')) socket.emit('rate', app.get('rates').ask)
- socket.on('getuser', async (data, callback) => {
+ socket.sockets.on("connect", async socket => {
+ socket.emit("connected");
+ if (app.get("rates")) socket.emit("rate", app.get("rates").ask);
+ socket.on("getuser", async (data, callback) => {
/* eslint-disable-next-line */
callback(
await db.User.findOne({
where: {
- username: socket.request.user,
- },
+ username: socket.request.user
+ }
})
- )
- })
+ );
+ });
- socket.on('disconnect', s => {
- let user = sids[socket.id]
- sids[user].splice(sids[user].indexOf(socket.id), 1)
- delete sids[socket.id]
- })
- })
+ socket.on("disconnect", s => {
+ let user = sids[socket.id];
+ sids[user].splice(sids[user].indexOf(socket.id), 1);
+ delete sids[socket.id];
+ });
+ });
const emit = (username, msg, data) => {
- if (data.username !== undefined) data = pick(data, ...whitelist)
+ if (data.username !== undefined) data = pick(data, ...whitelist);
- if (!sids[username]) return
+ if (!sids[username]) return;
sids[username].map((sid, i) => {
try {
- socket.to(sid).emit(msg, data)
+ socket.to(sid).emit(msg, data);
} catch (e) {
- sids[username].splice(i, 1)
+ sids[username].splice(i, 1);
}
- })
- }
+ });
+ };
const handlePayment = async msg => {
- if (!msg.settled) return
+ if (!msg.settled) return;
let payment = await db.Payment.findOne({
- include: { model: db.User, as: 'user' },
+ include: { model: db.User, as: "user" },
where: {
- hash: msg.payment_request,
- },
- })
+ hash: msg.payment_request
+ }
+ });
- if (!payment) return
+ if (!payment) return;
- payment.received = true
- payment.user.balance += parseInt(msg.value)
- payment.rate = app.get('rates').ask
+ payment.received = true;
+ payment.user.balance += parseInt(msg.value);
+ payment.rate = app.get("rates").ask;
- await payment.save()
- await payment.user.save()
- payments.push(msg.payment_request)
+ await payment.save();
+ await payment.user.save();
+ payments.push(msg.payment_request);
- emit(payment.user.username, 'invoice', msg)
- emit(payment.user.username, 'user', payment.user)
- }
+ emit(payment.user.username, "invoice", msg);
+ emit(payment.user.username, "user", payment.user);
+ };
- const invoices = lna.subscribeInvoices({})
- invoices.on('data', handlePayment)
+ const invoices = lna.subscribeInvoices({});
+ invoices.on("data", handlePayment);
- const invoicesb = lnb.subscribeInvoices({})
- invoicesb.on('data', handlePayment)
+ const invoicesb = lnb.subscribeInvoices({});
+ invoicesb.on("data", handlePayment);
- const zmqRawBlock = zmq.socket('sub')
- zmqRawBlock.connect(config.bitcoin.zmqrawblock)
- zmqRawBlock.subscribe('rawblock')
+ const zmqRawBlock = zmq.socket("sub");
+ zmqRawBlock.connect(config.bitcoin.zmqrawblock);
+ zmqRawBlock.subscribe("rawblock");
- const zmqRawTx = zmq.socket('sub')
- zmqRawTx.connect(config.bitcoin.zmqrawtx)
- zmqRawTx.subscribe('rawtx')
+ const zmqRawTx = zmq.socket("sub");
+ zmqRawTx.connect(config.bitcoin.zmqrawtx);
+ zmqRawTx.subscribe("rawtx");
- const addresses = {}
+ const addresses = {};
await db.User.findAll({
- attributes: ['username', 'address'],
+ attributes: ["username", "address"]
}).map(u => {
- addresses[u.address] = u.username
- })
+ addresses[u.address] = u.username;
+ });
const payments = (await db.Payment.findAll({
- attributes: ['hash'],
- })).map(p => p.hash)
+ attributes: ["hash"]
+ })).map(p => p.hash);
- zmqRawTx.on('message', async (topic, message, sequence) => {
- message = message.toString('hex')
+ zmqRawTx.on("message", async (topic, message, sequence) => {
+ message = message.toString("hex");
- let tx = bitcoin.Transaction.fromHex(message)
- let hash = reverse(tx.getHash()).toString('hex')
+ let tx = bitcoin.Transaction.fromHex(message);
+ let hash = reverse(tx.getHash()).toString("hex");
- if (payments.includes(hash)) return
+ if (payments.includes(hash)) return;
tx.outs.map(async o => {
try {
- let network = config.bitcoin.network
- if (network === 'mainnet') {
- network = 'bitcoin'
+ let network = config.bitcoin.network;
+ if (network === "mainnet") {
+ network = "bitcoin";
}
let address = bitcoin.address.fromOutputScript(
o.script,
bitcoin.networks[network]
- )
+ );
if (Object.keys(addresses).includes(address)) {
try {
- payments.push(hash)
+ payments.push(hash);
let user = await db.User.findOne({
where: {
- username: addresses[address],
- },
- })
+ username: addresses[address]
+ }
+ });
let invoices = await db.Payment.findAll({
limit: 1,
@@ -197,143 +196,143 @@ const authy = new Client({ key: config.authy.key });
hash: address,
received: null,
amount: {
- [Sequelize.Op.gt]: 0,
- },
+ [Sequelize.Op.gt]: 0
+ }
},
- order: [['createdAt', 'DESC']],
- })
+ order: [["createdAt", "DESC"]]
+ });
- let tip = null
- if (invoices.length) tip = invoices[0].tip
+ let tip = null;
+ if (invoices.length) tip = invoices[0].tip;
- let confirmed = false
+ let confirmed = false;
if (user.friend) {
- user.balance += o.value
- confirmed = true
+ user.balance += o.value;
+ confirmed = true;
} else {
- user.pending += o.value
+ user.pending += o.value;
}
- await user.save()
- emit(user.username, 'user', user)
+ await user.save();
+ emit(user.username, "user", user);
await db.Payment.create({
user_id: user.id,
hash,
amount: o.value,
- currency: 'CAD',
- rate: app.get('rates').ask,
+ currency: "CAD",
+ rate: app.get("rates").ask,
received: true,
tip,
- confirmed,
- })
+ confirmed
+ });
- emit(user.username, 'tx', message)
+ emit(user.username, "tx", message);
} catch (e) {
- l(e)
+ l(e);
}
}
} catch (e) {}
- })
- })
+ });
+ });
- zmqRawBlock.on('message', async (topic, message, sequence) => {
- topic = topic.toString('utf8')
- message = message.toString('hex')
+ zmqRawBlock.on("message", async (topic, message, sequence) => {
+ topic = topic.toString("utf8");
+ message = message.toString("hex");
switch (topic) {
- case 'rawblock': {
- let block = bitcoin.Block.fromHex(message)
- l('block', block.getHash().toString('hex'))
+ case "rawblock": {
+ let block = bitcoin.Block.fromHex(message);
+ l("block", block.getHash().toString("hex"));
await db.Payment.findAll({
- include: { model: db.User, as: 'user' },
- where: { confirmed: false },
+ include: { model: db.User, as: "user" },
+ where: { confirmed: false }
}).map(async p => {
if ((await bc.getRawTransaction(p.hash, true)).confirmations > 0) {
- let user = p.user
- p.confirmed = true
- user.balance += p.amount
- user.pending -= p.amount
- await user.save()
- await p.save()
- emit(user.username, 'user', user)
+ let user = p.user;
+ p.confirmed = true;
+ user.balance += p.amount;
+ user.pending -= p.amount;
+ await user.save();
+ await p.save();
+ emit(user.username, "user", user);
}
- })
+ });
- socket.emit('block', message)
- break
+ socket.emit("block", message);
+ break;
}
}
- })
+ });
- app.post('/register', async (req, res) => {
- let err = m => res.status(500).send(m)
- let user = req.body
- if (!user.username) return err('Username required')
- if (user.password.length < 2) return err('Password too short')
+ app.post("/register", async (req, res) => {
+ let err = m => res.status(500).send(m);
+ let user = req.body;
+ if (!user.username) return err("Username required");
+ if (user.password.length < 2) return err("Password too short");
- let exists = await db.User.count({ where: { username: user.username } })
- if (exists) return err('Username taken')
+ let exists = await db.User.count({ where: { username: user.username } });
+ if (exists) return err("Username taken");
- user.address = (await lna.newAddress({ type: 1 }, lna.meta)).address
- user.password = await bcrypt.hash(user.password, 1)
- user.name = user.username
- addresses[user.address] = user.username
+ user.address = (await lna.newAddress({ type: 1 }, lna.meta)).address;
+ user.password = await bcrypt.hash(user.password, 1);
+ user.name = user.username;
+ addresses[user.address] = user.username;
- await db.User.create(user)
- res.send(pick(user, ...whitelist))
- })
+ await db.User.create(user);
+ res.send(pick(user, ...whitelist));
+ });
const requestEmail = async user => {
- user.emailToken = uuidv4()
- await user.save()
+ user.emailToken = uuidv4();
+ await user.save();
- let mg = mailgun(config.mailgun)
+ let mg = mailgun(config.mailgun);
let msg = {
- from: 'CoinOS <[email protected]>',
+ from: "CoinOS <[email protected]>",
to: user.email,
- subject: 'CoinOS Email Verification',
- html: `Visit <a href="https://coinos.io/verifyEmail/${user.username}/${user.emailToken}">https://coinos.io/verify/${user.username}/${user.emailToken}</a> to verify your email address.`,
- }
+ subject: "CoinOS Email Verification",
+ html: `Visit <a href="https://coinos.io/verifyEmail/${user.username}/${user.emailToken}">https://coinos.io/verify/${user.username}/${user.emailToken}</a> to verify your email address.`
+ };
try {
- mg.messages().send(msg)
+ mg.messages().send(msg);
} catch (e) {
- l(e)
+ l(e);
}
- }
+ };
const requestPhone = async user => {
- user.phoneToken = Math.floor(100000 + Math.random() * 900000)
- await user.save()
- const client = require('twilio')(
+ user.phoneToken = Math.floor(100000 + Math.random() * 900000);
+ await user.save();
+ const client = require("twilio")(
config.twilio.sid,
config.twilio.authToken
- )
+ );
await client.messages.create({
body: user.phoneToken,
from: config.twilio.number,
- to: user.phone,
- })
- }
+ to: user.phone
+ });
+ };
- app.post('/requestEmail', auth, async (req, res) => {
- req.user.email = req.body.email
- await requestEmail(req.user)
- res.end()
- })
+ app.post("/requestEmail", auth, async (req, res) => {
+ req.user.email = req.body.email;
+ await requestEmail(req.user);
+ res.end();
+ });
- app.post('/requestPhone', auth, async (req, res) => {
- req.user.phone = req.body.phone
- await requestPhone(req.user)
- res.end()
- })
+ app.post("/requestPhone", auth, async (req, res) => {
+ req.user.phone = req.body.phone;
+ await requestPhone(req.user);
+ res.end();
+ });
- app.post('/user', auth, async (req, res) => {
- let { user } = req
+ app.post("/user", auth, async (req, res) => {
+ let { user } = req;
let {
email,
phone,
@@ -341,201 +340,201 @@ const authy = new Client({ key: config.authy.key });
pin,
pinconfirm,
password,
- passconfirm,
- } = req.body
+ passconfirm
+ } = req.body;
- if (user.email !== email && require('email-validator').validate(email)) {
- user.email = email
- user.emailVerified = false
- requestEmail(user)
+ if (user.email !== email && require("email-validator").validate(email)) {
+ user.email = email;
+ user.emailVerified = false;
+ requestEmail(user);
}
if (user.phone !== phone) {
- user.phone = phone
- user.phoneVerified = false
- requestPhone(user)
+ user.phone = phone;
+ user.phoneVerified = false;
+ requestPhone(user);
}
- user.email = email
- user.phone = phone
- user.twofa = twofa
+ user.email = email;
+ user.phone = phone;
+ user.twofa = twofa;
- console.log(user.twofa, email, phone)
+ console.log(user.twofa, email, phone);
if (password && password === passconfirm) {
- user.password = await bcrypt.hash(password, 1)
+ user.password = await bcrypt.hash(password, 1);
}
- if (pin && pin === pinconfirm) user.pin = await bcrypt.hash(pin, 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 })
- user.authyId = r.user.id
+ let r = await authy.registerUser({ countryCode: "CA", email, phone });
+ user.authyId = r.user.id;
} catch (e) {
- l(e)
+ l(e);
}
}
- await user.save()
- emit(req.user.username, 'user', req.user)
- res.send(user)
- })
+ await user.save();
+ emit(req.user.username, "user", req.user);
+ res.send(user);
+ });
- app.post('/forgot', async (req, res) => {
- let { user } = req
- let mg = mailgun(config.mailgun)
+ app.post("/forgot", async (req, res) => {
+ let { user } = req;
+ let mg = mailgun(config.mailgun);
let msg = {
- from: 'CoinOS <[email protected]>',
+ from: "CoinOS <[email protected]>",
to: user.email,
- subject: 'CoinOS Password Reset',
- html: `Visit <a href="https://coinos.io/reset/${user.username}/${user.token}">https://coinos.io/reset/${user.username}/${user.token}</a> to reset your password.`,
- }
+ subject: "CoinOS Password Reset",
+ html: `Visit <a href="https://coinos.io/reset/${user.username}/${user.token}">https://coinos.io/reset/${user.username}/${user.token}</a> to reset your password.`
+ };
try {
- mg.messages().send(msg)
+ mg.messages().send(msg);
} catch (e) {
- l(e)
+ l(e);
}
- })
+ });
- app.get('/verifyEmail/:username/:token', auth, async (req, res) => {
+ app.get("/verifyEmail/:username/:token", auth, async (req, res) => {
let user = await db.User.findOne({
where: {
username: req.params.username,
- emailToken: req.params.token,
- },
- })
+ emailToken: req.params.token
+ }
+ });
if (user) {
- user.emailVerified = true
- await user.save()
+ user.emailVerified = true;
+ await user.save();
- emit(user.username, 'user', user)
- emit(user.username, 'emailVerified', true)
+ emit(user.username, "user", user);
+ emit(user.username, "emailVerified", true);
- res.end()
+ res.end();
} else {
- res.status(500).send('invalid token or username')
+ res.status(500).send("invalid token or username");
}
- })
+ });
- app.get('/verifyPhone/:username/:token', auth, async (req, res) => {
+ app.get("/verifyPhone/:username/:token", auth, async (req, res) => {
let user = await db.User.findOne({
where: {
username: req.params.username,
- phoneToken: req.params.token,
- },
- })
+ phoneToken: req.params.token
+ }
+ });
- console.log(user, req.params)
+ console.log(user, req.params);
if (user) {
- user.phoneVerified = true
- await user.save()
+ user.phoneVerified = true;
+ await user.save();
- emit(user.username, 'user', user)
- emit(user.username, 'phoneVerified', true)
- res.end()
+ emit(user.username, "user", user);
+ emit(user.username, "phoneVerified", true);
+ res.end();
} else {
- res.status(500).send('invalid token or username')
+ res.status(500).send("invalid token or username");
}
- })
+ });
- app.post('/openchannel', auth, async (req, res) => {
- let err = m => res.status(500).send(m)
+ app.post("/openchannel", auth, async (req, res) => {
+ let err = m => res.status(500).send(m);
if (req.user.balance < 10000) {
- return err('Need at least 10000 satoshis for channel opening')
+ return err("Need at least 10000 satoshis for channel opening");
}
- let pending = await lna.pendingChannels({}, lna.meta)
+ let pending = await lna.pendingChannels({}, lna.meta);
let busypeers = pending.pending_open_channels.map(
c => c.channel.remote_node_pub
- )
- let peer = lna.channelpeers.find(p => !busypeers.includes(p))
- let sent = false
+ );
+ let peer = lna.channelpeers.find(p => !busypeers.includes(p));
+ let sent = false;
- l('channeling')
+ l("channeling");
if (!peer) {
res
.status(500)
- .send('All peers have pending channel requests, try again later')
- return
+ .send("All peers have pending channel requests, try again later");
+ return;
}
try {
- let amount = Math.min(req.user.balance, 16777216)
+ let amount = Math.min(req.user.balance, 16777216);
let openchannel = async (peer, amount) => {
let channel = await lna.openChannel({
- node_pubkey: new Buffer(peer, 'hex'),
- local_funding_amount: amount,
- })
+ node_pubkey: new Buffer(peer, "hex"),
+ local_funding_amount: amount
+ });
- channel.on('data', async data => {
- if (sent || !data.chan_pending) return
- req.user.balance += amount
- req.user.balance -= amount
- req.user.channel = reverse(data.chan_pending.txid).toString('hex')
- await req.user.save()
- emit(req.user.username, 'user', req.user)
- res.send(data)
- sent = true
- })
+ channel.on("data", async data => {
+ if (sent || !data.chan_pending) return;
+ req.user.balance += amount;
+ req.user.balance -= amount;
+ req.user.channel = reverse(data.chan_pending.txid).toString("hex");
+ await req.user.save();
+ emit(req.user.username, "user", req.user);
+ res.send(data);
+ sent = true;
+ });
- channel.on('error', err => {
- l('channel error', peer, err)
- let msg = err.message
+ channel.on("error", err => {
+ l("channel error", peer, err);
+ let msg = err.message;
if (
- msg.startsWith('Multiple') ||
- msg.startsWith('You gave') ||
- msg.startsWith('peer')
+ msg.startsWith("Multiple") ||
+ msg.startsWith("You gave") ||
+ msg.startsWith("peer")
) {
- busypeers.push(peer)
- peer = lna.channelpeers.find(p => !busypeers.includes(p))
+ busypeers.push(peer);
+ peer = lna.channelpeers.find(p => !busypeers.includes(p));
if (peer) {
- return openchannel(peer, amount)
+ return openchannel(peer, amount);
} else {
return res
.status(500)
.send(
"All peers are busy, couldn't open a channel, wait a few blocks and try again"
- )
+ );
}
}
- if (msg.startsWith('not enough')) {
- msg = 'Server wallet is busy. Wait for a block and try again'
+ if (msg.startsWith("not enough")) {
+ msg = "Server wallet is busy. Wait for a block and try again";
}
- return res.status(500).send(msg)
- })
- }
+ return res.status(500).send(msg);
+ });
+ };
- openchannel(peer, amount)
+ openchannel(peer, amount);
} catch (err) {
- l('rpc error', peer, err)
- return res.status(500).send(err)
+ l("rpc error", peer, err);
+ return res.status(500).send(err);
}
- })
+ });
- app.get('/channels', auth, async (req, res) => {
- return res.send(await lna.listChannels())
- })
+ app.get("/channels", auth, async (req, res) => {
+ return res.send(await lna.listChannels());
+ });
- app.get('/peers', auth, async (req, res) => {
- return res.send(await lna.listPeers())
- })
+ app.get("/peers", auth, async (req, res) => {
+ return res.send(await lna.listPeers());
+ });
- app.post('/sendPayment', auth, async (req, res) => {
- let hash = req.body.payreq
- let payreq = bolt11.decode(hash)
- l('sending lightning', req.user.username, payreq.satoshis)
+ app.post("/sendPayment", auth, async (req, res) => {
+ let hash = req.body.payreq;
+ let payreq = bolt11.decode(hash);
+ l("sending lightning", req.user.username, payreq.satoshis);
if (seen.includes(hash)) {
- return res.status(500).send("Invoice has been paid, can't pay again")
+ return res.status(500).send("Invoice has been paid, can't pay again");
}
try {
@@ -543,56 +542,56 @@ const authy = new Client({ key: config.authy.key });
let { balance } = await db.User.findOne(
{
where: {
- username: req.user.username,
- },
+ username: req.user.username
+ }
},
{ transaction }
- )
+ );
if (balance < payreq.satoshis) {
- throw new Error()
+ throw new Error();
}
- req.user.balance -= payreq.satoshis
- await req.user.save({ transaction })
- })
+ req.user.balance -= payreq.satoshis;
+ await req.user.save({ transaction });
+ });
} catch (e) {
- return res.status(500).send('Not enough satoshis')
+ return res.status(500).send("Not enough satoshis");
}
- const stream = lna.sendPayment(lna.meta, {})
- stream.write({ payment_request: req.body.payreq })
+ const stream = lna.sendPayment(lna.meta, {});
+ stream.write({ payment_request: req.body.payreq });
- stream.on('data', async m => {
+ stream.on("data", async m => {
if (m.payment_error) {
- res.status(500).send(m.payment_error)
+ res.status(500).send(m.payment_error);
} else {
- if (seen.includes(m.payment_preimage)) return
- seen.push(m.payment_preimage)
+ if (seen.includes(m.payment_preimage)) return;
+ seen.push(m.payment_preimage);
- let total = parseInt(m.payment_route.total_amt)
- req.user.balance -= total - payreq.satoshis
+ let total = parseInt(m.payment_route.total_amt);
+ req.user.balance -= total - payreq.satoshis;
await db.transaction(async transaction => {
- await req.user.save({ transaction })
+ await req.user.save({ transaction });
await db.Payment.create(
{
amount: -total,
user_id: req.user.id,
hash,
- rate: app.get('rates').ask,
- currency: 'CAD',
+ rate: app.get("rates").ask,
+ currency: "CAD"
},
{ transaction }
- )
- })
+ );
+ });
- emit(req.user.username, 'user', req.user)
+ emit(req.user.username, "user", req.user);
if (payreq.payeeNodeKey === config.lnb.id) {
- let invoice = await lna.addInvoice({ value: payreq.satoshis })
- let payback = lnb.sendPayment(lnb.meta, {})
+ let invoice = await lna.addInvoice({ value: payreq.satoshis });
+ let payback = lnb.sendPayment(lnb.meta, {});
/* eslint-disable-next-line */
let { payment_request } = invoice;
@@ -600,89 +599,89 @@ const authy = new Client({ key: config.authy.key });
payback.write({ payment_request });
}
- seen.push(hash)
- res.send(m)
+ seen.push(hash);
+ res.send(m);
}
- })
+ });
- stream.on('error', e => {
- let msg = e.message
+ stream.on("error", e => {
+ let msg = e.message;
- res.status(500).send(msg)
- })
- })
+ res.status(500).send(msg);
+ });
+ });
- app.get('/friends', auth, async (req, res) => {
+ app.get("/friends", auth, async (req, res) => {
try {
let friends = (await fb.api(
`/${req.user.username}/friends?access_token=${req.user.fbtoken}`
- )).data
+ )).data;
friends = await Promise.all(
friends.map(async f => {
let pic = (await fb.api(
`/${f.id}/picture?redirect=false&type=small&access_token=${req.user.fbtoken}`
- )).data
- f.pic = pic.url
- return f
+ )).data;
+ f.pic = pic.url;
+ return f;
})
- )
+ );
- res.send(friends)
+ res.send(friends);
} catch (e) {
res
.status(500)
- .send('There was a problem getting your facebook friends: ', e)
+ .send("There was a problem getting your facebook friends: ", e);
}
- })
+ });
- app.post('/payUser', auth, async (req, res) => {
- let { payuser, amount } = req.body
+ app.post("/payUser", auth, async (req, res) => {
+ let { payuser, amount } = req.body;
let user = await db.User.findOne({
where: {
- username: payuser,
- },
- })
+ username: payuser
+ }
+ });
if (!user) {
return res
.status(500)
- .send("Couldn't find the user you're trying to pay")
+ .send("Couldn't find the user you're trying to pay");
}
- let err = m => res.status(500).send(m)
+ let err = m => res.status(500).send(m);
- let invoice
+ let invoice;
try {
- invoice = await lnb.addInvoice({ value: amount })
+ invoice = await lnb.addInvoice({ value: amount });
} catch (e) {
- return err(e.message)
+ return err(e.message);
}
- let hash = invoice.payment_request
+ let hash = invoice.payment_request;
await db.Payment.create({
user_id: user.id,
hash,
amount,
- currency: 'CAD',
- rate: app.get('rates').ask,
- tip: 0,
- })
+ currency: "CAD",
+ rate: app.get("rates").ask,
+ tip: 0
+ });
- req.url = '/sendPayment'
- req.body.payreq = invoice.payment_request
- return app._router.handle(req, res)
- })
+ req.url = "/sendPayment";
+ req.body.payreq = invoice.payment_request;
+ return app._router.handle(req, res);
+ });
- app.post('/sendCoins', auth, async (req, res) => {
- const MINFEE = 3000
+ app.post("/sendCoins", auth, async (req, res) => {
+ const MINFEE = 3000;
- let { address, amount } = req.body
+ let { address, amount } = req.body;
- l('sending coins', req.user.username, amount, address)
+ l("sending coins", req.user.username, amount, address);
if (amount === req.user.balance) {
- amount = req.user.balance - MINFEE
+ amount = req.user.balance - MINFEE;
}
try {
@@ -690,281 +689,281 @@ const authy = new Client({ key: config.authy.key });
let { balance } = await db.User.findOne(
{
where: {
- username: req.user.username,
- },
+ username: req.user.username
+ }
},
{ transaction }
- )
+ );
if (amount > balance) {
- l('amount exceeds balance', amount, balance)
- throw new Error('insufficient funds')
+ l("amount exceeds balance", amount, balance);
+ throw new Error("insufficient funds");
}
- req.user.balance -= parseInt(amount) + 10000
- await req.user.save({ transaction })
- })
+ req.user.balance -= parseInt(amount) + 10000;
+ await req.user.save({ transaction });
+ });
} catch (e) {
- return res.status(500).send('Not enough satoshis')
+ return res.status(500).send("Not enough satoshis");
}
try {
- await bc.walletPassphrase(config.bitcoin.walletpass, 300)
- l('sending transaction')
+ await bc.walletPassphrase(config.bitcoin.walletpass, 300);
+ l("sending transaction");
let txid = await bc.sendToAddress(
address,
(amount / 100000000).toFixed(8)
- )
- l('transaction sent', txid)
- let txhex = await bc.getRawTransaction(txid)
- let tx = bitcoin.Transaction.fromHex(txhex)
+ );
+ l("transaction sent", txid);
+ let txhex = await bc.getRawTransaction(txid);
+ let tx = bitcoin.Transaction.fromHex(txhex);
let inputTotal = await tx.ins.reduce(async (a, input) => {
- let h = await bc.getRawTransaction(reverse(input.hash).toString('hex'))
- return a + bitcoin.Transaction.fromHex(h).outs[input.index].value
- }, 0)
- let outputTotal = tx.outs.reduce((a, b) => a + b.value, 0)
+ let h = await bc.getRawTransaction(reverse(input.hash).toString("hex"));
+ return a + bitcoin.Transaction.fromHex(h).outs[input.index].value;
+ }, 0);
+ let outputTotal = tx.outs.reduce((a, b) => a + b.value, 0);
- let fees = inputTotal - outputTotal
- let total = Math.min(parseInt(amount) + fees, req.user.balance)
- req.user.balance += 10000 - fees
- if (req.user.balance < 0) req.user.balance = 0
+ let fees = inputTotal - outputTotal;
+ let total = Math.min(parseInt(amount) + fees, req.user.balance);
+ req.user.balance += 10000 - fees;
+ if (req.user.balance < 0) req.user.balance = 0;
await db.transaction(async transaction => {
- await req.user.save({ transaction })
- emit(req.user.username, 'user', req.user)
+ await req.user.save({ transaction });
+ emit(req.user.username, "user", req.user);
await db.Payment.create(
{
amount: -total,
user_id: req.user.id,
hash: txid,
- rate: app.get('rates').ask,
- currency: 'CAD',
+ rate: app.get("rates").ask,
+ currency: "CAD"
},
{ transaction }
- )
- })
+ );
+ });
- res.send({ txid, tx, amount, fees })
+ res.send({ txid, tx, amount, fees });
} catch (e) {
- l(e)
- res.status(500).send(e.message)
+ l(e);
+ res.status(500).send(e.message);
}
- })
+ });
- app.post('/addInvoice', auth, async (req, res) => {
- let err = m => res.status(500).send(m)
- let { amount, address, tip } = req.body
+ app.post("/addInvoice", auth, async (req, res) => {
+ let err = m => res.status(500).send(m);
+ let { amount, address, tip } = req.body;
- let invoice
+ let invoice;
try {
- invoice = await lnb.addInvoice({ value: amount })
+ invoice = await lnb.addInvoice({ value: amount });
} catch (e) {
- return err(e.message)
+ return err(e.message);
}
- let hash = invoice.payment_request
- if (address) hash = address
+ let hash = invoice.payment_request;
+ if (address) hash = address;
await db.Payment.create({
user_id: req.user.id,
hash,
amount,
- currency: 'CAD',
- rate: app.get('rates').ask,
- tip,
- })
+ currency: "CAD",
+ rate: app.get("rates").ask,
+ tip
+ });
- res.send(invoice)
- })
+ res.send(invoice);
+ });
let fetchRates;
(fetchRates = async () => {
try {
let res = await axios.get(
- 'https://api.kraken.com/0/public/Ticker?pair=XBTCAD'
- )
- let ask = res.data.result.XXBTZCAD.c[0]
- let now = new Date()
- let ts = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`
- l(ts, 'ask price:', ask)
- app.set('rates', { ask })
- socket.emit('rate', ask)
+ "https://api.kraken.com/0/public/Ticker?pair=XBTCAD"
+ );
+ let ask = res.data.result.XXBTZCAD.c[0];
+ let now = new Date();
+ let ts = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
+ l(ts, "ask price:", ask);
+ app.set("rates", { ask });
+ socket.emit("rate", ask);
} catch (e) {
- l(e)
+ l(e);
}
- setTimeout(fetchRates, 3000)
- })()
+ setTimeout(fetchRates, 3000);
+ })();
- app.get('/rates', (req, res) => {
- res.send(app.get('rates'))
- })
+ app.get("/rates", (req, res) => {
+ res.send(app.get("rates"));
+ });
- app.post('/login', async (req, res) => {
+ app.post("/login", async (req, res) => {
try {
let user = await db.User.findOne({
where: {
- username: req.body.username,
- },
- })
+ username: req.body.username
+ }
+ });
if (
!user ||
!(await bcrypt.compare(req.body.password, user.password)) ||
(user.twofa && !(await authyVerify(user)))
) {
- return res.status(401).end()
+ return res.status(401).end();
}
- 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) });
- user = pick(user, ...whitelist)
- res.send({ user, token })
+ user = pick(user, ...whitelist);
+ res.send({ user, token });
} catch (err) {
- res.status(401).end()
+ res.status(401).end();
}
- })
+ });
- app.post('/facebookLogin', async (req, res) => {
- let { accessToken, userID } = req.body
+ app.post("/facebookLogin", async (req, res) => {
+ let { accessToken, userID } = req.body;
- let url = `https://graph.facebook.com/debug_token?input_token=${accessToken}&access_token=${config.facebook.appToken}`
- let check = await axios.get(url)
- if (!check.data.data.is_valid) return res.status(401).end()
+ let url = `https://graph.facebook.com/debug_token?input_token=${accessToken}&access_token=${config.facebook.appToken}`;
+ let check = await axios.get(url);
+ if (!check.data.data.is_valid) return res.status(401).end();
try {
let user = await db.User.findOne({
where: {
- username: req.body.userID,
- },
- })
+ username: req.body.userID
+ }
+ });
if (!user) {
- user = await db.User.create(user)
- user.username = userID
- user.name = (await fb.api(`/me?access_token=${accessToken}`)).name
- user.address = (await lna.newAddress({ type: 1 }, lna.meta)).address
- user.password = await bcrypt.hash(accessToken, 1)
- user.balance = 0
- user.pending = 0
+ user = await db.User.create(user);
+ user.username = userID;
+ user.name = (await fb.api(`/me?access_token=${accessToken}`)).name;
+ user.address = (await lna.newAddress({ type: 1 }, lna.meta)).address;
+ user.password = await bcrypt.hash(accessToken, 1);
+ user.balance = 0;
+ user.pending = 0;
let friends = (await fb.api(
`/${userID}/friends?access_token=${accessToken}`
- )).data
+ )).data;
if (friends.find(f => f.id === config.facebook.specialFriend)) {
- user.friend = true
- user.limit = 200
+ user.friend = true;
+ user.limit = 200;
}
- await user.save()
- addresses[user.address] = user.username
+ await user.save();
+ addresses[user.address] = user.username;
}
user.pic = (await fb.api(
`/me/picture?access_token=${accessToken}&redirect=false`
- )).data.url
- user.fbtoken = accessToken
- await user.save()
+ )).data.url;
+ user.fbtoken = accessToken;
+ await user.save();
- if (user.twofa && !(await authyVerify(user))) res.status(401).end()
+ if (user.twofa && !(await authyVerify(user))) res.status(401).end();
- let payload = { username: user.username }
- let token = jwt.sign(payload, config.jwt)
- res.cookie('token', token, { expires: new Date(Date.now() + 432000000) })
- res.send({ user, token })
+ let payload = { username: user.username };
+ let token = jwt.sign(payload, config.jwt);
+ res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
+ res.send({ user, token });
} catch (err) {
- l(err)
- res.status(401).end()
+ l(err);
+ res.status(401).end();
}
- })
+ });
- app.post('/buy', auth, async (req, res) => {
- const stripe = require('stripe')(config.stripe)
- const { token, amount, sat } = req.body
- let dollarAmount = parseInt(amount / 100)
+ app.post("/buy", auth, async (req, res) => {
+ const stripe = require("stripe")(config.stripe);
+ const { token, amount, sat } = req.body;
+ let dollarAmount = parseInt(amount / 100);
- if (dollarAmount > req.user.limit) return res.status(500).end()
+ if (dollarAmount > req.user.limit) return res.status(500).end();
try {
const charge = await stripe.charges.create({
amount,
- currency: 'cad',
- description: 'Bitcoin',
- source: token,
- })
+ currency: "cad",
+ description: "Bitcoin",
+ source: token
+ });
- req.user.balance += parseInt(sat)
- req.user.limit -= dollarAmount
- await req.user.save()
- emit(req.user.username, 'user', req.user)
+ req.user.balance += parseInt(sat);
+ req.user.limit -= dollarAmount;
+ await req.user.save();
+ emit(req.user.username, "user", req.user);
await db.Payment.create({
user_id: req.user.id,
hash: charge.balance_transaction,
amount: parseInt(sat),
- currency: 'CAD',
- rate: app.get('rates').ask,
+ currency: "CAD",
+ rate: app.get("rates").ask,
received: true,
- tip: 0,
- })
+ tip: 0
+ });
- res.send(`Bought ${amount}`)
+ res.send(`Bought ${amount}`);
} catch (e) {
- console.log(e)
- res.status(500).send(e)
+ console.log(e);
+ res.status(500).send(e);
}
- })
+ });
- app.post('/order', auth, async (req, res) => {
+ app.post("/order", auth, async (req, res) => {
await db.Order.create({
amount: 1,
price: 2,
- type: 'BUY',
- pair: 'BTC/CAD',
- })
- })
+ type: "BUY",
+ pair: "BTC/CAD"
+ });
+ });
- app.get('/me', async (req, res) => {
+ app.get("/me", async (req, res) => {
let data = (await fb.api(
- '/me/picture?access_token=EAAEIFqWk3ZAwBAEUfxQdH3T5CBKXmU8d7jQ5OTJBJZBiU1ZAp76lO26nh57WolM4R4JoKks9BCc49s8VrlEm2Ub1GlZCEzVD9fGxzUiranXDErDmR5gDUPKX3BhCsGA649a4hmbldRwKFTsmZCGZCergm9ACspKdTZB0WgFgA9wEdemIRIXuwCygNrymmKDh0Wd8nmoT4Hj3wZDZD&redirect=false'
- )).data
- res.send(data.url)
- })
+ "/me/picture?access_token=EAAEIFqWk3ZAwBAEUfxQdH3T5CBKXmU8d7jQ5OTJBJZBiU1ZAp76lO26nh57WolM4R4JoKks9BCc49s8VrlEm2Ub1GlZCEzVD9fGxzUiranXDErDmR5gDUPKX3BhCsGA649a4hmbldRwKFTsmZCGZCergm9ACspKdTZB0WgFgA9wEdemIRIXuwCygNrymmKDh0Wd8nmoT4Hj3wZDZD&redirect=false"
+ )).data;
+ res.send(data.url);
+ });
- app.get('/exchanges', async (req, res) => {
+ app.get("/exchanges", async (req, res) => {
let r = await axios.get(
- 'https://min-api.cryptocompare.com/data/v2/all/exchanges?fsym=BTC&api_key=6dc6d605ac45dcdbbc44d67111a2f03ba42ca8f54c5d4bf21069d2d3e99a89f0'
- )
- res.send(r.data)
- })
+ "https://min-api.cryptocompare.com/data/v2/all/exchanges?fsym=BTC&api_key=6dc6d605ac45dcdbbc44d67111a2f03ba42ca8f54c5d4bf21069d2d3e99a89f0"
+ );
+ res.send(r.data);
+ });
- app.get('/currencies', async (req, res) => {
- res.send(['CAD', 'USD'])
- })
+ app.get("/currencies", async (req, res) => {
+ res.send(["CAD", "USD"]);
+ });
- app.get('/balance/:address', async (req, res) => {
- let network = config.bitcoin.network === 'mainnet' ? 'main' : 'test3'
- let { address } = req.params
+ app.get("/balance/:address", async (req, res) => {
+ let network = config.bitcoin.network === "mainnet" ? "main" : "test3";
+ let { address } = req.params;
try {
res.send(
(await axios.get(
`https://api.blockcypher.com/v1/btc/${network}/addrs/${address}/balance`
)).data
- )
+ );
} catch (e) {
- res.status(500).send('Problem getting address balance')
+ res.status(500).send("Problem getting address balance");
}
- })
+ });
- app.use(function (err, req, res, next) {
- res.status(500)
- res.send('An error occurred')
- l(err.stack)
- return res.end()
- })
+ app.use(function(err, req, res, next) {
+ res.status(500);
+ res.send("An error occurred");
+ l(err.stack);
+ return res.end();
+ });
- server.listen(config.port)
-})()
+ server.listen(config.port);
+})();