aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--app.js28
-rw-r--r--install.js2
-rw-r--r--passport.js2
-rw-r--r--public/assets/img/bitcoin_coop.pngbin15002 -> 0 bytes
-rw-r--r--public/js/calculator.coffee38
-rw-r--r--public/js/setup.coffee104
-rw-r--r--public/js/wallet.coffee79
-rw-r--r--public/success.wavbin0 -> 57388 bytes
-rw-r--r--routes/users.js32
-rw-r--r--src/app.coffee21
-rw-r--r--src/passport.coffee2
-rw-r--r--src/routes/users.coffee21
-rw-r--r--views/calculator/address.html1
-rw-r--r--views/layout.html5
-rw-r--r--views/tips.html11
-rw-r--r--views/users/edit.html87
-rw-r--r--views/users/profile.html2
-rw-r--r--views/users/show.html2
-rw-r--r--views/users/wallet.html56
20 files changed, 287 insertions, 210 deletions
diff --git a/.gitignore b/.gitignore
index 21623d60..ff29d6ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
-public/bitcoins.pdf
node_modules
builtAssets
database.json
@@ -7,3 +6,6 @@ npm-debug.log
public/js/rates.json
src/config.coffee
config.js
+passenger*
+tmp
+public/assets/img/logos/*
diff --git a/app.js b/app.js
index c82f895e..cc79d0cc 100644
--- a/app.js
+++ b/app.js
@@ -105,13 +105,31 @@
app.get('/', cache, sessions["new"]);
+ app.get('/address', cache, calculator.address);
+
app.get('/register', cache, users["new"]);
+ app.get('/sweep', calculator.sweep);
+
app.get('/ticker', cache, calculator.ticker);
- app.get('/sweep', calculator.sweep);
+ app.get('/token', cache, function(req, res) {
+ res.write(config.blockcypher_token);
+ return res.end();
+ });
- app.get('/address', cache, calculator.address);
+ app.get('/tips', cache, function(req, res) {
+ return res.render('tips', {
+ notice: true,
+ layout: 'layout',
+ js: (function() {
+ return global.js;
+ }),
+ css: (function() {
+ return global.css;
+ })
+ });
+ });
app.get('/login', cache, sessions["new"]);
@@ -125,11 +143,13 @@
app.get('/verify/:token', users.verify);
- app.get('/:user/profile', authorize, users.profile);
+ app.post('/:user', authorize, users.update);
app.get('/:user/edit', authorize, users.edit);
- app.post('/:user', authorize, users.update);
+ app.get('/:user/profile', authorize, users.profile);
+
+ app.get('/:user/wallet', authorize, users.wallet);
app.get('/:user/transactions.json', authorize, transactions.json);
diff --git a/install.js b/install.js
index 088d593e..30ece122 100644
--- a/install.js
+++ b/install.js
@@ -3,7 +3,7 @@
db = require("./redis");
- bcrypt = require('bcrypt');
+ bcrypt = require('bcryptjs');
db.get("user:admin", function(err, res) {
if (!res) {
diff --git a/passport.js b/passport.js
index aa11d658..b8b266d1 100644
--- a/passport.js
+++ b/passport.js
@@ -3,7 +3,7 @@
db = require("redis").createClient();
- bcrypt = require('bcrypt');
+ bcrypt = require('bcryptjs');
passport = require('passport');
diff --git a/public/assets/img/bitcoin_coop.png b/public/assets/img/bitcoin_coop.png
deleted file mode 100644
index 7e204c4f..00000000
--- a/public/assets/img/bitcoin_coop.png
+++ /dev/null
Binary files differ
diff --git a/public/js/calculator.coffee b/public/js/calculator.coffee
index cc2dcece..f709465f 100644
--- a/public/js/calculator.coffee
+++ b/public/js/calculator.coffee
@@ -11,8 +11,8 @@
#= require js/modsqrt.js
#= require js/rfc1751.js
-EXCHANGE_FAIL = "Error fetching exchange rate"
-SOCKET_FAIL = "Error connecting to payment server"
+EXCHANGE_FAIL = "Problem fetching exchange rate"
+SOCKET_FAIL = "Problem connecting to payment server, notifications may not appear"
ADDRESS_FAIL = "Invalid address"
g = exports ? this
@@ -59,7 +59,9 @@ setup = ->
$('#title').html("<a href='/#{g.user.username}/edit'>#{g.user.title}</a>").show()
if g.user.logo
- $('#logo').attr('src', g.user.logo).show()
+ ext = g.user.logo.substr(g.user.logo.length - 3)
+ src = "/assets/img/logos/#{g.user.username}.#{ext}"
+ $('#logo').attr('src', src).show()
getAddress()
@@ -108,25 +110,29 @@ updateTotal = ->
new QRCode('qr', text: "bitcoin:#{g.user.address}?amount=#{g.amount_requested.toString()}", width: 280, height: 280)
listen = ->
- setTimeout(listen, 10000)
-
- unless g.blockchain and g.blockchain.readyState is 1
+ 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("wss://ws.blockchain.info/inv")
g.blockchain.onopen = ->
- $('#connection').fadeIn().removeClass('glyphicon-exclamation-sign').addClass('glyphicon-signal')
- clear(SOCKET_FAIL)
- g.blockchain.send('{"op":"addr_sub", "addr":"' + g.user.address + '"}')
+ if g.blockchain.readyState is 1
+ g.attempts = 0
+ clear(SOCKET_FAIL)
+ g.blockchain.send('{"op":"addr_sub", "addr":"' + g.user.address + '"}')
+ else
+ setTimeout(g.blockchain.onopen, 12000)
g.blockchain.onerror = ->
- $('#connection').addClass('glyphicon-exclamation-sign').removeClass('glyphicon-signal')
- g.blockchain = null
fail(SOCKET_FAIL)
+ g.blockchain.close()
+ delete g.blockchain
+ listen()
g.blockchain.onclose = ->
- $('#connection').addClass('glyphicon-exclamation-sign').removeClass('glyphicon-signal')
- g.blockchain = null
- fail(SOCKET_FAIL)
+ delete g.blockchain
listen()
g.blockchain.onmessage = (e) ->
@@ -149,7 +155,7 @@ logTransaction = (txid, amount) ->
$('#amount').blur()
$('#payment').hide()
$('#received').fadeIn('slow')
- $('#chaching')[0].play()
+ $('#success')[0].play()
g.user.index++
$.post("/#{g.user.username}/transactions",
@@ -171,6 +177,8 @@ getAddress = ->
master = bitcoin.HDNode.fromBase58(g.user.pubkey)
child = master.derive(0).derive(g.user.index)
g.user.address = child.pubKey.getAddress().toString()
+ g.blockchain.close() if g.blockchain
+ listen()
catch
fail(ADDRESS_FAIL)
diff --git a/public/js/setup.coffee b/public/js/setup.coffee
index 465cfb39..01705cdd 100644
--- a/public/js/setup.coffee
+++ b/public/js/setup.coffee
@@ -56,7 +56,6 @@ $(->
$('#email').val(data.email)
$('#title').val(data.title)
$('#logo').val(data.logo)
- $('#pubkey').val(data.pubkey)
$('#address').val(data.address)
$("#symbol option[value='#{data.symbol}']").attr('selected', 'selected')
$('#commission').val(data.commission)
@@ -72,96 +71,6 @@ $(->
$('#unit').append("<option value='#{v}'>#{v}</option>")
)
- $('#pubkey').blur(->
- if check_address($(this).val())
- $(this).parent().removeClass('has-error')
- else
- $(this).parent().addClass('has-error')
- )
-
- $('#generate').click(->
- key = new Key()
- g.pubkey = key.extended_public_key_string()
- g.privkey = key.extended_private_key_string()
-
- $('#modal').modal()
- $('#privkey_text').html(g.privkey)
- $('#qr').html('')
- new QRCode('qr', text: g.privkey, width: 260, height: 260)
- )
-
- $('#encryption-password').keyup((e) ->
- return if e.keyCode is 9 or e.keyCode is 16
- g.enc_privkey = CryptoJS.AES.encrypt(g.privkey, $(this).val()).toString()
- g.enc_privkey = g.privkey if $(this).val() == ''
- $('#privkey_text').html(g.enc_privkey)
- $('#qr').html('')
- new QRCode('qr', text: g.enc_privkey, width: 260, height: 260)
-
- if $(this).val()
- $('#status').html('(Encrypted)')
- else
- $('#status').html('(Unencrypted)')
- )
-
- $('#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')
- )
-
- $('#encryption-password, #encryption-confirm').keyup((e) -> check_passwords(e) unless e.keyCode is 9)
- $('#encryption-password, #encryption-confirm').blur((e) -> check_passwords(e))
-
- check_passwords = (e) ->
- if $('#encryption-password').val() != $('#encryption-confirm').val() or $('#encryption-password').val() is ''
- $('#encryption-password, #encryption-confirm').parent().addClass('has-error')
- $('#modal .alert').removeClass('alert-success').addClass('alert-danger')
- else
- $('#encryption-password, #encryption-confirm').parent().removeClass('has-error')
- $('#modal .alert').removeClass('alert-danger').addClass('alert-success')
-
- if $('.progress-bar-success').length > 0
- $('#encryption-password').parent().removeClass('has-error')
- else
- $('#encryption-password').parent().addClass('has-error')
-
- $('#print').click(->
- $('#key-dialog').printElement(printMode: 'popup')
- )
-
- $('a[data-toggle="tab"]').on('shown.bs.tab', (e) ->
- $('#print').toggle(e.target.attributes.href.value == '#step1')
- )
-
- $('#close').click(->
- $('#modal .form-control').blur()
- if $('#modal .has-error').length > 0
- $('#step1_link').click()
- $('#modal .has-error').effect('shake', 500)
- else
- g.update_key = true
- $('#modal').modal('hide')
- )
- $('#encrypt').submit(-> $('#close').click(); return false)
-
- $('#modal').on('show.bs.modal', ->
- $('#encryption-password, #encryption-confirm').val('').keyup().parent().removeClass('has-error')
- $('#modal .alert').removeClass('alert-success').addClass('alert-danger')
- )
-
- $('#modal').on('shown.bs.modal', ->
- g.update_key = false
- $('#encryption-password').focus()
- ).on('hidden.bs.modal', ->
- if g.update_key
- $('#pubkey').val(g.pubkey)
- $('#privkey').val(g.enc_privkey)
- )
-
$('#setup').submit(->
$('#setup .form-control').blur()
if $('#setup .has-error').length > 0
@@ -170,16 +79,3 @@ $(->
)
)
-check_address = (address) ->
- try
- bitcoin.Address.fromBase58Check(address)
- return true
- catch
- return isBip32(address)
-
-isBip32 = (address) ->
- try
- new BIP32(address)
- return true
- catch
- return false
diff --git a/public/js/wallet.coffee b/public/js/wallet.coffee
new file mode 100644
index 00000000..fcbbd062
--- /dev/null
+++ b/public/js/wallet.coffee
@@ -0,0 +1,79 @@
+#= require ../js/jquery-1.8.2.min.js
+#= require ../js/jquery-ui.min.js
+#= require ../js/jquery.printElement.min.js
+#= require ../js/check_password.js
+#= require ../js/bootstrap.min.js
+#= require ../js/jsbn.js
+#= require ../js/jsbn2.js
+#= require ../js/crypto-min.js
+#= require ../js/2.5.3-crypto-sha256.js
+#= require ../js/sha512.js
+#= require ../js/rfc1751.js
+#= require ../js/bitcoinjs-min-1.0.2.js
+#= require ../js/bitcoinjs-min.js
+#= require ../js/modsqrt.js
+#= require ../js/bip32.js
+#= require ../js/secure_random.js
+#= require ../js/qrcode.js
+#= require ../js/aes.js
+#= require ../js/key.js
+
+g = exports ? this
+g.proceed = false
+
+$(->
+ api = 'https://api.blockcypher.com/v1/btc/main'
+ addresses = []
+ balance = 0
+ token = ''
+ $('#balance, #amount').hide()
+ $.get("/token", (data) ->
+ token = data
+ $.get("#{api}/wallets/hd/yummy/addresses?token=#{token}", (data) ->
+ for c in data.chains
+ for a in c.chain_addresses
+ addresses.push(a.address)
+
+ chunks = []
+ for i in [0 .. addresses.length] by 10
+ chunks.push(addresses.slice(i,i+10))
+
+ doSetTimeout = (c,i) ->
+ setTimeout(->
+ $.get("#{api}/addrs/#{c.join(';')}/balance?token=#{token}", (addresses) ->
+ for address in addresses
+ balance = parseInt(balance) + parseInt(address.final_balance)
+ val = (balance / 100000000).toFixed(8)
+
+ $('#balance').html(val)
+ $('#amount').val(val)
+ $('#balance, #amount').fadeIn()
+ )
+ , i*1500)
+
+ for c, i in chunks
+ doSetTimeout(c, i)
+ )
+ )
+
+ user = $('#username').val()
+ $.getJSON("/#{user}.json", (data) ->
+ $('#pubkey').val(data.pubkey)
+ $('#address').val(data.address)
+ $('#setup').fadeIn()
+ )
+)
+
+check_address = (address) ->
+ try
+ bitcoin.Address.fromBase58Check(address)
+ return true
+ catch
+ return isBip32(address)
+
+isBip32 = (address) ->
+ try
+ new BIP32(address)
+ return true
+ catch
+ return false
diff --git a/public/success.wav b/public/success.wav
new file mode 100644
index 00000000..50547d2b
--- /dev/null
+++ b/public/success.wav
Binary files differ
diff --git a/routes/users.js b/routes/users.js
index c5e0f0ee..4ef67d2c 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -1,11 +1,15 @@
(function() {
- var bcrypt, config, db;
+ var bcrypt, config, db, fs, request;
db = require("../redis");
config = require("../config");
- bcrypt = require('bcrypt');
+ bcrypt = require('bcryptjs');
+
+ fs = require('fs');
+
+ request = require('request');
module.exports = function(sessions) {
return {
@@ -34,7 +38,7 @@
},
show: function(req, res) {
return db.hgetall("user:" + req.params.user, function(err, obj) {
- var options;
+ var ext, options, path;
if (obj) {
options = {
user: req.params.user,
@@ -50,6 +54,15 @@
if (req.query.verified != null) {
options.verified = true;
}
+ if (obj.logo && obj.logo.length > 3) {
+ ext = obj.logo.substr(obj.logo.length - 3);
+ path = "public/assets/img/logos/" + obj.username + "." + ext;
+ fs.lstat(path, function(err, stats) {
+ if ((ext === 'jpg' || ext === 'png' || ext === 'gif') && (err || !stats.isFile())) {
+ return request("" + obj.logo).pipe(fs.createWriteStream(path));
+ }
+ });
+ }
res.render('users/show', options);
return delete req.session.verified;
} else {
@@ -230,6 +243,19 @@
});
}
});
+ },
+ wallet: function(req, res) {
+ return res.render('users/wallet', {
+ user: req.params.user,
+ layout: 'layout',
+ navigation: true,
+ js: (function() {
+ return global.js;
+ }),
+ css: (function() {
+ return global.css;
+ })
+ });
}
};
};
diff --git a/src/app.coffee b/src/app.coffee
index 3208ae49..caab1bcb 100644
--- a/src/app.coffee
+++ b/src/app.coffee
@@ -63,10 +63,22 @@ do fetchRates = ->
setTimeout(fetchRates, 120000)
app.get('/', cache, sessions.new)
+app.get('/address', cache, calculator.address)
app.get('/register', cache, users.new)
-app.get('/ticker', cache, calculator.ticker)
app.get('/sweep', calculator.sweep)
-app.get('/address', cache, calculator.address)
+app.get('/ticker', cache, calculator.ticker)
+app.get('/token', cache, (req, res) ->
+ res.write(config.blockcypher_token)
+ res.end()
+)
+app.get('/tips', cache, (req, res) ->
+ res.render('tips',
+ notice: true,
+ layout: 'layout',
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+)
app.get('/login', cache, sessions.new)
app.post('/login', sessions.create)
@@ -76,9 +88,10 @@ app.get('/users/new', cache, users.new)
app.post('/users', users.create)
app.get('/verify/:token', users.verify)
-app.get('/:user/profile', authorize, users.profile)
-app.get('/:user/edit', authorize, users.edit)
app.post('/:user', authorize, users.update)
+app.get('/:user/edit', authorize, users.edit)
+app.get('/:user/profile', authorize, users.profile)
+app.get('/:user/wallet', authorize, users.wallet)
app.get('/:user/transactions.json', authorize, transactions.json)
app.post('/:user/transactions', transactions.create)
diff --git a/src/passport.coffee b/src/passport.coffee
index 12913424..aba6ff53 100644
--- a/src/passport.coffee
+++ b/src/passport.coffee
@@ -1,5 +1,5 @@
db = require("redis").createClient()
-bcrypt = require('bcrypt')
+bcrypt = require('bcryptjs')
passport = require('passport')
LocalStrategy = require('passport-local').Strategy
diff --git a/src/routes/users.coffee b/src/routes/users.coffee
index d3ecabaf..5daae180 100644
--- a/src/routes/users.coffee
+++ b/src/routes/users.coffee
@@ -1,6 +1,8 @@
db = require("../redis")
config = require("../config")
-bcrypt = require('bcrypt')
+bcrypt = require('bcryptjs')
+fs = require('fs')
+request = require('request')
module.exports = (sessions) ->
exists: (req, res) ->
@@ -33,6 +35,14 @@ module.exports = (sessions) ->
if req.query.verified?
options.verified = true
+ if obj.logo and obj.logo.length > 3
+ ext = obj.logo.substr(obj.logo.length - 3)
+ path = "public/assets/img/logos/#{obj.username}.#{ext}"
+ fs.lstat(path, (err, stats) ->
+ if ext in ['jpg', 'png', 'gif'] and (err or not stats.isFile())
+ request("#{obj.logo}").pipe(fs.createWriteStream(path))
+ )
+
res.render('users/show', options)
delete req.session.verified
else
@@ -182,3 +192,12 @@ module.exports = (sessions) ->
res.redirect("/#{reply.toString()}?verified")
)
)
+
+ wallet: (req, res) ->
+ res.render('users/wallet',
+ user: req.params.user,
+ layout: 'layout',
+ navigation: true,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
diff --git a/views/calculator/address.html b/views/calculator/address.html
index 54d988cb..19275e52 100644
--- a/views/calculator/address.html
+++ b/views/calculator/address.html
@@ -15,7 +15,6 @@
<div id="pubqr"></div>
</div>
-
<div id="key-dialog" class="alert alert-danger">
<span id="status"></span> Private Key
<pre id="privkey"></pre>
diff --git a/views/layout.html b/views/layout.html
index 5be45ded..e63e3c47 100644
--- a/views/layout.html
+++ b/views/layout.html
@@ -20,8 +20,9 @@
<div class="navbar">
<ul class="nav navbar-nav">
<li><a href="/{{user}}"><span class="glyphicon glyphicon-home"></span> Home</a></li>
- <li><a href="/{{user}}/report"><span class="glyphicon glyphicon-list-alt"></span> Transactions</a></li>
- <li><a href="/{{user}}/profile"><span class="glyphicon glyphicon-user"></span> Account Profile</a></li>
+ <li><a href="/{{user}}/report"><span class="glyphicon glyphicon-list-alt"></span> Sales</a></li>
+ <li><a href="/{{user}}/wallet"><span class="fa fa-bank"></span> Wallet</a></li>
+ <li><a href="/{{user}}/profile"><span class="glyphicon glyphicon-user"></span> Account</a></li>
<li><a href="/{{user}}/edit"><span class="glyphicon glyphicon-cog"></span> Settings</a></li>
<li><a href="/logout"><span class="glyphicon glyphicon-off"></span> Logout</a></li>
<!--
diff --git a/views/tips.html b/views/tips.html
new file mode 100644
index 00000000..a4ac19ba
--- /dev/null
+++ b/views/tips.html
@@ -0,0 +1,11 @@
+<h1>Congratulations</h1>
+
+<p>
+If you're here, you've probably received a Bitcoin tip from me. I've created a short YouTube video to explain what to do next and show how you can create your own paper wallets. Enjoy, and if you have any questions, don't hesitate to contact me!</p>
+
+<p>
+-Adam Soltys<br />
+</p>
+
+<iframe width="420" height="315" src="https://www.youtube.com/embed/be4J_OpciTc" frameborder="0" allowfullscreen></iframe>
diff --git a/views/users/edit.html b/views/users/edit.html
index 0e0af3df..beb98973 100644
--- a/views/users/edit.html
+++ b/views/users/edit.html
@@ -9,27 +9,16 @@
<input type="hidden" id="email" name="email" />
<div class="form-group">
- <label for="title">Store Name:</label>
+ <label for="title">Store Name <small>(optional)</small>:</label>
<input type="text" id="title" name="title" class="form-control" />
</div>
<div class="form-group">
- <label for="logo">Logo:</label>
+ <label for="logo">Logo <small>(optional)</small>:</label>
<input type="text" id="logo" name="logo" class="form-control" />
</div>
<div class="form-group">
- <label for="pubkey">Bitcoin Public Key:</label>
- <div class="input-group">
- <input type="text" id="pubkey" name="pubkey" class="form-control" placeholder="xpub..." />
- <input type="hidden" id="privkey" name="privkey" />
- <span class="input-group-btn">
- <button id="generate" type="button" class="btn">New</button>
- </span>
- </div>
- </div>
-
- <div class="form-group">
<label for="currency">Currency:</label>
<select id="currency" name="currency" class="form-control">
</select>
@@ -42,8 +31,21 @@
</div>
<div class="form-group">
- <label for="commission">Commission (+) / Discount (-) %:</label>
- <input type="text" id="commission" name="commission" class="form-control" />
+ <label for="commission">Discount:</label>
+
+ <select id="commission" name="commission" class="form-control">
+ <option value="0">None</option>
+ <option value="-1">1%</option>
+ <option value="-2">2%</option>
+ <option value="-3">3%</option>
+ <option value="-4">4%</option>
+ <option value="-5">5%</option>
+ <option value="-10">10%</option>
+ <option value="-15">15%</option>
+ <option value="-20">20%</option>
+ <option value="-25">25%</option>
+ <option value="-50">50%</option>
+ </select>
</div>
<div class="form-group">
@@ -54,58 +56,3 @@
<input class="btn btn-primary" type="submit" value="Done" />
</form>
-
-<div class="modal fade" id="modal" tabindex="-1" role="dialog">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
- <h4 class="modal-title">New Extended Key</h4>
- </div>
-
- <div class="modal-body">
- <ul class="nav nav-tabs" role="tablist">
- <li class="active"><a id="step1_link" href="#step1" role="tab" data-toggle="tab">Key</a></li>
- <li><a href="#step2" role="tab" data-toggle="tab">What's this?</a></li>
- </ul>
- <div class="tab-content">
- <div id="step1" class="tab-pane active">
- <form id="encrypt">
- <div class="form-group">
- <label for="encryption-password">Encryption Password:</label>
- <input type="password" id="encryption-password" name="encryption-password" class="form-control" />
- </div>
-
- <div class="form-group">
- <label for="encryption-confirm">Confirm Password:</label>
- <input type="password" id="encryption-confirm" name="encryption-confirm" class="form-control" />
- </div>
-
- <input type="submit" style="position: absolute; left: -9999px" />
- </form>
-
- <div id="key-dialog" class="alert alert-danger">
- Extended Private Key <span id="status">(Unencrypted)</span>
- <pre id="privkey_text"></pre>
- <div id="qr"></div>
- </div>
- </div>
- <div id="step2" class="tab-pane">
- <p>This is a Bitcoin extended key, also known as an <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki"><abbr title="Hierarchical Deterministic Wallet">HD Wallet</abbr></a>.</p>
- <p>The <b>public</b> portion of the key is stored and used by CoinOS to generate a separate receiving address for every payment to your account. This prevents people from seeing transactions to your account other than their own.</p>
- <p>The <b>private</b> portion of the key (displayed on the 'Key' tab) will not be accessible after you close this window. You are responsible for safely storing it and making copies of it, either by printing it out or saving it somewhere on your computer or online.</p>
- <p>Encrypting the key with a strong password provides a safeguard against someone gaining access to a copy of the key. They will need to know your password to decrypt the key. Keep the password written down and backed up separately from the key.</p>
- <p class="text-danger"><b>IMPORTANT: We cannot reset your password. If you lose it or forget it, any funds sent to your account will be lost forever.</b></p>
-
- <img src="/assets/img/forever.gif" width="370px" />
- </div>
-
- </div>
- </div>
- <div class="modal-footer">
- <button type="button" id="print" class="btn btn-primary"><span class="glyphicon glyphicon-print"></span> Print</button>
- <button type="button" id="close" class="btn btn-primary">Got it!</button>
- </div>
- </div>
- </div>
-</div>
diff --git a/views/users/profile.html b/views/users/profile.html
index 6d05d61d..dffa559c 100644
--- a/views/users/profile.html
+++ b/views/users/profile.html
@@ -21,7 +21,7 @@
</div>
<div class="form-group">
- <label for="confirm">Confirm New Password:</label>
+ <label for="confirm">Confirm Password:</label>
<input type="password" id="confirm" name="confirm" class="form-control" />
</div>
diff --git a/views/users/show.html b/views/users/show.html
index 5b8314a3..f37afad4 100644
--- a/views/users/show.html
+++ b/views/users/show.html
@@ -44,6 +44,6 @@ Your email has been verified. Thank you!
</div>
<button type="button" id="received" class="btn btn-success">Payment Received. Thank you!</button>
- <audio id="chaching" src="/cash_register.wav" hidden="true" enablejavascript="true">
+ <audio id="success" src="/success.wav" hidden="true" enablejavascript="true">
</div>
diff --git a/views/users/wallet.html b/views/users/wallet.html
new file mode 100644
index 00000000..873a12d1
--- /dev/null
+++ b/views/users/wallet.html
@@ -0,0 +1,56 @@
+{{#yield-scripts}}
+ {{#js}}js/wallet{{/js}}
+{{/yield-scripts}}
+
+<form id="setup" action="/{{user}}" method="post" style="display: none">
+ <h1>Wallet</h1>
+
+ <input type="hidden" id="username" name="username" value="{{user}}" />
+ <input type="hidden" id="email" name="email" />
+
+ <div class="form-group">
+ <label>Available Balance:</label>
+ <b id="balance" class="lead">0.05154234</b> BTC
+ </div>
+
+ <div>
+ <ul class="nav nav-tabs" role="tablist">
+ <li role="presentation" class="active"><a href="#withdraw" aria-controls="withdraw" role="tab" data-toggle="tab">Withdraw</a></li>
+ <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Manage Keys</a></li>
+ </ul>
+
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane active" id="withdraw">
+ <div class="form-group">
+ <label for="amount">Amount:</label>
+ <div class="input-group">
+ <input type="number" id="amount" name="amount" class="form-control" value="0.05154232" />
+ <span class="input-group-btn">
+ <button type="button" class="btn">BTC</button>
+ </span>
+ <span class="input-group-btn">
+ <button type="button" class="btn">Max</button>
+ </span>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="amount">Recipient:</label>
+ <div class="input-group">
+ <input type="text" id="recipient" name="recipient" class="form-control" />
+ <span class="input-group-btn">
+ <button type="button" class="btn"><span class="glyphicon glyphicon-camera"></span></button>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div role="tabpanel" class="tab-pane" id="settings">
+ <div class="form-group">
+ <label for="pubkey">Bitcoin Receiving Address or HD Wallet Pubkey:</label>
+ <input type="text" id="pubkey" name="pubkey" class="form-control" placeholder="xpub..." />
+ <input type="hidden" id="privkey" name="privkey" />
+ </div>
+ </div>
+ </div>
+ </div>
+</form>