Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow excluding wordlists when building for browserify #105

Merged
merged 3 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tests and getDefaultWordlist
  • Loading branch information
junderw committed Mar 28, 2019
commit 6194c3f3ffe458499282c87333c7278396936e7d
63 changes: 21 additions & 42 deletions src/_wordlists.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
// browserify by default only pulls in files that are hard coded in requires
// In order of last to first in this file, the default wordlist will be chosen
// based on what is present. (Bundles may remove wordlists they don't need)
const wordlistFilenames = [
'chinese_simplified',
'chinese_traditional',
'korean',
'french',
'italian',
'spanish',
'japanese',
'english',
];
const wordlists = {};
exports.wordlists = wordlists;
let _default;
exports._default = _default;
try {
exports._default = _default = require('./wordlists/chinese_simplified.json');
wordlists.chinese_simplified = _default;
}
catch (err) { }
try {
exports._default = _default = require('./wordlists/chinese_traditional.json');
wordlists.chinese_traditional = _default;
}
catch (err) { }
try {
exports._default = _default = require('./wordlists/korean.json');
wordlists.korean = _default;
}
catch (err) { }
try {
exports._default = _default = require('./wordlists/french.json');
wordlists.french = _default;
}
catch (err) { }
try {
exports._default = _default = require('./wordlists/italian.json');
wordlists.italian = _default;
}
catch (err) { }
try {
exports._default = _default = require('./wordlists/spanish.json');
wordlists.spanish = _default;
}
catch (err) { }
try {
exports._default = _default = require('./wordlists/japanese.json');
wordlists.japanese = _default;
wordlists.JA = _default;
}
catch (err) { }
try {
exports._default = _default = require('./wordlists/english.json');
wordlists.english = _default;
wordlists.EN = _default;
}
catch (err) { }
wordlistFilenames.forEach(lang => {
try {
exports._default = _default = require('./wordlists/' + lang + '.json');
wordlists[lang] = _default;
if (lang === 'japanese')
wordlists.JA = _default;
if (lang === 'english')
wordlists.EN = _default;
}
catch (err) { }
});
12 changes: 12 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,19 @@ function setDefaultWordlist(language) {
const result = _wordlists_1.wordlists[language];
if (result)
DEFAULT_WORDLIST = result;
else
throw new Error('Could not find wordlist for language "' + language + '"');
}
exports.setDefaultWordlist = setDefaultWordlist;
function getDefaultWordlist() {
if (!DEFAULT_WORDLIST)
throw new Error('No Default Wordlist set');
return Object.keys(_wordlists_1.wordlists).filter(lang => {
if (lang === 'JA' || lang === 'EN')
return false;
return _wordlists_1.wordlists[lang].every((word, index) => word === DEFAULT_WORDLIST[index]);
})[0];
}
exports.getDefaultWordlist = getDefaultWordlist;
var _wordlists_2 = require("./_wordlists");
exports.wordlists = _wordlists_2.wordlists;
40 changes: 40 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,46 @@ vectors.english.forEach(function (v, i) { testVector('English', undefined, 'TREZ
vectors.japanese.forEach(function (v, i) { testVector('Japanese', WORDLISTS.japanese, '㍍ガバヴァぱばぐゞちぢ十人十色', v, i) })
vectors.custom.forEach(function (v, i) { testVector('Custom', WORDLISTS.custom, undefined, v, i) })

test('getDefaultWordlist returns "english"', function (t) {
t.plan(1)
const english = bip39.getDefaultWordlist()
t.equal(english, 'english')
// TODO: Test that Error throws when called if no wordlists are compiled with bip39
})

test('setDefaultWordlist changes default wordlist', function (t) {
t.plan(4)
const english = bip39.getDefaultWordlist()
t.equal(english, 'english')

bip39.setDefaultWordlist('italian')

const italian = bip39.getDefaultWordlist()
t.equal(italian, 'italian')

const phraseItalian = bip39.entropyToMnemonic('00000000000000000000000000000000')
t.equal(phraseItalian.slice(0, 5), 'abaco')

bip39.setDefaultWordlist('english')

const phraseEnglish = bip39.entropyToMnemonic('00000000000000000000000000000000')
t.equal(phraseEnglish.slice(0, 7), 'abandon')
})

test('setDefaultWordlist throws on unknown wordlist', function (t) {
t.plan(2)
const english = bip39.getDefaultWordlist()
t.equal(english, 'english')

try {
bip39.setDefaultWordlist('abcdefghijklmnop')
} catch (error) {
t.equal(error.message, 'Could not find wordlist for language "abcdefghijklmnop"')
return
}
t.assert(false)
})

test('invalid entropy', function (t) {
t.plan(3)

Expand Down
52 changes: 18 additions & 34 deletions ts_src/_wordlists.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,26 @@
// browserify by default only pulls in files that are hard coded in requires
// In order of last to first in this file, the default wordlist will be chosen
// based on what is present. (Bundles may remove wordlists they don't need)
const wordlistFilenames: string[] = [
'chinese_simplified',
'chinese_traditional',
'korean',
'french',
'italian',
'spanish',
'japanese',
'english', // Last language available in list will be the default.
];
const wordlists: { [index: string]: string[] } = {};
let _default: string[] | undefined;
try {
_default = require('./wordlists/chinese_simplified.json');
wordlists.chinese_simplified = _default as string[];
} catch (err) {}
try {
_default = require('./wordlists/chinese_traditional.json');
wordlists.chinese_traditional = _default as string[];
} catch (err) {}
try {
_default = require('./wordlists/korean.json');
wordlists.korean = _default as string[];
} catch (err) {}
try {
_default = require('./wordlists/french.json');
wordlists.french = _default as string[];
} catch (err) {}
try {
_default = require('./wordlists/italian.json');
wordlists.italian = _default as string[];
} catch (err) {}
try {
_default = require('./wordlists/spanish.json');
wordlists.spanish = _default as string[];
} catch (err) {}
try {
_default = require('./wordlists/japanese.json');
wordlists.japanese = _default as string[];
wordlists.JA = _default as string[];
} catch (err) {}
try {
_default = require('./wordlists/english.json');
wordlists.english = _default as string[];
wordlists.EN = _default as string[];
} catch (err) {}
wordlistFilenames.forEach(lang => {
try {
_default = require('./wordlists/' + lang + '.json');
wordlists[lang] = _default as string[];
if (lang === 'japanese') wordlists.JA = _default as string[];
if (lang === 'english') wordlists.EN = _default as string[];
} catch (err) {}
});

// Last one to overwrite wordlist gets to be default.
export { wordlists, _default };
12 changes: 12 additions & 0 deletions ts_src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,18 @@ export function validateMnemonic(
export function setDefaultWordlist(language: string): void {
const result = wordlists[language];
if (result) DEFAULT_WORDLIST = result;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect this function to throw error if the wordlist does not exist.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition, why don't we provide getDefaultWordlist as well.

else
throw new Error('Could not find wordlist for language "' + language + '"');
}

export function getDefaultWordlist(): string {
if (!DEFAULT_WORDLIST) throw new Error('No Default Wordlist set');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should just return null...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think undefined is fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you export DEFAULT_LANGUAGE from _wordlists.ts and use it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean?

return Object.keys(wordlists).filter(lang => {
if (lang === 'JA' || lang === 'EN') return false;
return wordlists[lang].every(
(word, index) => word === DEFAULT_WORDLIST![index],
);
})[0];
}

export { wordlists } from './_wordlists';
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export declare function entropyToMnemonic(entropy: Buffer | string, wordlist?: s
export declare function generateMnemonic(strength?: number, rng?: (size: number) => Buffer, wordlist?: string[]): string;
export declare function validateMnemonic(mnemonic: string, wordlist?: string[]): boolean;
export declare function setDefaultWordlist(language: string): void;
export declare function getDefaultWordlist(): string;
export { wordlists } from './_wordlists';