(function() {
var ADDRESS_FAIL, API_URL, EXCHANGE_FAIL, SOCKET_FAIL, TEST_URL, clear, fail, fetchExchangeRate, g, getAddress, listen, logTransaction, multiplier, setup, updateTotal;
EXCHANGE_FAIL = "Problem fetching exchange rate";
SOCKET_FAIL = "Problem connecting to payment server, notifications may not appear";
ADDRESS_FAIL = "Invalid address";
API_URL = "wss://socket.blockcypher.com/v1/btc/main";
TEST_URL = "wss://socket.blockcypher.com/v1/btc/test3";
g = typeof exports !== "undefined" && exports !== null ? exports : this;
g.errors = [];
g.amount_requested = 0;
g.amount = 0..toFixed(2);
g.tip = 1;
g.transactions = [];
$(function() {
$.ajax({
url: $('#user').val() + '.json',
dataType: 'json',
success: function(data) {
g.user = data;
return setup();
}
});
$('button').click(function(e) {
return e.preventDefault();
});
$('.numpad .btn').off('click').click(function(e) {
var m, n;
e.preventDefault();
m = $(this).html();
n = parseFloat($('.amount').html());
if (m === 'C') {
g.amount = 0..toFixed(2);
updateTotal();
return;
}
if (n > 10000000) {
return;
}
if (m === '00') {
n = 100 * n;
} else {
n = 10 * n + parseFloat(m) / 100;
}
g.amount = n.toFixed(2);
return updateTotal();
});
$('.numpad .btn:last').off('click').click(function(e) {
e.preventDefault();
g.amount = (Math.floor(100 * (parseFloat($('.amount').html()) / 10)) / 100).toFixed(2);
return updateTotal();
});
$('.tippad .btn').off('click').click(function(e) {
var text, value;
e.preventDefault();
text = $(this).html();
if (text === 'No Tip') {
value = 0;
} else {
value = text.slice(1, -1);
}
$(this).addClass('active');
$(this).siblings().removeClass('active');
g.tip = 1 + (parseFloat(value) / 100);
return updateTotal();
});
$('#received').click(function() {
return window.location = "/" + g.user.username + "/report";
});
return $('#slide').click(function() {
$('#controls').slideToggle();
return $(this).find('i').toggleClass('fa-sort-up').toggleClass('fa-sort-down');
});
});
setup = function() {
var base, base1, base2, base3, base4, ext, src;
(base = g.user).address || (base.address = '');
(base1 = g.user).commission || (base1.commission = 0);
(base2 = g.user).currency || (base2.currency = 'CAD');
(base3 = g.user).symbol || (base3.symbol = 'quadrigacx');
(base4 = g.user).unit || (base4.unit = 'BTC');
if (g.user.title) {
$('#title').html("" + g.user.title + "").show();
}
if (g.user.logo) {
ext = g.user.logo.substr(g.user.logo.length - 3);
src = "/img/logos/" + g.user.username + "." + ext;
$('#logo').attr('src', src).show();
}
getAddress();
if (g.user.address[0] === 'm') {
API_URL = TEST_URL;
}
$('.symbol').html(g.user.currency);
$('.currency').html(g.user.currency);
$('.unit').html(g.user.unit);
$('#received').hide();
fetchExchangeRate();
return listen();
};
fetchExchangeRate = function() {
$.ajax({
url: "ticker?currency=" + g.user.currency + "&symbol=" + g.user.symbol + "&type=bid",
success: function(exchange) {
if (exchange != null) {
clear(EXCHANGE_FAIL);
} else {
fail(EXCHANGE_FAIL);
return;
}
g.exchange = (exchange - exchange * g.user.commission * 0.01).toFixed(2);
$('#exchange').html(g.exchange);
updateTotal();
if (!g.setupComplete) {
return g.setupComplete = true;
}
},
error: function() {
return fail(EXCHANGE_FAIL);
}
});
return setTimeout(fetchExchangeRate, 900000);
};
updateTotal = function() {
var precision, size, subtotal, time, total;
precision = 9 - multiplier().toString().length;
subtotal = parseFloat(g.amount * g.tip).toFixed(2);
total = (subtotal * multiplier() / g.exchange).toFixed(precision);
g.amount_requested = (subtotal / g.exchange).toFixed(8);
if (!$.isNumeric(total)) {
total = '';
}
$('#received').hide();
$('#payment').fadeIn('slow');
$('.tip').html((subtotal - g.amount).toFixed(2));
$('.subtotal').html(subtotal.toString());
$('.amount').html(g.amount);
$('.exchange').html(g.exchange);
$('.symbol').html(g.user.symbol);
if (g.user.commission < 0) {
$('.commission').html("+" + (Math.abs(g.user.commission)) + "%");
}
$('#total').html(total.toString());
size = 300;
$('#qr').css('height', size);
time = 0;
if (g.timeout) {
time = 10;
}
clearTimeout(g.timeout);
return g.timeout = setTimeout(function() {
$('#qr').html('');
return new QRCode('qr', {
text: "bitcoin:" + g.user.address + "?amount=" + (g.amount_requested.toString()),
width: size,
height: size
});
}, time);
};
listen = function() {
g.attempts++;
if (g.blockchain && g.blockchain.readyState === 1) {
return setTimeout(listen, 12000);
} else {
if (g.attempts > 3) {
fail(SOCKET_FAIL);
}
g.blockchain = new WebSocket(API_URL);
g.blockchain.onopen = function() {
if (g.blockchain.readyState === 1) {
g.attempts = 0;
clear(SOCKET_FAIL);
return g.blockchain.send('{"event":"unconfirmed-tx", "address":"' + g.user.address + '"}');
} else {
return setTimeout(g.blockchain.onopen, 12000 * g.attempts);
}
};
g.blockchain.onerror = function() {
fail(SOCKET_FAIL);
g.blockchain.close();
delete g.blockchain;
return listen();
};
g.blockchain.onclose = function() {
delete g.blockchain;
return listen();
};
return g.blockchain.onmessage = function(e) {
var amount, j, len, output, ref, tx;
tx = JSON.parse(e.data);
amount = 0;
if (tx.hash === g.last_seen) {
return;
}
g.last_seen = tx.hash;
ref = tx.outputs;
for (j = 0, len = ref.length; j < len; j++) {
output = ref[j];
if (output.addresses[0] === g.user.address) {
amount += output.value / 100000000;
}
}
return logTransaction(tx.hash, amount);
};
}
};
logTransaction = function(txid, amount) {
if ($('#received').is(":hidden") && amount >= g.amount_requested) {
$('#payment').hide();
$('#received').fadeIn('slow');
$('#success')[0].play();
g.user.index++;
if (g.transactions.indexOf(txid) === -1) {
g.transactions.push(txid);
$.post("/" + g.user.username + "/transactions", {
txid: txid,
address: g.user.address,
date: moment().format("YYYY-MM-DD HH:mm:ss"),
received: amount,
exchange: g.exchange,
tip: g.tip
});
}
return getAddress();
}
};
getAddress = function() {
var child, error, master;
try {
bitcoin.address.fromBase58Check(g.user.pubkey);
g.user.address = g.user.pubkey;
} catch (error) {
master = bitcoin.HDNode.fromBase58(g.user.pubkey);
child = master.derive(0).derive(g.user.index);
g.user.address = child.getAddress().toString();
if (g.blockchain) {
g.blockchain.close();
}
listen();
}
return $('#address').html("" + g.user.address + "");
};
fail = function(msg) {
g.errors.push(msg);
g.errors = g.errors.uniq();
return $('#error').show().html(g.errors.toString());
};
clear = function(msg) {
var i;
i = g.errors.indexOf(msg);
if (i >= 0) {
g.errors.splice(i, 1);
}
if (g.errors.length > 0) {
return $('#error').show().html(g.errors.toString());
} else {
$('#error').hide();
return $('#calculator').fadeIn('slow');
}
};
Array.prototype.uniq = function() {
var j, key, output, ref, results, value;
output = {};
for (key = j = 0, ref = this.length; 0 <= ref ? j < ref : j > ref; key = 0 <= ref ? ++j : --j) {
output[this[key]] = this[key];
}
results = [];
for (key in output) {
value = output[key];
results.push(value);
}
return results;
};
multiplier = function() {
switch (g.user.unit) {
case 'BTC':
return 1;
case 'mBTC':
return 1000;
case 'µBTC':
return 1000000;
case 'bits':
return 1000000;
case 'satoshis':
return 100000000;
}
};
}).call(this);