From b34c0f3549177884c19be3e7de2c7d91321d1e67 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Tue, 24 Nov 2015 04:55:07 +0100 Subject: [PATCH 01/92] Added Peercoin,NuBits,NuShares,BlockCredits,BlockShares,Peershares-default and testnets. --- LICENSE | 20 +- README.md | 12 +- index.html | 191 +++++--- js/coin.js | 53 +- js/{coinbin.js => cointoolkit.js} | 786 +++++++++++++++++------------- 5 files changed, 620 insertions(+), 442 deletions(-) rename js/{coinbin.js => cointoolkit.js} (71%) diff --git a/LICENSE b/LICENSE index cf457637..1ebdadc4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,20 +1,2 @@ -The MIT License (MIT) - Copyright (c) 2014 OutCast3k - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Copyright (c) 2015 ttutdxh.nubits@gmail.com diff --git a/README.md b/README.md index dd4e44a1..1a8b794b 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -coinbin +Cointoolkit ======= -A Open Source Browser Based Bitcoin Wallet. Version 1.2 beta by OutCast3k +A Open Source Browser Based Bitcoin Wallet. -Live version available at http://coinb.in/ or http://4zpinp6gdkjfplhk.onion +Live version available at http://ttutdxh-nubits.github.io/cointoolkit/ -Github URL: https://github.com/OutCast3k/coinbin/ - -Coinb.in supports a number of key features such as: +Github URL: https://github.com/ttutdxh-nubits/cointoolkit - Offline Compressed & uncompressed Address creation. - Offline Multisignature Address creation. @@ -28,4 +26,4 @@ Coinb.in supports a number of key features such as: - HD (bip32) support - Supports altcoins such as litecoin -Donate to 1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg to see more development! +Donate to 1JbsRVvU93PXN2JovuDE2NJTVNWkGEFrvx to see more development! diff --git a/index.html b/index.html index 9f7d4d0f..3921f6f3 100644 --- a/index.html +++ b/index.html @@ -2,11 +2,11 @@ - Bitcoin Wallet by Coinb.in + Cointoolkit - + - + @@ -30,7 +30,7 @@ - + @@ -45,7 +45,7 @@ - + Cointoolkit @@ -79,13 +88,13 @@
-

Coinb.in Welcome to the Blockchain

+

Cointoolkit Welcome to the Blockchain

-

Bitcoin. It's your money!

-

Be your own bank, take control of your own money and start using Bitcoin today!

+

Cointoolkit

+

Be your own bank, take control of your own money and start using NuBits today!

Learn more »

@@ -94,16 +103,16 @@

Bitcoin. It's your money!

Open Source

-

Coinbin is an open source web based wallet written in javascript and released under the MIT license which means its free to use and edit.

+

Cointoolkit is an open source web based wallet written in javascript and released under the MIT license which means its free to use and edit.

MultiSig

-

We offer a fully transparent multisig solution which works seamlessly offline and with other bitcoin clients.

+

We offer a fully transparent multisig solution which works seamlessly offline and with other wallets.

-

Raw Transactions

+

Raw Transactions

Create, verify, sign and broadcast custom raw transactions online with advanced features and minimal effort!

@@ -121,7 +130,7 @@

Addresses

Development

-

Use what we've built to write your own projects! See our documention (coming soon), or contribute at github.

+

Use what we've built to write your own projects! See our documention (coming soon), or contribute at github.

@@ -129,7 +138,7 @@

Development

-

Open Wallet browser based bitcoin wallet

+

Open Wallet browser based wallet

@@ -218,7 +227,7 @@

Open Wallet browser based bitcoin wallet

- +
@@ -238,18 +247,18 @@

Open Wallet browser based bitcoin wallet

-

New Address create a new address

-

Any keys used you will need to manually store safely as they will be needed later to redeem the bitcoins.

- - +

Create new address

+

Any keys used you will need to manually store safely as they will be needed later to redeem the coins.

+ + click generate to update
- +
- +
@@ -304,7 +313,7 @@

New Multisig Address Secure multisig address

-

Public keys can be generated in your browser or from your bitcoin client.

+

Public keys can be generated in your browser or from your wallet.

Enter the public keys of all the participants, to create a multi signature address. Maximum of 15 allowed. Compressed and uncompressed public keys are accepted.

@@ -367,7 +376,7 @@

New Multisig Address Secure multisig address

-

This script should be saved and should be shared with all the participants before a payment is made, so they may validate the authenticity of the address, it will also be used later to release the bitcoins.

+

This script should be saved and should be shared with all the participants before a payment is made, so they may validate the authenticity of the address, it will also be used later to release the coins.

@@ -454,7 +463,14 @@

Transaction Create a new transaction


+ +
+ +

Indicates the timestamp of a transaction.

+ +
+

The settings page can be used to select alternative networks of which you can retrieve your unspent outputs and broadcast a signed transaction into.

@@ -487,7 +503,7 @@

Transaction Create a new transaction

- +
@@ -567,7 +583,7 @@

Transaction Create a new transaction

Size: 0 bytes

- +
@@ -609,8 +625,10 @@

Redeem Script

Transaction Script

The above script has been decoded

Version:
+
Transaction Time:
Transaction Size:
Lock time:
+
Unit:

@@ -744,7 +762,7 @@

Keys

- +
@@ -786,19 +804,19 @@

Sign Transaction once a transaction has been verified

Size: 0 bytes

- +
-

Broadcast Transaction into the bitcoin network

+

Broadcast Transaction into the network

-

Enter your hex encoded bitcoin transaction

+

Enter your hex encoded transaction


- +
@@ -809,44 +827,55 @@

Development Javascript framework, API and more

-

About open source bitcoin wallet

+

About open source toolkit

Version 1.2

-

Compatible with bitcoin-qt

-

Github https://github.com/OutCast3k/coinbin/

-

TOR 4zpinp6gdkjfplhk.onion

+

Github https://github.com/ttutdxh-nubits/cointoolkit

What is Bitcoin?

Bitcoin is a type of digital currency in which encryption techniques are used to regulate the generation of units of currency and verify the transfer of funds, operating independently of a central bank. See weusecoins.com for more information.

-

If you are looking to buy some Bitcoin try LocalBitcoins.com.

+

If you are looking to buy some Bitcoin try LocalBitcoins.com.

+

This toolkit supports multiple cryptoassets other than bitcoin

Information

-

Coinb.in is a free and open source project released under the MIT license, originally by OutCast3k in 2013. Discussion of the project can be found at bitcointalk.org during its early testing stages when its primary focus was to develop a proof of concept multisig solution in javascript.

-

Coinb.in is run and funded by the generosity of others in terms of development and hosting.

-

Privacy

-

Coinb.in beleives strongly in privacy, not only do we support the use of TOR, the site does not collect and store IP or transaction data via our servers nor do we store your bitcoins private key. We do route traffic via cloudflare using an SSL certificate.

+

Cointoolkit is a free and open source project released under the MIT license, originally released by OutCast3k as Coinb.in in 2013, and modified to work with Peershares assets by ttutdxh.nubits@gmail.com

Donate

-

Please donate to 1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg if you found this project useful or want to see more features!

+

Please donate to 1JbsRVvU93PXN2JovuDE2NJTVNWkGEFrvx if you found this project useful or want to see more features!

-

Settings making coinb.in even better!

-

These simple settings below make coinb.in one of the most decentralized wallets in the world.

+

Settings

+

Customize the wallet settings to allow using the toolkit in other cryptoassets.

Network:

Select which network you'd like to use for key pair generation.

-
-
+
HD Pub:
-
+
HD Priv:
+ +
+ Extra time field?:
+ +
+ +
+ Extra unit field value?:
+ +
+ +
+ Decimal places:
+ +

-
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.

- +
- Broadcast:
-

Select the network you wish to broadcast the transaction via

- +
@@ -903,12 +945,10 @@

Settings making coinb.in even better!

- Unspent outputs:
-

Select the network you wish to retreive your unspent inputs from

- +
@@ -918,12 +958,12 @@

Settings making coinb.in even better!

- +

-

This page uses javascript to generate your addresses and sign your transactions within your browser, this means we never receive your private keys, this can be independently verified by reviewing the source code on github. You can even download this page and host it yourself or run it offline!

+

This page uses javascript to generate your addresses and sign your transactions within your browser, this means we never receive your private keys, this can be independently verified by reviewing the source code on github. You can even download this page and host it yourself or run it offline!


@@ -1024,15 +1064,8 @@
- -
@@ -1074,7 +1107,7 @@
- - + +
diff --git a/js/coin.js b/js/coin.js index 4f40f6f4..7472f3e6 100644 --- a/js/coin.js +++ b/js/coin.js @@ -36,8 +36,18 @@ /* start of address functions */ /* generate a private and public keypair, with address and WIF address */ - coinjs.newKeys = function(input){ - var privkey = (input) ? Crypto.SHA256(input) : this.newPrivkey(); + coinjs.newKeys = function(input, isPrivKey){ + if (input == "" || (isPrivKey && !input.match(/^[a-f0-9]{64}$/gi))) { + var message = (input == "")?'Empty seed':'Invalid private key'; + return { + 'privkey': message, + 'pubkey': message, + 'address': message, + 'wif': message, + 'compressed': message, + }; + } + var privkey = (input) ? ((isPrivKey)?input:Crypto.SHA256(input)) : this.newPrivkey(); var pubkey = this.newPubkey(privkey); return { 'privkey': privkey, diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 99cdc683..4fabf178 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -257,8 +257,9 @@ $(document).ready(function() { if($("#newCompressed").is(":checked")){ coinjs.compressed = true; } + var s = ($("#newBrainwallet").is(":checked")) ? $("#brainwallet").val() : null; - var coin = coinjs.newKeys(s); + var coin = coinjs.newKeys(s, ($("#newBrainwallet").is(":checked") && $("#brainwalletIsPrivKey").is(":checked"))); $("#newGeneratedAddress").val(coin.address); $("#newPubKey").val(coin.pubkey); $("#newPrivKey").val(coin.wif); @@ -273,14 +274,13 @@ $(document).ready(function() { $("#aes256passStatus").removeClass("hidden"); } $("#newPrivKeyEnc").val(CryptoJS.AES.encrypt(coin.wif, $("#aes256pass").val())+''); - $("#newAddrType").text($("#coinSelector option:selected").text()); }); $("#newBrainwallet").click(function(){ if($(this).is(":checked")){ - $("#brainwallet").removeClass("hidden"); + $("#keyFromData").removeClass("hidden"); } else { - $("#brainwallet").addClass("hidden"); + $("#keyFromData").addClass("hidden"); } }); From 0484e191ad6b51332cacd3c1625330c01c1f5c0f Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Tue, 24 Nov 2015 17:10:48 +0100 Subject: [PATCH 03/92] Global debug flag --- js/coin.js | 8 +++++--- js/cointoolkit.js | 17 ++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/js/coin.js b/js/coin.js index 7472f3e6..04fdc4c3 100644 --- a/js/coin.js +++ b/js/coin.js @@ -11,6 +11,8 @@ var coinjs = window.coinjs = function () { }; /* public vars */ + coinjs.debug = false; + coinjs.txExtraTimeField = false; coinjs.txExtraTimeFieldValue = false; coinjs.txExtraUnitField = false; @@ -278,7 +280,7 @@ publicKeyBytes.unshift(0x04); return Crypto.util.bytesToHex(publicKeyBytes); } catch (e) { - // console.log(e); + if (coinjs.debug) {console.log(e)}; return false; } } @@ -670,7 +672,7 @@ r.address = multi['address']; } } catch(e) { - // console.log(e); + if (coinjs.debug) {console.log(e)}; r = false; } return r; @@ -1142,7 +1144,7 @@ } else if (d['type'] == 'multisig') { this.signmultisig(i, wif); } else { - console.log('could not sign input', i); + if (coinjs.debug) {console.log('could not sign input', i)}; // could not sign } } diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 4fabf178..bb8f5308 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -798,7 +798,7 @@ $(document).ready(function() { var tx = coinjs.transaction(); try { var decode = tx.deserialize($("#verifyScript").val()); - // console.log(decode); + if (coinjs.debug) {console.log(decode)}; $("#verifyTransactionData .transactionVersion").html(decode['version']); $("#verifyTransactionData .transactionTime").html(decode['nTime']); $("#verifyTransactionData .transactionSize").html(decode.size()+' bytes'); @@ -1000,7 +1000,7 @@ $(document).ready(function() { $("#signedData .txSize").html(t.size()); $("#signedData").removeClass('hidden').fadeIn(); } catch(e) { - console.log(e); + if (coinjs.debug) {console.log(e)}; } } else { $("#signedDataError").removeClass('hidden').delay(2000).queue(function(){ @@ -1208,6 +1208,7 @@ $(document).ready(function() { default: function(redeem){ var tx = coinjs.transaction(); tx.listUnspent(redeem.addr, function(data){ + if (coinjs.debug) {console.log(data)}; if(redeem.addr) { $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); @@ -1236,7 +1237,7 @@ $(document).ready(function() { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); }, success: function(data) { - console.log(data); + if (coinjs.debug) {console.log(data)}; if((data.status && data.data) && data.status=='success'){ $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); for(var i in data.data.unspent){ @@ -1327,7 +1328,7 @@ $(document).ready(function() { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); }, success: function(data) { - console.log(data); + if (coinjs.debug) {console.log(data)}; if((data.status && data.data) && data.status=='success'){ $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); for(var i in data.data.txs){ @@ -1365,7 +1366,8 @@ $(document).ready(function() { r = (r!='') ? r : ' Failed to broadcast'; // build response $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, - success: function(data) { + success: function(data) { + if (coinjs.debug) {console.log(data)}; var obj = $.parseJSON(data.responseText); if((obj.status && obj.data) && obj.status=='success'){ $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+obj.data); @@ -1393,14 +1395,11 @@ $(document).ready(function() { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); }, success: function(data) { - console.log(data); + if (coinjs.debug) {console.log(data)}; if((data.exists && data.tx) && data.address == redeem.addr){ - console.log(1); $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); for(var i in data.tx){ - console.log(1); for(var v in data.tx[i].outputs){ - console.log(data.tx[i].outputs[v].status, data.tx[i].outputs[v].outAddress, redeem.addr); if (data.tx[i].outputs[v].status == "unspent" && data.tx[i].outputs[v].outAddress == redeem.addr) { var o = data.tx[i].outputs[v]; var tx = data.tx[i].txHash; From 763f96a4926a141193e42fc9e819a341b6d6a43d Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Tue, 24 Nov 2015 17:11:07 +0100 Subject: [PATCH 04/92] Mode change cleanup --- js/cointoolkit.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index bb8f5308..c4a5c4d9 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1023,6 +1023,9 @@ $(document).ready(function() { // log out of openwallet $("#walletLogout").click(); + + $("#newGeneratedAddress, #newPubKey, #newPrivKey, #newHDxpub, #newHDxprv").val(""); + $("#multiSigData").removeClass('show').addClass('hidden').hide(); $("#statusSettings").removeClass("alert-success").removeClass("alert-danger").addClass("hidden").html(""); $("#settings .has-error").removeClass("has-error"); @@ -1436,7 +1439,7 @@ $(document).ready(function() { } $("#coinSelector").change(); - $("#newKeysBtn, #newHDKeysBtn").click(); + //$("#newKeysBtn, #newHDKeysBtn").click(); var _getBroadcast = _get("broadcast"); if(_getBroadcast[0]){ From 3d395cb6ded1ad02407b6ab5cb5de479662bb5d5 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Tue, 24 Nov 2015 17:43:23 +0100 Subject: [PATCH 05/92] Added known pubkey identification --- index.html | 9 +++++++++ js/cointoolkit.js | 8 +++++++- known-pubkeys.js | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 known-pubkeys.js diff --git a/index.html b/index.html index d362f4e4..ea6acfb2 100644 --- a/index.html +++ b/index.html @@ -31,6 +31,8 @@ + + @@ -619,6 +621,13 @@

Redeem Script

?

+ + + + + + +
AddressPubkeyIdentity (if known)
diff --git a/js/cointoolkit.js b/js/cointoolkit.js index c4a5c4d9..20508b5f 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -783,8 +783,14 @@ $(document).ready(function() { $("#verifyRsData table tbody").html(""); for(var i=0;i').appendTo("#verifyRsData table tbody"); + $('').appendTo("#verifyRsData table tbody"); } $("#verifyRsData").removeClass("hidden"); $("#verify .verifyLink").attr('href','?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); diff --git a/known-pubkeys.js b/known-pubkeys.js new file mode 100644 index 00000000..6dd6f6aa --- /dev/null +++ b/known-pubkeys.js @@ -0,0 +1,3 @@ +var known_pubkeys = { + // "pubkey": {name:"John Doe"}, +}; \ No newline at end of file From a6fb55edcb1ce99233b6c932193cf30854047f22 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Tue, 24 Nov 2015 17:51:16 +0100 Subject: [PATCH 06/92] Added known pubkeys --- known-pubkeys.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/known-pubkeys.js b/known-pubkeys.js index 6dd6f6aa..d41576e8 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -1,3 +1,8 @@ var known_pubkeys = { // "pubkey": {name:"John Doe"}, + "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT member @jooize"}, + "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": {name:"Nu FLOT member @woodstockmerkle"}, + "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT member @masterOfDisaster"}, + "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT member @dysconnect"}, + "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT member @ttutdxh"}, }; \ No newline at end of file From a0d4b83e983f2c0cf6d72f9ee190b989f7db576e Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Tue, 24 Nov 2015 22:17:58 +0100 Subject: [PATCH 07/92] Added identification where possible --- index.html | 68 ++++++++++++++++++++++++--------- js/coin.js | 20 ++++------ js/cointoolkit.js | 96 ++++++++++++++++++++++++++++++++++++----------- known-pubkeys.js | 27 +++++++++---- 4 files changed, 153 insertions(+), 58 deletions(-) diff --git a/index.html b/index.html index ea6acfb2..539cd027 100644 --- a/index.html +++ b/index.html @@ -330,13 +330,27 @@

New Multisig Address Secure multisig address

-
-
-
- +
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ +
+ +
- -

@@ -495,24 +509,30 @@

Transaction Create a new transaction

Enter the address and amount you wish to make a payment to.

-
+
-
+
+
+ +
-
+
-
+
+
+ +
@@ -606,16 +626,29 @@

Verify transactions and other scripts

From fb532309154d4353821dc0f78cc5fbd036a57f77 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Wed, 25 Nov 2015 16:48:13 +0100 Subject: [PATCH 17/92] Usability fix --- index.html | 10 +++++++++- js/cointoolkit.js | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 18cbf5fa..abfbabcf 100644 --- a/index.html +++ b/index.html @@ -283,7 +283,7 @@

Create new address

- + @@ -293,6 +293,14 @@

Create new address

+ + +
+ + + + +

Address Options

You can use the advanced options below to generate different kind of keys and addresses.

diff --git a/js/cointoolkit.js b/js/cointoolkit.js index a9bf64a5..8235de30 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -262,7 +262,8 @@ $(document).ready(function() { var coin = coinjs.newKeys(s, ($("#newBrainwallet").is(":checked") && $("#brainwalletIsPrivKey").is(":checked"))); $("#newGeneratedAddress").val(coin.address); $("#newPubKey").val(coin.pubkey); - $("#newPrivKey").val(coin.wif); + $("#newPrivKeyWif").val(coin.wif); + $("#newPrivKey").val(coin.privkey); /* encrypted key code */ if((!$("#encryptKey").is(":checked")) || $("#aes256pass").val()==$("#aes256pass_confirm").val()){ @@ -1074,7 +1075,7 @@ $(document).ready(function() { // log out of openwallet $("#walletLogout").click(); - $("#newGeneratedAddress, #newPubKey, #newPrivKey, #newHDxpub, #newHDxprv").val(""); + $("#newGeneratedAddress, #newPubKey, #newPrivKeyWif, #newPrivKey, #newHDxpub, #newHDxprv").val(""); $("#multiSigData").removeClass('show').addClass('hidden').hide(); $("#statusSettings").removeClass("alert-success").removeClass("alert-danger").addClass("hidden").html(""); From 4b1f0e8f7479cfbbefd446b306c63ad84e9b4287 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 26 Nov 2015 00:05:20 +0100 Subject: [PATCH 18/92] Added new Nu FLOT members --- known-pubkeys.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/known-pubkeys.js b/known-pubkeys.js index 37328d3d..e7a9e583 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -9,8 +9,11 @@ var known = { "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT member @jooize"}, "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": {name:"Nu FLOT member @woodstockmerkle"}, "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT member @masterOfDisaster"}, + "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu @Dhume"}, "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT member @dysconnect"}, "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT member @ttutdxh"}, + "03686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe740495": {name:"Nu FLOT member @cryptog"}, + "039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb66808": {name:"Nu FLOT member @mhps"}, }, scriptHash: { // Nu FLOT addresses scripthash From 54bf2e881644a892f2f864a9ad6beee39a0bc727 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 26 Nov 2015 00:09:41 +0100 Subject: [PATCH 19/92] Added new Nu FLOT NSR address --- known-pubkeys.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index e7a9e583..ad3ebde8 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -17,6 +17,7 @@ var known = { }, scriptHash: { // Nu FLOT addresses scripthash - "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT Address testing"}, + "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT group 1st address"}, + "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NSR group 1st address"}, } } \ No newline at end of file From 38a3ef81a409f3df025887c879f0914abe36c550 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 26 Nov 2015 03:15:32 +0100 Subject: [PATCH 20/92] Schema fixes --- css/style.css | 15 +++++++++++ index.html | 65 ++++++++++++++++++++++++++++++----------------- js/cointoolkit.js | 6 ++++- 3 files changed, 62 insertions(+), 24 deletions(-) diff --git a/css/style.css b/css/style.css index 9cebfa22..df67696b 100644 --- a/css/style.css +++ b/css/style.css @@ -24,3 +24,18 @@ body { background-color: #f5f5f5; padding-top: 20px; } + +.glyphicon-refresh-animate { + -animation: spin 1s infinite linear; + -webkit-animation: spin2 1s infinite linear; +} + +@-webkit-keyframes spin2 { + from { -webkit-transform: rotate(0deg);} + to { -webkit-transform: rotate(360deg);} +} + +@keyframes spin { + from { transform: scale(1) rotate(0deg);} + to { transform: scale(1) rotate(360deg);} +} \ No newline at end of file diff --git a/index.html b/index.html index abfbabcf..92af2d8c 100644 --- a/index.html +++ b/index.html @@ -699,26 +699,34 @@

Redeem Script

diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 8235de30..d7cfa016 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -633,7 +633,7 @@ $(document).ready(function() { $("#inputs .txidRemove, #inputs .txidClear").click(); } - $("#redeemFromBtn").html("Please wait, loading...").attr('disabled',true); + $("#redeemFromBtn").html('Please wait, loading... ').attr('disabled',true); var host = $(this).attr('rel'); providers[$("#coinSelector").val()].listUnspent[host](redeem); @@ -841,6 +841,10 @@ $(document).ready(function() { $("#verifyTransactionData .transactionSize").html(decode.size()+' bytes'); $("#verifyTransactionData .transactionLockTime").html(decode['lock_time']); $("#verifyTransactionData .transactionUnit").html(String.fromCharCode(decode['nUnit'])); + $("#verifyTransactionData .verifyToSign").on( "click", function() { + $("#signTransaction").val(decode.serialize()); + window.location.hash = "#sign"; + }); $("#verifyTransactionData").removeClass("hidden"); $("#verifyTransactionData tbody").html(""); From 6524496c6ba0ddc46513e5f3cc6abe1f742a561b Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 26 Nov 2015 03:16:00 +0100 Subject: [PATCH 21/92] Improved blockexplorer.nu provider --- js/cointoolkit.js | 69 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index d7cfa016..15e5eeea 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1260,36 +1260,81 @@ $(document).ready(function() { /* external providers */ - var listunspent_blockexplorer_nu = function(redeem){ + var listunspent_blockexplorer_nu = function(redeem, page){ + if (typeof(page) == "undefined") { + page = 1; + } $.ajax ({ type: "GET", - url: "https://crossorigin.me/https://blockexplorer.nu/api/addressDetails/"+redeem.addr+"/1/newest", + url: "//crossorigin.me/https://blockexplorer.nu/api/addressDetails/"+redeem.addr+"/"+page+"/oldest", dataType: "json", + cache: "false", error: function(data) { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs! Is http://blockexplorer.nu/ down?'); + $("#redeemFromBtn").html("Load").attr('disabled',false); }, success: function(data) { if (coinjs.debug) {console.log(data)}; - if((data.exists && data.tx) && data.address == redeem.addr){ - $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + if (!data.exists) { + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + $("#redeemFromBtn").html("Load").attr('disabled',false); + } else if (data.address == redeem.addr && data.tx){ for(var i in data.tx){ for(var v in data.tx[i].outputs){ if (data.tx[i].outputs[v].status == "unspent" && data.tx[i].outputs[v].outAddress == redeem.addr) { var o = data.tx[i].outputs[v]; - var tx = data.tx[i].txHash; - var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : "00"; var amount = o.outValInt; - addOutput(tx, o.out_num, script, amount); + var tx = data.tx[i].txHash; + + if (redeem.isMultisig) { + var script = $("#redeemFrom").val(); + addOutput(tx, o.out_num, script, amount); + } else {; + (function(txid, out_num, amount){ + var msgTxError = ' Unexpected error, unable to retrieve transaction '+ txid +'! Is http://blockexplorer.nu/ down?'; + $.ajax ({ + type: "GET", + url: "//crossorigin.me/https://blockexplorer.nu/api/txDetails/"+txid, + dataType: "json", + cache: "false", + error: function(data) { + $("#redeemFromStatus").removeClass('hidden').html(msgTxError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.txHash == txid && data.outputs && data.outputs[out_num] && data.outputs[out_num].outScript){ + + var tx_rev = ((txid).match(/.{1,2}/g).reverse()).join("")+''; + var script = data.outputs[out_num].outScript; + script = script.replace('OP_DUP OP_HASH160 ', '76a914'); + script = script.replace(' OP_EQUALVERIFY OP_CHECKSIG', '88ac'); + + addOutput(tx_rev, out_num, script, amount); + + $("#redeemFromBtn").html('Loading, checked '+page*20+' records '); + totalInputAmount(); + } else { + $("#redeemFromStatus").removeClass('hidden').html(msgTxError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + } + } + }); + })(tx, o.out_num, amount); + } } } } + + $("#redeemFromBtn").html('Loading, checked '+page*20+' records '); + totalInputAmount(); + + ++page; + listunspent_blockexplorer_nu(redeem, page); } else { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); + $("#redeemFromBtn").html("Load").attr('disabled',false); } - }, - complete: function(data, status) { - $("#redeemFromBtn").html("Load").attr('disabled',false); - totalInputAmount(); } }); }; From 2090bac9bc5516f9a8216de7140481e0167950b3 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 26 Nov 2015 04:15:32 +0100 Subject: [PATCH 22/92] Improved Nu provider --- js/cointoolkit.js | 86 +++++++++++++---------------------------------- 1 file changed, 24 insertions(+), 62 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 15e5eeea..d2ceabbb 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1260,81 +1260,43 @@ $(document).ready(function() { /* external providers */ - var listunspent_blockexplorer_nu = function(redeem, page){ - if (typeof(page) == "undefined") { - page = 1; - } + var listunspent_blockexplorer_nu = function(redeem){ + var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' + var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is http://blockexplorer.nu/ down?'; $.ajax ({ type: "GET", - url: "//crossorigin.me/https://blockexplorer.nu/api/addressDetails/"+redeem.addr+"/"+page+"/oldest", + url: "//crossorigin.me/https://blockexplorer.nu/api/v1/addressUnspent/"+redeem.addr, dataType: "json", cache: "false", error: function(data) { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs! Is http://blockexplorer.nu/ down?'); + $("#redeemFromStatus").removeClass('hidden').html(msgError); $("#redeemFromBtn").html("Load").attr('disabled',false); }, success: function(data) { if (coinjs.debug) {console.log(data)}; - if (!data.exists) { - $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + if (data.length == 0) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); $("#redeemFromBtn").html("Load").attr('disabled',false); - } else if (data.address == redeem.addr && data.tx){ - for(var i in data.tx){ - for(var v in data.tx[i].outputs){ - if (data.tx[i].outputs[v].status == "unspent" && data.tx[i].outputs[v].outAddress == redeem.addr) { - var o = data.tx[i].outputs[v]; - var amount = o.outValInt; - var tx = data.tx[i].txHash; - - if (redeem.isMultisig) { - var script = $("#redeemFrom").val(); - addOutput(tx, o.out_num, script, amount); - } else {; - (function(txid, out_num, amount){ - var msgTxError = ' Unexpected error, unable to retrieve transaction '+ txid +'! Is http://blockexplorer.nu/ down?'; - $.ajax ({ - type: "GET", - url: "//crossorigin.me/https://blockexplorer.nu/api/txDetails/"+txid, - dataType: "json", - cache: "false", - error: function(data) { - $("#redeemFromStatus").removeClass('hidden').html(msgTxError); - $("#redeemFromBtn").html("Load").attr('disabled',false); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if (data.txHash == txid && data.outputs && data.outputs[out_num] && data.outputs[out_num].outScript){ - - var tx_rev = ((txid).match(/.{1,2}/g).reverse()).join("")+''; - var script = data.outputs[out_num].outScript; - script = script.replace('OP_DUP OP_HASH160 ', '76a914'); - script = script.replace(' OP_EQUALVERIFY OP_CHECKSIG', '88ac'); - - addOutput(tx_rev, out_num, script, amount); - - $("#redeemFromBtn").html('Loading, checked '+page*20+' records '); - totalInputAmount(); - } else { - $("#redeemFromStatus").removeClass('hidden').html(msgTxError); - $("#redeemFromBtn").html("Load").attr('disabled',false); - } - } - }); - })(tx, o.out_num, amount); - } - } + } else { + for(var i=0;i'); - totalInputAmount(); - - ++page; - listunspent_blockexplorer_nu(redeem, page); - } else { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); - $("#redeemFromBtn").html("Load").attr('disabled',false); + $("#redeemFromAddress").removeClass('hidden').html(msgSucess); } + }, + complete: function(data, status) { + $("#redeemFromBtn").html("Load").attr('disabled',false); + totalInputAmount(); } }); }; From ebea698d47cd7cd3344fde6426027a3480d0029b Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 26 Nov 2015 15:13:21 +0100 Subject: [PATCH 23/92] Added Nu FLOT NSR address --- known-pubkeys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index ad3ebde8..8e14cfc0 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -18,6 +18,6 @@ var known = { scriptHash: { // Nu FLOT addresses scripthash "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT group 1st address"}, - "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NSR group 1st address"}, + "d4f1e97d23cf339c35b509de707acdcb9886e03b": {name:"Nu FLOT NSR group 1st address"}, } } \ No newline at end of file From 7be22ec58484325b2a733e807c3b21bc1f226c06 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 26 Nov 2015 16:24:59 +0100 Subject: [PATCH 24/92] Added Nu FLOT member --- known-pubkeys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index 8e14cfc0..25f45029 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -9,7 +9,7 @@ var known = { "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT member @jooize"}, "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": {name:"Nu FLOT member @woodstockmerkle"}, "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT member @masterOfDisaster"}, - "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu @Dhume"}, + "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu FLOT member @Dhume"}, "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT member @dysconnect"}, "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT member @ttutdxh"}, "03686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe740495": {name:"Nu FLOT member @cryptog"}, From ae6139a069c918ce97cd7ab51af8c9390b770f3d Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Fri, 27 Nov 2015 15:54:49 +0100 Subject: [PATCH 25/92] Updated FLOT in known pubkeys --- known-pubkeys.js | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index 25f45029..fc38d3e4 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -5,19 +5,38 @@ var known = { // Developer "02113443efda4a9fe9bd38ca1f932aaee2c3cb6ee637f22eaa25af370a1cde6952": {name:"Developer", email:"ttutdxh.nubits@gmail.com", fee:1}, - // Nu FLOT members https://discuss.nubits.com/t/flot-operations-thread/3098/ - "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT member @jooize"}, - "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": {name:"Nu FLOT member @woodstockmerkle"}, - "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT member @masterOfDisaster"}, - "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu FLOT member @Dhume"}, - "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT member @dysconnect"}, - "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT member @ttutdxh"}, - "03686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe740495": {name:"Nu FLOT member @cryptog"}, - "039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb66808": {name:"Nu FLOT member @mhps"}, + // Nu FLOT members BTC https://discuss.nubits.com/t/flot-operations-thread/3098 + "02435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b": {name:"Nu FLOT @cryptog (BTC)"}, + "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu FLOT @Dhume"}, + "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT @dysconnect"}, + "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT @jooize"}, + "0312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f": {name:"Nu FLOT @masterOfDisaster (BTC)"}, + "03a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a7622521": {name:"Nu FLOT @mhps (BTC)"}, + "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, + "03da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb": {name:"Nu FLOT @woodstockmerkle (BTC)"}, + + // Nu FLOT members NBT group https://discuss.nubits.com/t/flot-operations-thread/3098 + "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT @dysconnect"}, + "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT @jooize"}, + "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT @masterOfDisaster (NBT and NSR)"}, + "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, + "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": {name:"Nu FLOT @woodstockmerkle (NBT)"}, + + + // Nu FLOT members NSR group https://discuss.nubits.com/t/flot-operations-buy-side-nsr-related/3103/ + "03686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe740495": {name:"Nu FLOT @cryptog (NSR)"}, + "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu FLOT @Dhume"}, + "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT @masterOfDisaster (NBT and NSR)"}, + "039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb66808": {name:"Nu FLOT @mhps (NSR)"}, + "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, }, scriptHash: { // Nu FLOT addresses scripthash - "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT group 1st address"}, - "d4f1e97d23cf339c35b509de707acdcb9886e03b": {name:"Nu FLOT NSR group 1st address"}, + "f716edbaa472c1470d36a3e78b17a4c9bb547fcf": {name:"Nu FLOT BTC group 1st address"}, // 55210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b2102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f210312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f21034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a76225212103da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb58ae + + "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT group 1st address"}, // 5321034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b94257155ae + + "d4f1e97d23cf339c35b509de707acdcb9886e03b": {name:"Nu FLOT NSR group provisional address"}, // 53210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe74049521039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb6680855ae + "c5389b7ac09e350895c1360906dc8e6f313cbb8c": {name:"Nu FLOT NSR group 1st address"}, // 532102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe74049521039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb6680855ae } } \ No newline at end of file From d7f71ce8f1f6a4d22172825107f8b612fdaf9949 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Fri, 27 Nov 2015 16:39:25 +0100 Subject: [PATCH 26/92] Updated FLOT known pubkeys --- known-pubkeys.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index fc38d3e4..bf62b809 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -18,7 +18,7 @@ var known = { // Nu FLOT members NBT group https://discuss.nubits.com/t/flot-operations-thread/3098 "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT @dysconnect"}, "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT @jooize"}, - "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT @masterOfDisaster (NBT and NSR)"}, + "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT @masterOfDisaster (NBT)"}, "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": {name:"Nu FLOT @woodstockmerkle (NBT)"}, @@ -26,7 +26,7 @@ var known = { // Nu FLOT members NSR group https://discuss.nubits.com/t/flot-operations-buy-side-nsr-related/3103/ "03686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe740495": {name:"Nu FLOT @cryptog (NSR)"}, "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu FLOT @Dhume"}, - "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT @masterOfDisaster (NBT and NSR)"}, + "03d05d8fb69fcd289548140dde8e906f6fc217b02477f81842f2483d9ea1c92425": {name:"Nu FLOT @masterOfDisaster (NSR)"}, "039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb66808": {name:"Nu FLOT @mhps (NSR)"}, "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, }, From af4864d62095b73122447f245c8a3539324e64ec Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 01:32:47 +0100 Subject: [PATCH 27/92] Changed pubkeys format --- known-pubkeys.js | 184 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 144 insertions(+), 40 deletions(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index bf62b809..24816889 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -1,42 +1,146 @@ -var known = { - pubKey: { - // "pubkey": {name:"John Doe"}, - - // Developer - "02113443efda4a9fe9bd38ca1f932aaee2c3cb6ee637f22eaa25af370a1cde6952": {name:"Developer", email:"ttutdxh.nubits@gmail.com", fee:1}, - - // Nu FLOT members BTC https://discuss.nubits.com/t/flot-operations-thread/3098 - "02435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b": {name:"Nu FLOT @cryptog (BTC)"}, - "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu FLOT @Dhume"}, - "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT @dysconnect"}, - "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT @jooize"}, - "0312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f": {name:"Nu FLOT @masterOfDisaster (BTC)"}, - "03a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a7622521": {name:"Nu FLOT @mhps (BTC)"}, - "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, - "03da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb": {name:"Nu FLOT @woodstockmerkle (BTC)"}, +(function () { + var memberOf = { + Nu: { + FLOT_NBT: 1, + FLOT_NSR: 2, + FLOT_BTC: 3 + } + } + + var known = { + pubKey: { + // "pubkey": {name:"John Doe"}, + + // Developer + "02113443efda4a9fe9bd38ca1f932aaee2c3cb6ee637f22eaa25af370a1cde6952": {name:"Developer", email:"ttutdxh.nubits@gmail.com", fee:1}, + }, + scriptHash: { + // Nu FLOT addresses scripthash. // Commented with redeemScript. + "f716edbaa472c1470d36a3e78b17a4c9bb547fcf": {name:"Nu FLOT BTC group 1st address"}, // 55210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b2102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f210312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f21034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a76225212103da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb58ae + + "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT group 1st address"}, // 5321034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b94257155ae + + "d4f1e97d23cf339c35b509de707acdcb9886e03b": {name:"Nu FLOT NSR group provisional address", deprecated:true}, // 53210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe74049521039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb6680855ae + "7077487df91c0166d33ee6079b0c2229788f6ac2": {name:"Nu FLOT NSR group 1st address"}, // 532102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe74049521039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb668082103d05d8fb69fcd289548140dde8e906f6fc217b02477f81842f2483d9ea1c9242555ae + }, + identities: { // id.pubkey{memberof, [deprecated]} + "cryptog": { + "02435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b": { + member: [ + memberOf.Nu.FLOT_BTC // https://discuss.nubits.com/t/via-quote/3098/15 + ] + }, + "03686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe740495": { + member: [ + memberOf.Nu.FLOT_NSR // https://discuss.nubits.com/t/via-quote/3103/20 + ] + }, + }, + "Dhume": { + "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": { + member: [ + memberOf.Nu.FLOT_BTC, // https://discuss.nubits.com/t/via-quote/3098/10 + memberOf.Nu.FLOT_NSR // https://discuss.nubits.com/t/via-quote/3103/14 + ] + } + }, + "dysconnect": { + "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": { + member: [ + memberOf.Nu.FLOT_BTC, // https://discuss.nubits.com/t/via-quote/3098/16 + memberOf.Nu.FLOT_NBT // https://discuss.nubits.com/t/via-quote/2902/167 + ] + } + }, + "jooize": { + "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": { + member: [ + memberOf.Nu.FLOT_BTC, // https://discuss.nubits.com/t/via-quote/3098/13 + memberOf.Nu.FLOT_NBT // https://discuss.nubits.com/t/via-quote/2902/170 + ] + } + }, + "masterOfDisaster": { + "0312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f": { + member: [ + memberOf.Nu.FLOT_BTC // https://discuss.nubits.com/t/via-quote/3098/12 + ] + }, + "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": { + member: [ + memberOf.Nu.FLOT_NBT // https://discuss.nubits.com/t/via-quote/2902/168 + ] + }, + "03d05d8fb69fcd289548140dde8e906f6fc217b02477f81842f2483d9ea1c92425": { + member: [ + memberOf.Nu.FLOT_NSR // https://discuss.nubits.com/t/via-quote/3103/1 + ] + } + }, + "mhps": { + "03a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a7622521": { + member: [ + memberOf.Nu.FLOT_BTC // https://discuss.nubits.com/t/via-quote/3098/14 + ] + }, + "039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb66808": { + member: [ + memberOf.Nu.FLOT_NSR // https://discuss.nubits.com/t/via-quote/3103/9 + ] + } + }, + "ttutdxh": { + "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": { + member: [ + memberOf.Nu.FLOT_BTC, // https://discuss.nubits.com/t/via-quote/3098/9 + memberOf.Nu.FLOT_NBT, // https://discuss.nubits.com/t/via-quote/2902/169 + memberOf.Nu.FLOT_NSR // https://discuss.nubits.com/t/via-quote/3103/6 + ] + } + }, + "woodstockmerkle": { + "03da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb": { + member: [ + memberOf.Nu.FLOT_BTC // https://discuss.nubits.com/t/via-quote/3098/11 + ] + }, + "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": { + member: [ + memberOf.Nu.FLOT_NBT // https://discuss.nubits.com/t/via-quote/2902/171 + ] + } + } + } + }; + - // Nu FLOT members NBT group https://discuss.nubits.com/t/flot-operations-thread/3098 - "034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff": {name:"Nu FLOT @dysconnect"}, - "0234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c07": {name:"Nu FLOT @jooize"}, - "02a144af74d018501f03d76ead130433335f969772792ec39ce389c8a234155259": {name:"Nu FLOT @masterOfDisaster (NBT)"}, - "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, - "02547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b942571": {name:"Nu FLOT @woodstockmerkle (NBT)"}, - - - // Nu FLOT members NSR group https://discuss.nubits.com/t/flot-operations-buy-side-nsr-related/3103/ - "03686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe740495": {name:"Nu FLOT @cryptog (NSR)"}, - "02e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f": {name:"Nu FLOT @Dhume"}, - "03d05d8fb69fcd289548140dde8e906f6fc217b02477f81842f2483d9ea1c92425": {name:"Nu FLOT @masterOfDisaster (NSR)"}, - "039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb66808": {name:"Nu FLOT @mhps (NSR)"}, - "03661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc": {name:"Nu FLOT @ttutdxh"}, - }, - scriptHash: { - // Nu FLOT addresses scripthash - "f716edbaa472c1470d36a3e78b17a4c9bb547fcf": {name:"Nu FLOT BTC group 1st address"}, // 55210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b2102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f210312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f21034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a76225212103da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb58ae - - "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT group 1st address"}, // 5321034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b94257155ae - - "d4f1e97d23cf339c35b509de707acdcb9886e03b": {name:"Nu FLOT NSR group provisional address"}, // 53210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe74049521039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb6680855ae - "c5389b7ac09e350895c1360906dc8e6f313cbb8c": {name:"Nu FLOT NSR group 1st address"}, // 532102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe74049521039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb6680855ae + for (var id in known.identities) { // Compute pubkey list + for (var pubkey in known.identities[id]) { + + // FLOT memberOfs + var FLOT = []; + for (var group in known.identities[id][pubkey].member) { + if (known.identities[id][pubkey].member[group] == memberOf.Nu.FLOT_BTC) FLOT.push("BTC"); + if (known.identities[id][pubkey].member[group] == memberOf.Nu.FLOT_NBT) FLOT.push("NBT"); + if (known.identities[id][pubkey].member[group] == memberOf.Nu.FLOT_NSR) FLOT.push("NSR"); + } + if (FLOT.length > 0) { + var prefix = (known.identities[id][pubkey].deprecated)?"DEPRECATED ":""; + known.pubKey[pubkey] = { + name: prefix + "Nu FLOT @"+ id + " " +(FLOT.join(", ")), + email: "", + fee: "" + } + } + } + } + + // Mark deprecated. Handling will change in the future. Maybe an alert. + for (var hash in known.scriptHash) { + known.scriptHash[hash].name = (known.scriptHash[hash].deprecated)?"DEPRECATED " + known.scriptHash[hash].name:known.scriptHash[hash].name; } -} \ No newline at end of file + + window['known'] = known; +})(); + +console.log("Loaded known identities", known); \ No newline at end of file From 7ec0a69ca4e90baadb6c3e2e6eee783b73b8eb25 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 02:02:26 +0100 Subject: [PATCH 28/92] Fixed incorrect check --- js/coin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/coin.js b/js/coin.js index e1fab74a..55b2e5de 100644 --- a/js/coin.js +++ b/js/coin.js @@ -678,7 +678,7 @@ r.spendToScript = function(address){ var addr = coinjs.addressDecode(address); var s = coinjs.script(); - if(addr.version==5){ // multisig address + if(addr.type=="multisig"){ // multisig address s.writeOp(169); //OP_HASH160 s.writeBytes(addr.bytes); s.writeOp(135); //OP_EQUAL From 0d65aa4b5ad8d39f2189b6312f7d2e5964c0e213 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 02:47:43 +0100 Subject: [PATCH 29/92] Added shortcut to sign from new transaction --- index.html | 16 +++++++++++++--- js/cointoolkit.js | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 92af2d8c..3f1d849c 100644 --- a/index.html +++ b/index.html @@ -630,9 +630,19 @@

New Transaction Create a new transaction

The transaction below has been generated and encoded. It can be broadcasted once it has been signed.


- - -

Size: 0 bytes

+ +
+
+

Size: 0 bytes

+
+ If you are sure: + +
+
+
diff --git a/js/cointoolkit.js b/js/cointoolkit.js index d2ceabbb..80deb5b4 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -518,6 +518,11 @@ $(document).ready(function() { if(!$("#recipients .row, #inputs .row").hasClass('has-error')){ $("#transactionCreate textarea").val(tx.serialize()); $("#transactionCreate .txSize").html(tx.size()); + + $("#transactionCreate .transactionToSign").on( "click", function() { + $("#signTransaction").val(tx.serialize()); + window.location.hash = "#sign"; + }); $("#transactionCreate").removeClass("hidden"); From e38e5915cf7a36337aa9f8a50e2d1be79a10a079 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 02:48:26 +0100 Subject: [PATCH 30/92] Fixed wallet availability --- js/cointoolkit.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 80deb5b4..6a05057e 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1151,9 +1151,11 @@ $(document).ready(function() { var mode = this.options[this.selectedIndex].value; + var walletAvailableUnspent = false; + var walletAvailableBroadcast = false; // deal with listUnspent settings` - + $('#coinjs_utxo').empty(); if(typeof(providers[mode]) == 'object' && typeof(providers[mode].listUnspent) == 'object' && Object.keys(providers[mode].listUnspent).length > 0){ $.each(providers[mode].listUnspent, function(key) { @@ -1163,19 +1165,21 @@ $(document).ready(function() { })); }); - $("#coinjs_utxo, #redeemFrom, #redeemFromBtn, #openBtn, .qrcodeScanner").attr('disabled',false); + $("#coinjs_utxo, #redeemFrom, #redeemFromBtn, .qrcodeScanner").attr('disabled',false); $("#coinjs_utxo").val(o[6]); $("#redeemFrom").val(""); + + walletAvailableUnspent = true; } else { - $("#coinjs_utxo, #redeemFrom, #redeemFromBtn, #openBtn, .qrcodeScanner").attr('disabled',true); + $("#coinjs_utxo, #redeemFrom, #redeemFromBtn, .qrcodeScanner").attr('disabled',true); $("#coinjs_utxo").append('').val("disabled"); $("#redeemFrom").val("Loading of address inputs is currently not available for " + this.options[ this.selectedIndex ].text); } // deal with broadcasting settings - + $('#coinjs_broadcast').empty(); if(typeof(providers[mode]) == 'object' && typeof(providers[mode].broadcast) == 'object' && Object.keys(providers[mode].broadcast).length > 0){ $.each(providers[mode].broadcast, function(key) { @@ -1185,16 +1189,21 @@ $(document).ready(function() { })); }); - $("#coinjs_broadcast, #rawTransaction, #rawSubmitBtn, #openBtn").attr('disabled',false); + $("#coinjs_broadcast, #rawTransaction, #rawSubmitBtn").attr('disabled',false); $("#coinjs_broadcast").val(o[5]); $("#rawTransaction").val(""); + + walletAvailableBroadcast = true; } else { - $("#coinjs_broadcast, #rawTransaction, #rawSubmitBtn, #openBtn").attr('disabled',true); + $("#coinjs_broadcast, #rawTransaction, #rawSubmitBtn").attr('disabled',true); $("#coinjs_broadcast").append('').val("disabled"); $("#rawTransaction").val("Transaction broadcasting is currently not available for " + this.options[ this.selectedIndex ].text); } + + // enable wallet if available + $("#openBtn").attr('disabled', (walletAvailableUnspent && walletAvailableBroadcast)); // deal with the reset $("#coinjs_pub").val(o[0]); From 7efd78a18e63de7e3d0a5429cb40d01f91715da4 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 18:03:40 +0100 Subject: [PATCH 31/92] Added shortcuts --- index.html | 17 ++++++++++++++++- js/cointoolkit.js | 14 ++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 3f1d849c..d4a3f746 100644 --- a/index.html +++ b/index.html @@ -921,7 +921,22 @@

Sign Transaction once a transaction has been verified

-

Size: 0 bytes

+
+
+

Size: 0 bytes

+
+ + Or + +
+
+
diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 6a05057e..51fc1843 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -520,7 +520,7 @@ $(document).ready(function() { $("#transactionCreate .txSize").html(tx.size()); $("#transactionCreate .transactionToSign").on( "click", function() { - $("#signTransaction").val(tx.serialize()); + $("#signTransaction").val(tx.serialize()).fadeOut().fadeIn();; window.location.hash = "#sign"; }); @@ -847,7 +847,7 @@ $(document).ready(function() { $("#verifyTransactionData .transactionLockTime").html(decode['lock_time']); $("#verifyTransactionData .transactionUnit").html(String.fromCharCode(decode['nUnit'])); $("#verifyTransactionData .verifyToSign").on( "click", function() { - $("#signTransaction").val(decode.serialize()); + $("#signTransaction").val(decode.serialize()).fadeOut().fadeIn(); window.location.hash = "#sign"; }); $("#verifyTransactionData").removeClass("hidden"); @@ -1059,6 +1059,16 @@ $(document).ready(function() { $("#signedData textarea").val(signed); $("#signedData .txSize").html(t.size()); $("#signedData").removeClass('hidden').fadeIn(); + + $("#signedData .signedToVerify").on( "click", function() { + $("#verifyScript").val(signed).fadeOut().fadeIn(); + window.location.hash = "#verify"; + }); + + $("#signedData .signedToBroadcast").on( "click", function() { + $("#broadcast #rawTransaction").val(signed).fadeOut().fadeIn(); + window.location.hash = "#broadcast"; + }); } catch(e) { if (coinjs.debug) {console.log(e)}; } From e17245bf9b69906c518710860d0df952fe7c21ba Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 19:30:47 +0100 Subject: [PATCH 32/92] Fixed unintuitive behavior --- js/cointoolkit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 51fc1843..b8d8646f 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1061,6 +1061,7 @@ $(document).ready(function() { $("#signedData").removeClass('hidden').fadeIn(); $("#signedData .signedToVerify").on( "click", function() { + $("#verifyTransactionData").addClass("hidden"); $("#verifyScript").val(signed).fadeOut().fadeIn(); window.location.hash = "#verify"; }); From 3fcfaa8f7a1c76cce311ca5950d0d54a533c902c Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 19:35:09 +0100 Subject: [PATCH 33/92] Fixed unintuitive behavior. Second option --- js/cointoolkit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index b8d8646f..0da9a8a6 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1061,8 +1061,8 @@ $(document).ready(function() { $("#signedData").removeClass('hidden').fadeIn(); $("#signedData .signedToVerify").on( "click", function() { - $("#verifyTransactionData").addClass("hidden"); $("#verifyScript").val(signed).fadeOut().fadeIn(); + $("#verifyBtn").click(); window.location.hash = "#verify"; }); From 4e771bac2fbd2b12bcc8435ff08a9d75c4be7595 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 28 Nov 2015 19:44:39 +0100 Subject: [PATCH 34/92] Fixed unintuitive behavior. Don't let even see previous result when changing data --- js/cointoolkit.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 0da9a8a6..9bd48ccb 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1153,6 +1153,14 @@ $(document).ready(function() { } }); + $("#verify #verifyScript").change(function(){ + $("#verify .verifyData").addClass("hidden"); + }); + + $("#sign #signTransaction, #sign #signPrivateKey").change(function(){ + $("#sign #signedData").addClass("hidden"); + }); + $("#coinSelector").change(function(){ $("#coinjs_coin").val(this.value).change(); $("#settingsBtn").click(); From ca224de89c811743129e8254b63a8a77fb2a5a67 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 29 Nov 2015 02:55:56 +0100 Subject: [PATCH 35/92] Layout changes --- css/style.css | 10 ++++++++++ index.html | 9 +++++---- js/coin.js | 7 +++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/css/style.css b/css/style.css index df67696b..4b0ef835 100644 --- a/css/style.css +++ b/css/style.css @@ -38,4 +38,14 @@ body { @keyframes spin { from { transform: scale(1) rotate(0deg);} to { transform: scale(1) rotate(360deg);} +} + +#verifyTransactionData .table>tbody>tr>td { + vertical-align: middle; +} + +@media (min-width: 768px) { + #modalMultisig .modal-dialog { + width: 70%; + } } \ No newline at end of file diff --git a/index.html b/index.html index d4a3f746..3498d260 100644 --- a/index.html +++ b/index.html @@ -99,7 +99,7 @@

Cointoolkit Welcome to the Blockchain

Cointoolkit

Be your own bank, take control of your own money and start using NuBits today!

-

Learn more »

+

Create new address »


@@ -112,7 +112,7 @@

Open Source

MultiSig

-

We offer a fully transparent multisig solution which works seamlessly offline and with other wallets.

+

This is the first tool that supports combining signatures in a multi signature transaction. Verify your first transaction, click the number of signatures and combine the other versions

@@ -271,7 +271,7 @@

QR Code Generator transfer data easily between devices

Create new address

Any keys used you will need to manually store safely as they will be needed later to redeem the coins.

- click generate to update +
@@ -926,8 +926,9 @@

Sign Transaction once a transaction has been verified

Size: 0 bytes

Or
+ + + + diff --git a/js/coin.js b/js/coin.js index 7fd9db8b..ec0324b4 100644 --- a/js/coin.js +++ b/js/coin.js @@ -252,6 +252,7 @@ return false; } } catch(e) { + if (coinjs.debug) {console.log(e)}; return false; } } @@ -922,9 +923,10 @@ return {'type':'scriptpubkey', 'signed':'true', 'signatures':1, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)}; } else if (this.ins[index].script.chunks[0]==0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1][this.ins[index].script.chunks[this.ins[index].script.chunks.length-1].length-1]==174) { // OP_CHECKMULTISIG // multisig script, with signature(s) included - var count = -1; + + var count = -1; // To account for serialized redeemScript for (var i = 0; i < this.ins[index].script.chunks.length; i++) { - if(this.ins[index].script.chunks[i]){ + if(this.ins[index].script.chunks[i]){ // omit 0 signature placeholder ++count; } } @@ -1074,27 +1076,26 @@ return true; } - /* sign a multisig input */ - r.signmultisig = function(index, wif){ - - function scriptListPubkey(redeemScript){ - var r = {}; - for(var i=1;ibytes'); @@ -860,16 +859,21 @@ $(document).ready(function() { h += ''; h += ''+o.outpoint.index+''; h += ''; - h += ' '; + h += ''; + h += ''; if(s['type']=='multisig' && s['signatures']>=1){ + h += ''; h += ' '+s['signatures']; + h += ''; } h += ''; h += ''; if(s['type']=='multisig'){ + h += ''; var script = coinjs.script(); var rs = script.decodeRedeemScript(s.script); h += rs['signaturesRequired']+' of '+rs['pubkeys'].length; + h += ''; } else { h += ''; } @@ -878,6 +882,11 @@ $(document).ready(function() { }); $(h).appendTo("#verifyTransactionData .ins tbody"); + + $("#verifyTransactionData .ins tbody").on( "click", "a[data-index]", function(e) { + e.preventDefault(); + decodeMultiSig(decode, $(this).attr("data-index")); + }); h = ''; $.each(decode.outs, function(i,o){ @@ -937,6 +946,50 @@ $(document).ready(function() { return false; } } + + function decodeMultiSig(tx, i) { + var html = ''; + var list = tx.listMultiSignature(i); + for (var pubkey in list) { + identity = ""; + if (known.pubKey[pubkey]) { + identity = known.pubKey[pubkey].name; + } + + var address = coinjs.pubkey2address(pubkey); + html += '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + '; + } + + $("#modalMultisig table tbody").html(html); + $("#modalMultisig .combine .alert").addClass("hidden"); + + $("#modalMultisig .combineTx").click(function() { + var newTx = tx.combineMultiSignature($("#modalMultisig .combine textarea").val()); + if (newTx) { + console.log(newTx, newTx.serialize()); + $("#verifyScript").val(newTx.serialize()).fadeOut().fadeIn(); + $("#verifyBtn").click(); + + $("#modalMultisig .combine .alert").addClass("hidden"); + $("#modalMultisig").modal("hide"); + + window.location.hash = "#verify"; + } else { + $("#modalMultisig .combine .alert").removeClass("hidden"); + } + }); + $("#modalMultisig").modal("show"); + } function hex2ascii(hex) { var str = ''; From 337dcd17a5a8eb821a74bc202ff533f9d72e45a8 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 29 Nov 2015 03:04:37 +0100 Subject: [PATCH 37/92] Layout fix --- js/cointoolkit.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 30107e3c..c6619128 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -950,6 +950,9 @@ $(document).ready(function() { function decodeMultiSig(tx, i) { var html = ''; var list = tx.listMultiSignature(i); + + if (coinjs.debug) {console.log(e)}; + for (var pubkey in list) { identity = ""; if (known.pubKey[pubkey]) { @@ -958,7 +961,7 @@ $(document).ready(function() { var address = coinjs.pubkey2address(pubkey); html += '\ - \ + \ \ \ \ From 38ea4d5ca267cdb15eee573169dae396d628d04c Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 29 Nov 2015 03:06:56 +0100 Subject: [PATCH 38/92] Layout fix 2, green not showing in live versions --- js/cointoolkit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index c6619128..1902386e 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -951,7 +951,7 @@ $(document).ready(function() { var html = ''; var list = tx.listMultiSignature(i); - if (coinjs.debug) {console.log(e)}; + if (coinjs.debug) {console.log(list[pubkey])}; for (var pubkey in list) { identity = ""; @@ -960,7 +960,7 @@ $(document).ready(function() { } var address = coinjs.pubkey2address(pubkey); - html += '\ + html += '\ \ \ \ From 0721d86e4ebd887687701450fb34bfc4a751f284 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 29 Nov 2015 03:09:11 +0100 Subject: [PATCH 39/92] Layout fix 3, still trying to figure out green... --- js/cointoolkit.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 1902386e..e3df2bcf 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -951,16 +951,16 @@ $(document).ready(function() { var html = ''; var list = tx.listMultiSignature(i); - if (coinjs.debug) {console.log(list[pubkey])}; - for (var pubkey in list) { identity = ""; if (known.pubKey[pubkey]) { identity = known.pubKey[pubkey].name; } + if (coinjs.debug) {console.log(list, pubkey, ((list[pubkey]) ? 'background-color: rgb(223, 240, 216);':''))}; + var address = coinjs.pubkey2address(pubkey); - html += '\ + html += '\ \ \ \ From 539bf11b5749cdb65489585ec4a624206f065fbd Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 29 Nov 2015 03:18:08 +0100 Subject: [PATCH 40/92] Final layout fix, I was in other mode than the tx, so tx was valid and verified but signatures were not. Added a fix so doesn't happen again --- js/cointoolkit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index e3df2bcf..ab081d80 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -957,7 +957,7 @@ $(document).ready(function() { identity = known.pubKey[pubkey].name; } - if (coinjs.debug) {console.log(list, pubkey, ((list[pubkey]) ? 'background-color: rgb(223, 240, 216);':''))}; + if (coinjs.debug) {console.log(list, pubkey)}; var address = coinjs.pubkey2address(pubkey); html += '\ @@ -1152,7 +1152,7 @@ $(document).ready(function() { $("#walletLogout").click(); $("#newGeneratedAddress, #newPubKey, #newPrivKeyWif, #newPrivKey, #newHDxpub, #newHDxprv").val(""); - $("#multiSigData").removeClass('show').addClass('hidden').hide(); + $("#multiSigData, .verifyData").removeClass('show').addClass('hidden'); $("#statusSettings").removeClass("alert-success").removeClass("alert-danger").addClass("hidden").html(""); $("#settings .has-error").removeClass("has-error"); From f337af83a54b06a5f37fc08a3cb7a775c8907689 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 29 Nov 2015 16:09:54 +0100 Subject: [PATCH 41/92] Fixed endianness issue --- index.html | 4 +- js/coin.js | 57 +------------- js/cointoolkit.js | 186 +++++++++++++++++++++------------------------- 3 files changed, 88 insertions(+), 159 deletions(-) diff --git a/index.html b/index.html index bd4e892a..e7896e57 100644 --- a/index.html +++ b/index.html @@ -66,7 +66,7 @@
  • Verify
  • Sign
  • Broadcast
  • -
  • Wallet
  • +
  • About
  • Settings
  • @@ -991,7 +991,7 @@

    Settings

    - + diff --git a/js/coin.js b/js/coin.js index ec0324b4..e9555284 100644 --- a/js/coin.js +++ b/js/coin.js @@ -26,13 +26,6 @@ coinjs.compressed = false; - /* other vars */ - coinjs.developer = '1JbsRVvU93PXN2JovuDE2NJTVNWkGEFrvx'; // bitcoin - - /* bit(coinb.in) api vars */ - coinjs.host = ('https:'==document.location.protocol?'https://':'http://')+'coinb.in/api/'; - coinjs.uid = '1'; - coinjs.key = '12345678901234567890123456789012'; /* start of address functions */ @@ -257,11 +250,6 @@ } } - /* retreive the balance from a given address */ - coinjs.addressBalance = function(address, callback){ - coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=addresses&request=bal&address='+address+'&r='+Math.random(), callback, "GET"); - } - /* decompress an compressed public key */ coinjs.pubkeydecompress = function(pubkey) { var curve = EllipticCurve.getSECCurveByName("secp256k1"); @@ -828,15 +816,10 @@ return r; } - /* list unspent transactions */ - r.listUnspent = function(address, callback) { - coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=addresses&request=unspent&address='+address+'&r='+Math.random(), callback, "GET"); - } - /* add unspent to transaction */ r.addUnspent = function(address, callback){ var self = this; - this.listUnspent(address, function(data){ + /*this.listUnspent(address, function(data){ TODO: not available anymore var s = coinjs.script(); var pubkeyScript = s.pubkeyHash(address); var value = 0; @@ -870,7 +853,7 @@ x.value = value; x.total = total; return callback(x); - }); + });*/ } /* add unspent and sign */ @@ -883,12 +866,6 @@ }); } - /* broadcast a transaction */ - r.broadcast = function(callback, txhex){ - var tx = txhex || this.serialize(); - coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction&rawtx='+tx+'&r='+Math.random(), callback, "GET"); - } - /* generate the transaction hash to sign from a transaction input */ r.transactionHash = function(index) { var clone = coinjs.clone(this); @@ -1448,36 +1425,6 @@ return bytes; } - /* raw ajax function to avoid needing bigger frame works like jquery, mootools etc */ - coinjs.ajax = function(u, f, m, a){ - var x = false; - try{ - x = new ActiveXObject('Msxml2.XMLHTTP') - } catch(e) { - try { - x = new ActiveXObject('Microsoft.XMLHTTP') - } catch(e) { - x = new XMLHttpRequest() - } - } - - if(x==false) { - return false; - } - - x.open(m, u, true); - x.onreadystatechange=function(){ - if((x.readyState==4) && f) - f(x.responseText); - }; - - if(m == 'POST'){ - x.setRequestHeader('Content-type','application/x-www-form-urlencoded'); - } - - x.send(a); - } - /* clone an object */ coinjs.clone = function(obj) { if(obj == null || typeof(obj) != 'object') return obj; diff --git a/js/cointoolkit.js b/js/cointoolkit.js index ab081d80..fd46e258 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -87,12 +87,12 @@ $(document).ready(function() { var thisbtn = $(this); var tx = coinjs.transaction(); var txfee = $("#txFee"); - var devaddr = coinjs.developer; + /*var devaddr = coinjs.developer; // TODO: generate address from dev known pubkey var devamount = $("#developerDonation"); if((devamount.val()*1)>0){ tx.addoutput(devaddr, devamount.val()*1); - } + }*/ var total = (devamount.val()*1) + (txfee.val()*1); @@ -106,7 +106,7 @@ $(document).ready(function() { thisbtn.attr('disabled',true); tx.addUnspent($("#walletAddress").html(), function(data){ - var dvalue = data.value/100000000 + var dvalue = data.value/("1e"+coinjs.decimalPlaces); if(dvalue>=total){ var change = dvalue-total; if(change>0){ @@ -121,7 +121,17 @@ $(document).ready(function() { var signed = txunspent.sign($("#walletKeys .privkey").val()); // and finally broadcast! - tx2.broadcast(function(data){ + /* + tx2.broadcast(function(data){ // TODO: function no longer part of coin.js + + + + r.broadcast = function(callback, txhex){ + var tx = txhex || this.serialize(); + coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction&rawtx='+tx+'&r='+Math.random(), callback, "GET"); + } + + if($(data).find("result").text()=="1"){ $("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-success').html("txid: "+$(data).find("txid").text()); } else { @@ -133,6 +143,7 @@ $(document).ready(function() { walletBalance(); }, signed); + */ } else { $("#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); @@ -183,7 +194,7 @@ $(document).ready(function() { } }); - total = total.toFixed(8); + total = total.toFixed(coinjs.decimalPlaces); if($("#walletSpend .has-error").length==0){ var balance = ($("#walletBalance").html()).replace(/[^0-9\.]+/g,'')*1; @@ -233,7 +244,7 @@ $(document).ready(function() { $("#walletLoader").removeClass("hidden"); coinjs.addressBalance($("#walletAddress").html(),function(data){ if($(data).find("result").text()==1){ - var v = $(data).find("balance").text()/100000000; + var v = $(data).find("balance").text()/("1e"+coinjs.decimalPlaces); $("#walletBalance").html(v+" BTC").attr('rel',v).fadeOut().fadeIn(); } else { $("#walletBalance").html("0.00 BTC").attr('rel',v).fadeOut().fadeIn(); @@ -678,40 +689,6 @@ $(document).ready(function() { 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 = '
    '+$("#recipients .addressAddTo").parent().parent().html()+'

    '; - $("#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 */ function addOutput(tx, n, script, amount) { if(tx){ @@ -721,9 +698,7 @@ $(document).ready(function() { $("#inputs .row:last input").attr('disabled',true); - var txid = ((tx).match(/.{1,2}/g).reverse()).join("")+''; - - $("#inputs .txId:last").val(txid); + $("#inputs .txId:last").val(tx); $("#inputs .txIdN:last").val(n); $("#inputs .txIdAmount:last").val(amount); $("#inputs .txIdScript:last").val(script); @@ -743,7 +718,7 @@ $(document).ready(function() { if(!isNaN($(o).val())){ f += $(o).val()*1; } - $("#totalInput").html((($("#totalInput").html()*1) + (f*1)).toFixed(8)); + $("#totalInput").html((($("#totalInput").html()*1) + (f*1)).toFixed(coinjs.decimalPlaces)); } }); totalFee(); @@ -762,14 +737,14 @@ $(document).ready(function() { f += $(o).val()*1; } }); - $("#totalOutput").html((f).toFixed(8)); + $("#totalOutput").html((f).toFixed(coinjs.decimalPlaces)); } totalFee(); }).keyup(); } function totalFee(){ - var fee = (($("#totalInput").html()*1) - ($("#totalOutput").html()*1)).toFixed(8); + var fee = (($("#totalInput").html()*1) - ($("#totalOutput").html()*1)).toFixed(coinjs.decimalPlaces); $("#transactionFee").val((fee>0)?fee:'0.00'); } @@ -1367,9 +1342,7 @@ $(document).ready(function() { $("#redeemFromStatus").removeClass('hidden').html(msgError); $("#redeemFromBtn").html("Load").attr('disabled',false); } else { - for(var i=0;i Retrieved unspent inputs from address '+redeem.addr+''); - - $.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 = (redeem.isMultisig==true) ? $("#redeemFrom").val() : $(o).find("script").text(); - var amount = (($(o).find("value").text()*1)/100000000).toFixed(8); - - addOutput(tx, n, script, amount); - }); - } - - $("#redeemFromBtn").html("Load").attr('disabled',false); - totalInputAmount(); - - mediatorPayment(redeem); - }); - }, blockr_io: function(redeem){ $.ajax ({ - type: "POST", + type: "GET", url: "https://btc.blockr.io/api/v1/address/unspent/"+redeem.addr+"?unconfirmed=1", dataType: "json", error: function(data) { @@ -1426,15 +1381,13 @@ $(document).ready(function() { }, success: function(data) { if (coinjs.debug) {console.log(data)}; - if((data.status && data.data) && data.status=='success'){ + if ((data.status && data.data) && data.status=='success'){ $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); for(var i in data.data.unspent){ var o = data.data.unspent[i]; - var tx = o.tx; - var n = o.n; var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script; - var amount = o.amount; - addOutput(tx, n, script, amount); + + addOutput(o.tx, o.n, script, o.amount); } } else { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); @@ -1445,35 +1398,40 @@ $(document).ready(function() { totalInputAmount(); } }); - } - }, - broadcast: { - default: function(btn){ - var thisbtn = btn; - $(thisbtn).val('Please wait, loading...').attr('disabled',true); + }, + coinb_in: function(redeem){ $.ajax ({ - type: "POST", - url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction', - data: {'rawtx':$("#rawTransaction").val()}, + type: "GET", + url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=addresses&request=unspent&address='+redeem.addr+'&r='+Math.random(), dataType: "xml", error: function(data) { - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(" There was an error submitting your request, please try again").prepend(''); + if (coinjs.debug) {console.log(data)}; + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); }, - success: function(data) { - $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); - if($(data).find("result").text()==1){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); - $("#rawTransactionStatus").html('txid: '+$(data).find("txid").text()); + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if ($(data).children("request").children("result").text()){ + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + $.each($(data).children("request").children("unspent").children(), function(i,o){ + var tx = (($(o).find("tx_hash").text()).match(/.{1,2}/g).reverse()).join("")+''; + var n = $(o).find("tx_output_n").text(); + var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : $(o).find("script").text(); + var amount = (($(o).find("value").text()*1)/("1e"+coinjs.decimalPlaces)).toFixed(coinjs.decimalPlaces); + + addOutput(tx, n, script, amount); + }); } else { - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend(' '); + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); } }, complete: function(data, status) { - $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).val('Submit').attr('disabled',false); + $("#redeemFromBtn").html("Load").attr('disabled',false); + totalInputAmount(); } }); - }, + } + }, + broadcast: { blockr_io: function(thisbtn){ $(thisbtn).val('Please wait, loading...').attr('disabled',true); $.ajax ({ @@ -1503,6 +1461,32 @@ $(document).ready(function() { } }); }, + coinb_in: function(btn){ + var thisbtn = btn; + $(thisbtn).val('Please wait, loading...').attr('disabled',true); + $.ajax ({ + type: "G", + url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction', + data: {'rawtx':$("#rawTransaction").val()}, + dataType: "xml", + error: function(data) { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(" There was an error submitting your request, please try again").prepend(''); + }, + success: function(data) { + $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); + if($(data).find("result").text()==1){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); + $("#rawTransactionStatus").html('txid: '+$(data).find("txid").text()); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend(' '); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).val('Submit').attr('disabled',false); + } + }); + } } }, litecoin: { @@ -1521,11 +1505,9 @@ $(document).ready(function() { $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); for(var i in data.data.txs){ var o = data.data.txs[i]; - var tx = ((o.txid).match(/.{1,2}/g).reverse()).join("")+''; - var n = o.output_no; var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script_hex; - var amount = o.value; - addOutput(tx, n, script, amount); + + addOutput(o.txid, o.output_no, script, o.value); } } else { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); From 88f493b8e887820438e28c06d66b122e9427215a Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Mon, 30 Nov 2015 00:12:48 +0100 Subject: [PATCH 42/92] Fixed broadcasting --- js/cointoolkit.js | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index fd46e258..d4a4f550 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -758,12 +758,6 @@ $(document).ready(function() { } }); - /* broadcast a transaction */ - - $("#rawSubmitBtn").click(function(){ - rawSubmitDefault(this); - }); - /* verify script code */ $("#verifyBtn").click(function(){ @@ -1440,17 +1434,15 @@ $(document).ready(function() { data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { - var obj = $.parseJSON(data.responseText); var r = ' '; - r += (obj.data) ? obj.data : ''; - r += (obj.message) ? ' '+obj.message : ''; + r += (data.data) ? data.data : ''; + r += (data.message) ? ' '+data.message : ''; r = (r!='') ? r : ' Failed to broadcast'; // build response $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, - success: function(data) { - var obj = $.parseJSON(data.responseText); - if((obj.status && obj.data) && obj.status=='success'){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+obj.data); + success: function(data) { + if((data.status && data.data) && data.status=='success'){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); } else { $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); } @@ -1472,7 +1464,7 @@ $(document).ready(function() { error: function(data) { $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(" There was an error submitting your request, please try again").prepend(''); }, - success: function(data) { + success: function(data) { $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); if($(data).find("result").text()==1){ $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); @@ -1529,18 +1521,16 @@ $(document).ready(function() { data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { - var obj = $.parseJSON(data.responseText); var r = ' '; - r += (obj.data) ? obj.data : ''; - r += (obj.message) ? ' '+obj.message : ''; + r += (data.data) ? data.data : ''; + r += (data.message) ? ' '+data.message : ''; r = (r!='') ? r : ' Failed to broadcast'; // build response $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, success: function(data) { if (coinjs.debug) {console.log(data)}; - var obj = $.parseJSON(data.responseText); - if((obj.status && obj.data) && obj.status=='success'){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+obj.data); + if((data.status && data.data) && data.status=='success'){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); } else { $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); } From ea0e7f6ec3a8b484714447b87046e0b6038adbbb Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Tue, 1 Dec 2015 03:36:12 +0100 Subject: [PATCH 43/92] Added input amount checker and usability fixes --- index.html | 93 ++++++++++++++++-------- js/coin.js | 42 +++++++---- js/cointoolkit.js | 177 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 231 insertions(+), 81 deletions(-) diff --git a/index.html b/index.html index e7896e57..e587ce0e 100644 --- a/index.html +++ b/index.html @@ -729,7 +729,24 @@

    Transaction Script

    - + + + + + + @@ -754,6 +771,7 @@

    Transaction Script

    + If the transaction is correct:
    +
    +
    Shareable verification link @@ -985,25 +1005,25 @@

    Settings

    Network:

    Select which network you'd like to use for key pair generation.

    @@ -1015,23 +1035,21 @@

    Settings


    -
    +
    Pub:
    -
    +
    Priv:
    -
    +
    Script Hash (multisig):
    -
    - -
    +
    HD Pub:
    @@ -1041,8 +1059,10 @@

    Settings

    HD Priv:
    +
    -
    +
    +
    Extra time field?:
    -
    +
    Extra unit field value?:
    -
    +
    Decimal places:
    + +
    + Symbol:
    + +

    @@ -1070,19 +1095,31 @@

    Settings

    Unspent outputs:
    -

    Select the network you wish to retreive your unspent inputs from

    +

    Select the provider you wish to retreive your unspent inputs from

    +
    + +
    +
    + Input amount:
    +

    Select the provider you wish to retreive transactions input amounts

    + +
    +
    +
    Broadcast:
    -

    Select the network you wish to broadcast the transaction via

    +

    Select the provider you wish to broadcast the transaction via

    diff --git a/js/coin.js b/js/coin.js index e9555284..3d57de26 100644 --- a/js/coin.js +++ b/js/coin.js @@ -12,17 +12,20 @@ /* public vars */ coinjs.debug = false; + /* Bitcoin by default */ + coinjs.pub = 0x00; + coinjs.priv = 0x80; + coinjs.multisig = 0x05; + coinjs.hdkey = {'prv':0x0488ade4, 'pub':0x0488b21e}; + coinjs.txExtraTimeField = false; coinjs.txExtraTimeFieldValue = false; coinjs.txExtraUnitField = false; coinjs.txExtraUnitFieldValue = false; coinjs.decimalPlaces = 8; + coinjs.symbol = 'BTC'; - coinjs.pub = 0x00; - coinjs.priv = 0x80; - coinjs.multisig = 0x05; - coinjs.hdkey = {'prv':0x0488ade4, 'pub':0x0488b21e}; coinjs.compressed = false; @@ -1071,9 +1074,13 @@ return r; } + r.extractRedeemScript = function(script){ + return (script.chunks[script.chunks.length-1]==174) ? script.buffer : script.chunks[script.chunks.length-1]; + } + /* sign a multisig input */ r.signmultisig = function(index, wif){ - var redeemScript = (this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174) ? this.ins[index].script.buffer : this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]; + var redeemScript = this.extractRedeemScript(this.ins[index].script); var sighash = Crypto.util.hexToBytes(this.transactionHash(index)); var signature = Crypto.util.hexToBytes(this.transactionSig(index, wif)); var s = coinjs.script(); @@ -1107,23 +1114,26 @@ var s = this.extractScriptKey(index); if(s['type'] != 'multisig') return false; + var redeemScript = this.extractRedeemScript(this.ins[index].script); + var sighash = Crypto.util.hexToBytes(this.transactionHash(index)); - var pubkeyList = this.scriptListPubkey(coinjs.script(Crypto.util.bytesToHex(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]))); - var sigsList = this.scriptListSigs(this.ins[index].script); - + var pubkeyList = this.scriptListPubkey(coinjs.script(redeemScript)); for (var x = 0; x < pubkeyList.length; x++) { list[pubkeyList[x]] = false; } - var pubkey = false; - for (var y = 0; y < sigsList.length; y++) { - pubkey = coinjs.verifySignature(sighash, sigsList[y], pubkeyList); - if (pubkey){ - list[pubkey] = Crypto.util.bytesToHex(sigsList[y]); + if (s['signed']) { + var sigsList = this.scriptListSigs(this.ins[index].script); + var pubkey = false; + for (var y = 0; y < sigsList.length; y++) { + pubkey = coinjs.verifySignature(sighash, sigsList[y], pubkeyList); + if (pubkey){ + list[pubkey] = Crypto.util.bytesToHex(sigsList[y]); + } } } - + return list; } @@ -1499,5 +1509,9 @@ } return r; } + + coinjs.formatAmount = function(amount) { + return (amount/("1e"+coinjs.decimalPlaces)).toString() + " " + coinjs.symbol; + } })(); diff --git a/js/cointoolkit.js b/js/cointoolkit.js index d4a4f550..d5925ca3 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1,5 +1,6 @@ $(document).ready(function() { + var toolkit = {}; /* open wallet code */ $("#openBtn").click(function(){ @@ -26,7 +27,7 @@ $(document).ready(function() { var keys = coinjs.newKeys(s); $("#walletAddress").html(keys.address); - $("#walletHistory").attr('href','https://btc.blockr.io/address/info/'+keys.address); + $("#walletHistory").attr('href','//btc.blockr.io/address/info/'+keys.address); $("#walletQrCode").html(""); var qrcode = new QRCode("walletQrCode"); @@ -63,7 +64,7 @@ $(document).ready(function() { $("#openWallet").addClass("hidden").show(); $("#walletAddress").html(""); - $("#walletHistory").attr('href','https://btc.blockr.io/address/info/'); + $("#walletHistory").attr('href','//btc.blockr.io/address/info/'); $("#walletQrCode").html(""); var qrcode = new QRCode("walletQrCode"); @@ -810,9 +811,9 @@ $(document).ready(function() { try { var decode = tx.deserialize($("#verifyScript").val()); $("#verifyTransactionData .transactionVersion").html(decode['version']); - $("#verifyTransactionData .transactionTime").html(decode['nTime']); + $("#verifyTransactionData .transactionTime").html(new Date(decode['nTime']*1000).toUTCString()); $("#verifyTransactionData .transactionSize").html(decode.size()+' bytes'); - $("#verifyTransactionData .transactionLockTime").html(decode['lock_time']); + $("#verifyTransactionData .transactionLockTime").html((decode['lock_time'] >= 500000000)?new Date(decode['nTime']*1000).toUTCString():"Block height "+decode['lock_time']); $("#verifyTransactionData .transactionUnit").html(String.fromCharCode(decode['nUnit'])); $("#verifyTransactionData .verifyToSign").on( "click", function() { $("#signTransaction").val(decode.serialize()).fadeOut().fadeIn(); @@ -821,22 +822,29 @@ $(document).ready(function() { $("#verifyTransactionData").removeClass("hidden"); $("#verifyTransactionData tbody").html(""); + $("#verifyTransactionData .ins tbody").html(""); + $("#verifyTransactionData .fee").addClass("hidden").attr("style", ""); + + var inAmountAvailable = 0; + var amountTotal = 0; + var h = ''; $.each(decode.ins, function(i,o){ var s = decode.extractScriptKey(i); - h += '
    '; - h += ''; - h += ''; - h += ''; - h += ''; + h += ''; + h += ''; + h += ''; + h += ''; + h += ''; - h += ''; h += ''; + + $(h).appendTo("#verifyTransactionData .ins tbody"); + + if (toolkit.getInputAmount != "disabled") { + (function (inputid, total) { + providers[$("#coinSelector").val()].getInputAmount[toolkit.getInputAmount](o.outpoint.hash, o.outpoint.index, function(result) { + $("#verifyTransactionData .ins tbody td[data-inputid="+inputid+"]").html((result)?coinjs.formatAmount(result):'Not found'); + if (result) { + amountTotal += result; + if (++inAmountAvailable == total) { + $.each(decode.outs, function(i,o){ + amountTotal -= o.value; + }); + + if ((amountTotal/("1e"+coinjs.decimalPlaces)) > 0.011) { + $("#verifyTransactionData .fee").attr("style", "color: red;") + } + $("#verifyTransactionData .fee").removeClass("hidden"); + $("#verifyTransactionData .fee .amount").html(coinjs.formatAmount(amountTotal)); + } + } + }); + })(i, decode.ins.length); + } else { + $("#verifyTransactionData .ins tbody td[data-inputid="+i+"]").html("Not available"); + } }); - - $(h).appendTo("#verifyTransactionData .ins tbody"); $("#verifyTransactionData .ins tbody").on( "click", "a[data-index]", function(e) { e.preventDefault(); @@ -902,7 +934,7 @@ $(document).ready(function() { h += ''; h += ''; h += ''; - h += ''; + h += ''; h += ''; h += ''; } @@ -948,7 +980,7 @@ $(document).ready(function() { $("#modalMultisig .combineTx").click(function() { var newTx = tx.combineMultiSignature($("#modalMultisig .combine textarea").val()); if (newTx) { - console.log(newTx, newTx.serialize()); + if (coinjs.debug) {console.log(newTx, newTx.serialize())}; $("#verifyScript").val(newTx.serialize()).fadeOut().fadeIn(); $("#verifyBtn").click(); @@ -1165,11 +1197,14 @@ $(document).ready(function() { $("#verifyTransactionData .txunit").hide(); } - coinjs.decimalPlaces = $("#coinjs_decimalplaces").val()*1;; + coinjs.decimalPlaces = $("#coinjs_decimalplaces").val()*1; + coinjs.symbol = $("#coinjs_symbol").val(); $("#rawSubmitBtn").attr('rel',$("#coinjs_broadcast option:selected").val()); $("#redeemFromBtn").attr('rel',$("#coinjs_utxo option:selected").val()); + toolkit.getInputAmount = $("#coinjs_getinputamount option:selected").val(); + $("#coinSelector").val($("#coinjs_coin").val()); $("#statusSettings").addClass("alert-success").removeClass("hidden").html(" Settings updated successfully").fadeOut().fadeIn().delay(2000).fadeOut(); ; @@ -1209,19 +1244,36 @@ $(document).ready(function() { })); }); - $("#coinjs_utxo, #redeemFrom, #redeemFromBtn, .qrcodeScanner").attr('disabled',false); + $("#coinjs_utxo, #redeemFrom, #redeemFromBtn").attr('disabled',false); $("#coinjs_utxo").val(o[6]); $("#redeemFrom").val(""); walletAvailableUnspent = true; } else { - $("#coinjs_utxo, #redeemFrom, #redeemFromBtn, .qrcodeScanner").attr('disabled',true); + $("#coinjs_utxo, #redeemFrom, #redeemFromBtn").attr('disabled',true); $("#coinjs_utxo").append('').val("disabled"); $("#redeemFrom").val("Loading of address inputs is currently not available for " + this.options[ this.selectedIndex ].text); } + // deal with input amount settings + $('#coinjs_getinputamount').empty(); + if(typeof(providers[mode]) == 'object' && typeof(providers[mode].getInputAmount) == 'object' && Object.keys(providers[mode].getInputAmount).length > 0){ + $.each(providers[mode].getInputAmount, function(key) { + $('#coinjs_getinputamount').append($('').val("disabled"); + } + // deal with broadcasting settings $('#coinjs_broadcast').empty(); @@ -1256,10 +1308,11 @@ $(document).ready(function() { $("#coinjs_hdpub").val(o[3]); $("#coinjs_hdprv").val(o[4]); - $("#coinjs_extratimefield").val(o[7]); - $("#coinjs_extraunitfieldvalue").val(o[8]); + $("#coinjs_extratimefield").val(o[8]); + $("#coinjs_extraunitfieldvalue").val(o[9]); - $("#coinjs_decimalplaces").val(o[9]); + $("#coinjs_decimalplaces").val(o[10]); + $("#coinjs_symbol").val(o[11]); // hide/show custom screen if($("option:selected",this).val()=="custom"){ @@ -1319,13 +1372,12 @@ $(document).ready(function() { /* external providers */ var listunspent_blockexplorer_nu = function(redeem){ - var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' - var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is http://blockexplorer.nu/ down?'; + var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' + var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is https://blockexplorer.nu/ down?'; $.ajax ({ type: "GET", url: "//crossorigin.me/https://blockexplorer.nu/api/v1/addressUnspent/"+redeem.addr, dataType: "json", - cache: "false", error: function(data) { $("#redeemFromStatus").removeClass('hidden').html(msgError); $("#redeemFromBtn").html("Load").attr('disabled',false); @@ -1356,6 +1408,25 @@ $(document).ready(function() { } }); }; + + var getinputamount_blockexplorer_nu = function(txid, index, callback) { + $.ajax ({ + type: "GET", + url: "//crossorigin.me/https://blockexplorer.nu/api/v1/txDetails/"+txid, + dataType: "json", + error: function(data) { + callback(false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.exists && data.outputs[index]) { + callback(data.outputs[index].outValInt*("1e"+coinjs.decimalPlaces)); + } else { + callback(false); + } + } + }); + } /* bit(coinb.in) api vars */ coinjs.host = '//coinb.in/api/'; @@ -1368,15 +1439,15 @@ $(document).ready(function() { blockr_io: function(redeem){ $.ajax ({ type: "GET", - url: "https://btc.blockr.io/api/v1/address/unspent/"+redeem.addr+"?unconfirmed=1", + url: "//btc.blockr.io/api/v1/address/unspent/"+redeem.addr+"?unconfirmed=1", dataType: "json", error: function(data) { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); }, success: function(data) { if (coinjs.debug) {console.log(data)}; - if ((data.status && data.data) && data.status=='success'){ - $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + if (data.status && data.data && data.status=='success'){ + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); for(var i in data.data.unspent){ var o = data.data.unspent[i]; var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script; @@ -1427,10 +1498,10 @@ $(document).ready(function() { }, broadcast: { blockr_io: function(thisbtn){ - $(thisbtn).val('Please wait, loading...').attr('disabled',true); + $(thisbtn).val('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", - url: "https://btc.blockr.io/api/v1/tx/push", + url: "//btc.blockr.io/api/v1/tx/push", data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { @@ -1455,7 +1526,7 @@ $(document).ready(function() { }, coinb_in: function(btn){ var thisbtn = btn; - $(thisbtn).val('Please wait, loading...').attr('disabled',true); + $(thisbtn).val('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "G", url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction', @@ -1479,6 +1550,26 @@ $(document).ready(function() { } }); } + }, + getInputAmount: { + blockr_io: function(txid, index, callback) { + $.ajax ({ + type: "GET", + url: "https://btc.blockr.io/api/v1/tx/info/"+txid, + dataType: "json", + error: function(data) { + callback(false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.status && data.data && data.status=='success' && data.data.vouts[index]){ + callback(data.data.vouts[index].amount*("1e"+coinjs.decimalPlaces)); + } else { + callback(false); + } + } + }); + } } }, litecoin: { @@ -1486,7 +1577,7 @@ $(document).ready(function() { chain_so: function(redeem){ $.ajax ({ type: "GET", - url: "https://chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, + url: "//chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, dataType: "json", error: function(data) { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); @@ -1494,7 +1585,7 @@ $(document).ready(function() { success: function(data) { if (coinjs.debug) {console.log(data)}; if((data.status && data.data) && data.status=='success'){ - $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); for(var i in data.data.txs){ var o = data.data.txs[i]; var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script_hex; @@ -1514,10 +1605,10 @@ $(document).ready(function() { }, broadcast: { blockr_io: function(thisbtn){ - $(thisbtn).val('Please wait, loading...').attr('disabled',true); + $(thisbtn).val('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", - url: "https://ltc.blockr.io/api/v1/tx/push", + url: "//ltc.blockr.io/api/v1/tx/push", data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { @@ -1548,6 +1639,9 @@ $(document).ready(function() { blockexplorer_nu: listunspent_blockexplorer_nu }, broadcast: { + }, + getInputAmount: { + blockexplorer_nu: getinputamount_blockexplorer_nu } }, nushares: { @@ -1555,6 +1649,9 @@ $(document).ready(function() { blockexplorer_nu: listunspent_blockexplorer_nu }, broadcast: { + }, + getInputAmount: { + blockexplorer_nu: getinputamount_blockexplorer_nu } } } @@ -1673,4 +1770,6 @@ $(document).ready(function() { } validateOutputAmount(); + + window["cointoolkit"] = toolkit; }); From a04a15d739d2034fe862098476edde8d9321fce2 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sat, 12 Dec 2015 20:12:18 +0100 Subject: [PATCH 44/92] Fixed signature order --- js/coin.js | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/js/coin.js b/js/coin.js index 3d57de26..ce37afc3 100644 --- a/js/coin.js +++ b/js/coin.js @@ -1082,7 +1082,7 @@ r.signmultisig = function(index, wif){ var redeemScript = this.extractRedeemScript(this.ins[index].script); var sighash = Crypto.util.hexToBytes(this.transactionHash(index)); - var signature = Crypto.util.hexToBytes(this.transactionSig(index, wif)); + var newSignature = Crypto.util.hexToBytes(this.transactionSig(index, wif)); var s = coinjs.script(); s.writeOp(0); @@ -1093,11 +1093,21 @@ } else if (this.ins[index].script.chunks[0]==0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1][this.ins[index].script.chunks[this.ins[index].script.chunks.length-1].length-1]==174){ var pubkeyList = this.scriptListPubkey(coinjs.script(redeemScript)); var sigsList = this.scriptListSigs(this.ins[index].script); - sigsList[sigsList.length] = signature; + sigsList[sigsList.length] = newSignature; + + var signatures = {}; + var pubkey; for (var y = 0; y < sigsList.length; y++) { - if(coinjs.verifySignature(sighash, sigsList[y], pubkeyList)){ - s.writeBytes(sigsList[y]); + pubkey = coinjs.verifySignature(sighash, sigsList[y], pubkeyList) + if(pubkey){ + signatures[pubkey] = sigsList[y]; + } + } + + for (var i in pubkeyList) { + if (signatures[pubkeyList[i]]) { + s.writeBytes(signatures[pubkeyList[i]]); } } @@ -1147,12 +1157,16 @@ for (var index = 0; index < this.ins.length; index++) { var s = this.extractScriptKey(index); if (s['type'] == 'multisig') { + var redeemScript = this.extractRedeemScript(this.ins[index].script); + var pubkeyList = this.scriptListPubkey(coinjs.script(redeemScript)); + var listThis = this.listMultiSignature(index); var list2 = tx2.listMultiSignature(index); var s = coinjs.script(); s.writeOp(0); - for (var pubkey in listThis) { + for (var i in pubkeyList) { + var pubkey = pubkeyList[i]; var valid = (listThis[pubkey])?listThis[pubkey]:list2[pubkey]; if (valid) { s.writeBytes(Crypto.util.hexToBytes(valid)); From 9086c6187f27177cacbf6ced32334799ac338b34 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 13 Dec 2015 21:34:03 +0100 Subject: [PATCH 45/92] Style fixes --- css/style.css | 6 +++++- index.html | 12 ++++++------ js/coin.js | 1 - 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/css/style.css b/css/style.css index 4b0ef835..4652d4a5 100644 --- a/css/style.css +++ b/css/style.css @@ -45,7 +45,11 @@ body { } @media (min-width: 768px) { - #modalMultisig .modal-dialog { + .wideModal .modal-dialog { width: 70%; } +} + +.sig_position { + text-align: center; } \ No newline at end of file diff --git a/index.html b/index.html index e587ce0e..79bef070 100644 --- a/index.html +++ b/index.html @@ -1151,7 +1151,7 @@

    Settings

    -
    TxidNScriptSigned?MultiSig? + Txid + + N + + Amount + + Script + + Signed? + + MultiSig? +
    '+o.outpoint.index+''; - h += ''; - if(s['type']=='multisig' && s['signatures']>=1){ - h += ''; - h += ' '+s['signatures']; - h += ''; - } + h = '
    '+o.outpoint.index+''; + h += ''; + if(s['type']=='multisig' && s['signatures']>=1){ + h += ''; + h += ' '+s['signatures']; + h += ''; + } h += ''; + h += ''; if(s['type']=='multisig'){ h += ''; var script = coinjs.script(); @@ -848,9 +856,33 @@ $(document).ready(function() { } h += '
    '+(o.value/("1e"+coinjs.decimalPlaces)).toFixed(coinjs.decimalPlaces)+''+coinjs.formatAmount(o.value)+'
    + @@ -1319,7 +1320,7 @@
    -
    +
    @@ -1340,6 +1341,36 @@
    + + + + diff --git a/js/coin.js b/js/coin.js index e8ac1088..0861d84a 100644 --- a/js/coin.js +++ b/js/coin.js @@ -29,6 +29,151 @@ coinjs.compressed = false; + coinjs.opcode = { + // push value + OP_FALSE : 0, + OP_0 : 0, + OP_PUSHDATA1 : 76, + OP_PUSHDATA2 : 77, + OP_PUSHDATA4 : 78, + OP_1NEGATE : 79, + OP_RESERVED : 80, + OP_1 : 81, + OP_TRUE : 81, + OP_2 : 82, + OP_3 : 83, + OP_4 : 84, + OP_5 : 85, + OP_6 : 86, + OP_7 : 87, + OP_8 : 88, + OP_9 : 89, + OP_10 : 90, + OP_11 : 91, + OP_12 : 92, + OP_13 : 93, + OP_14 : 94, + OP_15 : 95, + OP_16 : 96, + + // control + OP_NOP : 97, + OP_VER : 98, + OP_IF : 99, + OP_NOTIF : 100, + OP_VERIF : 101, + OP_VERNOTIF : 102, + OP_ELSE : 103, + OP_ENDIF : 104, + OP_VERIFY : 105, + OP_RETURN : 106, + + // stack ops + OP_TOALTSTACK : 107, + OP_FROMALTSTACK : 108, + OP_2DROP : 109, + OP_2DUP : 110, + OP_3DUP : 111, + OP_2OVER : 112, + OP_2ROT : 113, + OP_2SWAP : 114, + OP_IFDUP : 115, + OP_DEPTH : 116, + OP_DROP : 117, + OP_DUP : 118, + OP_NIP : 119, + OP_OVER : 120, + OP_PICK : 121, + OP_ROLL : 122, + OP_ROT : 123, + OP_SWAP : 124, + OP_TUCK : 125, + + // splice ops + OP_CAT : 126, + OP_SUBSTR : 127, + OP_LEFT : 128, + OP_RIGHT : 129, + OP_SIZE : 130, + + // bit logic + OP_INVERT : 131, + OP_AND : 132, + OP_OR : 133, + OP_XOR : 134, + OP_EQUAL : 135, + OP_EQUALVERIFY : 136, + OP_RESERVED1 : 137, + OP_RESERVED2 : 138, + + // numeric + OP_1ADD : 139, + OP_1SUB : 140, + OP_2MUL : 141, + OP_2DIV : 142, + OP_NEGATE : 143, + OP_ABS : 144, + OP_NOT : 145, + OP_0NOTEQUAL : 146, + + OP_ADD : 147, + OP_SUB : 148, + OP_MUL : 149, + OP_DIV : 150, + OP_MOD : 151, + OP_LSHIFT : 152, + OP_RSHIFT : 153, + + OP_BOOLAND : 154, + OP_BOOLOR : 155, + OP_NUMEQUAL : 156, + OP_NUMEQUALVERIFY : 157, + OP_NUMNOTEQUAL : 158, + OP_LESSTHAN : 159, + OP_GREATERTHAN : 160, + OP_LESSTHANOREQUAL : 161, + OP_GREATERTHANOREQUAL : 162, + OP_MIN : 163, + OP_MAX : 164, + + OP_WITHIN : 165, + + // crypto + OP_RIPEMD160 : 166, + OP_SHA1 : 167, + OP_SHA256 : 168, + OP_HASH160 : 169, + OP_HASH256 : 170, + OP_CODESEPARATOR : 171, + OP_CHECKSIG : 172, + OP_CHECKSIGVERIFY : 173, + OP_CHECKMULTISIG : 174, + OP_CHECKMULTISIGVERIFY : 175, + + // expansion + OP_NOP1 : 176, + OP_NOP2 : 177, + OP_NOP3 : 178, + OP_NOP4 : 179, + OP_NOP5 : 180, + OP_NOP6 : 181, + OP_NOP7 : 182, + OP_NOP8 : 183, + OP_NOP9 : 184, + OP_NOP10 : 185, + + // template matching params + OP_PUBKEYHASH : 253, + OP_PUBKEY : 254, + OP_INVALIDOPCODE : 255 + }; + + coinjs.reverseOpcode = []; + + for (var opcode in coinjs.opcode) { + coinjs.reverseOpcode[coinjs.opcode[opcode]] = opcode; + } + /* start of address functions */ @@ -725,6 +870,27 @@ return true; } + /* convert to opcodes */ + r.toASM = function() { + var s = ''; + + for (var i = 0; i < this.chunks.length; i++) { + var chunk = this.chunks[i]; + + if (i > 0) { + s += ' '; + } + + if (Array.isArray(chunk)) { + s += Crypto.util.bytesToHex(chunk); + } else { + s += coinjs.reverseOpcode[chunk]; + } + } + + return s; + } + r.parse(); return r; } @@ -1139,7 +1305,11 @@ for (var y = 0; y < sigsList.length; y++) { pubkey = coinjs.verifySignature(sighash, sigsList[y], pubkeyList); if (pubkey){ - list[pubkey] = Crypto.util.bytesToHex(sigsList[y]); + if (!list[pubkey]) {list[pubkey] = []}; + list[pubkey].push({ + sig: Crypto.util.bytesToHex(sigsList[y]), + pos: y + }); } } } @@ -1166,13 +1336,18 @@ s.writeOp(0); for (var i in pubkeyList) { var pubkey = pubkeyList[i]; - var valid = (listThis[pubkey])?listThis[pubkey]:list2[pubkey]; + + var valid = false; + try { + valid = (listThis[pubkey])?listThis[pubkey][0].sig:list2[pubkey][0].sig; // If multiple signatures found for a pubkey just take the first one. + } catch (e) {}; + if (valid) { s.writeBytes(Crypto.util.hexToBytes(valid)); } } - s.writeBytes(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]); // redeemScript + s.writeBytes(redeemScript); // redeemScript newTx.ins[index].script = s } diff --git a/js/cointoolkit.js b/js/cointoolkit.js index d5925ca3..34537ff5 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1,233 +1,6 @@ $(document).ready(function() { var toolkit = {}; - /* open wallet code */ - - $("#openBtn").click(function(){ - var email = $("#openEmail").val().toLowerCase(); - if(email.match(/[\s\w\d]+@[\s\w\d]+/g)){ - if($("#openPass").val().length>=10){ - if($("#openPass").val()==$("#openPassConfirm").val()){ - var email = $("#openEmail").val().toLowerCase(); - var pass = $("#openPass").val(); - var s = email; - s += '|'+pass+'|'; - s += s.length+'|!@'+((pass.length*7)+email.length)*7; - var regchars = (pass.match(/[a-z]+/g)) ? pass.match(/[a-z]+/g).length : 1; - var regupchars = (pass.match(/[A-Z]+/g)) ? pass.match(/[A-Z]+/g).length : 1; - var regnums = (pass.match(/[0-9]+/g)) ? pass.match(/[0-9]+/g).length : 1; - s += ((regnums+regchars)+regupchars)*pass.length+'3571'; - s += (s+''+s); - - for(i=0;i<=50;i++){ - s = Crypto.SHA256(s); - } - - coinjs.compressed = true; - var keys = coinjs.newKeys(s); - - $("#walletAddress").html(keys.address); - $("#walletHistory").attr('href','//btc.blockr.io/address/info/'+keys.address); - - $("#walletQrCode").html(""); - var qrcode = new QRCode("walletQrCode"); - qrcode.makeCode(keys.address); - - $("#walletKeys .privkey").val(keys.wif); - $("#walletKeys .pubkey").val(keys.pubkey); - $("#walletKeys .privkeyaes").val(CryptoJS.AES.encrypt(keys.wif, pass)); - - $("#openLogin").hide(); - $("#openWallet").removeClass("hidden").show(); - - walletBalance(); - checkBalanceLoop(); - } else { - $("#openLoginStatus").html("Your passwords do not match!").removeClass("hidden").fadeOut().fadeIn(); - } - } else { - $("#openLoginStatus").html("Your password must be at least 10 chars long").removeClass("hidden").fadeOut().fadeIn(); - } - } else { - $("#openLoginStatus").html("Your email address doesn't appear to be valid").removeClass("hidden").fadeOut().fadeIn(); - } - - $("#openLoginStatus").prepend(' '); - }); - - $("#walletLogout").click(function(){ - $("#openEmail").val(""); - $("#openPass").val(""); - $("#openPassConfirm").val(""); - - $("#openLogin").show(); - $("#openWallet").addClass("hidden").show(); - - $("#walletAddress").html(""); - $("#walletHistory").attr('href','//btc.blockr.io/address/info/'); - - $("#walletQrCode").html(""); - var qrcode = new QRCode("walletQrCode"); - qrcode.makeCode(""); - - $("#walletKeys .privkey").val(""); - $("#walletKeys .pubkey").val(""); - - }); - - $("#walletShowKeys").click(function(){ - $("#walletKeys").removeClass("hidden"); - $("#walletSpend").removeClass("hidden").addClass("hidden"); - }); - - $("#walletBalance").click(function(){ - walletBalance(); - }); - - $("#walletConfirmSend").click(function(){ - var thisbtn = $(this); - var tx = coinjs.transaction(); - var txfee = $("#txFee"); - /*var devaddr = coinjs.developer; // TODO: generate address from dev known pubkey - var devamount = $("#developerDonation"); - - if((devamount.val()*1)>0){ - tx.addoutput(devaddr, devamount.val()*1); - }*/ - - var total = (devamount.val()*1) + (txfee.val()*1); - - $.each($("#walletSpendTo .output"), function(i,o){ - var addr = $('.addressTo',o); - var amount = $('.amount',o); - total += amount.val()*1; - tx.addoutput(addr.val(), amount.val()*1); - }); - - thisbtn.attr('disabled',true); - - tx.addUnspent($("#walletAddress").html(), function(data){ - var dvalue = data.value/("1e"+coinjs.decimalPlaces); - if(dvalue>=total){ - var change = dvalue-total; - if(change>0){ - tx.addoutput($("#walletAddress").html(), change); - } - - // clone the transaction with out using coinjs.clone() function as it gives us trouble - var tx2 = coinjs.transaction(); - var txunspent = tx2.deserialize(tx.serialize()); - - // then sign - var signed = txunspent.sign($("#walletKeys .privkey").val()); - - // and finally broadcast! - /* - tx2.broadcast(function(data){ // TODO: function no longer part of coin.js - - - - r.broadcast = function(callback, txhex){ - var tx = txhex || this.serialize(); - coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction&rawtx='+tx+'&r='+Math.random(), callback, "GET"); - } - - - if($(data).find("result").text()=="1"){ - $("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-success').html("txid: "+$(data).find("txid").text()); - } else { - $("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-danger').html(unescape($(data).find("response").text()).replace(/\+/g,' ')); - thisbtn.attr('disabled',false); - } - - // update wallet balance - walletBalance(); - - }, signed); - */ - } else { - $("#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); - } - - $("#walletLoader").addClass("hidden"); - }); - }); - - $("#walletSendBtn").click(function(){ - - $("#walletSendStatus").addClass("hidden").html(""); - - var thisbtn = $(this); - var txfee = $("#txFee"); - var devamount = $("#developerDonation"); - - if((!isNaN(devamount.val())) && devamount.val()>=0){ - $(devamount).parent().removeClass('has-error'); - } else { - $(devamount).parent().addClass('has-error') - } - - if((!isNaN(txfee.val())) && txfee.val()>=0){ - $(txfee).parent().removeClass('has-error'); - } else { - $(txfee).parent().addClass('has-error'); - } - - var total = (devamount.val()*1) + (txfee.val()*1); - - $.each($("#walletSpendTo .output"), function(i,o){ - var amount = $('.amount',o); - var address = $('.addressTo',o); - - total += amount.val()*1; - - if((!isNaN($(amount).val())) && $(amount).val()>0){ - $(amount).parent().removeClass('has-error'); - } else { - $(amount).parent().addClass('has-error'); - } - - if(coinjs.addressDecode($(address).val())){ - $(address).parent().removeClass('has-error'); - } else { - $(address).parent().addClass('has-error'); - } - }); - - total = total.toFixed(coinjs.decimalPlaces); - - if($("#walletSpend .has-error").length==0){ - var balance = ($("#walletBalance").html()).replace(/[^0-9\.]+/g,'')*1; - if(total<=balance){ - $("#walletSendConfirmStatus").addClass("hidden").removeClass('alert-success').removeClass('alert-danger').html(""); - $("#spendAmount").html(total); - $("#modalWalletConfirm").modal("show"); - $("#walletConfirmSend").attr('disabled',false); - } else { - $("#walletSendStatus").removeClass("hidden").html("You are trying to spend "+total+' but have a balance of '+balance); - } - } else { - $("#walletSpend .has-error").fadeOut().fadeIn(); - $("#walletSendStatus").removeClass("hidden").html(' One or more input has an error'); - } - }); - - $("#walletShowSpend").click(function(){ - $("#walletSpend").removeClass("hidden"); - $("#walletKeys").removeClass("hidden").addClass("hidden"); - }); - - $("#walletSpendTo .addressAdd").click(function(){ - var clone = '
    '+$(this).parent().html()+'
    '; - $("#walletSpendTo").append(clone); - $("#walletSpendTo .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); - $("#walletSpendTo .glyphicon-minus:last").parent().removeClass('addressAdd').addClass('addressRemove'); - $("#walletSpendTo .addressRemove").unbind(""); - $("#walletSpendTo .addressRemove").click(function(){ - $(this).parent().fadeOut().remove(); - }); - }); function updateQueryStringParameter(uri, key, value) { var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"); @@ -262,1403 +35,1778 @@ $(document).ready(function() { },45000); } - /* new -> address code */ - $("#newKeysBtn").click(function(){ - coinjs.compressed = false; - if($("#newCompressed").is(":checked")){ - coinjs.compressed = true; - } - - var s = ($("#newBrainwallet").is(":checked")) ? $("#brainwallet").val() : null; - var coin = coinjs.newKeys(s, ($("#newBrainwallet").is(":checked") && $("#brainwalletIsPrivKey").is(":checked"))); - $("#newGeneratedAddress").val(coin.address); - $("#newPubKey").val(coin.pubkey); - $("#newPrivKeyWif").val(coin.wif); - $("#newPrivKey").val(coin.privkey); + function scannerStart(){ + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || false; + if(navigator.getUserMedia){ + if (!!window.stream) { + $("video").attr('src',null); + window.stream.stop(); + } - /* encrypted key code */ - if((!$("#encryptKey").is(":checked")) || $("#aes256pass").val()==$("#aes256pass_confirm").val()){ - $("#aes256passStatus").addClass("hidden"); - if($("#encryptKey").is(":checked")){ - $("#aes256wifkey").removeClass("hidden"); - } - } else { - $("#aes256passStatus").removeClass("hidden"); - } - $("#newPrivKeyEnc").val(CryptoJS.AES.encrypt(coin.wif, $("#aes256pass").val())+''); - }); + var videoSource = $("select#videoSource").val(); + var constraints = { + video: { + optional: [{sourceId: videoSource}] + } + }; - $("#newBrainwallet").click(function(){ - if($(this).is(":checked")){ - $("#keyFromData").removeClass("hidden"); + navigator.getUserMedia(constraints, function(stream){ + window.stream = stream; // make stream available to console + var videoElement = document.querySelector('video'); + videoElement.src = window.URL.createObjectURL(stream); + videoElement.play(); + }, function(error){ }); + + QCodeDecoder().decodeFromCamera(document.getElementById('videoReader'), function(er,data){ + if(!er){ + var match = data.match(/^(bitcoin|nu|Nu|bcexchange|B\&C\ Exchange|ppcoin|peercoin)\:([a-z0-9]{27,34})/i); + var result = match ? match[2] : data; + $(""+$("#qrcode-scanner-callback-to").html()).val(result); + $("#qrScanClose").click(); + } + }); } else { - $("#keyFromData").addClass("hidden"); + $("#videoReaderError").removeClass("hidden"); + $("#videoReader, #videoSource").addClass("hidden"); } - }); + } - $("#encryptKey").click(function(){ - if($(this).is(":checked")){ - $("#aes256passform").removeClass("hidden"); + /* 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 { - $("#aes256wifkey, #aes256passform, #aes256passStatus").addClass("hidden"); + var script = coinjs.script(); + var decodeRs = script.decodeRedeemScript(string); + if(decodeRs){ // redeem script + r.addr = decodeRs['address']; + r.from = 'redeemScript'; + r.decodedRs = decodeRs; + r.isMultisig = true; + } else { // something else + r.addr = ''; + r.from = 'other'; + r.isMultisig = false; + } } - }); - - /* new -> multisig code */ + return r; + } - $("#newMultiSigAddress").click(function(){ + /* global function to add outputs to page */ + function addOutput(tx, n, script, amount) { + if(tx){ + if($("#inputs .txId:last").val()!=""){ + $("#inputs .txidAdd").click(); + } - $("#multiSigData").removeClass('show').addClass('hidden').fadeOut(); - $("#multisigPubKeys .pubkey").parent().removeClass('has-error'); - $("#releaseCoins").parent().removeClass('has-error'); - $("#multiSigErrorMsg").hide(); + $("#inputs .row:last input").attr('disabled',true); - if((isNaN($("#releaseCoins option:selected").html())) || ((!isNaN($("#releaseCoins option:selected").html())) && ($("#releaseCoins option:selected").html()>$("#multisigPubKeys .pubkey").length || $("#releaseCoins option:selected").html()*1<=0 || $("#releaseCoins option:selected").html()*1>8))){ - $("#releaseCoins").parent().addClass('has-error'); - $("#multiSigErrorMsg").html(' Minimum signatures required is greater than the amount of public keys provided').fadeIn(); - return false; + $("#inputs .txId:last").val(tx); + $("#inputs .txIdN:last").val(n); + $("#inputs .txIdAmount:last").val(amount); + $("#inputs .txIdScript:last").val(script); } + } - var keys = []; - $.each($("#multisigPubKeys .pubkey"), function(i,o){ - if(coinjs.pubkeydecompress($(o).val())){ - keys.push($(o).val()); - $(o).parent().removeClass('has-error'); - } else { + /* math to calculate the inputs and outputs */ + + function totalInputAmount(){ + $("#totalInput").html('0.00'); + $.each($("#inputs .txIdAmount"), function(i,o){ + if(isNaN($(o).val())){ $(o).parent().addClass('has-error'); + } else { + $(o).parent().removeClass('has-error'); + var f = 0; + if(!isNaN($(o).val())){ + f += $(o).val()*1; + } + $("#totalInput").html((($("#totalInput").html()*1) + (f*1)).toFixed(coinjs.decimalPlaces)); } }); + totalFee(); + } - if(($("#multisigPubKeys .pubkey").parent().hasClass('has-error')==false) && $("#releaseCoins").parent().hasClass('has-error')==false){ - var sigsNeeded = $("#releaseCoins option:selected").html(); - var multisig = coinjs.pubkeys2MultisigAddress(keys, sigsNeeded); - $("#multiSigData .address").val(multisig['address']); - $("#multiSigData .script").val(multisig['redeemScript']); - $("#multiSigData .scriptUrl").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+multisig['redeemScript']+'#verify'); - $("#multiSigData").removeClass('hidden').addClass('show').fadeIn(); - $("#releaseCoins").removeClass('has-error'); + function validateOutputAmount(){ + $("#recipients .amount").unbind(''); + $("#recipients .amount").keyup(function(){ + if(isNaN($(this).val())){ + $(this).parent().addClass('has-error'); + } else { + $(this).parent().removeClass('has-error'); + var f = 0; + $.each($("#recipients .amount"),function(i,o){ + if(!isNaN($(o).val())){ + f += $(o).val()*1; + } + }); + $("#totalOutput").html((f).toFixed(coinjs.decimalPlaces)); + } + totalFee(); + }).keyup(); + } + + function totalFee(){ + var fee = (($("#totalInput").html()*1) - ($("#totalOutput").html()*1)).toFixed(coinjs.decimalPlaces); + $("#transactionFee").val((fee>0)?fee:'0.00'); + } + + function decodeRedeemScript(){ + var script = coinjs.script(); + var decode = script.decodeRedeemScript($("#verifyScript").val()); + if(decode){ + $("#verifyRsData .multisigAddress").val(decode['address']); + $("#verifyRsData .multisigScriptHash").val(decode['scriptHash']); + $("#verifyRsData .multisigScriptHashKnown").val((known.scriptHash[decode['scriptHash']])?known.scriptHash[decode['scriptHash']].name:''); + $("#verifyRsData .signaturesRequired").html(decode['signaturesRequired']); + $("#verifyRsData table tbody").html(""); + for(var i=0;i
    ').appendTo("#verifyRsData table tbody"); + } + $("#verifyRsData").removeClass("hidden"); + $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); + return true; } else { - $("#multiSigErrorMsg").html(' One or more public key is invalid!').fadeIn(); + return false; } - }); - - $("#multisigPubKeys .list").on('change', '.pubkey', function() { - var val = (known.pubKey[$(this).val()])?known.pubKey[$(this).val()].name:''; - $(this).parent().parent().find('.id').val(val) - }); + } - $("#multisigPubKeys .list .pubkeyAdd").click(function(){ - if($("#multisigPubKeys .list .pubkeyRemove").length<14){ - var clone = '
    '+$(this).parent().html()+'
    '; - $("#multisigPubKeys .list").append(clone); - $("#multisigPubKeys .list .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); - $("#multisigPubKeys .list .glyphicon-minus:last").parent().removeClass('pubkeyAdd').addClass('pubkeyRemove'); - $("#multisigPubKeys .list .pubkeyRemove").unbind(""); - $("#multisigPubKeys .list .pubkeyRemove").click(function(){ - $(this).parent().fadeOut().remove(); + function decodeTransactionScript(){ + var tx = coinjs.transaction(); + try { + var decode = tx.deserialize($("#verifyScript").val()); + $("#verifyTransactionData .transactionVersion").html(decode['version']); + $("#verifyTransactionData .transactionTime").html(new Date(decode['nTime']*1000).toUTCString()); + $("#verifyTransactionData .transactionSize").html(decode.size()+' bytes'); + $("#verifyTransactionData .transactionLockTime").html((decode['lock_time'] >= 500000000)?new Date(decode['nTime']*1000).toUTCString():"Block height "+decode['lock_time']); + $("#verifyTransactionData .transactionUnit").html(String.fromCharCode(decode['nUnit'])); + $("#verifyTransactionData .verifyToSign").on( "click", function() { + $("#signTransaction").val(decode.serialize()).fadeOut().fadeIn(); + window.location.hash = "#sign"; }); - } - }); + $("#verifyTransactionData").removeClass("hidden"); + $("#verifyTransactionData tbody").html(""); - $("#mediatorList").change(function(){ - var data = ($(this).val()).split(";"); - $("#mediatorPubkey").val(data[0]); - $("#mediatorEmail").val(data[1]); - $("#mediatorFee").val(data[2]); - }) + $("#verifyTransactionData .ins tbody").html(""); + $("#verifyTransactionData .fee").addClass("hidden").attr("style", ""); - $("#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()).change().fadeOut().fadeIn(); - $("#mediatorClose").click(); - return false; - } else if(count==len){ - $("#multisigPubKeys .pubkeyAdd").click(); - $("#mediatorAddKey").click(); - return false; + var inAmountAvailable = 0; + var amountTotal = 0; + + var h = ''; + $.each(decode.ins, function(i,o){ + var s = decode.extractScriptKey(i); + h = ''; + h += ''; + h += ''; + h += ''; + //h += ''; + h += ''; + h += ''; + h += ''; + + $(h).appendTo("#verifyTransactionData .ins tbody"); - $(".deriveHDbtn").click(function(){ - $("#verifyScript").val($("input[type='text']",$(this).parent().parent()).val()); - window.location = "#verify"; - $("#verifyBtn").click(); - }); - - $("#newHDKeysBtn").click(function(){ - coinjs.compressed = true; - var s = ($("#newHDBrainwallet").is(":checked")) ? $("#HDBrainwallet").val() : null; - var hd = coinjs.hd(); - var pair = hd.master(s); - $("#newHDxpub").val(pair.pubkey); - $("#newHDxprv").val(pair.privkey); - - }); - - $("#newHDBrainwallet").click(function(){ - if($(this).is(":checked")){ - $("#HDBrainwallet").removeClass("hidden"); - } else { - $("#HDBrainwallet").addClass("hidden"); - } - }); - - /* new -> transaction code */ - - $("#recipients").on('change', '.address', function() { - var addr = $(this).val(); - var identity = ''; - var details = coinjs.addressDecode(addr); - if (details.type == 'standard') { - $.each(known.pubKey, function(pubkey, id) { - if (coinjs.pubkey2address(pubkey, coinjs.pub) == addr) { - identity = known.pubKey[pubkey].name; - return false; - } - }); - } else if (details.type == 'multisig') { - $.each(known.scriptHash, function(scripthash, id) { - if (coinjs.scripthash2address(scripthash, coinjs.multisig) == addr) { - identity = known.scriptHash[scripthash].name; - return false; + $("#verifyTransactionData .ins tbody").data("tx", decode); + + if (toolkit.getInputAmount != "disabled") { + (function (inputid, total) { + providers[$("#coinSelector").val()].getInputAmount[toolkit.getInputAmount](o.outpoint.hash, o.outpoint.index, function(result) { + $("#verifyTransactionData .ins tbody td[data-inputid="+inputid+"]").html((result)?coinjs.formatAmount(result):'Not found'); + if (result) { + amountTotal += result; + if (++inAmountAvailable == total) { + $.each(decode.outs, function(i,o){ + amountTotal -= o.value; + }); + + if ((amountTotal/("1e"+coinjs.decimalPlaces)) > 0.011) { + $("#verifyTransactionData .fee").attr("style", "color: red;") + } + $("#verifyTransactionData .fee").removeClass("hidden"); + $("#verifyTransactionData .fee .amount").html(coinjs.formatAmount(amountTotal)); + } + } + }); + })(i, decode.ins.length); + } else { + $("#verifyTransactionData .ins tbody td[data-inputid="+i+"]").html("Not available"); } }); - } - $(this).parent().parent().find('.id').val(identity); - }); + h = ''; + $.each(decode.outs, function(i,o){ - $("#recipients .addressAddTo").click(function(){ - if($("#recipients .addressRemoveTo").length<19){ - var clone = '

    '+$(this).parent().parent().html()+'
    '; - $("#recipients").append(clone); - $("#recipients .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); - $("#recipients .glyphicon-minus:last").parent().removeClass('addressAdd').addClass('addressRemoveTo'); - $("#recipients .addressRemoveTo").unbind(""); - $("#recipients .addressRemoveTo").click(function(){ - $(this).parent().parent().fadeOut().remove(); - validateOutputAmount(); - }); - validateOutputAmount(); - } - }); + if(o.script.chunks.length==2 && o.script.chunks[0]==106){ // OP_RETURN - $("#inputs .txidAdd").click(function(){ - var clone = '

    '+$(this).parent().parent().html()+'
    '; - $("#inputs").append(clone); - $("#inputs .txidClear:last").remove(); - $("#inputs .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); - $("#inputs .glyphicon-minus:last").parent().removeClass('txidAdd').addClass('txidRemove'); - $("#inputs .txidRemove").unbind(""); - $("#inputs .txidRemove").click(function(){ - $(this).parent().parent().fadeOut().remove(); - totalInputAmount(); - }); - $("#inputs .row:last input").attr('disabled',false); + var data = Crypto.util.bytesToHex(o.script.chunks[1]); + var dataascii = hex2ascii(data); - $("#inputs .txIdAmount").unbind("").change(function(){ - totalInputAmount(); - }).keyup(function(){ - totalInputAmount(); - }); + if(dataascii.match(/^[\s\d\w]+$/ig)){ + data = dataascii; + } - }); + h += ''; + h += ''; + h += ''; // to account for known address value + h += ''; + h += ''; + h += ''; + } else { - $("#transactionBtn").click(function(){ - var tx = coinjs.transaction(); + var addr = ''; + var identity = ''; + if(o.script.chunks.length==5){ + var pubKeyHash = Crypto.util.bytesToHex(o.script.chunks[2]) + addr = coinjs.scripthash2address(pubKeyHash, coinjs.pub); + $.each(known.pubKey, function(pubkey, id) { + if (coinjs.pubkey2address(pubkey, coinjs.pub) == addr) { + identity = known.pubKey[pubkey].name; + return false; + } + }); + } else { + var scriptHash = Crypto.util.bytesToHex(o.script.chunks[1]); + addr = coinjs.scripthash2address(scriptHash, coinjs.multisig); + if (known.scriptHash[scriptHash]) { + identity = known.scriptHash[scriptHash].name; + } + } + + + - $("#transactionCreate, #transactionCreateStatus").addClass("hidden"); + h += ''; + h += ''; + h += ''; + h += ''; + h += ''; + h += ''; + } + }); + $(h).appendTo("#verifyTransactionData .outs tbody"); - if(($("#nLockTime").val()).match(/^[0-9]+$/g)){ - tx.lock_time = $("#nLockTime").val()*1; + $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); + return true; + } catch(e) { + return false; } + } + + function decodeMultiSig(tx, i) { + var html = ''; + var list = tx.listMultiSignature(i); - if(($("#nTime").val()).match(/^[0-9]+$/g)){ - tx.nTime = $("#nTime").val()*1; - } - - $("#inputs .row").removeClass('has-error'); - - $('#putTabs a[href="#txinputs"], #putTabs a[href="#txoutputs"]').attr('style',''); - - $.each($("#inputs .row"), function(i,o){ - 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"); + for (var pubkey in list) { + identity = ""; + if (known.pubKey[pubkey]) { + identity = known.pubKey[pubkey].name; } - - if(!$(o).hasClass("has-error")){ - tx.addinput($(".txId",o).val(), $(".txIdN",o).val(), $(".txIdScript",o).val()); + + var address = coinjs.pubkey2address(pubkey); + var signature_position = ''; + if (list[pubkey]) { + for (var x = 0; x < list[pubkey].length; x++) { + if (x > 0) {signature_position += ", "} + signature_position += ''+(list[pubkey][x].pos+1)+'' + } + } + html += '\ + \ + \ + \ + \ + '; + } + + $("#modalMultisig table tbody").html(html); + $("#modalMultisig .combine .alert").addClass("hidden"); + + $("#modalMultisig .combineTx").click(function() { + var newTx = tx.combineMultiSignature($("#modalMultisig .combine textarea").val()); + if (newTx) { + if (coinjs.debug) {console.log(newTx, newTx.serialize())}; + $("#verifyScript").val(newTx.serialize()).fadeOut().fadeIn(); + $("#verifyBtn").click(); + + $("#modalMultisig .combine .alert").addClass("hidden"); + $("#modalMultisig").modal("hide"); + + window.location.hash = "#verify"; } else { - $('#putTabs a[href="#txinputs"]').attr('style','color:#a94442;'); + $("#modalMultisig .combine .alert").removeClass("hidden"); } }); + $("#modalMultisig").modal("show"); + } - $("#recipients .row").removeClass('has-error'); + function decodeScript(script) { + var asm = ''; + var multisig = false; - $.each($("#recipients .row"), function(i,o){ - var a = ($(".address",o).val()); - var ad = coinjs.addressDecode(a); - if(((a!="") && (ad.version == coinjs.pub || ad.version == coinjs.multisig)) && $(".amount",o).val()!=""){ // address - tx.addoutput(a, $(".amount",o).val()); - } else if (((a!="") && ad.version === 42) && $(".amount",o).val()!=""){ // stealth address - tx.addstealth(ad, $(".amount",o).val()); - } else if (((($("#opReturn").is(":checked")) && a.match(/^[a-f0-9]+$/ig)) && a.length<160) && (a.length%2)==0) { // data - tx.adddata(a); - } else { // neither address nor data - $(o).addClass('has-error'); - $('#putTabs a[href="#txoutputs"]').attr('style','color:#a94442;'); + var pieces = script.toASM().split(" "); + for (i = 0; i < pieces.length; i++) { + if (i == pieces.length-1) { + var maybemultisig = coinjs.script(pieces[i]); + if (maybemultisig.chunks[maybemultisig.chunks.length - 1] == coinjs.opcode.OP_CHECKMULTISIG) { + multisig = true; + } } - }); - - if(!$("#recipients .row, #inputs .row").hasClass('has-error')){ - $("#transactionCreate textarea").val(tx.serialize()); - $("#transactionCreate .txSize").html(tx.size()); + asm += ''; - $("#transactionCreate .transactionToSign").on( "click", function() { - $("#signTransaction").val(tx.serialize()).fadeOut().fadeIn();; - window.location.hash = "#sign"; - }); - $("#transactionCreate").removeClass("hidden"); - - if($("#transactionFee").val()>=0.011){ - $("#modalWarningFeeAmount").html($("#transactionFee").val()); - $("#modalWarningFee").modal("show"); + if (multisig) { + asm += ''+pieces[i]+'' + + var inner_pieces = maybemultisig.toASM().split(" "); + for (x = 0; x < inner_pieces.length; x++) { + asm += ''+inner_pieces[x]; + console.log(known.scriptHash[inner_pieces[x]]); + if (known.pubKey[inner_pieces[x]]) { + asm += ' (Match with '+known.pubKey[inner_pieces[x]].name+')'; + } else if (known.scriptHash[inner_pieces[x]]) { + asm += ' (Match with '+known.scriptHash[inner_pieces[x]].name+')'; + } + asm += '
    '; + } + } else { + asm += pieces[i]; + if (known.pubKey[pieces[i]]) { + asm += ' (Match with '+known.pubKey[pieces[i]].name+')'; + } else if (known.scriptHash[pieces[i]]) { + asm += ' (Match with '+known.scriptHash[pieces[i]].name+')'; + } } - } else { - $("#transactionCreateStatus").removeClass("hidden").html("One or more input or output is invalid").fadeOut().fadeIn(); + + asm += '

    '; } - }); - $(".txidClear").click(function(){ - $("#inputs .row:first input").attr('disabled',false); - $("#inputs .row:first input").val(""); - totalInputAmount(); - }); + $("#modalScript .asm").html(asm); - $("#inputs .txIdAmount").unbind("").change(function(){ - totalInputAmount(); - }).keyup(function(){ - totalInputAmount(); - }); + $("#modalScript").modal("show"); + } - /* code for the qr code scanner */ - - $(".qrcodeScanner").click(function(){ - if ((typeof MediaStreamTrack === 'function') && typeof MediaStreamTrack.getSources === 'function'){ - MediaStreamTrack.getSources(function(sourceInfos){ - var f = 0; - $("select#videoSource").html(""); - for (var i = 0; i !== sourceInfos.length; ++i) { - var sourceInfo = sourceInfos[i]; - var option = document.createElement('option'); - option.value = sourceInfo.id; - if (sourceInfo.kind === 'video') { - option.text = sourceInfo.label || 'camera ' + ($("select#videoSource options").length + 1); - $(option).appendTo("select#videoSource"); - } - } - }); - - $("#videoSource").unbind("change").change(function(){ - scannerStart() - }); - - } else { - $("#videoSource").addClass("hidden"); - } - scannerStart(); - $("#qrcode-scanner-callback-to").html($(this).attr('forward-result')); - }); - - function scannerStart(){ - navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || false; - if(navigator.getUserMedia){ - if (!!window.stream) { - $("video").attr('src',null); - window.stream.stop(); - } + function hex2ascii(hex) { + var str = ''; + for (var i = 0; i < hex.length; i += 2) + str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + return str; + } - var videoSource = $("select#videoSource").val(); - var constraints = { - video: { - optional: [{sourceId: videoSource}] - } - }; + function decodePrivKey(){ + var wif = $("#verifyScript").val(); + if(wif.length==51 || wif.length==52){ + try { + var w2address = coinjs.wif2address(wif); + var w2pubkey = coinjs.wif2pubkey(wif); + var w2privkey = coinjs.wif2privkey(wif); - navigator.getUserMedia(constraints, function(stream){ - window.stream = stream; // make stream available to console - var videoElement = document.querySelector('video'); - videoElement.src = window.URL.createObjectURL(stream); - videoElement.play(); - }, function(error){ }); + $("#verifyPrivKey .address").val(w2address['address']); + $("#verifyPrivKey .pubkey").val(w2pubkey['pubkey']); + $("#verifyPrivKey .privkey").val(w2privkey['privkey']); + $("#verifyPrivKey .iscompressed").html(w2address['compressed']?'true':'false'); - QCodeDecoder().decodeFromCamera(document.getElementById('videoReader'), function(er,data){ - if(!er){ - var match = data.match(/^(bitcoin|nu|Nu|bcexchange|B\&C\ Exchange|ppcoin|peercoin)\:([a-z0-9]{27,34})/i); - var result = match ? match[2] : data; - $(""+$("#qrcode-scanner-callback-to").html()).val(result); - $("#qrScanClose").click(); - } - }); + $("#verifyPrivKey").removeClass("hidden"); + return true; + } catch (e) { + return false; + } } else { - $("#videoReaderError").removeClass("hidden"); - $("#videoReader, #videoSource").addClass("hidden"); + return false; } } - - /* broadcast code */ - $("#rawSubmitBtn").click(function(){ - var host = $(this).attr('rel'); - providers[$("#coinSelector").val()].broadcast[host](this); - }); - - /* redeem from button code */ - $("#redeemFromBtn").click(function(){ - var redeem = redeemingFrom($("#redeemFrom").val()); - - $("#redeemFromStatus, #redeemFromAddress").addClass('hidden'); - if(redeem.from=='multisigAddress'){ - $("#redeemFromStatus").removeClass('hidden').html(' This is a multisig address. You must use the redeem script, not the multisig address!'); + function decodePubKey(){ + var pubkey = $("#verifyScript").val(); + if(pubkey.length==66 || pubkey.length==130){ + try { + $("#verifyPubKey .address").val(coinjs.pubkey2address(pubkey)); + $("#verifyPubKey").removeClass("hidden"); + $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); + return true; + } catch (e) { + return false; + } + } else { return false; } + } - if(redeem.from=='other'){ - $("#redeemFromStatus").removeClass('hidden').html(' The address or multisig redeem script you have entered is invalid'); + function decodeHDaddress(){ + var s = $("#verifyScript").val(); + try { + var hex = Crypto.util.bytesToHex((coinjs.base58decode(s)).slice(0,4)); + var hex_cmp_prv = Crypto.util.bytesToHex((coinjs.numToBytes(coinjs.hdkey.prv,4)).reverse()); + var hex_cmp_pub = Crypto.util.bytesToHex((coinjs.numToBytes(coinjs.hdkey.pub,4)).reverse()); + if(hex == hex_cmp_prv || hex == hex_cmp_pub){ + var hd = coinjs.hd(s); + $("#verifyHDaddress .hdKey").html(s); + $("#verifyHDaddress .chain_code").val(Crypto.util.bytesToHex(hd.chain_code)); + $("#verifyHDaddress .depth").val(hd.depth); + $("#verifyHDaddress .version").val('0x'+(hd.version).toString(16)); + $("#verifyHDaddress .child_index").val(hd.child_index); + $("#verifyHDaddress .hdwifkey").val((hd.keys.wif)?hd.keys.wif:''); + $("#verifyHDaddress .key_type").html((((hd.depth==0 && hd.child_index==0)?'Master':'Derived')+' '+hd.type).toLowerCase()); + $("#verifyHDaddress .parent_fingerprint").val(Crypto.util.bytesToHex(hd.parent_fingerprint)); + $("#verifyHDaddress .derived_data table tbody").html(""); + deriveHDaddress(); + // Not sharing private keys! $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); + $("#verifyHDaddress").removeClass("hidden"); + return true; + } + } catch (e) { return false; } + } - if($("#clearInputsOnLoad").is(":checked")){ - $("#inputs .txidRemove, #inputs .txidClear").click(); - } - - $("#redeemFromBtn").html('Please wait, loading... ').attr('disabled',true); - - var host = $(this).attr('rel'); - providers[$("#coinSelector").val()].listUnspent[host](redeem); - }); - - /* 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.decodedRs = decodeRs; - r.isMultisig = true; - } else { // something else - r.addr = ''; - r.from = 'other'; - r.isMultisig = false; - } + function deriveHDaddress() { + var hd = coinjs.hd($("#verifyHDaddress .hdKey").html()); + var index_start = $("#verifyHDaddress .derivation_index_start").val()*1; + var index_end = $("#verifyHDaddress .derivation_index_end").val()*1; + var html = ''; + $("#verifyHDaddress .derived_data table tbody").html(""); + for(var i=index_start;i<=index_end;i++){ + var derived = hd.derive(i); + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; } - return r; + $(html).appendTo("#verifyHDaddress .derived_data table tbody"); } - /* global function to add outputs to page */ - function addOutput(tx, n, script, amount) { - if(tx){ - if($("#inputs .txId:last").val()!=""){ - $("#inputs .txidAdd").click(); - } + function getMouseXY(e) { + var tempX = 0; + var tempY = 0; + if (IE) { // If browser is IE + tempX = event.clientX + document.body.scrollLeft; + tempY = event.clientY + document.body.scrollTop; + } else { + tempX = e.pageX; + tempY = e.pageY; + }; - $("#inputs .row:last input").attr('disabled',true); + if (tempX < 0){tempX = 0}; + if (tempY < 0){tempY = 0}; + var xEnt = Crypto.util.bytesToHex([tempX]).slice(-2); + var yEnt = Crypto.util.bytesToHex([tempY]).slice(-2); + var addEnt = xEnt.concat(yEnt); - $("#inputs .txId:last").val(tx); - $("#inputs .txIdN:last").val(n); - $("#inputs .txIdAmount:last").val(amount); - $("#inputs .txIdScript:last").val(script); - } - } + if ($("#entropybucket").html().indexOf(xEnt) == -1 && $("#entropybucket").html().indexOf(yEnt) == -1) { + $("#entropybucket").html(addEnt + $("#entropybucket").html()); + }; - /* math to calculate the inputs and outputs */ + if ($("#entropybucket").html().length > 128) { + $("#entropybucket").html($("#entropybucket").html().slice(0, 128)) + }; - function totalInputAmount(){ - $("#totalInput").html('0.00'); - $.each($("#inputs .txIdAmount"), function(i,o){ - if(isNaN($(o).val())){ - $(o).parent().addClass('has-error'); - } else { - $(o).parent().removeClass('has-error'); - var f = 0; - if(!isNaN($(o).val())){ - f += $(o).val()*1; + return true; + }; + + function _get(value) { + var dataArray = (document.location.search).match(/(([a-z0-9\_\[\]]+\=[a-z0-9\_\.\%\@]+))/gi); + var r = []; + if(dataArray) { + for(var x in dataArray) { + if((dataArray[x]) && typeof(dataArray[x])=='string') { + if((dataArray[x].split('=')[0].toLowerCase()).replace(/\[\]$/ig,'') == value.toLowerCase()) { + r.push(unescape(dataArray[x].split('=')[1])); + } } - $("#totalInput").html((($("#totalInput").html()*1) + (f*1)).toFixed(coinjs.decimalPlaces)); } - }); - totalFee(); + } + return r; } - - function validateOutputAmount(){ - $("#recipients .amount").unbind(''); - $("#recipients .amount").keyup(function(){ - if(isNaN($(this).val())){ - $(this).parent().addClass('has-error'); - } else { - $(this).parent().removeClass('has-error'); - var f = 0; - $.each($("#recipients .amount"),function(i,o){ - if(!isNaN($(o).val())){ - f += $(o).val()*1; - } - }); - $("#totalOutput").html((f).toFixed(coinjs.decimalPlaces)); - } - totalFee(); - }).keyup(); - } - - function totalFee(){ - var fee = (($("#totalInput").html()*1) - ($("#totalOutput").html()*1)).toFixed(coinjs.decimalPlaces); - $("#transactionFee").val((fee>0)?fee:'0.00'); - } - - $("#optionsCollapse").click(function(){ - if($("#optionsAdvanced").hasClass('hidden')){ - $("#glyphcollapse").removeClass('glyphicon-collapse-down').addClass('glyphicon-collapse-up'); - $("#optionsAdvanced").removeClass("hidden"); - } else { - $("#glyphcollapse").removeClass('glyphicon-collapse-up').addClass('glyphicon-collapse-down'); - $("#optionsAdvanced").addClass("hidden"); - } - }); - - /* verify script code */ - - $("#verifyBtn").click(function(){ - $(".verifyData").addClass("hidden"); - $("#verifyStatus").hide(); - if(!decodeRedeemScript()){ - if(!decodeTransactionScript()){ - if(!decodePrivKey()){ - if(!decodePubKey()){ - if(!decodeHDaddress()){ - $("#verifyStatus").removeClass('hidden').fadeOut().fadeIn(); + + /* external providers */ + + var listunspent_blockexplorer_nu = function(redeem){ + var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' + var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is https://blockexplorer.nu/ down?'; + $.ajax ({ + type: "GET", + url: "//crossorigin.me/https://blockexplorer.nu/api/v1/addressUnspent/"+redeem.addr, + dataType: "json", + error: function(data) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.length == 0) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + } else { + for(var i=0;i').appendTo("#verifyRsData table tbody"); } - $("#verifyRsData").removeClass("hidden"); - $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); - return true; - } else { - return false; - } - } - - function decodeTransactionScript(){ - var tx = coinjs.transaction(); - try { - var decode = tx.deserialize($("#verifyScript").val()); - $("#verifyTransactionData .transactionVersion").html(decode['version']); - $("#verifyTransactionData .transactionTime").html(new Date(decode['nTime']*1000).toUTCString()); - $("#verifyTransactionData .transactionSize").html(decode.size()+' bytes'); - $("#verifyTransactionData .transactionLockTime").html((decode['lock_time'] >= 500000000)?new Date(decode['nTime']*1000).toUTCString():"Block height "+decode['lock_time']); - $("#verifyTransactionData .transactionUnit").html(String.fromCharCode(decode['nUnit'])); - $("#verifyTransactionData .verifyToSign").on( "click", function() { - $("#signTransaction").val(decode.serialize()).fadeOut().fadeIn(); - window.location.hash = "#sign"; - }); - $("#verifyTransactionData").removeClass("hidden"); - $("#verifyTransactionData tbody").html(""); + }); + }; - $("#verifyTransactionData .ins tbody").html(""); - $("#verifyTransactionData .fee").addClass("hidden").attr("style", ""); + var gitmultisig_listunspent = function(redeem, github_repository) { + if (!redeem.isMultisig) { + $("#redeemFromStatus").removeClass('hidden').html('This provider does not store scripts of unspent transactions, so transactions from single-signature addresses are impossible to create. Please select another provider'); + $("#redeemFromBtn").html("Load").attr('disabled',false); + return; + } - var inAmountAvailable = 0; - var amountTotal = 0; - - var h = ''; - $.each(decode.ins, function(i,o){ - var s = decode.extractScriptKey(i); - h = ''; - h += ''; - h += ''; - h += ''; - h += ''; - h += ''; - h += ''; - h += ''; - h += ''; // to account for known address value - h += ''; - h += ''; - h += ''; - } else { + }, + complete: function(data, status) { + $("#redeemFromBtn").html("Load").attr('disabled',false); + totalInputAmount(); + } + }); + }, + "coinb.in": function(redeem){ + $.ajax ({ + type: "GET", + url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=addresses&request=unspent&address='+redeem.addr+'&r='+Math.random(), + dataType: "xml", + error: function(data) { + if (coinjs.debug) {console.log(data)}; + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if ($(data).children("request").children("result").text()){ + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + $.each($(data).children("request").children("unspent").children(), function(i,o){ + var tx = (($(o).find("tx_hash").text()).match(/.{1,2}/g).reverse()).join("")+''; + var n = $(o).find("tx_output_n").text(); + var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : $(o).find("script").text(); + var amount = (($(o).find("value").text()*1)/("1e"+coinjs.decimalPlaces)).toFixed(coinjs.decimalPlaces); - var addr = ''; - var identity = ''; - if(o.script.chunks.length==5){ - var pubKeyHash = Crypto.util.bytesToHex(o.script.chunks[2]) - addr = coinjs.scripthash2address(pubKeyHash, coinjs.pub); - $.each(known.pubKey, function(pubkey, id) { - if (coinjs.pubkey2address(pubkey, coinjs.pub) == addr) { - identity = known.pubKey[pubkey].name; - return false; + addOutput(tx, n, script, amount); + }); + } else { + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); } - }); - } else { - var scriptHash = Crypto.util.bytesToHex(o.script.chunks[1]); - addr = coinjs.scripthash2address(scriptHash, coinjs.multisig); - if (known.scriptHash[scriptHash]) { - identity = known.scriptHash[scriptHash].name; + }, + complete: function(data, status) { + $("#redeemFromBtn").html("Load").attr('disabled',false); + totalInputAmount(); } - } - - - - - h += ''; - h += ''; - h += ''; - h += ''; - h += ''; - h += ''; + }); } - }); - $(h).appendTo("#verifyTransactionData .outs tbody"); + }, + broadcast: { + "blockr.io": function(thisbtn){ + $(thisbtn).val('Please wait, loading... ').attr('disabled',true); + $.ajax ({ + type: "POST", + url: "//btc.blockr.io/api/v1/tx/push", + data: {"hex":$("#rawTransaction").val()}, + dataType: "json", + error: function(data) { + var r = ' '; + r += (data.data) ? data.data : ''; + r += (data.message) ? ' '+data.message : ''; + r = (r!='') ? r : ' Failed to broadcast'; // build response + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); + }, + success: function(data) { + if((data.status && data.data) && data.status=='success'){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).val('Submit').attr('disabled',false); + } + }); + }, + "coinb.in": function(btn){ + var thisbtn = btn; + $(thisbtn).val('Please wait, loading... ').attr('disabled',true); + $.ajax ({ + type: "G", + url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction', + data: {'rawtx':$("#rawTransaction").val()}, + dataType: "xml", + error: function(data) { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(" There was an error submitting your request, please try again").prepend(''); + }, + success: function(data) { + $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); + if($(data).find("result").text()==1){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); + $("#rawTransactionStatus").html('txid: '+$(data).find("txid").text()); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend(' '); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).val('Submit').attr('disabled',false); + } + }); + } + }, + getInputAmount: { + "blockr.io": function(txid, index, callback) { + $.ajax ({ + type: "GET", + url: "https://btc.blockr.io/api/v1/tx/info/"+txid, + dataType: "json", + error: function(data) { + callback(false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.status && data.data && data.status=='success' && data.data.vouts[index]){ + callback(data.data.vouts[index].amount*("1e"+coinjs.decimalPlaces)); + } else { + callback(false); + } + } + }); + } + } + }, + litecoin: { + listUnspent: { + "chain.so": function(redeem){ + $.ajax ({ + type: "GET", + url: "//chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, + dataType: "json", + error: function(data) { + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if((data.status && data.data) && data.status=='success'){ + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + for(var i in data.data.txs){ + var o = data.data.txs[i]; + var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script_hex; - $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); - return true; - } catch(e) { - return false; + addOutput(o.txid, o.output_no, script, o.value); + } + } else { + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); + } + }, + complete: function(data, status) { + $("#redeemFromBtn").html("Load").attr('disabled',false); + totalInputAmount(); + } + }); + } + }, + broadcast: { + "blockr.io": function(thisbtn){ + $(thisbtn).val('Please wait, loading... ').attr('disabled',true); + $.ajax ({ + type: "POST", + url: "//ltc.blockr.io/api/v1/tx/push", + data: {"hex":$("#rawTransaction").val()}, + dataType: "json", + error: function(data) { + var r = ' '; + r += (data.data) ? data.data : ''; + r += (data.message) ? ' '+data.message : ''; + r = (r!='') ? r : ' Failed to broadcast'; // build response + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if((data.status && data.data) && data.status=='success'){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).val('Submit').attr('disabled',false); + } + }); + } + } + }, + nubits: { + listUnspent: { + "blockexplorer.nu": listunspent_blockexplorer_nu, + "FLOT @dysconnect git-multisig repository": function(redeem) { + gitmultisig_listunspent(redeem, "dc-tcs/flot-operations"); + }, + "FLOT @masterOfDisaster git-multisig repository": function(redeem) { + gitmultisig_listunspent(redeem, "Lamz0rNewb/flot-operations"); + }, + "FLOT @jooize git-multisig repository": function(redeem) { + gitmultisig_listunspent(redeem, "jooize/flot-operations"); + }, + }, + broadcast: { + }, + getInputAmount: { + "blockexplorer.nu": getinputamount_blockexplorer_nu + } + }, + nushares: { + listUnspent: { + "blockexplorer.nu": listunspent_blockexplorer_nu + }, + broadcast: { + }, + getInputAmount: { + "blockexplorer.nu": getinputamount_blockexplorer_nu + } } } - function decodeMultiSig(tx, i) { - var html = ''; - var list = tx.listMultiSignature(i); - - for (var pubkey in list) { - identity = ""; - if (known.pubKey[pubkey]) { - identity = known.pubKey[pubkey].name; - } - - if (coinjs.debug) {console.log(list, pubkey)}; - - var address = coinjs.pubkey2address(pubkey); - html += '\ - \ - \ - \ - '; - } - - $("#modalMultisig table tbody").html(html); - $("#modalMultisig .combine .alert").addClass("hidden"); - - $("#modalMultisig .combineTx").click(function() { - var newTx = tx.combineMultiSignature($("#modalMultisig .combine textarea").val()); - if (newTx) { - if (coinjs.debug) {console.log(newTx, newTx.serialize())}; - $("#verifyScript").val(newTx.serialize()).fadeOut().fadeIn(); - $("#verifyBtn").click(); - - $("#modalMultisig .combine .alert").addClass("hidden"); - $("#modalMultisig").modal("hide"); - - window.location.hash = "#verify"; - } else { - $("#modalMultisig .combine .alert").removeClass("hidden"); - } - }); - $("#modalMultisig").modal("show"); - } - - function hex2ascii(hex) { - var str = ''; - for (var i = 0; i < hex.length; i += 2) - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - return str; - } - - function decodePrivKey(){ - var wif = $("#verifyScript").val(); - if(wif.length==51 || wif.length==52){ - try { - var w2address = coinjs.wif2address(wif); - var w2pubkey = coinjs.wif2pubkey(wif); - var w2privkey = coinjs.wif2privkey(wif); + /* page load code */ - $("#verifyPrivKey .address").val(w2address['address']); - $("#verifyPrivKey .pubkey").val(w2pubkey['pubkey']); - $("#verifyPrivKey .privkey").val(w2privkey['privkey']); - $("#verifyPrivKey .iscompressed").html(w2address['compressed']?'true':'false'); + /* open wallet code */ - $("#verifyPrivKey").removeClass("hidden"); - return true; - } catch (e) { - return false; - } - } else { - return false; - } - } + $("#openBtn").click(function(){ + var email = $("#openEmail").val().toLowerCase(); + if(email.match(/[\s\w\d]+@[\s\w\d]+/g)){ + if($("#openPass").val().length>=10){ + if($("#openPass").val()==$("#openPassConfirm").val()){ + var email = $("#openEmail").val().toLowerCase(); + var pass = $("#openPass").val(); + var s = email; + s += '|'+pass+'|'; + s += s.length+'|!@'+((pass.length*7)+email.length)*7; + var regchars = (pass.match(/[a-z]+/g)) ? pass.match(/[a-z]+/g).length : 1; + var regupchars = (pass.match(/[A-Z]+/g)) ? pass.match(/[A-Z]+/g).length : 1; + var regnums = (pass.match(/[0-9]+/g)) ? pass.match(/[0-9]+/g).length : 1; + s += ((regnums+regchars)+regupchars)*pass.length+'3571'; + s += (s+''+s); - function decodePubKey(){ - var pubkey = $("#verifyScript").val(); - if(pubkey.length==66 || pubkey.length==130){ - try { - $("#verifyPubKey .address").val(coinjs.pubkey2address(pubkey)); - $("#verifyPubKey").removeClass("hidden"); - $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); - return true; - } catch (e) { - return false; - } - } else { - return false; - } - } + for(i=0;i<=50;i++){ + s = Crypto.SHA256(s); + } - function decodeHDaddress(){ - var s = $("#verifyScript").val(); - try { - var hex = Crypto.util.bytesToHex((coinjs.base58decode(s)).slice(0,4)); - var hex_cmp_prv = Crypto.util.bytesToHex((coinjs.numToBytes(coinjs.hdkey.prv,4)).reverse()); - var hex_cmp_pub = Crypto.util.bytesToHex((coinjs.numToBytes(coinjs.hdkey.pub,4)).reverse()); - if(hex == hex_cmp_prv || hex == hex_cmp_pub){ - var hd = coinjs.hd(s); - $("#verifyHDaddress .hdKey").html(s); - $("#verifyHDaddress .chain_code").val(Crypto.util.bytesToHex(hd.chain_code)); - $("#verifyHDaddress .depth").val(hd.depth); - $("#verifyHDaddress .version").val('0x'+(hd.version).toString(16)); - $("#verifyHDaddress .child_index").val(hd.child_index); - $("#verifyHDaddress .hdwifkey").val((hd.keys.wif)?hd.keys.wif:''); - $("#verifyHDaddress .key_type").html((((hd.depth==0 && hd.child_index==0)?'Master':'Derived')+' '+hd.type).toLowerCase()); - $("#verifyHDaddress .parent_fingerprint").val(Crypto.util.bytesToHex(hd.parent_fingerprint)); - $("#verifyHDaddress .derived_data table tbody").html(""); - deriveHDaddress(); - // Not sharing private keys! $("#verify .verifyLink").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+$("#verifyScript").val()); - $("#verifyHDaddress").removeClass("hidden"); - return true; - } - } catch (e) { - return false; - } - } + coinjs.compressed = true; + var keys = coinjs.newKeys(s); - function deriveHDaddress() { - var hd = coinjs.hd($("#verifyHDaddress .hdKey").html()); - var index_start = $("#verifyHDaddress .derivation_index_start").val()*1; - var index_end = $("#verifyHDaddress .derivation_index_end").val()*1; - var html = ''; - $("#verifyHDaddress .derived_data table tbody").html(""); - for(var i=index_start;i<=index_end;i++){ - var derived = hd.derive(i); - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - } - $(html).appendTo("#verifyHDaddress .derived_data table tbody"); - } + $("#walletAddress").html(keys.address); + $("#walletHistory").attr('href','//btc.blockr.io/address/info/'+keys.address); + $("#walletQrCode").html(""); + var qrcode = new QRCode("walletQrCode"); + qrcode.makeCode(keys.address); - /* sign code */ + $("#walletKeys .privkey").val(keys.wif); + $("#walletKeys .pubkey").val(keys.pubkey); + $("#walletKeys .privkeyaes").val(CryptoJS.AES.encrypt(keys.wif, pass)); - $("#signBtn").click(function(){ - var wifkey = $("#signPrivateKey"); - var script = $("#signTransaction"); + $("#openLogin").hide(); + $("#openWallet").removeClass("hidden").show(); - if(coinjs.addressDecode(wifkey.val())){ - $(wifkey).parent().removeClass('has-error'); + walletBalance(); + checkBalanceLoop(); + } else { + $("#openLoginStatus").html("Your passwords do not match!").removeClass("hidden").fadeOut().fadeIn(); + } + } else { + $("#openLoginStatus").html("Your password must be at least 10 chars long").removeClass("hidden").fadeOut().fadeIn(); + } } else { - $(wifkey).parent().addClass('has-error'); + $("#openLoginStatus").html("Your email address doesn't appear to be valid").removeClass("hidden").fadeOut().fadeIn(); } - if((script.val()).match(/^[a-f0-9]+$/ig)){ - $(script).parent().removeClass('has-error'); - } else { - $(script).parent().addClass('has-error'); - } + $("#openLoginStatus").prepend(' '); + }); - if($("#sign .has-error").length==0){ - $("#signedDataError").addClass('hidden'); - try { - var tx = coinjs.transaction(); - var t = tx.deserialize(script.val()); + $("#walletLogout").click(function(){ + $("#openEmail").val(""); + $("#openPass").val(""); + $("#openPassConfirm").val(""); - var signed = t.sign(wifkey.val()); - $("#signedData textarea").val(signed); - $("#signedData .txSize").html(t.size()); - $("#signedData").removeClass('hidden').fadeIn(); + $("#openLogin").show(); + $("#openWallet").addClass("hidden").show(); - $("#signedData .signedToVerify").on( "click", function() { - $("#verifyScript").val(signed).fadeOut().fadeIn(); - $("#verifyBtn").click(); - window.location.hash = "#verify"; - }); + $("#walletAddress").html(""); + $("#walletHistory").attr('href','//btc.blockr.io/address/info/'); + + $("#walletQrCode").html(""); + var qrcode = new QRCode("walletQrCode"); + qrcode.makeCode(""); + + $("#walletKeys .privkey").val(""); + $("#walletKeys .pubkey").val(""); - $("#signedData .signedToBroadcast").on( "click", function() { - $("#broadcast #rawTransaction").val(signed).fadeOut().fadeIn(); - window.location.hash = "#broadcast"; - }); - } catch(e) { - if (coinjs.debug) {console.log(e)}; - } - } else { - $("#signedDataError").removeClass('hidden').delay(2000).queue(function(){ - $(this).addClass("hidden").dequeue(); - }); - $("#signedData").addClass('hidden'); - } }); - /* settings page code */ + $("#walletShowKeys").click(function(){ + $("#walletKeys").removeClass("hidden"); + $("#walletSpend").removeClass("hidden").addClass("hidden"); + }); - $("#coinjs_pub").val('0x'+(coinjs.pub).toString(16)); - $("#coinjs_priv").val('0x'+(coinjs.priv).toString(16)); - $("#coinjs_multisig").val('0x'+(coinjs.multisig).toString(16)); + $("#walletBalance").click(function(){ + walletBalance(); + }); - $("#coinjs_hdpub").val('0x'+(coinjs.hdkey.pub).toString(16)); - $("#coinjs_hdprv").val('0x'+(coinjs.hdkey.prv).toString(16)); + $("#walletConfirmSend").click(function(){ + var thisbtn = $(this); + var tx = coinjs.transaction(); + var txfee = $("#txFee"); + /*var devaddr = coinjs.developer; // TODO: generate address from dev known pubkey + var devamount = $("#developerDonation"); - $("#settingsBtn").click(function(){ + if((devamount.val()*1)>0){ + tx.addoutput(devaddr, devamount.val()*1); + }*/ - // log out of openwallet - $("#walletLogout").click(); - - $("#newGeneratedAddress, #newPubKey, #newPrivKeyWif, #newPrivKey, #newHDxpub, #newHDxprv").val(""); - $("#multiSigData, .verifyData").removeClass('show').addClass('hidden'); + var total = (devamount.val()*1) + (txfee.val()*1); - $("#statusSettings").removeClass("alert-success").removeClass("alert-danger").addClass("hidden").html(""); - $("#settings .has-error").removeClass("has-error"); + $.each($("#walletSpendTo .output"), function(i,o){ + var addr = $('.addressTo',o); + var amount = $('.amount',o); + total += amount.val()*1; + tx.addoutput(addr.val(), amount.val()*1); + }); - $.each($(".coinjssetting"),function(i, o){ - if ($(o).hasClass("boolisvalid")) { - if(!$(o).val().match(/^0x[0-9a-f]+|false$/)){ - $(o).parent().addClass("has-error"); - } - } else { - if(!$(o).val().match(/^0x[0-9a-f]+$/)){ - $(o).parent().addClass("has-error"); + thisbtn.attr('disabled',true); + + tx.addUnspent($("#walletAddress").html(), function(data){ + var dvalue = data.value/("1e"+coinjs.decimalPlaces); + if(dvalue>=total){ + var change = dvalue-total; + if(change>0){ + tx.addoutput($("#walletAddress").html(), change); } - } - }); - if($("#settings .has-error").length==0){ + // clone the transaction with out using coinjs.clone() function as it gives us trouble + var tx2 = coinjs.transaction(); + var txunspent = tx2.deserialize(tx.serialize()); - coinjs.pub = $("#coinjs_pub").val()*1; - coinjs.priv = $("#coinjs_priv").val()*1; - coinjs.multisig = $("#coinjs_multisig").val()*1; + // then sign + var signed = txunspent.sign($("#walletKeys .privkey").val()); - coinjs.hdkey.pub = $("#coinjs_hdpub").val()*1; - coinjs.hdkey.prv = $("#coinjs_hdprv").val()*1; - - coinjs.txExtraTimeField = ($("#coinjs_extratimefield").val() == "true"); - if (coinjs.txExtraTimeField) { - $("#nTime").val(Date.now() / 1000 | 0); - $("#txTimeOptional").show(); - $("#verifyTransactionData .txtime").show(); + // and finally broadcast! + /* + tx2.broadcast(function(data){ // TODO: function no longer part of coin.js + + + + r.broadcast = function(callback, txhex){ + var tx = txhex || this.serialize(); + coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction&rawtx='+tx+'&r='+Math.random(), callback, "GET"); + } + + + if($(data).find("result").text()=="1"){ + $("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-success').html("txid: "+$(data).find("txid").text()); + } else { + $("#walletSendConfirmStatus").removeClass('hidden').addClass('alert-danger').html(unescape($(data).find("response").text()).replace(/\+/g,' ')); + thisbtn.attr('disabled',false); + } + + // update wallet balance + walletBalance(); + + }, signed); + */ } else { - $("#txTimeOptional").hide(); - $("#verifyTransactionData .txtime").hide(); + $("#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); } - - coinjs.txExtraUnitField = ($("#coinjs_extraunitfieldvalue").val() !== "false"); - if (coinjs.txExtraUnitField) { - coinjs.txExtraUnitFieldValue = $("#coinjs_extraunitfieldvalue").val()*1; - $("#verifyTransactionData .txunit").show(); + + $("#walletLoader").addClass("hidden"); + }); + }); + + $("#walletSendBtn").click(function(){ + + $("#walletSendStatus").addClass("hidden").html(""); + + var thisbtn = $(this); + var txfee = $("#txFee"); + var devamount = $("#developerDonation"); + + if((!isNaN(devamount.val())) && devamount.val()>=0){ + $(devamount).parent().removeClass('has-error'); + } else { + $(devamount).parent().addClass('has-error') + } + + if((!isNaN(txfee.val())) && txfee.val()>=0){ + $(txfee).parent().removeClass('has-error'); + } else { + $(txfee).parent().addClass('has-error'); + } + + var total = (devamount.val()*1) + (txfee.val()*1); + + $.each($("#walletSpendTo .output"), function(i,o){ + var amount = $('.amount',o); + var address = $('.addressTo',o); + + total += amount.val()*1; + + if((!isNaN($(amount).val())) && $(amount).val()>0){ + $(amount).parent().removeClass('has-error'); } else { - $("#verifyTransactionData .txunit").hide(); + $(amount).parent().addClass('has-error'); } - - coinjs.decimalPlaces = $("#coinjs_decimalplaces").val()*1; - coinjs.symbol = $("#coinjs_symbol").val(); - - $("#rawSubmitBtn").attr('rel',$("#coinjs_broadcast option:selected").val()); - $("#redeemFromBtn").attr('rel',$("#coinjs_utxo option:selected").val()); - - toolkit.getInputAmount = $("#coinjs_getinputamount option:selected").val(); - - $("#coinSelector").val($("#coinjs_coin").val()); - $("#statusSettings").addClass("alert-success").removeClass("hidden").html(" Settings updated successfully").fadeOut().fadeIn().delay(2000).fadeOut(); ; + if(coinjs.addressDecode($(address).val())){ + $(address).parent().removeClass('has-error'); + } else { + $(address).parent().addClass('has-error'); + } + }); + + total = total.toFixed(coinjs.decimalPlaces); + + if($("#walletSpend .has-error").length==0){ + var balance = ($("#walletBalance").html()).replace(/[^0-9\.]+/g,'')*1; + if(total<=balance){ + $("#walletSendConfirmStatus").addClass("hidden").removeClass('alert-success').removeClass('alert-danger').html(""); + $("#spendAmount").html(total); + $("#modalWalletConfirm").modal("show"); + $("#walletConfirmSend").attr('disabled',false); + } else { + $("#walletSendStatus").removeClass("hidden").html("You are trying to spend "+total+' but have a balance of '+balance); + } } else { - $("#statusSettings").addClass("alert-danger").removeClass("hidden").html("There is an error with one or more of your settings"); + $("#walletSpend .has-error").fadeOut().fadeIn(); + $("#walletSendStatus").removeClass("hidden").html(' One or more input has an error'); } }); - - $("#verify #verifyScript").change(function(){ - $("#verify .verifyData").addClass("hidden"); - }); - $("#sign #signTransaction, #sign #signPrivateKey").change(function(){ - $("#sign #signedData").addClass("hidden"); + $("#walletShowSpend").click(function(){ + $("#walletSpend").removeClass("hidden"); + $("#walletKeys").removeClass("hidden").addClass("hidden"); }); - $("#coinSelector").change(function(){ - $("#coinjs_coin").val(this.value).change(); - $("#settingsBtn").click(); + $("#walletSpendTo .addressAdd").click(function(){ + var clone = '
    '+$(this).parent().html()+'
    '; + $("#walletSpendTo").append(clone); + $("#walletSpendTo .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); + $("#walletSpendTo .glyphicon-minus:last").parent().removeClass('addressAdd').addClass('addressRemove'); + $("#walletSpendTo .addressRemove").unbind(""); + $("#walletSpendTo .addressRemove").click(function(){ + $(this).parent().fadeOut().remove(); + }); }); - $("#coinjs_coin").change(function(){ - var o = ($("option:selected",this).attr("rel")).split(";"); - var mode = this.options[this.selectedIndex].value; - - var walletAvailableUnspent = false; - var walletAvailableBroadcast = false; - - // deal with listUnspent settings` - - $('#coinjs_utxo').empty(); - if(typeof(providers[mode]) == 'object' && typeof(providers[mode].listUnspent) == 'object' && Object.keys(providers[mode].listUnspent).length > 0){ - $.each(providers[mode].listUnspent, function(key) { - $('#coinjs_utxo').append($('').val("disabled"); - - $("#redeemFrom").val("Loading of address inputs is currently not available for " + this.options[ this.selectedIndex ].text); + /* new -> address code */ + + $("#newKeysBtn").click(function(){ + coinjs.compressed = false; + if($("#newCompressed").is(":checked")){ + coinjs.compressed = true; } - // deal with input amount settings - $('#coinjs_getinputamount').empty(); - if(typeof(providers[mode]) == 'object' && typeof(providers[mode].getInputAmount) == 'object' && Object.keys(providers[mode].getInputAmount).length > 0){ - $.each(providers[mode].getInputAmount, function(key) { - $('#coinjs_getinputamount').append($('').val("disabled"); + $("#aes256passStatus").removeClass("hidden"); } - - // deal with broadcasting settings + $("#newPrivKeyEnc").val(CryptoJS.AES.encrypt(coin.wif, $("#aes256pass").val())+''); + }); - $('#coinjs_broadcast').empty(); - if(typeof(providers[mode]) == 'object' && typeof(providers[mode].broadcast) == 'object' && Object.keys(providers[mode].broadcast).length > 0){ - $.each(providers[mode].broadcast, function(key) { - $('#coinjs_broadcast').append($('').val("disabled"); - - $("#rawTransaction").val("Transaction broadcasting is currently not available for " + this.options[ this.selectedIndex ].text); + $("#keyFromData").addClass("hidden"); } - - // enable wallet if available - $("#openBtn").attr('disabled', (walletAvailableUnspent && walletAvailableBroadcast)); - - // deal with the reset - $("#coinjs_pub").val(o[0]); - $("#coinjs_multisig").val(o[1]); - $("#coinjs_priv").val(o[2]); - $("#coinjs_hdpub").val(o[3]); - $("#coinjs_hdprv").val(o[4]); - - $("#coinjs_extratimefield").val(o[8]); - $("#coinjs_extraunitfieldvalue").val(o[9]); - - $("#coinjs_decimalplaces").val(o[10]); - $("#coinjs_symbol").val(o[11]); + }); - // hide/show custom screen - if($("option:selected",this).val()=="custom"){ - $("#settingsCustom").removeClass("hidden"); + $("#encryptKey").click(function(){ + if($(this).is(":checked")){ + $("#aes256passform").removeClass("hidden"); } else { - $("#settingsCustom").addClass("hidden"); + $("#aes256wifkey, #aes256passform, #aes256passStatus").addClass("hidden"); } }); - /* capture mouse movement to add entropy */ - var IE = document.all?true:false // Boolean, is browser IE? - if (!IE) document.captureEvents(Event.MOUSEMOVE) - document.onmousemove = getMouseXY; - function getMouseXY(e) { - var tempX = 0; - var tempY = 0; - if (IE) { // If browser is IE - tempX = event.clientX + document.body.scrollLeft; - tempY = event.clientY + document.body.scrollTop; - } else { - tempX = e.pageX; - tempY = e.pageY; - }; + /* new -> multisig code */ - if (tempX < 0){tempX = 0}; - if (tempY < 0){tempY = 0}; - var xEnt = Crypto.util.bytesToHex([tempX]).slice(-2); - var yEnt = Crypto.util.bytesToHex([tempY]).slice(-2); - var addEnt = xEnt.concat(yEnt); + $("#newMultiSigAddress").click(function(){ - if ($("#entropybucket").html().indexOf(xEnt) == -1 && $("#entropybucket").html().indexOf(yEnt) == -1) { - $("#entropybucket").html(addEnt + $("#entropybucket").html()); - }; + $("#multiSigData").removeClass('show').addClass('hidden').fadeOut(); + $("#multisigPubKeys .pubkey").parent().removeClass('has-error'); + $("#releaseCoins").parent().removeClass('has-error'); + $("#multiSigErrorMsg").hide(); - if ($("#entropybucket").html().length > 128) { - $("#entropybucket").html($("#entropybucket").html().slice(0, 128)) - }; + if((isNaN($("#releaseCoins option:selected").html())) || ((!isNaN($("#releaseCoins option:selected").html())) && ($("#releaseCoins option:selected").html()>$("#multisigPubKeys .pubkey").length || $("#releaseCoins option:selected").html()*1<=0 || $("#releaseCoins option:selected").html()*1>8))){ + $("#releaseCoins").parent().addClass('has-error'); + $("#multiSigErrorMsg").html(' Minimum signatures required is greater than the amount of public keys provided').fadeIn(); + return false; + } - return true; - }; - - function _get(value) { - var dataArray = (document.location.search).match(/(([a-z0-9\_\[\]]+\=[a-z0-9\_\.\%\@]+))/gi); - var r = []; - if(dataArray) { - for(var x in dataArray) { - if((dataArray[x]) && typeof(dataArray[x])=='string') { - if((dataArray[x].split('=')[0].toLowerCase()).replace(/\[\]$/ig,'') == value.toLowerCase()) { - r.push(unescape(dataArray[x].split('=')[1])); - } - } + var keys = []; + $.each($("#multisigPubKeys .pubkey"), function(i,o){ + if(coinjs.pubkeydecompress($(o).val())){ + keys.push($(o).val()); + $(o).parent().removeClass('has-error'); + } else { + $(o).parent().addClass('has-error'); } + }); + + if(($("#multisigPubKeys .pubkey").parent().hasClass('has-error')==false) && $("#releaseCoins").parent().hasClass('has-error')==false){ + var sigsNeeded = $("#releaseCoins option:selected").html(); + var multisig = coinjs.pubkeys2MultisigAddress(keys, sigsNeeded); + $("#multiSigData .address").val(multisig['address']); + $("#multiSigData .script").val(multisig['redeemScript']); + $("#multiSigData .scriptUrl").val(document.location.origin+''+document.location.pathname+'?mode='+$("#coinSelector").val()+'&verify='+multisig['redeemScript']+'#verify'); + $("#multiSigData").removeClass('hidden').addClass('show').fadeIn(); + $("#releaseCoins").removeClass('has-error'); + } else { + $("#multiSigErrorMsg").html(' One or more public key is invalid!').fadeIn(); } - return r; - } - - /* external providers */ + }); - var listunspent_blockexplorer_nu = function(redeem){ - var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' - var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is https://blockexplorer.nu/ down?'; - $.ajax ({ - type: "GET", - url: "//crossorigin.me/https://blockexplorer.nu/api/v1/addressUnspent/"+redeem.addr, - dataType: "json", - error: function(data) { - $("#redeemFromStatus").removeClass('hidden').html(msgError); - $("#redeemFromBtn").html("Load").attr('disabled',false); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if (data.length == 0) { - $("#redeemFromStatus").removeClass('hidden').html(msgError); - $("#redeemFromBtn").html("Load").attr('disabled',false); - } else { - for(var i=0;i'; + $("#multisigPubKeys .list").append(clone); + $("#multisigPubKeys .list .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); + $("#multisigPubKeys .list .glyphicon-minus:last").parent().removeClass('pubkeyAdd').addClass('pubkeyRemove'); + $("#multisigPubKeys .list .pubkeyRemove").unbind(""); + $("#multisigPubKeys .list .pubkeyRemove").click(function(){ + $(this).parent().fadeOut().remove(); + }); + } + }); + + $("#mediatorList").change(function(){ + var data = ($(this).val()).split(";"); + $("#mediatorPubkey").val(data[0]); + $("#mediatorEmail").val(data[1]); + $("#mediatorFee").val(data[2]); + }) + + $("#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()).change().fadeOut().fadeIn(); + $("#mediatorClose").click(); + return false; + } else if(count==len){ + $("#multisigPubKeys .pubkeyAdd").click(); + $("#mediatorAddKey").click(); + return false; } - }, - complete: function(data, status) { - $("#redeemFromBtn").html("Load").attr('disabled',false); - totalInputAmount(); - } - }); - }; + count++; + }); + + $("#mediatorClose").click(); + } + }); + + /* new -> Hd address code */ + + $(".deriveHDbtn").click(function(){ + $("#verifyScript").val($("input[type='text']",$(this).parent().parent()).val()); + window.location = "#verify"; + $("#verifyBtn").click(); + }); + + $("#newHDKeysBtn").click(function(){ + coinjs.compressed = true; + var s = ($("#newHDBrainwallet").is(":checked")) ? $("#HDBrainwallet").val() : null; + var hd = coinjs.hd(); + var pair = hd.master(s); + $("#newHDxpub").val(pair.pubkey); + $("#newHDxprv").val(pair.privkey); + + }); + + $("#newHDBrainwallet").click(function(){ + if($(this).is(":checked")){ + $("#HDBrainwallet").removeClass("hidden"); + } else { + $("#HDBrainwallet").addClass("hidden"); + } + }); + + /* new -> transaction code */ - var getinputamount_blockexplorer_nu = function(txid, index, callback) { - $.ajax ({ - type: "GET", - url: "//crossorigin.me/https://blockexplorer.nu/api/v1/txDetails/"+txid, - dataType: "json", - error: function(data) { - callback(false); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if (data.exists && data.outputs[index]) { - callback(data.outputs[index].outValInt*("1e"+coinjs.decimalPlaces)); - } else { - callback(false); + $("#recipients").on('change', '.address', function() { + var addr = $(this).val(); + var identity = ''; + var details = coinjs.addressDecode(addr); + if (details.type == 'standard') { + $.each(known.pubKey, function(pubkey, id) { + if (coinjs.pubkey2address(pubkey, coinjs.pub) == addr) { + identity = known.pubKey[pubkey].name; + return false; } - } - }); - } + }); + } else if (details.type == 'multisig') { + $.each(known.scriptHash, function(scripthash, id) { + if (coinjs.scripthash2address(scripthash, coinjs.multisig) == addr) { + identity = known.scriptHash[scripthash].name; + return false; + } + }); + } - /* bit(coinb.in) api vars */ - coinjs.host = '//coinb.in/api/'; - coinjs.uid = '1'; - coinjs.key = '12345678901234567890123456789012'; - - var providers = { - bitcoin: { - listUnspent: { - blockr_io: function(redeem){ - $.ajax ({ - type: "GET", - url: "//btc.blockr.io/api/v1/address/unspent/"+redeem.addr+"?unconfirmed=1", - dataType: "json", - error: function(data) { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if (data.status && data.data && data.status=='success'){ - $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); - for(var i in data.data.unspent){ - var o = data.data.unspent[i]; - var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script; - - addOutput(o.tx, o.n, script, o.amount); - } - } else { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); - } - }, - complete: function(data, status) { - $("#redeemFromBtn").html("Load").attr('disabled',false); - totalInputAmount(); - } - }); - }, - coinb_in: function(redeem){ - $.ajax ({ - type: "GET", - url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=addresses&request=unspent&address='+redeem.addr+'&r='+Math.random(), - dataType: "xml", - error: function(data) { - if (coinjs.debug) {console.log(data)}; - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if ($(data).children("request").children("result").text()){ - $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); - $.each($(data).children("request").children("unspent").children(), function(i,o){ - var tx = (($(o).find("tx_hash").text()).match(/.{1,2}/g).reverse()).join("")+''; - var n = $(o).find("tx_output_n").text(); - var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : $(o).find("script").text(); - var amount = (($(o).find("value").text()*1)/("1e"+coinjs.decimalPlaces)).toFixed(coinjs.decimalPlaces); + $(this).parent().parent().find('.id').val(identity); + }); - addOutput(tx, n, script, amount); - }); - } else { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); - } - }, - complete: function(data, status) { - $("#redeemFromBtn").html("Load").attr('disabled',false); - totalInputAmount(); - } - }); + $("#recipients .addressAddTo").click(function(){ + if($("#recipients .addressRemoveTo").length<19){ + var clone = '

    '+$(this).parent().parent().html()+'
    '; + $("#recipients").append(clone); + $("#recipients .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); + $("#recipients .glyphicon-minus:last").parent().removeClass('addressAdd').addClass('addressRemoveTo'); + $("#recipients .addressRemoveTo").unbind(""); + $("#recipients .addressRemoveTo").click(function(){ + $(this).parent().parent().fadeOut().remove(); + validateOutputAmount(); + }); + validateOutputAmount(); + } + }); + + $("#inputs .txidAdd").click(function(){ + var clone = '

    '+$(this).parent().parent().html()+'
    '; + $("#inputs").append(clone); + $("#inputs .txidClear:last").remove(); + $("#inputs .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); + $("#inputs .glyphicon-minus:last").parent().removeClass('txidAdd').addClass('txidRemove'); + $("#inputs .txidRemove").unbind(""); + $("#inputs .txidRemove").click(function(){ + $(this).parent().parent().fadeOut().remove(); + totalInputAmount(); + }); + $("#inputs .row:last input").attr('disabled',false); + + $("#inputs .txIdAmount").unbind("").change(function(){ + totalInputAmount(); + }).keyup(function(){ + totalInputAmount(); + }); + + }); + + $("#transactionBtn").click(function(){ + var tx = coinjs.transaction(); + + $("#transactionCreate, #transactionCreateStatus").addClass("hidden"); + + if(($("#nLockTime").val()).match(/^[0-9]+$/g)){ + tx.lock_time = $("#nLockTime").val()*1; + } + + if(($("#nTime").val()).match(/^[0-9]+$/g)){ + tx.nTime = $("#nTime").val()*1; + } + + $("#inputs .row").removeClass('has-error'); + + $('#putTabs a[href="#txinputs"], #putTabs a[href="#txoutputs"]').attr('style',''); + + $.each($("#inputs .row"), function(i,o){ + 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()); + } else { + $('#putTabs a[href="#txinputs"]').attr('style','color:#a94442;'); + } + }); + + $("#recipients .row").removeClass('has-error'); + + $.each($("#recipients .row"), function(i,o){ + var a = ($(".address",o).val()); + var ad = coinjs.addressDecode(a); + if(((a!="") && (ad.version == coinjs.pub || ad.version == coinjs.multisig)) && $(".amount",o).val()!=""){ // address + tx.addoutput(a, $(".amount",o).val()); + } else if (((a!="") && ad.version === 42) && $(".amount",o).val()!=""){ // stealth address + tx.addstealth(ad, $(".amount",o).val()); + } else if (((($("#opReturn").is(":checked")) && a.match(/^[a-f0-9]+$/ig)) && a.length<160) && (a.length%2)==0) { // data + tx.adddata(a); + } else { // neither address nor data + $(o).addClass('has-error'); + $('#putTabs a[href="#txoutputs"]').attr('style','color:#a94442;'); + } + }); + + + if(!$("#recipients .row, #inputs .row").hasClass('has-error')){ + $("#transactionCreate textarea").val(tx.serialize()); + $("#transactionCreate .txSize").html(tx.size()); + + $("#transactionCreate .transactionToSign").on( "click", function() { + $("#signTransaction").val(tx.serialize()).fadeOut().fadeIn();; + window.location.hash = "#sign"; + }); + + $("#transactionCreate").removeClass("hidden"); + + if($("#transactionFee").val()>=0.011){ + $("#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(){ + $("#inputs .row:first input").attr('disabled',false); + $("#inputs .row:first input").val(""); + totalInputAmount(); + }); + + $("#inputs .txIdAmount").unbind("").change(function(){ + totalInputAmount(); + }).keyup(function(){ + totalInputAmount(); + }); + + /* code for the qr code scanner */ + + $(".qrcodeScanner").click(function(){ + if ((typeof MediaStreamTrack === 'function') && typeof MediaStreamTrack.getSources === 'function'){ + MediaStreamTrack.getSources(function(sourceInfos){ + var f = 0; + $("select#videoSource").html(""); + for (var i = 0; i !== sourceInfos.length; ++i) { + var sourceInfo = sourceInfos[i]; + var option = document.createElement('option'); + option.value = sourceInfo.id; + if (sourceInfo.kind === 'video') { + option.text = sourceInfo.label || 'camera ' + ($("select#videoSource options").length + 1); + $(option).appendTo("select#videoSource"); + } } - }, - broadcast: { - blockr_io: function(thisbtn){ - $(thisbtn).val('Please wait, loading... ').attr('disabled',true); - $.ajax ({ - type: "POST", - url: "//btc.blockr.io/api/v1/tx/push", - data: {"hex":$("#rawTransaction").val()}, - dataType: "json", - error: function(data) { - var r = ' '; - r += (data.data) ? data.data : ''; - r += (data.message) ? ' '+data.message : ''; - r = (r!='') ? r : ' Failed to broadcast'; // build response - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); - }, - success: function(data) { - if((data.status && data.data) && data.status=='success'){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); - } else { - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); - } - }, - complete: function(data, status) { - $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).val('Submit').attr('disabled',false); - } - }); - }, - coinb_in: function(btn){ - var thisbtn = btn; - $(thisbtn).val('Please wait, loading... ').attr('disabled',true); - $.ajax ({ - type: "G", - url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction', - data: {'rawtx':$("#rawTransaction").val()}, - dataType: "xml", - error: function(data) { - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(" There was an error submitting your request, please try again").prepend(''); - }, - success: function(data) { - $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); - if($(data).find("result").text()==1){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); - $("#rawTransactionStatus").html('txid: '+$(data).find("txid").text()); - } else { - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend(' '); - } - }, - complete: function(data, status) { - $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).val('Submit').attr('disabled',false); - } - }); + }); + + $("#videoSource").unbind("change").change(function(){ + scannerStart() + }); + + } else { + $("#videoSource").addClass("hidden"); + } + scannerStart(); + $("#qrcode-scanner-callback-to").html($(this).attr('forward-result')); + }); + + /* code for the script decoder */ + + $(".scriptDecoder").click(function(){ + if ((typeof MediaStreamTrack === 'function') && typeof MediaStreamTrack.getSources === 'function'){ + MediaStreamTrack.getSources(function(sourceInfos){ + var f = 0; + $("select#videoSource").html(""); + for (var i = 0; i !== sourceInfos.length; ++i) { + var sourceInfo = sourceInfos[i]; + var option = document.createElement('option'); + option.value = sourceInfo.id; + if (sourceInfo.kind === 'video') { + option.text = sourceInfo.label || 'camera ' + ($("select#videoSource options").length + 1); + $(option).appendTo("select#videoSource"); + } } - }, - getInputAmount: { - blockr_io: function(txid, index, callback) { - $.ajax ({ - type: "GET", - url: "https://btc.blockr.io/api/v1/tx/info/"+txid, - dataType: "json", - error: function(data) { - callback(false); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if (data.status && data.data && data.status=='success' && data.data.vouts[index]){ - callback(data.data.vouts[index].amount*("1e"+coinjs.decimalPlaces)); - } else { - callback(false); - } + }); + + $("#videoSource").unbind("change").change(function(){ + scannerStart() + }); + + } else { + $("#videoSource").addClass("hidden"); + } + scannerStart(); + $("#qrcode-scanner-callback-to").html($(this).attr('forward-result')); + }); + + /* broadcast code */ + $("#rawSubmitBtn").click(function(){ + var host = $(this).attr('rel'); + providers[$("#coinSelector").val()].broadcast[host](this); + }); + + /* redeem from button code */ + $("#redeemFromBtn").click(function(){ + var redeem = redeemingFrom($("#redeemFrom").val()); + + $("#redeemFromStatus, #redeemFromAddress").addClass('hidden'); + + if(redeem.from=='multisigAddress'){ + $("#redeemFromStatus").removeClass('hidden').html(' This is a multisig address. You must use the redeem script, not the multisig address!'); + return false; + } + + if(redeem.from=='other'){ + $("#redeemFromStatus").removeClass('hidden').html(' 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'); + providers[$("#coinSelector").val()].listUnspent[host](redeem); + }); + + $("#optionsCollapse").click(function(){ + if($("#optionsAdvanced").hasClass('hidden')){ + $("#glyphcollapse").removeClass('glyphicon-collapse-down').addClass('glyphicon-collapse-up'); + $("#optionsAdvanced").removeClass("hidden"); + } else { + $("#glyphcollapse").removeClass('glyphicon-collapse-up').addClass('glyphicon-collapse-down'); + $("#optionsAdvanced").addClass("hidden"); + } + }); + + /* verify script code */ + + $("#verifyBtn").click(function(){ + $(".verifyData").addClass("hidden"); + $("#verifyStatus").hide(); + if(!decodeRedeemScript()){ + if(!decodeTransactionScript()){ + if(!decodePrivKey()){ + if(!decodePubKey()){ + if(!decodeHDaddress()){ + $("#verifyStatus").removeClass('hidden').fadeOut().fadeIn(); } - }); + } } } - }, - litecoin: { - listUnspent: { - chain_so: function(redeem){ - $.ajax ({ - type: "GET", - url: "//chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, - dataType: "json", - error: function(data) { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if((data.status && data.data) && data.status=='success'){ - $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); - for(var i in data.data.txs){ - var o = data.data.txs[i]; - var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script_hex; + } + + }); + + /* sign code */ + + $("#signBtn").click(function(){ + var wifkey = $("#signPrivateKey"); + var script = $("#signTransaction"); + + if(coinjs.addressDecode(wifkey.val())){ + $(wifkey).parent().removeClass('has-error'); + } else { + $(wifkey).parent().addClass('has-error'); + } + + if((script.val()).match(/^[a-f0-9]+$/ig)){ + $(script).parent().removeClass('has-error'); + } else { + $(script).parent().addClass('has-error'); + } + + if($("#sign .has-error").length==0){ + $("#signedDataError").addClass('hidden'); + try { + var tx = coinjs.transaction(); + var t = tx.deserialize(script.val()); + + var signed = t.sign(wifkey.val()); + $("#signedData textarea").val(signed); + $("#signedData .txSize").html(t.size()); + $("#signedData").removeClass('hidden').fadeIn(); + + $("#signedData .signedToVerify").on( "click", function() { + $("#verifyScript").val(signed).fadeOut().fadeIn(); + $("#verifyBtn").click(); + window.location.hash = "#verify"; + }); + + $("#signedData .signedToBroadcast").on( "click", function() { + $("#broadcast #rawTransaction").val(signed).fadeOut().fadeIn(); + window.location.hash = "#broadcast"; + }); + } catch(e) { + if (coinjs.debug) {console.log(e)}; + } + } else { + $("#signedDataError").removeClass('hidden').delay(2000).queue(function(){ + $(this).addClass("hidden").dequeue(); + }); + $("#signedData").addClass('hidden'); + } + }); - addOutput(o.txid, o.output_no, script, o.value); - } - } else { - $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); - } - }, - complete: function(data, status) { - $("#redeemFromBtn").html("Load").attr('disabled',false); - totalInputAmount(); - } - }); + /* settings page code */ + + $("#coinjs_pub").val('0x'+(coinjs.pub).toString(16)); + $("#coinjs_priv").val('0x'+(coinjs.priv).toString(16)); + $("#coinjs_multisig").val('0x'+(coinjs.multisig).toString(16)); + + $("#coinjs_hdpub").val('0x'+(coinjs.hdkey.pub).toString(16)); + $("#coinjs_hdprv").val('0x'+(coinjs.hdkey.prv).toString(16)); + + $("#settingsBtn").click(function(){ + + // log out of openwallet + $("#walletLogout").click(); + + $("#newGeneratedAddress, #newPubKey, #newPrivKeyWif, #newPrivKey, #newHDxpub, #newHDxprv").val(""); + $("#multiSigData, .verifyData").removeClass('show').addClass('hidden'); + + $("#statusSettings").removeClass("alert-success").removeClass("alert-danger").addClass("hidden").html(""); + $("#settings .has-error").removeClass("has-error"); + + $.each($(".coinjssetting"),function(i, o){ + if ($(o).hasClass("boolisvalid")) { + if(!$(o).val().match(/^0x[0-9a-f]+|false$/)){ + $(o).parent().addClass("has-error"); } - }, - broadcast: { - blockr_io: function(thisbtn){ - $(thisbtn).val('Please wait, loading... ').attr('disabled',true); - $.ajax ({ - type: "POST", - url: "//ltc.blockr.io/api/v1/tx/push", - data: {"hex":$("#rawTransaction").val()}, - dataType: "json", - error: function(data) { - var r = ' '; - r += (data.data) ? data.data : ''; - r += (data.message) ? ' '+data.message : ''; - r = (r!='') ? r : ' Failed to broadcast'; // build response - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if((data.status && data.data) && data.status=='success'){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); - } else { - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); - } - }, - complete: function(data, status) { - $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).val('Submit').attr('disabled',false); - } - }); + } else { + if(!$(o).val().match(/^0x[0-9a-f]+$/)){ + $(o).parent().addClass("has-error"); } } - }, - nubits: { - listUnspent: { - blockexplorer_nu: listunspent_blockexplorer_nu - }, - broadcast: { - }, - getInputAmount: { - blockexplorer_nu: getinputamount_blockexplorer_nu + }); + + if($("#settings .has-error").length==0){ + + coinjs.pub = $("#coinjs_pub").val()*1; + coinjs.priv = $("#coinjs_priv").val()*1; + coinjs.multisig = $("#coinjs_multisig").val()*1; + + coinjs.hdkey.pub = $("#coinjs_hdpub").val()*1; + coinjs.hdkey.prv = $("#coinjs_hdprv").val()*1; + + coinjs.txExtraTimeField = ($("#coinjs_extratimefield").val() == "true"); + if (coinjs.txExtraTimeField) { + $("#nTime").val(Date.now() / 1000 | 0); + $("#txTimeOptional").show(); + $("#verifyTransactionData .txtime").show(); + } else { + $("#txTimeOptional").hide(); + $("#verifyTransactionData .txtime").hide(); } - }, - nushares: { - listUnspent: { - blockexplorer_nu: listunspent_blockexplorer_nu - }, - broadcast: { - }, - getInputAmount: { - blockexplorer_nu: getinputamount_blockexplorer_nu + + coinjs.txExtraUnitField = ($("#coinjs_extraunitfieldvalue").val() !== "false"); + if (coinjs.txExtraUnitField) { + coinjs.txExtraUnitFieldValue = $("#coinjs_extraunitfieldvalue").val()*1; + $("#verifyTransactionData .txunit").show(); + } else { + $("#verifyTransactionData .txunit").hide(); } + + coinjs.decimalPlaces = $("#coinjs_decimalplaces").val()*1; + coinjs.symbol = $("#coinjs_symbol").val(); + + $("#rawSubmitBtn").attr('rel',$("#coinjs_broadcast option:selected").val()); + $("#redeemFromBtn").attr('rel',$("#coinjs_utxo option:selected").val()); + + toolkit.getInputAmount = $("#coinjs_getinputamount option:selected").val(); + + $("#coinSelector").val($("#coinjs_coin").val()); + + $("#statusSettings").addClass("alert-success").removeClass("hidden").html(" Settings updated successfully").fadeOut().fadeIn().delay(2000).fadeOut(); ; + } else { + $("#statusSettings").addClass("alert-danger").removeClass("hidden").html("There is an error with one or more of your settings"); } - } + }); - /* page load code */ + $("#verify #verifyScript").change(function(){ + $("#verify .verifyData").addClass("hidden"); + }); + + $("#sign #signTransaction, #sign #signPrivateKey").change(function(){ + $("#sign #signedData").addClass("hidden"); + }); + + $("#coinSelector").change(function(){ + $("#coinjs_coin").val(this.value).change(); + $("#settingsBtn").click(); + }); + $("#coinjs_coin").change(function(){ + var o = ($("option:selected",this).attr("rel")).split(";"); + + var mode = this.options[this.selectedIndex].value; + + var walletAvailableUnspent = false; + var walletAvailableBroadcast = false; + + // deal with listUnspent settings` + + $('#coinjs_utxo').empty(); + if(typeof(providers[mode]) == 'object' && typeof(providers[mode].listUnspent) == 'object' && Object.keys(providers[mode].listUnspent).length > 0){ + $.each(providers[mode].listUnspent, function(key) { + $('#coinjs_utxo').append($('').val("disabled"); + + $("#redeemFrom").val("Loading of address inputs is currently not available for " + this.options[ this.selectedIndex ].text); + } + + // deal with input amount settings + $('#coinjs_getinputamount').empty(); + if(typeof(providers[mode]) == 'object' && typeof(providers[mode].getInputAmount) == 'object' && Object.keys(providers[mode].getInputAmount).length > 0){ + $.each(providers[mode].getInputAmount, function(key) { + $('#coinjs_getinputamount').append($('').val("disabled"); + } + + // deal with broadcasting settings + + $('#coinjs_broadcast').empty(); + if(typeof(providers[mode]) == 'object' && typeof(providers[mode].broadcast) == 'object' && Object.keys(providers[mode].broadcast).length > 0){ + $.each(providers[mode].broadcast, function(key) { + $('#coinjs_broadcast').append($('').val("disabled"); + + $("#rawTransaction").val("Transaction broadcasting is currently not available for " + this.options[ this.selectedIndex ].text); + } + + // enable wallet if available + $("#openBtn").attr('disabled', (walletAvailableUnspent && walletAvailableBroadcast)); + + // deal with the reset + $("#coinjs_pub").val(o[0]); + $("#coinjs_multisig").val(o[1]); + $("#coinjs_priv").val(o[2]); + $("#coinjs_hdpub").val(o[3]); + $("#coinjs_hdprv").val(o[4]); + + $("#coinjs_extratimefield").val(o[8]); + $("#coinjs_extraunitfieldvalue").val(o[9]); + + $("#coinjs_decimalplaces").val(o[10]); + $("#coinjs_symbol").val(o[11]); + + // hide/show custom screen + if($("option:selected",this).val()=="custom"){ + $("#settingsCustom").removeClass("hidden"); + } else { + $("#settingsCustom").addClass("hidden"); + } + }); + + /* verify page code*/ + + $("#verifyTransactionData .ins tbody").on( "click", "a[data-index-multisig]", function(e) { + e.preventDefault(); + decodeMultiSig($("#verifyTransactionData .ins tbody").data("tx"), $(this).attr("data-index-multisig")); + }); + + $("#verifyTransactionData .ins tbody").on( "click", "a[data-index-inputscript]", function(e) { + e.preventDefault(); + decodeScript($("#verifyTransactionData .ins tbody").data("tx").ins[$(this).attr("data-index-inputscript")].script); + }); + + $("#verifyTransactionData .outs tbody").on( "click", "a[data-index-outputscript]", function(e) { + e.preventDefault(); + decodeScript($("#verifyTransactionData .ins tbody").data("tx").outs[$(this).attr("data-index-outputscript")].script); + }); + + /* capture mouse movement to add entropy */ + var IE = document.all?true:false // Boolean, is browser IE? + if (!IE) document.captureEvents(Event.MOUSEMOVE) + document.onmousemove = getMouseXY; - $('input[readonly]').click(function () { + $("html").on( "click", "input[readonly]", function () { this.select(); }); From a3ecd0e4a92de739d942c3e3aa1da40882b89277 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 13 Dec 2015 21:38:24 +0100 Subject: [PATCH 47/92] Usability improvement --- js/cointoolkit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 34537ff5..510ece8f 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -223,7 +223,7 @@ $(document).ready(function() { h += '
    '; h += ''; //h += ''; - h += ''; h += ''; h += ''; - h += ''; + h += ''; h += ''; } }); From 937b25aceb8c532275bf7bc4023291d9a814cd0f Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Sun, 13 Dec 2015 22:32:58 +0100 Subject: [PATCH 48/92] Clear results when updating inputs --- js/cointoolkit.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 510ece8f..8c1f8945 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1675,14 +1675,17 @@ $(document).ready(function() { } }); - $("#verify #verifyScript").change(function(){ + + // clear results when data changed + $("#verify #verifyScript").on('input', function(){ $("#verify .verifyData").addClass("hidden"); }); - $("#sign #signTransaction, #sign #signPrivateKey").change(function(){ + $("#sign #signTransaction, #sign #signPrivateKey").on('input', function(){ $("#sign #signedData").addClass("hidden"); }); + $("#coinSelector").change(function(){ $("#coinjs_coin").val(this.value).change(); $("#settingsBtn").click(); From cfdba44a638e6b15766201a07eec74dbe8bccd95 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 17 Dec 2015 16:33:02 +0100 Subject: [PATCH 49/92] Fixed typo and debug info --- js/coin.js | 8 ++++---- js/cointoolkit.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/js/coin.js b/js/coin.js index 0861d84a..c96a6f46 100644 --- a/js/coin.js +++ b/js/coin.js @@ -393,7 +393,7 @@ return false; } } catch(e) { - if (coinjs.debug) {console.log(e)}; + if (coinjs.debug) {console.log(e.stack)}; return false; } } @@ -411,7 +411,7 @@ publicKeyBytes.unshift(0x04); return Crypto.util.bytesToHex(publicKeyBytes); } catch (e) { - if (coinjs.debug) {console.log(e)}; + if (coinjs.debug) {console.log(e.stack)}; return false; } } @@ -804,7 +804,7 @@ r.scriptHash = multi['scriptHash']; } } catch(e) { - if (coinjs.debug) {console.log(e)}; + if (coinjs.debug) {console.log(e.stack)}; r = false; } return r; @@ -1254,7 +1254,7 @@ s.writeOp(0); if(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174){ - s.writeBytes(signature); + s.writeBytes(newSignature); } else if (this.ins[index].script.chunks[0]==0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1][this.ins[index].script.chunks[this.ins[index].script.chunks.length-1].length-1]==174){ var pubkeyList = this.scriptListPubkey(coinjs.script(redeemScript)); diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 8c1f8945..69f37e66 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1590,7 +1590,7 @@ $(document).ready(function() { window.location.hash = "#broadcast"; }); } catch(e) { - if (coinjs.debug) {console.log(e)}; + if (coinjs.debug) {console.log(e.stack)}; } } else { $("#signedDataError").removeClass('hidden').delay(2000).queue(function(){ From abd2eb19e96adf6bf72391321e094b093f38aa32 Mon Sep 17 00:00:00 2001 From: Miguel Angel Nubla Date: Thu, 17 Dec 2015 16:40:59 +0100 Subject: [PATCH 50/92] Ignore invalid signatures --- js/coin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/coin.js b/js/coin.js index c96a6f46..75afdd51 100644 --- a/js/coin.js +++ b/js/coin.js @@ -1532,7 +1532,7 @@ r = sig.r; s = sig.s; } else { - throw "Invalid value for signature"; + return false; } var pubkey; From c8f59b367644587e9f242da22436e7590795d273 Mon Sep 17 00:00:00 2001 From: Erkan Yilmaz Date: Thu, 31 Dec 2015 14:58:10 +0100 Subject: [PATCH 51/92] its -> it's --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 21f617b0..5c43f457 100644 --- a/index.html +++ b/index.html @@ -107,7 +107,7 @@

    Cointoolkit

    Open Source

    -

    Cointoolkit is an open source web based wallet written in javascript and released under the MIT license which means its free to use and edit.

    +

    Cointoolkit is an open source web based wallet written in javascript and released under the MIT license which means it's free to use and edit.

    From 82679e42582188ec6d3ff843cabbad97c2d2e3fd Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Sat, 2 Jan 2016 18:54:56 +0100 Subject: [PATCH 52/92] Fixed selector --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 21f617b0..65886c18 100644 --- a/index.html +++ b/index.html @@ -1319,7 +1319,7 @@

    -
    +
    From 4c31d219729d9f2a86eac0141df2563f7130c875 Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Sat, 2 Jan 2016 23:56:18 +0100 Subject: [PATCH 53/92] Added sorting of pubkeys on multisig creation --- css/jquery-ui-sort-only.min.css | 6 ++++ css/style.css | 14 +++++++++ index.html | 52 +++++++++++++++++++++------------ js/cointoolkit.js | 51 +++++++++++++++++++++++--------- js/jquery-ui-sort-only.min.js | 7 +++++ 5 files changed, 98 insertions(+), 32 deletions(-) create mode 100644 css/jquery-ui-sort-only.min.css create mode 100644 js/jquery-ui-sort-only.min.js diff --git a/css/jquery-ui-sort-only.min.css b/css/jquery-ui-sort-only.min.css new file mode 100644 index 00000000..dd15d34f --- /dev/null +++ b/css/jquery-ui-sort-only.min.css @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.11.4 - 2016-01-02 +* http://jqueryui.com +* Includes: core.css, sortable.css +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-sortable-handle{-ms-touch-action:none;touch-action:none} \ No newline at end of file diff --git a/css/style.css b/css/style.css index 4652d4a5..05d8a7ea 100644 --- a/css/style.css +++ b/css/style.css @@ -52,4 +52,18 @@ body { .sig_position { text-align: center; +} + +#multisigPubKeys .item { + margin-bottom: 5px; +} + +.glyphicon-minus:before { + content: "\2212"; + margin-left: -1px; +} + +.handle { + padding-left: 15px; + font-size: 20px; } \ No newline at end of file diff --git a/index.html b/index.html index 65886c18..4ea79280 100644 --- a/index.html +++ b/index.html @@ -11,10 +11,12 @@ + + @@ -358,27 +360,37 @@

    New Multisig Address Secure multisig address

    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    +
    S# Address Pubkey Identity (if known)
    '+o.outpoint.index+'Analyze'; + h += ''; + h += ''; + if(s['type']=='multisig' && s['signatures']>=1){ + h += ''; + h += ' '+s['signatures']; + h += ''; + } + h += ''; + if(s['type']=='multisig'){ + h += ''; + var script = coinjs.script(); + var rs = script.decodeRedeemScript(s.script); + h += rs['signaturesRequired']+' of '+rs['pubkeys'].length; + h += ''; + } else { + h += ''; } - count++; - }); - - $("#mediatorClose").click(); - } - }); - - /* new -> Hd address code */ + h += '
    '+(o.value/("1e"+coinjs.decimalPlaces)).toFixed(coinjs.decimalPlaces)+'
    '+coinjs.formatAmount(o.value)+'Analyze
    \ + '+signature_position+'\ + \ + \ + \ + \ + \ + \ +
    '+i+'
    '+o.outpoint.index+''; - h += ''; - if(s['type']=='multisig' && s['signatures']>=1){ - h += ''; - h += ' '+s['signatures']; - h += ''; - } - h += ''; - if(s['type']=='multisig'){ - h += ''; - var script = coinjs.script(); - var rs = script.decodeRedeemScript(s.script); - h += rs['signaturesRequired']+' of '+rs['pubkeys'].length; - h += ''; + var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' + var msgError = ' Unexpected error, unable to retrieve unspent outputs! This provider only store unspent outputs for FLOT addresses https://github.com/'+github_repository+'. Please select another provider'; + $.ajax ({ + type: "GET", + url: "https://raw.githubusercontent.com/"+github_repository+"/master/"+redeem.addr+"/unspent", + dataType: "json", + error: function(data) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (typeof(data.unspent) != "object") { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); } else { - h += ''; + console.log(1); + for(var i=0;i Unexpected error, unable to retrieve unspent outputs!'); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.status && data.data && data.status=='success'){ + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + for(var i in data.data.unspent){ + var o = data.data.unspent[i]; + var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.script; - if ((amountTotal/("1e"+coinjs.decimalPlaces)) > 0.011) { - $("#verifyTransactionData .fee").attr("style", "color: red;") - } - $("#verifyTransactionData .fee").removeClass("hidden"); - $("#verifyTransactionData .fee .amount").html(coinjs.formatAmount(amountTotal)); + addOutput(o.tx, o.n, script, o.amount); } + } else { + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); } - }); - })(i, decode.ins.length); - } else { - $("#verifyTransactionData .ins tbody td[data-inputid="+i+"]").html("Not available"); - } - }); - - $("#verifyTransactionData .ins tbody").on( "click", "a[data-index]", function(e) { - e.preventDefault(); - decodeMultiSig(decode, $(this).attr("data-index")); - }); - - h = ''; - $.each(decode.outs, function(i,o){ - - if(o.script.chunks.length==2 && o.script.chunks[0]==106){ // OP_RETURN - - var data = Crypto.util.bytesToHex(o.script.chunks[1]); - var dataascii = hex2ascii(data); - - if(dataascii.match(/^[\s\d\w]+$/ig)){ - data = dataascii; - } - - h += '
    '+(o.value/("1e"+coinjs.decimalPlaces)).toFixed(coinjs.decimalPlaces)+'
    '+coinjs.formatAmount(o.value)+'
    \ - \ - \ - \ - \ - \ -
    '+i+'
    '+o.outpoint.index+'Analyze'; + h += 'Advanced'; h += ''; h += ''; if(s['type']=='multisig' && s['signatures']>=1){ @@ -320,7 +320,7 @@ $(document).ready(function() { h += ''+coinjs.formatAmount(o.value)+'AnalyzeAdvanced
    + + + + + + + + + + + + + + + + +
    + + + +
    + + - -
    +
    - - - - - + + + +

    Enter the amount of signatures required to release the coins

    @@ -429,6 +441,8 @@

    New Multisig Address Secure multisig address

    + Or +
    diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 69f37e66..a6072c43 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1214,23 +1214,39 @@ $(document).ready(function() { $("#multiSigErrorMsg").html(' One or more public key is invalid!').fadeIn(); } }); + + $("#newMultiSigAddressSort").click(function(){ + var mylist = $("#multisigPubKeys .sort"); + var listitems = mylist.children(); + listitems.sort(function(a, b) { + var compA = $(a).find('.pubkey').val().toUpperCase(); + var compB = $(b).find('.pubkey').val().toUpperCase(); + return (compA < compB) ? -1 : (compA > compB) ? 1 : 0; + }) + $.each(listitems, function(idx, itm) { + console.log(itm); + mylist.append(itm); + }); + $("#multiSigData").addClass("hidden"); + }); - $("#multisigPubKeys .list").on('change', '.pubkey', function() { + $("#multisigPubKeys .list").on('input change', '.pubkey', function() { var val = (known.pubKey[$(this).val()])?known.pubKey[$(this).val()].name:''; $(this).parent().parent().find('.id').val(val) }); - $("#multisigPubKeys .list .pubkeyAdd").click(function(){ + $("#multisigPubKeys .list") + .on('click', '.pubkeyAdd', function(){ if($("#multisigPubKeys .list .pubkeyRemove").length<14){ - var clone = '
    '+$(this).parent().html()+'
    '; - $("#multisigPubKeys .list").append(clone); - $("#multisigPubKeys .list .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); - $("#multisigPubKeys .list .glyphicon-minus:last").parent().removeClass('pubkeyAdd').addClass('pubkeyRemove'); - $("#multisigPubKeys .list .pubkeyRemove").unbind(""); - $("#multisigPubKeys .list .pubkeyRemove").click(function(){ - $(this).parent().fadeOut().remove(); - }); + var clone = $(this).parent().parent().clone(); + $(this).parent().parent().after(clone); + $(clone).find('.pubkey').val('').change(); } + $("#multiSigData").addClass("hidden"); + }) + .on('click', '.pubkeyRemove', function(){ + $(this).parent().parent().remove(); + $("#multiSigData").addClass("hidden"); }); $("#mediatorList").change(function(){ @@ -1289,7 +1305,7 @@ $(document).ready(function() { /* new -> transaction code */ - $("#recipients").on('change', '.address', function() { + $("#recipients").on('input change', '.address', function() { var addr = $(this).val(); var identity = ''; var details = coinjs.addressDecode(addr); @@ -1677,14 +1693,18 @@ $(document).ready(function() { // clear results when data changed - $("#verify #verifyScript").on('input', function(){ + $("#verify #verifyScript").on('input change', function(){ $("#verify .verifyData").addClass("hidden"); }); - $("#sign #signTransaction, #sign #signPrivateKey").on('input', function(){ + $("#sign #signTransaction, #sign #signPrivateKey").on('input change', function(){ $("#sign #signedData").addClass("hidden"); }); + $("#multisigPubKeys .list").on('input change', '.pubkey', function(){ + $("#multiSigData").addClass("hidden"); + }); + $("#coinSelector").change(function(){ $("#coinjs_coin").val(this.value).change(); @@ -1920,6 +1940,11 @@ $(document).ready(function() { $(".pubkeyAdd").click(); } + $( ".sort" ).sortable({ + handle: '.handle', + change: function() {$("#multiSigData").addClass("hidden")} + }); + validateOutputAmount(); window["cointoolkit"] = toolkit; diff --git a/js/jquery-ui-sort-only.min.js b/js/jquery-ui-sort-only.min.js new file mode 100644 index 00000000..478f0651 --- /dev/null +++ b/js/jquery-ui-sort-only.min.js @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.11.4 - 2016-01-02 +* http://jqueryui.com +* Includes: core.js, widget.js, mouse.js, sortable.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var s=0,n=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,a=n.call(arguments,1),o=0,r=a.length;r>o;o++)for(i in a[o])s=a[o][i],a[o].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(a){var o="string"==typeof a,r=n.call(arguments,1),h=this;return o?this.each(function(){var i,n=e.data(this,s);return"instance"===a?(h=n,!1):n?e.isFunction(n[a])&&"_"!==a.charAt(0)?(i=n[a].apply(n,r),i!==n&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+a+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+a+"'")}):(r.length&&(a=e.widget.extend.apply(null,[a].concat(r))),this.each(function(){var t=e.data(this,s);t?(t.option(a||{}),t._init&&t._init()):e.data(this,s,new i(a,this))})),h}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=s++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget;var a=!1;e(document).mouseup(function(){a=!1}),e.widget("ui.mouse",{version:"1.11.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!a){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,n="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),a=!0,!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button)return this._mouseUp(t);if(!t.which)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),a=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),e.widget("ui.sortable",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(e,t,i){return e>=t&&t+i>e},_isFloating:function(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))},_create:function(){this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(e,t){this._super(e,t),"handle"===e&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),e.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,i){var s=null,n=!1,a=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,a.widgetName+"-item")===a?(s=e(this),!1):void 0}),e.data(t.target,a.widgetName+"-item")===a&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var n,a,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(a=this.document.find("body"),this.storedCursor=a.css("cursor"),a.css("cursor",o.cursor),this.storedStylesheet=e("").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!e.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=e.left,o=a+e.width,r=e.top,h=r+e.height,l=this.offset.click.top,u=this.offset.click.left,d="x"===this.options.axis||s+l>r&&h>s+l,c="y"===this.options.axis||t+u>a&&o>t+u,p=d&&c;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(e){var t="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top,e.height),i="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left,e.width),s=t&&i,n=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return s?this.floating?a&&"right"===a||"down"===n?2:1:n&&("down"===n?2:1):!1},_intersectsWithSides:function(e){var t=this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&t||"up"===s&&!t)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){r.push(this)}var s,n,a,o,r=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(a=e(l[s],this.document[0]),n=a.length-1;n>=0;n--)o=e.data(a[n],this.widgetFullName),o&&o!==this&&!o.options.disabled&&h.push([e.isFunction(o.options.items)?o.options.items.call(o.element):e(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(r)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,u=this.items,d=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],c=this._connectWith();if(c&&this.ready)for(i=c.length-1;i>=0;i--)for(n=e(c[i],this.document[0]),s=n.length-1;s>=0;s--)a=e.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(d.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a));for(i=d.length-1;i>=0;i--)for(o=d[i][1],r=d[i][0],s=0,l=r.length;l>s;s++)h=e(r[s]),h.data(this.widgetName+"-item",o),u.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),n=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tbody"===s?t._createTrPlaceholder(t.currentItem.find("tr").eq(0),e("",t.document[0]).appendTo(n)):"tr"===s?t._createTrPlaceholder(t.currentItem,n):"img"===s&&n.attr("src",t.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(e,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_createTrPlaceholder:function(t,i){var s=this;t.children().each(function(){e(" ",s.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(t){var i,s,n,a,o,r,h,l,u,d,c=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!e.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(c&&e.contains(this.containers[i].element[0],c.element[0]))continue;c=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,a=null,u=c.floating||this._isFloating(this.currentItem),o=u?"left":"top",r=u?"width":"height",d=u?"clientX":"clientY",s=this.items.length-1;s>=0;s--)e.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[o],l=!1,t[d]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(t[d]-h)&&(n=Math.abs(t[d]-h),a=this.items[s],this.direction=l?"up":"down"));if(!a&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;a?this._rearrange(t,a,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.width():this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(t=e(n.containment)[0],i=e(n.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]) +},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n=this.options,a=t.pageX,o=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.leftthis.containment[2]&&(a=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&n.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||n.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(n.push(function(e){this._trigger("remove",e,this._uiHash())}),n.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!t){for(s=0;n.length>s;s++)n[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}})}); \ No newline at end of file From 339a86b5e950ae858d185c2b36631989a7f2a28d Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Sun, 10 Jan 2016 23:40:55 +0100 Subject: [PATCH 54/92] Transaction input editor bugfix --- index.html | 2 +- js/cointoolkit.js | 42 +++++++++++++++++------------------------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/index.html b/index.html index f86797a5..fb26eff7 100644 --- a/index.html +++ b/index.html @@ -617,7 +617,7 @@

    New Transaction Create a new transaction

    - +
    diff --git a/js/cointoolkit.js b/js/cointoolkit.js index a6072c43..a83bbe48 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -110,7 +110,7 @@ $(document).ready(function() { function addOutput(tx, n, script, amount) { if(tx){ if($("#inputs .txId:last").val()!=""){ - $("#inputs .txidAdd").click(); + $("#inputs .txidAdd:last").click(); } $("#inputs .row:last input").attr('disabled',true); @@ -1343,25 +1343,22 @@ $(document).ready(function() { } }); - $("#inputs .txidAdd").click(function(){ - var clone = '

    '+$(this).parent().parent().html()+'
    '; - $("#inputs").append(clone); - $("#inputs .txidClear:last").remove(); - $("#inputs .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); - $("#inputs .glyphicon-minus:last").parent().removeClass('txidAdd').addClass('txidRemove'); - $("#inputs .txidRemove").unbind(""); - $("#inputs .txidRemove").click(function(){ - $(this).parent().parent().fadeOut().remove(); - totalInputAmount(); - }); - $("#inputs .row:last input").attr('disabled',false); + $("#inputs").on('click', '.txidAdd', function(){ + var clone = $(this).parent().parent().clone(); + $("input", clone).attr('disabled', false).val(""); + $(this).parent().parent().after(clone); + }); - $("#inputs .txIdAmount").unbind("").change(function(){ - totalInputAmount(); - }).keyup(function(){ - totalInputAmount(); - }); + $("#inputs").on('click', '.txidRemove', function(){ + if ($("#inputs .txidRemove").length < 2) return; + $(this).parent().parent().fadeOut().remove(); + totalInputAmount(); + }); + $("#inputs").on('input change', ".txIdAmount", function(){ + totalInputAmount(); + }).keyup(function(){ + totalInputAmount(); }); $("#transactionBtn").click(function(){ @@ -1435,12 +1432,6 @@ $(document).ready(function() { } }); - $(".txidClear").click(function(){ - $("#inputs .row:first input").attr('disabled',false); - $("#inputs .row:first input").val(""); - totalInputAmount(); - }); - $("#inputs .txIdAmount").unbind("").change(function(){ totalInputAmount(); }).keyup(function(){ @@ -1528,7 +1519,8 @@ $(document).ready(function() { } if($("#clearInputsOnLoad").is(":checked")){ - $("#inputs .txidRemove, #inputs .txidClear").click(); + $("#inputs .txidAdd:last").click(); + $("#inputs .txidRemove:not(:last)").click(); } $("#redeemFromBtn").html('Please wait, loading... ').attr('disabled',true); From 635b09432660e09dfe18c602a37fa548ffbce94b Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Wed, 20 Jan 2016 18:56:35 +0100 Subject: [PATCH 55/92] Fixed floating point issue --- js/cointoolkit.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index a83bbe48..fe7f6146 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -260,7 +260,7 @@ $(document).ready(function() { amountTotal -= o.value; }); - if ((amountTotal/("1e"+coinjs.decimalPlaces)) > 0.011) { + if ((amountTotal/("1e"+coinjs.decimalPlaces)).toFixed(coinjs.decimalPlaces) > 0.011) { $("#verifyTransactionData .fee").attr("style", "color: red;") } $("#verifyTransactionData .fee").removeClass("hidden"); @@ -621,7 +621,7 @@ $(document).ready(function() { success: function(data) { if (coinjs.debug) {console.log(data)}; if (data.exists && data.outputs[index]) { - callback(data.outputs[index].outValInt*("1e"+coinjs.decimalPlaces)); + callback(parseInt(data.outputs[index].outValInt*("1e"+coinjs.decimalPlaces), 10)); } else { callback(false); } @@ -802,7 +802,7 @@ $(document).ready(function() { success: function(data) { if (coinjs.debug) {console.log(data)}; if (data.status && data.data && data.status=='success' && data.data.vouts[index]){ - callback(data.data.vouts[index].amount*("1e"+coinjs.decimalPlaces)); + callback(parseInt(data.data.vouts[index].amount*("1e"+coinjs.decimalPlaces), 10)); } else { callback(false); } From 531f18d75b1cceff35ed66b436f3557f51bba1e8 Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Wed, 20 Jan 2016 19:10:19 +0100 Subject: [PATCH 56/92] Forced HTTPS redirection on the default domain --- js/cointoolkit.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index fe7f6146..539eb2ae 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1,5 +1,9 @@ $(document).ready(function() { + if(window.location.hostname == "ttutdxh-nubits.github.io" && window.location.protocol != 'https:') { + window.location.protocol = "https:"; + } + var toolkit = {}; function updateQueryStringParameter(uri, key, value) { From 680c49d4efea132d20a3c0d553f27395b68b7d28 Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Wed, 20 Jan 2016 19:21:58 +0100 Subject: [PATCH 57/92] Added broadcast button in the verify page --- index.html | 5 +++++ js/cointoolkit.js | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/index.html b/index.html index fb26eff7..587b5b2e 100644 --- a/index.html +++ b/index.html @@ -791,6 +791,11 @@

    Transaction Script

    Continue to Sign + Or +
    diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 539eb2ae..29687852 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -210,6 +210,10 @@ $(document).ready(function() { $("#signTransaction").val(decode.serialize()).fadeOut().fadeIn(); window.location.hash = "#sign"; }); + $("#verifyTransactionData .verifyToBroadcast").on( "click", function() { + $("#broadcast #rawTransaction").val(decode.serialize()).fadeOut().fadeIn(); + window.location.hash = "#broadcast"; + }); $("#verifyTransactionData").removeClass("hidden"); $("#verifyTransactionData tbody").html(""); From 074c6bc2ae88089c0fd8381bedbe664314181aef Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Thu, 21 Jan 2016 18:57:27 +0100 Subject: [PATCH 58/92] Improved broadcast feedback --- index.html | 5 ++++- js/cointoolkit.js | 28 +++++++++++++++------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/index.html b/index.html index 587b5b2e..adb071d7 100644 --- a/index.html +++ b/index.html @@ -991,7 +991,10 @@

    Broadcast Transaction into the network


    - +
    diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 29687852..7561ff26 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -744,18 +744,19 @@ $(document).ready(function() { } }, broadcast: { - "blockr.io": function(thisbtn){ - $(thisbtn).val('Please wait, loading... ').attr('disabled',true); + "blockr.io": function(thisbtn){ + var orig_html = $(thisbtn).html(); + $(thisbtn).html('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", url: "//btc.blockr.io/api/v1/tx/push", data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { - var r = ' '; + var r = ''; r += (data.data) ? data.data : ''; r += (data.message) ? ' '+data.message : ''; - r = (r!='') ? r : ' Failed to broadcast'; // build response + r = (r!='') ? r : ' Failed to broadcast. Internal server error'; $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, success: function(data) { @@ -767,13 +768,13 @@ $(document).ready(function() { }, complete: function(data, status) { $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).val('Submit').attr('disabled',false); + $(thisbtn).html(orig_html).attr('disabled',false); } }); }, - "coinb.in": function(btn){ - var thisbtn = btn; - $(thisbtn).val('Please wait, loading... ').attr('disabled',true); + "coinb.in": function(thisbtn){ + var orig_html = $(thisbtn).html(); + $(thisbtn).html('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "G", url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction', @@ -793,7 +794,7 @@ $(document).ready(function() { }, complete: function(data, status) { $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).val('Submit').attr('disabled',false); + $(thisbtn).html(orig_html).attr('disabled',false); } }); } @@ -852,17 +853,18 @@ $(document).ready(function() { }, broadcast: { "blockr.io": function(thisbtn){ - $(thisbtn).val('Please wait, loading... ').attr('disabled',true); + var orig_html = $(thisbtn).html(); + $(thisbtn).html('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", url: "//ltc.blockr.io/api/v1/tx/push", data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { - var r = ' '; + var r = ''; r += (data.data) ? data.data : ''; r += (data.message) ? ' '+data.message : ''; - r = (r!='') ? r : ' Failed to broadcast'; // build response + r = (r!='') ? r : ' Failed to broadcast. Internal server error'; $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, success: function(data) { @@ -875,7 +877,7 @@ $(document).ready(function() { }, complete: function(data, status) { $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).val('Submit').attr('disabled',false); + $(thisbtn).hmtl(orig_html).attr('disabled',false); } }); } From 1c72eb7feb3b53e9238d82b1de5b43986c25bb21 Mon Sep 17 00:00:00 2001 From: mh001 Date: Tue, 26 Jan 2016 00:33:36 +0800 Subject: [PATCH 59/92] replace btc key https://discuss.nubits.com/t/flot-operations-buy-side-btc-related/3117/167 --- known-pubkeys.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index 24816889..ec48b9be 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -79,6 +79,12 @@ }, "mhps": { "03a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a7622521": { + deprecated: true, //https://discuss.nubits.com/t/flot-operations-buy-side-btc-related/3117/168 + member: [ + memberOf.Nu.FLOT_BTC // https://discuss.nubits.com/t/via-quote/3098/14 + ] + }, + "0326c19862fb329470c828ace6749b64c50b4d9a8da60d60e4e32ebe96b388b2ae": { member: [ memberOf.Nu.FLOT_BTC // https://discuss.nubits.com/t/via-quote/3098/14 ] @@ -143,4 +149,4 @@ window['known'] = known; })(); -console.log("Loaded known identities", known); \ No newline at end of file +console.log("Loaded known identities", known); From 9c2f0aeded518a6da687ed46d44c1c5ee5f881db Mon Sep 17 00:00:00 2001 From: mh001 Date: Tue, 26 Jan 2016 08:22:41 +0800 Subject: [PATCH 60/92] add space before comment URL See pull request comments. --- known-pubkeys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index ec48b9be..30449745 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -79,7 +79,7 @@ }, "mhps": { "03a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a7622521": { - deprecated: true, //https://discuss.nubits.com/t/flot-operations-buy-side-btc-related/3117/168 + deprecated: true, // https://discuss.nubits.com/t/flot-operations-buy-side-btc-related/3117/168 member: [ memberOf.Nu.FLOT_BTC // https://discuss.nubits.com/t/via-quote/3098/14 ] From ae183d53b58943ead662b2e599a26a161a401d96 Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Wed, 3 Feb 2016 22:23:59 +0100 Subject: [PATCH 61/92] Added new FLOT BTC address https://discuss.nubits.com/t/flot-operations-buy-side-btc-related/3117/177 --- known-pubkeys.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/known-pubkeys.js b/known-pubkeys.js index 30449745..f2591582 100644 --- a/known-pubkeys.js +++ b/known-pubkeys.js @@ -16,8 +16,9 @@ }, scriptHash: { // Nu FLOT addresses scripthash. // Commented with redeemScript. - "f716edbaa472c1470d36a3e78b17a4c9bb547fcf": {name:"Nu FLOT BTC group 1st address"}, // 55210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b2102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f210312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f21034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a76225212103da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb58ae - + "f716edbaa472c1470d36a3e78b17a4c9bb547fcf": {name:"Nu FLOT BTC group 1st address", deprecated:true}, // 55210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b2102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f210312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f21034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103a5fc09a5de595e4758bfbc3a932e2c448cc49a557dd6e64788cee530a76225212103da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb58ae + "afd5c3c6fb0c40799f0a874396df7bfce2bc29a3": {name:"Nu FLOT BTC group 2nd address"}, // 55210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102435b894b94b4b27dd24436b3f9ad0b9409d855ab4be6e91141d445804e84750b2102e2fcdfe246e9cd4864d9119b8af465487385eccd0ea30a8cb21d44d36818189f210312cd6eb361c9ebb0d90e44946492a237eab4c7a7d88a0db800f2f460937cc22f210326c19862fb329470c828ace6749b64c50b4d9a8da60d60e4e32ebe96b388b2ae21034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103da8082062298c40f0b473b74f3c95b57eaaebe3e67ed30ce56347b2e727915fb58ae + "f35b24f264597d66ba8c366a5005824bb6a06138": {name:"Nu FLOT NBT group 1st address"}, // 5321034b0bd0f653d4ac0a2e9e81eb1863bb8e5743f6cb1ea40d845b939c225a1a80ff2102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102547427fc2ea3a0ab9ef70f5e1640ff5112b113f65696948f992bd0770b94257155ae "d4f1e97d23cf339c35b509de707acdcb9886e03b": {name:"Nu FLOT NSR group provisional address", deprecated:true}, // 53210234139729dd413c84a71a0bfd6f236790be861b37311cef3240277c940e4b0c072102a144af74d018501f03d76ead130433335f969772792ec39ce389c8a2341552592103661a4370dfcfbcea25d1800057220f4572b6eecab95bb0670e8676a9e34451dc2103686ee42f635c71c08f326e66139b6cb37167402cc0562584655aac03fe74049521039854d0e2abf6e4971e1350137b876da6a05132737c11ca3e37aaed2a0eb6680855ae From c9497a8d0c889f5353326360111a6472de1bc178 Mon Sep 17 00:00:00 2001 From: ttutdxh-nubits Date: Sat, 6 Feb 2016 04:19:27 +0100 Subject: [PATCH 62/92] Fix window.location.protocol issues in Firefox --- js/cointoolkit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 7561ff26..f2040e33 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1,7 +1,7 @@ $(document).ready(function() { if(window.location.hostname == "ttutdxh-nubits.github.io" && window.location.protocol != 'https:') { - window.location.protocol = "https:"; + window.location.href = "https:" + window.location.href.substring(window.location.protocol.length); } var toolkit = {}; From b5ce0b25fecfe9476924c79f382a9a223584c654 Mon Sep 17 00:00:00 2001 From: ttutdxh Date: Wed, 17 Feb 2016 02:17:28 +0100 Subject: [PATCH 63/92] Added broadcast provider for NBT, NSR, BKC, BKS and listunspent and getinputamount for BKC and BKS --- js/cointoolkit.js | 169 +++++++++++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 55 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index f2040e33..6541e0f7 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -579,62 +579,97 @@ $(document).ready(function() { } /* external providers */ - - var listunspent_blockexplorer_nu = function(redeem){ - var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' - var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is https://blockexplorer.nu/ down?'; - $.ajax ({ - type: "GET", - url: "//crossorigin.me/https://blockexplorer.nu/api/v1/addressUnspent/"+redeem.addr, - dataType: "json", - error: function(data) { - $("#redeemFromStatus").removeClass('hidden').html(msgError); - $("#redeemFromBtn").html("Load").attr('disabled',false); - }, - success: function(data) { - if (coinjs.debug) {console.log(data)}; - if (data.length == 0) { - $("#redeemFromStatus").removeClass('hidden').html(msgError); - $("#redeemFromBtn").html("Load").attr('disabled',false); - } else { - for(var i=0;i'+redeem.addr+'' + var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is ' + endpoint + '/ down?'; + $.ajax ({ + type: "GET", + url: 'https://crossorigin.me/' + endpoint + '/api/v1/addressUnspent/' + redeem.addr, + dataType: "json", + error: function(data) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.length == 0) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); } else { - var script = data[i].outScript; - script = script.replace('OP_DUP OP_HASH160 ', '76a914'); - script = script.replace(' OP_EQUALVERIFY OP_CHECKSIG', '88ac'); + for(var i=0;i').attr('disabled',true); + $.ajax ({ + type: "POST", + url: endpoint + "/api/sendrawtx", + data: {"hex":$("#rawTransaction").val()}, + dataType: "json", + error: function(data) { + var r = ''; + r += (data.data) ? data.data : ''; + r += (data.message) ? ' '+data.message : ''; + r = (r!='') ? r : ' Failed to broadcast. Internal server error'; + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); + }, + success: function(data) { + if((data.status && data.data) && data.status=='success'){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).html(orig_html).attr('disabled',false); + } + }); + } + } }; var gitmultisig_listunspent = function(redeem, github_repository) { @@ -885,7 +920,7 @@ $(document).ready(function() { }, nubits: { listUnspent: { - "blockexplorer.nu": listunspent_blockexplorer_nu, + "blockexplorer.nu": nuBasedExplorer.listUnspent('https://blockexplorer.nu'), "FLOT @dysconnect git-multisig repository": function(redeem) { gitmultisig_listunspent(redeem, "dc-tcs/flot-operations"); }, @@ -897,19 +932,43 @@ $(document).ready(function() { }, }, broadcast: { + "blockexplorer.nu": nuBasedExplorer.broadcast('https://blockexplorer.nu') }, getInputAmount: { - "blockexplorer.nu": getinputamount_blockexplorer_nu + "blockexplorer.nu": nuBasedExplorer.getInputAmount('https://blockexplorer.nu') } }, nushares: { listUnspent: { - "blockexplorer.nu": listunspent_blockexplorer_nu + "blockexplorer.nu": nuBasedExplorer.listUnspent('https://blockexplorer.nu') + }, + broadcast: { + "blockexplorer.nu": nuBasedExplorer.broadcast('https://blockexplorer.nu') + }, + getInputAmount: { + "blockexplorer.nu": nuBasedExplorer.getInputAmount('https://blockexplorer.nu') + } + }, + blockcredits: { + listUnspent: { + "bcblockexplorer.com": nuBasedExplorer.listUnspent('https://bcblockexplorer.com') + }, + broadcast: { + "bcblockexplorer.com": nuBasedExplorer.broadcast('https://bcblockexplorer.com') + }, + getInputAmount: { + "bcblockexplorer.com": nuBasedExplorer.getInputAmount('https://bcblockexplorer.com') + } + }, + blockshares: { + listUnspent: { + "bcblockexplorer.com": nuBasedExplorer.listUnspent('https://bcblockexplorer.com') }, broadcast: { + "bcblockexplorer.com": nuBasedExplorer.broadcast('https://bcblockexplorer.com') }, getInputAmount: { - "blockexplorer.nu": getinputamount_blockexplorer_nu + "bcblockexplorer.com": nuBasedExplorer.getInputAmount('https://bcblockexplorer.com') } } } From 7fe3f9b4971a8111d100a466e99ab98745150631 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sat, 20 Feb 2016 21:30:51 -0200 Subject: [PATCH 64/92] include DASH Add DASH --- index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/index.html b/index.html index adb071d7..d2a2e324 100644 --- a/index.html +++ b/index.html @@ -1028,6 +1028,7 @@

    Settings

    Select which network you'd like to use for key pair generation.

    - + From 856082c9fbbeea55884c4f8d2702f928e865c2b3 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 21 Feb 2016 00:17:02 -0300 Subject: [PATCH 66/92] fix added DASH fix DASH --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 42a72cb0..95d05fc5 100644 --- a/index.html +++ b/index.html @@ -1028,7 +1028,7 @@

    Settings

    Select which network you'd like to use for key pair generation.

    '; html += ''; html += ''; + html += ''; html += ''; html += ''; } From c6b01e45a18a04c35234ff379d96cd178d0290ae Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 21 Feb 2016 17:51:39 -0300 Subject: [PATCH 68/92] HD address update added more info on HD address --- index.html | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 95d05fc5..906bc523 100644 --- a/index.html +++ b/index.html @@ -837,16 +837,29 @@

    HD Address

    -
    +
    Chain Code
    -
    - Key
    +
    + Private Key (WIF)
    +
    + Extended xPub
    + +
    + +
    + Address
    + +
    +
    + Public key (hex)
    + +
    @@ -907,7 +920,7 @@

    Keys

    - + From e971eb45a2e4edfa926f933a95cfd592d46804e0 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 21 Feb 2016 18:43:32 -0300 Subject: [PATCH 69/92] bug dash fix transaction offline dash bug fix --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 906bc523..d6bed7e3 100644 --- a/index.html +++ b/index.html @@ -1041,7 +1041,7 @@

    Settings

    Select which network you'd like to use for key pair generation.

    '; h += ''; h += ''; - //h += ''; - h += ''; + //h += ''; h += ''; h += ''; - h += ''; + h += ''; + //h += ''; h += ''; } }); From cd2783547cd83f9e606b41304e59fa38f882e20f Mon Sep 17 00:00:00 2001 From: triplexfw Date: Tue, 23 Feb 2016 20:20:12 -0300 Subject: [PATCH 71/92] HD address dash update update HD address to dash drkv HD public address drkp HD private address --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index d6bed7e3..2ce89815 100644 --- a/index.html +++ b/index.html @@ -1041,7 +1041,7 @@

    Settings

    Select which network you'd like to use for key pair generation.

    - - - - - + + + + - - - + - - @@ -1171,7 +1166,7 @@

    Settings


    -

    This page uses javascript to generate your addresses and sign your transactions within your browser, this means we never receive your private keys, this can be independently verified by reviewing the source code on github. You can even download this page and host it yourself or run it offline!

    +

    This page uses javascript to generate your addresses and sign your transactions within your browser, this means we never receive your private keys, this can be independently verified by reviewing the source code on github. You can even download this page and host it yourself or run it offline!


    From c36a3c5769c5f8f532669dcbc33a40859c147773 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 27 Mar 2016 21:08:12 -0300 Subject: [PATCH 75/92] Update cointoolkit.js --- js/cointoolkit.js | 134 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 119 insertions(+), 15 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index ce2ad585..96c17787 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -588,7 +588,7 @@ $(document).ready(function() { var nuBasedExplorer = { listUnspent: function(endpoint) { return function(redeem){ - var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' + var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is ' + endpoint + '/ down?'; $.ajax ({ type: "GET", @@ -604,7 +604,7 @@ $(document).ready(function() { $("#redeemFromStatus").removeClass('hidden').html(msgError); $("#redeemFromBtn").html("Load").attr('disabled',false); } else { - for(var i=0;i').attr('disabled',true); $.ajax ({ type: "POST", - url: endpoint + "/api/sendrawtx", - data: {"hex":$("#rawTransaction").val()}, + url: endpoint + "/api/v1/sendrawtx", + data: { + "rawTx": $("#rawTransaction").val(), + "checkInputs": 1 + }, dataType: "json", error: function(data) { + data = $.parseJSON(data.responseText); var r = ''; r += (data.data) ? data.data : ''; - r += (data.message) ? ' '+data.message : ''; + r += (data.status) ? ' '+data.status : ''; r = (r!='') ? r : ' Failed to broadcast. Internal server error'; $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, success: function(data) { - if((data.status && data.data) && data.status=='success'){ + data = $.parseJSON(data.responseText); + if(data.success==true){ $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); } else { - $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); - } + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Error'+data.status).prepend(''); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).html(orig_html).attr('disabled',false); + } + }); + } + } + }; + + var bcBasedExplorer = { + listUnspent: function(endpoint) { + return function(redeem){ + var msgSucess = ' Retrieved unspent inputs from address '+redeem.addr+'' + var msgError = ' Unexpected error, unable to retrieve unspent outputs! Is ' + endpoint + '/ down?'; + var msgError = ' According to ' + endpoint + '/ unspent balance for '+redeem.addr+' is 0'; + $.ajax ({ + type: "GET", + url: endpoint + '/api/v1/unspent/' + redeem.addr, + dataType: "json", + error: function(data) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.txs.length == 0) { + $("#redeemFromStatus").removeClass('hidden').html(msgError); + $("#redeemFromBtn").html("Load").attr('disabled',false); + } else { + for(var i=0;i').attr('disabled',true); + $.ajax ({ + type: "POST", + url: endpoint + "/api/v1/sendrawtx", + data: { + "rawTx": $("#rawTransaction").val(), + "checkInputs": 1 + }, + dataType: "json", + error: function(data) { + data = $.parseJSON(data.responseText); + var r = ''; + r += (data.data) ? data.data : ''; + r += (data.status) ? ' '+data.status : ''; + r = (r!='') ? r : ' Failed to broadcast. Internal server error'; + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); + }, + success: function(data) { + data = $.parseJSON(data.responseText); + if(data.success==true){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Error'+data.status).prepend(''); + } }, complete: function(data, status) { $("#rawTransactionStatus").fadeOut().fadeIn(); - $(thisbtn).html(orig_html).attr('disabled',false); + $(thisbtn).html(orig_html).attr('disabled',false); } }); } @@ -721,12 +825,12 @@ $(document).ready(function() { coinjs.key = '12345678901234567890123456789012'; var providers = { - bitcoin: { + bitcoin: { listUnspent: { "blockr.io": function(redeem){ $.ajax ({ type: "GET", - url: "//btc.blockr.io/api/v1/address/unspent/"+redeem.addr+"?unconfirmed=1", + url: "https://btc.blockr.io/api/v1/address/unspent/"+redeem.addr+"?unconfirmed=1", dataType: "json", error: function(data) { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); @@ -789,7 +893,7 @@ $(document).ready(function() { $(thisbtn).html('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", - url: "//btc.blockr.io/api/v1/tx/push", + url: "https://btc.blockr.io/api/v1/tx/push", data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { @@ -865,7 +969,7 @@ $(document).ready(function() { "chain.so": function(redeem){ $.ajax ({ type: "GET", - url: "//chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, + url: "https://chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, dataType: "json", error: function(data) { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); @@ -897,7 +1001,7 @@ $(document).ready(function() { $(thisbtn).html('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", - url: "//ltc.blockr.io/api/v1/tx/push", + url: "https://ltc.blockr.io/api/v1/tx/push", data: {"hex":$("#rawTransaction").val()}, dataType: "json", error: function(data) { From 08eb8b88f3f9713a009667ae29a1668484f16866 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 27 Mar 2016 21:09:29 -0300 Subject: [PATCH 76/92] update getinfo --- index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 8ecc39fd..eae4283a 100644 --- a/index.html +++ b/index.html @@ -1042,9 +1042,9 @@

    Settings

    - + - + From 88df77819692171e900fbf0117df5ea8812685a0 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Mon, 27 Jun 2016 18:27:55 -0300 Subject: [PATCH 82/92] update transaction DASH --- js/cointoolkit.js | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index a8b1bf1a..6d94280d 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1115,6 +1115,94 @@ $(document).ready(function() { } } }, + DASH: { + listUnspent: { + "insight.dash": function(redeem){ + $.ajax ({ + type: "GET", + url: "http://insight.dash.siampm.com/api/addr/"+redeem.addr+"/utxo", + dataType: "json", + error: function(data) { + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); + }, + success: function(data) { + if (coinjs.debug) {console.log(data)}; + if(data){ + $("#redeemFromAddress").removeClass('hidden').html(' Retrieved unspent inputs from address '+redeem.addr+''); + for(var i in data){ + var o = data[i]; + var script = (redeem.isMultisig==true) ? $("#redeemFrom").val() : o.scriptPubKey; + + addOutput(o.txid, o.vout, script, o.amount); + } + } else { + $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs.'); + } + }, + complete: function(data, status) { + $("#redeemFromBtn").html("Load").attr('disabled',false); + totalInputAmount(); + } + }); + } + }, + broadcast: { + "blockr.io": function(thisbtn){ + var orig_html = $(thisbtn).html(); + $(thisbtn).html('Please wait, loading... ').attr('disabled',true); + $.ajax ({ + type: "POST", + url: "https://btc.blockr.io/api/v1/tx/push", + data: {"hex":$("#rawTransaction").val()}, + dataType: "json", + error: function(data) { + var r = ''; + r += (data.data) ? data.data : ''; + r += (data.message) ? ' '+data.message : ''; + r = (r!='') ? r : ' Failed to broadcast. Internal server error'; + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); + }, + success: function(data) { + if((data.status && data.data) && data.status=='success'){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).html(orig_html).attr('disabled',false); + } + }); + }, + "coinb.in": function(thisbtn){ + var orig_html = $(thisbtn).html(); + $(thisbtn).html('Please wait, loading... ').attr('disabled',true); + $.ajax ({ + type: "G", + url: coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=sendrawtransaction', + data: {'rawtx':$("#rawTransaction").val()}, + dataType: "xml", + error: function(data) { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(" There was an error submitting your request, please try again").prepend(''); + }, + success: function(data) { + $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); + if($(data).find("result").text()==1){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); + $("#rawTransactionStatus").html('txid: '+$(data).find("txid").text()); + } else { + $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend(' '); + } + }, + complete: function(data, status) { + $("#rawTransactionStatus").fadeOut().fadeIn(); + $(thisbtn).html(orig_html).attr('disabled',false); + } + }); + } + } + }, nubits: { listUnspent: { "blockexplorer.nu": nuBasedExplorer.listUnspent('https://blockexplorer.nu'), From 2fdbb2f9c3c9693273b0a32611db1723095e7b04 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 23 Oct 2016 09:18:50 -0200 Subject: [PATCH 83/92] dash fix get info, upgrade dogecoin(1) --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 54d49ed8..6cefb6ec 100644 --- a/index.html +++ b/index.html @@ -1043,7 +1043,7 @@

    Settings

    - + From 440bde4fba015e74de7ad5ab1e4840b7a4a3b2df Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 23 Oct 2016 09:21:05 -0200 Subject: [PATCH 84/92] dash fix get info, upgrade dogecoin(1) --- js/cointoolkit.js | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 6d94280d..3467a149 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1059,13 +1059,13 @@ $(document).ready(function() { } }, broadcast: { - "blockr.io": function(thisbtn){ + "blockcypher": function(thisbtn){ var orig_html = $(thisbtn).html(); $(thisbtn).html('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", - url: "https://btc.blockr.io/api/v1/tx/push", - data: {"hex":$("#rawTransaction").val()}, + url: "https://api.blockcypher.com/v1/doge/main/txs/push", + data: {"tx":$("#rawTransaction").val()}, dataType: "json", error: function(data) { var r = ''; @@ -1075,8 +1075,8 @@ $(document).ready(function() { $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, success: function(data) { - if((data.status && data.data) && data.status=='success'){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data); + if((data.status && data.data) && data.status=='1'){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data.tx); } else { $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); } @@ -1113,14 +1113,34 @@ $(document).ready(function() { } }); } + }, + getInputAmount: { + "blockcypher": function(txid, index, callback) { + $.ajax ({ + type: "GET", + url: "https://api.blockcypher.com/v1/doge/main/txs/"+txid, + dataType: "json", + error: function(data) { + callback(false); + }, + sucess: function(data) { + if (coinjs.debug) {console.log(data)}; + if (data.outputs[index]){ + callback(parseInt(data.outputs[index].value*("1e"+coinjs.decimalPlaces), 10)); + } else { + callback(false); + } + } + }); + } } - }, + }, DASH: { listUnspent: { "insight.dash": function(redeem){ $.ajax ({ type: "GET", - url: "http://insight.dash.siampm.com/api/addr/"+redeem.addr+"/utxo", + url: "https://insight.dash.siampm.com/api/addr/"+redeem.addr+"/utxo", dataType: "json", error: function(data) { $("#redeemFromStatus").removeClass('hidden').html(' Unexpected error, unable to retrieve unspent outputs!'); From 01546b6f23ac58911d13b4eeb0a2899be8ea2153 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Mon, 24 Oct 2016 13:11:48 -0200 Subject: [PATCH 85/92] doge upgrade --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 6cefb6ec..e9482a00 100644 --- a/index.html +++ b/index.html @@ -1405,4 +1405,4 @@ - + \ No newline at end of file From 02e83f930fba0d46214ea8981410a5431ea7bb89 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Mon, 24 Oct 2016 13:12:54 -0200 Subject: [PATCH 86/92] doge upgrade --- js/cointoolkit.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 3467a149..98e23a70 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1065,7 +1065,7 @@ $(document).ready(function() { $.ajax ({ type: "POST", url: "https://api.blockcypher.com/v1/doge/main/txs/push", - data: {"tx":$("#rawTransaction").val()}, + data: JSON.stringify({"tx":$("#rawTransaction").val()}), dataType: "json", error: function(data) { var r = ''; @@ -1075,8 +1075,8 @@ $(document).ready(function() { $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend(''); }, success: function(data) { - if((data.status && data.data) && data.status=='1'){ - $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data.tx); + if(data.tx.hash){ + $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.tx.hash); } else { $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend(''); } @@ -1120,13 +1120,13 @@ $(document).ready(function() { type: "GET", url: "https://api.blockcypher.com/v1/doge/main/txs/"+txid, dataType: "json", - error: function(data) { + error: function(data) { callback(false); }, - sucess: function(data) { + success: function(data) { if (coinjs.debug) {console.log(data)}; - if (data.outputs[index]){ - callback(parseInt(data.outputs[index].value*("1e"+coinjs.decimalPlaces), 10)); + if (data.outputs[index]){ + callback(data.outputs[index].value); //callback(parseInt(data.outputs[index].value*("1e"+coinjs.decimalPlaces), 10)); } else { callback(false); } From ce59f205faf1700686d176053d2c34d6690cd07b Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 1 Jan 2017 09:49:26 -0300 Subject: [PATCH 87/92] Update cointoolkit.js --- js/cointoolkit.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 98e23a70..e9c33ceb 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1167,13 +1167,13 @@ $(document).ready(function() { } }, broadcast: { - "blockr.io": function(thisbtn){ + "insight.dash": function(thisbtn){ var orig_html = $(thisbtn).html(); $(thisbtn).html('Please wait, loading... ').attr('disabled',true); $.ajax ({ type: "POST", - url: "https://btc.blockr.io/api/v1/tx/push", - data: {"hex":$("#rawTransaction").val()}, + url: "https://insight.dash.siampm.com/api/tx/send", + data: {'rawtx':$("#rawTransaction").val()}, dataType: "json", error: function(data) { var r = ''; From 8a60b67e4c717ff749e64457af599a9c821b75e8 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Sun, 1 Jan 2017 10:00:15 -0300 Subject: [PATCH 88/92] DASH Broadcast FIX DASH Broadcast ADD --- index.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index e9482a00..e77f3c14 100644 --- a/index.html +++ b/index.html @@ -1041,7 +1041,8 @@

    Settings

    Select which network you'd like to use for key pair generation.

    From c344e145d01b947d2442c3196e5aefb586773fc6 Mon Sep 17 00:00:00 2001 From: triplexfw Date: Fri, 12 Oct 2018 16:57:22 -0300 Subject: [PATCH 92/92] privatekey hex to signature add privatekey hex to signature transaction --- js/cointoolkit.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/js/cointoolkit.js b/js/cointoolkit.js index 3a5f2cf3..681aa4ae 100644 --- a/js/cointoolkit.js +++ b/js/cointoolkit.js @@ -1821,7 +1821,7 @@ $(document).ready(function() { }); $("#recipients .addressAddTo").click(function(){ - if($("#recipients .addressRemoveTo").length<19){ + if($("#recipients .addressRemoveTo").length<100){ var clone = '

    '+$(this).parent().parent().html()+'
    '; $("#recipients").append(clone); $("#recipients .glyphicon-plus:last").removeClass('glyphicon-plus').addClass('glyphicon-minus'); @@ -2054,6 +2054,11 @@ $(document).ready(function() { $("#signBtn").click(function(){ var wifkey = $("#signPrivateKey"); + if((wifkey.val()).match(/^[a-f0-9]+$/ig)){ + coinjs.compressed = true; + var coint = coinjs.newKeys(wifkey.val(), true); + wifkey.val(coint.wif) + } var script = $("#signTransaction"); if(coinjs.addressDecode(wifkey.val())){
    IndexAddressPrivate Key (WIF)Extended xPubExtended xPrv
    IndexAddressPrivate Key (WIF)Extended xPubPublic key (hex)Extended xPrv
    '+o.outpoint.index+'Advanced'; + h += 'AdvancedAdvanced'; h += ''; h += ''; if(s['type']=='multisig' && s['signatures']>=1){ @@ -328,7 +328,8 @@ $(document).ready(function() { h += ''+coinjs.formatAmount(o.value)+'AdvancedAdvancedAdvanced