From 93c3ef47579733040dbc6eec865b528d1ca49911 Mon Sep 17 00:00:00 2001 From: Ian Coleman Date: Tue, 31 Oct 2017 11:04:38 +1100 Subject: [PATCH] Use correct prefixes for xprv/xpub with segwit --- src/js/bitcoinjs-extensions.js | 33 +++++++++++++++++ src/js/index.js | 66 ++++++++++++++++++++++++++++++++-- tests.js | 10 +++--- 3 files changed, 102 insertions(+), 7 deletions(-) diff --git a/src/js/bitcoinjs-extensions.js b/src/js/bitcoinjs-extensions.js index 4448c7f..388dd0b 100644 --- a/src/js/bitcoinjs-extensions.js +++ b/src/js/bitcoinjs-extensions.js @@ -261,3 +261,36 @@ bitcoinjs.bitcoin.networks.bitcoinCashBitbpay = { scriptHash: 0x28, wif: 0x80 }; + +bitcoinjs.bitcoin.networks.bitcoinBip49 = { + messagePrefix: '\x18Bitcoin Signed Message:\n', + bip32: { + public: 0x049d7cb2, + private: 0x049d7878 + }, + pubKeyHash: 0x00, + scriptHash: 0x05, + wif: 0x80 +}; + +bitcoinjs.bitcoin.networks.testnetBip49 = { + messagePrefix: '\x18Bitcoin Signed Message:\n', + bip32: { + public: 0x044a5262, + private: 0x044a4e28 + }, + pubKeyHash: 0x6f, + scriptHash: 0xc4, + wif: 0xef +}; + +bitcoinjs.bitcoin.networks.litecoinBip49 = { + messagePrefix: '\x19Litecoin Signed Message:\n', + bip32: { + public: 0x01b26ef6, + private: 0x01b26792 + }, + pubKeyHash: 0x30, + scriptHash: 0x32, + wif: 0xb0 +}; diff --git a/src/js/index.js b/src/js/index.js index b1559ef..b2fb17e 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -111,7 +111,7 @@ DOM.bip44change.on("input", calcForDerivationPath); DOM.bip49account.on("input", calcForDerivationPath); DOM.bip49change.on("input", calcForDerivationPath); - DOM.tab.on("shown.bs.tab", calcForDerivationPath); + DOM.tab.on("shown.bs.tab", tabChanged); DOM.hardenedAddresses.on("change", calcForDerivationPath); DOM.useP2wpkhNestedInP2sh.on("change", calcForDerivationPath); DOM.indexToggle.on("click", toggleIndexes); @@ -214,6 +214,35 @@ calcForDerivationPath(); } + function tabChanged() { + showPending(); + adjustNetworkForBip49(); + var phrase = DOM.phrase.val(); + if (phrase != "") { + // Calculate and display for mnemonic + var errorText = findPhraseErrors(phrase); + if (errorText) { + showValidationError(errorText); + return; + } + // Calculate and display + var passphrase = DOM.passphrase.val(); + calcBip32RootKeyFromSeed(phrase, passphrase); + } + else { + // Calculate and display for root key + var rootKeyBase58 = DOM.rootKey.val(); + var errorText = validateRootKey(rootKeyBase58); + if (errorText) { + showValidationError(errorText); + return; + } + // Calculate and display + calcBip32RootKeyFromBase58(rootKeyBase58); + } + calcForDerivationPath(); + } + function delayedEntropyChanged() { hideValidationError(); showPending(); @@ -644,12 +673,16 @@ })()); } + function P2wpkhNestedInP2shSelected() { + return bip49TabSelected() || (bip32TabSelected() && useP2wpkhNestedInP2sh()); + } + function TableRow(index, isLast) { var self = this; this.shouldGenerate = true; var useHardenedAddresses = DOM.hardenedAddresses.prop("checked"); - var isP2wpkhNestedInP2sh = bip49TabSelected() || (bip32TabSelected() && useP2wpkhNestedInP2sh()); + var isP2wpkhNestedInP2sh = P2wpkhNestedInP2shSelected(); var p2wpkhNestedInP2shAvailable = networkHasBip49(); function init() { @@ -1229,6 +1262,35 @@ } } + function adjustNetworkForBip49() { + // If bip49 is selected the xpub/xprv prefixes need to be adjusted + // to avoid accidentally importing BIP49 xpub to BIP44 watch only + // wallet. + // See https://github.com/iancoleman/bip39/issues/125 + if (P2wpkhNestedInP2shSelected()) { + if (network == bitcoinjs.bitcoin.networks.bitcoin) { + network = bitcoinjs.bitcoin.networks.bitcoinBip49; + } + else if (network == bitcoinjs.bitcoin.networks.testnet) { + network = bitcoinjs.bitcoin.networks.testnetBip49; + } + else if (network == bitcoinjs.bitcoin.networks.litecoin) { + network = bitcoinjs.bitcoin.networks.litecoinBip49; + } + } + else { + if (network == bitcoinjs.bitcoin.networks.bitcoinBip49) { + network = bitcoinjs.bitcoin.networks.bitcoin; + } + else if (network == bitcoinjs.bitcoin.networks.testnetBip49) { + network = bitcoinjs.bitcoin.networks.testnet; + } + else if (network == bitcoinjs.bitcoin.networks.litecoinBip49) { + network = bitcoinjs.bitcoin.networks.litecoin; + } + } + } + var networks = [ { name: "BCH - Bitcoin Cash", diff --git a/tests.js b/tests.js index c0f7df7..909868b 100644 --- a/tests.js +++ b/tests.js @@ -3690,7 +3690,7 @@ page.open(url, function(status) { }); waitForFeedback(function() { // Check feedback is correct - var expected = "No root key"; + var expected = "Invalid root key"; var actual = page.evaluate(function() { return $(".feedback").text(); }); @@ -3997,7 +3997,7 @@ page.open(url, function(status) { function() { page.open(url, function(status) { // set the phrase - var expected = "xprvA1hukYsW7QfX9CVsaDAKde4eryajKa4DKWb6m9YjSnqkiZHrahFwwTJfEQTwBQ5kptWT5pZMkkusT1oK8dc1efQ8VFfq4SLSPAWd7Cpt423"; + var expected = "yprvALYB4DYRG6CzzVgzQZwwqjAA2wjBGC3iEd7KYYScpoDdmf75qMRWZWxoFcRXBJjgEXdFqJ9vDRGRLJQsrL22Su5jMbNFeM9vetaGVqy9Qy2"; page.evaluate(function() { $("#bip49-tab a").click(); $(".phrase").val("abandon abandon ability").trigger("input"); @@ -4022,7 +4022,7 @@ page.open(url, function(status) { function() { page.open(url, function(status) { // set the phrase - var expected = "xpub6EhGA4QPwnDpMgaLgEhKzn1PR1RDj2n4gjWhZXxM18NjbMd18EaCVFd95gkLARJaBD2rXAYJED2gdkUbGn1KkrSzCKR554AdABUELoainnt"; + var expected = "ypub6ZXXTj5K6TmJCymTWbUxCs6tayZffemZbr2vLvrEP8kceTSENtjm7KHH6thvAKxVar9fGe8rgsPEX369zURLZ68b4f7Vexz7RuXsjQ69YDt"; page.evaluate(function() { $("#bip49-tab a").click(); $(".phrase").val("abandon abandon ability").trigger("input"); @@ -4111,7 +4111,7 @@ page.open(url, function(status) { function() { page.open(url, function(status) { // set the phrase - var expected = "xprv9y3uhgQbfQZbj3o98nfgLDwGGuCJjUn7GKArSAZXjKgMjSdYHjQmTyf78s22g6jsGrxXvHB6HJeFyvFSPkuYZajeTGMZVXV6aNLWw2fagCn"; + var expected = "yprvAHtB1M5Wp675aLzFy9TJYK2mSsLkg6mcBRh5DZTR7L4EnYSmYPaL63KFA4ycg1PngW5LfkmejxzosCs17TKZMpRFKc3z5SJar6QAKaFcaZL"; page.evaluate(function() { $("#bip49-tab a").click(); $(".phrase").val("abandon abandon ability"); @@ -4137,7 +4137,7 @@ page.open(url, function(status) { function() { page.open(url, function(status) { // set the phrase - var expected = "xpub6C3G7BwVVn7twXscEpCghMszpw2o8wVxdY6TEYy9HfDLcExgqGj21myazAiq6HSmW2F1cBiFqJa3D1cqcDpSh8pbZF5x4iqpd4PyJvd3gjB"; + var expected = "ypub6WsXQrcQeTfNnq4j5AzJuSyVzuBF5ZVTYecg1ws2ffbDfLmv5vtadqdj1NgR6C6gufMpMfJpHxvb6JEQKvETVNWCRanNedfJtnTchZiJtsL"; page.evaluate(function() { $("#bip49-tab a").click(); $(".phrase").val("abandon abandon ability"); -- 2.41.0