Compare commits

...

54 Commits
0.1.1 ... 0.2.6

Author SHA1 Message Date
Ian Coleman
9ff30babbc Release v0.2.6 2017-09-20 11:39:06 +10:00
Ian Coleman
ee0981f1ec Detect and warn of filtered entropy 2017-09-20 11:25:21 +10:00
Ian Coleman
6024e655a8 Update process for committing changes
Do not include changes in bip39-standalone.html
2017-09-19 11:15:25 +10:00
Ian Coleman
7e6bdc498e Reword entropy text to say one type, not multiple 2017-09-19 11:13:03 +10:00
iancoleman
16b4c2788a Merge pull request #117 from jonathancross/iancoleman-bip39-bip49
Adding BIP 49 to "More info" section.
2017-09-19 10:32:20 +10:00
iancoleman
0197de2795 Merge pull request #116 from jonathancross/iancoleman-bip39-compile
Allowing compilation with Python 2.x
2017-09-19 10:26:32 +10:00
Jonathan Cross
861750ae51 Adding BIP 49 to "More info" section. 2017-09-18 02:18:51 +02:00
Jonathan Cross
a40d59d904 Allowing compilation with Python 2.x and 3. 2017-09-18 01:57:05 +02:00
iancoleman
d933c3f731 Merge pull request #103 from Zwilla/patch-3
correctLevel from 2 to 3
2017-09-08 08:12:34 +10:00
iancoleman
408ecc184a Merge pull request #102 from Zwilla/patch-2
remove sourceMappingURL=zxcvbn.js.map
2017-09-08 08:07:51 +10:00
Zwilla
00114002fe correctLevel from 2 to 3
correctLevel 3 is generally recommended for industrial environments.

See also: https://github.com/iancoleman/bip39/issues/101
2017-09-07 14:32:42 +02:00
Zwilla
e80955983d remove sourceMappingURL=zxcvbn.js.map
just remove this line, if not every time we run the converter it searches for the map file. It is not enough to uncomment this line.
thx
2017-09-07 09:42:54 +02:00
iancoleman
f20b7e7128 Merge pull request #98 from Zwilla/patch-1
changed some wrong comma and ;
2017-09-04 10:03:05 +10:00
Zwilla
908dc06fe8 changed some wrong comma and ;
nothing else
2017-09-04 01:55:55 +02:00
Ian Coleman
3d548c6f9b Improve release process order and add details 2017-09-01 13:20:29 +10:00
Ian Coleman
0a8d06d03e Release v0.2.5 2017-09-01 12:35:42 +10:00
Ian Coleman
88311463c7 Allow P2WPKH nested in P2SH addresses on BIP32 tab 2017-09-01 12:28:27 +10:00
Ian Coleman
cd7c8327b1 Validate root key correctly for alternate networks 2017-09-01 12:27:03 +10:00
Ian Coleman
0cda44d5f6 Rename bip49 to p2wpkhNestedInP2sh where suitable 2017-09-01 12:25:45 +10:00
Ian Coleman
7258b102c1 Add confirmation steps to the release process 2017-08-28 10:03:21 +10:00
Ian Coleman
8d18f379fd Release v0.2.4 2017-08-28 09:48:48 +10:00
Ian Coleman
3abab9b087 Add a checkbox to switch litecoin key prefixes 2017-08-28 09:45:38 +10:00
Ian Coleman
b18eb97ae3 Show error when using xpub with hardened addresses 2017-08-24 09:37:21 +10:00
Ian Coleman
88ea3e40ee Release v0.2.3 2017-08-23 09:45:09 +10:00
Ian Coleman
8a9f391376 Test for Maza network 2017-08-23 09:41:53 +10:00
iancoleman
e40acc3ab0 Merge pull request #92 from jonspock/master
Add maza coin, update PIVX in bip39-standalone.html
2017-08-23 09:30:43 +10:00
Jon Spock
56ad960105 Add maza coin 2017-08-21 17:13:44 -07:00
Ian Coleman
f128bd58c4 Release v0.2.2 2017-08-16 11:26:10 +10:00
Ian Coleman
0eda54f5a7 Improve showing feedback for pending calculations 2017-08-16 11:04:13 +10:00
Ian Coleman
ed6d9d3905 Clear old seed when mnemonic is changed 2017-08-16 10:43:09 +10:00
Ian Coleman
47b64d3ee1 Add PIVX network tests 2017-08-14 15:27:24 +10:00
iancoleman
bc33f5ee53 Merge pull request #89 from alkley/master
Add PIVX
2017-08-14 14:43:04 +10:00
alkley
c0df01895d Added PIVX 2017-08-11 15:08:53 +02:00
Ian Coleman
b3cc3930d0 Release v0.2.1 2017-08-07 19:13:10 +10:00
Ian Coleman
c18511dd0d Add myriadcoin test 2017-08-07 19:01:03 +10:00
Ian Coleman
7ebdf61c99 Order networks alphabetically 2017-08-07 18:57:41 +10:00
Ian Coleman
daab55dc61 Add BCH - Bitcoin Cash network 2017-08-07 18:54:12 +10:00
Ian Coleman
7b742f87d3 Default coin selection is BTC - Bitcoin 2017-08-07 18:54:12 +10:00
iancoleman
4d9c184a84 Merge pull request #87 from alkley/master
Add Myriadcoin
2017-08-07 18:53:46 +10:00
alkley
d5e01cc6e2 placeholder scripthash 2017-08-06 18:20:33 +02:00
alkley
adedbf9169 Added myriad to selectbox 2017-08-06 17:45:22 +02:00
alkley
f36d10080a Added myriad to extensions 2017-08-06 17:40:42 +02:00
Ian Coleman
8335cf17bc Add testing and publishing to release process 2017-08-05 16:26:14 +10:00
Ian Coleman
9987f0c184 Release v0.2.0 2017-08-05 15:14:45 +10:00
Ian Coleman
d2fea262c3 Formalize the release process 2017-08-05 15:10:45 +10:00
Ian Coleman
6c08f364b3 Add BIP49 tab 2017-08-02 17:28:39 +10:00
Ian Coleman
fa2e4e936e Refactor clearKey to better named clearKeys 2017-08-02 17:12:21 +10:00
Ian Coleman
684624b522 Change BIP44 purpose and coin fields to readonly 2017-08-02 17:12:13 +10:00
Ian Coleman
33b3dd47aa Order tabs for derivation path alphabetically 2017-08-02 17:12:04 +10:00
Ian Coleman
a0091a40c4 Upgrade bitcoinjs from v1.5.7 to v3.1.1 2017-08-02 17:11:39 +10:00
Ian Coleman
039a98ba5a Release v0.1.2 2017-07-03 11:00:41 +10:00
iancoleman
9dab7e5d0c Merge pull request #81 from mikeyb/naming
Add CRW / Change bip44 dropdown naming convention
2017-07-03 10:42:20 +10:00
mikeyb
534481b628 standardize dropdown naming scheme 2017-07-02 09:44:54 -07:00
mikeyb
0921f37077 Add CRW - Crown 2017-07-01 15:38:46 -07:00
13 changed files with 29130 additions and 23223 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,54 @@
# 0.2.6
* Detect and warn when entropy is filtered / discarded
* Reword entropy text to indicate using a single source only
* Add BIP49 to More Info section
* Update compile script to work across python 2 and 3
* QR Codes use correctLevel 3 instead of 2
* Source map removed from zxcvbn
* Tidy up code with consistent use of commas and semicolons
# 0.2.5
* Rename variables for clarity between BIP49 and P2WPKH Nested In P2SH
* Fix bug for validation of root key when using non-bitcoin networks
* Add option to use P2WPKH Nested In P2SH addresses on BIP32 tab
# 0.2.4
* Show error when using xpub with hardened addresses
* Allow switching litecoin prefixes between xprv and Ltpv
# 0.2.3
* Add maza coin
# 0.2.2
* Improve showing feedback for pending calculations
* Bugfix: Clear old seed when mnemonic is changed
* Add PIVX network
# 0.2.1
* BTC is the default coin
* Add myriadcoin
* Add Bitcon Cash
# 0.2.0
* BitcoinJS library upgrded to v3.1.1
* Tab order is alphabetical
* BIP44 'purpose' and 'coin' fields are readonly
* Refactor method to clear old data from the display
* BIP49 support
* Release process is documented
# 0.1.2
* Add Crown network
* Network names are displayed with currency code
# 0.1.1
* Add DASH Testnet

View File

@@ -1,6 +1,7 @@
import os
import re
import datetime
from io import open
# This script generates the bip39-standalone.html file.

View File

@@ -55,7 +55,10 @@ at 1PC9aZC4hNX2rmmrt7uHTfYAS3hRbph4UN
Please do not make modifications to `bip39-standalone.html`, since they will
be overwritten by `compile.py`.
Make changes in `src/*` and apply them using the command `python compile.py`
Make changes in `src/*`.
Changes are applied during release using the command `python compile.py`, so
please do not commit changes to `bip39-standalone.html`
# Tests

23
release_process.md Normal file
View File

@@ -0,0 +1,23 @@
Once all code changes for this version have been committed, a release can be
created with the following steps:
1. Run tests and ensure all tests pass
1. Set the version in index.html
1. Update changelog
1. Run `python compile.py`
1. Commit these changes with message `Release vX.Y.Z`
1. Tag the commit `git tag X.Y.Z`
1. Get the hash of the file `sha256sum bip39-standalone.html`
1. Create the text for the release notes (see prior releases)
1. Sign the release notes `gpg --clearsign /tmp/signature.txt`
1. Push the changes `git push`
1. Push the new tag `git push --tags`
1. Create a release on github from the tagged commit
1. include the signed release notes as text for the release
1. include the changelog for this release as text for the release
1. attach signature.txt.asc
1. attach the bip39-standalone.html file
1. Add a new post to twitter from @bip39tool with the version, link and hash
1. Publish to any hosted locations (eg iancoleman.github.io/bip39)
1. Download the file from the release and confirm it hashes to the expected value `sha256sum bip39-standalone.html`
1. Download the signature from the release and verify it. `gpg --verify signature.txt.asc`

View File

@@ -114,7 +114,7 @@
<div class="container">
<h1 class="text-center">Mnemonic Code Converter</h1>
<p class="version">v0.1.1</p>
<p class="version">v0.2.6</p>
<hr>
<div class="row">
<div class="col-md-12">
@@ -163,7 +163,14 @@
<div class="form-group">
<label for="entropy" class="col-sm-2 control-label" data-translate>Entropy</label>
<div class="col-sm-7">
<textarea id="entropy" rows="2" class="entropy form-control" placeholder="Accepts binary, base 6, 6-sided dice, base 10, hexadecimal, cards" data-translate-placeholder></textarea>
<textarea id="entropy" rows="2" class="entropy form-control" placeholder="Accepts either binary, base 6, 6-sided dice, base 10, hexadecimal or cards" data-translate-placeholder></textarea>
<div class="row filter-warning text-danger hidden">
<p class="col-sm-12">
<strong>
Some characters have been discarded
</strong>
</p>
</div>
<div class="row">
<label class="col-sm-3 control-label" data-translate><span class="more-info" data-translate-title title="Based on estimates from zxcvbn using Filtered Entropy">Time To Crack</span></label>
<div class="crack-time col-sm-3 form-control-static"></div>
@@ -266,6 +273,15 @@
<textarea id="root-key" class="root-key form-control" data-show-qr></textarea>
</div>
</div>
<div class="form-group litecoin-ltub-container hidden">
<label for="litecoin-use-ltub" class="col-sm-2 control-label" data-translate>Prefixes</label>
<div class="col-sm-10 checkbox">
<label>
<input type="checkbox" id="litecoin-use-ltub" class="litecoin-use-ltub">
Use <code>Ltpv / Ltub</code> instead of <code>xprv / xpub</code>
</label>
</div>
</div>
</form>
</div>
</div>
@@ -276,11 +292,14 @@
<div class="col-md-12">
<h2>Derivation Path</h2>
<ul class="derivation-type nav nav-tabs" role="tablist">
<li id="bip32-tab">
<a href="#bip32" role="tab" data-toggle="tab">BIP32</a>
</li>
<li id="bip44-tab" class="active">
<a href="#bip44" role="tab" data-toggle="tab">BIP44</a>
</li>
<li id="bip32-tab">
<a href="#bip32" role="tab" data-toggle="tab">BIP32</a>
<li id="bip49-tab">
<a href="#bip49" role="tab" data-toggle="tab">BIP49</a>
</li>
</ul>
<div class="derivation-type tab-content">
@@ -299,7 +318,7 @@
<a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#purpose" target="_blank" data-translate>Purpose</a>
</label>
<div class="col-sm-10">
<input id="purpose" type="text" class="purpose form-control" value="44">
<input id="purpose" type="text" class="purpose form-control" value="44" readonly>
</div>
</div>
<div class="form-group">
@@ -307,7 +326,7 @@
<a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#registered-coin-types" target="_blank" data-translate>Coin</a>
</label>
<div class="col-sm-10">
<input id="coin" type="text" class="coin form-control" value="0">
<input id="coin" type="text" class="coin form-control" value="0" readonly>
</div>
</div>
<div class="form-group">
@@ -396,6 +415,13 @@
<span data-translate>Use hardened addresses</span>
</label>
</div>
<div class="form-group">
<div class="col-sm-2"></div>
<label class="col-sm-10">
<input class="p2wpkh-nested-in-p2sh" type="checkbox">
<span data-translate>Use SegWit addresses (ie P2WPKH Nested In P2SH)</span>
</label>
</div>
<div class="form-group">
<label for="core-path" class="col-sm-2 control-label" data-translate>Bitcoin Core</label>
<div class="col-sm-10">
@@ -435,6 +461,96 @@
</div>
</form>
</div>
<div id="bip49" class="tab-pane">
<form class="form-horizontal" role="form">
<br>
<div class="unavailable hidden">
<div class="form-group">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<p data-translate>BIP49 is unavailable for this coin.</p>
</div>
</div>
</div>
<div class="available">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<p data-translate-html>
For more info see the
<a href="https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki" target="_blank">BIP49 spec</a>.
</p>
</div>
<div class="form-group">
<label for="purpose" class="col-sm-2 control-label">
<a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#purpose" target="_blank" data-translate>Purpose</a>
</label>
<div class="col-sm-10">
<input id="purpose" type="text" class="purpose form-control" value="49" readonly>
</div>
</div>
<div class="form-group">
<label for="coin" class="col-sm-2 control-label">
<a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#registered-coin-types" target="_blank" data-translate>Coin</a>
</label>
<div class="col-sm-10">
<input id="coin" type="text" class="coin form-control" value="0" readonly>
</div>
</div>
<div class="form-group">
<label for="account" class="col-sm-2 control-label">
<a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#account" target="_blank" data-translate>Account</a>
</label>
<div class="col-sm-10">
<input id="account" type="text" class="account form-control" value="0">
</div>
</div>
<div class="form-group">
<label for="change" class="col-sm-2 control-label">
<a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#change" target="_blank" data-translate>External / Internal</a>
</label>
<div class="col-sm-10">
<input id="change" type="text" class="change form-control" value="0">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
</label>
<div class="col-sm-10">
<p data-translate>The account extended keys can be used for importing to most BIP49 compatible wallets.</p>
</div>
</div>
<div class="form-group">
<label for="account-xprv" class="col-sm-2 control-label">
<span data-translate>Account Extended Private Key</span>
</label>
<div class="col-sm-10">
<textarea id="account-xprv" type="text" class="account-xprv form-control" readonly data-show-qr></textarea>
</div>
</div>
<div class="form-group">
<label for="account-xpub" class="col-sm-2 control-label">
<span data-translate>Account Extended Public Key</span>
</label>
<div class="col-sm-10">
<textarea id="account-xpub" type="text" class="account-xpub form-control" readonly data-show-qr></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
</label>
<div class="col-sm-10">
<p data-translate>The BIP32 derivation path and extended keys are the basis for the derived addresses.</p>
</div>
</div>
<div class="form-group">
<label for="bip49-path" class="col-sm-2 control-label" data-translate>BIP32 Derivation Path</label>
<div class="col-sm-10">
<input id="bip49-path" type="text" class="path form-control" value="m/49'/0'/0'/0" readonly="readonly">
</div>
</div>
</div>
</form>
</div>
</div>
<form class="form-horizontal" role="form">
<div class="form-group">
@@ -524,6 +640,11 @@
Read more at the
<a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki" target="_blank">official BIP44 spec</a>
</p>
<h3>BIP49 <span class="small" data-translate>Derivation scheme for P2WPKH-nested-in-P2SH based accounts</span></h3>
<p data-translate-html>
Read more at the
<a href="https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki" target="_blank">official BIP49 spec</a>
</p>
<h3 data-translate>Private Keys</h3>
<p>
<span data-translate-html>
@@ -686,7 +807,7 @@
<script src="js/bootstrap.min.js"></script>
<script src="js/levenshtein.js"></script>
<script src="js/jquery.qrcode.min.js"></script>
<script src="js/bitcoinjs-1-5-7.js"></script>
<script src="js/bitcoinjs-3-1-1.js"></script>
<script src="js/bitcoinjs-extensions.js"></script>
<script src="js/ethereumjs-util.js"></script>
<script src="js/ripple-util.js"></script>

File diff suppressed because it is too large Load Diff

14840
src/js/bitcoinjs-3-1-1.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,107 +1,230 @@
bitcoin.networks.shadow = {
magicPrefix: '\x19ShadowCash Signed Message:\n',
bitcoinjs.bitcoin.networks.shadow = {
messagePrefix: 'unused',
bip32: {
public: 0xEE80286A,
private: 0xEE8031E8
},
pubKeyHash: 0x3f,
scriptHash: 0x7d,
wif: 0xbf,
dustThreshold: 0,
feePerKb: 1000,
estimateFee: function() { return "unused in this app" },
wif: 0xbf
};
bitcoin.networks.shadowtn = {
magicPrefix: '\x19ShadowCash Signed Message:\n',
bitcoinjs.bitcoin.networks.shadowtn = {
messagePrefix: 'unused',
bip32: {
public: 0x76C0FDFB,
private: 0x76C1077A
},
pubKeyHash: 0x7f,
scriptHash: 0xc4,
wif: 0xff,
dustThreshold: 0,
feePerKb: 1000,
estimateFee: function() { return "unused in this app" },
wif: 0xff
};
bitcoin.networks.clam = {
bitcoinjs.bitcoin.networks.clam = {
messagePrefix: 'unused',
bip32: {
public: 0xa8c26d64,
private: 0xa8c17826
},
pubKeyHash: 0x89,
wif: 0x85,
scriptHash: 0x00, // TODO set this correctly
wif: 0x85
};
bitcoin.networks.dash = {
bitcoinjs.bitcoin.networks.crown = {
messagePrefix: 'unused',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80
};
bitcoinjs.bitcoin.networks.dash = {
messagePrefix: 'unused',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x4c,
scriptHash: 0x10,
wif: 0xcc,
wif: 0xcc
};
bitcoin.networks.dashtn = {
bitcoinjs.bitcoin.networks.maza = {
messagePrefix: 'unused',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x32,
scriptHash: 0x09,
wif: 0xe0
};
bitcoinjs.bitcoin.networks.dashtn = {
messagePrefix: 'unused',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
pubKeyHash: 0x8c,
scriptHash: 0x13,
wif: 0xef,
wif: 0xef
};
bitcoin.networks.game = {
bitcoinjs.bitcoin.networks.game = {
messagePrefix: 'unused',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x26,
scriptHash: 0x05,
wif: 0xa6,
wif: 0xa6
};
bitcoin.networks.namecoin = {
bitcoinjs.bitcoin.networks.namecoin = {
messagePrefix: 'unused',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x34,
//scriptHash: 0x10,
wif: 0x80,
scriptHash: 0x00, // TODO set this correctly
wif: 0x80
};
bitcoin.networks.peercoin = {
bitcoinjs.bitcoin.networks.peercoin = {
messagePrefix: 'unused',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x37,
//scriptHash: 0x10,
wif: 0xb7,
scriptHash: 0x00, // TODO set this correctly
wif: 0xb7
};
bitcoin.networks.slimcoin = {
bitcoinjs.bitcoin.networks.slimcoin = {
messagePrefix: 'unused',
bip32: {
public: 0xef6adf10,
private: 0xef69ea80
},
pubKeyHash: 0x3f,
scriptHash: 0x7d,
wif: 0x46,
wif: 0x46
};
bitcoin.networks.slimcointn = {
bitcoinjs.bitcoin.networks.slimcointn = {
messagePrefix: 'unused',
bip32: {
public: 0x043587CF,
private: 0x04358394
},
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0x57,
wif: 0x57
};
bitcoinjs.bitcoin.networks.dogecoin = {
messagePrefix: '\x19Dogecoin Signed Message:\n',
bip32: {
public: 0x02facafd,
private: 0x02fac398
},
pubKeyHash: 0x1e,
scriptHash: 0x16,
wif: 0x9e
};
bitcoinjs.bitcoin.networks.viacoin = {
messagePrefix: '\x18Viacoin Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x47,
scriptHash: 0x21,
wif: 0xc7
};
bitcoinjs.bitcoin.networks.viacointestnet = {
messagePrefix: '\x18Viacoin Signed Message:\n',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
pubKeyHash: 0x7f,
scriptHash: 0xc4,
wif: 0xff
};
bitcoinjs.bitcoin.networks.gamerscoin = {
messagePrefix: '\x19Gamerscoin Signed Message:\n',
bip32: {
public: 0x019da462,
private: 0x019d9cfe
},
pubKeyHash: 0x26,
scriptHash: 0x05,
wif: 0xA6
};
bitcoinjs.bitcoin.networks.jumbucks = {
messagePrefix: '\x19Jumbucks Signed Message:\n',
bip32: {
public: 0x037a689a,
private: 0x037a6460
},
pubKeyHash: 0x2b,
scriptHash: 0x05,
wif: 0xab
};
bitcoinjs.bitcoin.networks.zetacoin = {
messagePrefix: '\x18Zetacoin Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x50,
scriptHash: 0x09,
wif: 0xe0
};
bitcoinjs.bitcoin.networks.myriadcoin = {
messagePrefix: 'unused',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x32,
scriptHash: 0x00, // TODO set this correctly
wif: 0xb2
};
bitcoinjs.bitcoin.networks.pivx = {
messagePrefix: 'unused',
bip32: {
public: 0x022d2533,
private: 0x0221312b
},
pubKeyHash: 0x1e,
scriptHash: 0x0d,
wif: 0xd4
};
bitcoinjs.bitcoin.networks.pivxtestnet = {
messagePrefix: 'unused',
bip32: {
public: 0x3a8061a0,
private: 0x3a805837
},
pubKeyHash: 0x8b,
scriptHash: 0x13,
wif: 0xef
};

View File

@@ -6,7 +6,7 @@
var seed = null;
var bip32RootKey = null;
var bip32ExtendedKey = null;
var network = bitcoin.networks.bitcoin;
var network = bitcoinjs.bitcoin.networks.bitcoin;
var addressRowTemplate = $("#address-row-template");
var showIndex = true;
@@ -14,6 +14,7 @@
var showPubKey = true;
var showPrivKey = true;
var showQr = false;
var litecoinUseLtub = false;
var entropyChangeTimeoutEvent = null;
var phraseChangeTimeoutEvent = null;
@@ -37,18 +38,23 @@
DOM.entropyWordCount = DOM.entropyContainer.find(".word-count");
DOM.entropyBinary = DOM.entropyContainer.find(".binary");
DOM.entropyMnemonicLength = DOM.entropyContainer.find(".mnemonic-length");
DOM.entropyFilterWarning = DOM.entropyContainer.find(".filter-warning");
DOM.phrase = $(".phrase");
DOM.passphrase = $(".passphrase");
DOM.generateContainer = $(".generate-container");
DOM.generate = $(".generate");
DOM.seed = $(".seed");
DOM.rootKey = $(".root-key");
DOM.litecoinLtubContainer = $(".litecoin-ltub-container");
DOM.litecoinUseLtub = $(".litecoin-use-ltub");
DOM.extendedPrivKey = $(".extended-priv-key");
DOM.extendedPubKey = $(".extended-pub-key");
DOM.bip32tab = $("#bip32-tab");
DOM.bip44tab = $("#bip44-tab");
DOM.bip49tab = $("#bip49-tab");
DOM.bip32panel = $("#bip32");
DOM.bip44panel = $("#bip44");
DOM.bip49panel = $("#bip49");
DOM.bip32path = $("#bip32-path");
DOM.bip44path = $("#bip44-path");
DOM.bip44purpose = $("#bip44 .purpose");
@@ -57,8 +63,18 @@
DOM.bip44accountXprv = $("#bip44 .account-xprv");
DOM.bip44accountXpub = $("#bip44 .account-xpub");
DOM.bip44change = $("#bip44 .change");
DOM.bip49unavailable = $("#bip49 .unavailable");
DOM.bip49available = $("#bip49 .available");
DOM.bip49path = $("#bip49-path");
DOM.bip49purpose = $("#bip49 .purpose");
DOM.bip49coin = $("#bip49 .coin");
DOM.bip49account = $("#bip49 .account");
DOM.bip49accountXprv = $("#bip49 .account-xprv");
DOM.bip49accountXpub = $("#bip49 .account-xpub");
DOM.bip49change = $("#bip49 .change");
DOM.generatedStrength = $(".generate-container .strength");
DOM.hardenedAddresses = $(".hardened-addresses");
DOM.useP2wpkhNestedInP2sh = $(".p2wpkh-nested-in-p2sh");
DOM.addresses = $(".addresses");
DOM.rowsToAdd = $(".rows-to-add");
DOM.more = $(".more");
@@ -87,13 +103,15 @@
DOM.generate.on("click", generateClicked);
DOM.more.on("click", showMore);
DOM.rootKey.on("input", delayedRootKeyChanged);
DOM.litecoinUseLtub.on("change", litecoinUseLtubChanged);
DOM.bip32path.on("input", calcForDerivationPath);
DOM.bip44purpose.on("input", calcForDerivationPath);
DOM.bip44coin.on("input", calcForDerivationPath);
DOM.bip44account.on("input", calcForDerivationPath);
DOM.bip44change.on("input", calcForDerivationPath);
DOM.bip49account.on("input", calcForDerivationPath);
DOM.bip49change.on("input", calcForDerivationPath);
DOM.tab.on("shown.bs.tab", calcForDerivationPath);
DOM.hardenedAddresses.on("change", calcForDerivationPath);
DOM.useP2wpkhNestedInP2sh.on("change", calcForDerivationPath);
DOM.indexToggle.on("click", toggleIndexes);
DOM.addressToggle.on("click", toggleAddresses);
DOM.publicKeyToggle.on("click", togglePublicKeys);
@@ -110,8 +128,18 @@
// Event handlers
function networkChanged(e) {
clearDerivedKeys();
clearAddressesList();
DOM.litecoinLtubContainer.addClass("hidden");
var networkIndex = e.target.value;
networks[networkIndex].onSelect();
var network = networks[networkIndex];
network.onSelect();
if (network.p2wpkhNestedInP2shAvailable) {
showP2wpkhNestedInP2shAvailable();
}
else {
showP2wpkhNestedInP2shUnavailable();
}
if (seed != null) {
phraseChanged();
}
@@ -155,6 +183,10 @@
function delayedPhraseChanged() {
hideValidationError();
seed = null;
bip32RootKey = null;
bip32ExtendedKey = null;
clearAddressesList();
showPending();
if (phraseChangeTimeoutEvent != null) {
clearTimeout(phraseChangeTimeoutEvent);
@@ -164,7 +196,6 @@
function phraseChanged() {
showPending();
hideValidationError();
setMnemonicLanguage();
// Get the mnemonic phrase
var phrase = DOM.phrase.val();
@@ -177,7 +208,6 @@
var passphrase = DOM.passphrase.val();
calcBip32RootKeyFromSeed(phrase, passphrase);
calcForDerivationPath();
hidePending();
}
function delayedEntropyChanged() {
@@ -240,7 +270,6 @@
function rootKeyChanged() {
showPending();
hideValidationError();
// Validate the root key TODO
var rootKeyBase58 = DOM.rootKey.val();
var errorText = validateRootKey(rootKeyBase58);
if (errorText) {
@@ -252,10 +281,25 @@
calcForDerivationPath();
}
function litecoinUseLtubChanged() {
litecoinUseLtub = DOM.litecoinUseLtub.prop("checked");
if (litecoinUseLtub) {
network = bitcoinjs.bitcoin.networks.litecoinLtub;
}
else {
network = bitcoinjs.bitcoin.networks.litecoin;
}
phraseChanged();
}
function calcForDerivationPath() {
showPending();
clearDerivedKeys();
clearAddressesList();
hideValidationError();
showPending();
// Don't show bip49 if it's selected but network doesn't support it
if (bip49TabSelected() && !networkHasBip49()) {
return;
}
// Get the derivation path
var derivationPath = getDerivationPath();
var errorText = findDerivationPathErrors(derivationPath);
@@ -267,8 +311,10 @@
if (bip44TabSelected()) {
displayBip44Info();
}
if (bip49TabSelected()) {
displayBip49Info();
}
displayBip32Info();
hidePending();
}
function generateClicked() {
@@ -338,11 +384,11 @@
function calcBip32RootKeyFromSeed(phrase, passphrase) {
seed = mnemonic.toSeed(phrase, passphrase);
bip32RootKey = bitcoin.HDNode.fromSeedHex(seed, network);
bip32RootKey = bitcoinjs.bitcoin.HDNode.fromSeedHex(seed, network);
}
function calcBip32RootKeyFromBase58(rootKeyBase58) {
bip32RootKey = bitcoin.HDNode.fromBase58(rootKeyBase58, network);
bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, network);
}
function calcBip32ExtendedKey(path) {
@@ -360,7 +406,7 @@
continue;
}
var hardened = bit[bit.length-1] == "'";
var isPriv = "privKey" in extendedKey;
var isPriv = !(extendedKey.isNeutered());
var invalidDerivationPath = hardened && !isPriv;
if (invalidDerivationPath) {
extendedKey = null;
@@ -416,7 +462,7 @@
function validateRootKey(rootKeyBase58) {
try {
bitcoin.HDNode.fromBase58(rootKeyBase58);
bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, network);
}
catch (e) {
return "Invalid root key";
@@ -440,6 +486,21 @@
console.log("Using derivation path from BIP44 tab: " + derivationPath);
return derivationPath;
}
if (bip49TabSelected()) {
var purpose = parseIntNoNaN(DOM.bip49purpose.val(), 49);
var coin = parseIntNoNaN(DOM.bip49coin.val(), 0);
var account = parseIntNoNaN(DOM.bip49account.val(), 0);
var change = parseIntNoNaN(DOM.bip49change.val(), 0);
var path = "m/";
path += purpose + "'/";
path += coin + "'/";
path += account + "'/";
path += change;
DOM.bip49path.val(path);
var derivationPath = DOM.bip49path.val();
console.log("Using derivation path from BIP49 tab: " + derivationPath);
return derivationPath;
}
else if (bip32TabSelected()) {
var derivationPath = DOM.bip32path.val();
console.log("Using derivation path from BIP32 tab: " + derivationPath);
@@ -489,8 +550,10 @@
return "No root key";
}
// Check no hardened derivation path when using xpub keys
var hardened = path.indexOf("'") > -1;
var isXpubkey = !("privKey" in bip32RootKey);
var hardenedPath = path.indexOf("'") > -1;
var hardenedAddresses = bip32TabSelected() && DOM.hardenedAddresses.prop("checked");
var hardened = hardenedPath || hardenedAddresses;
var isXpubkey = bip32RootKey.isNeutered();
if (hardened && isXpubkey) {
return "Hardened derivation path is invalid with xpub key";
}
@@ -509,24 +572,42 @@
// Calculate the account extended keys
var accountExtendedKey = calcBip32ExtendedKey(path);
var accountXprv = accountExtendedKey.toBase58();
var accountXpub = accountExtendedKey.toBase58(false);
var accountXpub = accountExtendedKey.neutered().toBase58();
// Display the extended keys
DOM.bip44accountXprv.val(accountXprv);
DOM.bip44accountXpub.val(accountXpub);
}
function displayBip49Info() {
// Get the derivation path for the account
var purpose = parseIntNoNaN(DOM.bip49purpose.val(), 49);
var coin = parseIntNoNaN(DOM.bip49coin.val(), 0);
var account = parseIntNoNaN(DOM.bip49account.val(), 0);
var path = "m/";
path += purpose + "'/";
path += coin + "'/";
path += account + "'/";
// Calculate the account extended keys
var accountExtendedKey = calcBip32ExtendedKey(path);
var accountXprv = accountExtendedKey.toBase58();
var accountXpub = accountExtendedKey.neutered().toBase58();
// Display the extended keys
DOM.bip49accountXprv.val(accountXprv);
DOM.bip49accountXpub.val(accountXpub);
}
function displayBip32Info() {
// Display the key
DOM.seed.val(seed);
var rootKey = bip32RootKey.toBase58();
DOM.rootKey.val(rootKey);
var xprvkeyB58 = "NA";
if (bip32ExtendedKey.privKey) {
if (!bip32ExtendedKey.isNeutered()) {
xprvkeyB58 = bip32ExtendedKey.toBase58();
}
var extendedPrivKey = xprvkeyB58;
DOM.extendedPrivKey.val(extendedPrivKey);
var extendedPubKey = bip32ExtendedKey.toBase58(false);
var extendedPubKey = bip32ExtendedKey.neutered().toBase58();
DOM.extendedPubKey.val(extendedPubKey);
// Display the addresses and privkeys
clearAddressesList();
@@ -542,21 +623,25 @@
for (var i=0; i<rows.length; i++) {
rows[i].shouldGenerate = false;
}
hidePending();
}
for (var i=0; i<total; i++) {
var index = i + start;
rows.push(new TableRow(index));
var isLast = i == total - 1;
rows.push(new TableRow(index, isLast));
}
})());
}
function TableRow(index) {
function TableRow(index, isLast) {
var self = this;
this.shouldGenerate = true;
var useHardenedAddresses = DOM.hardenedAddresses.prop("checked");
var isP2wpkhNestedInP2sh = bip49TabSelected() || (bip32TabSelected() && useP2wpkhNestedInP2sh());
var p2wpkhNestedInP2shAvailable = networkHasBip49();
function init() {
calculateValues();
@@ -567,7 +652,7 @@
if (!self.shouldGenerate) {
return;
}
var key = "";
var key = "NA";
if (useHardenedAddresses) {
key = bip32ExtendedKey.deriveHardened(index);
}
@@ -576,17 +661,17 @@
}
var address = key.getAddress().toString();
var privkey = "NA";
if (key.privKey) {
privkey = key.privKey.toWIF(network);
if (!key.isNeutered()) {
privkey = key.keyPair.toWIF(network);
}
var pubkey = key.pubKey.toHex();
var pubkey = key.getPublicKeyBuffer().toString('hex');
var indexText = getDerivationPath() + "/" + index;
if (useHardenedAddresses) {
indexText = indexText + "'";
}
// Ethereum values are different
if (networks[DOM.network.val()].name == "Ethereum") {
var privKeyBuffer = key.privKey.d.toBuffer();
if (networks[DOM.network.val()].name == "ETH - Ethereum") {
var privKeyBuffer = key.keyPair.d.toBuffer();
privkey = privKeyBuffer.toString('hex');
var addressBuffer = ethUtil.privateToAddress(privKeyBuffer);
var hexAddress = addressBuffer.toString('hex');
@@ -596,11 +681,25 @@
pubkey = ethUtil.addHexPrefix(pubkey);
}
// Ripple values are different
if (networks[DOM.network.val()].name == "Ripple") {
if (networks[DOM.network.val()].name == "XRP - Ripple") {
privkey = convertRipplePriv(privkey);
address = convertRippleAdrr(address);
}
// BIP49 addresses are different
if (isP2wpkhNestedInP2sh) {
if (!p2wpkhNestedInP2shAvailable) {
return;
}
var keyhash = bitcoinjs.bitcoin.crypto.hash160(key.getPublicKeyBuffer());
var scriptsig = bitcoinjs.bitcoin.script.witnessPubKeyHash.output.encode(keyhash);
var addressbytes = bitcoinjs.bitcoin.crypto.hash160(scriptsig);
var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes);
address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network)
}
addAddressToList(indexText, address, pubkey, privkey);
if (isLast) {
hidePending();
}
}, 50)
}
@@ -627,7 +726,7 @@
function clearDisplay() {
clearAddressesList();
clearKey();
clearKeys();
hideValidationError();
}
@@ -643,10 +742,20 @@
}
}
function clearKey() {
function clearKeys() {
clearRootKey();
clearDerivedKeys();
}
function clearRootKey() {
DOM.rootKey.val("");
}
function clearDerivedKeys() {
DOM.extendedPrivKey.val("");
DOM.extendedPubKey.val("");
DOM.bip44accountXprv.val("");
DOM.bip44accountXpub.val("");
}
function addAddressToList(indexText, address, pubkey, privkey) {
@@ -734,6 +843,9 @@
var option = $("<option>");
option.attr("value", i);
option.text(network.name);
if (network.name == "BTC - Bitcoin") {
option.prop("selected", true);
}
DOM.phraseNetwork.append(option);
}
}
@@ -950,6 +1062,16 @@
DOM.entropyWordCount.text(wordCount);
DOM.entropyBinary.text(entropy.binaryStr);
DOM.entropyBitsPerEvent.text(bitsPerEvent);
// detect and warn of filtering
var rawNoSpaces = DOM.entropy.val().replace(/\s/g, "");
var cleanNoSpaces = entropy.cleanStr.replace(/\s/g, "");
var isFiltered = rawNoSpaces.length != cleanNoSpaces.length;
if (isFiltered) {
DOM.entropyFilterWarning.removeClass('hidden');
}
else {
DOM.entropyFilterWarning.addClass('hidden');
}
}
function getEntropyTypeStr(entropy) {
@@ -1055,140 +1177,239 @@
return DOM.bip32tab.hasClass("active");
}
function useP2wpkhNestedInP2sh() {
return DOM.useP2wpkhNestedInP2sh.prop("checked");
}
function networkHasBip49() {
return networks[DOM.network.val()].p2wpkhNestedInP2shAvailable;
}
function bip49TabSelected() {
return DOM.bip49tab.hasClass("active");
}
function setHdCoin(coinValue) {
DOM.bip44coin.val(coinValue);
DOM.bip49coin.val(coinValue);
}
function showP2wpkhNestedInP2shAvailable() {
DOM.bip49unavailable.addClass("hidden");
DOM.bip49available.removeClass("hidden");
DOM.useP2wpkhNestedInP2sh.prop("disabled", false);
}
function showP2wpkhNestedInP2shUnavailable() {
DOM.bip49available.addClass("hidden");
DOM.bip49unavailable.removeClass("hidden");
DOM.useP2wpkhNestedInP2sh.prop("disabled", true);
DOM.useP2wpkhNestedInP2sh.prop("checked", false);
}
var networks = [
{
name: "Bitcoin",
name: "BCH - Bitcoin Cash",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.bitcoin;
DOM.bip44coin.val(0);
network = bitcoinjs.bitcoin.networks.bitcoin;
setHdCoin(145);
},
},
{
name: "Bitcoin Testnet",
name: "BTC - Bitcoin",
p2wpkhNestedInP2shAvailable: true,
onSelect: function() {
network = bitcoin.networks.testnet;
DOM.bip44coin.val(1);
network = bitcoinjs.bitcoin.networks.bitcoin;
setHdCoin(0);
},
},
{
name: "CLAM",
name: "BTC - Bitcoin Testnet",
p2wpkhNestedInP2shAvailable: true,
onSelect: function() {
network = bitcoin.networks.clam;
DOM.bip44coin.val(23);
network = bitcoinjs.bitcoin.networks.testnet;
setHdCoin(1);
},
},
{
name: "Dogecoin",
name: "CLAM - Clams",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.dogecoin;
DOM.bip44coin.val(3);
network = bitcoinjs.bitcoin.networks.clam;
setHdCoin(23);
},
},
{
name: "DASH",
name: "CRW - Crown",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.dash;
DOM.bip44coin.val(5);
network = bitcoinjs.bitcoin.networks.crown;
setHdCoin(72);
},
},
{
name: "DASH Testnet",
name: "DASH - Dash",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.dashtn;
DOM.bip44coin.val(1);
network = bitcoinjs.bitcoin.networks.dash;
setHdCoin(5);
},
},
{
name: "Ethereum",
name: "DASH - Dash Testnet",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.bitcoin;
DOM.bip44coin.val(60);
network = bitcoinjs.bitcoin.networks.dashtn;
setHdCoin(1);
},
},
{
name: "GAME",
name: "DOGE - Dogecoin",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.game;
DOM.bip44coin.val(101);
network = bitcoinjs.bitcoin.networks.dogecoin;
setHdCoin(3);
},
},
{
name: "Jumbucks",
name: "ETH - Ethereum",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.jumbucks;
DOM.bip44coin.val(26);
network = bitcoinjs.bitcoin.networks.bitcoin;
setHdCoin(60);
},
},
{
name: "Litecoin",
name: "GAME - GameCredits",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.litecoin;
DOM.bip44coin.val(2);
network = bitcoinjs.bitcoin.networks.game;
setHdCoin(101);
},
},
{
name: "Namecoin",
name: "JBS - Jumbucks",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.namecoin;
DOM.bip44coin.val(7);
network = bitcoinjs.bitcoin.networks.jumbucks;
setHdCoin(26);
},
},
{
name: "Peercoin",
name: "LTC - Litecoin",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.peercoin;
DOM.bip44coin.val(6);
network = bitcoinjs.bitcoin.networks.litecoin;
setHdCoin(2);
DOM.litecoinLtubContainer.removeClass("hidden");
},
},
{
name: "Ripple",
name: "MAZA - Maza",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.bitcoin;
DOM.bip44coin.val(144);
network = bitcoinjs.bitcoin.networks.maza;
setHdCoin(13);
},
},
{
name: "NMC - Namecoin",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoinjs.bitcoin.networks.namecoin;
setHdCoin(7);
},
},
{
name: "ShadowCash",
name: "PIVX - PIVX",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.shadow;
DOM.bip44coin.val(35);
network = bitcoinjs.bitcoin.networks.pivx;
setHdCoin(119);
},
},
{
name: "ShadowCash Testnet",
name: "PIVX - PIVX Testnet",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.shadowtn;
DOM.bip44coin.val(1);
network = bitcoinjs.bitcoin.networks.pivxtestnet;
setHdCoin(1);
},
},
{
name: "Slimcoin",
name: "PPC - Peercoin",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.slimcoin;
DOM.bip44coin.val(63);
network = bitcoinjs.bitcoin.networks.peercoin;
setHdCoin(6);
},
},
{
name: "Slimcoin Testnet",
name: "SDC - ShadowCash",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.slimcointn;
DOM.bip44coin.val(111);
network = bitcoinjs.bitcoin.networks.shadow;
setHdCoin(35);
},
},
{
name: "Viacoin",
name: "SDC - ShadowCash Testnet",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.viacoin;
DOM.bip44coin.val(14);
network = bitcoinjs.bitcoin.networks.shadowtn;
setHdCoin(1);
},
},
{
name: "Viacoin Testnet",
name: "SLM - Slimcoin",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoin.networks.viacointestnet;
DOM.bip44coin.val(1);
network = bitcoinjs.bitcoin.networks.slimcoin;
setHdCoin(63);
},
},
{
name: "SLM - Slimcoin Testnet",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoinjs.bitcoin.networks.slimcointn;
setHdCoin(111);
},
},
{
name: "VIA - Viacoin",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoinjs.bitcoin.networks.viacoin;
setHdCoin(14);
},
},
{
name: "VIA - Viacoin Testnet",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoinjs.bitcoin.networks.viacointestnet;
setHdCoin(1);
},
},
{
name: "XMY - Myriadcoin",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoinjs.bitcoin.networks.myriadcoin;
setHdCoin(90);
},
},
{
name: "XRP - Ripple",
p2wpkhNestedInP2shAvailable: false,
onSelect: function() {
network = bitcoinjs.bitcoin.networks.bitcoin;
setHdCoin(144);
},
}
]
var clients = [

View File

@@ -23,6 +23,6 @@ this.getLength()-a.getLength())return this;for(var c=l.glog(this.get(0))-l.glog(
55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,
45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];p.getRSBlocks=function(a,c){var d=p.getRsBlockTable(a,c);if(void 0==d)throw Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+c);for(var b=d.length/3,e=[],f=0;f<b;f++)for(var h=d[3*f+0],g=d[3*f+1],j=d[3*f+2],l=0;l<h;l++)e.push(new p(g,j));return e};p.getRsBlockTable=function(a,c){switch(c){case 1:return p.RS_BLOCK_TABLE[4*(a-1)+0];case 0:return p.RS_BLOCK_TABLE[4*(a-1)+1];case 3:return p.RS_BLOCK_TABLE[4*
(a-1)+2];case 2:return p.RS_BLOCK_TABLE[4*(a-1)+3]}};t.prototype={get:function(a){return 1==(this.buffer[Math.floor(a/8)]>>>7-a%8&1)},put:function(a,c){for(var d=0;d<c;d++)this.putBit(1==(a>>>c-d-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var g=Math.ceil((i+1)*b)-Math.floor(i*b),
correctLevel:3,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var g=Math.ceil((i+1)*b)-Math.floor(i*b),
j=Math.ceil((f+1)*b)-Math.floor(f*b);d.fillRect(Math.round(i*b),Math.round(f*e),g,j)}}else{a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();c=r("<table></table>").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e<a.getModuleCount();e++){f=r("<tr></tr>").css("height",b+"px").appendTo(c);for(i=0;i<a.getModuleCount();i++)r("<td></td>").css("width",
d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;$(a).appendTo(this)})}})($);

View File

@@ -25,4 +25,4 @@ var time_estimates;time_estimates={estimate_attack_times:function(e){var t,n,s,o
},{}]},{},[4])(4)
});
//# sourceMappingURL=zxcvbn.js.map

758
tests.js
View File

@@ -281,7 +281,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Bitcoin Testnet";
return $(this).html() == "BTC - Bitcoin Testnet";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -311,7 +311,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Litecoin";
return $(this).html() == "LTC - Litecoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -341,7 +341,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Ripple";
return $(this).html() == "XRP - Ripple";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -371,7 +371,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Dogecoin";
return $(this).html() == "DOGE - Dogecoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -401,7 +401,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "ShadowCash";
return $(this).html() == "SDC - ShadowCash";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -431,7 +431,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "ShadowCash Testnet";
return $(this).html() == "SDC - ShadowCash Testnet";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -461,7 +461,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Viacoin";
return $(this).html() == "VIA - Viacoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -491,7 +491,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Viacoin Testnet";
return $(this).html() == "VIA - Viacoin Testnet";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -521,7 +521,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Jumbucks";
return $(this).html() == "JBS - Jumbucks";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -551,7 +551,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "CLAM";
return $(this).html() == "CLAM - Clams";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -571,6 +571,36 @@ page.open(url, function(status) {
});
},
// Network can be set to crown
function() {
page.open(url, function(status) {
// set the phrase and coin
var expected = "18pWSwSUAQdiwMHUfFZB1fM2xue9X1FqE5";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "CRW - Crown";
}).prop("selected", true);
$(".network").trigger("change");
});
// check the address is generated correctly
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".address:first").text();
});
if (actual != expected) {
console.log("CRW address is incorrect");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
},
// Network can be set to dash
function() {
page.open(url, function(status) {
@@ -581,7 +611,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "DASH";
return $(this).html() == "DASH - Dash";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -610,7 +640,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "DASH Testnet";
return $(this).html() == "DASH - Dash Testnet";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -640,7 +670,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "GAME";
return $(this).html() == "GAME - GameCredits";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -670,7 +700,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Namecoin";
return $(this).html() == "NMC - Namecoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -700,7 +730,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Peercoin";
return $(this).html() == "PPC - Peercoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -731,7 +761,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Ethereum";
return $(this).html() == "ETH - Ethereum";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -792,7 +822,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Slimcoin";
return $(this).html() == "SLM - Slimcoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -822,7 +852,7 @@ page.open(url, function(status) {
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "Slimcoin Testnet";
return $(this).html() == "SLM - Slimcoin Testnet";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -842,6 +872,156 @@ page.open(url, function(status) {
});
},
// Network can be set to bitcoin cash
function() {
page.open(url, function(status) {
// set the phrase and coin
var expected = "1JKvb6wKtsjNoCRxpZ4DGrbniML7z5U16A";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "BCH - Bitcoin Cash";
}).prop("selected", true);
$(".network").trigger("change");
});
// check the address is generated correctly
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".address:first").text();
});
if (actual != expected) {
console.log("Bitcoin Cash address is incorrect");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
},
// Network can be set to myriadcoin
function() {
page.open(url, function(status) {
// set the phrase and coin
var expected = "MJEswvRR46wh9BoiVj9DzKYMBkCramhoBV";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "XMY - Myriadcoin";
}).prop("selected", true);
$(".network").trigger("change");
});
// check the address is generated correctly
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".address:first").text();
});
if (actual != expected) {
console.log("Myriadcoin address is incorrect");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
},
// Network can be set to pivx
function() {
page.open(url, function(status) {
// set the phrase and coin
var expected = "DBxgT7faCuno7jmtKuu6KWCiwqsVPqh1tS";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "PIVX - PIVX";
}).prop("selected", true);
$(".network").trigger("change");
});
// check the address is generated correctly
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".address:first").text();
});
if (actual != expected) {
console.log("PIVX address is incorrect");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
},
// Network can be set to pivx testnet
function() {
page.open(url, function(status) {
// set the phrase and coin
var expected = "yB5U384n6dGkVE3by5y9VdvHHPwPg68fQj";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "PIVX - PIVX Testnet";
}).prop("selected", true);
$(".network").trigger("change");
});
// check the address is generated correctly
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".address:first").text();
});
if (actual != expected) {
console.log("PIVX Testnet address is incorrect");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
},
// Network can be set to maza
function() {
page.open(url, function(status) {
// set the phrase and coin
var expected = "MGW4Bmi2NEm4PxSjgeFwhP9vg18JHoRnfw";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
$(".network option[selected]").removeAttr("selected");
$(".network option").filter(function() {
return $(this).html() == "MAZA - Maza";
}).prop("selected", true);
$(".network").trigger("change");
});
// check the address is generated correctly
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".address:first").text();
});
if (actual != expected) {
console.log("Maza address is incorrect");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
},
// BIP39 seed is set from phrase
function() {
page.open(url, function(status) {
@@ -998,70 +1178,6 @@ page.open(url, function(status) {
});
},
// BIP44 purpose field changes address list
function() {
page.open(url, function(status) {
// set the phrase
var expected = "1JbDzRJ2cDT8aat2xwKd6Pb2zzavow5MhF";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
});
waitForGenerate(function() {
// change the bip44 purpose field to 45
page.evaluate(function() {
$("#bip44 .purpose").val("45");
$("#bip44 .purpose").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("BIP44 purpose field generates incorrect address");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
});
},
// BIP44 coin field changes address list
function() {
page.open(url, function(status) {
// set the phrase
var expected = "1F6dB2djQYrxoyfZZmfr6D5voH8GkJTghk";
page.evaluate(function() {
$(".phrase").val("abandon abandon ability");
$(".phrase").trigger("input");
});
waitForGenerate(function() {
// change the bip44 purpose field to 45
page.evaluate(function() {
$("#bip44 .coin").val("1");
$("#bip44 .coin").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("BIP44 coin field generates incorrect address");
console.log("Expected: " + expected);
console.log("Actual: " + actual);
fail();
}
next();
});
});
});
},
// BIP44 account field changes address list
function() {
page.open(url, function(status) {
@@ -2014,7 +2130,7 @@ page.open(url, function(status) {
// 4) switch from bitcoin to litecoin
page.evaluate(function() {
$(".network option").filter(function() {
return $(this).html() == "Litecoin";
return $(this).html() == "LTC - Litecoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -2060,7 +2176,7 @@ page.open(url, function(status) {
// switch from bitcoin to clam
page.evaluate(function() {
$(".network option").filter(function() {
return $(this).html() == "CLAM";
return $(this).html() == "CLAM - Clams";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -2094,7 +2210,7 @@ page.open(url, function(status) {
// 4) switch from bitcoin to viacoin
page.evaluate(function() {
$(".network option").filter(function() {
return $(this).html() == "Viacoin";
return $(this).html() == "VIA - Viacoin";
}).prop("selected", true);
$(".network").trigger("change");
});
@@ -3362,7 +3478,7 @@ page.open(url, function(status) {
// check the BIP44 account extended private key
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".account-xprv").val();
return $("#bip44 .account-xprv").val();
});
if (actual != expected) {
console.log("BIP44 account extended private key is incorrect");
@@ -3388,7 +3504,7 @@ page.open(url, function(status) {
// check the BIP44 account extended public key
waitForGenerate(function() {
var actual = page.evaluate(function() {
return $(".account-xpub").val();
return $("#bip44 .account-xpub").val();
});
if (actual != expected) {
console.log("BIP44 account extended public key is incorrect");
@@ -3760,6 +3876,474 @@ page.open(url, function(status) {
});
},
// 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();
});
});
});
},
// If you wish to add more tests, do so here...
// Here is a blank test template