Pure TypeScript BOLT12 library (bolt12-utils)#30
Open
vincenzopalazzo wants to merge 22 commits into
Open
Conversation
Replace the outdated JavaScript implementation (bip-schnorr, js-sha256) with a modern TypeScript library using only audited pure-JS dependencies (@noble/curves, @noble/hashes). Passes all 53 official test vectors from lightning/bolts offers-test.json including valid offers, malformed input rejection, and semantic validation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vanilla JS/HTML/CSS single-page website that: - Interactive decoder: paste any lno offer, see color-coded TLV fields with hover-to-inspect detail panel (inspired by bolt11.org) - Educational sections: BOLT11 vs BOLT12 comparison, message flow diagram, offer fields reference table, key concepts (blinded paths, TLV encoding, Merkle signatures, bech32) - Learning resources with links to the spec, bolt12.org, LDK, Optech - Uses the bolt12-decoder library bundled via esbuild for browser Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements parsing, merkle reconstruction, and signature verification for payer proofs (lnp prefix). Includes 13 tests covering all validation paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update decoder to handle all BOLT12 message types (offers, invoice requests, invoices, payer proofs). Add GitHub Actions workflow to deploy the website/ directory to GitHub Pages on push to master. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a Usage section with copy-able code snippets showing how to decode offers, parse TLV streams, verify signatures, and use payer proofs. Includes a "Run" button that decodes a sample offer live in the browser. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each code snippet now executes automatically on page load using the bundled bolt12 library, with the real output rendered directly below. No "Run" button needed - results are visible immediately. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a split-pane editor/output playground (like TypeScript Playground). Users can edit code on the left and see live results on the right. Three example tabs: Decode Offer, TLV Parsing, Validate. Code runs via the bundled bolt12 library. Supports Ctrl+Enter and Tab indenting. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
decodeOffer() now returns named fields directly:
const { description, amount, issuer_id, offer_id } = decodeOffer(str);
Adds fields.ts with OfferFields interface and extractOfferFields().
Updates playground examples to showcase the destructured API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Buffer.from().toString('hex') in merkle.ts and
payer_proof.ts with pure JS byte comparison, fixing
"ReferenceError: Buffer is not defined" in the browser.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement createPayerProof() that generates BOLT12 payer proofs from invoices, preimages, and payer secret keys. Fix merkle tree algorithm to use LnNonce (matching LDK) instead of LnAll, and use recursive DFS tree traversal for correct missing_hashes ordering. All 7 test vectors pass (3 basic, 3 with notes, 1 invalid preimage). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add documentation section explaining BOLT12 payer proofs with selective disclosure flow diagram and TLV field reference table. Add interactive playground tab demonstrating createPayerProof API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New tab demonstrates decoding and verifying a payer proof, showing disclosed fields, omitted markers, and payer info. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These earlier implementations have been superseded by the pure TypeScript rewrite in js/. Updated README, Makefile, and TODO to reflect the new project structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…CSVs Update the lightning-rfc submodule from rustyrussell/lightning-rfc (guilt/offers branch) to the official lightning/bolts master. Regenerate all spec CSV files from the latest BOLT markdown: - bolt12.csv: new spec field name prefixes (offer_, invreq_, invoice_), new fields (invreq_paths, invreq_bip_353_name, invoice_amount), updated blinded_payinfo with htlc_minimum/maximum_msat - bolt4.csv: updated onion routing types - bolt1.csv: updated messaging types Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New tools/generate-ts.ts replaces the broken Python generate-code.py (which fails on the latest spec's sciddir_or_pubkey type). The generator parses CSV spec files directly and produces: - TypeScript interfaces (OfferFields, InvoiceRequestFields, InvoiceFields, InvoiceErrorFields, BlindedPayinfo, FallbackAddress) - CONSTANT_CASE TLV type constants for all message types - KNOWN_*_TYPES sets for validation - TLV name lookup maps - Field extractor functions (extractOfferFields, etc.) Generated code uses pure Uint8Array (no Node.js Buffer), matching the existing codebase conventions. Complex subtypes (blinded_path, fallback_address) are stored as raw bytes for custom parser handling. Output marked with @fileoverview and @generated JSDoc tags. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Export all generated types, constants, and extractors from index.ts (GeneratedOfferFields, InvoiceRequestFields, InvoiceFields, etc.) - Add 'generate' npm script: npm run generate - Add generated-test.ts with 22 smoke tests verifying constants, lookup tables, extractor parity with hand-written code, and spec-compliant field naming - Update test script to run all 3 test suites (82 total tests) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Style guide (google.github.io/styleguide/tsguide.html): - Always use braces for control structures (utils, offer, bech32, fields, payer_proof) - Replace catch(e: any) with catch(e: unknown) + type narrowing in payer_proof.ts Deprecation: - Mark fields.ts module, OfferFields, Chain, and extractOfferFields with @deprecated JSDoc tags pointing to generated.ts replacements - Add migration guidance in deprecation messages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add files, repository, keywords, author fields and prepublishOnly script. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add comprehensive README with full API reference, examples, and type docs - Rename package from bolt12-decoder to bolt12-utils - Add BIP21/321 donation URI with taproot, ARK, and BOLT12 offer (lno= param) - Update website install hint to bolt12-utils Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5fbc135 to
f0b7a59
Compare
- Remove old node-test (Node 10-15), python-tests (3.6-3.9), and BOLT quote tests jobs — all referenced deleted python/ and javascript/ dirs - Add TypeScript test matrix (Node 18, 20, 22) - Add generated types drift check (regenerate + git diff) - Update actions to v4 (checkout, setup-node) - Update Makefile to use npm instead of make -C js - Clean up pages workflow branch list Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add verification tests mirroring ocean-ln's verify_offer_payment logic: - Test 1: Valid CLN offer + invoice + preimage (full verification passes) - Test 2/3: Phoenix wallet offer with blinded paths (verification correctly rejects due to payment hash mismatch with mismatched preimage) The verification flow exercises decoding offers and invoices, extracting signing pubkeys (including fallback from blinded paths), comparing offer IDs, verifying invoice signatures, and checking proof-of-payment via SHA256(preimage) == payment_hash. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Complete rewrite of the JS/TypeScript BOLT12 library as a pure TypeScript implementation with zero native dependencies. Published as
bolt12-utilson npm.@noble/curves(secp256k1/schnorr) and@noble/hashes(SHA-256), no Node.jsBuffertools/generate-ts.tsreplaces the broken Python generator (which fails on modern spec'ssciddir_or_pubkeytype). Covers all 4 message types: offer, invoice_request, invoice, invoice_errorlightning-rfcsubmodule pointed to latest lightning/bolts master, CSVs regeneratedlnpmessages (BOLT12 PR #1295)fields.tspreserved but@deprecatedChanges
js/src/js/test/js/README.mdtools/generate-ts.tsgenerate-code.pyspecs/website/python/,javascript/,bolt12/directories (superseded)Maintenance
I will maintain the
bolt12-utilsnpm package and keep the generated types in sync with the BOLT12 spec as it evolves.Test plan
cd js && npm test— all 82 tests passnpm run build— TypeScript compiles cleanlynpm run generate— types regenerate from spec CSVnpm run build:web— browser bundle buildsnpm pack— 49.6 kB, 51 files🤖 Generated with Claude Code