Skip to content
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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
],
"[solidity]": {
"editor.defaultFormatter": "JuanBlanco.solidity"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
75 changes: 40 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<div align="center">
<h1>BIP39</h1>
<p><strong>TypeScript library and CLI for generating, validating, and converting BIP39 English mnemonics</strong></p>
# BIP39

**TypeScript library and CLI for generating, validating, and converting BIP39 English mnemonics**

<img alt="License" src="https://img.shields.io/badge/license-MIT-blue.svg" />
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-5.9.3-3178C6?logo=typescript&logoColor=white" />
<img alt="Node" src="https://img.shields.io/badge/node-%3E%3D24-339933?logo=node.js&logoColor=white" />
<img alt="pnpm" src="https://img.shields.io/badge/pnpm-10.30.0-F69220?logo=pnpm&logoColor=white" />
</div>


## Project Overview
## Overview

This repository provides the core BIP39 workflows for the English wordlist profile:

Expand Down Expand Up @@ -77,11 +76,11 @@ node dist/cli/index.js mnemonic-to-seed "abandon abandon abandon abandon abandon

```ts
import {
entropyToMnemonic,
generateEntropy,
mnemonicToEntropy,
mnemonicToSeed,
validateMnemonic,
entropyToMnemonic,
generateEntropy,
mnemonicToEntropy,
mnemonicToSeed,
validateMnemonic,
} from "./dist/index.js";

const entropy = generateEntropy(16);
Expand All @@ -91,10 +90,10 @@ const seed = mnemonicToSeed(mnemonic, "TREZOR");
const validation = validateMnemonic(mnemonic);

console.log({
mnemonic,
roundTripEntropyLength: roundTripEntropy.length,
seedLength: seed.length,
validation,
mnemonic,
roundTripEntropyLength: roundTripEntropy.length,
seedLength: seed.length,
validation,
});
```

Expand Down Expand Up @@ -134,31 +133,37 @@ The main repository-level configuration files are:
- `tsconfig.json` for TypeScript compilation and build output settings
- `biome.json` for linting and formatting

## Directory Structure
## Structure

```text
.
├── assets/ # Pinned specification assets and test vectors
├── src/ # TypeScript source code
│ ├── bip39/ # Core entropy/mnemonic/seed workflows
│ ├── bits/ # Bit conversion helpers
│ ├── cli/ # Command-line interface
│ ├── constants/ # Fixed BIP39 constants and mappings
│ ├── crypto/ # SHA-256 and PBKDF2 wrappers
│ ├── entropy/ # Secure entropy generation
│ ├── errors/ # Standard error codes
│ ├── integration/ # Error messaging and integration adapters
│ ├── normalize/ # Compatibility input normalization
│ ├── parser/ # Strict mnemonic parsing rules
│ ├── types/ # Shared DTOs and result types
│ └── index.ts # Public export surface
├── tests/ # Unit and integration tests
├── biome.json # Lint/format configuration
├── package.json # Scripts and package metadata
├── README.md # Project overview and usage
└── tsconfig.json # TypeScript compilation configuration
├── assets/
├── src/
│ ├── bip39/
│ ├── cli/
│ ├── integration/
│ └── index.ts
├── tests/
├── biome.json
├── package.json
├── README.md
└── tsconfig.json
```

| Path | Description |
| --- | --- |
| `assets/` | Pinned specification assets and test vectors |
| `src/` | TypeScript source code |
| `src/bip39/` | BIP39 library, primitives, entropy, and wordlists |
| `src/cli/` | Command-line interface |
| `src/integration/` | Shared input normalization and external adapters |
| `src/index.ts` | Public export surface |
| `tests/` | Unit and integration tests |
| `biome.json` | Lint/format configuration |
| `package.json` | Scripts and package metadata |
| `README.md` | Project overview and usage |
| `tsconfig.json` | TypeScript compilation configuration |

## License

MIT - see [LICENSE](LICENSE).
19 changes: 6 additions & 13 deletions src/DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
# src design

- Purpose: TypeScript source for the BIP39 implementation.
- `src/constants/` defines fixed BIP39 constants and length/word-count relations.
- `src/bits/` implements bit and chunk conversions used in mnemonic encoding.
- `src/bip39/` contains core BIP39 conversion functions.
- `src/errors/` defines standard error codes and priority ordering.
- `src/crypto/` wraps SHA-256 and PBKDF2-HMAC-SHA512 using standard libraries.
- `src/normalize/` provides a compatibility input adapter (trim, NFKD, lowercase).
- `src/parser/` implements strict mnemonic parsing contracts.
- `src/entropy/` generates entropy via secure randomness with injectable providers for tests.
- `src/cli/` provides a command-line interface wrapping the core APIs.
- `src/integration/` wires core APIs to external systems (UI/BIP32) and error messaging.
- `src/types/` defines shared DTOs such as `ValidationResult`.
- `src/wordlist/` loads and validates the English wordlist with index mappings.
- `src/index.ts` re-exports the public surface for these foundational modules.
- `src/bip39/` groups the BIP39 library: conversions, validation and result types, strict parsing, constants, error codes, bit operations, cryptographic primitives, secure entropy generation, and English wordlists. These remain separate files with their existing responsibilities.
- `src/integration/` provides shared CLI/UI input normalization, external adapters (UI/BIP32), and error messaging.
- `src/cli/` provides argument handling, command adapters, and text output around the library APIs.
- Dependencies flow from CLI and integration adapters into the BIP39 library; the library does not depend on either adapter directory.
- `src/index.ts` preserves the public export surface independently of the internal file layout.
- Wordlist exports are explicit so the synchronous loader remains internal to core and CLI modules.
- Build output is emitted to `dist/`; `src/` contains TypeScript sources only.
19 changes: 16 additions & 3 deletions src/bip39/DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# bip39 design

- Purpose: Core BIP39 conversion functions built on fixed assets and primitives.
- Scope: Deterministic conversions only; no UI or random entropy generation.
- Includes: `entropyToMnemonic`, `mnemonicToEntropy`, `mnemonicToSeed`, and `validateMnemonic`.
- Purpose: Keep the BIP39 library and its supporting primitives together, with each responsibility in a separate module.
- Scope: Conversion, validation, strict parsing, wordlist loading, and secure entropy generation, including runtime file and standard-library crypto operations. UI/CLI input normalization and presentation remain in the adapter directories.
- `entropyToMnemonic.ts` handles entropy encoding; `mnemonicToSeed.ts` handles seed derivation separately from strict mnemonic validation.
- `mnemonic.ts` groups validation, entropy recovery, `ValidationResult`, and the existing recovery error classes around a private decoder.
- The decoder checks format, word count, word membership, and checksum in that order. Both public APIs propagate infrastructure errors unchanged.
- `validateMnemonic` returns exactly its five public fields; `mnemonicToEntropy` translates decoder failures into the existing exception classes. Decoded entropy stays internal to validation.
- `strictMnemonic.ts` enforces NFKD, spacing, and lowercase ASCII for the English profile and extracts word arrays; it does not apply compatibility input normalization.
- `constants.ts` defines fixed BIP39 constants and deterministic length/word-count relations without I/O or crypto dependencies.
- `bitOps.ts` provides pure conversions between bytes, bit arrays, and integer chunks in MSB-first order.
- `errorCodes.ts` defines error identifiers and priority ordering; user-facing messages belong to the integration layer.
- `crypto.ts` wraps standard SHA-256 and PBKDF2-HMAC-SHA512 primitives and maps PBKDF2 failures; it does not implement cryptographic algorithms itself.
- `entropyGenerator.ts` validates allowed byte lengths and delegates secure entropy generation to a randomness provider, with provider injection for tests.
- `wordlist.ts` owns the shared `Wordlist` type, line splitting, integrity checks, file-order index mappings, and both English wordlist loaders; it performs no input normalization or crypto.
- Public `loadEnglishWordlist` reads asynchronously; `loadEnglishWordlistSync` serves conversions and CLI generation and stays excluded from the root public exports.
- The loaders maintain separate caches because returned dictionaries are mutable; each caches only successful loads.
- Wordlist parsing preserves error precedence: the public parser checks empty lines first, while the synchronous loader checks word count before empty or duplicate words in file order.
- Output: JavaScript is emitted to `dist/`; keep this directory TypeScript-only.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/crypto/crypto.ts → src/bip39/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createHash, pbkdf2Sync } from "node:crypto";

import { PBKDF2_ITERATIONS, SEED_BYTES } from "../constants/bip39.js";
import { ErrorCode } from "../errors/errorCodes.js";
import { PBKDF2_ITERATIONS, SEED_BYTES } from "./constants.js";
import { ErrorCode } from "./errorCodes.js";

export class Pbkdf2FailureError extends Error {
code = ErrorCode.ERR_PBKDF2_FAILURE;
Expand Down
44 changes: 0 additions & 44 deletions src/bip39/englishWordlist.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { randomBytes } from "node:crypto";

import { ENTROPY_BYTES } from "../constants/bip39.js";
import { ENTROPY_BYTES } from "./constants.js";

export class InvalidEntropyLengthError extends Error {
constructor(message = "Invalid entropy length") {
Expand Down
15 changes: 6 additions & 9 deletions src/bip39/entropyToMnemonic.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { bitsToIntegers, bytesToBits } from "../bits/bitOps.js";
import {
checksumBitsForEntropyBits,
ENTROPY_BYTES,
} from "../constants/bip39.js";
import { sha256 } from "../crypto/crypto.js";
import { ErrorCode } from "../errors/errorCodes.js";
import { loadEnglishWordlist } from "./englishWordlist.js";
import { bitsToIntegers, bytesToBits } from "./bitOps.js";
import { checksumBitsForEntropyBits, ENTROPY_BYTES } from "./constants.js";
import { sha256 } from "./crypto.js";
import { ErrorCode } from "./errorCodes.js";
import { loadEnglishWordlistSync } from "./wordlist.js";

export class EntropyLengthError extends Error {
code = ErrorCode.ERR_ENTROPY_LENGTH;
Expand All @@ -32,7 +29,7 @@ export const entropyToMnemonic = (entropy: Uint8Array): string => {
const checksum = bytesToBits(sha256(entropy)).slice(0, checksumBits);
const combined = entropyBitArray.concat(checksum);
const indices = bitsToIntegers(combined, 11);
const { words } = loadEnglishWordlist();
const { words } = loadEnglishWordlistSync();
const mnemonicWords = indices.map((index) => {
const word = words[index];
if (word === undefined) {
Expand Down
File renamed without changes.
Loading