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

Add Portuguese wordlist #19

Merged
merged 8 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
```

This submodule contains the word lists defined by BIP39 for Czech, English, French, Italian, Japanese, Korean, Simplified and Traditional Chinese, and Spanish. These are not imported by default, as that would increase bundle sizes too much. Instead, you should import and use them explicitly.
This submodule contains the word lists defined by BIP39 for Czech, English, French, Italian, Japanese, Korean, Portuguese, Simplified and Traditional Chinese, and Spanish. These are not imported by default, as that would increase bundle sizes too much. Instead, you should import and use them explicitly.

```typescript
function generateMnemonic(wordlist: string[], strength?: number): string;
Expand All @@ -72,9 +72,10 @@ import { wordlist as french } from '@scure/bip39/wordlists/french';
import { wordlist as italian } from '@scure/bip39/wordlists/italian';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese';
import { wordlist as korean } from '@scure/bip39/wordlists/korean';
import { wordlist as simp } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish';
import { wordlist as trad } from '@scure/bip39/wordlists/traditional-chinese';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese';
```

The module implements [bip39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) standard:
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@
"license": "MIT",
"scripts": {
"build": "tsc && tsc -p tsconfig.esm.json",
"lint": "prettier --check 'src/**/*.ts' 'test/*.test.ts'",
"format": "prettier --write 'src/**/*.ts' 'test/*.test.ts'",
"test": "cd test && tsc && node bip39.test.js"
"lint": "prettier --check 'src/**/*.ts' 'test/*.test.ts' 'scripts/*.js'",
"format": "prettier --write 'src/**/*.ts' 'test/*.test.ts' 'scripts/*.js'",
"test": "cd test && tsc && node bip39.test.js",
"fetch-wordlist": "./scripts/fetch-wordlist.js"
},
"exports": {
".": {
Expand Down
54 changes: 54 additions & 0 deletions scripts/fetch-wordlist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env node

// dependencies
const path = require('path');
const fs = require('fs');
const util = require('util');
const assert = require('assert');
const writeFileAsync = util.promisify(fs.writeFile);

// arguments
const arg = process.argv[2];
if (arg === undefined) {
console.error('Supply language (lowercased, snakecased) argument.');
process.exit();
}

// parse language argument
const filenameSnakeCased = arg;
const parts = arg.split('_');
const filenameKebabCased = parts.length > 1 ? `${parts[1]}-${parts[0]}` : arg;

// fetch, validate and save file
(async () => {
try {
// fetch
const url = `https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/${filenameSnakeCased}.txt`;
const response = await fetch(url);
if (response.ok === false) throw new Error(`Fetch (${url}) failed`);
const txtContent = await response.text();

// remove trailing line breaks
const wordlist = txtContent.replace(/\n+$/, '');

// validate .txt file content
validateTxtContent(wordlist);

// write .ts file
const tsContent = `export const wordlist: string[] = \`${wordlist}\`.split('\\n');\n`;
await writeFileAsync(
path.join(__dirname, '..', 'src/wordlists', `${filenameKebabCased}.ts`),
tsContent
);
} catch (err) {
console.error(err);
}
})();

// assertions
const validateTxtContent = (txtContent) => {
const words = txtContent.split('\n');
const emptyLines = words.filter((word) => word.trim() === '');
assert.equal(emptyLines.length, 0);
assert.equal(words.length, 2048);
};
Loading