From 7c5dfc8d51efe4df4e67f86f33c489a320fcb8f9 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 31 Jul 2014 21:06:23 -0700 Subject: Move coffee files to src/ folder --- src/app.coffee | 72 +++++++++++++++++++++++ src/app.js | 128 ++++++++++++++++++++++++++++++++++++++++ src/install.coffee | 16 +++++ src/install.js | 23 ++++++++ src/passport.coffee | 35 +++++++++++ src/passport.js | 45 ++++++++++++++ src/redis.coffee | 5 ++ src/redis.js | 11 ++++ src/routes/calculator.coffee | 28 +++++++++ src/routes/calculator.js | 42 +++++++++++++ src/routes/sessions.coffee | 21 +++++++ src/routes/sessions.js | 34 +++++++++++ src/routes/transactions.coffee | 38 ++++++++++++ src/routes/transactions.js | 48 +++++++++++++++ src/routes/users.coffee | 98 +++++++++++++++++++++++++++++++ src/routes/users.js | 130 +++++++++++++++++++++++++++++++++++++++++ src/socket_test.coffee | 14 +++++ src/socket_test.js | 64 ++++++++++++++++++++ 18 files changed, 852 insertions(+) create mode 100644 src/app.coffee create mode 100644 src/app.js create mode 100644 src/install.coffee create mode 100644 src/install.js create mode 100644 src/passport.coffee create mode 100644 src/passport.js create mode 100644 src/redis.coffee create mode 100644 src/redis.js create mode 100644 src/routes/calculator.coffee create mode 100644 src/routes/calculator.js create mode 100644 src/routes/sessions.coffee create mode 100644 src/routes/sessions.js create mode 100644 src/routes/transactions.coffee create mode 100644 src/routes/transactions.js create mode 100644 src/routes/users.coffee create mode 100644 src/routes/users.js create mode 100644 src/socket_test.coffee create mode 100644 src/socket_test.js (limited to 'src') diff --git a/src/app.coffee b/src/app.coffee new file mode 100644 index 00000000..e0930713 --- /dev/null +++ b/src/app.coffee @@ -0,0 +1,72 @@ +express = require('express') +bodyParser = require('body-parser') +cookieParser = require('cookie-parser') +path = require('path') +engines = require('consolidate') +passport = require('./passport') + +calculator = require("./routes/calculator") +sessions = require("./routes/sessions")(passport) +transactions = require("./routes/transactions") +users = require("./routes/users")(sessions) + +session = require('express-session') +RedisStore = require('connect-redis')(session) +sessionStore = new RedisStore(require('./redis').host, ttl: 172800) + + +app = express() +app.enable('trust proxy') +app.engine('html', require('hogan-express')) +app.set('view engine', 'html') +app.set('views', __dirname + '/views') +app.use(express.static(__dirname + '/public')) +app.use(require('connect-assets')(src: 'public')) +app.use(bodyParser.urlencoded({ extended: true})) +app.use(bodyParser.json()) +app.use(bodyParser.json({ type: 'application/vnd.api+json' })) +app.use(cookieParser('weareallmadeofstars')) +app.use(session(resave: true, saveUninitialized: true, secret: 'weareallmadeofstars', store: sessionStore, cookie: { maxAge: 25920000000 }, key: 'vanbtc.sid')) +app.use(passport.initialize()) +app.use(passport.session()) + +authorize = (req, res, next) -> + + if req.params.user is req.user?.username or + req.user?.username is 'admin' or + req.user?.username is 'ben' + return next() + res.redirect('/login') + +app.get('/', sessions.new) +app.get('/register', users.new) +app.get('/ticker', calculator.ticker) +app.get('/sweep', calculator.sweep) + +app.get('/login', sessions.new) +app.post('/login', sessions.create) +app.get('/logout', sessions.destroy) + +app.get('/:user/exists', users.exists) +app.get('/:user.json', users.json) + +app.get('/users', users.index) +app.get('/users/new', users.new) +app.post('/users', users.create) + +app.get('/:user/edit', authorize, users.edit) +app.post('/:user/update', authorize, users.update) + +app.get('/:user/transactions.json', authorize, transactions.json) +app.post('/:user/transactions', transactions.create) +app.get('/:user/report', authorize, transactions.index) +app.get('/:user', users.show) + +app.use((err, req, res, next) -> + res.status(500) + res.send('An error occurred'); + console.log(err) + res.end() +) + +app.listen(3000) diff --git a/src/app.js b/src/app.js new file mode 100644 index 00000000..05452d81 --- /dev/null +++ b/src/app.js @@ -0,0 +1,128 @@ +(function() { + var RedisStore, app, authorize, bodyParser, calculator, cookieParser, engines, express, passport, path, session, sessionStore, sessions, transactions, users; + + express = require('express'); + + bodyParser = require('body-parser'); + + cookieParser = require('cookie-parser'); + + path = require('path'); + + engines = require('consolidate'); + + passport = require('./passport'); + + calculator = require("./routes/calculator"); + + sessions = require("./routes/sessions")(passport); + + transactions = require("./routes/transactions"); + + users = require("./routes/users")(sessions); + + session = require('express-session'); + + RedisStore = require('connect-redis')(session); + + sessionStore = new RedisStore(require('./redis').host, { + ttl: 172800 + }); + + app = express(); + + app.enable('trust proxy'); + + app.engine('html', require('hogan-express')); + + app.set('view engine', 'html'); + + app.set('views', __dirname + '/views'); + + app.use(express["static"](__dirname + '/public')); + + app.use(require('connect-assets')({ + src: 'public' + })); + + app.use(bodyParser.urlencoded({ + extended: true + })); + + app.use(bodyParser.json()); + + app.use(bodyParser.json({ + type: 'application/vnd.api+json' + })); + + app.use(cookieParser('weareallmadeofstars')); + + app.use(session({ + resave: true, + saveUninitialized: true, + secret: 'weareallmadeofstars', + store: sessionStore, + cookie: { + maxAge: 25920000000 + }, + key: 'vanbtc.sid' + })); + + app.use(passport.initialize()); + + app.use(passport.session()); + + authorize = function(req, res, next) { + var _ref, _ref1, _ref2; + if (req.params.user === ((_ref = req.user) != null ? _ref.username : void 0) || ((_ref1 = req.user) != null ? _ref1.username : void 0) === 'admin' || ((_ref2 = req.user) != null ? _ref2.username : void 0) === 'ben') { + return next(); + } + return res.redirect('/login'); + }; + + app.get('/', sessions["new"]); + + app.get('/register', users["new"]); + + app.get('/ticker', calculator.ticker); + + app.get('/sweep', calculator.sweep); + + app.get('/login', sessions["new"]); + + app.post('/login', sessions.create); + + app.get('/logout', sessions.destroy); + + app.get('/:user/exists', users.exists); + + app.get('/:user.json', users.json); + + app.get('/users', users.index); + + app.get('/users/new', users["new"]); + + app.post('/users', users.create); + + app.get('/:user/edit', authorize, users.edit); + + app.post('/:user/update', authorize, users.update); + + app.get('/:user/transactions.json', authorize, transactions.json); + + app.post('/:user/transactions', transactions.create); + + app.get('/:user/report', authorize, transactions.index); + + app.get('/:user', users.show); + + app.use(function(err, req, res, next) { + res.status(500); + res.send('An error occurred'); + console.log(err); + return res.end(); + }); + + app.listen(3000); + +}).call(this); diff --git a/src/install.coffee b/src/install.coffee new file mode 100644 index 00000000..38e32b6f --- /dev/null +++ b/src/install.coffee @@ -0,0 +1,16 @@ +db = require("./redis") +bcrypt = require('bcrypt') + +db.get("user:admin", (err, res) -> + if !res + bcrypt.hash('admin', 12, (err, hash) -> + db.sadd("users","user:admin") + db.hmset("user:admin", + username: 'admin' + password: hash, + , -> + console.log("Created admin user with password 'admin'") + process.exit() + ) + ) +) diff --git a/src/install.js b/src/install.js new file mode 100644 index 00000000..088d593e --- /dev/null +++ b/src/install.js @@ -0,0 +1,23 @@ +(function() { + var bcrypt, db; + + db = require("./redis"); + + bcrypt = require('bcrypt'); + + db.get("user:admin", function(err, res) { + if (!res) { + return bcrypt.hash('admin', 12, function(err, hash) { + db.sadd("users", "user:admin"); + return db.hmset("user:admin", { + username: 'admin', + password: hash + }, function() { + console.log("Created admin user with password 'admin'"); + return process.exit(); + }); + }); + } + }); + +}).call(this); diff --git a/src/passport.coffee b/src/passport.coffee new file mode 100644 index 00000000..12913424 --- /dev/null +++ b/src/passport.coffee @@ -0,0 +1,35 @@ +db = require("redis").createClient() +bcrypt = require('bcrypt') + +passport = require('passport') +LocalStrategy = require('passport-local').Strategy + +passport.serializeUser((user, done) -> + done(null, user.username) +) + +passport.deserializeUser((username, done) -> + db.hgetall("user:"+username, (err, user) -> + return done(null, user) + ) +) + +passport.use(new LocalStrategy( + (username, password, done) -> + db.hget("user:"+username, 'password', (err, hash) -> + return done(err) if err + if hash + bcrypt.compare(password, hash, (err, match) -> + if match + db.hgetall("user:"+username, (err, user) -> + return done(null, user) + ) + else + return done(null, false) + ) + else + return done(null, false) + ) +)) + +module.exports = passport diff --git a/src/passport.js b/src/passport.js new file mode 100644 index 00000000..aa11d658 --- /dev/null +++ b/src/passport.js @@ -0,0 +1,45 @@ +(function() { + var LocalStrategy, bcrypt, db, passport; + + db = require("redis").createClient(); + + bcrypt = require('bcrypt'); + + passport = require('passport'); + + LocalStrategy = require('passport-local').Strategy; + + passport.serializeUser(function(user, done) { + return done(null, user.username); + }); + + passport.deserializeUser(function(username, done) { + return db.hgetall("user:" + username, function(err, user) { + return done(null, user); + }); + }); + + passport.use(new LocalStrategy(function(username, password, done) { + return db.hget("user:" + username, 'password', function(err, hash) { + if (err) { + return done(err); + } + if (hash) { + return bcrypt.compare(password, hash, function(err, match) { + if (match) { + return db.hgetall("user:" + username, function(err, user) { + return done(null, user); + }); + } else { + return done(null, false); + } + }); + } else { + return done(null, false); + } + }); + })); + + module.exports = passport; + +}).call(this); diff --git a/src/redis.coffee b/src/redis.coffee new file mode 100644 index 00000000..38524595 --- /dev/null +++ b/src/redis.coffee @@ -0,0 +1,5 @@ +settings = + port: 6379 + host: '127.0.0.1' + +module.exports = require('redis').createClient(settings.port, settings.host) diff --git a/src/redis.js b/src/redis.js new file mode 100644 index 00000000..85312c4e --- /dev/null +++ b/src/redis.js @@ -0,0 +1,11 @@ +(function() { + var settings; + + settings = { + port: 6379, + host: '127.0.0.1' + }; + + module.exports = require('redis').createClient(settings.port, settings.host); + +}).call(this); diff --git a/src/routes/calculator.coffee b/src/routes/calculator.coffee new file mode 100644 index 00000000..891fdce8 --- /dev/null +++ b/src/routes/calculator.coffee @@ -0,0 +1,28 @@ +exports.new = (req, res) -> + res.render('calculator/setup') + +exports.sweep = (req, res) -> + res.render('calculator/sweep', layout: 'layout') + +exports.show = (req, res) -> + res.render('calculator/show', layout: 'layout', x: 'meow') + +exports.ticker = (req, res) -> + fs = require('fs') + fs.readFile("./public/js/rates.json", (err, data) -> + req.query.currency ||= 'CAD' + req.query.symbol ||= 'quadrigacx' + req.query.type ||= 'bid' + + try + exchange = JSON.parse(data)[req.query.currency][req.query.symbol]['rates'][req.query.type].toString() + catch e + exchange = "0" + + res.writeHead(200, + 'Content-Length': exchange.length, + 'Content-Type': 'text/plain') + res.write(exchange) + res.end() + ) + diff --git a/src/routes/calculator.js b/src/routes/calculator.js new file mode 100644 index 00000000..3e067df6 --- /dev/null +++ b/src/routes/calculator.js @@ -0,0 +1,42 @@ +(function() { + exports["new"] = function(req, res) { + return res.render('calculator/setup'); + }; + + exports.sweep = function(req, res) { + return res.render('calculator/sweep', { + layout: 'layout' + }); + }; + + exports.show = function(req, res) { + return res.render('calculator/show', { + layout: 'layout', + x: 'meow' + }); + }; + + exports.ticker = function(req, res) { + var fs; + fs = require('fs'); + return fs.readFile("./public/js/rates.json", function(err, data) { + var e, exchange, _base, _base1, _base2; + (_base = req.query).currency || (_base.currency = 'CAD'); + (_base1 = req.query).symbol || (_base1.symbol = 'quadrigacx'); + (_base2 = req.query).type || (_base2.type = 'bid'); + try { + exchange = JSON.parse(data)[req.query.currency][req.query.symbol]['rates'][req.query.type].toString(); + } catch (_error) { + e = _error; + exchange = "0"; + } + res.writeHead(200, { + 'Content-Length': exchange.length, + 'Content-Type': 'text/plain' + }); + res.write(exchange); + return res.end(); + }); + }; + +}).call(this); diff --git a/src/routes/sessions.coffee b/src/routes/sessions.coffee new file mode 100644 index 00000000..775c52ac --- /dev/null +++ b/src/routes/sessions.coffee @@ -0,0 +1,21 @@ +module.exports = (passport) -> + new: (req, res) -> + res.render('sessions/new') + + create: (req, res, next) -> + passport.authenticate('local', (err, user, info) -> + if (err) + return next(err) + if (!user) + return res.render('sessions/new', badpw: true) + req.login(user, (err) -> + if (err) + return next(err) + url = "/#{user.username}/edit" + return res.redirect(url) + ) + )(req, res, next) + + destroy: (req, res) -> + req.logout() + res.redirect('/login') diff --git a/src/routes/sessions.js b/src/routes/sessions.js new file mode 100644 index 00000000..f038b484 --- /dev/null +++ b/src/routes/sessions.js @@ -0,0 +1,34 @@ +(function() { + module.exports = function(passport) { + return { + "new": function(req, res) { + return res.render('sessions/new'); + }, + create: function(req, res, next) { + return passport.authenticate('local', function(err, user, info) { + if (err) { + return next(err); + } + if (!user) { + return res.render('sessions/new', { + badpw: true + }); + } + return req.login(user, function(err) { + var url; + if (err) { + return next(err); + } + url = "/" + user.username + "/edit"; + return res.redirect(url); + }); + })(req, res, next); + }, + destroy: function(req, res) { + req.logout(); + return res.redirect('/login'); + } + }; + }; + +}).call(this); diff --git a/src/routes/transactions.coffee b/src/routes/transactions.coffee new file mode 100644 index 00000000..0bdaeed6 --- /dev/null +++ b/src/routes/transactions.coffee @@ -0,0 +1,38 @@ +db = require('../redis') + +module.exports = + json: (req, res) -> + user = req.params.user + r = 'transactions': [] + + db.lrange("#{user}:transactions", 0, -1, (err, transactions) -> + process = (err, t) -> + r.transactions.push t + + if i >= transactions.length + res.write(JSON.stringify(r)) + res.end() + else + db.hgetall("#{user}:transactions:#{transactions[i++]}", process) + + i = 0 + db.hgetall("#{user}:transactions:#{transactions[i++]}", process) + ) + + create: (req, res) -> + user = req.params.user + db.incr('transactions', (err, id) -> + db.hmset("#{user}:transactions:#{id}", req.body, -> + db.rpush("#{user}:transactions", id, -> + res.write(JSON.stringify(req.body)) + res.end() + ) + ) + ) + + index: (req, res) -> + res.render('transactions/index', + user: req.params.user, + layout: 'layout' + ) + diff --git a/src/routes/transactions.js b/src/routes/transactions.js new file mode 100644 index 00000000..97fc5659 --- /dev/null +++ b/src/routes/transactions.js @@ -0,0 +1,48 @@ +(function() { + var db; + + db = require('../redis'); + + module.exports = { + json: function(req, res) { + var r, user; + user = req.params.user; + r = { + 'transactions': [] + }; + return db.lrange("" + user + ":transactions", 0, -1, function(err, transactions) { + var i, process; + process = function(err, t) { + r.transactions.push(t); + if (i >= transactions.length) { + res.write(JSON.stringify(r)); + return res.end(); + } else { + return db.hgetall("" + user + ":transactions:" + transactions[i++], process); + } + }; + i = 0; + return db.hgetall("" + user + ":transactions:" + transactions[i++], process); + }); + }, + create: function(req, res) { + var user; + user = req.params.user; + return db.incr('transactions', function(err, id) { + return db.hmset("" + user + ":transactions:" + id, req.body, function() { + return db.rpush("" + user + ":transactions", id, function() { + res.write(JSON.stringify(req.body)); + return res.end(); + }); + }); + }); + }, + index: function(req, res) { + return res.render('transactions/index', { + user: req.params.user, + layout: 'layout' + }); + } + }; + +}).call(this); diff --git a/src/routes/users.coffee b/src/routes/users.coffee new file mode 100644 index 00000000..db4dde03 --- /dev/null +++ b/src/routes/users.coffee @@ -0,0 +1,98 @@ +db = require("../redis") +bcrypt = require('bcrypt') + +module.exports = (sessions) -> + exists: (req, res) -> + db.hgetall("user:"+req.params.user, (err, obj) -> + if obj? then res.write('true') else res.write('false') + res.end() + ) + + json: (req, res) -> + db.hgetall("user:"+req.params.user, (err, obj) -> + delete obj['password'] + res.writeHead(200, {"Content-Type": "application/json"}); + res.write(JSON.stringify(obj)) + res.end() + ) + + index: (req, res) -> + return + db.keys('*', (err, obj) -> + res.write(JSON.stringify(obj)) + res.end() + ) + + list: (req, res) -> + res.render('users/index', + layout: 'layout' + ) + + show: (req, res) -> + db.hgetall("user:"+req.params.user, (err, obj) -> + if obj + res.render('calculator/show', + user: req.params.user, + layout: 'layout' + ) + else + res.render('sessions/new', + notice: true + ) + ) + + new: (req, res) -> + res.render('users/new', + js: (-> global.js), + css: (-> global.css) + ) + + create: (req, res) -> + errormsg = "" + userkey = "user:"+req.body.username + db.hgetall(userkey, (err, obj) -> + if obj + res.redirect(req.body.username) + else + if req.body.confirm != req.body.password + errormsg += "Passwords must match" + return res.render('users/new', + js: (-> global.js), + css: (-> global.css), + error: errormsg + ) + + bcrypt.hash(req.body.password, 12, (err, hash) -> + db.sadd("users",userkey) + db.hmset(userkey, + username: req.body.username, + password: hash, + email: req.body.email + , -> + req.headers['referer'] = "/#{req.body.username}/edit" + sessions.create(req, res) + ) + ) + ) + + edit: (req, res) -> + res.render('calculator/setup', + user: req.params.user, + layout: 'layout' + ) + + update: (req, res) -> + return unless req.params.user is req.user.username or + req.user.username is 'admin' or req.user.username is 'ben' + if req.body.password is '' + delete req.body.password + db.hmset("user:"+req.params.user, req.body, -> + if not req.body.password? + res.redirect("/#{req.params.user}") + else + bcrypt.hash(req.body.password, 12, (err, hash) -> + db.hmset("user:"+req.params.user,password: hash, -> + res.redirect("/#{req.params.user}") + ) + ) + ) diff --git a/src/routes/users.js b/src/routes/users.js new file mode 100644 index 00000000..137d5bb9 --- /dev/null +++ b/src/routes/users.js @@ -0,0 +1,130 @@ +(function() { + var bcrypt, db; + + db = require("../redis"); + + bcrypt = require('bcrypt'); + + module.exports = function(sessions) { + return { + exists: function(req, res) { + return db.hgetall("user:" + req.params.user, function(err, obj) { + if (obj != null) { + res.write('true'); + } else { + res.write('false'); + } + return res.end(); + }); + }, + json: function(req, res) { + return db.hgetall("user:" + req.params.user, function(err, obj) { + delete obj['password']; + res.writeHead(200, { + "Content-Type": "application/json" + }); + res.write(JSON.stringify(obj)); + return res.end(); + }); + }, + index: function(req, res) { + return; + return db.keys('*', function(err, obj) { + res.write(JSON.stringify(obj)); + return res.end(); + }); + }, + list: function(req, res) { + return res.render('users/index', { + layout: 'layout' + }); + }, + show: function(req, res) { + return db.hgetall("user:" + req.params.user, function(err, obj) { + if (obj) { + return res.render('calculator/show', { + user: req.params.user, + layout: 'layout' + }); + } else { + return res.render('sessions/new', { + notice: true + }); + } + }); + }, + "new": function(req, res) { + return res.render('users/new', { + js: (function() { + return global.js; + }), + css: (function() { + return global.css; + }) + }); + }, + create: function(req, res) { + var errormsg, userkey; + errormsg = ""; + userkey = "user:" + req.body.username; + return db.hgetall(userkey, function(err, obj) { + if (obj) { + return res.redirect(req.body.username); + } else { + if (req.body.confirm !== req.body.password) { + errormsg += "Passwords must match"; + return res.render('users/new', { + js: (function() { + return global.js; + }), + css: (function() { + return global.css; + }), + error: errormsg + }); + } + return bcrypt.hash(req.body.password, 12, function(err, hash) { + db.sadd("users", userkey); + return db.hmset(userkey, { + username: req.body.username, + password: hash, + email: req.body.email + }, function() { + req.headers['referer'] = "/" + req.body.username + "/edit"; + return sessions.create(req, res); + }); + }); + } + }); + }, + edit: function(req, res) { + return res.render('calculator/setup', { + user: req.params.user, + layout: 'layout' + }); + }, + update: function(req, res) { + if (!(req.params.user === req.user.username || req.user.username === 'admin' || req.user.username === 'ben')) { + return; + } + if (req.body.password === '') { + delete req.body.password; + } + return db.hmset("user:" + req.params.user, req.body, function() { + if (req.body.password == null) { + return res.redirect("/" + req.params.user); + } else { + return bcrypt.hash(req.body.password, 12, function(err, hash) { + return db.hmset("user:" + req.params.user, { + password: hash + }, function() { + return res.redirect("/" + req.params.user); + }); + }); + } + }); + } + }; + }; + +}).call(this); diff --git a/src/socket_test.coffee b/src/socket_test.coffee new file mode 100644 index 00000000..315be3a3 --- /dev/null +++ b/src/socket_test.coffee @@ -0,0 +1,14 @@ + transaction = {"hash":{},"version":1,"lock_time":0,"ins":[{"s":{},"q":4294967295,"o":{}}],"outs":[{"v":{},"s":{}},{"v":{},"s":{}}],"_buffer":{},"txid":"8500a0893a2d83a17819673884ade21bbef07d8c92bfe51682e45873cc2d3720","vin":[{"n":0,"txid":"1549415465c84fb519ffb92339ef80461427502c90d5d3ac5d01f27d824feabd","vout":1}],"vout":[{"valueSat":10000,"scriptPubKey":{"addresses":["1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr"]},"n":0},{"valueSat":3966838180,"scriptPubKey":{"addresses":["1Ao8Swc6vSosrjednQkNZeXEXVu1ZcxYZE"]},"n":1}],"time":1405573125} + + $('body').append(transaction.vout[0].valueSat) + + socket = io('ws://insight.bitpay.com') + socket.on('connect', -> + $('body').append('connected') + this.emit('subscribe', '1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr') + ) + + socket.on('1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr', (data) -> + $('body').append(JSON.stringify(data)) + ) + diff --git a/src/socket_test.js b/src/socket_test.js new file mode 100644 index 00000000..a029c016 --- /dev/null +++ b/src/socket_test.js @@ -0,0 +1,64 @@ +(function() { + var socket, transaction; + + transaction = { + "hash": {}, + "version": 1, + "lock_time": 0, + "ins": [ + { + "s": {}, + "q": 4294967295, + "o": {} + } + ], + "outs": [ + { + "v": {}, + "s": {} + }, { + "v": {}, + "s": {} + } + ], + "_buffer": {}, + "txid": "8500a0893a2d83a17819673884ade21bbef07d8c92bfe51682e45873cc2d3720", + "vin": [ + { + "n": 0, + "txid": "1549415465c84fb519ffb92339ef80461427502c90d5d3ac5d01f27d824feabd", + "vout": 1 + } + ], + "vout": [ + { + "valueSat": 10000, + "scriptPubKey": { + "addresses": ["1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr"] + }, + "n": 0 + }, { + "valueSat": 3966838180, + "scriptPubKey": { + "addresses": ["1Ao8Swc6vSosrjednQkNZeXEXVu1ZcxYZE"] + }, + "n": 1 + } + ], + "time": 1405573125 + }; + + $('body').append(transaction.vout[0].valueSat); + + socket = io('ws://insight.bitpay.com'); + + socket.on('connect', function() { + $('body').append('connected'); + return this.emit('subscribe', '1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr'); + }); + + socket.on('1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr', function(data) { + return $('body').append(JSON.stringify(data)); + }); + +}).call(this); -- cgit v1.2.3