CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-bech32

Bech32 and Bech32m encoding/decoding library for Bitcoin addresses

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/bech32@2.0.x
Publish Source
CLI
Badge
tessl/npm-bech32 badge