aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Coleman <coleman.ian@gmail.com>2016-08-23 10:31:39 +1000
committerIan Coleman <coleman.ian@gmail.com>2016-08-23 10:31:39 +1000
commitefe41586705d3eba480da31bb1002c4e54e73ef0 (patch)
treef071e764935ce06c165fdc014ed29172271c3cef /src
parent563e401a4f3880da88bfc69cf51be5a1becd4c66 (diff)
downloadBIP39-efe41586705d3eba480da31bb1002c4e54e73ef0.tar.gz
BIP39-efe41586705d3eba480da31bb1002c4e54e73ef0.tar.zst
BIP39-efe41586705d3eba480da31bb1002c4e54e73ef0.zip
BIP32 Root Key can be specified by user
Diffstat (limited to 'src')
-rw-r--r--src/index.html2
-rw-r--r--src/js/index.js85
2 files changed, 75 insertions, 12 deletions
diff --git a/src/index.html b/src/index.html
index 6708675..fcdf109 100644
--- a/src/index.html
+++ b/src/index.html
@@ -105,7 +105,7 @@
105 <div class="form-group"> 105 <div class="form-group">
106 <label for="root-key" class="col-sm-2 control-label">BIP32 Root Key</label> 106 <label for="root-key" class="col-sm-2 control-label">BIP32 Root Key</label>
107 <div class="col-sm-10"> 107 <div class="col-sm-10">
108 <textarea id="root-key" class="root-key form-control" readonly="readonly"></textarea> 108 <textarea id="root-key" class="root-key form-control"></textarea>
109 </div> 109 </div>
110 </div> 110 </div>
111 </form> 111 </form>
diff --git a/src/js/index.js b/src/js/index.js
index f3582b0..88e891c 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -12,6 +12,7 @@
12 var showPrivKey = true; 12 var showPrivKey = true;
13 13
14 var phraseChangeTimeoutEvent = null; 14 var phraseChangeTimeoutEvent = null;
15 var rootKeyChangedTimeoutEvent = null;
15 16
16 var DOM = {}; 17 var DOM = {};
17 DOM.network = $(".network"); 18 DOM.network = $(".network");
@@ -50,12 +51,13 @@
50 DOM.passphrase.on("input", delayedPhraseChanged); 51 DOM.passphrase.on("input", delayedPhraseChanged);
51 DOM.generate.on("click", generateClicked); 52 DOM.generate.on("click", generateClicked);
52 DOM.more.on("click", showMore); 53 DOM.more.on("click", showMore);
53 DOM.bip32path.on("input", delayedPhraseChanged); 54 DOM.rootKey.on("input", delayedRootKeyChanged);
54 DOM.bip44purpose.on("input", delayedPhraseChanged); 55 DOM.bip32path.on("input", calcForDerivationPath);
55 DOM.bip44coin.on("input", delayedPhraseChanged); 56 DOM.bip44purpose.on("input", calcForDerivationPath);
56 DOM.bip44account.on("input", delayedPhraseChanged); 57 DOM.bip44coin.on("input", calcForDerivationPath);
57 DOM.bip44change.on("input", delayedPhraseChanged); 58 DOM.bip44account.on("input", calcForDerivationPath);
58 DOM.tab.on("click", delayedPhraseChanged); 59 DOM.bip44change.on("input", calcForDerivationPath);
60 DOM.tab.on("shown.bs.tab", calcForDerivationPath);
59 DOM.indexToggle.on("click", toggleIndexes); 61 DOM.indexToggle.on("click", toggleIndexes);
60 DOM.addressToggle.on("click", toggleAddresses); 62 DOM.addressToggle.on("click", toggleAddresses);
61 DOM.privateKeyToggle.on("click", togglePrivateKeys); 63 DOM.privateKeyToggle.on("click", togglePrivateKeys);
@@ -70,7 +72,7 @@
70 function networkChanged(e) { 72 function networkChanged(e) {
71 var network = e.target.value; 73 var network = e.target.value;
72 networks[network].onSelect(); 74 networks[network].onSelect();
73 delayedPhraseChanged(); 75 displayBip32Info();
74 } 76 }
75 77
76 function delayedPhraseChanged() { 78 function delayedPhraseChanged() {
@@ -87,12 +89,57 @@
87 hideValidationError(); 89 hideValidationError();
88 // Get the mnemonic phrase 90 // Get the mnemonic phrase
89 var phrase = DOM.phrase.val(); 91 var phrase = DOM.phrase.val();
90 var passphrase = DOM.passphrase.val();
91 var errorText = findPhraseErrors(phrase); 92 var errorText = findPhraseErrors(phrase);
92 if (errorText) { 93 if (errorText) {
93 showValidationError(errorText); 94 showValidationError(errorText);
94 return; 95 return;
95 } 96 }
97 // Calculate and display
98 var passphrase = DOM.passphrase.val();
99 calcBip32RootKeyFromSeed(phrase, passphrase);
100 calcForDerivationPath();
101 hidePending();
102 }
103
104 function delayedRootKeyChanged() {
105 // Warn if there is an existing mnemonic or passphrase.
106 if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) {
107 if (!confirm("This will clear existing mnemonic and passphrase")) {
108 DOM.rootKey.val(bip32RootKey);
109 return
110 }
111 }
112 hideValidationError();
113 showPending();
114 // Clear existing mnemonic and passphrase
115 DOM.phrase.val("");
116 DOM.passphrase.val("");
117 seed = null;
118 if (rootKeyChangedTimeoutEvent != null) {
119 clearTimeout(rootKeyChangedTimeoutEvent);
120 }
121 rootKeyChangedTimeoutEvent = setTimeout(rootKeyChanged, 400);
122 }
123
124 function rootKeyChanged() {
125 showPending();
126 hideValidationError();
127 // Validate the root key TODO
128 var rootKeyBase58 = DOM.rootKey.val();
129 var errorText = validateRootKey(rootKeyBase58);
130 if (errorText) {
131 showValidationError(errorText);
132 return;
133 }
134 // Calculate and display
135 calcBip32RootKeyFromBase58(rootKeyBase58);
136 calcForDerivationPath();
137 hidePending();
138 }
139
140 function calcForDerivationPath() {
141 showPending();
142 hideValidationError();
96 // Get the derivation path 143 // Get the derivation path
97 var derivationPath = getDerivationPath(); 144 var derivationPath = getDerivationPath();
98 var errorText = findDerivationPathErrors(derivationPath); 145 var errorText = findDerivationPathErrors(derivationPath);
@@ -100,8 +147,7 @@
100 showValidationError(errorText); 147 showValidationError(errorText);
101 return; 148 return;
102 } 149 }
103 // Calculate and display 150 calcBip32ExtendedKey(derivationPath);
104 calcBip32Seed(phrase, passphrase, derivationPath);
105 displayBip32Info(); 151 displayBip32Info();
106 hidePending(); 152 hidePending();
107 } 153 }
@@ -148,9 +194,16 @@
148 return words; 194 return words;
149 } 195 }
150 196
151 function calcBip32Seed(phrase, passphrase, path) { 197 function calcBip32RootKeyFromSeed(phrase, passphrase) {
152 seed = mnemonic.toSeed(phrase, passphrase); 198 seed = mnemonic.toSeed(phrase, passphrase);
153 bip32RootKey = bitcoin.HDNode.fromSeedHex(seed, network); 199 bip32RootKey = bitcoin.HDNode.fromSeedHex(seed, network);
200 }
201
202 function calcBip32RootKeyFromBase58(rootKeyBase58) {
203 bip32RootKey = bitcoin.HDNode.fromBase58(rootKeyBase58);
204 }
205
206 function calcBip32ExtendedKey(path) {
154 bip32ExtendedKey = bip32RootKey; 207 bip32ExtendedKey = bip32RootKey;
155 // Derive the key from the path 208 // Derive the key from the path
156 var pathBits = path.split("/"); 209 var pathBits = path.split("/");
@@ -213,6 +266,16 @@
213 return false; 266 return false;
214 } 267 }
215 268
269 function validateRootKey(rootKeyBase58) {
270 try {
271 bitcoin.HDNode.fromBase58(rootKeyBase58);
272 }
273 catch (e) {
274 return "Invalid root key";
275 }
276 return "";
277 }
278
216 function getDerivationPath() { 279 function getDerivationPath() {
217 if (DOM.bip44tab.hasClass("active")) { 280 if (DOM.bip44tab.hasClass("active")) {
218 var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44); 281 var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44);