README.md (3693B)
1 # ppad-bolt9 2 3 [](https://hackage.haskell.org/package/ppad-bolt9) 4  5 [](https://docs.ppad.tech/bolt9) 6 7 A pure Haskell implementation of Lightning Network feature flags, per 8 [BOLT #9][bolt9]: an abstract feature vector type that preserves its 9 wire bytes, the table of known features with their contexts and 10 dependencies, sender- and receiver-side validation for each context, 11 and BOLT #2 channel types. 12 13 ## Usage 14 15 A sample GHCi session: 16 17 ``` 18 > :set -XOverloadedStrings 19 > 20 > -- import qualified 21 > import qualified Lightning.Protocol.BOLT9 as BOLT9 22 > 23 > -- build a feature vector for an init message, with dependencies 24 > let opt = BOLT9.Optional 25 > let fv = BOLT9.set_feature_with_deps BOLT9.OptionZeroconf opt BOLT9.empty 26 > BOLT9.list_features fv 27 [(OptionScidAlias,Optional),(OptionZeroconf,Optional)] 28 > 29 > -- check it against the sender's rules, then encode it 30 > BOLT9.validate_local BOLT9.InitContext fv 31 Right () 32 > BOLT9.render fv 33 "\b\128\NUL\NUL\NUL\NUL\NUL" 34 > 35 > -- a received vector keeps its exact bytes 36 > let theirs = BOLT9.parse "\NUL\STX\NUL\NUL" 37 > BOLT9.render theirs 38 "\NUL\STX\NUL\NUL" 39 > BOLT9.test_feature BOLT9.BasicMpp theirs 40 Just Optional 41 > 42 > -- check it against the receiver's rules for init 43 > BOLT9.validate_remote BOLT9.InitContext theirs 44 Right () 45 > BOLT9.validate_remote BOLT9.InitContext (BOLT9.set_bit 100 theirs) 46 Left (UnknownBit 100 :| []) 47 > 48 > -- channel types follow BOLT #2 49 > let ct = BOLT9.ChannelType BOLT9.BasicAnchors False True 50 > BOLT9.channel_type (BOLT9.channel_type_features ct) == Just ct 51 True 52 ``` 53 54 ## Documentation 55 56 Haddocks (API documentation, etc.) are hosted at 57 [docs.ppad.tech/bolt9](https://docs.ppad.tech/bolt9). 58 59 ## Specification 60 61 The library implements BOLT #9 as of [lightning/bolts@1aadb719][spec] 62 (2026-09-21), a copy of which lives in `etc/09-features.md`, together 63 with the feature-vector rules of BOLTs #1, #2, #4, #7 and #11 for each 64 context. 65 66 Not implemented: 67 68 * Feature fields of BOLT #12 offers, invoice requests and invoices, 69 which the BOLT #9 table assigns no context. 70 * The BOLT #11 encoding of features as 5-bit groups. 71 * BOLT #1's notions of *offered* and *negotiated* features. 72 * BOLT #2's rule against `option_scid_alias` in the channel type of an 73 announced channel, which depends on `channel_flags`. 74 * BOLT #4's check that a payment uses only features in 75 `allowed_features`. 76 * The `C-` and `C+` presentation rules for `channel_announcement`. No 77 feature in the table uses them, or `C`. 78 * The receiving requirements specific to each feature, which BOLT #9 79 defers to the linked sections of the other BOLTs. 80 81 BOLT #2 defines `zero_fee_commitments` as a basic channel type, though 82 the BOLT #9 table doesn't list it in the `T` context; `ChannelType` 83 follows BOLT #2. 84 85 ## Performance 86 87 The aim is best-in-class performance for pure Haskell code. Run the 88 benchmark suite with: 89 90 ``` 91 $ cabal bench 92 ``` 93 94 ## Security 95 96 This is a pre-release library and makes no claims about security 97 whatsoever. 98 99 ## Development 100 101 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 102 development shell with: 103 104 ``` 105 $ nix develop 106 ``` 107 108 Then do e.g.: 109 110 ``` 111 $ cabal repl ppad-bolt9 112 ``` 113 114 to get a REPL for the main library. 115 116 [bolt9]: https://github.com/lightning/bolts/blob/master/09-features.md 117 [spec]: https://github.com/lightning/bolts/blob/1aadb719b4007c4cea0ba6e36b08c4fb53788dee/09-features.md 118 [nixos]: https://nixos.org/ 119 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html