npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bolt11-ts

v0.2.1

Published

Modern TypeScript BOLT 11 Lightning Network payment request encoder/decoder

Downloads

306

Readme

bolt11-ts

npm version CI License: MIT TypeScript Node.js

Modern TypeScript implementation of BOLT 11 Lightning Network payment request encoder/decoder with a minimal dependency tree.

Why bolt11-ts?

The original bolt11 library hasn't been updated in years and has a large dependency tree (including elliptic). This library is a complete rewrite in TypeScript that:

  • Minimal dependencies - Only depends on @noble/secp256k1 and @noble/hashes (audited, zero transitive deps)
  • Full BOLT 11 compliance - Passes all specification test vectors
  • Modern TypeScript - Full type safety and excellent IDE support
  • ESM native - Built for modern JavaScript
  • Universal runtime - Works in Node.js, Bun, Deno, and browsers (no polyfills needed)
  • Well tested - Comprehensive test suite including spec vectors
  • Easy migration - Similar API to the original library (see migration guide)

Installation

npm install bolt11-ts

Runtime Compatibility

| Runtime | Status | Notes | |---------|--------|-------| | Node.js 20+ | ✅ Tested in CI | Full support | | Bun 1.x | ✅ Tested in CI | Full support | | Deno 2.x | ✅ Tested in CI | Use --unstable-sloppy-imports for .js extensions | | Browsers (Chromium, Firefox, WebKit) | ✅ Tested in CI | Playwright tests against real browser engines |

No polyfills required — uses @noble/hashes for SHA-256, TextEncoder/TextDecoder, and @noble/secp256k1 which are all universal.

Quick Start

import { decode, encode, sign } from 'bolt11-ts';

// Decode a payment request
const invoice = 'lnbc2500u1pvjluezsp5zyg3zyg3zyg3...';
const decoded = await decode(invoice);

console.log(decoded.satoshis); // 250000
console.log(decoded.tagsObject.description); // '1 cup coffee'
console.log(decoded.payeeNodeKey); // '03e7156ae33b0a...'

// Encode and sign a payment request
const unsigned = encode({
  network: 'bitcoin',
  satoshis: 250000,
  tags: [
    { tagName: 'payment_hash', data: '...' },
    { tagName: 'payment_secret', data: '...' },
    { tagName: 'description', data: '1 cup coffee' },
    { tagName: 'expire_time', data: 3600 },
  ],
});

const signed = await sign(unsigned, privateKeyHex);
console.log(signed.paymentRequest); // 'lnbc2500u1...'

API

decode(paymentRequest: string): Promise<PaymentRequestObject>

Decodes a BOLT 11 payment request string.

const decoded = await decode('lnbc2500u1pvjluez...');

// Returns:
{
  paymentRequest: string;
  complete: boolean;
  prefix: string;
  network: Network;
  satoshis: number | null;
  millisatoshis: string | null;
  timestamp: number;
  timestampString: string;
  timeExpireDate: number;
  timeExpireDateString: string;
  payeeNodeKey: string | null;
  signature: string;
  recoveryFlag: number;
  tags: TagData[];
  tagsObject: TagsObject;
}

encode(options: EncodeOptions): PaymentRequestObject

Creates an unsigned payment request.

const unsigned = encode({
  network: 'bitcoin', // or 'testnet', 'regtest', 'simnet'
  satoshis: 1000, // optional
  millisatoshis: '1000000', // optional (alternative to satoshis)
  timestamp: 1496314658, // optional (defaults to current time)
  tags: [
    { tagName: 'payment_hash', data: 'hex string' },
    { tagName: 'payment_secret', data: 'hex string' },
    { tagName: 'description', data: 'Coffee' },
    { tagName: 'expire_time', data: 3600 },
    { tagName: 'min_final_cltv_expiry', data: 144 },
    // ... more tags
  ],
});

sign(paymentRequest: PaymentRequestObject, privateKey: string): Promise<SignedPaymentRequest>

Signs a payment request with a private key.

const signed = await sign(unsigned, privateKeyHex);
console.log(signed.paymentRequest); // Full encoded payment request

Supported Tags

| Tag Name | BOLT 11 Code | Description | |----------|--------------|-------------| | payment_hash | p (1) | Payment hash (required) | | payment_secret | s (16) | Payment secret (required) | | description | d (13) | Short UTF-8 description | | purpose_commit_hash | h (23) | Hash of description >639 bytes | | payee | n (19) | Payee public key | | expire_time | x (6) | Expiry time in seconds | | min_final_cltv_expiry | c (24) | Min final CLTV expiry | | fallback_address | f (9) | On-chain fallback address | | route_hint | r (3) | Routing hints for private channels | | feature_bits | 9 (5) | Feature bits | | metadata | m (27) | Payment metadata |

Migration from bolt11

This library has a similar API but is not a drop-in replacement — key methods are now async:

// Old:
import * as bolt11 from 'bolt11';
const decoded = bolt11.decode('lnbc...');

// New:
import { decode } from 'bolt11-ts';
const decoded = await decode('lnbc...');
// Note: decode() is now async due to crypto operations

Key Differences

  1. Async crypto: decode() and sign() are async (use @noble/secp256k1)
  2. ESM only: No CommonJS support (use Node.js 20+)
  3. Stricter types: Full TypeScript with strict type checking

Examples

Decode with all features

const decoded = await decode(invoice);

// Access common fields
console.log(decoded.satoshis);
console.log(decoded.timestamp);
console.log(decoded.payeeNodeKey);

// Access specific tags
console.log(decoded.tagsObject.description);
console.log(decoded.tagsObject.payment_hash);
console.log(decoded.tagsObject.expire_time);
console.log(decoded.tagsObject.route_hint);

Create invoice with routing hints

const unsigned = encode({
  network: 'bitcoin',
  satoshis: 10000,
  tags: [
    { tagName: 'payment_hash', data: paymentHashHex },
    { tagName: 'payment_secret', data: secretHex },
    { tagName: 'description', data: 'Premium coffee' },
    { 
      tagName: 'route_hint', 
      data: [
        {
          pubkey: '029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255',
          short_channel_id: '0102030405060708',
          fee_base_msat: 1000,
          fee_proportional_millionths: 100,
          cltv_expiry_delta: 40,
        },
      ],
    },
  ],
});

const signed = await sign(unsigned, privateKey);

Testing

# Run all tests
npm test

# Run specific test suite
npx tsx test/decode.test.ts
npx tsx test/encode.test.ts
npx tsx test/spec-vectors.test.ts

# Type check
npm run typecheck

# Lint
npm run lint

# Format
npm run format

Development

# Install dependencies
npm install

# Build
npm run build

# Run tests with coverage
npm test -- --experimental-test-coverage

# Format code
npm run format

Specification

This library implements BOLT #11: Invoice Protocol for Lightning Payments.

All test vectors from the specification are included in the test suite and pass.

Security

Minimal Dependency Tree

This library has two production dependencies, both from the audited @noble family by Paul Miller:

Both have zero transitive dependencies, are audited, and work across all runtimes. A minimal dependency tree reduces the attack surface compared to the original bolt11 package.

Reporting Vulnerabilities

If you discover a security vulnerability, please open a GitHub issue.

License

MIT © Nova Carnivore

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass: npm test
  5. Format code: npm run format
  6. Submit a pull request

Acknowledgments

See Also