X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=src%2Fjs%2Findex.js;h=1f4cc1fe12ab203ff39474804ac1e63c44c1463b;hb=6d2e202083c4166aa4be8557789a8a461df6bd5c;hp=52b0db5d86f4f8ba3ea49dceaaaae6e5f6cbcc0c;hpb=c4f4208b95cf6fb85a8d669c0c8dcdb8b12bb2e7;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FBIP39.git diff --git a/src/js/index.js b/src/js/index.js index 52b0db5..1f4cc1f 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -6,7 +6,7 @@ var seed = null; var bip32RootKey = null; var bip32ExtendedKey = null; - var network = bitcoinjs.bitcoin.networks.bitcoin; + var network = libs.bitcoin.networks.bitcoin; var addressRowTemplate = $("#address-row-template"); var showIndex = true; @@ -16,8 +16,10 @@ var showQr = false; var litecoinUseLtub = true; + var entropyTypeAutoDetect = true; var entropyChangeTimeoutEvent = null; var phraseChangeTimeoutEvent = null; + var seedChangedTimeoutEvent = null; var rootKeyChangedTimeoutEvent = null; var generationProcesses = []; @@ -32,6 +34,7 @@ DOM.entropy = $(".entropy"); DOM.entropyFiltered = DOM.entropyContainer.find(".filtered"); DOM.entropyType = DOM.entropyContainer.find(".type"); + DOM.entropyTypeInputs = DOM.entropyContainer.find("input[name='entropy-type']"); DOM.entropyCrackTime = DOM.entropyContainer.find(".crack-time"); DOM.entropyEventCount = DOM.entropyContainer.find(".event-count"); DOM.entropyBits = DOM.entropyContainer.find(".bits"); @@ -44,6 +47,10 @@ DOM.entropyWeakEntropyOverrideWarning = DOM.entropyContainer.find(".weak-entropy-override-warning"); DOM.entropyFilterWarning = DOM.entropyContainer.find(".filter-warning"); DOM.phrase = $(".phrase"); + DOM.splitMnemonic = $(".splitMnemonic"); + DOM.showSplitMnemonic = $(".showSplitMnemonic"); + DOM.phraseSplit = $(".phraseSplit"); + DOM.phraseSplitWarn = $(".phraseSplitWarn"); DOM.passphrase = $(".passphrase"); DOM.generateContainer = $(".generate-container"); DOM.generate = $(".generate"); @@ -87,6 +94,18 @@ DOM.bip84accountXprv = $("#bip84 .account-xprv"); DOM.bip84accountXpub = $("#bip84 .account-xpub"); DOM.bip84change = $("#bip84 .change"); + DOM.bip85 = $('.bip85'); + DOM.showBip85 = $('.showBip85'); + DOM.bip85Field = $('.bip85Field'); + DOM.bip85application = $('#bip85-application'); + DOM.bip85mnemonicLanguage = $('#bip85-mnemonic-language'); + DOM.bip85mnemonicLanguageInput = $('.bip85-mnemonic-language-input'); + DOM.bip85mnemonicLength = $('#bip85-mnemonic-length'); + DOM.bip85mnemonicLengthInput = $('.bip85-mnemonic-length-input'); + DOM.bip85index = $('#bip85-index'); + DOM.bip85indexInput = $('.bip85-index-input'); + DOM.bip85bytes = $('#bip85-bytes'); + DOM.bip85bytesInput = $('.bip85-bytes-input'); DOM.bip141unavailable = $("#bip141 .unavailable"); DOM.bip141available = $("#bip141 .available"); DOM.bip141path = $("#bip141-path"); @@ -126,11 +145,15 @@ DOM.useEntropy.on("change", setEntropyVisibility); DOM.entropy.on("input", delayedEntropyChanged); DOM.entropyMnemonicLength.on("change", entropyChanged); + DOM.entropyTypeInputs.on("change", entropyTypeChanged); DOM.phrase.on("input", delayedPhraseChanged); + DOM.showSplitMnemonic.on("change", toggleSplitMnemonic); DOM.passphrase.on("input", delayedPhraseChanged); DOM.generate.on("click", generateClicked); DOM.more.on("click", showMore); + DOM.seed.on("input", delayedSeedChanged); DOM.rootKey.on("input", delayedRootKeyChanged); + DOM.showBip85.on('change', toggleBip85); DOM.litecoinUseLtub.on("change", litecoinUseLtubChanged); DOM.bip32path.on("input", calcForDerivationPath); DOM.bip44account.on("input", calcForDerivationPath); @@ -139,6 +162,11 @@ DOM.bip49change.on("input", calcForDerivationPath); DOM.bip84account.on("input", calcForDerivationPath); DOM.bip84change.on("input", calcForDerivationPath); + DOM.bip85application.on('input', calcBip85); + DOM.bip85mnemonicLanguage.on('change', calcBip85); + DOM.bip85mnemonicLength.on('change', calcBip85); + DOM.bip85index.on('input', calcBip85); + DOM.bip85bytes.on('input', calcBip85); DOM.bip141path.on("input", calcForDerivationPath); DOM.bip141semantics.on("change", tabChanged); DOM.tab.on("shown.bs.tab", tabChanged); @@ -232,7 +260,16 @@ if (phraseChangeTimeoutEvent != null) { clearTimeout(phraseChangeTimeoutEvent); } - phraseChangeTimeoutEvent = setTimeout(phraseChanged, 400); + phraseChangeTimeoutEvent = setTimeout(function() { + phraseChanged(); + var entropy = mnemonic.toRawEntropyHex(DOM.phrase.val()); + if (entropy !== null) { + DOM.entropyMnemonicLength.val("raw"); + DOM.entropy.val(entropy); + DOM.entropyTypeInputs.filter("[value='hexadecimal']").prop("checked", true); + entropyTypeAutoDetect = false; + } + }, 400); } function phraseChanged() { @@ -249,8 +286,10 @@ var passphrase = DOM.passphrase.val(); calcBip32RootKeyFromSeed(phrase, passphrase); calcForDerivationPath(); + calcBip85(); // Show the word indexes showWordIndexes(); + writeSplitPhrase(phrase); } function tabChanged() { @@ -297,6 +336,7 @@ clearDisplay(); clearEntropyFeedback(); DOM.phrase.val(""); + DOM.phraseSplit.val(""); showValidationError("Blank entropy"); return; } @@ -319,6 +359,35 @@ } } + function entropyTypeChanged() { + entropyTypeAutoDetect = false; + entropyChanged(); + } + + function delayedSeedChanged() { + // Warn if there is an existing mnemonic or passphrase. + if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) { + if (!confirm("This will clear existing mnemonic and passphrase")) { + DOM.seed.val(seed); + return + } + } + hideValidationError(); + showPending(); + // Clear existing mnemonic and passphrase + DOM.phrase.val(""); + DOM.phraseSplit.val(""); + DOM.passphrase.val(""); + DOM.rootKey.val(""); + clearAddressesList(); + clearDerivedKeys(); + seed = null; + if (seedChangedTimeoutEvent != null) { + clearTimeout(seedChangedTimeoutEvent); + } + seedChangedTimeoutEvent = setTimeout(seedChanged, 400); + } + function delayedRootKeyChanged() { // Warn if there is an existing mnemonic or passphrase. if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) { @@ -331,6 +400,7 @@ showPending(); // Clear existing mnemonic and passphrase DOM.phrase.val(""); + DOM.phraseSplit.val(""); DOM.passphrase.val(""); seed = null; if (rootKeyChangedTimeoutEvent != null) { @@ -339,6 +409,23 @@ rootKeyChangedTimeoutEvent = setTimeout(rootKeyChanged, 400); } + function seedChanged() { + showPending(); + hideValidationError(); + seed = DOM.seed.val(); + bip32RootKey = libs.bitcoin.HDNode.fromSeedHex(seed, network); + var rootKeyBase58 = bip32RootKey.toBase58(); + DOM.rootKey.val(rootKeyBase58); + var errorText = validateRootKey(rootKeyBase58); + if (errorText) { + showValidationError(errorText); + return; + } + // Calculate and display + calcForDerivationPath(); + calcBip85(); + } + function rootKeyChanged() { showPending(); hideValidationError(); @@ -351,19 +438,98 @@ // Calculate and display calcBip32RootKeyFromBase58(rootKeyBase58); calcForDerivationPath(); + calcBip85(); } function litecoinUseLtubChanged() { litecoinUseLtub = DOM.litecoinUseLtub.prop("checked"); if (litecoinUseLtub) { - network = bitcoinjs.bitcoin.networks.litecoin; + network = libs.bitcoin.networks.litecoin; } else { - network = bitcoinjs.bitcoin.networks.litecoinXprv; + network = libs.bitcoin.networks.litecoinXprv; } phraseChanged(); } + function toggleSplitMnemonic() { + if (DOM.showSplitMnemonic.prop("checked")) { + DOM.splitMnemonic.removeClass("hidden"); + } + else { + DOM.splitMnemonic.addClass("hidden"); + } + } + + function toggleBip85() { + if (DOM.showBip85.prop('checked')) { + DOM.bip85.removeClass('hidden'); + calcBip85(); + } else { + DOM.bip85.addClass('hidden'); + } + } + + function toggleBip85Fields() { + if (DOM.showBip85.prop('checked')) { + DOM.bip85mnemonicLanguageInput.addClass('hidden'); + DOM.bip85mnemonicLengthInput.addClass('hidden'); + DOM.bip85bytesInput.addClass('hidden'); + + var app = DOM.bip85application.val(); + if (app === 'bip39') { + DOM.bip85mnemonicLanguageInput.removeClass('hidden'); + DOM.bip85mnemonicLengthInput.removeClass('hidden'); + } else if (app === 'hex') { + DOM.bip85bytesInput.removeClass('hidden'); + } + } + } + + function calcBip85() { + if (!DOM.showBip85.prop('checked')) { + return + } + + toggleBip85Fields(); + + var app = DOM.bip85application.val(); + + var phrase = DOM.phrase.val(); + var passphrase = DOM.passphrase.val(); + if (!phrase) { + return; + } + try { + var master = libs.bip85.BIP85.fromMnemonic(phrase, passphrase); + + var result; + + const index = parseInt(DOM.bip85index.val(), 10); + + if (app === 'bip39') { + const language = parseInt(DOM.bip85mnemonicLanguage.val(), 10); + const length = parseInt(DOM.bip85mnemonicLength.val(), 10); + + result = master.deriveBIP39(language, length, index).toMnemonic(); + } else if (app === 'wif') { + result = master.deriveWIF(index).toWIF(); + } else if (app === 'xprv') { + result = master.deriveXPRV(index).toXPRV(); + } else if (app === 'hex') { + const bytes = parseInt(DOM.bip85bytes.val(), 10); + + result = master.deriveHex(bytes, index).toEntropy(); + } + + hideValidationError(); + DOM.bip85Field.val(result); + } catch (e) { + showValidationError('BIP85: ' + e.message); + DOM.bip85Field.val(''); + } + } + function calcForDerivationPath() { clearDerivedKeys(); clearAddressesList(); @@ -487,27 +653,85 @@ function calcBip32RootKeyFromSeed(phrase, passphrase) { seed = mnemonic.toSeed(phrase, passphrase); - bip32RootKey = bitcoinjs.bitcoin.HDNode.fromSeedHex(seed, network); + bip32RootKey = libs.bitcoin.HDNode.fromSeedHex(seed, network); + if(isGRS()) + bip32RootKey = libs.groestlcoinjs.HDNode.fromSeedHex(seed, network); + } function calcBip32RootKeyFromBase58(rootKeyBase58) { + if(isGRS()) { + calcBip32RootKeyFromBase58GRS(rootKeyBase58); + return; + } + // try parsing with various segwit network params since this extended + // key may be from any one of them. + if (networkHasSegwit()) { + var n = network; + if ("baseNetwork" in n) { + n = libs.bitcoin.networks[n.baseNetwork]; + } + // try parsing using base network params + try { + bip32RootKey = libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n); + return; + } + catch (e) {} + // try parsing using p2wpkh params + if ("p2wpkh" in n) { + try { + bip32RootKey = libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkh); + return; + } + catch (e) {} + } + // try parsing using p2wpkh-in-p2sh network params + if ("p2wpkhInP2sh" in n) { + try { + bip32RootKey = libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkhInP2sh); + return; + } + catch (e) {} + } + // try parsing using p2wsh network params + if ("p2wsh" in n) { + try { + bip32RootKey = libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wsh); + return; + } + catch (e) {} + } + // try parsing using p2wsh-in-p2sh network params + if ("p2wshInP2sh" in n) { + try { + bip32RootKey = libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wshInP2sh); + return; + } + catch (e) {} + } + } + // try the network params as currently specified + bip32RootKey = libs.bitcoin.HDNode.fromBase58(rootKeyBase58, network); + } + + function calcBip32RootKeyFromBase58GRS(rootKeyBase58) { // try parsing with various segwit network params since this extended // key may be from any one of them. if (networkHasSegwit()) { var n = network; if ("baseNetwork" in n) { - n = bitcoinjs.bitcoin.networks[n.baseNetwork]; + n = libs.bitcoin.networks[n.baseNetwork]; } // try parsing using base network params try { - bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n); + bip32RootKey = libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, n); return; } catch (e) {} // try parsing using p2wpkh params if ("p2wpkh" in n) { try { - bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkh); + bip32RootKey = libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, n.p2wpkh); return; } catch (e) {} @@ -515,14 +739,14 @@ // try parsing using p2wpkh-in-p2sh network params if ("p2wpkhInP2sh" in n) { try { - bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkhInP2sh); + bip32RootKey = libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, n.p2wpkhInP2sh); return; } catch (e) {} } } // try the network params as currently specified - bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, network); + bip32RootKey = libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, network); } function calcBip32ExtendedKey(path) { @@ -552,7 +776,7 @@ extendedKey = extendedKey.derive(index); } } - return extendedKey + return extendedKey; } function showValidationError(errorText) { @@ -595,23 +819,26 @@ } function validateRootKey(rootKeyBase58) { + if(isGRS()) + return validateRootKeyGRS(rootKeyBase58); + // try various segwit network params since this extended key may be from // any one of them. if (networkHasSegwit()) { var n = network; if ("baseNetwork" in n) { - n = bitcoinjs.bitcoin.networks[n.baseNetwork]; + n = libs.bitcoin.networks[n.baseNetwork]; } // try parsing using base network params try { - bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n); + libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n); return ""; } catch (e) {} // try parsing using p2wpkh params if ("p2wpkh" in n) { try { - bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkh); + libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkh); return ""; } catch (e) {} @@ -619,7 +846,23 @@ // try parsing using p2wpkh-in-p2sh network params if ("p2wpkhInP2sh" in n) { try { - bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkhInP2sh); + libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wpkhInP2sh); + return ""; + } + catch (e) {} + } + // try parsing using p2wsh network params + if ("p2wsh" in n) { + try { + libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wsh); + return ""; + } + catch (e) {} + } + // try parsing using p2wsh-in-p2sh network params + if ("p2wshInP2sh" in n) { + try { + libs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wshInP2sh); return ""; } catch (e) {} @@ -627,7 +870,48 @@ } // try the network params as currently specified try { - bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, network); + libs.bitcoin.HDNode.fromBase58(rootKeyBase58, network); + } + catch (e) { + return "Invalid root key"; + } + return ""; + } + + function validateRootKeyGRS(rootKeyBase58) { + // try various segwit network params since this extended key may be from + // any one of them. + if (networkHasSegwit()) { + var n = network; + if ("baseNetwork" in n) { + n = libs.bitcoin.networks[n.baseNetwork]; + } + // try parsing using base network params + try { + libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, n); + return ""; + } + catch (e) {} + // try parsing using p2wpkh params + if ("p2wpkh" in n) { + try { + libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, n.p2wpkh); + return ""; + } + catch (e) {} + } + // try parsing using p2wpkh-in-p2sh network params + if ("p2wpkhInP2sh" in n) { + try { + libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, n.p2wpkhInP2sh); + return ""; + } + catch (e) {} + } + } + // try the network params as currently specified + try { + libs.groestlcoinjs.HDNode.fromBase58(rootKeyBase58, network); } catch (e) { return "Invalid root key"; @@ -745,6 +1029,14 @@ return false; } + function isGRS() { + return networks[DOM.network.val()].name == "GRS - Groestlcoin" || networks[DOM.network.val()].name == "GRS - Groestlcoin Testnet"; + } + + function isELA() { + return networks[DOM.network.val()].name == "ELA - Elastos" + } + function displayBip44Info() { // Get the derivation path for the account var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44); @@ -758,9 +1050,14 @@ var accountExtendedKey = calcBip32ExtendedKey(path); var accountXprv = accountExtendedKey.toBase58(); var accountXpub = accountExtendedKey.neutered().toBase58(); + // Display the extended keys DOM.bip44accountXprv.val(accountXprv); DOM.bip44accountXpub.val(accountXpub); + + if (isELA()) { + displayBip44InfoForELA(); + } } function displayBip49Info() { @@ -816,6 +1113,10 @@ clearAddressesList(); var initialAddressCount = parseInt(DOM.rowsToAdd.val()); displayAddresses(0, initialAddressCount); + + if (isELA()) { + displayBip32InfoForELA(); + } } function displayAddresses(start, total) { @@ -853,6 +1154,14 @@ (bip141TabSelected() && DOM.bip141semantics.val() == "p2wpkh-p2sh"); } + function p2wshSelected() { + return bip141TabSelected() && DOM.bip141semantics.val() == "p2wsh"; + } + + function p2wshInP2shSelected() { + return (bip141TabSelected() && DOM.bip141semantics.val() == "p2wsh-p2sh"); + } + function TableRow(index, isLast) { var self = this; @@ -864,6 +1173,8 @@ var segwitAvailable = networkHasSegwit(); var isP2wpkh = p2wpkhSelected(); var isP2wpkhInP2sh = p2wpkhInP2shSelected(); + var isP2wsh = p2wshSelected(); + var isP2wshInP2sh = p2wshInP2shSelected(); function init() { calculateValues(); @@ -887,7 +1198,10 @@ var keyPair = key.keyPair; var useUncompressed = useBip38; if (useUncompressed) { - keyPair = new bitcoinjs.bitcoin.ECPair(keyPair.d, null, { network: network, compressed: false }); + keyPair = new libs.bitcoin.ECPair(keyPair.d, null, { network: network, compressed: false }); + if(isGRS()) + keyPair = new libs.groestlcoinjs.ECPair(keyPair.d, null, { network: network, compressed: false }); + } // get address var address = keyPair.getAddress().toString(); @@ -898,9 +1212,14 @@ privkey = keyPair.toWIF(); // BIP38 encode private key if required if (useBip38) { - privkey = bitcoinjsBip38.encrypt(keyPair.d.toBuffer(), false, bip38password, function(p) { - console.log("Progressed " + p.percent.toFixed(1) + "% for index " + index); - }); + if(isGRS()) + privkey = libs.groestlcoinjsBip38.encrypt(keyPair.d.toBuffer(), false, bip38password, function(p) { + console.log("Progressed " + p.percent.toFixed(1) + "% for index " + index); + }, null, networks[DOM.network.val()].name.includes("Testnet")); + else + privkey = libs.bip38.encrypt(keyPair.d.toBuffer(), false, bip38password, function(p) { + console.log("Progressed " + p.percent.toFixed(1) + "% for index " + index); + }); } } // get pubkey @@ -910,27 +1229,62 @@ indexText = indexText + "'"; } // Ethereum values are different - if ((networks[DOM.network.val()].name == "ETH - Ethereum") - || (networks[DOM.network.val()].name == "ETC - Ethereum Classic") - || (networks[DOM.network.val()].name == "PIRL - Pirl") - || (networks[DOM.network.val()].name == "MIX - MIX") - || (networks[DOM.network.val()].name == "MUSIC - Musicoin") - || (networks[DOM.network.val()].name == "POA - Poa") - || (networks[DOM.network.val()].name == "EXP - Expanse") - || (networks[DOM.network.val()].name == "CLO - Callisto") - || (networks[DOM.network.val()].name == "DXN - DEXON") - || (networks[DOM.network.val()].name == "ELLA - Ellaism") - || (networks[DOM.network.val()].name == "ESN - Ethersocial Network") - || (networks[DOM.network.val()].name == "VET - VeChain") - ) { - var privKeyBuffer = keyPair.d.toBuffer(32); - privkey = privKeyBuffer.toString('hex'); - var addressBuffer = ethUtil.privateToAddress(privKeyBuffer); + if (networkIsEthereum()) { + var pubkeyBuffer = keyPair.getPublicKeyBuffer(); + var ethPubkey = libs.ethUtil.importPublic(pubkeyBuffer); + var addressBuffer = libs.ethUtil.publicToAddress(ethPubkey); + var hexAddress = addressBuffer.toString('hex'); + var checksumAddress = libs.ethUtil.toChecksumAddress(hexAddress); + address = libs.ethUtil.addHexPrefix(checksumAddress); + pubkey = libs.ethUtil.addHexPrefix(pubkey); + if (hasPrivkey) { + privkey = libs.ethUtil.bufferToHex(keyPair.d.toBuffer()); + } + } + //TRX is different + if (networks[DOM.network.val()].name == "TRX - Tron") { + keyPair = new libs.bitcoin.ECPair(keyPair.d, null, { network: network, compressed: false }); + var pubkeyBuffer = keyPair.getPublicKeyBuffer(); + var ethPubkey = libs.ethUtil.importPublic(pubkeyBuffer); + var addressBuffer = libs.ethUtil.publicToAddress(ethPubkey); + address = libs.bitcoin.address.toBase58Check(addressBuffer, 0x41); + if (hasPrivkey) { + privkey = keyPair.d.toBuffer().toString('hex'); + } + } + + // RSK values are different + if (networkIsRsk()) { + var pubkeyBuffer = keyPair.getPublicKeyBuffer(); + var ethPubkey = libs.ethUtil.importPublic(pubkeyBuffer); + var addressBuffer = libs.ethUtil.publicToAddress(ethPubkey); var hexAddress = addressBuffer.toString('hex'); - var checksumAddress = ethUtil.toChecksumAddress(hexAddress); - address = ethUtil.addHexPrefix(checksumAddress); - privkey = ethUtil.addHexPrefix(privkey); - pubkey = ethUtil.addHexPrefix(pubkey); + // Use chainId based on selected network + // Ref: https://developers.rsk.co/rsk/architecture/account-based/#chainid + var chainId; + var rskNetworkName = networks[DOM.network.val()].name; + switch (rskNetworkName) { + case "R-BTC - RSK": + chainId = 30; + break; + case "tR-BTC - RSK Testnet": + chainId = 31; + break; + default: + chainId = null; + } + var checksumAddress = toChecksumAddressForRsk(hexAddress, chainId); + address = libs.ethUtil.addHexPrefix(checksumAddress); + pubkey = libs.ethUtil.addHexPrefix(pubkey); + if (hasPrivkey) { + privkey = libs.ethUtil.bufferToHex(keyPair.d.toBuffer()); + } + } + + // Handshake values are different + if (networks[DOM.network.val()].name == "HNS - Handshake") { + var ring = libs.handshake.KeyRing.fromPublic(keyPair.getPublicKeyBuffer()) + address = ring.getAddress().toString(); } // Stellar is different @@ -940,15 +1294,23 @@ var path = "m/"; path += purpose + "'/"; path += coin + "'/" + index + "'"; - var keypair = stellarUtil.getKeypair(path, seed); + var keypair = libs.stellarUtil.getKeypair(path, seed); indexText = path; privkey = keypair.secret(); pubkey = address = keypair.publicKey(); } + + // Nano currency + if (networks[DOM.network.val()].name == "NANO - Nano") { + var nanoKeypair = libs.nanoUtil.getKeypair(index, seed); + privkey = nanoKeypair.privKey; + pubkey = nanoKeypair.pubKey; + address = nanoKeypair.address; + } + if ((networks[DOM.network.val()].name == "NAS - Nebulas")) { - var NasAccount = require("nebulas-account"); var privKeyBuffer = keyPair.d.toBuffer(32); - var nebulasAccount = new NasAccount(); + var nebulasAccount = libs.nebulas.Account.NewAccount(); nebulasAccount.setPrivateKey(privKeyBuffer); address = nebulasAccount.getAddressString(); privkey = nebulasAccount.getPrivateKeyString(); @@ -959,50 +1321,132 @@ privkey = convertRipplePriv(privkey); address = convertRippleAdrr(address); } + // Jingtum values are different + if (networks[DOM.network.val()].name == "SWTC - Jingtum") { + privkey = convertJingtumPriv(privkey); + address = convertJingtumAdrr(address); + } + // CasinoCoin values are different + if (networks[DOM.network.val()].name == "CSC - CasinoCoin") { + privkey = convertCasinoCoinPriv(privkey); + address = convertCasinoCoinAdrr(address); + } // Bitcoin Cash address format may vary if (networks[DOM.network.val()].name == "BCH - Bitcoin Cash") { var bchAddrType = DOM.bitcoinCashAddressType.filter(":checked").val(); if (bchAddrType == "cashaddr") { - address = bchaddr.toCashAddress(address); + address = libs.bchaddr.toCashAddress(address); } else if (bchAddrType == "bitpay") { - address = bchaddr.toBitpayAddress(address); + address = libs.bchaddr.toBitpayAddress(address); } } // Bitcoin Cash address format may vary if (networks[DOM.network.val()].name == "SLP - Simple Ledger Protocol") { var bchAddrType = DOM.bitcoinCashAddressType.filter(":checked").val(); if (bchAddrType == "cashaddr") { - address = bchaddr.toSlpAddress(address); + address = libs.bchaddrSlp.toSlpAddress(address); } } + + // ZooBC address format may vary + if (networks[DOM.network.val()].name == "ZBC - ZooBlockchain") { + + var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44); + var coin = parseIntNoNaN(DOM.bip44coin.val(), 0); + var path = "m/"; + path += purpose + "'/"; + path += coin + "'/" + index + "'"; + var result = libs.zoobcUtil.getKeypair(path, seed); + + let publicKey = result.pubKey.slice(1, 33); + let privateKey = result.key; + + privkey = privateKey.toString('hex'); + pubkey = publicKey.toString('hex'); + + indexText = path; + address = libs.zoobcUtil.getZBCAddress(publicKey, 'ZBC'); + } + // Segwit addresses are different if (isSegwit) { if (!segwitAvailable) { return; } if (isP2wpkh) { - var keyhash = bitcoinjs.bitcoin.crypto.hash160(key.getPublicKeyBuffer()); - var scriptpubkey = bitcoinjs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash); - address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network) + var keyhash = libs.bitcoin.crypto.hash160(key.getPublicKeyBuffer()); + var scriptpubkey = libs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash); + address = libs.bitcoin.address.fromOutputScript(scriptpubkey, network) } else if (isP2wpkhInP2sh) { - var keyhash = bitcoinjs.bitcoin.crypto.hash160(key.getPublicKeyBuffer()); - var scriptsig = bitcoinjs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash); - var addressbytes = bitcoinjs.bitcoin.crypto.hash160(scriptsig); - var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes); - address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network) + var keyhash = libs.bitcoin.crypto.hash160(key.getPublicKeyBuffer()); + var scriptsig = libs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash); + var addressbytes = libs.bitcoin.crypto.hash160(scriptsig); + var scriptpubkey = libs.bitcoin.script.scriptHash.output.encode(addressbytes); + address = libs.bitcoin.address.fromOutputScript(scriptpubkey, network) + } + else if (isP2wsh) { + // https://github.com/libs.bitcoinjs-lib/blob/v3.3.2/test/integration/addresses.js#L71 + // This is a 1-of-1 + var witnessScript = libs.bitcoin.script.multisig.output.encode(1, [key.getPublicKeyBuffer()]); + var scriptPubKey = libs.bitcoin.script.witnessScriptHash.output.encode(libs.bitcoin.crypto.sha256(witnessScript)); + address = libs.bitcoin.address.fromOutputScript(scriptPubKey, network); + } + else if (isP2wshInP2sh) { + // https://github.com/libs.bitcoinjs-lib/blob/v3.3.2/test/integration/transactions.js#L183 + // This is a 1-of-1 + var witnessScript = libs.bitcoin.script.multisig.output.encode(1, [key.getPublicKeyBuffer()]); + var redeemScript = libs.bitcoin.script.witnessScriptHash.output.encode(libs.bitcoin.crypto.sha256(witnessScript)); + var scriptPubKey = libs.bitcoin.script.scriptHash.output.encode(libs.bitcoin.crypto.hash160(redeemScript)); + address = libs.bitcoin.address.fromOutputScript(scriptPubKey, network) } } if ((networks[DOM.network.val()].name == "CRW - Crown")) { - address = bitcoinjs.bitcoin.networks.crown.toNewAddress(address); + address = libs.bitcoin.networks.crown.toNewAddress(address); } if (networks[DOM.network.val()].name == "EOS - EOSIO") { address = "" - pubkey = eosUtil.bufferToPublic(keyPair.getPublicKeyBuffer()); - privkey = eosUtil.bufferToPrivate(keyPair.d.toBuffer(32)); + pubkey = EOSbufferToPublic(keyPair.getPublicKeyBuffer()); + privkey = EOSbufferToPrivate(keyPair.d.toBuffer(32)); + } + + if (networks[DOM.network.val()].name == "FIO - Foundation for Interwallet Operability") { + address = "" + pubkey = FIObufferToPublic(keyPair.getPublicKeyBuffer()); + privkey = FIObufferToPrivate(keyPair.d.toBuffer(32)); + } + + //Groestlcoin Addresses are different + if(isGRS()) { + + if (isSegwit) { + if (!segwitAvailable) { + return; + } + if (isP2wpkh) { + address = libs.groestlcoinjs.address.fromOutputScript(scriptpubkey, network) + } + else if (isP2wpkhInP2sh) { + address = libs.groestlcoinjs.address.fromOutputScript(scriptpubkey, network) + } + } + //non-segwit addresses are handled by using groestlcoinjs for bip32RootKey + } + + if (isELA()) { + let elaAddress = calcAddressForELA( + seed, + parseIntNoNaN(DOM.bip44coin.val(), 0), + parseIntNoNaN(DOM.bip44account.val(), 0), + parseIntNoNaN(DOM.bip44change.val(), 0), + index + ); + address = elaAddress.address; + privkey = elaAddress.privateKey; + pubkey = elaAddress.publicKey; } addAddressToList(indexText, address, pubkey, privkey); @@ -1140,7 +1584,7 @@ if (comparedTo.indexOf(word) == 0) { return comparedTo; } - var distance = Levenshtein.get(word, comparedTo); + var distance = libs.levenshtein.get(word, comparedTo); if (distance < minDistance) { closestWord = comparedTo; minDistance = distance; @@ -1296,6 +1740,49 @@ return phrase; } + function writeSplitPhrase(phrase) { + var wordCount = phrase.split(/\s/g).length; + var left=[]; + for (var i=0;i0) { + groupI=(groupI+1)%3; + seed = seed * 16807 % 2147483647; + var selected=Math.floor(left.length*(seed - 1) / 2147483646); + group[groupI].push(left[selected]); + left.splice(selected,1); + } + var cards=[phrase.split(/\s/g),phrase.split(/\s/g),phrase.split(/\s/g)]; + for (var i=0;i<3;i++) { + for (var ii=0;ii= 8 ? + stripAddress[i].toUpperCase() : + stripAddress[i]; + } + + return checksumAddress; + } + + // RSK - RSK functions - end + + // ELA - Elastos functions - begin + function displayBip44InfoForELA() { + if (!isELA()) { + return; + } + + var coin = parseIntNoNaN(DOM.bip44coin.val(), 0); + var account = parseIntNoNaN(DOM.bip44account.val(), 0); + + // Calculate the account extended keys + var accountXprv = libs.elastosjs.getAccountExtendedPrivateKey(seed, coin, account); + var accountXpub = libs.elastosjs.getAccountExtendedPublicKey(seed, coin, account); + + // Display the extended keys + DOM.bip44accountXprv.val(accountXprv); + DOM.bip44accountXpub.val(accountXpub); + } + + function displayBip32InfoForELA() { + if (!isELA()) { + return; + } + + var coin = parseIntNoNaN(DOM.bip44coin.val(), 0); + var account = parseIntNoNaN(DOM.bip44account.val(), 0); + var change = parseIntNoNaN(DOM.bip44change.val(), 0); + + DOM.extendedPrivKey.val(libs.elastosjs.getBip32ExtendedPrivateKey(seed, coin, account, change)); + DOM.extendedPubKey.val(libs.elastosjs.getBip32ExtendedPublicKey(seed, coin, account, change)); + + // Display the addresses and privkeys + clearAddressesList(); + var initialAddressCount = parseInt(DOM.rowsToAdd.val()); + displayAddresses(0, initialAddressCount); + } + + function calcAddressForELA(seed, coin, account, change, index) { + if (!isELA()) { + return; + } + + var publicKey = libs.elastosjs.getDerivedPublicKey(libs.elastosjs.getMasterPublicKey(seed), change, index); + return { + privateKey: libs.elastosjs.getDerivedPrivateKey(seed, coin, account, change, index), + publicKey: publicKey, + address: libs.elastosjs.getAddress(publicKey.toString('hex')) + }; + } + // ELA - Elastos functions - end + init(); })();