diff options
author | Ian Coleman <coleman.ian@gmail.com> | 2017-10-31 11:04:38 +1100 |
---|---|---|
committer | Ian Coleman <coleman.ian@gmail.com> | 2017-10-31 11:44:42 +1100 |
commit | 93c3ef47579733040dbc6eec865b528d1ca49911 (patch) | |
tree | a81eb6e44be20c15de4c4fe1c5819e060b4f4a86 | |
parent | fe8f2d140d9c9e260ebeab7135aa5197b27df406 (diff) | |
download | BIP39-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.js | 33 | ||||
-rw-r--r-- | src/js/index.js | 66 | ||||
-rw-r--r-- | 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 = { | |||
261 | scriptHash: 0x28, | 261 | scriptHash: 0x28, |
262 | wif: 0x80 | 262 | wif: 0x80 |
263 | }; | 263 | }; |
264 | |||
265 | bitcoinjs.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 | |||
276 | bitcoinjs.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 | |||
287 | bitcoinjs.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", |
@@ -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) { | |||
3997 | function() { | 3997 | function() { |
3998 | page.open(url, function(status) { | 3998 | page.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) { | |||
4022 | function() { | 4022 | function() { |
4023 | page.open(url, function(status) { | 4023 | page.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) { | |||
4111 | function() { | 4111 | function() { |
4112 | page.open(url, function(status) { | 4112 | page.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) { | |||
4137 | function() { | 4137 | function() { |
4138 | page.open(url, function(status) { | 4138 | page.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"); |