Skip to main content

Overview

The invoice module provides comprehensive Lightning Network invoice creation, parsing, and management. It handles invoice secret generation, persistence, metadata encryption, and builder-pattern invoice construction.

Invoice Structure

Represents a parsed Lightning Network invoice.
type Invoice struct {
    RawInvoice      string
    FallbackAddress *MuunPaymentURI
    Network         *Network
    MilliSat        string
    Destination     []byte
    PaymentHash     []byte
    Expiry          int64
    Description     string
    Sats            int64
}
RawInvoice
string
The original invoice string (bech32 encoded)
FallbackAddress
*MuunPaymentURI
Optional on-chain fallback address
MilliSat
string
Payment amount in millisatoshis
Destination
[]byte
Recipient node public key (compressed)
PaymentHash
[]byte
Payment hash (32 bytes)
Expiry
int64
Unix timestamp when invoice expires
Description
string
Invoice description/memo
Sats
int64
Payment amount in satoshis (MilliSat / 1000)

ParseInvoice

Parses a Lightning Network invoice string.
func ParseInvoice(rawInput string, network *Network) (*Invoice, error)
rawInput
string
required
Lightning invoice string (with or without “lightning:” prefix)
network
*Network
required
Network configuration (mainnet, testnet, regtest)
Returns: *Invoice - Parsed invoice structure
Errors: ErrInvalidInvoice

Example

network := Mainnet()
invoice, err := ParseInvoice(
    "lnbc10u1p3pj257pp5yztkwjcz5ytjw...",
    network,
)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Amount: %d sats\n", invoice.Sats)
fmt.Printf("Description: %s\n", invoice.Description)
fmt.Printf("Expiry: %d\n", invoice.Expiry)

Invoice Generation

InvoiceSecrets

Bundle of cryptographic secrets required for invoice generation.
type InvoiceSecrets struct {
    preimage      []byte
    paymentSecret []byte
    keyPath       string
    PaymentHash   []byte
    IdentityKey   *HDPublicKey
    UserHtlcKey   *HDPublicKey
    MuunHtlcKey   *HDPublicKey
    ShortChanId   int64
}
PaymentHash
[]byte
SHA256 hash of the preimage
IdentityKey
*HDPublicKey
Derived identity key for signing invoices
UserHtlcKey
*HDPublicKey
User’s HTLC key for receiving payments
MuunHtlcKey
*HDPublicKey
Muun’s HTLC key for receiving payments
ShortChanId
int64
Synthetic short channel ID

GenerateInvoiceSecrets

Generates new invoice secrets to register with the server.
func GenerateInvoiceSecrets(
    userKey, muunKey *HDPublicKey,
) (*InvoiceSecretsList, error)
userKey
*HDPublicKey
required
User’s HD public key
muunKey
*HDPublicKey
required
Muun’s HD public key
Returns: *InvoiceSecretsList - List of secrets to register
Generates: Up to MaxUnusedSecrets (5) new secrets

Example

// Generate secrets
secretsList, err := GenerateInvoiceSecrets(userPubKey, muunPubKey)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Generated %d secrets\n", secretsList.Length())

// Access individual secrets
for i := 0; i < secretsList.Length(); i++ {
    secret := secretsList.Get(i)
    fmt.Printf("Payment hash: %x\n", secret.PaymentHash)
}

PersistInvoiceSecrets

Stores registered secrets in the local database.
func PersistInvoiceSecrets(list *InvoiceSecretsList) error
list
*InvoiceSecretsList
required
List of secrets returned from server registration
Returns: error if database operation fails

Example

// Generate and persist secrets
secrets, err := GenerateInvoiceSecrets(userKey, muunKey)
if err != nil {
    log.Fatal(err)
}

// Register with server (not shown)
// ...

// Persist to local database
err = PersistInvoiceSecrets(secrets)
if err != nil {
    log.Fatal(err)
}

InvoiceBuilder

Builder pattern for creating Lightning invoices.
type InvoiceBuilder struct {
    net         *Network
    userKey     *HDPrivateKey
    routeHints  []*RouteHints
    description string
    amountMSat  lnwire.MilliSatoshi
    metadata    *OperationMetadata
}

Builder Methods

Network

func (i *InvoiceBuilder) Network(net *Network) *InvoiceBuilder
net
*Network
required
Network configuration

UserKey

func (i *InvoiceBuilder) UserKey(userKey *HDPrivateKey) *InvoiceBuilder
userKey
*HDPrivateKey
required
User’s private key for signing

Description

func (i *InvoiceBuilder) Description(description string) *InvoiceBuilder
description
string
Invoice description/memo

AmountSat

func (i *InvoiceBuilder) AmountSat(amountSat int64) *InvoiceBuilder
amountSat
int64
Amount in satoshis

AmountMSat

func (i *InvoiceBuilder) AmountMSat(amountMSat int64) *InvoiceBuilder
amountMSat
int64
Amount in millisatoshis

AddRouteHints

func (i *InvoiceBuilder) AddRouteHints(routeHints *RouteHints) *InvoiceBuilder
routeHints
*RouteHints
required
Routing hints for reaching the node

Metadata

func (i *InvoiceBuilder) Metadata(metadata *OperationMetadata) *InvoiceBuilder
metadata
*OperationMetadata
Additional encrypted metadata

Build

Creates and returns the signed invoice string.
func (i *InvoiceBuilder) Build() (string, error)
Returns: string - Bech32 encoded Lightning invoice
Errors: Database errors, signing errors, no unused secrets available

Complete Example

builder := &InvoiceBuilder{}
invoice, err := builder.
    Network(Mainnet()).
    UserKey(userPrivateKey).
    Description("Coffee payment").
    AmountSat(5000).
    Build()

if err != nil {
    log.Fatal(err)
}

fmt.Printf("Invoice: %s\n", invoice)

RouteHints

Routing information for reaching the invoice recipient.
type RouteHints struct {
    Pubkey                    string
    FeeBaseMsat               int64
    FeeProportionalMillionths int64
    CltvExpiryDelta           int32
}
Pubkey
string
required
Public key of the routing node (hex)
FeeBaseMsat
int64
required
Base routing fee in millisatoshis
FeeProportionalMillionths
int64
required
Proportional fee in millionths (ppm)
CltvExpiryDelta
int32
required
CLTV expiry delta in blocks

OperationMetadata

Encrypted metadata stored with invoices.
type OperationMetadata struct {
    Invoice     string `json:"invoice,omitempty"`
    LnurlSender string `json:"lnurlSender,omitempty"`
}
Invoice
string
The generated invoice string
LnurlSender
string
LNURL sender identifier

GetInvoiceMetadata

Retrieves encrypted metadata for a payment hash.
func GetInvoiceMetadata(paymentHash []byte) (string, error)
paymentHash
[]byte
required
Payment hash (32 bytes)
Returns: string - Encrypted metadata
Errors: Database errors, invoice not found

Invoice Features

Generated invoices include the following features:
// Required features
features.Set(lnwire.TLVOnionPayloadRequired)
features.Set(lnwire.PaymentAddrRequired)

Standard Parameters

  • CLTV Expiry: 72 blocks (~12 hours)
  • Expiry Time: 24 hours
  • Payment Secret: Required for all invoices
  • TLV Onion: Required for payment secrets
Payment secrets are required in all Muun invoices to prevent amount theft attacks. This has been standard since LND v0.12.0 (January 2021).

Key Derivation Paths

Invoice keys are derived using the following structure:
Base path: m/schema:1'/recovery:1'/invoices:4/<random1>/<random2>
├── /0 - Identity key (invoice signing)
├── /1 - HTLC key (payment receiving)
└── /3 - Metadata encryption key

Constants

const MaxUnusedSecrets = 5

const (
    identityKeyChildIndex          = 0
    htlcKeyChildIndex              = 1
    encryptedMetadataKeyChildIndex = 3
)

const lightningScheme = "lightning:"

Security Features

Secret Management

  • Preimages generated with cryptographically secure randomness
  • Payment secrets unique per invoice
  • Automatic secret rotation (max 5 unused)
  • Secure key derivation with random indexes

Metadata Encryption

  • Metadata encrypted with derived encryption key
  • Unique encryption key per invoice
  • JSON encoding before encryption

Invoice Signing

  • Signed with derived identity key
  • Compact signature format
  • BIP340-compatible for modern wallets

Build docs developers (and LLMs) love