aboutsummaryrefslogtreecommitdiff
path: root/src/js/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/index.js')
-rw-r--r--src/js/index.js213
1 files changed, 191 insertions, 22 deletions
diff --git a/src/js/index.js b/src/js/index.js
index 0ecb735..9807449 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -15,6 +15,7 @@
15 var showPrivKey = true; 15 var showPrivKey = true;
16 var showQr = false; 16 var showQr = false;
17 var litecoinUseLtub = true; 17 var litecoinUseLtub = true;
18 var isDefaultBip44ChangeValue = true;
18 19
19 var entropyChangeTimeoutEvent = null; 20 var entropyChangeTimeoutEvent = null;
20 var phraseChangeTimeoutEvent = null; 21 var phraseChangeTimeoutEvent = null;
@@ -44,6 +45,8 @@
44 DOM.entropyWeakEntropyOverrideWarning = DOM.entropyContainer.find(".weak-entropy-override-warning"); 45 DOM.entropyWeakEntropyOverrideWarning = DOM.entropyContainer.find(".weak-entropy-override-warning");
45 DOM.entropyFilterWarning = DOM.entropyContainer.find(".filter-warning"); 46 DOM.entropyFilterWarning = DOM.entropyContainer.find(".filter-warning");
46 DOM.phrase = $(".phrase"); 47 DOM.phrase = $(".phrase");
48 DOM.splitPhrase = $(".phraseSplit");
49 DOM.phraseSplitWarn = $(".phraseSplitWarn");
47 DOM.passphrase = $(".passphrase"); 50 DOM.passphrase = $(".passphrase");
48 DOM.generateContainer = $(".generate-container"); 51 DOM.generateContainer = $(".generate-container");
49 DOM.generate = $(".generate"); 52 DOM.generate = $(".generate");
@@ -69,6 +72,7 @@
69 DOM.bip44accountXprv = $("#bip44 .account-xprv"); 72 DOM.bip44accountXprv = $("#bip44 .account-xprv");
70 DOM.bip44accountXpub = $("#bip44 .account-xpub"); 73 DOM.bip44accountXpub = $("#bip44 .account-xpub");
71 DOM.bip44change = $("#bip44 .change"); 74 DOM.bip44change = $("#bip44 .change");
75 DOM.defaultBip44ChangeValue = $("#bip44 .default-bip44-change-value");
72 DOM.bip49unavailable = $("#bip49 .unavailable"); 76 DOM.bip49unavailable = $("#bip49 .unavailable");
73 DOM.bip49available = $("#bip49 .available"); 77 DOM.bip49available = $("#bip49 .available");
74 DOM.bip49path = $("#bip49-path"); 78 DOM.bip49path = $("#bip49-path");
@@ -134,7 +138,9 @@
134 DOM.litecoinUseLtub.on("change", litecoinUseLtubChanged); 138 DOM.litecoinUseLtub.on("change", litecoinUseLtubChanged);
135 DOM.bip32path.on("input", calcForDerivationPath); 139 DOM.bip32path.on("input", calcForDerivationPath);
136 DOM.bip44account.on("input", calcForDerivationPath); 140 DOM.bip44account.on("input", calcForDerivationPath);
141 DOM.bip44change.on("input", modifiedDefaultBip44ChangeValue);
137 DOM.bip44change.on("input", calcForDerivationPath); 142 DOM.bip44change.on("input", calcForDerivationPath);
143 DOM.defaultBip44ChangeValue.on("click", resetDefaultBip44ChangeValue);
138 DOM.bip49account.on("input", calcForDerivationPath); 144 DOM.bip49account.on("input", calcForDerivationPath);
139 DOM.bip49change.on("input", calcForDerivationPath); 145 DOM.bip49change.on("input", calcForDerivationPath);
140 DOM.bip84account.on("input", calcForDerivationPath); 146 DOM.bip84account.on("input", calcForDerivationPath);
@@ -232,7 +238,14 @@
232 if (phraseChangeTimeoutEvent != null) { 238 if (phraseChangeTimeoutEvent != null) {
233 clearTimeout(phraseChangeTimeoutEvent); 239 clearTimeout(phraseChangeTimeoutEvent);
234 } 240 }
235 phraseChangeTimeoutEvent = setTimeout(phraseChanged, 400); 241 phraseChangeTimeoutEvent = setTimeout(function() {
242 phraseChanged();
243 var entropy = mnemonic.toRawEntropyHex(DOM.phrase.val());
244 if (entropy !== null) {
245 DOM.entropyMnemonicLength.val("raw");
246 DOM.entropy.val(entropy);
247 }
248 }, 400);
236 } 249 }
237 250
238 function phraseChanged() { 251 function phraseChanged() {
@@ -297,6 +310,7 @@
297 clearDisplay(); 310 clearDisplay();
298 clearEntropyFeedback(); 311 clearEntropyFeedback();
299 DOM.phrase.val(""); 312 DOM.phrase.val("");
313 DOM.phraseSplit.val("");
300 showValidationError("Blank entropy"); 314 showValidationError("Blank entropy");
301 return; 315 return;
302 } 316 }
@@ -331,6 +345,7 @@
331 showPending(); 345 showPending();
332 // Clear existing mnemonic and passphrase 346 // Clear existing mnemonic and passphrase
333 DOM.phrase.val(""); 347 DOM.phrase.val("");
348 DOM.phraseSplit.val("");
334 DOM.passphrase.val(""); 349 DOM.passphrase.val("");
335 seed = null; 350 seed = null;
336 if (rootKeyChangedTimeoutEvent != null) { 351 if (rootKeyChangedTimeoutEvent != null) {
@@ -417,6 +432,7 @@
417 if (DOM.phrase.val().length > 0) { 432 if (DOM.phrase.val().length > 0) {
418 var newPhrase = convertPhraseToNewLanguage(); 433 var newPhrase = convertPhraseToNewLanguage();
419 DOM.phrase.val(newPhrase); 434 DOM.phrase.val(newPhrase);
435 writeSplitPhrase(newPhrase);
420 phraseChanged(); 436 phraseChanged();
421 } 437 }
422 else { 438 else {
@@ -477,6 +493,7 @@
477 // show the words 493 // show the words
478 var words = mnemonic.toMnemonic(data); 494 var words = mnemonic.toMnemonic(data);
479 DOM.phrase.val(words); 495 DOM.phrase.val(words);
496 writeSplitPhrase(words);
480 // show the entropy 497 // show the entropy
481 var entropyHex = uint8ArrayToHex(data); 498 var entropyHex = uint8ArrayToHex(data);
482 DOM.entropy.val(entropyHex); 499 DOM.entropy.val(entropyHex);
@@ -594,7 +611,7 @@
594 extendedKey = extendedKey.derive(index); 611 extendedKey = extendedKey.derive(index);
595 } 612 }
596 } 613 }
597 return extendedKey 614 return extendedKey;
598 } 615 }
599 616
600 function showValidationError(errorText) { 617 function showValidationError(errorText) {
@@ -726,12 +743,14 @@
726 var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44); 743 var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44);
727 var coin = parseIntNoNaN(DOM.bip44coin.val(), 0); 744 var coin = parseIntNoNaN(DOM.bip44coin.val(), 0);
728 var account = parseIntNoNaN(DOM.bip44account.val(), 0); 745 var account = parseIntNoNaN(DOM.bip44account.val(), 0);
729 var change = parseIntNoNaN(DOM.bip44change.val(), 0); 746 var change = parseIntNoNaN(DOM.bip44change.val(), "");
730 var path = "m/"; 747 var path = "m";
731 path += purpose + "'/"; 748 path += "/" + purpose + "'";
732 path += coin + "'/"; 749 path += "/" + coin + "'";
733 path += account + "'/"; 750 path += "/" + account + "'";
734 path += change; 751 if (change !== "") {
752 path += "/" + change;
753 }
735 DOM.bip44path.val(path); 754 DOM.bip44path.val(path);
736 var derivationPath = DOM.bip44path.val(); 755 var derivationPath = DOM.bip44path.val();
737 console.log("Using derivation path from BIP44 tab: " + derivationPath); 756 console.log("Using derivation path from BIP44 tab: " + derivationPath);
@@ -835,6 +854,10 @@
835 return networks[DOM.network.val()].name == "GRS - Groestlcoin" || networks[DOM.network.val()].name == "GRS - Groestlcoin Testnet"; 854 return networks[DOM.network.val()].name == "GRS - Groestlcoin" || networks[DOM.network.val()].name == "GRS - Groestlcoin Testnet";
836 } 855 }
837 856
857 function isELA() {
858 return networks[DOM.network.val()].name == "ELA - Elastos"
859 }
860
838 function displayBip44Info() { 861 function displayBip44Info() {
839 // Get the derivation path for the account 862 // Get the derivation path for the account
840 var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44); 863 var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44);
@@ -848,9 +871,14 @@
848 var accountExtendedKey = calcBip32ExtendedKey(path); 871 var accountExtendedKey = calcBip32ExtendedKey(path);
849 var accountXprv = accountExtendedKey.toBase58(); 872 var accountXprv = accountExtendedKey.toBase58();
850 var accountXpub = accountExtendedKey.neutered().toBase58(); 873 var accountXpub = accountExtendedKey.neutered().toBase58();
874
851 // Display the extended keys 875 // Display the extended keys
852 DOM.bip44accountXprv.val(accountXprv); 876 DOM.bip44accountXprv.val(accountXprv);
853 DOM.bip44accountXpub.val(accountXpub); 877 DOM.bip44accountXpub.val(accountXpub);
878
879 if (isELA()) {
880 displayBip44InfoForELA();
881 }
854 } 882 }
855 883
856 function displayBip49Info() { 884 function displayBip49Info() {
@@ -906,6 +934,10 @@
906 clearAddressesList(); 934 clearAddressesList();
907 var initialAddressCount = parseInt(DOM.rowsToAdd.val()); 935 var initialAddressCount = parseInt(DOM.rowsToAdd.val());
908 displayAddresses(0, initialAddressCount); 936 displayAddresses(0, initialAddressCount);
937
938 if (isELA()) {
939 displayBip32InfoForELA();
940 }
909 } 941 }
910 942
911 function displayAddresses(start, total) { 943 function displayAddresses(start, total) {
@@ -1008,19 +1040,7 @@
1008 indexText = indexText + "'"; 1040 indexText = indexText + "'";
1009 } 1041 }
1010 // Ethereum values are different 1042 // Ethereum values are different
1011 if ((networks[DOM.network.val()].name == "ETH - Ethereum") 1043 if (networkIsEthereum()) {
1012 || (networks[DOM.network.val()].name == "ETC - Ethereum Classic")
1013 || (networks[DOM.network.val()].name == "PIRL - Pirl")
1014 || (networks[DOM.network.val()].name == "MIX - MIX")
1015 || (networks[DOM.network.val()].name == "MUSIC - Musicoin")
1016 || (networks[DOM.network.val()].name == "POA - Poa")
1017 || (networks[DOM.network.val()].name == "EXP - Expanse")
1018 || (networks[DOM.network.val()].name == "CLO - Callisto")
1019 || (networks[DOM.network.val()].name == "DXN - DEXON")
1020 || (networks[DOM.network.val()].name == "ELLA - Ellaism")
1021 || (networks[DOM.network.val()].name == "ESN - Ethersocial Network")
1022 || (networks[DOM.network.val()].name == "VET - VeChain")
1023 ) {
1024 var privKeyBuffer = keyPair.d.toBuffer(32); 1044 var privKeyBuffer = keyPair.d.toBuffer(32);
1025 privkey = privKeyBuffer.toString('hex'); 1045 privkey = privKeyBuffer.toString('hex');
1026 var addressBuffer = ethUtil.privateToAddress(privKeyBuffer); 1046 var addressBuffer = ethUtil.privateToAddress(privKeyBuffer);
@@ -1125,6 +1145,19 @@
1125 //non-segwit addresses are handled by using groestlcoinjs for bip32RootKey 1145 //non-segwit addresses are handled by using groestlcoinjs for bip32RootKey
1126 } 1146 }
1127 1147
1148 if (isELA()) {
1149 let elaAddress = calcAddressForELA(
1150 seed,
1151 parseIntNoNaN(DOM.bip44coin.val(), 0),
1152 parseIntNoNaN(DOM.bip44account.val(), 0),
1153 parseIntNoNaN(DOM.bip44change.val(), 0),
1154 index
1155 );
1156 address = elaAddress.address;
1157 privkey = elaAddress.privateKey;
1158 pubkey = elaAddress.publicKey;
1159 }
1160
1128 addAddressToList(indexText, address, pubkey, privkey); 1161 addAddressToList(indexText, address, pubkey, privkey);
1129 if (isLast) { 1162 if (isLast) {
1130 hidePending(); 1163 hidePending();
@@ -1415,6 +1448,40 @@
1415 } 1448 }
1416 return phrase; 1449 return phrase;
1417 } 1450 }
1451
1452 function writeSplitPhrase(phrase) {
1453 var wordCount = phrase.split(/\s/g).length; //get number of words in phrase
1454 var left=[]; //initialize array of indexs
1455 for (var i=0;i<wordCount;i++) left.push(i); //add all indexs to array
1456 var group=[[],[],[]], //make array for 3 groups
1457 groupI=-1; //initialize group index
1458 var seed = Math.abs(sjcl.hash.sha256.hash(phrase)[0])% 2147483647; //start seed at sudo random value based on hash of words
1459 while (left.length>0) { //while indexs left
1460 groupI=(groupI+1)%3; //get next group to insert index into
1461 seed = seed * 16807 % 2147483647; //change random value.(simple predicatable random number generator works well for this use)
1462 var selected=Math.floor(left.length*(seed - 1) / 2147483646); //get index in left we will use for this group
1463 group[groupI].push(left[selected]); //add index to group
1464 left.splice(selected,1); //remove selected index
1465 }
1466 var cards=[phrase.split(/\s/g),phrase.split(/\s/g),phrase.split(/\s/g)];//make array of cards
1467 for (var i=0;i<3;i++) { //go through each card
1468 for (var ii=0;ii<wordCount/3;ii++) cards[i][group[i][ii]]='XXXX'; //erase words listed in the group
1469 cards[i]='Card '+(i+1)+': '+wordArrayToPhrase(cards[i]); //combine words on card back to string
1470 }
1471 DOM.splitPhrase.val(cards.join("\r\n")); //make words visible
1472 var triesPerSecond=10000000000; //assumed number of tries per second
1473 var hackTime=Math.pow(2,wordCount*10/3)/triesPerSecond; //get number of bits of unknown data per card
1474 if (hackTime<1) {
1475 hackTime="<1 second";
1476 } else if (hackTime<86400) {
1477 hackTime=Math.floor(hackTime)+" seconds";
1478 } else if(hackTime<31557600) {
1479 hackTime=Math.floor(hackTime/86400)+" days";
1480 } else {
1481 hackTime=Math.floor(hackTime/31557600)+" years";
1482 }
1483 DOM.phraseSplitWarn.html("Time to hack with only one card: "+hackTime);
1484 }
1418 1485
1419 function isUsingOwnEntropy() { 1486 function isUsingOwnEntropy() {
1420 return DOM.useEntropy.prop("checked"); 1487 return DOM.useEntropy.prop("checked");
@@ -1473,6 +1540,7 @@
1473 var phrase = mnemonic.toMnemonic(entropyArr); 1540 var phrase = mnemonic.toMnemonic(entropyArr);
1474 // Set the mnemonic in the UI 1541 // Set the mnemonic in the UI
1475 DOM.phrase.val(phrase); 1542 DOM.phrase.val(phrase);
1543 writeSplitPhrase(phrase);
1476 // Show the word indexes 1544 // Show the word indexes
1477 showWordIndexes(); 1545 showWordIndexes();
1478 // Show the checksum 1546 // Show the checksum
@@ -1636,6 +1704,23 @@
1636 return DOM.bip32tab.hasClass("active"); 1704 return DOM.bip32tab.hasClass("active");
1637 } 1705 }
1638 1706
1707 function networkIsEthereum() {
1708 var name = networks[DOM.network.val()].name;
1709 return (name == "ETH - Ethereum")
1710 || (name == "ETC - Ethereum Classic")
1711 || (name == "EWT - EnergyWeb")
1712 || (name == "PIRL - Pirl")
1713 || (name == "MIX - MIX")
1714 || (name == "MUSIC - Musicoin")
1715 || (name == "POA - Poa")
1716 || (name == "EXP - Expanse")
1717 || (name == "CLO - Callisto")
1718 || (name == "DXN - DEXON")
1719 || (name == "ELLA - Ellaism")
1720 || (name == "ESN - Ethersocial Network")
1721 || (name == "VET - VeChain")
1722 }
1723
1639 function networkHasSegwit() { 1724 function networkHasSegwit() {
1640 var n = network; 1725 var n = network;
1641 if ("baseNetwork" in network) { 1726 if ("baseNetwork" in network) {
@@ -1665,10 +1750,30 @@
1665 return DOM.bip141tab.hasClass("active"); 1750 return DOM.bip141tab.hasClass("active");
1666 } 1751 }
1667 1752
1753 function setBip44ChangeValue() {
1754 if (isDefaultBip44ChangeValue) {
1755 if (networkIsEthereum()) {
1756 DOM.bip44change.val("");
1757 } else {
1758 DOM.bip44change.val(0);
1759 }
1760 }
1761 }
1762
1763 function modifiedDefaultBip44ChangeValue() {
1764 isDefaultBip44ChangeValue = false;
1765 }
1766
1767 function resetDefaultBip44ChangeValue() {
1768 isDefaultBip44ChangeValue = true;
1769 setBip44ChangeValue();
1770 }
1771
1668 function setHdCoin(coinValue) { 1772 function setHdCoin(coinValue) {
1669 DOM.bip44coin.val(coinValue); 1773 DOM.bip44coin.val(coinValue);
1670 DOM.bip49coin.val(coinValue); 1774 DOM.bip49coin.val(coinValue);
1671 DOM.bip84coin.val(coinValue); 1775 DOM.bip84coin.val(coinValue);
1776 setBip44ChangeValue();
1672 } 1777 }
1673 1778
1674 function showSegwitAvailable() { 1779 function showSegwitAvailable() {
@@ -2163,6 +2268,13 @@
2163 }, 2268 },
2164 }, 2269 },
2165 { 2270 {
2271 name: "ELA - Elastos",
2272 onSelect: function () {
2273 network = bitcoinjs.bitcoin.networks.elastos;
2274 setHdCoin(2305);
2275 },
2276 },
2277 {
2166 name: "ELLA - Ellaism", 2278 name: "ELLA - Ellaism",
2167 segwitAvailable: false, 2279 segwitAvailable: false,
2168 onSelect: function() { 2280 onSelect: function() {
@@ -2213,7 +2325,14 @@
2213 network = bitcoinjs.bitcoin.networks.bitcoin; 2325 network = bitcoinjs.bitcoin.networks.bitcoin;
2214 setHdCoin(60); 2326 setHdCoin(60);
2215 }, 2327 },
2216 }, 2328 },
2329 {
2330 name: "EWT - EnergyWeb",
2331 onSelect: function() {
2332 network = bitcoinjs.bitcoin.networks.bitcoin;
2333 setHdCoin(246);
2334 },
2335 },
2217 { 2336 {
2218 name: "EXCL - Exclusivecoin", 2337 name: "EXCL - Exclusivecoin",
2219 onSelect: function() { 2338 onSelect: function() {
@@ -3070,6 +3189,56 @@
3070 } 3189 }
3071 ] 3190 ]
3072 3191
3192 // ELA - Elastos functions - begin
3193 function displayBip44InfoForELA() {
3194 if (!isELA()) {
3195 return;
3196 }
3197
3198 var coin = parseIntNoNaN(DOM.bip44coin.val(), 0);
3199 var account = parseIntNoNaN(DOM.bip44account.val(), 0);
3200
3201 // Calculate the account extended keys
3202 var accountXprv = elastosjs.getAccountExtendedPrivateKey(seed, coin, account);
3203 var accountXpub = elastosjs.getAccountExtendedPublicKey(seed, coin, account);
3204
3205 // Display the extended keys
3206 DOM.bip44accountXprv.val(accountXprv);
3207 DOM.bip44accountXpub.val(accountXpub);
3208 }
3209
3210 function displayBip32InfoForELA() {
3211 if (!isELA()) {
3212 return;
3213 }
3214
3215 var coin = parseIntNoNaN(DOM.bip44coin.val(), 0);
3216 var account = parseIntNoNaN(DOM.bip44account.val(), 0);
3217 var change = parseIntNoNaN(DOM.bip44change.val(), 0);
3218
3219 DOM.extendedPrivKey.val(elastosjs.getBip32ExtendedPrivateKey(seed, coin, account, change));
3220 DOM.extendedPubKey.val(elastosjs.getBip32ExtendedPublicKey(seed, coin, account, change));
3221
3222 // Display the addresses and privkeys
3223 clearAddressesList();
3224 var initialAddressCount = parseInt(DOM.rowsToAdd.val());
3225 displayAddresses(0, initialAddressCount);
3226 }
3227
3228 function calcAddressForELA(seed, coin, account, change, index) {
3229 if (!isELA()) {
3230 return;
3231 }
3232
3233 var publicKey = elastosjs.getDerivedPublicKey(elastosjs.getMasterPublicKey(seed), change, index);
3234 return {
3235 privateKey: elastosjs.getDerivedPrivateKey(seed, coin, account, change, index),
3236 publicKey: publicKey,
3237 address: elastosjs.getAddress(publicKey.toString('hex'))
3238 };
3239 }
3240 // ELA - Elastos functions - end
3241
3073 init(); 3242 init();
3074 3243
3075})(); 3244})();