or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-bech32

Bech32 and Bech32m encoding/decoding library for Bitcoin addresses

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

To install, run

npx @tessl/cli install tessl/npm-bech32@2.0.0

index.mddocs/

Bech32

Bech32 is a TypeScript library providing BIP173/BIP350 compatible Bech32 and Bech32m encoding and decoding for Bitcoin addresses. It supports both the original Bech32 standard (const=1) and the newer Bech32m standard (const=0x2bc830a3), with comprehensive error handling, checksum validation, and bit conversion utilities.

Package Information

  • Package Name: bech32
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install bech32

Core Imports

import { bech32, bech32m } from "bech32";

For CommonJS:

const { bech32, bech32m } = require("bech32");

Basic Usage

import { bech32, bech32m } from "bech32";

// Decode Bech32 address
const decoded = bech32.decode('abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw');
// => { prefix: 'abcdef', words: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31] }

// Decode Bech32m address
const decodedM = bech32m.decode('abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx');
// => { prefix: 'abcdef', words: [31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0] }

// Convert bytes to words and encode
const words = bech32.toWords(Buffer.from('foobar', 'utf8'));
const encoded = bech32.encode('foo', words);
// => 'foo1vehk7cnpwgry9h96'

const encodedM = bech32m.encode('foo', words);
// => 'foo1vehk7cnpwgkc4mqc'

Architecture

The library is structured around two main library objects (bech32 and bech32m) that share the same interface but use different encoding constants:

  • bech32: Uses encoding constant 1 for original Bech32 standard (BIP173)
  • bech32m: Uses encoding constant 0x2bc830a3 for Bech32m standard (BIP350)

Both libraries provide the same API for encoding, decoding, and bit conversion utilities.

Capabilities

Encoding

Encodes a human-readable prefix and 5-bit words into a Bech32/Bech32m string.

/**
 * Encodes a prefix and 5-bit words into a Bech32/Bech32m string
 * @param prefix - Human-readable prefix (will be converted to lowercase)
 * @param words - Array of 5-bit words (values 0-31)
 * @param LIMIT - Optional length limit (default: 90, max recommended: 1023)
 * @returns Encoded Bech32/Bech32m string
 * @throws TypeError if exceeds length limit
 * @throws Error for invalid prefix or non-5-bit words
 */
function encode(prefix: string, words: ArrayLike<number>, LIMIT?: number): string;

Usage Examples:

import { bech32, bech32m } from "bech32";

// Basic encoding
const words = [15, 25, 9, 5, 23, 15, 17];
const bech32Encoded = bech32.encode('bc', words);
const bech32mEncoded = bech32m.encode('bc', words);

// With custom length limit
const longEncoded = bech32.encode('test', words, 100);

Safe Decoding

Decodes a Bech32/Bech32m string with error throwing on invalid input.

/**
 * Decodes a Bech32/Bech32m string (throws on error)
 * @param str - Bech32/Bech32m encoded string
 * @param LIMIT - Optional length limit (default: 90)
 * @returns Decoded object with prefix and words
 * @throws Error for invalid strings, checksum failures, etc.
 */
function decode(str: string, LIMIT?: number): Decoded;

Usage Examples:

import { bech32, bech32m } from "bech32";

try {
  const result = bech32.decode('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4');
  console.log(result.prefix); // 'bc'
  console.log(result.words);  // Array of 5-bit words
} catch (error) {
  console.error('Invalid Bech32 string:', error.message);
}

Unsafe Decoding

Decodes a Bech32/Bech32m string returning undefined on invalid input instead of throwing.

/**
 * Decodes a Bech32/Bech32m string (returns undefined on error)
 * @param str - Bech32/Bech32m encoded string
 * @param LIMIT - Optional length limit (default: 90)
 * @returns Decoded object or undefined if invalid
 */
function decodeUnsafe(str: string, LIMIT?: number): Decoded | undefined;

Usage Examples:

import { bech32 } from "bech32";

const result = bech32.decodeUnsafe('invalid-bech32-string');
if (result) {
  console.log('Valid:', result);
} else {
  console.log('Invalid string');
}

Bit Conversion - To Words

Converts 8-bit bytes to 5-bit words for Bech32 encoding.

/**
 * Converts 8-bit bytes to 5-bit words
 * @param bytes - Array of 8-bit bytes
 * @returns Array of 5-bit words with padding
 */
function toWords(bytes: ArrayLike<number>): number[];

Usage Examples:

import { bech32 } from "bech32";

// Convert string to bytes then to words
const bytes = Buffer.from('hello', 'utf8');
const words = bech32.toWords(bytes);
console.log(words); // Array of 5-bit values

// Convert hex to words
const hexBytes = Buffer.from('deadbeef', 'hex');
const hexWords = bech32.toWords(hexBytes);

Bit Conversion - From Words (Safe)

Converts 5-bit words to 8-bit bytes with error throwing on invalid input.

/**
 * Converts 5-bit words to 8-bit bytes (throws on error)
 * @param words - Array of 5-bit words
 * @returns Array of 8-bit bytes
 * @throws Error for excess padding or non-zero padding
 */
function fromWords(words: ArrayLike<number>): number[];

Usage Examples:

import { bech32 } from "bech32";

try {
  const words = [15, 25, 9, 5, 23, 15, 17, 4, 8];
  const bytes = bech32.fromWords(words);
  const text = Buffer.from(bytes).toString('utf8');
  console.log(text);
} catch (error) {
  console.error('Invalid word padding:', error.message);
}

Bit Conversion - From Words (Unsafe)

Converts 5-bit words to 8-bit bytes returning undefined on invalid input.

/**
 * Converts 5-bit words to 8-bit bytes (returns undefined on error)
 * @param words - Array of 5-bit words
 * @returns Array of 8-bit bytes or undefined if invalid
 */
function fromWordsUnsafe(words: ArrayLike<number>): number[] | undefined;

Usage Examples:

import { bech32 } from "bech32";

const words = [15, 25, 9, 5, 23, 15, 17, 4, 8];
const bytes = bech32.fromWordsUnsafe(words);
if (bytes) {
  const text = Buffer.from(bytes).toString('utf8');
  console.log(text);
} else {
  console.log('Invalid padding');
}

Types

/**
 * Result structure for decoded Bech32/Bech32m strings
 */
interface Decoded {
  /** Human-readable prefix */
  prefix: string;
  /** Array of 5-bit words (values 0-31) */
  words: number[];
}

/**
 * Interface defining the structure of bech32/bech32m library objects
 */
interface BechLib {
  /** Decode with undefined return on error */
  decodeUnsafe: (str: string, LIMIT?: number) => Decoded | undefined;
  /** Decode with error throwing */
  decode: (str: string, LIMIT?: number) => Decoded;
  /** Encode prefix and words to string */
  encode: (prefix: string, words: ArrayLike<number>, LIMIT?: number) => string;
  /** Convert 8-bit bytes to 5-bit words */
  toWords: (bytes: ArrayLike<number>) => number[];
  /** Convert 5-bit words to 8-bit bytes (unsafe) */
  fromWordsUnsafe: (words: ArrayLike<number>) => number[] | undefined;
  /** Convert 5-bit words to 8-bit bytes (safe) */
  fromWords: (words: ArrayLike<number>) => number[];
}

Error Handling

The library provides comprehensive error handling for various invalid input scenarios:

  • Invalid prefix: Non-ASCII characters outside range 33-126
  • Mixed case strings: Strings with both uppercase and lowercase characters
  • Missing separator: Strings without the '1' separator character
  • Invalid characters: Characters not in the Bech32 alphabet
  • Checksum failures: Invalid or corrupted checksums
  • Length violations: Strings exceeding specified limits
  • Padding errors: Invalid bit padding during word conversion
  • Non-5-bit words: Values outside the 0-31 range for encoding

Common error patterns:

// Length limit exceeded
bech32.encode('test', words, 50); // May throw TypeError

// Invalid checksum
bech32.decode('bc1invalid'); // Throws Error with descriptive message

// Padding errors
bech32.fromWords([31, 31, 31]); // May throw Error for invalid padding