allow backend API choice between blockcypher/blockchair/chain.so

This commit is contained in:
Wowee0 2019-08-16 16:28:29 -05:00
parent 477ca8890d
commit efc16c10fb
2 changed files with 137 additions and 70 deletions

View file

@ -1353,8 +1353,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="litecoin_mainnet" rel="0x30;0xb0;0x32;0x019da462;0x019d9cfe;chain.so_litecoin;chain.so_litecoin">Litecoin (mainnet)</option> <option value="litecoin_mainnet" rel="0x30;0xb0;0x32;0x019da462;0x019d9cfe;blockcypher_litecoin;blockcypher_litecoin">Litecoin (mainnet)</option>
<option value="dogecoin_mainnet" rel="0x1e;0x9e;0x16;0x0827421e;0x089944e4;chain.so_dogecoin;chain.so_dogecoin">Dogecoin (mainnet)</option> <option value="dogecoin_mainnet" rel="0x1e;0x9e;0x16;0x0827421e;0x089944e4;blockcypher_dogecoin;blockcypher_dogecoin">Dogecoin (mainnet)</option>
<option value="carboncoin_mainnet" rel="0x2f;0xaf;0x05;0x488b21e;0x488ade4;cryptoid.info_carboncoin;cryptoid.info_carboncoin">Carboncoin (mainnet)</option> <option value="carboncoin_mainnet" rel="0x2f;0xaf;0x05;0x488b21e;0x488ade4;cryptoid.info_carboncoin;cryptoid.info_carboncoin">Carboncoin (mainnet)</option>
<option value="shadowcash_mainnet" rel="0x3f;0xbf;0x7d;0xee80286a;0xee8031e8;false;false">ShadowCash (mainnet)</option> <option value="shadowcash_mainnet" rel="0x3f;0xbf;0x7d;0xee80286a;0xee8031e8;false;false">ShadowCash (mainnet)</option>
<option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;false;false">Bitcoin (testnet)</option> <option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;false;false">Bitcoin (testnet)</option>
@ -1411,8 +1411,13 @@
<p class="text-muted">Select the network you wish to broadcast the transaction via</p> <p class="text-muted">Select the network you wish to broadcast the transaction via</p>
<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="chain.so_bitcoinmainnet"> Chain.so (Bitcoin mainnet)</option>
<option value="blockcypher_bitcoinmainnet"> Blockcypher.com (Bitcoin mainnet)</option> <option value="blockcypher_bitcoinmainnet"> Blockcypher.com (Bitcoin mainnet)</option>
<option value="blockcypher_litecoin"> Blockcypher.com (Litecoin)</option>
<option value="blockcypher_dogecoin"> Blockcypher.com (Dogecoin)</option>
<option value="blockchair_bitcoinmainnet"> Blockchair.com (Bitcoin mainnet)</option>
<option value="blockchair_litecoin"> Blockchair.com (Litecoin)</option>
<option value="blockchair_dogecoin"> Blockchair.com (Dogecoin)</option>
<option value="chain.so_bitcoinmainnet"> Chain.so (Bitcoin mainnet)</option>
<option value="chain.so_litecoin"> Chain.so (Litecoin)</option> <option value="chain.so_litecoin"> Chain.so (Litecoin)</option>
<option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option> <option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option>
<option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option> <option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>
@ -1428,6 +1433,13 @@
<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="blockcypher_bitcoinmainnet"> Blockcypher.com (Bitcoin mainnet)</option>
<option value="blockcypher_litecoin"> Blockcypher.com (Litecoin)</option>
<option value="blockcypher_dogecoin"> Blockcypher.com (Dogecoin)</option>
<option value="blockchair_bitcoinmainnet"> Blockchair.com (Bitcoin mainnet)</option>
<option value="blockchair_litecoin"> Blockchair.com (Litecoin)</option>
<option value="blockchair_dogecoin"> Blockchair.com (Dogecoin)</option>
<option value="chain.so_bitcoinmainnet"> Chain.so (Bitcoin mainnet)</option>
<option value="chain.so_litecoin"> Chain.so (Litecoin)</option> <option value="chain.so_litecoin"> Chain.so (Litecoin)</option>
<option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option> <option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option>
<option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option> <option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>

View file

@ -907,10 +907,32 @@ $(document).ready(function() {
var host = $(this).attr('rel'); var host = $(this).attr('rel');
if(host=='chain.so_litecoin'){ // api: blockcypher blockchair chain.so
listUnspentChainso_Litecoin(redeem); // network name "btc" "bitcoin" "BTC"
// network name "ltc" "litecoin" "LTC"
// network name "doge" "dogecoin" "DOGE"
debugger;
if(host=='chain.so_bitcoinmainnet'){
listUnspentChainso(redeem, "BTC");
} else if(host=='chain.so_litecoin'){
listUnspentChainso(redeem, "LTC");
} else if(host=='chain.so_dogecoin'){ } else if(host=='chain.so_dogecoin'){
listUnspentChainso_Dogecoin(redeem); listUnspentChainso(redeem, "DOGE");
} else if(host=='blockcypher_bitcoinmainnet'){
listUnspentBlockcypher(redeem, "btc");
} else if(host=='blockcypher_litecoin'){
listUnspentBlockcypher(redeem, "ltc");
} else if(host=='blockcypher_dogecoin'){
listUnspentBlockcypher(redeem, "doge");
} else if(host=='blockchair_bitcoinmainnet'){
listUnspentBlockchair(redeem, "bitcoin");
} else if(host=='blockchair_litecoin'){
listUnspentBlockchair(redeem, "litecoin");
} else if(host=='blockchair_dogecoin'){
listUnspentBlockchair(redeem, "dogecoin");
} else if(host=='cryptoid.info_carboncoin'){ } else if(host=='cryptoid.info_carboncoin'){
listUnspentCryptoidinfo_Carboncoin(redeem); listUnspentCryptoidinfo_Carboncoin(redeem);
} else { } else {
@ -1054,25 +1076,26 @@ $(document).ready(function() {
} }
/* retrieve unspent data from chainso for litecoin */ /* retrieve unspent data from blockcypher */
function listUnspentChainso_Litecoin(redeem){ function listUnspentBlockcypher(redeem,network){
$.ajax ({ $.ajax ({
type: "GET", type: "GET",
url: "https://chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, url: "https://api.blockcypher.com/v1/"+network+"/main/addrs/"+redeem.addr+"?includeScript=true&unspentOnly=true",
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!'); $("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!');
}, },
success: function(data) { success: function(data) {
if((data.status && data.data) && data.status=='success'){ if(data.txrefs) {
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>'); $("#redeemFromAddress").removeClass('hidden').html(
for(var i in data.data.txs){ '<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
var o = data.data.txs[i]; for(var i in data.txrefs){
var tx = ((""+o.txid).match(/.{1,2}/g).reverse()).join("")+''; var o = data.txrefs[i]
var tx = ((""+o.tx_hash).match(/.{1,2}/g).reverse()).join("")+'';
if(tx.match(/^[a-f0-9]+$/)){ if(tx.match(/^[a-f0-9]+$/)){
var n = o.output_no; var n = o.tx_output_n;
var script = (redeem.redeemscript==true) ? redeem.decodedRs : o.script_hex; var script = (redeem.redeemscript==true) ? redeem.decodedRs : o.script;
var amount = o.value; var amount = ((o.value.toString()*1)/100000000).toFixed(8);
addOutput(tx, n, script, amount); addOutput(tx, n, script, amount);
} }
} }
@ -1121,19 +1144,54 @@ $(document).ready(function() {
} }
/* retrieve unspent data from chain.so for dogecoin */
function listUnspentChainso_Dogecoin(redeem){ /* retrieve unspent data from blockchair */
function listUnspentBlockchair(redeem,network){
$.ajax ({ $.ajax ({
type: "GET", type: "GET",
url: "https://chain.so/api/v2/get_tx_unspent/doge/"+redeem.addr, url: "https://api.blockchair.com/"+network+"/dashboards/address/"+redeem.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.context && data.data) && data.context.code =='200'){
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
var all_info = data.data[redeem.addr];
for(var i in all_info.utxo){
var o = all_info.utxo[i];
var tx = ((""+o.transaction_hash).match(/.{1,2}/g).reverse()).join("")+'';
if(tx.match(/^[a-f0-9]+$/)){
var n = o.index;
var script = (redeem.redeemscript==true) ? redeem.decodedRs : all_info.address.script_hex;
var amount = ((o.value.toString()*1)/100000000).toFixed(8);
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 chainso */
function listUnspentChainso(redeem, network){
$.ajax ({
type: "GET",
url: "https://chain.so/api/v2/get_tx_unspent/"+network+"/"+redeem.addr,
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!'); $("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!');
}, },
success: function(data) { success: function(data) {
if((data.status && data.data) && data.status=='success'){ if((data.status && data.data) && data.status=='success'){
$("#redeemFromAddress").removeClass('hidden').html( $("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
'<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+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).match(/.{1,2}/g).reverse()).join("")+''; var tx = ((""+o.txid).match(/.{1,2}/g).reverse()).join("")+'';
@ -1155,6 +1213,7 @@ $(document).ready(function() {
}); });
} }
/* math to calculate the inputs and outputs */ /* math to calculate the inputs and outputs */
function totalInputAmount(){ function totalInputAmount(){
@ -1268,11 +1327,11 @@ $(document).ready(function() {
} }
// broadcast transaction via chain.so (mainnet) // broadcast transaction via chain.so (mainnet)
function rawSubmitChainso_BitcoinMainnet(thisbtn){ function rawSubmitChainso(thisbtn, network){
$(thisbtn).val('Please wait, loading...').attr('disabled',true); $(thisbtn).val('Please wait, loading...').attr('disabled',true);
$.ajax ({ $.ajax ({
type: "POST", type: "POST",
url: "https://chain.so/api/v2/send_tx/BTC/", url: "https://chain.so/api/v2/send_tx/"+network+"/",
data: {"tx_hex":$("#rawTransaction").val()}, data: {"tx_hex":$("#rawTransaction").val()},
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
@ -1284,7 +1343,7 @@ $(document).ready(function() {
}, },
success: function(data) { success: function(data) {
if(data.status && data.data.txid){ if(data.status && data.data.txid){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + data.data.txid + '<br> <a href="https://chain.so/tx/BTC/' + data.data.txid + '" target="_blank">View on Blockchain Explorer</a>'); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + data.data.txid + '<br> <a href="https://chain.so/tx/'+network+'/' + data.data.txid + '" target="_blank">View on Blockchain Explorer</a>');
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
} }
@ -1297,11 +1356,11 @@ $(document).ready(function() {
} }
// broadcast transaction via blockcypher.com (mainnet) // broadcast transaction via blockcypher.com (mainnet)
function rawSubmitblockcypher_BitcoinMainnet(thisbtn){ function rawSubmitblockcypher(thisbtn, network){
$(thisbtn).val('Please wait, loading...').attr('disabled',true); $(thisbtn).val('Please wait, loading...').attr('disabled',true);
$.ajax ({ $.ajax ({
type: "POST", type: "POST",
url: "https://api.blockcypher.com/v1/btc/main/txs/push", url: "https://api.blockcypher.com/v1/"+network+"/main/txs/push",
data: JSON.stringify({"tx":$("#rawTransaction").val()}), data: JSON.stringify({"tx":$("#rawTransaction").val()}),
error: function(data) { error: function(data) {
var obj = $.parseJSON(data.responseText); var obj = $.parseJSON(data.responseText);
@ -1312,7 +1371,8 @@ $(document).ready(function() {
}, },
success: function(data) { success: function(data) {
if((data.tx) && data.tx.hash){ if((data.tx) && data.tx.hash){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + data.tx.hash + '<br> <a href="https://live.blockcypher.com/btc/tx/' + data.tx.hash + '" target="_blank">View on Blockchain Explorer</a>'); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden")
.html(' TXID: ' + data.tx.hash + '<br> <a href="https://live.blockcypher.com/'+network+'/tx/' + data.tx.hash + '" target="_blank">View on Blockchain Explorer</a>');
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
} }
@ -1324,14 +1384,13 @@ $(document).ready(function() {
}); });
} }
// broadcast transaction via blockchair
// broadcast transaction via chain.so for litecoin function rawSubmitblockchair(thisbtn, network){
function rawSubmitchainso_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://chain.so/api/v2/send_tx/LTC", url: "https://api.blockchair.com/"+network+"/push/transaction",
data: {"tx_hex":$("#rawTransaction").val()}, data: {"data":$("#rawTransaction").val()},
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
var obj = $.parseJSON(data.responseText); var obj = $.parseJSON(data.responseText);
@ -1343,39 +1402,9 @@ $(document).ready(function() {
}, },
success: function(data) { success: function(data) {
// console.info(JSON.stringify(data, null, 4)); // console.info(JSON.stringify(data, null, 4));
if((data.status && data.data) && data.status=='success'){ if((data.context && data.data) && data.context.code=='200'){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + data.data.txid + '<br> <a href="https://chain.so/tx/LTC/' + data.data.txid + '" target="_blank">View on Blockchain Explorer</a>'); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden")
} else { .html(' TXID: ' + data.data.transaction_hash + '<br> <a href="https://blockchair.com/'+network+'/transaction/' + data.data.transaction_hash + '" target="_blank">View on Blockchain Explorer</a>');
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
}
},
complete: function(data, status) {
$("#rawTransactionStatus").fadeOut().fadeIn();
$(thisbtn).val('Submit').attr('disabled',false);
}
});
}
// broadcast transaction via chain.so for dogecoin
function rawSubmitchainso_dogecoin(thisbtn){
$(thisbtn).val('Please wait, loading...').attr('disabled',true);
$.ajax ({
type: "POST",
url: "https://chain.so/api/v2/send_tx/DOGE",
data: {"tx_hex":$("#rawTransaction").val()},
dataType: "json",
error: function(data) {
var obj = $.parseJSON(data.responseText);
var r = ' ';
r += (obj.data.tx_hex) ? ' '+obj.data.tx_hex : '';
r = (r!='') ? r : ' Failed to broadcast'; // build response
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
// console.error(JSON.stringify(data, null, 4));
},
success: function(data) {
// console.info(JSON.stringify(data, null, 4));
if((data.status && data.data) && data.status=='success'){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + data.data.txid + '<br> <a href="https://chain.so/tx/DOGE/' + data.data.txid + '" target="_blank">View on Blockchain Explorer</a>');
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
} }
@ -1888,22 +1917,48 @@ $(document).ready(function() {
function configureBroadcast(){ function configureBroadcast(){
var host = $("#coinjs_broadcast option:selected").val(); var host = $("#coinjs_broadcast option:selected").val();
// api: blockcypher blockchair chain.so
// network name "btc" "bitcoin" "BTC"
// network name "ltc" "litecoin" "LTC"
// network name "doge" "dogecoin" "DOGE"
$("#rawSubmitBtn").unbind(""); $("#rawSubmitBtn").unbind("");
if(host=="chain.so_bitcoinmainnet"){ if(host=="chain.so_bitcoinmainnet"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
rawSubmitChainso_BitcoinMainnet(this); rawSubmitChainso(this, "BTC");
}); });
} else if(host=="chain.so_litecoin"){ } else if(host=="chain.so_litecoin"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
rawSubmitchainso_litecoin(this); rawSubmitchainso(this, "LTC");
}); });
} else if(host=="chain.so_dogecoin"){ } else if(host=="chain.so_dogecoin"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
rawSubmitchainso_dogecoin(this); rawSubmitchainso(this, "DOGE");
}); });
} else if(host=="blockcypher_bitcoinmainnet"){ } else if(host=="blockcypher_bitcoinmainnet"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
rawSubmitblockcypher_BitcoinMainnet(this); rawSubmitblockcypher(this, "btc");
});
} else if(host=="blockcypher_litecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockcypher(this, "ltc");
});
} else if(host=="blockcypher_dogecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockcypher(this, "doge");
});
} else if(host=="blockchair_bitcoinmainnet"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockchair(this, "bitcoin");
});
} else if(host=="blockchair_litecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockchair(this, "litecoin");
});
} else if(host=="blockchair_dogecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockchair(this, "dogecoin");
}); });
} else if(host=="cryptoid.info_carboncoin"){ } else if(host=="cryptoid.info_carboncoin"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){