aboutsummaryrefslogtreecommitdiffstats
path: root/static/js
diff options
context:
space:
mode:
Diffstat (limited to 'static/js')
-rw-r--r--static/js/calculator.coffee268
-rw-r--r--static/js/generate_address.coffee74
-rw-r--r--static/js/index.coffee44
-rw-r--r--static/js/profile.coffee30
-rw-r--r--static/js/register.coffee53
-rw-r--r--static/js/setup.coffee65
-rw-r--r--static/js/setup.js4
-rw-r--r--static/js/signin.coffee6
-rw-r--r--static/js/wallet.coffee456
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', '&micro;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())
-
-