aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2018-03-15 22:13:42 -0700
committerAdam Soltys <[email protected]>2018-03-15 22:13:42 -0700
commit869b33813e72689c053ba8505c8806129ec3c7d5 (patch)
treef3044c3aeaf23d08efd7425df83be6695f0f3715
parent79aeed9061db8b335e60bc4bee48571e717fa637 (diff)
downloadcoinos-server-869b33813e72689c053ba8505c8806129ec3c7d5.tar.gz
coinos-server-869b33813e72689c053ba8505c8806129ec3c7d5.zip
use payments table for in and out ln and onchain payments
-rw-r--r--db.js30
-rw-r--r--index.js91
-rw-r--r--migrations/20180312160019-addInvoiceRateAndCurrency.js13
-rw-r--r--migrations/20180315232457-renameInvoices.js15
-rw-r--r--migrations/20180316032817-addPaymentsAmount.js11
-rw-r--r--package.json1
-rw-r--r--yarn.lock54
7 files changed, 167 insertions, 48 deletions
diff --git a/db.js b/db.js
index 42ba47f9..4c108d3a 100644
--- a/db.js
+++ b/db.js
@@ -25,8 +25,7 @@ const auto = new SequelizeAuto(
const tables = {
User: 'users',
- Transaction: 'transactions',
- Invoice: 'invoices',
+ Payment: 'payments',
}
const db = new Sequelize(
@@ -70,15 +69,32 @@ const p = (lnrpc) => {
db[k] = db.define(k, fields, { tableName: t })
- if (t === 'invoices') {
- db['Invoice'].belongsTo(db['User'], {
+ let typefields = {}
+
+ let options = {}
+
+ if (t === 'users') {
+ options = {
+ before: (findOptions, args, context) => {
+ findOptions.where = { id: context.user.id }
+ return findOptions
+ }
+ }
+ }
+
+ if (t === 'payments') {
+ db['Payment'].belongsTo(db['User'], {
as: 'user',
foreignKey: 'user_id'
})
- }
- let typefields = {}
- let options = {}
+ options = {
+ before: (findOptions, args, context) => {
+ findOptions.where = { user_id: context.user.id }
+ return findOptions
+ }
+ }
+ }
gqltypes[t] = new GraphQLObjectType({
name: t,
diff --git a/index.js b/index.js
index 1912a7a5..122fa774 100644
--- a/index.js
+++ b/index.js
@@ -18,7 +18,7 @@ import zmq from 'zmq'
import cache from './cache'
-import { graphqlExpress, graphiqlExpress } from 'apollo-server-express'
+import graphqlHTTP from 'express-graphql'
dotenv.config()
const l = console.log
@@ -59,13 +59,20 @@ const l = console.log
const auth = passport.authenticate('jwt', { session: false })
const sids = {}
+ app.use(passport.initialize())
+
+ app.use('/graphql', auth, graphqlHTTP({
+ schema: db.gqlschema,
+ graphiql: true
+ }))
+
socket.use((socket, next) => {
try {
let token = socket.request.headers.cookie.match(`;\\s*token=([^;]+)`)[1]
let user = jwt.decode(token).username
socket.request.user = user
sids[user] = socket.id
- } catch (e) { /* */ }
+ } catch (e) { /**/ }
next()
})
@@ -76,23 +83,21 @@ const l = console.log
})
})
- app.use(passport.initialize())
-
const handlePayment = async msg => {
- let invoice = await db['Invoice'].findOne({
+ let payment = await db['Payment'].findOne({
include: { model: db['User'], as: 'user' },
where: {
- payreq: msg.payment_request
+ hash: msg.payment_request
}
})
- if (!invoice) return
+ if (!payment) return
- invoice.user.channelbalance += parseInt(msg.value)
- l(invoice.user.username, msg.value)
- await invoice.user.save()
+ payment.user.channelbalance += parseInt(msg.value)
+ l(payment.user.username, msg.value)
+ await payment.user.save()
- socket.to(sids[invoice.user.username]).emit('invoice', msg)
+ socket.to(sids[payment.user.username]).emit('invoice', msg)
}
const invoices = lna.subscribeInvoices({})
@@ -106,7 +111,6 @@ const l = console.log
zmqSock.subscribe('rawblock')
zmqSock.subscribe('rawtx')
- const seen = []
const channelpeers = [
'039cc950286a8fa99218283d1adc2456e0d5e81be558da77dd6e85ba9a1fff5ad3',
'022ea315e5052b152579e70a90bacfd6aa7420f2ce94674d4ca8da29d709bc70fd',
@@ -125,8 +129,8 @@ const l = console.log
switch (topic) {
case 'rawtx': {
- if (seen.includes(message)) return
-
+ let hash = (await bc.decodeRawTransaction(message)).hash
+ if (await db.Payment.findOne({ where: { hash } })) return
let tx = bitcoin.Transaction.fromHex(message)
let total = tx.outs.reduce((a, b) => a + b.value, 0)
tx.outs.map(async o => {
@@ -141,10 +145,18 @@ const l = console.log
user.balance += o.value
await user.save()
+
+ await db.Payment.create({
+ user_id: user.id,
+ hash: hash,
+ amount: o.value,
+ currency: 'CAD',
+ rate: app.get('rates').ask,
+ })
+
socket.emit('tx', message)
- seen.push(message)
}
- } catch(e) { }
+ } catch(e) {}
})
break
@@ -238,6 +250,14 @@ const l = console.log
let total = parseInt(m.payment_route.total_amt) + parseInt(m.payment_route.total_fees)
req.user.channelbalance -= total
+ await db['Payment'].create({
+ amount: -total,
+ user_id: req.user.id,
+ hash: req.body.payreq,
+ rate: app.get('rates').ask,
+ currency: 'CAD',
+ })
+
await req.user.save()
res.send(m)
}
@@ -275,11 +295,18 @@ const l = console.log
let output_total = tx.outs.reduce((a, b) => a + b.value, 0)
let fees = input_total - output_total
- let total = parseInt(amount) + fees
-
- req.user.balance -= Math.min(req.user.balance, total)
+ let total = Math.min(parseInt(amount) + fees, req.user.balance)
+ req.user.balance -= total
await req.user.save()
+ await db['Payment'].create({
+ amount: -total,
+ user_id: req.user.id,
+ hash: txid,
+ rate: app.get('rates').ask,
+ currency: 'CAD',
+ })
+
res.send({ txid, tx, amount, fees })
} catch (e) {
l(e)
@@ -290,9 +317,12 @@ const l = console.log
app.post('/addInvoice', auth, async (req, res) => {
let invoice = await lnb.addInvoice({ value: req.body.amount })
- await db.Invoice.create({
+ await db.Payment.create({
user_id: req.user.id,
- payreq: invoice.payment_request,
+ hash: invoice.payment_request,
+ amount: req.body.amount,
+ currency: 'CAD',
+ rate: app.get('rates').ask,
})
res.send(invoice)
@@ -335,25 +365,6 @@ const l = console.log
}
})
- app.get('/secret', passport.authenticate('jwt', { session: false }), (req, res) => {
- res.send({message: 'Success! You can not see this without a token'})
- })
-
- app.get('/api/users/me',
- passport.authenticate('basic', { session: false }),
- function(req, res) {
- res.send({ id: req.user.id, username: req.user.username });
- });
-
- app.use('/graphql', bodyParser.json(), graphqlExpress({
- schema: db.gqlschema,
- context: {},
- tracing: true,
- cacheControl: true,
- }))
-
- app.use('/graphiql', graphiqlExpress({ endpointURL: '/graphql' }))
-
app.use(function (err, req, res, next) {
res.status(500)
res.send('An error occurred')
diff --git a/migrations/20180312160019-addInvoiceRateAndCurrency.js b/migrations/20180312160019-addInvoiceRateAndCurrency.js
new file mode 100644
index 00000000..97dbc6ea
--- /dev/null
+++ b/migrations/20180312160019-addInvoiceRateAndCurrency.js
@@ -0,0 +1,13 @@
+'use strict';
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ queryInterface.addColumn('invoices', 'rate', { type: Sequelize.DOUBLE })
+ return queryInterface.addColumn('invoices', 'currency', { type: Sequelize.STRING })
+ },
+
+ down: (queryInterface, Sequelize) => {
+ queryInterface.removeColumn('invoices', 'rate')
+ return queryInterface.removeColumn('invoices', 'currency')
+ }
+};
diff --git a/migrations/20180315232457-renameInvoices.js b/migrations/20180315232457-renameInvoices.js
new file mode 100644
index 00000000..9e06e56d
--- /dev/null
+++ b/migrations/20180315232457-renameInvoices.js
@@ -0,0 +1,15 @@
+'use strict';
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ queryInterface.renameTable('invoices', 'payments')
+ queryInterface.addColumn('payments', 'address', { type: Sequelize.INTEGER });
+ queryInterface.addColumn('payments', 'received', { type: Sequelize.BOOLEAN });
+ },
+
+ down: (queryInterface, Sequelize) => {
+ queryInterface.removeColumn('payments', 'received');
+ queryInterface.removeColumn('payments', 'address');
+ queryInterface.renameTable('payments', 'invoices')
+ }
+};
diff --git a/migrations/20180316032817-addPaymentsAmount.js b/migrations/20180316032817-addPaymentsAmount.js
new file mode 100644
index 00000000..89356ea3
--- /dev/null
+++ b/migrations/20180316032817-addPaymentsAmount.js
@@ -0,0 +1,11 @@
+'use strict';
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.addColumn('payments', 'amount', { type: Sequelize.DOUBLE });
+ },
+
+ down: (queryInterface, Sequelize) => {
+ return queryInterface.removeColumn('payments', 'amount');
+ }
+};
diff --git a/package.json b/package.json
index d5202a88..e64e9133 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"cors": "^2.8.4",
"dotenv": "^4.0.0",
"express": "4.14.0",
+ "express-graphql": "^0.6.12",
"express-session": "^1.6.5",
"graphql": "^0.12.3",
"graphql-redis-subscriptions": "^1.4.0",
diff --git a/yarn.lock b/yarn.lock
index 3bf918be..38d5f3f8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -31,6 +31,13 @@ [email protected], accepts@~1.3.3:
mime-types "~2.1.11"
negotiator "0.6.1"
+accepts@^1.3.0:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
+ dependencies:
+ mime-types "~2.1.18"
+ negotiator "0.6.1"
+
accepts@~1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f"
@@ -1802,6 +1809,10 @@ content-disposition@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
+content-type@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
+
content-type@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed"
@@ -2098,6 +2109,10 @@ [email protected], depd@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+
depd@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -2564,6 +2579,15 @@ expand-template@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.0.tgz#e09efba977bf98f9ee0ed25abd0c692e02aec3fc"
+express-graphql@^0.6.12:
+ version "0.6.12"
+ resolved "https://registry.yarnpkg.com/express-graphql/-/express-graphql-0.6.12.tgz#dfcb2058ca72ed5190b140830ad8cdbf76a9128a"
+ dependencies:
+ accepts "^1.3.0"
+ content-type "^1.0.4"
+ http-errors "^1.3.0"
+ raw-body "^2.3.2"
+
express-session@^1.6.5:
version "1.15.2"
resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.2.tgz#d98516443a4ccb8688e1725ae584c02daa4093d4"
@@ -3325,6 +3349,15 @@ hosted-git-info@^2.1.4:
version "2.4.2"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
[email protected], http-errors@^1.3.0:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
+ dependencies:
+ depd "1.1.1"
+ inherits "2.0.3"
+ setprototypeof "1.0.3"
+ statuses ">= 1.3.1 < 2"
+
http-errors@~1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750"
@@ -3393,7 +3426,7 @@ [email protected], iconv-lite@~0.4.13:
version "0.4.15"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
-iconv-lite@^0.4.17, iconv-lite@^0.4.18:
[email protected], iconv-lite@^0.4.17, iconv-lite@^0.4.18:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@@ -4223,6 +4256,10 @@ mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
+mime-db@~1.33.0:
+ version "1.33.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
+
mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.7:
version "2.1.15"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
@@ -4245,6 +4282,12 @@ mime-types@~2.1.16, mime-types@~2.1.17:
dependencies:
mime-db "~1.30.0"
+mime-types@~2.1.18:
+ version "2.1.18"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
+ dependencies:
+ mime-db "~1.33.0"
+
version "1.2.4"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.4.tgz#11b5fdaf29c2509255176b80ad520294f5de92b7"
@@ -5097,6 +5140,15 @@ range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
+raw-body@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
+ dependencies:
+ bytes "3.0.0"
+ http-errors "1.6.2"
+ iconv-lite "0.4.19"
+ unpipe "1.0.0"
+
raw-body@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96"