+// github issue 58
+// https://github.com/iancoleman/bip39/issues/58
+// bip32 derivation is correct, does not drop leading zeros
+// see also
+// https://medium.com/@alexberegszaszi/why-do-my-bip32-wallets-disagree-6f3254cc5846
+function() {
+page.open(url, function(status) {
+ // set the phrase and passphrase
+ var expected = "17rxURoF96VhmkcEGCj5LNQkmN9HVhWb7F";
+ // Note that bitcore generates an incorrect address
+ // 13EuKhffWkBE2KUwcbkbELZb1MpzbimJ3Y
+ // see the medium.com link above for more details
+ page.evaluate(function() {
+ $(".phrase").val("fruit wave dwarf banana earth journey tattoo true farm silk olive fence");
+ $(".passphrase").val("banana").trigger("input");
+ });
+ // check the address is generated correctly
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $(".address:first").text();
+ });
+ if (actual != expected) {
+ console.log("BIP32 derivation is incorrect");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+
+// github issue 60
+// Japanese mnemonics generate incorrect bip32 seed
+// BIP39 seed is set from phrase
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "a262d6fb6122ecf45be09c50492b31f92e9beb7d9a845987a02cefda57a15f9c467a17872029a9e92299b5cbdf306e3a0ee620245cbd508959b6cb7ca637bd55";
+ page.evaluate(function() {
+ $(".phrase").val("あいこくしん あいこくしん あいこくしん あいこくしん あいこくしん あいこくしん あいこくしん あいこくしん あいこくしん あいこくしん あいこくしん あおぞら");
+ $("#passphrase").val("メートルガバヴァぱばぐゞちぢ十人十色");
+ $("#passphrase").trigger("input");
+ });
+ // check the seed is generated correctly
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $(".seed").val();
+ });
+ if (actual != expected) {
+ console.log("BIP39 seed is incorrectly generated from Japanese mnemonic");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// BIP49 official test vectors
+// https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki#test-vectors
+function() {
+page.open(url, function(status) {
+ // set the phrase and select bitcoin testnet
+ var expected = "2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about");
+ $(".network option[selected]").removeAttr("selected");
+ $(".network option").filter(function() {
+ return $(this).html() == "BTC - Bitcoin Testnet";
+ }).prop("selected", true);
+ $(".network").trigger("change");
+ $(".phrase").trigger("input");
+ });
+ // check the first address
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $(".address:first").text();
+ });
+ if (actual != expected) {
+ console.log("BIP49 address is incorrect");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// BIP49 derivation path is shown
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "m/49'/0'/0'/0";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability").trigger("input");
+ });
+ // check the derivation path of the first address
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $("#bip49 .path").val();
+ });
+ if (actual != expected) {
+ console.log("BIP49 derivation path is incorrect");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// BIP49 extended private key is shown
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "xprvA1hukYsW7QfX9CVsaDAKde4eryajKa4DKWb6m9YjSnqkiZHrahFwwTJfEQTwBQ5kptWT5pZMkkusT1oK8dc1efQ8VFfq4SLSPAWd7Cpt423";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability").trigger("input");
+ });
+ // check the BIP49 extended private key
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $(".extended-priv-key").val();
+ });
+ if (actual != expected) {
+ console.log("BIP49 extended private key is incorrect");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// BIP49 extended public key is shown
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "xpub6EhGA4QPwnDpMgaLgEhKzn1PR1RDj2n4gjWhZXxM18NjbMd18EaCVFd95gkLARJaBD2rXAYJED2gdkUbGn1KkrSzCKR554AdABUELoainnt";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability").trigger("input");
+ });
+ // check the BIP49 extended public key
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $(".extended-pub-key").val();
+ });
+ if (actual != expected) {
+ console.log("BIP49 extended public key is incorrect");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// BIP49 account field changes address list
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "381wg1GGN4rP88rNC9v7QWsiww63yLVPsn";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability").trigger("input");
+ });
+ waitForGenerate(function() {
+ // change the bip49 account field to 1
+ page.evaluate(function() {
+ $("#bip49 .account").val("1");
+ $("#bip49 .account").trigger("input");
+ });
+ waitForGenerate(function() {
+ // check the address for the new derivation path
+ var actual = page.evaluate(function() {
+ return $(".address:first").text();
+ });
+ if (actual != expected) {
+ console.log("BIP49 account field generates incorrect address");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+ });
+});
+},
+
+// BIP49 change field changes address list
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "3PEM7MiKed5konBoN66PQhK8r3hjGhy9dT";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability").trigger("input");
+ });
+ waitForGenerate(function() {
+ // change the bip49 change field to 1
+ page.evaluate(function() {
+ $("#bip49 .change").val("1");
+ $("#bip49 .change").trigger("input");
+ });
+ waitForGenerate(function() {
+ // check the address for the new derivation path
+ var actual = page.evaluate(function() {
+ return $(".address:first").text();
+ });
+ if (actual != expected) {
+ console.log("BIP49 change field generates incorrect address");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+ });
+});
+},
+
+// BIP49 account extendend private key is shown
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "xprv9y3uhgQbfQZbj3o98nfgLDwGGuCJjUn7GKArSAZXjKgMjSdYHjQmTyf78s22g6jsGrxXvHB6HJeFyvFSPkuYZajeTGMZVXV6aNLWw2fagCn";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability");
+ $(".phrase").trigger("input");
+ });
+ // check the BIP49 account extended private key
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $("#bip49 .account-xprv").val();
+ });
+ if (actual != expected) {
+ console.log("BIP49 account extended private key is incorrect");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// BIP49 account extendend public key is shown
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ var expected = "xpub6C3G7BwVVn7twXscEpCghMszpw2o8wVxdY6TEYy9HfDLcExgqGj21myazAiq6HSmW2F1cBiFqJa3D1cqcDpSh8pbZF5x4iqpd4PyJvd3gjB";
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability");
+ $(".phrase").trigger("input");
+ });
+ // check the BIP49 account extended public key
+ waitForGenerate(function() {
+ var actual = page.evaluate(function() {
+ return $("#bip49 .account-xpub").val();
+ });
+ if (actual != expected) {
+ console.log("BIP49 account extended public key is incorrect");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// Test selecting coin where bip49 is unavailable (eg CLAM)
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability");
+ $(".phrase").trigger("input");
+ });
+ waitForGenerate(function() {
+ // select non-bip49 network, ie CLAM network
+ page.evaluate(function() {
+ $(".network option[selected]").removeAttr("selected");
+ $(".network option").filter(function() {
+ return $(this).html() == "CLAM - Clams";
+ }).prop("selected", true);
+ $(".network").trigger("change");
+ });
+ // check the BIP49 error is shown
+ var bip49ErrorShown = page.evaluate(function() {
+ var bip49hidden = $("#bip49 .available").hasClass("hidden");
+ bip49hidden = bip49hidden && !($("#bip49 .unavailable").hasClass("hidden"));
+ return bip49hidden;
+ });
+ if (!bip49ErrorShown) {
+ console.log("BIP49 error not shown for non-bip49 network");
+ fail();
+ }
+ // check there are no addresses shown
+ var addressCount = page.evaluate(function() {
+ return $(".address").length;
+ });
+ if (addressCount != 0) {
+ console.log("BIP49 address count for non-bip49 network is " + addressCount);
+ fail();
+ }
+ // check the derived keys are blank
+ var areBlank = page.evaluate(function() {
+ var prvKeyIsBlank = $(".extended-priv-key").val().length == 0;
+ var pubKeyIsBlank = $(".extended-pub-key").val().length == 0;
+ return prvKeyIsBlank && pubKeyIsBlank;
+ });
+ if (!areBlank) {
+ console.log("BIP49 extended keys for non-bip49 network are not blank ");
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// github issue 43
+// Cleared mnemonic and root key still allows addresses to be generated
+// https://github.com/iancoleman/bip39/issues/43
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ page.evaluate(function() {
+ $("#bip49-tab a").click();
+ $(".phrase").val("abandon abandon ability");
+ $(".phrase").trigger("input");
+ });
+ waitForGenerate(function() {
+ // clear the mnemonic and root key
+ page.evaluate(function() {
+ $(".phrase").val("");
+ $(".phrase").trigger("input");
+ $(".root-key").val("");
+ $(".root-key").trigger("input");
+ $(".more").click();
+ });
+ waitForFeedback(function() {
+ // check there are no addresses shown
+ var addressCount = page.evaluate(function() {
+ return $(".address").length;
+ });
+ if (addressCount != 0) {
+ console.log("Clearing mnemonic should not allow addresses to be generated");
+ fail();
+ }
+ next();
+ });
+ });
+});
+},
+
+// Github issue 95
+// error trying to generate addresses from xpub with hardened derivation
+function() {
+page.open(url, function(status) {
+ // set the phrase
+ page.evaluate(function() {
+ // Use bip32 tab with hardened addresses
+ $(".hardened-addresses").prop("checked", true);
+ $("#bip32-tab a").click();
+ // set xpub for account 0 of bip44 for 'abandon abandon ability'
+ var bip44AccountXpub = "xpub6CzDCPbtLrrn4VpVbyyQLHbdSMpZoHN4iuW64VswCyEpfjM2mJGdaHJ2DyuZwtst96E16VvcERb8BBeJdHSCVmAq9RhtRQg6eAZFrTKCNqf";
+ $("#root-key").val(bip44AccountXpub);
+ $("#root-key").trigger("input");
+ });
+ waitForFeedback(function() {
+ // check the error message shows
+ var expected = "Hardened derivation path is invalid with xpub key";
+ var actual = page.evaluate(function() {
+ return $(".feedback").text();
+ });
+ if (actual != expected) {
+ console.log("xpub key with hardened addresses does not show feedback");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// Litecoin uses xprv by default, and can optionally be set to ltpv
+// github issue 96
+// https://github.com/iancoleman/bip39/issues/96
+// Issue with extended keys on Litecoin
+function() {
+page.open(url, function(status) {
+ // set the phrase and coin
+ page.evaluate(function() {
+ $(".phrase").val("abandon abandon ability");
+ $(".network option[selected]").removeAttr("selected");
+ $(".network option").filter(function() {
+ return $(this).html() == "LTC - Litecoin";
+ }).prop("selected", true);
+ $(".network").trigger("change");
+ $(".phrase").trigger("input");
+ });
+ // check the extended key is generated correctly
+ waitForGenerate(function() {
+ var expected = "xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi";
+ var actual = page.evaluate(function() {
+ return $(".root-key").val();
+ });
+ if (actual != expected) {
+ console.log("Litecoin root key does not default to xprv");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ // set litecoin to use ltub
+ page.evaluate(function() {
+ $(".addresses").empty();
+ $(".litecoin-use-ltub").prop("checked", true);
+ $(".litecoin-use-ltub").trigger("change");
+ });
+ waitForGenerate(function() {
+ var expected = "Ltpv71G8qDifUiNesiPqf6h5V6eQ8ic77oxQiYtawiACjBEx3sTXNR2HGDGnHETYxESjqkMLFBkKhWVq67ey1B2MKQXannUqNy1RZVHbmrEjnEU";
+ var actual = page.evaluate(function() {
+ return $(".root-key").val();
+ });
+ if (actual != expected) {
+ console.log("Litecoin root key cannot be set to use ltub");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+ });
+});
+},
+
+// BIP32 tab can use P2WPKH Nested In P2SH
+// github issue 91 part 2
+// https://github.com/iancoleman/bip39/issues/91
+// generate new addresses from xpub?
+function() {
+page.open(url, function(status) {
+ // set the xpub and coin and select bip32 tab with p2wpkh addresses
+ page.evaluate(function() {
+ // use p2wpkh addresses
+ $(".p2wpkh-nested-in-p2sh").prop("checked", true);
+ // use bip32 tab
+ $("#bip32-tab a").click();
+ // use testnet
+ $(".network option[selected]").removeAttr("selected");
+ $(".network option").filter(function() {
+ return $(this).html() == "BTC - Bitcoin Testnet";
+ }).prop("selected", true);
+ $(".network").trigger("change");
+ // Set root xpub to BIP49 official test vector account 0
+ $(".root-key").val("tpubDD7tXK8KeQ3YY83yWq755fHY2JW8Ha8Q765tknUM5rSvjPcGWfUppDFMpQ1ScziKfW3ZNtZvAD7M3u7bSs7HofjTD3KP3YxPK7X6hwV8Rk2");
+ $(".root-key").trigger("input");
+ });
+ // check the address is generated correctly
+ waitForGenerate(function() {
+ var expected = "2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2";
+ var actual = page.evaluate(function() {
+ return $(".address:first").text();
+ });
+ if (actual != expected) {
+ console.log("BIP32 tab cannot generate P2WPKH Nested In P2SH addresses");
+ console.log("Expected: " + expected);
+ console.log("Actual: " + actual);
+ fail();
+ }
+ next();
+ });
+});
+},
+
+// github issue 99
+// https://github.com/iancoleman/bip39/issues/99#issuecomment-327094159
+// "warn me emphatically when they have detected invalid input" to the entropy field
+// A warning is shown when entropy is filtered and discarded
+function() {
+page.open(url, function(status) {
+ // use entropy
+ page.evaluate(function() {
+ $(".use-entropy").prop("checked", true).trigger("change");
+ $(".entropy").val("00000000 00000000 00000000 00000000").trigger("input");
+ });
+ // check the filter warning does not show
+ waitForGenerate(function() {
+ var warningIsHidden = page.evaluate(function() {
+ return $(".entropy-container .filter-warning").hasClass("hidden");
+ });
+ if (!warningIsHidden) {
+ console.log("Entropy filter warning is showing when it should not");
+ fail();
+ }
+ page.evaluate(function() {
+ $(".entropy").val("10000000 zxcvbn 00000000 00000000 00000000").trigger("input");
+ });
+ // check the filter warning shows
+ waitForEntropyFeedback(function() {
+ var warningIsHidden = page.evaluate(function() {
+ return $(".entropy-container .filter-warning").hasClass("hidden");
+ });
+ if (warningIsHidden) {
+ console.log("Entropy filter warning is not showing when it should");
+ fail();
+ }
+ next();
+ });
+ });
+});
+},
+