lots of of small changes; bug fixes, extra validation, warning of large fee, a mediation section and more
This commit is contained in:
parent
fe141b0b8a
commit
ab395a82f2
2 changed files with 194 additions and 8 deletions
97
index.html
97
index.html
|
@ -301,8 +301,20 @@
|
||||||
<div class="tab-pane tab-content" id="newMultiSig">
|
<div class="tab-pane tab-content" id="newMultiSig">
|
||||||
<h2>New Multisig Address <small>Secure multisig address</small></h2>
|
<h2>New Multisig Address <small>Secure multisig address</small></h2>
|
||||||
|
|
||||||
<p>Public keys can be <a href="#newAddress">generated in your browser</a> or from your bitcoin client</a>.</p>
|
<div class="row">
|
||||||
<p>Enter the public keys of all the participants, to create a <a href="https://en.bitcoin.it/wiki/Address#Multi-signature_addresses" target="_blank">multi signature address</a>. Maximum of 15 allowed. Compressed and uncompressed public keys are accepted.</p>
|
|
||||||
|
<div class="col-md-8">
|
||||||
|
<p>Public keys can be <a href="#newAddress">generated in your browser</a> or from your bitcoin client</a>.</p>
|
||||||
|
<p>Enter the public keys of all the participants, to create a <a href="https://en.bitcoin.it/wiki/Address#Multi-signature_addresses" target="_blank">multi signature address</a>. Maximum of 15 allowed. Compressed and uncompressed public keys are accepted.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<p class="alert alert-info"><span class="glyphicon glyphicon-info-sign"></span> <a href="javascript:;" data-toggle="modal" data-target="#modalMediator"><abbr>Need a Mediator?</abbr></a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="multisigPubKeys" class="row">
|
<div id="multisigPubKeys" class="row">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
|
@ -542,6 +554,8 @@
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<div id="transactionCreateStatus" class="alert alert-danger hidden"></div>
|
||||||
|
|
||||||
<div id="transactionCreate" class="alert alert-success hidden">
|
<div id="transactionCreate" class="alert alert-success hidden">
|
||||||
<label>Transaction</label>
|
<label>Transaction</label>
|
||||||
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode" style="float:right;"><span class="glyphicon glyphicon-qrcode"></span></button>
|
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode" style="float:right;"><span class="glyphicon glyphicon-qrcode"></span></button>
|
||||||
|
@ -778,6 +792,7 @@
|
||||||
|
|
||||||
<div class="tab-pane tab-content" id="broadcast">
|
<div class="tab-pane tab-content" id="broadcast">
|
||||||
<h2>Broadcast Transaction <small>into the bitcoin network</small></h2>
|
<h2>Broadcast Transaction <small>into the bitcoin network</small></h2>
|
||||||
|
<a href="#settings" style="float:right;"><span class="glyphicon glyphicon-cog"></span></a>
|
||||||
<p>Enter your hex encoded bitcoin transaction</p>
|
<p>Enter your hex encoded bitcoin transaction</p>
|
||||||
<textarea class="form-control" style="height:125px" id="rawTransaction"></textarea>
|
<textarea class="form-control" style="height:125px" id="rawTransaction"></textarea>
|
||||||
<br>
|
<br>
|
||||||
|
@ -992,6 +1007,84 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- qrcode scanner modal -->
|
<!-- qrcode scanner modal -->
|
||||||
|
|
||||||
|
<!-- mediator modal -->
|
||||||
|
<div class="modal fade" id="modalMediator" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h4 class="modal-title">Transaction Mediation</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>You can add a public key when creating a <i>2-of-3 multi signature address</i> and for a low fee your mediator will help with the recovery of the funds should any disputes arise.</p>
|
||||||
|
|
||||||
|
<p>Should a dispute arise please contact the below address for further information</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<label>Mediator:</label>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
You need to contact us before adding your pubkey
|
||||||
|
and submitting a pull request on github.
|
||||||
|
|
||||||
|
format is: pubkey;email;fee
|
||||||
|
-->
|
||||||
|
|
||||||
|
<select id="mediatorList" class="form-control">
|
||||||
|
<option value="02b6231cc602740c29436eafbb6448880f4058cc3d2745c709deee313104678277;support@coinb.in;1">Coinb.in</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-5">
|
||||||
|
<label>Address:</label> <span class="text-muted">(for disputes)</span>
|
||||||
|
<input id="mediatorEmail" type="text" class="form-control address" value="" readonly>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label>Fee (%):</label>
|
||||||
|
<input id="mediatorFee" type="text" class="form-control address" value="" readonly>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<label>Public Key:</label>
|
||||||
|
<input id="mediatorPubkey" type="text" class="form-control address" value="" readonly>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-primary" type="button" id="mediatorAddKey">Add Public Key</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal" id="mediatorClose">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- mediator modal -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- warning (fee) modal -->
|
||||||
|
<div class="modal fade" id="modalWarningFee" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h4 class="modal-title"><b>Warning High Fee!</b></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
Please be aware that you have created a transaction with what seems to be a very high fee of <span id="modalWarningFeeAmount"></span> BTC!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal" id="warningFeeClose">OK, I've got it!</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- warning (fee) modal -->
|
||||||
|
|
||||||
<div class="hidden" id="entropybucket"></div>
|
<div class="hidden" id="entropybucket"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
105
js/coinbin.js
105
js/coinbin.js
|
@ -126,6 +126,7 @@ $(document).ready(function() {
|
||||||
$("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-success').html("txid: "+$(data).find("txid").text());
|
$("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-success').html("txid: "+$(data).find("txid").text());
|
||||||
} else {
|
} else {
|
||||||
$("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-danger').html(unescape($(data).find("response").text()).replace(/\+/g,' '));
|
$("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-danger').html(unescape($(data).find("response").text()).replace(/\+/g,' '));
|
||||||
|
thisbtn.attr('disabled',false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update wallet balance
|
// update wallet balance
|
||||||
|
@ -134,9 +135,9 @@ $(document).ready(function() {
|
||||||
}, signed);
|
}, signed);
|
||||||
} else {
|
} else {
|
||||||
$("#walletSendConfirmStatus").removeClass("hidden").addClass('alert-danger').html("You have a confirmed balance of "+data.value+" BTC unable to send "+total+" BTC").fadeOut().fadeIn();
|
$("#walletSendConfirmStatus").removeClass("hidden").addClass('alert-danger').html("You have a confirmed balance of "+data.value+" BTC unable to send "+total+" BTC").fadeOut().fadeIn();
|
||||||
|
thisbtn.attr('disabled',false);
|
||||||
}
|
}
|
||||||
|
|
||||||
thisbtn.attr('disabled',false);
|
|
||||||
$("#walletLoader").addClass("hidden");
|
$("#walletLoader").addClass("hidden");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -331,6 +332,34 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#mediatorList").change(function(){
|
||||||
|
var data = ($(this).val()).split(";");
|
||||||
|
$("#mediatorPubkey").val(data[0]);
|
||||||
|
$("#mediatorEmail").val(data[1]);
|
||||||
|
$("#mediatorFee").val(data[2]);
|
||||||
|
}).change();
|
||||||
|
|
||||||
|
$("#mediatorAddKey").click(function(){
|
||||||
|
var count = 0;
|
||||||
|
var len = $(".pubkeyRemove").length;
|
||||||
|
if(len<14){
|
||||||
|
$.each($("#multisigPubKeys .pubkey"),function(i,o){
|
||||||
|
if($(o).val()==''){
|
||||||
|
$(o).val($("#mediatorPubkey").val()).fadeOut().fadeIn();
|
||||||
|
$("#mediatorClose").click();
|
||||||
|
return false;
|
||||||
|
} else if(count==len){
|
||||||
|
$("#multisigPubKeys .pubkeyAdd").click();
|
||||||
|
$("#mediatorAddKey").click();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#mediatorClose").click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/* new -> Hd address code */
|
/* new -> Hd address code */
|
||||||
|
|
||||||
$(".deriveHDbtn").click(function(){
|
$(".deriveHDbtn").click(function(){
|
||||||
|
@ -398,13 +427,29 @@ $(document).ready(function() {
|
||||||
$("#transactionBtn").click(function(){
|
$("#transactionBtn").click(function(){
|
||||||
var tx = coinjs.transaction();
|
var tx = coinjs.transaction();
|
||||||
|
|
||||||
|
$("#transactionCreate, #transactionCreateStatus").addClass("hidden");
|
||||||
|
|
||||||
if(($("#nLockTime").val()).match(/^[0-9]+$/g)){
|
if(($("#nLockTime").val()).match(/^[0-9]+$/g)){
|
||||||
tx.lock_time = $("#nLockTime").val()*1;
|
tx.lock_time = $("#nLockTime").val()*1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$("#inputs .row").removeClass('has-error');
|
||||||
|
|
||||||
|
$('#putTabs a[href="#txinputs"], #putTabs a[href="#txoutputs"]').attr('style','');
|
||||||
|
|
||||||
$.each($("#inputs .row"), function(i,o){
|
$.each($("#inputs .row"), function(i,o){
|
||||||
if($(".txId",o).val()!="" && $(".txIdN",o).val()!=""){
|
if(!($(".txId",o).val()).match(/^[a-f0-9]+$/i)){
|
||||||
|
$(o).addClass("has-error");
|
||||||
|
} else if((!($(".txIdScript",o).val()).match(/^[a-f0-9]+$/i)) && $(".txIdScript",o).val()!=""){
|
||||||
|
$(o).addClass("has-error");
|
||||||
|
} else if (!($(".txIdN",o).val()).match(/^[0-9]+$/i)){
|
||||||
|
$(o).addClass("has-error");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$(o).hasClass("has-error")){
|
||||||
tx.addinput($(".txId",o).val(), $(".txIdN",o).val(), $(".txIdScript",o).val());
|
tx.addinput($(".txId",o).val(), $(".txIdN",o).val(), $(".txIdScript",o).val());
|
||||||
|
} else {
|
||||||
|
$('#putTabs a[href="#txinputs"]').attr('style','color:#a94442;');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -421,13 +466,24 @@ $(document).ready(function() {
|
||||||
tx.adddata(a);
|
tx.adddata(a);
|
||||||
} else { // neither address nor data
|
} else { // neither address nor data
|
||||||
$(o).addClass('has-error');
|
$(o).addClass('has-error');
|
||||||
|
$('#putTabs a[href="#txoutputs"]').attr('style','color:#a94442;');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#transactionCreate textarea").val(tx.serialize());
|
|
||||||
$("#transactionCreate .txSize").html(tx.size());
|
|
||||||
|
|
||||||
$("#transactionCreate").removeClass("hidden");
|
if(!$("#recipients .row, #inputs .row").hasClass('has-error')){
|
||||||
|
$("#transactionCreate textarea").val(tx.serialize());
|
||||||
|
$("#transactionCreate .txSize").html(tx.size());
|
||||||
|
|
||||||
|
$("#transactionCreate").removeClass("hidden");
|
||||||
|
|
||||||
|
if($("#transactionFee").val()>=0.01){
|
||||||
|
$("#modalWarningFeeAmount").html($("#transactionFee").val());
|
||||||
|
$("#modalWarningFee").modal("show");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$("#transactionCreateStatus").removeClass("hidden").html("One or more input or output is invalid").fadeOut().fadeIn();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".txidClear").click(function(){
|
$(".txidClear").click(function(){
|
||||||
|
@ -563,6 +619,7 @@ $(document).ready(function() {
|
||||||
if(decodeRs){ // redeem script
|
if(decodeRs){ // redeem script
|
||||||
r.addr = decodeRs['address'];
|
r.addr = decodeRs['address'];
|
||||||
r.from = 'redeemScript';
|
r.from = 'redeemScript';
|
||||||
|
r.decodedRs = decodeRs;
|
||||||
r.isMultisig = true;
|
r.isMultisig = true;
|
||||||
} else { // something else
|
} else { // something else
|
||||||
r.addr = '';
|
r.addr = '';
|
||||||
|
@ -573,6 +630,40 @@ $(document).ready(function() {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* mediator payment code for when you used a public key */
|
||||||
|
function mediatorPayment(redeem){
|
||||||
|
|
||||||
|
if(redeem.from=="redeemScript"){
|
||||||
|
|
||||||
|
$('#recipients .row[rel="'+redeem.addr+'"]').parent().remove();
|
||||||
|
|
||||||
|
$.each(redeem.decodedRs.pubkeys, function(i, o){
|
||||||
|
$.each($("#mediatorList option"), function(mi, mo){
|
||||||
|
|
||||||
|
var ms = ($(mo).val()).split(";");
|
||||||
|
|
||||||
|
var pubkey = ms[0]; // mediators pubkey
|
||||||
|
var fee = ms[2]*1; // fee in a percentage
|
||||||
|
var payto = coinjs.pubkey2address(pubkey); // pay to mediators address
|
||||||
|
|
||||||
|
if(o==pubkey){ // matched a mediators pubkey?
|
||||||
|
|
||||||
|
var clone = '<span><div class="row recipients mediator mediator_'+pubkey+'" rel="'+redeem.addr+'">'+$("#recipients .addressAddTo").parent().parent().html()+'</div><br></span>';
|
||||||
|
$("#recipients").prepend(clone);
|
||||||
|
|
||||||
|
$("#recipients .mediator_"+pubkey+" .glyphicon-plus:first").removeClass('glyphicon-plus');
|
||||||
|
$("#recipients .mediator_"+pubkey+" .address:first").val(payto).attr('disabled', true).attr('readonly',true).attr('title','Medation fee for '+$(mo).html());
|
||||||
|
|
||||||
|
var amount = ((fee*$("#totalInput").html())/100).toFixed(8);
|
||||||
|
$("#recipients .mediator_"+pubkey+" .amount:first").attr('disabled',(((amount*1)==0)?false:true)).val(amount).attr('title','Medation fee for '+$(mo).html());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
validateOutputAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* global function to add outputs to page */
|
/* global function to add outputs to page */
|
||||||
function addOutput(tx, n, script, amount) {
|
function addOutput(tx, n, script, amount) {
|
||||||
if(tx){
|
if(tx){
|
||||||
|
@ -610,6 +701,8 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$("#redeemFromBtn").html("Load").attr('disabled',false);
|
$("#redeemFromBtn").html("Load").attr('disabled',false);
|
||||||
totalInputAmount();
|
totalInputAmount();
|
||||||
|
|
||||||
|
mediatorPayment(redeem);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +752,7 @@ $(document).ready(function() {
|
||||||
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="https://btc.blockr.io/address/info/'+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
|
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="https://btc.blockr.io/address/info/'+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
|
||||||
for(var i in data.data.txs){
|
for(var i in data.data.txs){
|
||||||
var o = data.data.txs[i];
|
var o = data.data.txs[i];
|
||||||
var tx = o.txid;
|
var tx = ((o.txid).match(/.{1,2}/g).reverse()).join("")+'';
|
||||||
var n = o.output_no;
|
var n = o.output_no;
|
||||||
var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script_hex;
|
var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script_hex;
|
||||||
var amount = o.value;
|
var amount = o.value;
|
||||||
|
|
Loading…
Reference in a new issue