Download the PHP package nova-carnivore/bolt12-php without Composer
On this page you can find all versions of the php package nova-carnivore/bolt12-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package bolt12-php
bolt12-php
Modern PHP 8.3+ BOLT 12 Lightning Network offer/invoice encoder/decoder with BIP-340 Schnorr signatures. Full spec compliance, production-ready.
Features
- ⚡ Full BOLT 12 spec compliance — Offers, Invoice Requests, Invoices, Invoice Errors
- 🔐 BIP-340 Schnorr signatures — Pure PHP implementation with Merkle tree construction
- 🏗️ Modern PHP 8.3+ — Enums, readonly classes, named arguments, match expressions
- 🔍 PHPStan level 9 — Maximum static analysis strictness
- 🌐 All message types — Offer (lno), Invoice Request (lnr), Invoice (lni), Invoice Error
- 🏷️ All TLV fields — chains, metadata, currency, amounts, paths, features, BIP-353, and more
- 🔄 Round-trip safe — Encode → decode preserves all data
- 📏 PSR-12 code style — Enforced with PHP-CS-Fixer
- 🔒 Constant-time crypto — Uses GMP for big integer operations
- 🔗 Blinded paths — Full support for multi-hop blinded payment paths
Installation
Requirements
- PHP 8.3 or higher
- ext-gmp (required for big integers and BIP-340 crypto)
Quick Start
Decode (Auto-detect Type)
Encode an Offer
Encode an Invoice Request (auto-signed)
Encode an Invoice (auto-signed)
Verify Signatures
Invoice Errors
Full Payment Flow Example
API Reference
Decoder::decode(string $bolt12String): Offer|InvoiceRequest|Invoice
Decodes any BOLT 12 bech32 string (auto-detects type by prefix).
Decoder::decodeInvoiceError(array $bytes): InvoiceError
Decodes a BOLT 12 Invoice Error from raw TLV bytes.
Encoder::encodeOffer(...): string
Encodes a BOLT 12 Offer (lno1...). Not signed per spec.
Encoder::encodeInvoiceRequest(...): string
Encodes and signs a BOLT 12 Invoice Request (lnr1...).
Encoder::encodeInvoice(...): string
Encodes and signs a BOLT 12 Invoice (lni1...).
Encoder::encodeInvoiceError(...): array
Encodes a BOLT 12 Invoice Error as raw TLV bytes.
Signer::verifyInvoiceRequest(InvoiceRequest $invReq): bool
Verifies a BIP-340 Schnorr signature on an invoice request.
Signer::verifyInvoice(Invoice $invoice): bool
Verifies a BIP-340 Schnorr signature on an invoice.
Signer::getPublicKey(string $privateKeyHex): string
Derives a compressed public key from a private key.
Data Classes
| Class | Description |
|---|---|
Offer |
Decoded offer with all fields as readonly properties |
InvoiceRequest |
Decoded invoice request with signature |
Invoice |
Decoded invoice with paths, payinfo, and signature |
InvoiceError |
Decoded invoice error |
BlindedPath |
Blinded path with hops |
BlindedPayInfo |
Payment info for blinded paths |
FallbackAddress |
On-chain fallback address |
OnionMessageHop |
Single hop in a blinded path |
Bip353Name |
BIP-353 name (user@domain) |
TlvEntry |
Raw TLV type-value pair |
BOLT 12 Spec Coverage
Message Types
| Type | Prefix | Encode | Decode | Sign | Verify |
|---|---|---|---|---|---|
| Offer | lno |
✅ | ✅ | ✅* | ✅* |
| Invoice Request | lnr |
✅ | ✅ | ✅ | ✅ |
| Invoice | lni |
✅ | ✅ | ✅ | ✅ |
| Invoice Error | — | ✅ | ✅ | N/A | N/A |
* Offers are optionally signed per spec
TLV Fields
| Type | Field | Offer | InvReq | Invoice |
|---|---|---|---|---|
| 0 | invreq_metadata |
— | ✅ | ✅ |
| 2 | offer_chains |
✅ | ✅ | ✅ |
| 4 | offer_metadata |
✅ | ✅ | ✅ |
| 6 | offer_currency |
✅ | ✅ | ✅ |
| 8 | offer_amount |
✅ | ✅ | ✅ |
| 10 | offer_description |
✅ | ✅ | ✅ |
| 12 | offer_features |
✅ | ✅ | ✅ |
| 14 | offer_absolute_expiry |
✅ | ✅ | ✅ |
| 16 | offer_paths |
✅ | ✅ | ✅ |
| 18 | offer_issuer |
✅ | ✅ | ✅ |
| 20 | offer_quantity_max |
✅ | ✅ | ✅ |
| 22 | offer_issuer_id |
✅ | ✅ | ✅ |
| 80 | invreq_chain |
— | ✅ | ✅ |
| 82 | invreq_amount |
— | ✅ | ✅ |
| 84 | invreq_features |
— | ✅ | ✅ |
| 86 | invreq_quantity |
— | ✅ | ✅ |
| 88 | invreq_payer_id |
— | ✅ | ✅ |
| 89 | invreq_payer_note |
— | ✅ | ✅ |
| 90 | invreq_paths |
— | ✅ | ✅ |
| 91 | invreq_bip_353_name |
— | ✅ | ✅ |
| 160 | invoice_paths |
— | — | ✅ |
| 162 | invoice_blindedpay |
— | — | ✅ |
| 164 | invoice_created_at |
— | — | ✅ |
| 166 | invoice_relative_expiry |
— | — | ✅ |
| 168 | invoice_payment_hash |
— | — | ✅ |
| 170 | invoice_amount |
— | — | ✅ |
| 172 | invoice_fallbacks |
— | — | ✅ |
| 174 | invoice_features |
— | — | ✅ |
| 176 | invoice_node_id |
— | — | ✅ |
| 240 | signature |
✅* | ✅ | ✅ |
Encoding
- Bech32 without checksum — per BOLT 12 spec
- BigSize TLV type/length encoding
- tu64 truncated unsigned 64-bit values
+concatenation support for long strings
Cryptography
- BIP-340 Schnorr signatures (64-byte raw, not DER)
- Tagged hashes —
SHA256(SHA256(tag) || SHA256(tag) || msg) - Merkle tree for multi-TLV signatures with nonce leaves
- secp256k1 elliptic curve arithmetic
Security
- BIP-340 Schnorr signatures use pure PHP with GMP for big integer arithmetic
- All elliptic curve operations use constant-time modular arithmetic via GMP
- The Merkle tree construction includes nonce leaves to prevent revealing adjacent fields
- Private keys are only used in signing operations and never stored
Exception Handling
Development
Architecture
Key Differences from BOLT 11
| Feature | BOLT 11 | BOLT 12 |
|---|---|---|
| Encoding | Bech32 with checksum | Bech32 without checksum |
| Crypto | ECDSA recovery | BIP-340 Schnorr |
| Signatures | Simple message hash | Merkle tree construction |
| TLV encoding | 5-bit continuation | BigSize encoding |
| Message types | 1 (invoice only) | 4 (offer, invreq, invoice, error) |
| Privacy | Direct node ID | Blinded paths |
License
MIT — see LICENSE.