aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Coleman <coleman.ian@gmail.com>2017-10-31 11:04:38 +1100
committerIan Coleman <coleman.ian@gmail.com>2017-10-31 11:44:42 +1100
commit93c3ef47579733040dbc6eec865b528d1ca49911 (patch)
treea81eb6e44be20c15de4c4fe1c5819e060b4f4a86
parentfe8f2d140d9c9e260ebeab7135aa5197b27df406 (diff)
downloadBIP39-93c3ef47579733040dbc6eec865b528d1ca49911.tar.gz
BIP39-93c3ef47579733040dbc6eec865b528d1ca49911.tar.zst
BIP39-93c3ef47579733040dbc6eec865b528d1ca49911.zip
Use correct prefixes for xprv/xpub with segwit
-rw-r--r--src/js/bitcoinjs-extensions.js33
-rw-r--r--src/js/index.js66
-rw-r--r--tests.js10
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 = {
261 scriptHash: 0x28, 261 scriptHash: 0x28,
262 wif: 0x80 262 wif: 0x80
263}; 263};
264
265bitcoinjs.bitcoin.networks.bitcoinBip49 = {
266 messagePrefix: '\x18Bitcoin Signed Message:\n',
267 bip32: {
268 public: 0x049d7cb2,
269 private: 0x049d7878
270 },
271 pubKeyHash: 0x00,
272 scriptHash: 0x05,
273 wif: 0x80
274};
275
276bitcoinjs.bitcoin.networks.testnetBip49 = {
277 messagePrefix: '\x18Bitcoin Signed Message:\n',
278 bip32: {
279 public: 0x044a5262,
280 private: 0x044a4e28
281 },
282 pubKeyHash: 0x6f,
283 scriptHash: 0xc4,
284 wif: 0xef
285};
286
287bitcoinjs.bitcoin.networks.litecoinBip49 = {
288 messagePrefix: '\x19Litecoin Signed Message:\n',
289 bip32: {
290 public: 0x01b26ef6,
291 private: 0x01b26792
292 },
293 pubKeyHash: 0x30,
294 scriptHash: 0x32,
295 wif: 0xb0
296};
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 @@
111 DOM.bip44change.on("input", calcForDerivationPath); 111 DOM.bip44change.on("input", calcForDerivationPath);
112 DOM.bip49account.on("input", calcForDerivationPath); 112 DOM.bip49account.on("input", calcForDerivationPath);
113 DOM.bip49change.on("input", calcForDerivationPath); 113 DOM.bip49change.on("input", calcForDerivationPath);
114 DOM.tab.on("shown.bs.tab", calcForDerivationPath); 114 DOM.tab.on("shown.bs.tab", tabChanged);
115 DOM.hardenedAddresses.on("change", calcForDerivationPath); 115 DOM.hardenedAddresses.on("change", calcForDerivationPath);
116 DOM.useP2wpkhNestedInP2sh.on("change", calcForDerivationPath); 116 DOM.useP2wpkhNestedInP2sh.on("change", calcForDerivationPath);
117 DOM.indexToggle.on("click", toggleIndexes); 117 DOM.indexToggle.on("click", toggleIndexes);
@@ -214,6 +214,35 @@
214 calcForDerivationPath(); 214 calcForDerivationPath();
215 } 215 }
216 216
217 function tabChanged() {
218 showPending();
219 adjustNetworkForBip49();
220 var phrase = DOM.phrase.val();
221 if (phrase != "") {
222 // Calculate and display for mnemonic
223 var errorText = findPhraseErrors(phrase);
224 if (errorText) {
225 showValidationError(errorText);
226 return;
227 }
228 // Calculate and display
229 var passphrase = DOM.passphrase.val();
230 calcBip32RootKeyFromSeed(phrase, passphrase);
231 }
232 else {
233 // Calculate and display for root key
234 var rootKeyBase58 = DOM.rootKey.val();
235 var errorText = validateRootKey(rootKeyBase58);
236 if (errorText) {
237 showValidationError(errorText);
238 return;
239 }
240 // Calculate and display
241 calcBip32RootKeyFromBase58(rootKeyBase58);
242 }
243 calcForDerivationPath();
244 }
245
217 function delayedEntropyChanged() { 246 function delayedEntropyChanged() {
218 hideValidationError(); 247 hideValidationError();
219 showPending(); 248 showPending();
@@ -644,12 +673,16 @@
644 })()); 673 })());
645 } 674 }
646 675
676 function P2wpkhNestedInP2shSelected() {
677 return bip49TabSelected() || (bip32TabSelected() && useP2wpkhNestedInP2sh());
678 }
679
647 function TableRow(index, isLast) { 680 function TableRow(index, isLast) {
648 681
649 var self = this; 682 var self = this;
650 this.shouldGenerate = true; 683 this.shouldGenerate = true;
651 var useHardenedAddresses = DOM.hardenedAddresses.prop("checked"); 684 var useHardenedAddresses = DOM.hardenedAddresses.prop("checked");
652 var isP2wpkhNestedInP2sh = bip49TabSelected() || (bip32TabSelected() && useP2wpkhNestedInP2sh()); 685 var isP2wpkhNestedInP2sh = P2wpkhNestedInP2shSelected();
653 var p2wpkhNestedInP2shAvailable = networkHasBip49(); 686 var p2wpkhNestedInP2shAvailable = networkHasBip49();
654 687
655 function init() { 688 function init() {
@@ -1229,6 +1262,35 @@
1229 } 1262 }
1230 } 1263 }
1231 1264
1265 function adjustNetworkForBip49() {
1266 // If bip49 is selected the xpub/xprv prefixes need to be adjusted
1267 // to avoid accidentally importing BIP49 xpub to BIP44 watch only
1268 // wallet.
1269 // See https://github.com/iancoleman/bip39/issues/125
1270 if (P2wpkhNestedInP2shSelected()) {
1271 if (network == bitcoinjs.bitcoin.networks.bitcoin) {
1272 network = bitcoinjs.bitcoin.networks.bitcoinBip49;
1273 }
1274 else if (network == bitcoinjs.bitcoin.networks.testnet) {
1275 network = bitcoinjs.bitcoin.networks.testnetBip49;
1276 }
1277 else if (network == bitcoinjs.bitcoin.networks.litecoin) {
1278 network = bitcoinjs.bitcoin.networks.litecoinBip49;
1279 }
1280 }
1281 else {
1282 if (network == bitcoinjs.bitcoin.networks.bitcoinBip49) {
1283 network = bitcoinjs.bitcoin.networks.bitcoin;
1284 }
1285 else if (network == bitcoinjs.bitcoin.networks.testnetBip49) {
1286 network = bitcoinjs.bitcoin.networks.testnet;
1287 }
1288 else if (network == bitcoinjs.bitcoin.networks.litecoinBip49) {
1289 network = bitcoinjs.bitcoin.networks.litecoin;
1290 }
1291 }
1292 }
1293
1232 var networks = [ 1294 var networks = [
1233 { 1295 {
1234 name: "BCH - Bitcoin Cash", 1296 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) {
3690 }); 3690 });
3691 waitForFeedback(function() { 3691 waitForFeedback(function() {
3692 // Check feedback is correct 3692 // Check feedback is correct
3693 var expected = "No root key"; 3693 var expected = "Invalid root key";
3694 var actual = page.evaluate(function() { 3694 var actual = page.evaluate(function() {
3695 return $(".feedback").text(); 3695 return $(".feedback").text();
3696 }); 3696 });
@@ -3997,7 +3997,7 @@ page.open(url, function(status) {
3997function() { 3997function() {
3998page.open(url, function(status) { 3998page.open(url, function(status) {
3999 // set the phrase 3999 // set the phrase
4000 var expected = "xprvA1hukYsW7QfX9CVsaDAKde4eryajKa4DKWb6m9YjSnqkiZHrahFwwTJfEQTwBQ5kptWT5pZMkkusT1oK8dc1efQ8VFfq4SLSPAWd7Cpt423"; 4000 var expected = "yprvALYB4DYRG6CzzVgzQZwwqjAA2wjBGC3iEd7KYYScpoDdmf75qMRWZWxoFcRXBJjgEXdFqJ9vDRGRLJQsrL22Su5jMbNFeM9vetaGVqy9Qy2";
4001 page.evaluate(function() { 4001 page.evaluate(function() {
4002 $("#bip49-tab a").click(); 4002 $("#bip49-tab a").click();
4003 $(".phrase").val("abandon abandon ability").trigger("input"); 4003 $(".phrase").val("abandon abandon ability").trigger("input");
@@ -4022,7 +4022,7 @@ page.open(url, function(status) {
4022function() { 4022function() {
4023page.open(url, function(status) { 4023page.open(url, function(status) {
4024 // set the phrase 4024 // set the phrase
4025 var expected = "xpub6EhGA4QPwnDpMgaLgEhKzn1PR1RDj2n4gjWhZXxM18NjbMd18EaCVFd95gkLARJaBD2rXAYJED2gdkUbGn1KkrSzCKR554AdABUELoainnt"; 4025 var expected = "ypub6ZXXTj5K6TmJCymTWbUxCs6tayZffemZbr2vLvrEP8kceTSENtjm7KHH6thvAKxVar9fGe8rgsPEX369zURLZ68b4f7Vexz7RuXsjQ69YDt";
4026 page.evaluate(function() { 4026 page.evaluate(function() {
4027 $("#bip49-tab a").click(); 4027 $("#bip49-tab a").click();
4028 $(".phrase").val("abandon abandon ability").trigger("input"); 4028 $(".phrase").val("abandon abandon ability").trigger("input");
@@ -4111,7 +4111,7 @@ page.open(url, function(status) {
4111function() { 4111function() {
4112page.open(url, function(status) { 4112page.open(url, function(status) {
4113 // set the phrase 4113 // set the phrase
4114 var expected = "xprv9y3uhgQbfQZbj3o98nfgLDwGGuCJjUn7GKArSAZXjKgMjSdYHjQmTyf78s22g6jsGrxXvHB6HJeFyvFSPkuYZajeTGMZVXV6aNLWw2fagCn"; 4114 var expected = "yprvAHtB1M5Wp675aLzFy9TJYK2mSsLkg6mcBRh5DZTR7L4EnYSmYPaL63KFA4ycg1PngW5LfkmejxzosCs17TKZMpRFKc3z5SJar6QAKaFcaZL";
4115 page.evaluate(function() { 4115 page.evaluate(function() {
4116 $("#bip49-tab a").click(); 4116 $("#bip49-tab a").click();
4117 $(".phrase").val("abandon abandon ability"); 4117 $(".phrase").val("abandon abandon ability");
@@ -4137,7 +4137,7 @@ page.open(url, function(status) {
4137function() { 4137function() {
4138page.open(url, function(status) { 4138page.open(url, function(status) {
4139 // set the phrase 4139 // set the phrase
4140 var expected = "xpub6C3G7BwVVn7twXscEpCghMszpw2o8wVxdY6TEYy9HfDLcExgqGj21myazAiq6HSmW2F1cBiFqJa3D1cqcDpSh8pbZF5x4iqpd4PyJvd3gjB"; 4140 var expected = "ypub6WsXQrcQeTfNnq4j5AzJuSyVzuBF5ZVTYecg1ws2ffbDfLmv5vtadqdj1NgR6C6gufMpMfJpHxvb6JEQKvETVNWCRanNedfJtnTchZiJtsL";
4141 page.evaluate(function() { 4141 page.evaluate(function() {
4142 $("#bip49-tab a").click(); 4142 $("#bip49-tab a").click();
4143 $(".phrase").val("abandon abandon ability"); 4143 $(".phrase").val("abandon abandon ability");