aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app.js29
-rw-r--r--package.json2
-rw-r--r--public/js/wallet.coffee43
-rw-r--r--public/js/wallet.js47
-rw-r--r--src/app.coffee20
-rw-r--r--views/users/wallet.html3
6 files changed, 82 insertions, 62 deletions
diff --git a/app.js b/app.js
index 33098305..a84e945a 100644
--- a/app.js
+++ b/app.js
@@ -1,5 +1,6 @@
(function() {
- var RedisStore, app, authorize, bodyParser, cache, config, cookieParser, express, fetchRates, fs, passport, path, request, session, sessionStore, sessions, transactions, users;
+ var RedisStore, app, authorize, bodyParser, cache, config, cookieParser, express, fetchRates, fs, passport, path, proxy, proxyContext, proxyMiddleware, proxyOptions, request, session, sessionStore, sessions, transactions, users,
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
request = require('request');
@@ -17,6 +18,8 @@
fs = require('fs');
+ proxyMiddleware = require('http-proxy-middleware');
+
sessions = require("./routes/sessions")(passport);
transactions = require("./routes/transactions");
@@ -31,6 +34,23 @@
ttl: 172800
});
+ proxyContext = '/blockcypher';
+
+ proxyOptions = {
+ target: 'https://api.blockcypher.com',
+ changeOrigin: true,
+ pathRewrite: {
+ '^/blockcypher/': '/'
+ },
+ onProxyReq: function(proxyReq, req, res) {
+ var symbol;
+ symbol = __indexOf.call(proxyReq.path, '?') >= 0 ? '&' : '?';
+ return proxyReq.path += "" + symbol + "token=" + config.blockcypher_token;
+ }
+ };
+
+ proxy = proxyMiddleware(proxyContext, proxyOptions);
+
app = express();
app.enable('trust proxy');
@@ -43,6 +63,8 @@
app.use(express["static"](__dirname + '/public'));
+ app.use(proxy);
+
app.use(bodyParser.urlencoded({
extended: true
}));
@@ -137,11 +159,6 @@
});
});
- app.get('/token', cache, function(req, res) {
- res.write(config.blockcypher_token);
- return res.end();
- });
-
app.get('/tips', cache, function(req, res) {
return res.render('tips', {
notice: true,
diff --git a/package.json b/package.json
index d7ec101f..ace1ba6b 100644
--- a/package.json
+++ b/package.json
@@ -19,10 +19,12 @@
"express": "4.6.1",
"express-session": "^1.6.5",
"hogan-express": "0.5.2",
+ "http-proxy-middleware": "^0.9.0",
"jquery": "^2.1.4",
"jquery-ui": "^1.10.5",
"less": "1.7.3",
"moment": "^2.10.6",
+ "node-http-proxy": "^0.2.3",
"nodemailer": "~1.2.1",
"passport": "0.2.0",
"passport-local": "1.0.0",
diff --git a/public/js/wallet.coffee b/public/js/wallet.coffee
index ebe6826a..cfaac22b 100644
--- a/public/js/wallet.coffee
+++ b/public/js/wallet.coffee
@@ -1,15 +1,17 @@
g = exports ? this
g.proceed = false
-g.api = 'https://api.blockcypher.com/v1/btc/main'
+g.api = '/blockcypher/v1/btc/main'
validators =
address: (e) ->
+ return true if e.val() is ''
try
bitcoin.address.fromBase58Check(e.val())
catch
return false
password: (e) ->
+ return true if e.val() is ''
g.master = null
try
g.master = bitcoin.HDNode.fromBase58(CryptoJS.AES.decrypt($('#privkey').val(), e.val()).toString(CryptoJS.enc.Utf8))
@@ -17,13 +19,13 @@ validators =
catch
return false
-
errors =
- address: 'Invalid address'
- password: 'Wrong password'
+ address: 'Invalid address.'
+ password: 'Wrong password.'
$(->
- getToken()
+ getUser()
+
$('form').validator(custom: validators, errors: errors)
$('button[data-toggle=tooltip]').tooltip(trigger: 'hover')
@@ -39,7 +41,7 @@ $(->
$.post("/#{g.user.username}", $('#keys form').serializeObject(), ->
$.ajax(
- url: "#{g.api}/wallets/hd/#{g.user.username}?token=#{g.token}"
+ url: "#{g.api}/wallets/hd/#{g.user.username}"
type: 'DELETE'
).done(->
setTimeout(->
@@ -48,8 +50,8 @@ $(->
extended_public_key: $('#pubkey').val()
subchain_indexes: [0,1]
- $.post("#{g.api}/wallets/hd?token=#{g.token}", JSON.stringify(data)).always(->
- $.post("#{g.api}/wallets/hd/#{g.user.username}/addresses/derive?token=#{g.token}").always(->
+ $.post("#{g.api}/wallets/hd", JSON.stringify(data)).always(->
+ $.post("#{g.api}/wallets/hd/#{g.user.username}/addresses/derive").always(->
getBalance()
)
)
@@ -79,11 +81,11 @@ $(->
$('#max').click(->
if $('#currency_toggle').html() is g.user.unit
- $('#amount').val(g.balance)
+ $('#amount').val(g.balance).blur()
else
g.amount = parseFloat(g.balance).toFixed(precision())
amount = (g.balance / multiplier() * g.exchange).toFixed(2)
- $('#amount').val(amount)
+ $('#amount').val(amount).blur()
)
$('#amount').change(->
@@ -141,13 +143,6 @@ $(->
$('.close').on('click', -> $(this).closest('.alert').fadeOut())
)
-
-getToken = ->
- $.get("/token", (token) ->
- g.token = token
- getUser()
- )
-
getUser = ->
$.getJSON("/#{$('#username').val()}.json", (user) ->
g.user = user
@@ -168,7 +163,7 @@ getExchangeRate = ->
)
createWallet = ->
- $.get("#{g.api}/wallets?token=#{g.token}", (data) ->
+ $.get("#{g.api}/wallets", (data) ->
if g.user.username in data.wallet_names
getBalance()
else
@@ -178,7 +173,7 @@ createWallet = ->
extended_public_key: g.user.pubkey
subchain_indexes: [0,1]
- $.post("#{g.api}/wallets/hd?token=#{g.token}", JSON.stringify(data)).always(getBalance)
+ $.post("#{g.api}/wallets/hd", JSON.stringify(data)).always(getBalance)
else
# TODO implement this properly
$('#balance').html(99)
@@ -187,7 +182,7 @@ createWallet = ->
getBalance = ->
- $.get("#{g.api}/addrs/#{g.user.username}/balance?token=#{g.token}&omitWalletAddresses=true", (data) ->
+ $.get("#{g.api}/addrs/#{g.user.username}/balance?omitWalletAddresses=true", (data) ->
balance = data.final_balance
g.balance = balance.toBTC()
fiat = balance.toFiat()
@@ -227,7 +222,7 @@ sendTransaction = ->
outputs: [{addresses: [$('#recipient').val()], value: 1}]
preference: $('#priority').val()
- $.post("#{g.api}/txs/new?token=#{g.token}", JSON.stringify(params)).done((data) ->
+ $.post("#{g.api}/txs/new", JSON.stringify(params)).done((data) ->
if $('#currency_toggle').html() is g.user.unit
amount = $('#amount').val()
else
@@ -240,7 +235,7 @@ sendTransaction = ->
if value > parseFloat(g.balance).toSatoshis() - params.fees
params.outputs[0].value -= params.fees
- $.post("#{g.api}/txs/new?token=#{g.token}", JSON.stringify(params)).done((data) ->
+ $.post("#{g.api}/txs/new", JSON.stringify(params)).done((data) ->
data.pubkeys = []
data.signatures = data.tosign.map((tosign, i) ->
path = data.tx.inputs[i].hd_path.split('/')
@@ -265,14 +260,14 @@ sendTransaction = ->
dialog.getModalBody().html($('.dialog').html())
dialog.getModal().find('.btn-primary').click(->
- $.post("#{g.api}/txs/send?token=#{g.token}", JSON.stringify(g.data)).then((finaltx) ->
+ $.post("#{g.api}/txs/send", JSON.stringify(g.data)).then((finaltx) ->
$('#transaction_sent').fadeIn()
balance = g.balance.toSatoshis() - finaltx.tx.outputs[0].value - finaltx.tx.fees
g.balance = balance.toBTC()
fiat = balance.toFiat()
$('#balance').html(g.balance)
$('#fiat').html("#{fiat} #{g.user.currency}")
- $('#blockchain').off('click').on('click', -> window.open('https://live.blockcypher.com/btc/main/' + finaltx.tx.hash, '_blank'))
+ $('#blockchain').off('click').on('click', -> window.open('https://live.blockcypher.com/btc/main/tx/' + finaltx.tx.hash, '_blank'))
dialog.close()
)
)
diff --git a/public/js/wallet.js b/public/js/wallet.js
index d83b764d..cadd6db3 100644
--- a/public/js/wallet.js
+++ b/public/js/wallet.js
@@ -1,16 +1,19 @@
;(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0](function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){
(function(){(function() {
- var check_address, convertedAmount, createWallet, displayErrors, errors, g, getBalance, getExchangeRate, getToken, getUser, isBip32, multiplier, precision, sendTransaction, validators,
+ var check_address, convertedAmount, createWallet, displayErrors, errors, g, getBalance, getExchangeRate, getUser, isBip32, multiplier, precision, sendTransaction, validators,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
g = typeof exports !== "undefined" && exports !== null ? exports : this;
g.proceed = false;
- g.api = 'https://api.blockcypher.com/v1/btc/main';
+ g.api = '/blockcypher/v1/btc/main';
validators = {
address: function(e) {
+ if (e.val() === '') {
+ return true;
+ }
try {
return bitcoin.address.fromBase58Check(e.val());
} catch (_error) {
@@ -18,6 +21,9 @@
}
},
password: function(e) {
+ if (e.val() === '') {
+ return true;
+ }
g.master = null;
try {
g.master = bitcoin.HDNode.fromBase58(CryptoJS.AES.decrypt($('#privkey').val(), e.val()).toString(CryptoJS.enc.Utf8));
@@ -29,12 +35,12 @@
};
errors = {
- address: 'Invalid address',
- password: 'Wrong password'
+ address: 'Invalid address.',
+ password: 'Wrong password.'
};
$(function() {
- getToken();
+ getUser();
$('form').validator({
custom: validators,
errors: errors
@@ -52,7 +58,7 @@
$('#keys_updated').fadeIn();
$.post("/" + g.user.username, $('#keys form').serializeObject(), function() {
return $.ajax({
- url: "" + g.api + "/wallets/hd/" + g.user.username + "?token=" + g.token,
+ url: "" + g.api + "/wallets/hd/" + g.user.username,
type: 'DELETE'
}).done(function() {
return setTimeout(function() {
@@ -62,8 +68,8 @@
extended_public_key: $('#pubkey').val(),
subchain_indexes: [0, 1]
};
- return $.post("" + g.api + "/wallets/hd?token=" + g.token, JSON.stringify(data)).always(function() {
- return $.post("" + g.api + "/wallets/hd/" + g.user.username + "/addresses/derive?token=" + g.token).always(function() {
+ return $.post("" + g.api + "/wallets/hd", JSON.stringify(data)).always(function() {
+ return $.post("" + g.api + "/wallets/hd/" + g.user.username + "/addresses/derive").always(function() {
return getBalance();
});
});
@@ -92,11 +98,11 @@
$('#max').click(function() {
var amount;
if ($('#currency_toggle').html() === g.user.unit) {
- return $('#amount').val(g.balance);
+ return $('#amount').val(g.balance).blur();
} else {
g.amount = parseFloat(g.balance).toFixed(precision());
amount = (g.balance / multiplier() * g.exchange).toFixed(2);
- return $('#amount').val(amount);
+ return $('#amount').val(amount).blur();
}
});
$('#amount').change(function() {
@@ -152,13 +158,6 @@
});
});
- getToken = function() {
- return $.get("/token", function(token) {
- g.token = token;
- return getUser();
- });
- };
-
getUser = function() {
return $.getJSON("/" + ($('#username').val()) + ".json", function(user) {
g.user = user;
@@ -180,7 +179,7 @@
};
createWallet = function() {
- return $.get("" + g.api + "/wallets?token=" + g.token, function(data) {
+ return $.get("" + g.api + "/wallets", function(data) {
var _ref;
if (_ref = g.user.username, __indexOf.call(data.wallet_names, _ref) >= 0) {
return getBalance();
@@ -191,7 +190,7 @@
extended_public_key: g.user.pubkey,
subchain_indexes: [0, 1]
};
- return $.post("" + g.api + "/wallets/hd?token=" + g.token, JSON.stringify(data)).always(getBalance);
+ return $.post("" + g.api + "/wallets/hd", JSON.stringify(data)).always(getBalance);
} else {
$('#balance').html(99);
return $('#amount').val(99);
@@ -201,7 +200,7 @@
};
getBalance = function() {
- return $.get("" + g.api + "/addrs/" + g.user.username + "/balance?token=" + g.token + "&omitWalletAddresses=true", function(data) {
+ return $.get("" + g.api + "/addrs/" + g.user.username + "/balance?omitWalletAddresses=true", function(data) {
var balance, fiat;
balance = data.final_balance;
g.balance = balance.toBTC();
@@ -257,7 +256,7 @@
],
preference: $('#priority').val()
};
- return $.post("" + g.api + "/txs/new?token=" + g.token, JSON.stringify(params)).done(function(data) {
+ return $.post("" + g.api + "/txs/new", JSON.stringify(params)).done(function(data) {
var amount, value;
if ($('#currency_toggle').html() === g.user.unit) {
amount = $('#amount').val();
@@ -270,7 +269,7 @@
if (value > parseFloat(g.balance).toSatoshis() - params.fees) {
params.outputs[0].value -= params.fees;
}
- return $.post("" + g.api + "/txs/new?token=" + g.token, JSON.stringify(params)).done(function(data) {
+ return $.post("" + g.api + "/txs/new", JSON.stringify(params)).done(function(data) {
var fee, total;
data.pubkeys = [];
data.signatures = data.tosign.map(function(tosign, i) {
@@ -293,7 +292,7 @@
$('.dialog .address').html(data.tx.outputs[0].addresses[0]);
dialog.getModalBody().html($('.dialog').html());
return dialog.getModal().find('.btn-primary').click(function() {
- return $.post("" + g.api + "/txs/send?token=" + g.token, JSON.stringify(g.data)).then(function(finaltx) {
+ return $.post("" + g.api + "/txs/send", JSON.stringify(g.data)).then(function(finaltx) {
var balance, fiat;
$('#transaction_sent').fadeIn();
balance = g.balance.toSatoshis() - finaltx.tx.outputs[0].value - finaltx.tx.fees;
@@ -302,7 +301,7 @@
$('#balance').html(g.balance);
$('#fiat').html("" + fiat + " " + g.user.currency);
$('#blockchain').off('click').on('click', function() {
- return window.open('https://live.blockcypher.com/btc/main/' + finaltx.tx.hash, '_blank');
+ return window.open('https://live.blockcypher.com/btc/main/tx/' + finaltx.tx.hash, '_blank');
});
return dialog.close();
});
diff --git a/src/app.coffee b/src/app.coffee
index df3c0433..fc1eee37 100644
--- a/src/app.coffee
+++ b/src/app.coffee
@@ -6,6 +6,7 @@ path = require('path')
passport = require('./passport')
config = require('./config')
fs = require('fs')
+proxyMiddleware = require('http-proxy-middleware')
sessions = require("./routes/sessions")(passport)
transactions = require("./routes/transactions")
@@ -15,12 +16,25 @@ session = require('express-session')
RedisStore = require('connect-redis')(session)
sessionStore = new RedisStore(require('./redis').host, ttl: 172800)
+proxyContext = '/blockcypher'
+proxyOptions =
+ target: 'https://api.blockcypher.com'
+ changeOrigin: true
+ pathRewrite:
+ '^/blockcypher/': '/'
+ onProxyReq: (proxyReq, req, res) ->
+ symbol = if '?' in proxyReq.path then '&' else '?'
+ proxyReq.path += "#{symbol}token=#{config.blockcypher_token}"
+
+proxy = proxyMiddleware(proxyContext, proxyOptions)
+
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(proxy)
app.use(bodyParser.urlencoded({ extended: true}))
app.use(bodyParser.json())
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
@@ -61,6 +75,7 @@ do fetchRates = ->
)
setTimeout(fetchRates, 120000)
+
app.get('/', cache, sessions.new)
app.get('/address', cache, (req, res) ->
@@ -91,11 +106,6 @@ app.get('/ticker', cache, (req, res) ->
)
)
-app.get('/token', cache, (req, res) ->
- res.write(config.blockcypher_token)
- res.end()
-)
-
app.get('/tips', cache, (req, res) ->
res.render('tips',
notice: true,
diff --git a/views/users/wallet.html b/views/users/wallet.html
index 4848eedd..7195f865 100644
--- a/views/users/wallet.html
+++ b/views/users/wallet.html
@@ -93,7 +93,6 @@
<label for="amount">To Address:</label>
<input type="text" id="recipient" name="recipient" class="form-control" data-address="true" required />
</div>
- <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
<div class="help-block with-errors"></div>
</div>
@@ -106,7 +105,6 @@
<option value="high">High</option>
</select>
</div>
- <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
</div>
<div class="form-group has-feedback">
@@ -114,7 +112,6 @@
<label for="password">Password:</label>
<input id="password" name="password" type="password" class="form-control" data-password="true" required />
</div>
- <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
<div class="help-block with-errors"></div>
</div>