Skip to content

BOLT-11 Invoice Decoder

Decode BOLT-11 Lightning invoices to extract amount, payment hash, description, expiry, route hints, payee node key, and all other tagged fields. Supports mainnet, testnet, signet, and regtest invoices.

Import

ts
import { bolt11 } from 'nostr-core'
// or import individual functions
import { decodeBolt11, Bolt11Error } from 'nostr-core'

Bolt11Invoice Type

ts
type Bolt11Invoice = {
  paymentRequest: string
  prefix: string
  network: Bolt11Network
  amountMsat?: number
  amountSat?: number
  timestamp: number
  expiry: number
  expiresAt: number
  isExpired: boolean
  paymentHash: string
  paymentSecret?: string
  description?: string
  descriptionHash?: string
  payeeNodeKey?: string
  minFinalCltvExpiry: number
  featureBits?: Uint8Array
  metadata?: string
  routeHints: Bolt11RouteHint[][]
  fallbackAddresses: Bolt11FallbackAddress[]
  signature: string
  recoveryFlag: number
  unknownTags: { tag: number; words: number[] }[]
}
FieldTypeDescription
paymentRequeststringCanonical lowercase invoice string
prefixstringHRP prefix (e.g. "lnbc2500u")
networkBolt11Network"mainnet", "testnet", "signet", or "regtest"
amountMsatnumber (optional)Amount in millisatoshis (undefined for zero-amount invoices)
amountSatnumber (optional)Amount in satoshis
timestampnumberUnix timestamp when invoice was created
expirynumberExpiry time in seconds (default 3600)
expiresAtnumberAbsolute expiry (timestamp + expiry)
isExpiredbooleanWhether expired at decode time
paymentHashstringPayment hash (256-bit, hex)
paymentSecretstring (optional)Payment secret (256-bit, hex)
descriptionstring (optional)Short description (UTF-8)
descriptionHashstring (optional)SHA-256 hash of a longer description (hex)
payeeNodeKeystring (optional)Payee node public key (33-byte compressed, hex). Recovered from signature if not in n tag.
minFinalCltvExpirynumberMin final CLTV expiry delta in blocks (default 18)
featureBitsUint8Array (optional)Feature bit flags
metadatastring (optional)Payment metadata (hex)
routeHintsBolt11RouteHint[][]Route hints for private channels
fallbackAddressesBolt11FallbackAddress[]Fallback on-chain addresses
signaturestringSignature R||S (64 bytes, hex)
recoveryFlagnumberSignature recovery flag (0-3)

Bolt11RouteHint Type

ts
type Bolt11RouteHint = {
  pubkey: string
  shortChannelId: string
  feeBaseMsat: number
  feeProportionalMillionths: number
  cltvExpiryDelta: number
}

Bolt11FallbackAddress Type

ts
type Bolt11FallbackAddress = {
  version: number
  hex: string
}

Bolt11Error Class

ts
class Bolt11Error extends Error {
  code: string
}
CodeDescription
INVALID_BECH32Invalid bech32 encoding or checksum
INVALID_PREFIXPrefix doesn't start with "ln"
INVALID_AMOUNTMalformed amount in HRP
UNKNOWN_NETWORKUnrecognized currency prefix
INVALID_LENGTHInvoice data too short
INVALID_TAGTag data overflows invoice
MISSING_PAYMENT_HASHRequired payment hash tag missing

bolt11.decode / decodeBolt11

ts
function decode(invoice: string): Bolt11Invoice

Decodes a BOLT-11 Lightning invoice string.

ParameterTypeDescription
invoicestringBOLT-11 invoice (e.g. "lnbc10u1p...")

Returns: Bolt11Invoice - Decoded invoice with all fields.

Throws: Bolt11Error if the invoice is malformed.

Accepts uppercase (QR code format) and lightning: URI prefix.

ts
const decoded = bolt11.decode('lnbc2500u1pvjluez...')

console.log(decoded.network)         // 'mainnet'
console.log(decoded.amountSat)       // 250000
console.log(decoded.paymentHash)     // '0001020304...'
console.log(decoded.description)     // '1 cup coffee'
console.log(decoded.payeeNodeKey)    // '03e7156a...'
console.log(decoded.isExpired)       // true/false

// Also works with lightning: prefix
const d2 = bolt11.decode('lightning:lnbc10u1p...')

// Also works with uppercase (QR code)
const d3 = bolt11.decode('LNBC10U1P...')

Full Example

ts
import { bolt11, NWC } from 'nostr-core'

// Decode an invoice before paying
const invoice = 'lnbc2500u1pvjluez...'
const decoded = bolt11.decode(invoice)

// Check amount and expiry
if (decoded.isExpired) {
  console.log('Invoice expired!')
} else {
  console.log(`Pay ${decoded.amountSat} sats to ${decoded.payeeNodeKey}`)
  console.log(`Description: ${decoded.description}`)
  console.log(`Expires in ${decoded.expiresAt - Math.floor(Date.now() / 1000)}s`)

  // Pay via NWC
  const nwc = new NWC('nostr+walletconnect://...')
  await nwc.connect()
  const result = await nwc.payInvoice(invoice)
  console.log('Paid! Preimage:', result.preimage)
  nwc.close()
}

Amount Multipliers

SuffixMultiplierExampleAmount
(none)1 BTClnbc1100,000,000 sat
mmilli-BTClnbc20m2,000,000 sat
umicro-BTClnbc2500u250,000 sat
nnano-BTClnbc1500n150 sat
ppico-BTClnbc10p0.001 sat (1 msat)

Released under the MIT License.