diff options
| author | Adam Soltys <[email protected]> | 2018-03-15 22:13:42 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2018-03-15 22:13:42 -0700 |
| commit | 869b33813e72689c053ba8505c8806129ec3c7d5 (patch) | |
| tree | f3044c3aeaf23d08efd7425df83be6695f0f3715 | |
| parent | 79aeed9061db8b335e60bc4bee48571e717fa637 (diff) | |
| download | coinos-server-869b33813e72689c053ba8505c8806129ec3c7d5.tar.gz coinos-server-869b33813e72689c053ba8505c8806129ec3c7d5.zip | |
use payments table for in and out ln and onchain payments
| -rw-r--r-- | db.js | 30 | ||||
| -rw-r--r-- | index.js | 91 | ||||
| -rw-r--r-- | migrations/20180312160019-addInvoiceRateAndCurrency.js | 13 | ||||
| -rw-r--r-- | migrations/20180315232457-renameInvoices.js | 15 | ||||
| -rw-r--r-- | migrations/20180316032817-addPaymentsAmount.js | 11 | ||||
| -rw-r--r-- | package.json | 1 | ||||
| -rw-r--r-- | yarn.lock | 54 |
7 files changed, 167 insertions, 48 deletions
@@ -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, @@ -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", @@ -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" |
