diff options
| author | Adam Soltys <[email protected]> | 2017-01-21 18:56:05 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2017-01-21 18:56:05 -0800 |
| commit | c413e457579b68b7a92ab47cdd867202ee7bb47e (patch) | |
| tree | 4d84c4af06e936a54890468cc4351deabcd8c0f9 /static | |
| parent | 931f2262d9ef7f571fe87b176f6cd531b3579a68 (diff) | |
| download | coinos-server-c413e457579b68b7a92ab47cdd867202ee7bb47e.tar.gz coinos-server-c413e457579b68b7a92ab47cdd867202ee7bb47e.zip | |
Ditch coffeescript
Diffstat (limited to 'static')
| -rw-r--r-- | static/js/calculator.coffee | 268 | ||||
| -rw-r--r-- | static/js/generate_address.coffee | 74 | ||||
| -rw-r--r-- | static/js/index.coffee | 44 | ||||
| -rw-r--r-- | static/js/profile.coffee | 30 | ||||
| -rw-r--r-- | static/js/register.coffee | 53 | ||||
| -rw-r--r-- | static/js/setup.coffee | 65 | ||||
| -rw-r--r-- | static/js/setup.js | 4 | ||||
| -rw-r--r-- | static/js/signin.coffee | 6 | ||||
| -rw-r--r-- | static/js/wallet.coffee | 456 |
9 files changed, 2 insertions, 998 deletions
diff --git a/static/js/calculator.coffee b/static/js/calculator.coffee deleted file mode 100644 index 75192596..00000000 --- a/static/js/calculator.coffee +++ /dev/null @@ -1,268 +0,0 @@ -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 = exports ? this -g.errors = [] -g.amount_requested = 0 -g.amount = 0.toFixed(2) -g.tip = 1 -g.transactions = [] - -$(-> - $.ajax( - url: $('#user').val() + '.json', - dataType: 'json', - success: (data) -> - g.user = data - setup() - ) - - $('button').click((e) -> - e.preventDefault() - ) - - $('.numpad .btn').off('click').click((e) -> - e.preventDefault() - - m = $(this).html() - n = parseFloat($('.amount').html()) - - if m is 'C' - g.amount = 0.toFixed(2) - updateTotal() - return - - return if n > 10000000 - - if m is '00' - n = 100 * n - else - n = 10 * n + parseFloat(m) / 100 - - g.amount = n.toFixed(2) - - updateTotal() - ) - - $('.numpad .btn:last').off('click').click((e) -> - e.preventDefault() - - g.amount = (Math.floor(100 * (parseFloat($('.amount').html()) / 10)) / 100).toFixed(2) - updateTotal() - ) - - $('.tippad .btn').off('click').click((e) -> - e.preventDefault() - - text = $(this).html() - if text is 'No Tip' - value = 0 - else - value = text.slice(1, -1) - - $(this).addClass('active') - $(this).siblings().removeClass('active') - g.tip = 1 + (parseFloat(value)/100) - updateTotal() - ) - - $('#received').click(-> window.location = "/#{g.user.username}/report") - $('#slide').click(-> - $('#controls').slideToggle() - $(this).find('i').toggleClass('fa-sort-up').toggleClass('fa-sort-down') - ) -) - -setup = -> - g.user.address or= '' - g.user.commission or= 0 - g.user.currency or= 'CAD' - g.user.symbol or= 'quadrigacx' - g.user.unit or= 'BTC' - - if g.user.title - $('#title').html("<a href='/#{g.user.username}/edit'>#{g.user.title}</a>").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] is 'm' - API_URL = TEST_URL - - $('.symbol').html(g.user.currency) - $('.currency').html(g.user.currency) - $('.unit').html(g.user.unit) - - $('#received').hide() - - fetchExchangeRate() - listen() - -fetchExchangeRate = -> - $.ajax( - url: "ticker?currency=#{g.user.currency}&symbol=#{g.user.symbol}&type=bid", - success: (exchange) -> - if exchange? - clear(EXCHANGE_FAIL) - else - fail(EXCHANGE_FAIL) - return - - g.exchange = (exchange - exchange * g.user.commission * 0.01).toFixed(2) - $('#exchange').html(g.exchange) - updateTotal() - - unless g.setupComplete - g.setupComplete = true - - error: -> fail(EXCHANGE_FAIL) - ) - setTimeout(fetchExchangeRate, 900000) - -updateTotal = -> - 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) - - unless $.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) - g.timeout = setTimeout(-> - $('#qr').html('') - new QRCode('qr', - text: "bitcoin:#{g.user.address}?amount=#{g.amount_requested.toString()}" - width: size - height: size - ) - , time) - -listen = -> - g.attempts++ - if g.blockchain and g.blockchain.readyState is 1 - setTimeout(listen, 12000) - else - fail(SOCKET_FAIL) if g.attempts > 3 - g.blockchain = new WebSocket(API_URL) - - g.blockchain.onopen = -> - if g.blockchain.readyState is 1 - g.attempts = 0 - clear(SOCKET_FAIL) - g.blockchain.send('{"event":"unconfirmed-tx", "address":"' + g.user.address + '"}') - else - setTimeout(g.blockchain.onopen, 12000 * g.attempts) - - g.blockchain.onerror = -> - fail(SOCKET_FAIL) - g.blockchain.close() - delete g.blockchain - listen() - - g.blockchain.onclose = -> - delete g.blockchain - listen() - - g.blockchain.onmessage = (e) -> - tx = JSON.parse(e.data) - amount = 0 - - return if tx.hash == g.last_seen - g.last_seen = tx.hash - - for output in tx.outputs - if (output.addresses[0] == g.user.address) - amount += output.value / 100000000 - - logTransaction(tx.hash, amount) - -logTransaction = (txid, amount) -> - if $('#received').is(":hidden") and amount >= g.amount_requested - $('#payment').hide() - $('#received').fadeIn('slow') - $('#success')[0].play() - g.user.index++ - - if g.transactions.indexOf(txid) is -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 - ) - - getAddress() - -getAddress = -> - try - bitcoin.address.fromBase58Check(g.user.pubkey) - g.user.address = g.user.pubkey - catch - master = bitcoin.HDNode.fromBase58(g.user.pubkey) - child = master.derive(0).derive(g.user.index) - g.user.address = child.getAddress().toString() - g.blockchain.close() if g.blockchain - listen() - - $('#address').html("<a href='https://blockchain.info/address/#{g.user.address}'>#{g.user.address}</a>") - -fail = (msg) -> - g.errors.push(msg) - g.errors = g.errors.uniq() - $('#error').show().html(g.errors.toString()) - -clear = (msg) -> - i = g.errors.indexOf(msg) - g.errors.splice(i, 1) if i >= 0 - if (g.errors.length > 0) - $('#error').show().html(g.errors.toString()) - else - $('#error').hide() - $('#calculator').fadeIn('slow') - -Array::uniq = -> - output = {} - output[@[key]] = @[key] for key in [0...@length] - value for key, value of output - -multiplier = -> - switch g.user.unit - when 'BTC' then 1 - when 'mBTC' then 1000 - when 'µBTC' then 1000000 - when 'bits' then 1000000 - when 'satoshis' then 100000000 - - diff --git a/static/js/generate_address.coffee b/static/js/generate_address.coffee deleted file mode 100644 index face65ea..00000000 --- a/static/js/generate_address.coffee +++ /dev/null @@ -1,74 +0,0 @@ -g = this - -$(-> - genKey() - $('.regenerate').click(genKey) - - $('#encrypt').submit(-> - $('.form-control').blur() - if $('.has-error').length > 0 - $('.has-error').effect('shake', 500) - return false - - $('#modal').modal() - return false - ) - - $('#modal').on('shown.bs.modal', -> - bip38 = new Bip38 - g.enc_privkey = bip38.encrypt(g.privkey, $('#password').val(), g.pubkey) - $('#modal-body').html('Done!') - setTimeout( - -> $('#modal').modal('hide') - 1000 - ) - ) - - $('#modal').on('hidden.bs.modal', -> - if $('#password').val() == '' - g.enc_privkey = g.privkey - $('#status').html('') - else - $('#status').html('Encrypted') - - $('#privkey').html(g.enc_privkey) - $('#privqr').html('') - new QRCode('privqr', text: $('#privkey').html(), width: 260, height: 260) - ) - - $('.print').click(-> window.print()) - $('#password').pwstrength(showVerdicts: false) - $('#password').blur(-> - $('#confirm').blur() - $(this).parent().next('.alert').remove() - - if $('.progress-bar-success').length > 0 - $(this).parent().removeClass('has-error') - else - $(this).parent().addClass('has-error') - ) - $('#confirm').blur(-> - if $('#password').val() == $('#confirm').val() - $('#confirm').parent().removeClass('has-error') - else - $('#confirm').parent().addClass('has-error') - ) -) - -genKey = -> - $('#password').focus() - key = bitcoin.ECKey.makeRandom(false) - g.privkey = key.toWIF() - g.pubkey = key.pub.getAddress().toString() - - $('#pubkey').html(g.pubkey) - $('#privkey').html(g.privkey) - - $('#pubqr, #privqr, #status').html('') - $('#password, #confirm').val('').keyup().parent().removeClass('has-error') - - new QRCode('pubqr', text: $('#pubkey').html(), width: 260, height: 260) - new QRCode('privqr', text: $('#privkey').html(), width: 260, height: 260) - - - diff --git a/static/js/index.coffee b/static/js/index.coffee deleted file mode 100644 index 090abbe2..00000000 --- a/static/js/index.coffee +++ /dev/null @@ -1,44 +0,0 @@ -#= require js/jquery-1.8.2.min.js -#= require js/bootstrap.min.js - -g = exports ? this - -$(-> - fetchExchangeRate('ask') - fetchExchangeRate('bid') - - $('#username').blur(-> - $.get( - "/#{$(this).val()}/exists", - username: $(this).val(), - (data) -> - if data is "true" - $('#username').prev().css('color', 'red').html('Username (taken)') - g.preventSubmit = true - else - $('#username').prev().css('color', 'black').html('Username') - g.preventSubmit = false - ) - ) - - $('#signup').submit(-> - return false if g.preventSubmit - return true - ) -) - -fetchExchangeRate = (type) -> - commission = 0.015 - commission *= -1 if type is 'bid' - - $.ajax( - url: "/ticker?symbol=virtexCAD&type=#{type}&amount=100", - success: (exchange) -> - if not exchange? - exchange = '??' - - exchange = exchange - exchange * commission - $("##{type}").html(exchange.toFixed(2)) - error: -> - $("##{type}").html('??') - ) diff --git a/static/js/profile.coffee b/static/js/profile.coffee deleted file mode 100644 index a894f275..00000000 --- a/static/js/profile.coffee +++ /dev/null @@ -1,30 +0,0 @@ -g = exports ? this -g.proceed = false - -$(-> - $('[data-toggle=popover]').popover() - $('#title').focus() - - user = $('#username').val() - $.getJSON("/#{user}.json", (data) -> - $('#email').val(data.email) - $('#phone').val(data.phone) - $('#profile').fadeIn() - ) - - $('#confirm').blur(-> - $('#confirm_error').remove() - if $('#password').val() != $('#confirm').val() - $('#password, #confirm').parent().addClass('has-error') - $('#confirm').parent().after('<div id="confirm_error" class="alert alert-danger">Passwords don\'t match</div>') - else - $('#password, #confirm').parent().removeClass('has-error') - ) - - $('#profile').submit(-> - $('#profile .form-control').blur() - if $('#profile .has-error').length > 0 - $('#profile .has-error').effect('shake', 500) - return false - ) -) diff --git a/static/js/register.coffee b/static/js/register.coffee deleted file mode 100644 index 98842328..00000000 --- a/static/js/register.coffee +++ /dev/null @@ -1,53 +0,0 @@ -g = this - -$(-> - $('#username').focus() - - $('#username').blur(-> - $(this).parent().next('.alert').remove() - - if /^[a-z]+$/.test($(this).val()) - $(this).parent().removeClass('has-error') - else - $(this).parent().addClass('has-error') - $(this).parent().after('<div class="alert alert-danger">Username must be lowercase</div>') - ) - - $('#password').blur(-> - $('#confirm').blur() - $(this).parent().next('.alert').remove() - ) - - $('#confirm').blur(-> - return if $(this).val() == '' - $(this).parent().next('.alert').remove() - - if $('#password').val() == $('#confirm').val() - $('#confirm').parent().removeClass('has-error') - else - $('#confirm').parent().addClass('has-error') - $('#confirm').parent().after('<div class="alert alert-danger">Passwords don\'t match</div>') - ) - - $('#email').blur(-> - return if $(this).val() == '' - $(this).parent().next('.alert').remove() - if validateEmail($(this).val()) - $(this).parent().removeClass('has-error') - else - $(this).parent().addClass('has-error') - $(this).parent().after('<div class="alert alert-danger">Invalid email</div>') - ) - - $('#register').submit(-> - $('.form-control').blur() - if $('.has-error').length > 0 - $('.has-error').effect('shake', 500) - return false - else - mnemonic = bip39.generateMnemonic() - key = bitcoin.HDNode.fromSeedBuffer(bip39.mnemonicToSeed(mnemonic)).deriveHardened(44).deriveHardened(0) - $('#pubkey').val(key.neutered().toString()) - $('#privkey').val(CryptoJS.AES.encrypt(key.toString(), $('#password').val()).toString()) - ) -) diff --git a/static/js/setup.coffee b/static/js/setup.coffee deleted file mode 100644 index d796c897..00000000 --- a/static/js/setup.coffee +++ /dev/null @@ -1,65 +0,0 @@ -g = exports ? this -g.proceed = false - -$(-> - $('#encryption-password').pwstrength(showVerdicts: false) - - $.getJSON("/js/rates.json", (data) -> - currencies = Object.keys(data) - currencies = currencies.sort() - currencies.pop() - - $.each(currencies, (i, v) -> - $('#currency').append("<option value='#{v}'>#{v}</option>") - ) - $("#currency option[value='CAD']").attr('selected', 'selected') - - $('#currency').change(-> - currency = $(this).val() - return unless currency - - $('#symbol option').remove() - symbols = Object.keys(data[currency]) - $.each(symbols, (i, v) -> - return if v == 'localbitcoins' - $('#symbol').append("<option value='#{v}'>#{v}</option>") - ) - - switch currency - when 'CAD' - $("#symbol option[value='quadrigacx']").attr('selected', 'selected') - when 'USD' - $("#symbol option[value='bitstamp']").attr('selected', 'selected') - ) - - user = $('#username').val() - $.getJSON("/#{user}.json", (data) -> - data.commission ?= 0 - data.unit ?= 'BTC' - $('#email').val(data.email) - $('#title').val(data.title) - $('#logo').val(data.logo) - $('#address').val(data.address) - $('#commission').val(data.commission) - $('#unit').val(data.unit) - $("#currency option[value='#{data.currency}']").attr('selected', 'selected') - $('#currency').change() - $("#symbol option[value='#{data.symbol}']").attr('selected', 'selected') - $('#setup').fadeIn() - $('#title').focus() - ) - ) - - units = ['BTC', 'mBTC', 'µBTC', 'bits', 'satoshis'] - $.each(units, (i, v) -> - $('#unit').append("<option value='#{v}'>#{v}</option>") - ) - - $('#setup').submit(-> - $('#setup .form-control').blur() - if $('#setup .has-error').length > 0 - $('#setup .has-error').effect('shake', 500) - return false - ) -) - diff --git a/static/js/setup.js b/static/js/setup.js index e96bd00d..63b9e291 100644 --- a/static/js/setup.js +++ b/static/js/setup.js @@ -11,7 +11,7 @@ $('#encryption-password').pwstrength({ showVerdicts: false }); - $.getJSON("/js/rates.json", function(data) { + $.getJSON("/rates", function(data) { var currencies, user; currencies = Object.keys(data); currencies = currencies.sort(); @@ -79,4 +79,4 @@ },{}]},{},[1]) -;
\ No newline at end of file +; diff --git a/static/js/signin.coffee b/static/js/signin.coffee deleted file mode 100644 index df7dbb39..00000000 --- a/static/js/signin.coffee +++ /dev/null @@ -1,6 +0,0 @@ -$(-> - $('#register').click(-> - window.location.href = '/register' - $(this).preventDefault() - ) -) diff --git a/static/js/wallet.coffee b/static/js/wallet.coffee deleted file mode 100644 index 1beefd23..00000000 --- a/static/js/wallet.coffee +++ /dev/null @@ -1,456 +0,0 @@ -g = exports ? this -g.proceed = false -g.api = '/blockcypher/v1/btc/main' - -validators = - address: (e) -> - return true if e.val() is '' - try - bitcoin.address.fromBase58Check(e.val()) - catch - return false - - key: (e) -> - $('#keytype').val() != 'unknown' - -errors = - address: 'Invalid address.' - key: 'Could not detect key type.' - -$(-> - getUser() - - $('#types').attr('data-content', """ - Bitcoin Address (starts with 1 or 3)<br /> - Private Key (starts with 5 or L)<br /> - HD Wallet pubkey (starts with xpub)<br /> - HD Wallet private key (starts with xprv)<br /> - AES Encrypted Private Key (starts with U)<br /> - BIP38 Encrypted Private Key (starts with 6)<br /> - BIP39 Mnemonic (series of 12-24 english words) - """) - .popover(html: true) - .on("show.bs.popover", -> $(this).data("bs.popover").tip().css(minWidth: "400px")) - - $('form').validator(custom: validators, errors: errors, delay: 1200) - $('[data-toggle=tooltip]').tooltip(trigger: 'hover') - - $('#key').keyup(-> - val = $(this).val() - - $('#keytype').val('unknown') - - switch val[0] - when '1' - try - bitcoin.address.fromBase58Check(val) - $('#keytype').val('address') - when 'm' - try - bitcoin.address.fromBase58Check(val) - $('#keytype').val('address') - when '5', \ - 'L', \ - 'K' - try - bitcoin.ECPair.fromWIF(val) - $('#keytype').val('wif') - when 'U' - try - if CryptoJS.AES.decrypt(val, g.password).toString(CryptoJS.enc.Utf8) - $('#keytype').val('aes') - when '6' - if bip38().verify(val) - $('#keytype').val('bip38') - when 'x' - if $(this).val()[3] is 'b' - try - bitcoin.HDNode.fromBase58(val) - $('#keytype').val('xpub') - else - try - bitcoin.HDNode.fromBase58(val) - $('#keytype').val('xprv') - else - if val.split(' ').length in [12, 15, 18, 21, 24] and bip39.validateMnemonic(val) - $('#keytype').val('bip39') - ) - - $('#save').click(-> - $('.form-control').blur() - if $('#keys .has-error').length > 0 - $('#keys .has-error').effect('shake', 500) - return - - key = $('#key').val() - proceed = true - - switch $('#keytype').val() - when 'address' - $('#pubkey').val(key) - $('#privkey').val('') - when 'wif' - pubkey = bitcoin.ECPair.fromWIF(key).getAddress() - privkey = CryptoJS.AES.encrypt(key, g.password) - $('#pubkey').val(pubkey) - $('#privkey').val(privkey) - when 'aes' - try - pubkey = bitcoin.HDNode.fromBase58(CryptoJS.AES.decrypt(key, g.password).toString(CryptoJS.enc.Utf8)).neutered().toString() - $('#pubkey').val(pubkey) - $('#privkey').val(key) - catch - try - pubkey = bitcoin.ECPair.fromWIF(CryptoJS.AES.decrypt(key, g.password).toString(CryptoJS.enc.Utf8)).getAddress() - $('#pubkey').val(pubkey) - $('#privkey').val(key) - catch - proceed = false - when 'bip38' - wif = bip38().decrypt(key, g.password) - pubkey = bitcoin.ECPair.fromWIF(wif).getAddress() - privkey = CryptoJS.AES.encrypt(wif, g.password) - $('#pubkey').val(pubkey) - $('#privkey, #key').val(privkey) - when 'xpub' - $('#pubkey').val(key) - $('#privkey').val('') - when 'xprv' - pubkey = bitcoin.HDNode.fromBase58(key).neutered().toString() - privkey = CryptoJS.AES.encrypt(key, g.password) - $('#pubkey').val(pubkey) - $('#privkey').val(privkey) - when 'bip39' - master = bitcoin.HDNode.fromSeedBuffer(bip39.mnemonicToSeed(key)).deriveHardened(44).deriveHardened(0) - pubkey = master.neutered().toString() - privkey = CryptoJS.AES.encrypt(master.toString(), g.password) - $('#pubkey').val(pubkey) - $('#privkey').val(privkey) - - if proceed - updateUser() - $('#keys').hide() - $('#keys_updated').fadeIn() - $('#balances').hide() - $('#fetching').show() - ) - - - $('#withdrawal form input[type=button]').click(sendTransaction) - - $('#currency_toggle').click(-> - if $(this).html() is g.user.unit - $(this).html(g.user.currency) - g.amount = parseFloat($('#amount').val()).toFixed(precision()) - amount = (g.amount * g.exchange / multiplier()).toFixed(2) - $('#amount').val(amount) - $('#amount').attr('step', 0.01) - $('#amount').attr('max', (g.balance * g.exchange / multiplier()).toFixed(2)) - else - $(this).html(g.user.unit) - $('#amount').val(convertedAmount()) - $('#amount').attr('step', 0.00000001 * multiplier()) - $('#amount').attr('max', g.balance) - ) - - $('#max').click(-> - if $('#currency_toggle').html() is g.user.unit - $('#amount').val(g.balance).blur() - else - g.amount = parseFloat(g.balance).toFixed(precision()) - amount = (g.balance / multiplier() * g.exchange).toFixed(2) - $('#amount').val(amount).blur() - ) - - $('#amount').change(-> - if $('#currency_toggle').html() is g.user.unit - $(this).val(parseFloat($(this).val()).toFixed(precision())) - else - $(this).val(parseFloat($(this).val()).toFixed(2)) - - if parseFloat($(this).val()) > parseFloat($(this).attr('max')) - $(this).val($(this).attr('max')) - ) - - $('#password').keyup(-> - try - if g.user.privkey - g.privkey = CryptoJS.AES.decrypt(g.user.privkey, $(this).val()).toString(CryptoJS.enc.Utf8) - - if g.privkey[0] is 'x' - g.key = bitcoin.HDNode.fromBase58(g.privkey) - else - g.key = bitcoin.ECPair.fromWIF(g.privkey) - - $('#key').val(g.privkey).keyup() - else - $('#key').val(g.user.pubkey).keyup() - - $(this).closest('.form-group').hide() - $('.wallet').fadeIn() - g.password = $(this).val() - ) - - $('#manage').click(-> - $('#withdrawal').hide() - $('#keys').show() - $('#privkey').val(g.user.privkey) - ) - - $('#withdraw').click(-> - $('#withdrawal').show() - $('#amount').focus() - $('#keys').hide() - $('#withdrawal form').validator('destroy') - $('#withdrawal form').validator(custom: validators, errors: errors, delay: 1200) - ) - - $('#cancel').click(-> - $('#keys').hide() - if g.balance > 0 and g.user.privkey - $('#withdrawal form').validator('destroy') - $('#withdrawal form').validator(custom: validators, errors: errors, delay: 1200) - $('#withdrawal').show() - $('#amount').focus() - ) - - $('#backup').click(-> - url = 'data:application/json;base64,' + btoa(JSON.stringify(g.user.privkey)) - a = document.createElement('a') - a.setAttribute('href', url) - a.setAttribute('download', 'wallet.json.aes') - a.click() - ) - - $('#generate').click(-> - bootbox.confirm('<h3>Are you sure?</h3> <p>This will overwrite your existing wallet so make sure that you have the backup we sent to your email in case you want to restore it.</p>', (result) -> - if result - mnemonic = bip39.generateMnemonic() - key = bitcoin.HDNode.fromSeedBuffer(bip39.mnemonicToSeed(mnemonic)).deriveHardened(44).deriveHardened(0) - $('#key').val(key.toString()).effect('highlight', {}, 2000).keyup() - ) - ) - - $('.close').on('click', -> $(this).closest('.alert').fadeOut()) -) - -getUser = -> - $.getJSON("/#{$('#username').val()}.json", (user) -> - g.user = user - $('#key').val(user.pubkey) - $('#pubkey').val(user.pubkey) - $('#privkey').val(user.privkey) - $('#address').val(user.address) - $('.address').html(user.address) - $('#unit').html(user.unit) - $('#currency_toggle').html(user.unit) - $('#amount').attr('step', 0.00000001 * multiplier()) - $('#password').closest('.form-group').show() - $('#password').focus() - - getExchangeRate() - $('#password').keyup() - ) - -getExchangeRate = -> - $.get("/ticker?currency=#{g.user.currency}&symbol=#{g.user.symbol}&type=bid", (exchange) -> - g.exchange = exchange - createWallet() - ) - -createWallet = -> - $.get("#{g.api}/wallets", (data) -> - if g.user.username in data.wallet_names - getBalance() - else - params = name: g.user.username - - if isBip32(g.user.pubkey) - params.extended_public_key = g.user.pubkey - params.subchain_indexes = [0,1] - - $.post("#{g.api}/wallets/hd", JSON.stringify(params)).done(getBalance).fail(-> $('.wallet').fadeIn()) - else - params.addresses = [g.user.pubkey] - $.post("#{g.api}/wallets", JSON.stringify(params)).done(getBalance).fail(-> $('.wallet').fadeIn()) - ) - - -getBalance = -> - $.get("#{g.api}/addrs/#{g.user.username}/balance?omitWalletAddresses=true", (data) -> - balance = data.final_balance - g.balance = parseFloat(balance.toBTC()) - fiat = balance.toFiat() - $('#balance').html(g.balance) - $('#fiat').html("#{fiat} #{g.user.currency}") - $('#amount').attr('max', g.balance) - $('#balances').show() - $('#fetching').hide() - - if g.balance > 0 and g.user.privkey - $('#keys').hide() - $('#withdrawal form').validator('destroy') - $('#withdrawal form').validator(custom: validators, errors: errors, delay: 1200) - $('#withdrawal').show() - $('#amount').focus() - ) - -updateUser = -> - data = $('#keys form').serializeObject() - delete data['key'] - - $.post("/#{g.user.username}", data, -> - $.ajax( - url: "#{g.api}/wallets/#{g.user.username}" - type: 'DELETE' - ).always(-> - $.ajax( - url: "#{g.api}/wallets/hd/#{g.user.username}" - type: 'DELETE' - ).always(-> - getUser() - ) - ) - ) - -sendTransaction = -> - if g.key and not (typeof g.key.d is 'undefined' and typeof g.key.keyPair.d is 'undefined') - dialog = new BootstrapDialog( - title: '<h3>Confirm Transaction</h3>' - message: '<i class="fa fa-spinner fa-spin"></i> Calculating fee...</i>' - buttons: [ - label: 'Send' - cssClass: 'btn-primary' - , - label: ' Cancel' - cssClass: 'btn-default' - action: (dialogItself) -> dialogItself.close() - icon: 'glyphicon glyphicon-ban-circle' - ] - ).open() - - params = - inputs: [{wallet_name: g.user.username, wallet_token: g.token}] - outputs: [{addresses: [$('#recipient').val()], value: 1}] - preference: $('#priority').val() - - $.post("#{g.api}/txs/new", JSON.stringify(params)).done((data) -> - if $('#currency_toggle').html() is g.user.unit - amount = $('#amount').val() - else - amount = convertedAmount() - - value = parseInt(amount * 100000000 / multiplier()) - - params.fees = data.tx.fees - params.outputs[0].value = value - if value > parseFloat(g.balance).toSatoshis() - params.fees - params.outputs[0].value -= params.fees - - $.post("#{g.api}/txs/new", JSON.stringify(params)).done((data) -> - data.pubkeys = [] - if g.key instanceof bitcoin.ECPair - data.signatures = data.tosign.map((tosign, i) -> - data.pubkeys.push(g.key.getPublicKeyBuffer().toString('hex')) - g.key.sign(new buffer.Buffer(tosign, "hex")).toDER().toString("hex") - ) - else - data.signatures = data.tosign.map((tosign, i) -> - path = data.tx.inputs[i].hd_path.split('/') - key = g.key.derive(parseInt(path[1])).derive(parseInt(path[2])) - data.pubkeys.push(key.keyPair.getPublicKeyBuffer().toString('hex')) - key.keyPair.sign(new buffer.Buffer(tosign, "hex")).toDER().toString("hex") - ) - - g.data = data - - amount = data.tx.outputs[0].value - fee = data.tx.fees - total = amount - if value > parseFloat(g.balance).toSatoshis() - data.tx.fees - total += fee - - - $('.dialog .amount').html("#{(amount.toBTC())} #{g.user.unit} (#{amount.toFiat()} #{g.user.currency})") - $('.dialog .fee').html("#{(fee.toBTC())} #{g.user.unit} (#{fee.toFiat()} #{g.user.currency})") - $('.dialog .total').html("#{(total.toBTC())} #{g.user.unit} (#{total.toFiat()} #{g.user.currency})") - $('.dialog .address').html(data.tx.outputs[0].addresses[0]) - - dialog.getModalBody().html($('.dialog').html()) - - if amount.toBTC() < 0.00000534 - displayErrors({errors: [error: 'Amount left over after fee is too small to send']}, dialog) - - dialog.getModal().find('.btn-primary').click(-> - $.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://blockchain.info/tx/' + finaltx.tx.hash, '_blank')) - dialog.close() - ) - ) - ).fail((data) -> - displayErrors(data.responseJSON, dialog) - ) - ).fail((data) -> - displayErrors(data.responseJSON, dialog) - ) - -displayErrors = (data, dialog) -> - if data.errors - dialog.getModalBody().html('') - dialog.getModal().find('.btn-primary').hide() - for e in data.errors - dialog.getModalBody().append("<div class='alert alert-danger'>#{e.error}</div>") - - -convertedAmount = -> - g.amount = amount unless g.amount and !isNaN(parseFloat(g.amount)) - amount = parseFloat($('#amount').val() * multiplier() / g.exchange).toFixed(precision()) - difference = parseFloat(Math.abs(g.amount - amount).toFixed(precision())) - tolerance = parseFloat((.00000002 * g.exchange * multiplier()).toFixed(precision())) - if difference > tolerance - return amount - else - return g.amount - - -check_address = (address) -> - try - bitcoin.address.fromBase58Check(address) - return true - catch - return isBip32(address) - -isBip32 = (address) -> - try - bitcoin.HDNode.fromBase58(address) - return true - catch - return false - -multiplier = -> - switch g.user.unit - when 'BTC' then 1 - when 'mBTC' then 1000 - when 'µBTC' then 1000000 - when 'bits' then 1000000 - when 'satoshis' then 100000000 - -precision = -> - 9 - multiplier().toString().length - -Number.prototype.toBTC = -> - parseFloat((this / 100000000 * multiplier())).toFixed(precision()) - -Number.prototype.toFiat = -> - parseFloat((this * g.exchange / 100000000)).toFixed(2) - -Number.prototype.toSatoshis = -> - parseInt(this * 100000000 / multiplier()) - - |
