Mnemonic from Seed
Description
Section titled “Description”This example demonstrates how to use mnemonicFromSeed() to convert a 32-byte seed into a 25-word Algorand mnemonic. The mnemonic uses BIP39-style word encoding where each word represents 11 bits of data. Key concepts:
- A 32-byte (256-bit) seed produces 24 data words (256 / 11 = ~23.3, rounded up)
- A 25th checksum word is computed from the SHA-512/256 hash of the seed
- The mnemonic is deterministic: same seed always produces same mnemonic
Prerequisites
Section titled “Prerequisites”- No LocalNet required
Run This Example
Section titled “Run This Example”From the repository root:
cd examplesnpm run example algo25/01-mnemonic-from-seed.ts/** * Example: Mnemonic from Seed * * This example demonstrates how to use mnemonicFromSeed() to convert a 32-byte * seed into a 25-word Algorand mnemonic. The mnemonic uses BIP39-style word * encoding where each word represents 11 bits of data. * * Key concepts: * - A 32-byte (256-bit) seed produces 24 data words (256 / 11 = ~23.3, rounded up) * - A 25th checksum word is computed from the SHA-512/256 hash of the seed * - The mnemonic is deterministic: same seed always produces same mnemonic * * Prerequisites: * - No LocalNet required */
import { mnemonicFromSeed } from '@algorandfoundation/algokit-utils/algo25';import { formatBytes, formatHex, printHeader, printInfo, printStep, printSuccess,} from '../shared/utils.js';
function main() { printHeader('Mnemonic from Seed Example');
// Step 1: Generate a random 32-byte seed printStep(1, 'Generate a Random 32-byte Seed');
const seed = new Uint8Array(32); crypto.getRandomValues(seed);
printInfo(`Seed length: ${seed.length} bytes (256 bits)`); printInfo(`Seed bytes: ${formatBytes(seed, 16)}`); printInfo(`Seed hex: ${formatHex(seed)}`);
// Step 2: Convert seed to mnemonic printStep(2, 'Convert Seed to 25-Word Mnemonic');
const mnemonic = mnemonicFromSeed(seed); const words = mnemonic.split(' ');
printInfo(`Total words: ${words.length}`); printInfo(`Data words: 24 (encoding 256 bits of seed data)`); printInfo(`Checksum word: 1 (derived from SHA-512/256 hash of seed)`);
// Step 3: Display the 25 words printStep(3, 'Display the Mnemonic Words');
printInfo('Mnemonic words:'); // Display words in rows of 5 for readability for (let i = 0; i < words.length; i += 5) { const row = words.slice(i, i + 5); const numbered = row .map((w, j) => `${(i + j + 1).toString().padStart(2, ' ')}. ${w.padEnd(10)}`) .join(' '); printInfo(` ${numbered}`); }
// Step 4: Explain the 11-bit encoding scheme printStep(4, 'Explain the 11-bit Encoding Scheme');
printInfo('How seed bits map to mnemonic words:'); printInfo(' - Seed: 32 bytes = 256 bits'); printInfo(' - Each word encodes 11 bits (2^11 = 2048 possible words)'); printInfo(' - 256 bits / 11 bits per word = 23.27 words'); printInfo(' - This rounds up to 24 words (with 8 padding bits)'); printInfo(' - 24 words × 11 bits = 264 bits total'); printInfo(' - Extra 8 bits are zero-padded'); printInfo(''); printInfo('Checksum word calculation:'); printInfo(' - Compute SHA-512/256 hash of the 32-byte seed'); printInfo(' - Take the first 11 bits of the hash'); printInfo(' - Map those 11 bits to a word from the wordlist'); printInfo(' - This becomes the 25th (checksum) word');
// Step 5: Verify determinism printStep(5, 'Verify Determinism - Same Seed Produces Same Mnemonic');
const mnemonic1 = mnemonicFromSeed(seed); const mnemonic2 = mnemonicFromSeed(seed);
printInfo(`First call result:`); printInfo(` "${mnemonic1.split(' ').slice(0, 5).join(' ')}..."`); printInfo(`Second call result:`); printInfo(` "${mnemonic2.split(' ').slice(0, 5).join(' ')}..."`);
const isIdentical = mnemonic1 === mnemonic2; printInfo(`Mnemonics identical: ${isIdentical ? 'Yes' : 'No'}`);
if (isIdentical) { printSuccess('Determinism verified: same seed always produces same mnemonic'); }
// Step 6: Show a second random seed for comparison printStep(6, 'Different Seed Produces Different Mnemonic');
const seed2 = new Uint8Array(32); crypto.getRandomValues(seed2); const mnemonic3 = mnemonicFromSeed(seed2);
printInfo(`Seed 1 (first 8 bytes): ${formatHex(seed.slice(0, 8))}...`); printInfo(`Seed 2 (first 8 bytes): ${formatHex(seed2.slice(0, 8))}...`); printInfo(''); printInfo(`Mnemonic 1 (first 3 words): ${mnemonic1.split(' ').slice(0, 3).join(' ')}...`); printInfo(`Mnemonic 2 (first 3 words): ${mnemonic3.split(' ').slice(0, 3).join(' ')}...`);
const isDifferent = mnemonic1 !== mnemonic3; printInfo(`Mnemonics different: ${isDifferent ? 'Yes' : 'No'}`);
// Summary printStep(7, 'Summary');
printInfo('mnemonicFromSeed() converts a 32-byte seed to a 25-word mnemonic:'); printInfo(' - Input: 32-byte Uint8Array (cryptographically random seed)'); printInfo(' - Output: Space-separated string of 25 words'); printInfo(' - Words 1-24: Encode the 256-bit seed (11 bits per word)'); printInfo(' - Word 25: Checksum derived from SHA-512/256 hash'); printInfo(' - Deterministic: reproducible from the same seed'); printInfo(' - BIP39-compatible wordlist: 2048 English words');
printSuccess('Mnemonic from Seed example completed successfully!');}
main();