added extra support for altcoins, litecoin beta added via #settings page
This commit is contained in:
parent
004de1f318
commit
a1c3c60244
3 changed files with 177 additions and 64 deletions
|
@ -26,5 +26,6 @@ Coinb.in supports a number of key features such as:
|
||||||
- An offical .onion address for tor users.
|
- An offical .onion address for tor users.
|
||||||
- Offline qrcode creator and scanning tool
|
- Offline qrcode creator and scanning tool
|
||||||
- HD (bip32) support
|
- HD (bip32) support
|
||||||
|
- supports altcoins such as litecoin
|
||||||
|
|
||||||
Donate to 1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg to see more development!
|
Donate to 1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg to see more development!
|
||||||
|
|
20
index.html
20
index.html
|
@ -218,8 +218,8 @@
|
||||||
<input type="text" class="form-control" value="0.00001" id="txFee">
|
<input type="text" class="form-control" value="0.00001" id="txFee">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-5">
|
<div class="col-xs-5">
|
||||||
<label><abbr title="the amount to donate to the sites developer">Donation</abbr></label>
|
<label><abbr title="the amount to donate to coinb.in">Donation</abbr></label>
|
||||||
<input type="text" class="form-control" value="0.00" id="developerDonation">
|
<input type="text" class="form-control" value="0.001" id="developerDonation">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
@ -442,6 +442,12 @@
|
||||||
<input type="text" class="form-control" value="0" id="nLockTime">
|
<input type="text" class="form-control" value="0" id="nLockTime">
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
|
||||||
|
<label>Network</label>
|
||||||
|
<p>The <a href="#settings">settings</a> page can be used to select alternative networks of which you can retrieve your unspent outputs and broadcast a signed transaction into.</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -815,7 +821,8 @@
|
||||||
<p class="text-muted">Select which network you'd like to use for key pair generation.</p>
|
<p class="text-muted">Select which network you'd like to use for key pair generation.</p>
|
||||||
<select class="form-control" id="coinjs_coin">
|
<select class="form-control" id="coinjs_coin">
|
||||||
<option value="bitcoin_mainnet" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;coinb.in;coinb.in">Bitcoin (mainnet)</option>
|
<option value="bitcoin_mainnet" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;coinb.in;coinb.in">Bitcoin (mainnet)</option>
|
||||||
<option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;blockr.io_bitcointestnet;false">Bitcoin (testnet)</option>
|
<option value="litecoin_mainnet" rel="0x30;0xb0;0x05;0x019da462;0x019d9cfe;blockr.io_litecoin;chain.so_litecoin">Litecoin (mainnet)</option>
|
||||||
|
<!-- <option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;blockr.io_bitcointestnet;false">Bitcoin (testnet)</option> -->
|
||||||
|
|
||||||
<option value="custom" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;false;false">Custom</option>
|
<option value="custom" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;false;false">Custom</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -858,7 +865,7 @@
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<div class="alert alert-info"> <span class="glyphicon glyphicon-info-sign"></span> You will not be able to automatically broadcast or retreive your unspent inputs from coinb.in when using this setting and will need to use your desktop client instead, however everything else will continue to function normally.</div>
|
<div class="alert alert-info"> <span class="glyphicon glyphicon-info-sign"></span> You will not be able to automatically broadcast or retreive your unspent outputs from coinb.in when using this setting and will need to use your desktop client instead, however everything else such as creating key pairs, addresses, transaction generation and signing will continue to function normally.</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -870,7 +877,8 @@
|
||||||
<select class="form-control" id="coinjs_broadcast">
|
<select class="form-control" id="coinjs_broadcast">
|
||||||
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
|
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
|
||||||
<option value="blockr.io_bitcoinmainnet"> Blockr.io (Bitcoin mainnet)</option>
|
<option value="blockr.io_bitcoinmainnet"> Blockr.io (Bitcoin mainnet)</option>
|
||||||
<option value="blockr.io_bitcointestnet"> Blockr.io (Bitcoin testnet)</option>
|
<option value="blockr.io_litecoin"> Blockr.io (Litecoin)</option>
|
||||||
|
<!-- <option value="blockr.io_bitcointestnet"> Blockr.io (Bitcoin testnet)</option> -->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -883,6 +891,8 @@
|
||||||
<p class="text-muted">Select the network you wish to retreive your unspent inputs from</p>
|
<p class="text-muted">Select the network you wish to retreive your unspent inputs from</p>
|
||||||
<select class="form-control" id="coinjs_utxo">
|
<select class="form-control" id="coinjs_utxo">
|
||||||
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
|
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
|
||||||
|
<option value="blockr.io_bitcoinmainnet"> Blockr.io (Bitcoin mainnet)</option>
|
||||||
|
<option value="chain.so_litecoin"> Chain.so (Litecoin)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
220
js/coinbin.js
220
js/coinbin.js
|
@ -507,71 +507,177 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* redeem from button code */
|
||||||
|
|
||||||
$("#redeemFromBtn").click(function(){
|
$("#redeemFromBtn").click(function(){
|
||||||
var thisbtn = this;
|
var string = $("#redeemFrom").val();
|
||||||
var addr = '';
|
var redeem = redeemingFrom(string);
|
||||||
var isMultiSig = false;
|
|
||||||
var s = $("#redeemFrom").val();
|
|
||||||
|
|
||||||
$("#redeemFromStatus, #redeemFromAddress").addClass('hidden');
|
$("#redeemFromStatus, #redeemFromAddress").addClass('hidden');
|
||||||
$(thisbtn).html("Please wait, loading...").attr('disabled',true);
|
|
||||||
|
|
||||||
var decode = coinjs.addressDecode(s);
|
if(redeem.from=='multisigAddress'){
|
||||||
|
|
||||||
if(decode.version == coinjs.pub){
|
|
||||||
addr = s;
|
|
||||||
} else if (decode.version == coinjs.priv){
|
|
||||||
var a = coinjs.wif2address(s);
|
|
||||||
addr = a['address'];
|
|
||||||
} else if (decode.version == coinjs.multisig){
|
|
||||||
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> You should use the redeem script, not the multisig address!');
|
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> You should use the redeem script, not the multisig address!');
|
||||||
} else {
|
return false;
|
||||||
var script = coinjs.script();
|
|
||||||
var decodeRs = script.decodeRedeemScript(s);
|
|
||||||
if(decodeRs){
|
|
||||||
addr = decodeRs['address'];
|
|
||||||
isMultiSig = true;
|
|
||||||
} else {
|
|
||||||
// input is neither a regular address or redeem script
|
|
||||||
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> The address or multisig redeem script you have entered is invalid');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(redeem.from=='other'){
|
||||||
|
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> The address or multisig redeem script you have entered is invalid');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($("#clearInputsOnLoad").is(":checked")){
|
||||||
|
$("#inputs .txidRemove, #inputs .txidClear").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#redeemFromBtn").html("Please wait, loading...").attr('disabled',true);
|
||||||
|
|
||||||
|
var host = $(this).attr('rel');
|
||||||
|
if(host=='blockr.io_bitcoinmainnet'){
|
||||||
|
listUnspentBlockrio_BitcoinMainnet(redeem.addr);
|
||||||
|
} else if(host=='chain.so_litecoin'){
|
||||||
|
listUnspentChainso_Litecoin(redeem.addr);
|
||||||
|
} else {
|
||||||
|
listUnspentDefault(redeem.addr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* function to determine what we are redeeming from */
|
||||||
|
function redeemingFrom(string){
|
||||||
|
var r = {};
|
||||||
|
var decode = coinjs.addressDecode(string);
|
||||||
|
if(decode.version == coinjs.pub){ // regular address
|
||||||
|
r.addr = string;
|
||||||
|
r.from = 'address';
|
||||||
|
r.isMultisig = false;
|
||||||
|
} else if (decode.version == coinjs.priv){ // wif key
|
||||||
|
var a = coinjs.wif2address(string);
|
||||||
|
r.addr = a['address'];
|
||||||
|
r.from = 'wif';
|
||||||
|
r.isMultisig = false;
|
||||||
|
} else if (decode.version == coinjs.multisig){ // mulisig address
|
||||||
|
r.addr = '';
|
||||||
|
r.from = 'multisigAddress';
|
||||||
|
r.isMultisig = false;
|
||||||
|
} else {
|
||||||
|
var script = coinjs.script();
|
||||||
|
var decodeRs = script.decodeRedeemScript(string);
|
||||||
|
if(decodeRs){ // redeem script
|
||||||
|
r.addr = decodeRs['address'];
|
||||||
|
r.from = 'redeemScript';
|
||||||
|
r.isMultisig = true;
|
||||||
|
} else { // something else
|
||||||
|
r.addr = '';
|
||||||
|
r.from = 'other';
|
||||||
|
r.isMultisig = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* global function to add outputs to page */
|
||||||
|
function addOutput(tx, n, script, amount) {
|
||||||
|
if(tx){
|
||||||
|
if($("#inputs .txId:last").val()!=""){
|
||||||
|
$("#inputs .txidAdd").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#inputs .row:last input").attr('disabled',true);
|
||||||
|
|
||||||
|
var txid = ((tx).match(/.{1,2}/g).reverse()).join("")+'';
|
||||||
|
|
||||||
|
$("#inputs .txId:last").val(txid);
|
||||||
|
$("#inputs .txIdN:last").val(n);
|
||||||
|
$("#inputs .txIdAmount:last").val(amount);
|
||||||
|
$("#inputs .txIdScript:last").val(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default function to retreive unspent outputs*/
|
||||||
|
function listUnspentDefault(addr){
|
||||||
var tx = coinjs.transaction();
|
var tx = coinjs.transaction();
|
||||||
tx.listUnspent(addr, function(data){
|
tx.listUnspent(addr, function(data){
|
||||||
if(addr) {
|
if(addr) {
|
||||||
if($("#clearInputsOnLoad").is(":checked")){
|
|
||||||
$("#inputs .txidRemove, #inputs .txidClear").click();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="https://btc.blockr.io/address/info/'+addr+'" target="_blank">'+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/'+addr+'" target="_blank">'+addr+'</a>');
|
||||||
|
|
||||||
$.each($(data).find("unspent").children(), function(i,o){
|
$.each($(data).find("unspent").children(), function(i,o){
|
||||||
|
var tx = $(o).find("tx_hash").text();
|
||||||
|
var n = $(o).find("tx_output_n").text();
|
||||||
|
var script = (addr.isMultisig==true) ? $("#inputs .txIdScript:last").val(string) :$(o).find("script").text();
|
||||||
|
var amount = (($(o).find("value").text()*1)/100000000).toFixed(8);
|
||||||
|
|
||||||
if($("#inputs .txId:last").val()!=""){
|
addOutput(tx, n, script, amount);
|
||||||
$("#inputs .txidAdd").click();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#inputs .row:last input").attr('disabled',true);
|
|
||||||
|
|
||||||
var val = (($(o).find("value").text()*1)/100000000);
|
|
||||||
var txid = (($(o).find("tx_hash").text()).match(/.{1,2}/g).reverse()).join("")+'';
|
|
||||||
|
|
||||||
$("#inputs .txId:last").val(txid);
|
|
||||||
$("#inputs .txIdN:last").val($(o).find("tx_output_n").text());
|
|
||||||
$("#inputs .txIdAmount:last").val(val.toFixed(8));
|
|
||||||
if(isMultiSig==true){
|
|
||||||
$("#inputs .txIdScript:last").val(s);
|
|
||||||
} else {
|
|
||||||
$("#inputs .txIdScript:last").val($(o).find("script").text());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(thisbtn).html("Load").attr('disabled',false);
|
$("#redeemFromBtn").html("Load").attr('disabled',false);
|
||||||
totalInputAmount();
|
totalInputAmount();
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
/* retrieve unspent data from blockrio for mainnet */
|
||||||
|
function listUnspentBlockrio_BitcoinMainnet(addr){
|
||||||
|
$.ajax ({
|
||||||
|
type: "POST",
|
||||||
|
url: "https://btc.blockr.io/api/v1/address/unspent/"+addr,
|
||||||
|
dataType: "json",
|
||||||
|
error: function(data) {
|
||||||
|
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!');
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
if((data.status && data.data) && data.status=='success'){
|
||||||
|
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="https://btc.blockr.io/address/info/'+addr+'" target="_blank">'+addr+'</a>');
|
||||||
|
for(var i in data.data.unspent){
|
||||||
|
var o = data.data.unspent[i];
|
||||||
|
var tx = o.tx;
|
||||||
|
var n = o.n;
|
||||||
|
var script = o.script;
|
||||||
|
var amount = o.amount;
|
||||||
|
addOutput(tx, n, script, amount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function(data, status) {
|
||||||
|
$("#redeemFromBtn").html("Load").attr('disabled',false);
|
||||||
|
totalInputAmount();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* retrieve unspent data from blockrio for litecoin */
|
||||||
|
function listUnspentChainso_Litecoin(addr){
|
||||||
|
$.ajax ({
|
||||||
|
type: "GET",
|
||||||
|
url: "https://chain.so/api/v2/get_tx_unspent/ltc/"+addr,
|
||||||
|
dataType: "json",
|
||||||
|
error: function(data) {
|
||||||
|
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!');
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
console.log(data);
|
||||||
|
if((data.status && data.data) && data.status=='success'){
|
||||||
|
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="https://btc.blockr.io/address/info/'+addr+'" target="_blank">'+addr+'</a>');
|
||||||
|
for(var i in data.data.txs){
|
||||||
|
var o = data.data.txs[i];
|
||||||
|
var tx = o.txid;
|
||||||
|
var n = o.output_no;
|
||||||
|
var script = o.script_hex;
|
||||||
|
var amount = o.value;
|
||||||
|
addOutput(tx, n, script, amount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function(data, status) {
|
||||||
|
$("#redeemFromBtn").html("Load").attr('disabled',false);
|
||||||
|
totalInputAmount();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* math to calculate the inputs and outputs */
|
||||||
|
|
||||||
function totalInputAmount(){
|
function totalInputAmount(){
|
||||||
$("#totalInput").html('0.00');
|
$("#totalInput").html('0.00');
|
||||||
|
@ -679,12 +785,12 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// broadcast transaction via blockr.io (testnet)
|
// broadcast transaction via blockr.io for litecoin
|
||||||
function rawSubmitBlockrio_BitcoinTestnet(thisbtn){
|
function rawSubmitBlockrio_litecoin(thisbtn){
|
||||||
$(thisbtn).val('Please wait, loading...').attr('disabled',true);
|
$(thisbtn).val('Please wait, loading...').attr('disabled',true);
|
||||||
$.ajax ({
|
$.ajax ({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "https://tbtc.blockr.io/api/v1/tx/push",
|
url: "https://ltc.blockr.io/api/v1/tx/push",
|
||||||
data: {"hex":$("#rawTransaction").val()},
|
data: {"hex":$("#rawTransaction").val()},
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
error: function(data) {
|
error: function(data) {
|
||||||
|
@ -1068,6 +1174,9 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$("#settingsBtn").click(function(){
|
$("#settingsBtn").click(function(){
|
||||||
|
|
||||||
|
// log out of openwallet
|
||||||
|
$("#walletLogout").click();
|
||||||
|
|
||||||
$("#statusSettings").removeClass("alert-success").removeClass("alert-danger").addClass("hidden").html("");
|
$("#statusSettings").removeClass("alert-success").removeClass("alert-danger").addClass("hidden").html("");
|
||||||
$("#settings .has-error").removeClass("has-error");
|
$("#settings .has-error").removeClass("has-error");
|
||||||
|
|
||||||
|
@ -1096,8 +1205,6 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#coinjs_coin").change(function(){
|
$("#coinjs_coin").change(function(){
|
||||||
// log out of openwallet
|
|
||||||
$("#walletLogout").click();
|
|
||||||
|
|
||||||
var o = ($("option:selected",this).attr("rel")).split(";");
|
var o = ($("option:selected",this).attr("rel")).split(";");
|
||||||
|
|
||||||
|
@ -1136,11 +1243,10 @@ $(document).ready(function() {
|
||||||
|
|
||||||
function configureBroadcast(){
|
function configureBroadcast(){
|
||||||
var host = $("#coinjs_broadcast option:selected").val();
|
var host = $("#coinjs_broadcast option:selected").val();
|
||||||
var tx = coinjs.transaction();
|
|
||||||
$("#rawSubmitBtn").unbind("");
|
$("#rawSubmitBtn").unbind("");
|
||||||
if(host=="blockr.io_bitcointestnet"){
|
if(host=="blockr.io_litecoin"){
|
||||||
$("#rawSubmitBtn").click(function(){
|
$("#rawSubmitBtn").click(function(){
|
||||||
rawSubmitBlockrio_BitcoinTestnet(this)
|
rawSubmitBlockrio_litecoin(this)
|
||||||
});
|
});
|
||||||
} else if(host=="blockr.io_bitcoinmainnet"){
|
} else if(host=="blockr.io_bitcoinmainnet"){
|
||||||
$("#rawSubmitBtn").click(function(){
|
$("#rawSubmitBtn").click(function(){
|
||||||
|
@ -1151,14 +1257,10 @@ $(document).ready(function() {
|
||||||
rawSubmitDefault(this); // revert to default
|
rawSubmitDefault(this); // revert to default
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureGetUnspentTx(){
|
function configureGetUnspentTx(){
|
||||||
// function coming soon, which will allow you to retrieve unspent inputs
|
$("#redeemFromBtn").attr('rel',$("#coinjs_utxo option:selected").val());
|
||||||
// from other block chain providers
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* capture mouse movement to add entropy */
|
/* capture mouse movement to add entropy */
|
||||||
|
|
Loading…
Reference in a new issue