diff options
-rw-r--r-- | src/index.html | 2 | ||||
-rw-r--r-- | src/js/index.js | 56 | ||||
-rw-r--r-- | src/js/segwit-parameters.js | 56 | ||||
-rw-r--r-- | tests/spec/tests.js | 96 |
4 files changed, 210 insertions, 0 deletions
diff --git a/src/index.html b/src/index.html index 36e238f..61fe022 100644 --- a/src/index.html +++ b/src/index.html | |||
@@ -509,6 +509,8 @@ | |||
509 | <select class="form-control bip141-semantics"> | 509 | <select class="form-control bip141-semantics"> |
510 | <option value="p2wpkh">P2WPKH</option> | 510 | <option value="p2wpkh">P2WPKH</option> |
511 | <option value="p2wpkh-p2sh" selected>P2WPKH nested in P2SH</option> | 511 | <option value="p2wpkh-p2sh" selected>P2WPKH nested in P2SH</option> |
512 | <option value="p2wsh">P2WSH</option> | ||
513 | <option value="p2wsh-p2sh">P2WSH nested in P2SH</option> | ||
512 | </select> | 514 | </select> |
513 | </div> | 515 | </div> |
514 | </div> | 516 | </div> |
diff --git a/src/js/index.js b/src/js/index.js index 0b34ade..db47412 100644 --- a/src/js/index.js +++ b/src/js/index.js | |||
@@ -539,6 +539,22 @@ | |||
539 | } | 539 | } |
540 | catch (e) {} | 540 | catch (e) {} |
541 | } | 541 | } |
542 | // try parsing using p2wsh network params | ||
543 | if ("p2wsh" in n) { | ||
544 | try { | ||
545 | bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wsh); | ||
546 | return; | ||
547 | } | ||
548 | catch (e) {} | ||
549 | } | ||
550 | // try parsing using p2wsh-in-p2sh network params | ||
551 | if ("p2wshInP2sh" in n) { | ||
552 | try { | ||
553 | bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wshInP2sh); | ||
554 | return; | ||
555 | } | ||
556 | catch (e) {} | ||
557 | } | ||
542 | } | 558 | } |
543 | // try the network params as currently specified | 559 | // try the network params as currently specified |
544 | bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, network); | 560 | bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, network); |
@@ -681,6 +697,22 @@ | |||
681 | } | 697 | } |
682 | catch (e) {} | 698 | catch (e) {} |
683 | } | 699 | } |
700 | // try parsing using p2wsh network params | ||
701 | if ("p2wsh" in n) { | ||
702 | try { | ||
703 | bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wsh); | ||
704 | return ""; | ||
705 | } | ||
706 | catch (e) {} | ||
707 | } | ||
708 | // try parsing using p2wsh-in-p2sh network params | ||
709 | if ("p2wshInP2sh" in n) { | ||
710 | try { | ||
711 | bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wshInP2sh); | ||
712 | return ""; | ||
713 | } | ||
714 | catch (e) {} | ||
715 | } | ||
684 | } | 716 | } |
685 | // try the network params as currently specified | 717 | // try the network params as currently specified |
686 | try { | 718 | try { |
@@ -968,6 +1000,14 @@ | |||
968 | (bip141TabSelected() && DOM.bip141semantics.val() == "p2wpkh-p2sh"); | 1000 | (bip141TabSelected() && DOM.bip141semantics.val() == "p2wpkh-p2sh"); |
969 | } | 1001 | } |
970 | 1002 | ||
1003 | function p2wshSelected() { | ||
1004 | return bip141TabSelected() && DOM.bip141semantics.val() == "p2wsh"; | ||
1005 | } | ||
1006 | |||
1007 | function p2wshInP2shSelected() { | ||
1008 | return (bip141TabSelected() && DOM.bip141semantics.val() == "p2wsh-p2sh"); | ||
1009 | } | ||
1010 | |||
971 | function TableRow(index, isLast) { | 1011 | function TableRow(index, isLast) { |
972 | 1012 | ||
973 | var self = this; | 1013 | var self = this; |
@@ -979,6 +1019,8 @@ | |||
979 | var segwitAvailable = networkHasSegwit(); | 1019 | var segwitAvailable = networkHasSegwit(); |
980 | var isP2wpkh = p2wpkhSelected(); | 1020 | var isP2wpkh = p2wpkhSelected(); |
981 | var isP2wpkhInP2sh = p2wpkhInP2shSelected(); | 1021 | var isP2wpkhInP2sh = p2wpkhInP2shSelected(); |
1022 | var isP2wsh = p2wshSelected(); | ||
1023 | var isP2wshInP2sh = p2wshInP2shSelected(); | ||
982 | 1024 | ||
983 | function init() { | 1025 | function init() { |
984 | calculateValues(); | 1026 | calculateValues(); |
@@ -1109,6 +1151,14 @@ | |||
1109 | var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes); | 1151 | var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes); |
1110 | address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network) | 1152 | address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network) |
1111 | } | 1153 | } |
1154 | else if (isP2wsh) { | ||
1155 | // TODO | ||
1156 | address = ""; | ||
1157 | } | ||
1158 | else if (isP2wshInP2sh) { | ||
1159 | // TODO | ||
1160 | address = ""; | ||
1161 | } | ||
1112 | } | 1162 | } |
1113 | 1163 | ||
1114 | if ((networks[DOM.network.val()].name == "CRW - Crown")) { | 1164 | if ((networks[DOM.network.val()].name == "CRW - Crown")) { |
@@ -1794,6 +1844,12 @@ | |||
1794 | else if (p2wpkhInP2shSelected() && "p2wpkhInP2sh" in network) { | 1844 | else if (p2wpkhInP2shSelected() && "p2wpkhInP2sh" in network) { |
1795 | network = network.p2wpkhInP2sh; | 1845 | network = network.p2wpkhInP2sh; |
1796 | } | 1846 | } |
1847 | else if (p2wshSelected() && "p2wsh" in network) { | ||
1848 | network = network.p2wsh; | ||
1849 | } | ||
1850 | else if (p2wshInP2shSelected() && "p2wshInP2sh" in network) { | ||
1851 | network = network.p2wshInP2sh; | ||
1852 | } | ||
1797 | } | 1853 | } |
1798 | 1854 | ||
1799 | function lastIndexInTable() { | 1855 | function lastIndexInTable() { |
diff --git a/src/js/segwit-parameters.js b/src/js/segwit-parameters.js index de4d634..83d49da 100644 --- a/src/js/segwit-parameters.js +++ b/src/js/segwit-parameters.js | |||
@@ -56,6 +56,62 @@ bitcoinjs.bitcoin.networks.testnet.p2wpkhInP2sh = { | |||
56 | wif: 0xef | 56 | wif: 0xef |
57 | }; | 57 | }; |
58 | 58 | ||
59 | // p2wsh | ||
60 | |||
61 | bitcoinjs.bitcoin.networks.bitcoin.p2wsh = { | ||
62 | baseNetwork: "bitcoin", | ||
63 | messagePrefix: '\x18Bitcoin Signed Message:\n', | ||
64 | bech32: 'bc', | ||
65 | bip32: { | ||
66 | public: 0x02aa7ed3, | ||
67 | private: 0x02aa7a99 | ||
68 | }, | ||
69 | pubKeyHash: 0x00, | ||
70 | scriptHash: 0x05, | ||
71 | wif: 0x80 | ||
72 | }; | ||
73 | |||
74 | bitcoinjs.bitcoin.networks.testnet.p2wsh = { | ||
75 | baseNetwork: "testnet", | ||
76 | messagePrefix: '\x18Bitcoin Signed Message:\n', | ||
77 | bech32: 'tb', | ||
78 | bip32: { | ||
79 | public: 0x02575483, | ||
80 | private: 0x02575048 | ||
81 | }, | ||
82 | pubKeyHash: 0x6f, | ||
83 | scriptHash: 0xc4, | ||
84 | wif: 0xef | ||
85 | }; | ||
86 | |||
87 | // p2wsh in p2sh | ||
88 | |||
89 | bitcoinjs.bitcoin.networks.bitcoin.p2wshInP2sh = { | ||
90 | baseNetwork: "bitcoin", | ||
91 | messagePrefix: '\x18Bitcoin Signed Message:\n', | ||
92 | bech32: 'bc', | ||
93 | bip32: { | ||
94 | public: 0x0295b43f, | ||
95 | private: 0x0295b005 | ||
96 | }, | ||
97 | pubKeyHash: 0x00, | ||
98 | scriptHash: 0x05, | ||
99 | wif: 0x80 | ||
100 | }; | ||
101 | |||
102 | bitcoinjs.bitcoin.networks.testnet.p2wshInP2sh = { | ||
103 | baseNetwork: "testnet", | ||
104 | messagePrefix: '\x18Bitcoin Signed Message:\n', | ||
105 | bech32: 'tb', | ||
106 | bip32: { | ||
107 | public: 0x024289ef, | ||
108 | private: 0x024285b5 | ||
109 | }, | ||
110 | pubKeyHash: 0x6f, | ||
111 | scriptHash: 0xc4, | ||
112 | wif: 0xef | ||
113 | }; | ||
114 | |||
59 | bitcoinjs.bitcoin.networks.litecoin.p2wpkh = { | 115 | bitcoinjs.bitcoin.networks.litecoin.p2wpkh = { |
60 | baseNetwork: "litecoin", | 116 | baseNetwork: "litecoin", |
61 | messagePrefix: '\x19Litecoin Signed Message:\n', | 117 | messagePrefix: '\x19Litecoin Signed Message:\n', |
diff --git a/tests/spec/tests.js b/tests/spec/tests.js index af8944c..fc71353 100644 --- a/tests/spec/tests.js +++ b/tests/spec/tests.js | |||
@@ -3694,6 +3694,102 @@ it('Can generate BIP141 addresses with P2WPKH-in-P2SH semanitcs', function(done) | |||
3694 | }); | 3694 | }); |
3695 | }); | 3695 | }); |
3696 | 3696 | ||
3697 | it('Can generate BIP141 addresses with P2WSH semanitcs', function(done) { | ||
3698 | driver.findElement(By.css('#bip141-tab a')) | ||
3699 | .click(); | ||
3700 | // Choose P2WSH | ||
3701 | driver.executeScript(function() { | ||
3702 | $(".bip141-semantics option[selected]").removeAttr("selected"); | ||
3703 | $(".bip141-semantics option").filter(function(i,e) { | ||
3704 | return $(e).html() == "P2WSH"; | ||
3705 | }).prop("selected", true); | ||
3706 | $(".bip141-semantics").trigger("change"); | ||
3707 | }); | ||
3708 | driver.findElement(By.css(".phrase")) | ||
3709 | .sendKeys("abandon abandon ability"); | ||
3710 | driver.sleep(generateDelay).then(function() { | ||
3711 | driver.findElement(By.css("#root-key")) | ||
3712 | .getAttribute("value") | ||
3713 | .then(function(rootKey) { | ||
3714 | expect(rootKey).toBe("ZprvAhadJRUYsNge9uHspaggavxU1BUQ8QwfT4Z9UGq5sKF2mSt1mVy8EckLAaoBdmLHyP5eYDJ3LxtmzMNnLg2MRFe7QN2ueF4NCH4s5PrCDR6"); | ||
3715 | // TODO check first address | ||
3716 | done(); | ||
3717 | }) | ||
3718 | }); | ||
3719 | }); | ||
3720 | |||
3721 | it('Can generate BIP141 addresses with P2WSH-in-P2SH semanitcs', function(done) { | ||
3722 | driver.findElement(By.css('#bip141-tab a')) | ||
3723 | .click(); | ||
3724 | // Choose P2WSH-in-P2SH | ||
3725 | driver.executeScript(function() { | ||
3726 | $(".bip141-semantics option[selected]").removeAttr("selected"); | ||
3727 | $(".bip141-semantics option").filter(function(i,e) { | ||
3728 | return $(e).html() == "P2WSH nested in P2SH"; | ||
3729 | }).prop("selected", true); | ||
3730 | $(".bip141-semantics").trigger("change"); | ||
3731 | }); | ||
3732 | driver.findElement(By.css(".phrase")) | ||
3733 | .sendKeys("abandon abandon ability"); | ||
3734 | driver.sleep(generateDelay).then(function() { | ||
3735 | driver.findElement(By.css("#root-key")) | ||
3736 | .getAttribute("value") | ||
3737 | .then(function(rootKey) { | ||
3738 | expect(rootKey).toBe("YprvANkMzkodih9AJc6kzDu4NqrxqDKxBnxAXx2vgswCVJs9iM4nWqoZcZ6C9NqbdrgNZjxqnjhUtJYE74mDcycLd1xWY2LV4LEsvZ1DgqxuAKe"); | ||
3739 | // TODO check first address | ||
3740 | done(); | ||
3741 | }) | ||
3742 | }); | ||
3743 | }); | ||
3744 | |||
3745 | it('Uses Vprv for bitcoin testnet p2wsh', function(done) { | ||
3746 | selectNetwork("BTC - Bitcoin Testnet"); | ||
3747 | driver.findElement(By.css('#bip141-tab a')) | ||
3748 | .click() | ||
3749 | // Choose P2WSH | ||
3750 | driver.executeScript(function() { | ||
3751 | $(".bip141-semantics option[selected]").removeAttr("selected"); | ||
3752 | $(".bip141-semantics option").filter(function(i,e) { | ||
3753 | return $(e).html() == "P2WSH"; | ||
3754 | }).prop("selected", true); | ||
3755 | $(".bip141-semantics").trigger("change"); | ||
3756 | }); | ||
3757 | driver.findElement(By.css('.phrase')) | ||
3758 | .sendKeys('abandon abandon ability'); | ||
3759 | driver.sleep(generateDelay).then(function() { | ||
3760 | driver.findElement(By.css('.root-key')) | ||
3761 | .getAttribute("value") | ||
3762 | .then(function(path) { | ||
3763 | expect(path).toBe("Vprv16YtLrHXxePM5ja5hXQbiJs5JKDAc4WcaXo5rZcrVMU6bMhUg1oY7fpPku3i819gvMcHvq1h8aELDsyfCEs19vj1Q3iDHRrESWyJConkoT1"); | ||
3764 | done(); | ||
3765 | }) | ||
3766 | }); | ||
3767 | }); | ||
3768 | |||
3769 | it('Uses Uprv for bitcoin testnet p2wsh-in-p2sh', function(done) { | ||
3770 | selectNetwork("BTC - Bitcoin Testnet"); | ||
3771 | driver.findElement(By.css('#bip141-tab a')) | ||
3772 | .click() | ||
3773 | // Choose P2WSH-in-P2SH | ||
3774 | driver.executeScript(function() { | ||
3775 | $(".bip141-semantics option[selected]").removeAttr("selected"); | ||
3776 | $(".bip141-semantics option").filter(function(i,e) { | ||
3777 | return $(e).html() == "P2WSH nested in P2SH"; | ||
3778 | }).prop("selected", true); | ||
3779 | $(".bip141-semantics").trigger("change"); | ||
3780 | }); | ||
3781 | driver.findElement(By.css('.phrase')) | ||
3782 | .sendKeys('abandon abandon ability'); | ||
3783 | driver.sleep(generateDelay).then(function() { | ||
3784 | driver.findElement(By.css('.root-key')) | ||
3785 | .getAttribute("value") | ||
3786 | .then(function(path) { | ||
3787 | expect(path).toBe("Uprv95RJn67y7xyEuRLHenkZYVUx9LkARJzAsVx3ZJMeyHMdVwosWD9K8JTe4Z1FeE4gwBVcnqKF3f82ZvJxkBxHS5E74fYnigxvqeke8ZV3Fp2"); | ||
3788 | done(); | ||
3789 | }) | ||
3790 | }); | ||
3791 | }); | ||
3792 | |||
3697 | it('Can generate BIP141 addresses with P2WPKH semanitcs', function(done) { | 3793 | it('Can generate BIP141 addresses with P2WPKH semanitcs', function(done) { |
3698 | // This result tested against bitcoinjs-lib test spec for segwit address | 3794 | // This result tested against bitcoinjs-lib test spec for segwit address |
3699 | // using the first private key of this mnemonic and default path m/0 | 3795 | // using the first private key of this mnemonic and default path m/0 |