mirror of
https://github.com/OneKeyHQ/bip39.git
synced 2026-04-06 02:43:49 +00:00
25204
bip39-standalone.html
25204
bip39-standalone.html
File diff suppressed because one or more lines are too long
10
compile.py
10
compile.py
@@ -6,7 +6,7 @@ import datetime
|
||||
|
||||
# It removes script and style tags and replaces with the file content.
|
||||
|
||||
f = open('src/index.html')
|
||||
f = open('src/index.html', "r", encoding="utf-8")
|
||||
page = f.read()
|
||||
f.close()
|
||||
|
||||
@@ -18,7 +18,7 @@ scripts = scriptsFinder.findall(page)
|
||||
|
||||
for script in scripts:
|
||||
filename = os.path.join("src", script)
|
||||
s = open(filename)
|
||||
s = open(filename, "r", encoding="utf-8")
|
||||
scriptContent = "<script>%s</script>" % s.read()
|
||||
s.close()
|
||||
scriptTag = """<script src="%s"></script>""" % script
|
||||
@@ -32,7 +32,7 @@ styles = stylesFinder.findall(page)
|
||||
|
||||
for style in styles:
|
||||
filename = os.path.join("src", style)
|
||||
s = open(filename)
|
||||
s = open(filename, "r", encoding="utf-8")
|
||||
styleContent = "<style>%s</style>" % s.read()
|
||||
s.close()
|
||||
styleTag = """<link rel="stylesheet" href="%s">""" % style
|
||||
@@ -41,8 +41,8 @@ for style in styles:
|
||||
|
||||
# Write the standalone file
|
||||
|
||||
f = open('bip39-standalone.html', 'w')
|
||||
f = open('bip39-standalone.html', 'w', encoding="utf-8")
|
||||
f.write(page)
|
||||
f.close()
|
||||
|
||||
print "%s - DONE" % datetime.datetime.now()
|
||||
print("%s - DONE" % datetime.datetime.now())
|
||||
|
||||
22
readme.md
22
readme.md
@@ -28,6 +28,28 @@ import private keys into a wallet or supply someone with a list of addresses.
|
||||
|
||||
The BIP32 keys can be used at [bip32.org](https://bip32.org) if desired.
|
||||
|
||||
## Donations
|
||||
|
||||
Since this project is the efforts of many people, most of which don't appear in
|
||||
the obvious places like code or issues, donating to the project itself causes
|
||||
significant operational difficulties.
|
||||
|
||||
As a result, if you would like to support this project financially you are
|
||||
encouraged to donate to one of the many groups that makes the internet a place
|
||||
amenable to projects such as this one.
|
||||
|
||||
[Donation-accepting organizations and projects](https://en.bitcoin.it/wiki/Donation-accepting_organizations_and_projects)
|
||||
|
||||
If the list is too difficult to choose from, the EFF is a good choice.
|
||||
|
||||
[Electronic Frontier Foundation](https://supporters.eff.org/donate)
|
||||
|
||||
or for a direct bitcoin address, consider donating to the
|
||||
[Free Software Foundation](https://www.fsf.org/about/ways-to-donate/)
|
||||
at 1PC9aZC4hNX2rmmrt7uHTfYAS3hRbph4UN
|
||||
|
||||

|
||||
|
||||
## Making changes
|
||||
|
||||
Please do not make modifications to `bip39-standalone.html`, since they will
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
||||
<meta content="bitcoin mnemonic converter" name="description" />
|
||||
<meta content="Ian Coleman" name="author" />
|
||||
<link type="image/x-icon" rel="icon" href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAF0lEQVRIx2NgGAWjYBSMglEwCkbBSAcACBAAAeaR9cIAAAAASUVORK5CYII=" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
@@ -182,9 +183,9 @@
|
||||
<label class="col-sm-3 control-label" data-translate>Mnemonic Length</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="mnemonic-length form-control">
|
||||
<option value="raw" data-translate>From entropy length (3 words per 32 bits)</option>
|
||||
<option value="raw" selected data-translate>Use Raw Entropy (3 words per 32 bits)</option>
|
||||
<option value="12">12 <span data-translate>Words</span></option>
|
||||
<option value="15" selected>15 <span data-translate>Words</option>
|
||||
<option value="15">15 <span data-translate>Words</option>
|
||||
<option value="18">18 <span data-translate>Words</span></option>
|
||||
<option value="21">21 <span data-translate>Words</span></option>
|
||||
<option value="24">24 <span data-translate>Words</span></option>
|
||||
@@ -367,6 +368,15 @@
|
||||
<a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki" target="_blank">BIP32 spec</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="bip32-client" class="col-sm-2 control-label" data-translate>Client</label>
|
||||
<div class="col-sm-10">
|
||||
<select id="bip32-client" class="client form-control">
|
||||
<option value="custom">Custom derivation path</option>
|
||||
<!-- populated by javascript -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="bip32-path" class="col-sm-2 control-label" data-translate>BIP32 Derivation Path</label>
|
||||
<div class="col-sm-10">
|
||||
@@ -392,6 +402,18 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="core-path" class="col-sm-2 control-label" data-translate>Multibit</label>
|
||||
<div class="col-sm-10">
|
||||
<p class="form-control no-border">
|
||||
<span data-translate-html>Use path <code>m/0'/0</code>.</span>
|
||||
</p>
|
||||
<p class="form-control no-border">
|
||||
<span data-translate>For more info see</span>
|
||||
<a href="https://multibit.org/" target="_blank">MultiBit HD</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" data-translate>Block Explorers</label>
|
||||
<div class="col-sm-10">
|
||||
@@ -651,12 +673,17 @@
|
||||
<td class="privkey"><span data-show-qr></span></td>
|
||||
</tr>
|
||||
</script>
|
||||
<script src="js/polyfill.es6.js"></script>
|
||||
<script src="js/basex.js"></script>
|
||||
<script src="js/unorm.js"></script>
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<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-extensions.js"></script>
|
||||
<script src="js/ethereumjs-util.js"></script>
|
||||
<script src="js/ripple-util.js"></script>
|
||||
<script src="js/sjcl-bip39.js"></script>
|
||||
<script src="js/translate.js"></script>
|
||||
<script src="js/phrases_en.js"></script>
|
||||
|
||||
2010
src/js/basex.js
Normal file
2010
src/js/basex.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,16 @@ bitcoin.networks.dash = {
|
||||
wif: 0xcc,
|
||||
};
|
||||
|
||||
bitcoin.networks.game = {
|
||||
bip32: {
|
||||
public: 0x0488b21e,
|
||||
private: 0x0488ade4
|
||||
},
|
||||
pubKeyHash: 0x26,
|
||||
scriptHash: 0x05,
|
||||
wif: 0xa6,
|
||||
};
|
||||
|
||||
bitcoin.networks.namecoin = {
|
||||
bip32: {
|
||||
public: 0x0488b21e,
|
||||
|
||||
18762
src/js/ethereumjs-util.js
Normal file
18762
src/js/ethereumjs-util.js
Normal file
File diff suppressed because it is too large
Load Diff
143
src/js/index.js
143
src/js/index.js
@@ -23,6 +23,7 @@
|
||||
|
||||
var DOM = {};
|
||||
DOM.network = $(".network");
|
||||
DOM.bip32Client = $("#bip32-client");
|
||||
DOM.phraseNetwork = $("#network-phrase");
|
||||
DOM.useEntropy = $(".use-entropy");
|
||||
DOM.entropyContainer = $(".entropy-container");
|
||||
@@ -77,6 +78,7 @@
|
||||
function init() {
|
||||
// Events
|
||||
DOM.network.on("change", networkChanged);
|
||||
DOM.bip32Client.on("change", bip32ClientChanged);
|
||||
DOM.useEntropy.on("change", setEntropyVisibility);
|
||||
DOM.entropy.on("input", delayedEntropyChanged);
|
||||
DOM.entropyMnemonicLength.on("change", entropyChanged);
|
||||
@@ -102,6 +104,7 @@
|
||||
hidePending();
|
||||
hideValidationError();
|
||||
populateNetworkSelect();
|
||||
populateClientSelect();
|
||||
}
|
||||
|
||||
// Event handlers
|
||||
@@ -117,6 +120,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
function bip32ClientChanged(e) {
|
||||
var clientIndex = DOM.bip32Client.val();
|
||||
if (clientIndex == "custom") {
|
||||
DOM.bip32path.prop("readonly", false);
|
||||
}
|
||||
else {
|
||||
DOM.bip32path.prop("readonly", true);
|
||||
clients[clientIndex].onSelect();
|
||||
if (seed != null) {
|
||||
phraseChanged();
|
||||
}
|
||||
else {
|
||||
rootKeyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setEntropyVisibility() {
|
||||
if (isUsingOwnEntropy()) {
|
||||
DOM.entropyContainer.removeClass("hidden");
|
||||
@@ -564,6 +584,20 @@
|
||||
if (useHardenedAddresses) {
|
||||
indexText = indexText + "'";
|
||||
}
|
||||
// Ethereum values are different
|
||||
if (networks[DOM.network.val()].name == "Ethereum") {
|
||||
var privKeyBuffer = key.privKey.d.toBuffer();
|
||||
privkey = privKeyBuffer.toString('hex');
|
||||
var addressBuffer = ethUtil.privateToAddress(privKeyBuffer);
|
||||
var hexAddress = addressBuffer.toString('hex');
|
||||
var checksumAddress = ethUtil.toChecksumAddress(hexAddress);
|
||||
address = ethUtil.addHexPrefix(checksumAddress);
|
||||
}
|
||||
// Ripple values are different
|
||||
if (networks[DOM.network.val()].name == "Ripple") {
|
||||
privkey = convertRipplePriv(privkey);
|
||||
address = convertRippleAdrr(address);
|
||||
}
|
||||
addAddressToList(indexText, address, pubkey, privkey);
|
||||
}, 50)
|
||||
}
|
||||
@@ -702,6 +736,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
function populateClientSelect() {
|
||||
for (var i=0; i<clients.length; i++) {
|
||||
var client = clients[i];
|
||||
var option = $("<option>");
|
||||
option.attr("value", i);
|
||||
option.text(client.name);
|
||||
DOM.bip32Client.append(option);
|
||||
}
|
||||
}
|
||||
|
||||
function getLanguage() {
|
||||
var defaultLanguage = "english";
|
||||
// Try to get from existing phrase
|
||||
@@ -1047,10 +1091,10 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Litecoin",
|
||||
name: "CLAM",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.litecoin;
|
||||
DOM.bip44coin.val(2);
|
||||
network = bitcoin.networks.clam;
|
||||
DOM.bip44coin.val(23);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1060,6 +1104,62 @@
|
||||
DOM.bip44coin.val(3);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DASH",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.dash;
|
||||
DOM.bip44coin.val(5);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ethereum",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.bitcoin;
|
||||
DOM.bip44coin.val(60);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GAME",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.game;
|
||||
DOM.bip44coin.val(101);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Jumbucks",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.jumbucks;
|
||||
DOM.bip44coin.val(26);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Litecoin",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.litecoin;
|
||||
DOM.bip44coin.val(2);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Namecoin",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.namecoin;
|
||||
DOM.bip44coin.val(7);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Peercoin",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.peercoin;
|
||||
DOM.bip44coin.val(6);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ripple",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.bitcoin;
|
||||
DOM.bip44coin.val(144);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ShadowCash",
|
||||
onSelect: function() {
|
||||
@@ -1088,41 +1188,30 @@
|
||||
DOM.bip44coin.val(1);
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
var clients = [
|
||||
{
|
||||
name: "Jumbucks",
|
||||
name: "Bitcoin Core",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.jumbucks;
|
||||
DOM.bip44coin.val(26);
|
||||
DOM.bip32path.val("m/0'/0'");
|
||||
DOM.hardenedAddresses.prop('checked', true);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "CLAM",
|
||||
name: "blockchain.info",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.clam;
|
||||
DOM.bip44coin.val(23);
|
||||
DOM.bip32path.val("m/44'/0'/0'");
|
||||
DOM.hardenedAddresses.prop('checked', false);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DASH",
|
||||
name: "MultiBit HD",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.dash;
|
||||
DOM.bip44coin.val(5);
|
||||
DOM.bip32path.val("m/0'/0");
|
||||
DOM.hardenedAddresses.prop('checked', false);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Namecoin",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.namecoin;
|
||||
DOM.bip44coin.val(7);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Peercoin",
|
||||
onSelect: function() {
|
||||
network = bitcoin.networks.peercoin;
|
||||
DOM.bip44coin.val(6);
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
init();
|
||||
|
||||
@@ -130,10 +130,11 @@ var Mnemonic = function(language) {
|
||||
|
||||
self.toSeed = function(mnemonic, passphrase) {
|
||||
passphrase = passphrase || '';
|
||||
mnemonic = self.joinWords(self.splitWords(self.normalizeString(mnemonic))); // removes blanks
|
||||
mnemonic = self.joinWords(self.splitWords(mnemonic)); // removes duplicate blanks
|
||||
var mnemonicNormalized = self.normalizeString(mnemonic);
|
||||
passphrase = self.normalizeString(passphrase)
|
||||
passphrase = "mnemonic" + passphrase;
|
||||
var mnemonicBits = sjcl.codec.utf8String.toBits(mnemonic);
|
||||
var mnemonicBits = sjcl.codec.utf8String.toBits(mnemonicNormalized);
|
||||
var passphraseBits = sjcl.codec.utf8String.toBits(passphrase);
|
||||
var result = sjcl.misc.pbkdf2(mnemonicBits, passphraseBits, PBKDF2_ROUNDS, 512, hmacSHA512);
|
||||
var hashHex = sjcl.codec.hex.fromBits(result);
|
||||
|
||||
3793
src/js/polyfill.es6.js
Normal file
3793
src/js/polyfill.es6.js
Normal file
File diff suppressed because it is too large
Load Diff
10
src/js/ripple-util.js
Normal file
10
src/js/ripple-util.js
Normal file
@@ -0,0 +1,10 @@
|
||||
function convertRippleAdrr(address) {
|
||||
return window.basex('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz').encode(
|
||||
window.basex('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz').decode(address)
|
||||
)
|
||||
}
|
||||
|
||||
function convertRipplePriv(priv) {
|
||||
return window.basex('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz').decode(priv).toString("hex").slice(2)
|
||||
}
|
||||
|
||||
442
src/js/unorm.js
Normal file
442
src/js/unorm.js
Normal file
File diff suppressed because one or more lines are too long
321
tests.js
321
tests.js
@@ -4,7 +4,7 @@
|
||||
|
||||
var page = require('webpage').create();
|
||||
var url = 'src/index.html';
|
||||
var testMaxTime = 10000;
|
||||
var testMaxTime = 20000;
|
||||
|
||||
page.viewportSize = {
|
||||
width: 1024,
|
||||
@@ -280,7 +280,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=1]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Bitcoin Testnet";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -308,7 +310,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=2]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Litecoin";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -336,7 +340,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=3]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Dogecoin";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -364,7 +370,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=4]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "ShadowCash";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -392,7 +400,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=5]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "ShadowCash Testnet";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -420,7 +430,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=6]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Viacoin";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -448,7 +460,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=7]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Viacoin Testnet";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -476,7 +490,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=8]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Jumbucks";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -504,7 +520,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=9]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "CLAM";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -532,7 +550,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=10]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "DASH";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -551,6 +571,36 @@ page.open(url, function(status) {
|
||||
});
|
||||
},
|
||||
|
||||
// Network can be set to game
|
||||
function() {
|
||||
page.open(url, function(status) {
|
||||
// set the phrase and coin
|
||||
var expected = "GSMY9bAp36cMR4zyT4uGVS7GFjpdXbao5Q";
|
||||
page.evaluate(function() {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "GAME";
|
||||
}).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("GAME address is incorrect");
|
||||
console.log("Expected: " + expected);
|
||||
console.log("Actual: " + actual);
|
||||
fail();
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Network can be set to namecoin
|
||||
function() {
|
||||
page.open(url, function(status) {
|
||||
@@ -560,7 +610,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=11]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Namecoin";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -588,7 +640,9 @@ page.open(url, function(status) {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option[value=12]").prop("selected", true);
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Peercoin";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
// check the address is generated correctly
|
||||
@@ -607,6 +661,68 @@ page.open(url, function(status) {
|
||||
});
|
||||
},
|
||||
|
||||
// Network can be set to ethereum
|
||||
function() {
|
||||
|
||||
page.open(url, function(status) {
|
||||
|
||||
// set the phrase and coin
|
||||
page.evaluate(function() {
|
||||
$(".phrase").val("abandon abandon ability");
|
||||
$(".phrase").trigger("input");
|
||||
$(".network option[selected]").removeAttr("selected");
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Ethereum";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
// check the address is generated correctly
|
||||
// this value comes from
|
||||
// https://www.myetherwallet.com/#view-wallet-info
|
||||
// Unusual capitalization is due to checksum
|
||||
var expected = "0xe5815d5902Ad612d49283DEdEc02100Bd44C2772";
|
||||
var actual = page.evaluate(function() {
|
||||
return $(".address:first").text();
|
||||
});
|
||||
if (actual != expected) {
|
||||
console.log("Ethereum address is incorrect");
|
||||
console.log("Expected: " + expected);
|
||||
console.log("Actual: " + actual);
|
||||
fail();
|
||||
}
|
||||
// check the private key is correct
|
||||
// this private key can be imported into
|
||||
// https://www.myetherwallet.com/#view-wallet-info
|
||||
// and it should correlate to the address above
|
||||
var expected = "8f253078b73d7498302bb78c171b23ce7a8fb511987d2b2702b731638a4a15e7";
|
||||
var actual = page.evaluate(function() {
|
||||
return $(".privkey:first").text();
|
||||
});
|
||||
if (actual != expected) {
|
||||
console.log("Ethereum privkey is incorrect");
|
||||
console.log("Expected: " + expected);
|
||||
console.log("Actual: " + actual);
|
||||
fail();
|
||||
}
|
||||
// check the public key is correct
|
||||
// TODO
|
||||
// don't have any third-party source to generate the expected value
|
||||
//var expected = "?";
|
||||
//var actual = page.evaluate(function() {
|
||||
// return $(".pubkey:first").text();
|
||||
//});
|
||||
//if (actual != expected) {
|
||||
// console.log("Ethereum privkey is incorrect");
|
||||
// console.log("Expected: " + expected);
|
||||
// console.log("Actual: " + actual);
|
||||
// fail();
|
||||
//}
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// BIP39 seed is set from phrase
|
||||
function() {
|
||||
page.open(url, function(status) {
|
||||
@@ -1778,7 +1894,10 @@ page.open(url, function(status) {
|
||||
waitForGenerate(function() {
|
||||
// 4) switch from bitcoin to litecoin
|
||||
page.evaluate(function() {
|
||||
$(".network").val("2").trigger("change");
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Litecoin";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
// 5) Check derivation path is displayed correctly
|
||||
@@ -1821,7 +1940,10 @@ page.open(url, function(status) {
|
||||
waitForGenerate(function() {
|
||||
// switch from bitcoin to clam
|
||||
page.evaluate(function() {
|
||||
$(".network").val("9").trigger("change");
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "CLAM";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
// check derivation path is displayed correctly
|
||||
@@ -1852,7 +1974,10 @@ page.open(url, function(status) {
|
||||
waitForGenerate(function() {
|
||||
// 4) switch from bitcoin to viacoin
|
||||
page.evaluate(function() {
|
||||
$(".network").val("6").trigger("change");
|
||||
$(".network option").filter(function() {
|
||||
return $(this).html() == "Viacoin";
|
||||
}).prop("selected", true);
|
||||
$(".network").trigger("change");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
// 5) ensure the derived address is correct
|
||||
@@ -2268,7 +2393,6 @@ page.open(url, function(status) {
|
||||
// use entropy
|
||||
page.evaluate(function() {
|
||||
$(".use-entropy").prop("checked", true).trigger("change");
|
||||
$(".mnemonic-length").val("raw");
|
||||
$(".entropy").val("00000000 00000000 00000000 00000000").trigger("input");
|
||||
});
|
||||
// check the mnemonic is set and address is correct
|
||||
@@ -2804,7 +2928,6 @@ page.open(url, function(status) {
|
||||
// use entropy
|
||||
page.evaluate(function() {
|
||||
$(".use-entropy").prop("checked", true).trigger("change");
|
||||
$(".mnemonic-length").val("raw");
|
||||
});
|
||||
var nextTest = function runNextTest(i) {
|
||||
function getFeedbackError(expected, actual) {
|
||||
@@ -2886,7 +3009,6 @@ page.open(url, function(status) {
|
||||
// use entropy
|
||||
page.evaluate(function() {
|
||||
$(".use-entropy").prop("checked", true).trigger("change");
|
||||
$(".mnemonic-length").val("raw");
|
||||
var entropy = "00000000 00000000 00000000 00000000";
|
||||
entropy += "11111111 11111111 11111111 1111"; // Missing last byte
|
||||
$(".entropy").val(entropy).trigger("input");
|
||||
@@ -2913,7 +3035,6 @@ page.open(url, function(status) {
|
||||
// use entropy
|
||||
page.evaluate(function() {
|
||||
$(".use-entropy").prop("checked", true).trigger("change");
|
||||
$(".mnemonic-length").val("raw");
|
||||
var entropy = "";
|
||||
// Generate a very long entropy string
|
||||
for (var i=0; i<33; i++) {
|
||||
@@ -2947,7 +3068,6 @@ page.open(url, function(status) {
|
||||
// use entropy
|
||||
page.evaluate(function() {
|
||||
$(".use-entropy").prop("checked", true).trigger("change");
|
||||
$(".mnemonic-length").val("raw");
|
||||
var entropy = "543210543210543210543210543210543210543210543210543210543210543210543210543210543210543210543210543";
|
||||
$(".entropy").val(entropy).trigger("input");
|
||||
});
|
||||
@@ -3039,7 +3159,6 @@ page.open(url, function(status) {
|
||||
// use entropy
|
||||
page.evaluate(function() {
|
||||
$(".use-entropy").prop("checked", true).trigger("change");
|
||||
$(".mnemonic-length").val("raw");
|
||||
$(".entropy").val("7S 9H 9S QH 8C KS AS 7D 7C QD 4S 4D TC 2D 5S JS 3D 8S 8H 4C 3C AC 3S QC 9C JC 7H AD TD JD 6D KH 5C QS 2S 6S 6H JH KD 9D-6C TS TH 4H KC 5H 2H AH 2C 8D 3H 5D").trigger("input");
|
||||
});
|
||||
// get the mnemonic
|
||||
@@ -3345,6 +3464,7 @@ page.open(url, function(status) {
|
||||
// use entropy
|
||||
page.evaluate(function() {
|
||||
$(".use-entropy").prop("checked", true).trigger("change");
|
||||
$(".mnemonic-length").val("15");
|
||||
$(".entropy").val("1111").trigger("input");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
@@ -3364,6 +3484,163 @@ page.open(url, function(status) {
|
||||
});
|
||||
},
|
||||
|
||||
// Github pull request 55
|
||||
// https://github.com/iancoleman/bip39/pull/55
|
||||
// Client select
|
||||
function() {
|
||||
page.open(url, function(status) {
|
||||
// set mnemonic and select bip32 tab
|
||||
page.evaluate(function() {
|
||||
$("#bip32-tab a").click();
|
||||
$(".phrase").val("abandon abandon ability").trigger("input");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
// BITCOIN CORE
|
||||
// set bip32 client to bitcoin core
|
||||
page.evaluate(function() {
|
||||
var bitcoinCoreIndex = "0";
|
||||
$("#bip32-client").val(bitcoinCoreIndex).trigger("change");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
// get the derivation path
|
||||
var actual = page.evaluate(function() {
|
||||
return $("#bip32-path").val();
|
||||
});
|
||||
// check the derivation path is correct
|
||||
expected = "m/0'/0'"
|
||||
if (actual != expected) {
|
||||
console.log("Selecting Bitcoin Core client does not set correct derivation path");
|
||||
console.log("Expected: " + expected);
|
||||
console.log("Actual: " + actual);
|
||||
fail();
|
||||
}
|
||||
// get hardened addresses
|
||||
var usesHardenedAddresses = page.evaluate(function() {
|
||||
return $(".hardened-addresses").prop("checked");
|
||||
});
|
||||
// check hardened addresses is selected
|
||||
if(!usesHardenedAddresses) {
|
||||
console.log("Selecting Bitcoin Core client does not use hardened addresses");
|
||||
fail();
|
||||
}
|
||||
// check input is readonly
|
||||
var pathIsReadonly = page.evaluate(function() {
|
||||
return $("#bip32-path").prop("readonly");
|
||||
});
|
||||
if (!pathIsReadonly) {
|
||||
console.log("Selecting Bitcoin Core client does not set derivation path to readonly");
|
||||
fail();
|
||||
}
|
||||
// MULTIBIT
|
||||
// set bip32 client to multibit
|
||||
page.evaluate(function() {
|
||||
var multibitIndex = "2";
|
||||
$("#bip32-client").val(multibitIndex).trigger("change");
|
||||
});
|
||||
waitForGenerate(function() {
|
||||
// get the derivation path
|
||||
var actual = page.evaluate(function() {
|
||||
return $("#bip32-path").val();
|
||||
});
|
||||
// check the derivation path is correct
|
||||
expected = "m/0'/0"
|
||||
if (actual != expected) {
|
||||
console.log("Selecting Multibit client does not set correct derivation path");
|
||||
console.log("Expected: " + expected);
|
||||
console.log("Actual: " + actual);
|
||||
fail();
|
||||
}
|
||||
// get hardened addresses
|
||||
var usesHardenedAddresses = page.evaluate(function() {
|
||||
return $(".hardened-addresses").prop("checked");
|
||||
});
|
||||
// check hardened addresses is selected
|
||||
if(usesHardenedAddresses) {
|
||||
console.log("Selecting Multibit client does not uncheck hardened addresses");
|
||||
fail();
|
||||
}
|
||||
// CUSTOM DERIVATION PATH
|
||||
// check input is not readonly
|
||||
page.evaluate(function() {
|
||||
$("#bip32-client").val("custom").trigger("change");
|
||||
});
|
||||
// do not wait for generate, since there is no change to the
|
||||
// derivation path there is no new generation performed
|
||||
var pathIsReadonly = page.evaluate(function() {
|
||||
return $("#bip32-path").prop("readonly");
|
||||
});
|
||||
if (pathIsReadonly) {
|
||||
console.log("Selecting Custom Derivation Path does not allow derivation path input");
|
||||
fail();
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 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();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// If you wish to add more tests, do so here...
|
||||
|
||||
// Here is a blank test template
|
||||
|
||||
Reference in New Issue
Block a user