or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-scure--bip39

Secure, audited & minimal implementation of BIP39 mnemonic phrases

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@scure/bip39@2.0.x

To install, run

npx @tessl/cli install tessl/npm-scure--bip39@2.0.0

index.mddocs/

@scure/bip39

@scure/bip39 is a secure, audited, and minimal implementation of BIP39 mnemonic phrases for cryptocurrency applications. It provides comprehensive functionality for generating cryptographically secure mnemonic phrases, converting between mnemonics and entropy, validating mnemonic phrases, and deriving seed data using key derivation functions.

Package Information

  • Package Name: @scure/bip39
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @scure/bip39

Core Imports

import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english.js';

For CommonJS:

const bip39 = require('@scure/bip39');
const { wordlist } = require('@scure/bip39/wordlists/english.js');

Basic Usage

import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english.js';

// Generate a random 12-word mnemonic
const mnemonic = bip39.generateMnemonic(wordlist);
console.log(mnemonic);
// "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"

// Validate the mnemonic
const isValid = bip39.validateMnemonic(mnemonic, wordlist);
console.log(isValid); // true

// Convert mnemonic to seed for cryptographic operations
const seed = await bip39.mnemonicToSeed(mnemonic, 'optional-passphrase');
console.log(seed); // Uint8Array(64) [...]

// Convert mnemonic to raw entropy (reversible)
const entropy = bip39.mnemonicToEntropy(mnemonic, wordlist);
// Convert entropy back to mnemonic (reversible)
const recreatedMnemonic = bip39.entropyToMnemonic(entropy, wordlist);

Architecture

@scure/bip39 is built around several key components:

  • Mnemonic Generation: Cryptographically secure random mnemonic phrase generation
  • Entropy Conversion: Bidirectional conversion between mnemonics and raw entropy data
  • Validation System: Mnemonic phrase validation against specific wordlists
  • Key Derivation: PBKDF2-based seed derivation with optional passphrase protection
  • Multi-language Support: 10 different language wordlists with proper Unicode handling
  • Performance Variants: Pure JavaScript and WebCrypto API implementations

Capabilities

Mnemonic Generation

Generate cryptographically secure random mnemonic phrases using CSPRNG.

/**
 * Generate x random words. Uses Cryptographically-Secure Random Number Generator.
 * @param wordlist - Array of 2048 words for specific language
 * @param strength - Mnemonic strength in bits: 128, 160, 192, 224, or 256 (default: 128)
 * @returns Mnemonic string with 12, 15, 18, 21, or 24 words respectively
 * @throws TypeError for invalid entropy strength (must be divisible by 32 and ≤256)
 */
function generateMnemonic(wordlist: string[], strength: number = 128): string;

Usage Examples:

import { generateMnemonic } from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english.js';

// Generate 12-word mnemonic (128 bits, default)
const mnemonic12 = generateMnemonic(wordlist);

// Generate 24-word mnemonic (256 bits)
const mnemonic24 = generateMnemonic(wordlist, 256);

// Generate 15-word mnemonic (160 bits)
const mnemonic15 = generateMnemonic(wordlist, 160);

// Generate 18-word mnemonic (192 bits)
const mnemonic18 = generateMnemonic(wordlist, 192);

// Generate 21-word mnemonic (224 bits)
const mnemonic21 = generateMnemonic(wordlist, 224);

Entropy Conversion

Convert between mnemonic strings and raw entropy bytes (bidirectional operations).

/**
 * Reversible: Converts mnemonic string to raw entropy in form of byte array.
 * @param mnemonic - 12-24 word mnemonic string
 * @param wordlist - Wordlist array used for mnemonic
 * @returns Uint8Array of entropy bytes
 * @throws Error for invalid mnemonic or entropy length
 */
function mnemonicToEntropy(mnemonic: string, wordlist: string[]): Uint8Array;

/**
 * Reversible: Converts raw entropy in form of byte array to mnemonic string.
 * @param entropy - Uint8Array of entropy bytes (16, 20, 24, 28, or 32 bytes)
 * @param wordlist - Wordlist array for mnemonic generation
 * @returns 12-24 word mnemonic string
 */
function entropyToMnemonic(entropy: Uint8Array, wordlist: string[]): string;

Usage Examples:

import { mnemonicToEntropy, entropyToMnemonic } from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english.js';

const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';

// Convert mnemonic to entropy
const entropy = mnemonicToEntropy(mnemonic, wordlist);
console.log(entropy); // Uint8Array(16) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

// Convert entropy back to mnemonic
const recreatedMnemonic = entropyToMnemonic(entropy, wordlist);
console.log(recreatedMnemonic === mnemonic); // true

// Using custom entropy
const customEntropy = new Uint8Array([
  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
]);
const customMnemonic = entropyToMnemonic(customEntropy, wordlist);

Mnemonic Validation

Validate mnemonic phrases against specific wordlists.

/**
 * Validates mnemonic for being 12-24 words contained in wordlist.
 * @param mnemonic - Mnemonic string to validate
 * @param wordlist - Wordlist array for validation
 * @returns Boolean indicating validity
 */
function validateMnemonic(mnemonic: string, wordlist: string[]): boolean;

Usage Examples:

import { validateMnemonic } from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english.js';

const validMnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
const invalidMnemonic = 'invalid mnemonic phrase';

console.log(validateMnemonic(validMnemonic, wordlist)); // true
console.log(validateMnemonic(invalidMnemonic, wordlist)); // false

// Validate against different language
import { wordlist as frenchWordlist } from '@scure/bip39/wordlists/french.js';
console.log(validateMnemonic(validMnemonic, frenchWordlist)); // false (wrong language)

Seed Derivation

Derive cryptographic seeds from mnemonic phrases using PBKDF2 with optional passphrase protection.

/**
 * Derive 64-byte seed from mnemonic using PBKDF2-SHA512 with 2048 iterations (async, irreversible)
 * @param mnemonic - 12-24 word mnemonic string
 * @param passphrase - Optional password for additional protection (default: '')
 * @returns Promise resolving to 64-byte Uint8Array seed
 */
function mnemonicToSeed(mnemonic: string, passphrase: string = ''): Promise<Uint8Array>;

/**
 * Derive 64-byte seed from mnemonic using PBKDF2-SHA512 with 2048 iterations (sync, irreversible)
 * @param mnemonic - 12-24 word mnemonic string
 * @param passphrase - Optional password for additional protection (default: '')
 * @returns 64-byte Uint8Array seed
 */
function mnemonicToSeedSync(mnemonic: string, passphrase: string = ''): Uint8Array;

/**
 * Derive 64-byte seed using native WebCrypto API with PBKDF2-SHA512 and 2048 iterations (async, irreversible)
 * @param mnemonic - 12-24 word mnemonic string
 * @param passphrase - Optional password for additional protection (default: '')
 * @returns Promise resolving to 64-byte Uint8Array seed
 */
function mnemonicToSeedWebcrypto(mnemonic: string, passphrase: string = ''): Promise<Uint8Array>;

Usage Examples:

import { mnemonicToSeed, mnemonicToSeedSync, mnemonicToSeedWebcrypto } from '@scure/bip39';

const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';

// Async version (recommended)
const seed = await mnemonicToSeed(mnemonic);
console.log(seed.length); // 64

// With passphrase for additional security
const seedWithPass = await mnemonicToSeed(mnemonic, 'my-secret-passphrase');

// Synchronous version (blocks execution)
const seedSync = mnemonicToSeedSync(mnemonic);

// WebCrypto version (faster in browsers)
const seedWebcrypto = await mnemonicToSeedWebcrypto(mnemonic, 'passphrase');

Wordlist Support

@scure/bip39 supports 10 different language wordlists, each containing exactly 2048 words.

// All wordlist modules export the same interface
interface WordlistModule {
  wordlist: string[];
}

Available Wordlists:

// English (most commonly used)
import { wordlist } from '@scure/bip39/wordlists/english.js';

// Other supported languages
import { wordlist as czech } from '@scure/bip39/wordlists/czech.js';
import { wordlist as french } from '@scure/bip39/wordlists/french.js';
import { wordlist as italian } from '@scure/bip39/wordlists/italian.js';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese.js';
import { wordlist as korean } from '@scure/bip39/wordlists/korean.js';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese.js';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese.js';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish.js';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese.js';

Usage Examples:

import { generateMnemonic, validateMnemonic } from '@scure/bip39';
import { wordlist as english } from '@scure/bip39/wordlists/english.js';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese.js';

// Generate English mnemonic
const englishMnemonic = generateMnemonic(english);

// Generate Japanese mnemonic (uses ideographic space U+3000 as separator instead of regular space)
const japaneseMnemonic = generateMnemonic(japanese);
console.log(japaneseMnemonic); // Words separated by (U+3000) instead of space

// Validate against specific language
const isValidEnglish = validateMnemonic(englishMnemonic, english);
const isValidJapanese = validateMnemonic(japaneseMnemonic, japanese);

// Cross-language validation will fail
const crossValidation = validateMnemonic(englishMnemonic, japanese); // false

Types

// All wordlists are arrays of exactly 2048 strings
type Wordlist = string[];

// Entropy byte arrays must be exactly 16, 20, 24, 28, or 32 bytes
// corresponding to 128, 160, 192, 224, or 256 bits respectively
type EntropyBytes = Uint8Array;

// Mnemonic strength must be exactly 128, 160, 192, 224, or 256 bits
// corresponding to 12, 15, 18, 21, or 24 words respectively
type MnemonicStrength = 128 | 160 | 192 | 224 | 256;

// Seed is always 64 bytes
type Seed = Uint8Array;

Error Handling

The library throws specific errors for various invalid inputs:

  • TypeError:
    • "Invalid entropy" - for strength values not divisible by 32 or exceeding 256
    • "invalid mnemonic type: [type]" - for non-string mnemonic input
  • Error:
    • "Invalid mnemonic" - for mnemonics that don't have exactly 12, 15, 18, 21, or 24 words
    • "invalid entropy length" - for entropy arrays that aren't exactly 16, 20, 24, 28, or 32 bytes
    • "Wordlist: expected array of 2048 strings" - for wordlists that aren't arrays of exactly 2048 strings
    • "wordlist: non-string element: [element]" - for wordlists containing non-string elements

Security Features

  • NFKD Unicode normalization for all text inputs
  • Cryptographically secure random number generation via @noble/hashes
  • Independent security audit by Cure53 (January 2022)
  • Minimal dependency tree (only 2 audited dependencies by the same author)
  • Standard compliance with BIP39 specification
  • PBKDF2-SHA512 with 2048 iterations for seed derivation (follows BIP39 standard)

Performance Considerations

  • Tree-shakeable: Unused wordlists are excluded from builds
  • WebCrypto variant: mnemonicToSeedWebcrypto uses native browser APIs for better performance
  • Bundle size: 14KB gzipped with one wordlist, 79KB with all wordlists
  • No source maps: Excluded to keep package size minimal