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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
63 changes: 21 additions & 42 deletions src/_wordlists.js
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
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
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
@@ -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
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
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';