aboutsummaryrefslogtreecommitdiff
path: root/src/js
diff options
context:
space:
mode:
authorIan Coleman <ian@iancoleman.io>2017-11-22 12:11:48 +1100
committerIan Coleman <ian@iancoleman.io>2017-11-22 13:03:47 +1100
commitc49e881294343b762109bb8104e7c1b45898c894 (patch)
treed5977e411ccc4351de1384b611c05ef1a428c213 /src/js
parent0fd67b5915a08168d31caaa581f55cf86591be73 (diff)
downloadBIP39-c49e881294343b762109bb8104e7c1b45898c894.tar.gz
BIP39-c49e881294343b762109bb8104e7c1b45898c894.tar.zst
BIP39-c49e881294343b762109bb8104e7c1b45898c894.zip
Add BIP141 tab for full segwit compatibility
Diffstat (limited to 'src/js')
-rw-r--r--src/js/bitcoinjs-extensions.js33
-rw-r--r--src/js/index.js88
-rw-r--r--src/js/segwit-parameters.js58
3 files changed, 117 insertions, 62 deletions
diff --git a/src/js/bitcoinjs-extensions.js b/src/js/bitcoinjs-extensions.js
index 63f7c6e..1509a6c 100644
--- a/src/js/bitcoinjs-extensions.js
+++ b/src/js/bitcoinjs-extensions.js
@@ -284,39 +284,6 @@ bitcoinjs.bitcoin.networks.monacoin = {
284 wif: 0xb0 284 wif: 0xb0
285}; 285};
286 286
287bitcoinjs.bitcoin.networks.bitcoinBip49 = {
288 messagePrefix: '\x18Bitcoin Signed Message:\n',
289 bip32: {
290 public: 0x049d7cb2,
291 private: 0x049d7878
292 },
293 pubKeyHash: 0x00,
294 scriptHash: 0x05,
295 wif: 0x80
296};
297
298bitcoinjs.bitcoin.networks.testnetBip49 = {
299 messagePrefix: '\x18Bitcoin Signed Message:\n',
300 bip32: {
301 public: 0x044a5262,
302 private: 0x044a4e28
303 },
304 pubKeyHash: 0x6f,
305 scriptHash: 0xc4,
306 wif: 0xef
307};
308
309bitcoinjs.bitcoin.networks.litecoinBip49 = {
310 messagePrefix: '\x19Litecoin Signed Message:\n',
311 bip32: {
312 public: 0x01b26ef6,
313 private: 0x01b26792
314 },
315 pubKeyHash: 0x30,
316 scriptHash: 0x32,
317 wif: 0xb0
318};
319
320bitcoinjs.bitcoin.networks.litecoinXprv = { 287bitcoinjs.bitcoin.networks.litecoinXprv = {
321 messagePrefix: '\x19Litecoin Signed Message:\n', 288 messagePrefix: '\x19Litecoin Signed Message:\n',
322 bip32: { 289 bip32: {
diff --git a/src/js/index.js b/src/js/index.js
index b88e9d7..261a6d1 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -52,6 +52,7 @@
52 DOM.bip32tab = $("#bip32-tab"); 52 DOM.bip32tab = $("#bip32-tab");
53 DOM.bip44tab = $("#bip44-tab"); 53 DOM.bip44tab = $("#bip44-tab");
54 DOM.bip49tab = $("#bip49-tab"); 54 DOM.bip49tab = $("#bip49-tab");
55 DOM.bip141tab = $("#bip141-tab");
55 DOM.bip32panel = $("#bip32"); 56 DOM.bip32panel = $("#bip32");
56 DOM.bip44panel = $("#bip44"); 57 DOM.bip44panel = $("#bip44");
57 DOM.bip49panel = $("#bip49"); 58 DOM.bip49panel = $("#bip49");
@@ -72,6 +73,10 @@
72 DOM.bip49accountXprv = $("#bip49 .account-xprv"); 73 DOM.bip49accountXprv = $("#bip49 .account-xprv");
73 DOM.bip49accountXpub = $("#bip49 .account-xpub"); 74 DOM.bip49accountXpub = $("#bip49 .account-xpub");
74 DOM.bip49change = $("#bip49 .change"); 75 DOM.bip49change = $("#bip49 .change");
76 DOM.bip141unavailable = $("#bip141 .unavailable");
77 DOM.bip141available = $("#bip141 .available");
78 DOM.bip141path = $("#bip141-path");
79 DOM.bip141semantics = $(".bip141-semantics");
75 DOM.generatedStrength = $(".generate-container .strength"); 80 DOM.generatedStrength = $(".generate-container .strength");
76 DOM.hardenedAddresses = $(".hardened-addresses"); 81 DOM.hardenedAddresses = $(".hardened-addresses");
77 DOM.useBitpayAddressesContainer = $(".use-bitpay-addresses-container"); 82 DOM.useBitpayAddressesContainer = $(".use-bitpay-addresses-container");
@@ -111,6 +116,8 @@
111 DOM.bip44change.on("input", calcForDerivationPath); 116 DOM.bip44change.on("input", calcForDerivationPath);
112 DOM.bip49account.on("input", calcForDerivationPath); 117 DOM.bip49account.on("input", calcForDerivationPath);
113 DOM.bip49change.on("input", calcForDerivationPath); 118 DOM.bip49change.on("input", calcForDerivationPath);
119 DOM.bip141path.on("input", calcForDerivationPath);
120 DOM.bip141semantics.on("change", tabChanged);
114 DOM.tab.on("shown.bs.tab", tabChanged); 121 DOM.tab.on("shown.bs.tab", tabChanged);
115 DOM.hardenedAddresses.on("change", calcForDerivationPath); 122 DOM.hardenedAddresses.on("change", calcForDerivationPath);
116 DOM.indexToggle.on("click", toggleIndexes); 123 DOM.indexToggle.on("click", toggleIndexes);
@@ -138,6 +145,7 @@
138 var network = networks[networkIndex]; 145 var network = networks[networkIndex];
139 network.onSelect(); 146 network.onSelect();
140 if (network.segwitAvailable) { 147 if (network.segwitAvailable) {
148 adjustNetworkForSegwit();
141 showSegwitAvailable(); 149 showSegwitAvailable();
142 } 150 }
143 else { 151 else {
@@ -343,7 +351,7 @@
343 if (bip44TabSelected()) { 351 if (bip44TabSelected()) {
344 displayBip44Info(); 352 displayBip44Info();
345 } 353 }
346 if (bip49TabSelected()) { 354 else if (bip49TabSelected()) {
347 displayBip49Info(); 355 displayBip49Info();
348 } 356 }
349 displayBip32Info(); 357 displayBip32Info();
@@ -523,7 +531,7 @@
523 console.log("Using derivation path from BIP44 tab: " + derivationPath); 531 console.log("Using derivation path from BIP44 tab: " + derivationPath);
524 return derivationPath; 532 return derivationPath;
525 } 533 }
526 if (bip49TabSelected()) { 534 else if (bip49TabSelected()) {
527 var purpose = parseIntNoNaN(DOM.bip49purpose.val(), 49); 535 var purpose = parseIntNoNaN(DOM.bip49purpose.val(), 49);
528 var coin = parseIntNoNaN(DOM.bip49coin.val(), 0); 536 var coin = parseIntNoNaN(DOM.bip49coin.val(), 0);
529 var account = parseIntNoNaN(DOM.bip49account.val(), 0); 537 var account = parseIntNoNaN(DOM.bip49account.val(), 0);
@@ -543,6 +551,11 @@
543 console.log("Using derivation path from BIP32 tab: " + derivationPath); 551 console.log("Using derivation path from BIP32 tab: " + derivationPath);
544 return derivationPath; 552 return derivationPath;
545 } 553 }
554 else if (bip141TabSelected()) {
555 var derivationPath = DOM.bip141path.val();
556 console.log("Using derivation path from BIP141 tab: " + derivationPath);
557 return derivationPath;
558 }
546 else { 559 else {
547 console.log("Unknown derivation path"); 560 console.log("Unknown derivation path");
548 } 561 }
@@ -673,7 +686,16 @@
673 } 686 }
674 687
675 function segwitSelected() { 688 function segwitSelected() {
676 return bip49TabSelected(); 689 return bip49TabSelected() || bip141TabSelected();
690 }
691
692 function p2wpkhSelected() {
693 return bip141TabSelected() && DOM.bip141semantics.val() == "p2wpkh";
694 }
695
696 function p2wpkhInP2shSelected() {
697 return bip49TabSelected() ||
698 (bip141TabSelected() && DOM.bip141semantics.val() == "p2wpkh-p2sh");
677 } 699 }
678 700
679 function TableRow(index, isLast) { 701 function TableRow(index, isLast) {
@@ -683,6 +705,8 @@
683 var useHardenedAddresses = DOM.hardenedAddresses.prop("checked"); 705 var useHardenedAddresses = DOM.hardenedAddresses.prop("checked");
684 var isSegwit = segwitSelected(); 706 var isSegwit = segwitSelected();
685 var segwitAvailable = networkHasSegwit(); 707 var segwitAvailable = networkHasSegwit();
708 var isP2wpkh = p2wpkhSelected();
709 var isP2wpkhInP2sh = p2wpkhInP2shSelected();
686 710
687 function init() { 711 function init() {
688 calculateValues(); 712 calculateValues();
@@ -731,11 +755,18 @@
731 if (!segwitAvailable) { 755 if (!segwitAvailable) {
732 return; 756 return;
733 } 757 }
734 var keyhash = bitcoinjs.bitcoin.crypto.hash160(key.getPublicKeyBuffer()); 758 if (isP2wpkh) {
735 var scriptsig = bitcoinjs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash); 759 var keyhash = bitcoinjs.bitcoin.crypto.hash160(key.getPublicKeyBuffer());
736 var addressbytes = bitcoinjs.bitcoin.crypto.hash160(scriptsig); 760 var scriptpubkey = bitcoinjs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash);
737 var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes); 761 address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network)
738 address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network) 762 }
763 else if (isP2wpkhInP2sh) {
764 var keyhash = bitcoinjs.bitcoin.crypto.hash160(key.getPublicKeyBuffer());
765 var scriptsig = bitcoinjs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash);
766 var addressbytes = bitcoinjs.bitcoin.crypto.hash160(scriptsig);
767 var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes);
768 address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network)
769 }
739 } 770 }
740 addAddressToList(indexText, address, pubkey, privkey); 771 addAddressToList(indexText, address, pubkey, privkey);
741 if (isLast) { 772 if (isLast) {
@@ -1233,6 +1264,10 @@
1233 return DOM.bip49tab.hasClass("active"); 1264 return DOM.bip49tab.hasClass("active");
1234 } 1265 }
1235 1266
1267 function bip141TabSelected() {
1268 return DOM.bip141tab.hasClass("active");
1269 }
1270
1236 function setHdCoin(coinValue) { 1271 function setHdCoin(coinValue) {
1237 DOM.bip44coin.val(coinValue); 1272 DOM.bip44coin.val(coinValue);
1238 DOM.bip49coin.val(coinValue); 1273 DOM.bip49coin.val(coinValue);
@@ -1241,11 +1276,15 @@
1241 function showSegwitAvailable() { 1276 function showSegwitAvailable() {
1242 DOM.bip49unavailable.addClass("hidden"); 1277 DOM.bip49unavailable.addClass("hidden");
1243 DOM.bip49available.removeClass("hidden"); 1278 DOM.bip49available.removeClass("hidden");
1279 DOM.bip141unavailable.addClass("hidden");
1280 DOM.bip141available.removeClass("hidden");
1244 } 1281 }
1245 1282
1246 function showSegwitUnavailable() { 1283 function showSegwitUnavailable() {
1247 DOM.bip49available.addClass("hidden"); 1284 DOM.bip49available.addClass("hidden");
1248 DOM.bip49unavailable.removeClass("hidden"); 1285 DOM.bip49unavailable.removeClass("hidden");
1286 DOM.bip141available.addClass("hidden");
1287 DOM.bip141unavailable.removeClass("hidden");
1249 } 1288 }
1250 1289
1251 function useBitpayAddresses() { 1290 function useBitpayAddresses() {
@@ -1266,27 +1305,18 @@
1266 // to avoid accidentally importing BIP49 xpub to BIP44 watch only 1305 // to avoid accidentally importing BIP49 xpub to BIP44 watch only
1267 // wallet. 1306 // wallet.
1268 // See https://github.com/iancoleman/bip39/issues/125 1307 // See https://github.com/iancoleman/bip39/issues/125
1269 if (segwitSelected()) { 1308 var segwitNetworks = null;
1270 if (network == bitcoinjs.bitcoin.networks.bitcoin) { 1309 // if a segwit network is alread selected, need to use base network to
1271 network = bitcoinjs.bitcoin.networks.bitcoinBip49; 1310 // look up new parameters
1272 } 1311 if ("baseNetwork" in network) {
1273 else if (network == bitcoinjs.bitcoin.networks.testnet) { 1312 network = bitcoinjs.bitcoin.networks[network.baseNetwork];
1274 network = bitcoinjs.bitcoin.networks.testnetBip49; 1313 }
1275 } 1314 // choose the right segwit params
1276 else if (network == bitcoinjs.bitcoin.networks.litecoin) { 1315 if (p2wpkhSelected() && "p2wpkh" in network) {
1277 network = bitcoinjs.bitcoin.networks.litecoinBip49; 1316 network = network.p2wpkh;
1278 } 1317 }
1279 } 1318 else if (p2wpkhInP2shSelected() && "p2wpkhInP2sh" in network) {
1280 else { 1319 network = network.p2wpkhInP2sh;
1281 if (network == bitcoinjs.bitcoin.networks.bitcoinBip49) {
1282 network = bitcoinjs.bitcoin.networks.bitcoin;
1283 }
1284 else if (network == bitcoinjs.bitcoin.networks.testnetBip49) {
1285 network = bitcoinjs.bitcoin.networks.testnet;
1286 }
1287 else if (network == bitcoinjs.bitcoin.networks.litecoinBip49) {
1288 network = bitcoinjs.bitcoin.networks.litecoin;
1289 }
1290 } 1320 }
1291 } 1321 }
1292 1322
diff --git a/src/js/segwit-parameters.js b/src/js/segwit-parameters.js
new file mode 100644
index 0000000..38cf9e0
--- /dev/null
+++ b/src/js/segwit-parameters.js
@@ -0,0 +1,58 @@
1(function() {
2
3// p2wpkh
4
5bitcoinjs.bitcoin.networks.bitcoin.p2wpkh = {
6 baseNetwork: "bitcoin",
7 messagePrefix: '\x18Bitcoin Signed Message:\n',
8 bech32: 'bc',
9 bip32: {
10 public: 0x04b24746,
11 private: 0x04b2430c
12 },
13 pubKeyHash: 0x00,
14 scriptHash: 0x05,
15 wif: 0x80
16};
17
18// p2wpkh in p2sh
19
20bitcoinjs.bitcoin.networks.bitcoin.p2wpkhInP2sh = {
21 baseNetwork: "bitcoin",
22 messagePrefix: '\x18Bitcoin Signed Message:\n',
23 bech32: 'bc',
24 bip32: {
25 public: 0x049d7cb2,
26 private: 0x049d7878
27 },
28 pubKeyHash: 0x00,
29 scriptHash: 0x05,
30 wif: 0x80
31};
32
33bitcoinjs.bitcoin.networks.testnet.p2wpkhInP2sh = {
34 baseNetwork: "testnet",
35 messagePrefix: '\x18Bitcoin Signed Message:\n',
36 bech32: 'tb',
37 bip32: {
38 public: 0x044a5262,
39 private: 0x044a4e28
40 },
41 pubKeyHash: 0x6f,
42 scriptHash: 0xc4,
43 wif: 0xef
44};
45
46bitcoinjs.bitcoin.networks.litecoin.p2wpkhInP2sh = {
47 baseNetwork: "litecoin",
48 messagePrefix: '\x19Litecoin Signed Message:\n',
49 bip32: {
50 public: 0x01b26ef6,
51 private: 0x01b26792
52 },
53 pubKeyHash: 0x30,
54 scriptHash: 0x32,
55 wif: 0xb0
56};
57
58})();