README.md (4735B)
1 # ppad-bolt3 2 3 [](https://hackage.haskell.org/package/ppad-bolt3) 4  5 [](https://docs.ppad.tech/bolt3) 6 7 A pure Haskell implementation of [BOLT #3][bolt3], the Lightning 8 Network's Bitcoin transaction and script formats: commitment, HTLC and 9 closing transactions, their output scripts and witnesses, 10 per-commitment key derivation, and per-commitment secret generation and 11 storage. 12 13 Amounts, points and secrets use the types of [ppad-bolt1][bolt1], and 14 transactions convert to [ppad-tx][tx] for txids, sighashes and 15 serialization. 16 17 ## Usage 18 19 A sample GHCi session: 20 21 ``` 22 > :set -XOverloadedStrings 23 > import qualified Bitcoin.Prim.Tx as BT 24 > import qualified Data.ByteString as BS 25 > import qualified Lightning.Protocol.BOLT1 as BOLT1 26 > import Lightning.Protocol.BOLT3 27 > 28 > -- per-commitment secrets come from a seed; secrets aren't shown 29 > let Just sd = seed (BS.replicate 32 0xff) 30 > let Just cn = commitment_number 0 31 > let i = commitment_secret_index cn 32 > let secret = generate_from_seed sd i 33 > secret 34 PerCommitmentSecret <redacted> 35 > 36 > -- the peer keeps revealed secrets in compact storage 37 > let Just store = insert_secret secret i empty_secret_store 38 > fmap (== secret) (derive_old_secret i store) 39 Just True 40 > 41 > -- the commitment's per-commitment point, and a private key for it 42 > let Just pcp = derive_per_commitment_point secret 43 > let Just base = seckey (BS.pack [1 .. 32]) 44 > derive_privkey base pcp 45 Just (Seckey <redacted>) 46 > 47 > -- fees and HTLC trimming 48 > commitment_fee (FeeratePerKw 5000) StaticRemotekey 2 49 Satoshi 5340 50 > let Just dust = fmap DustLimit (BOLT1.satoshi 546) 51 > htlc_trim_threshold dust (FeeratePerKw 5000) StaticRemotekey HTLCOffered 52 Satoshi 3861 53 > 54 > -- an option_simple_close transaction: the closer pays the fee, and 55 > -- its OP_RETURN output has amount zero 56 > let Just txid = BT.mkTxId (BS.replicate 32 0x01) 57 > let Just [closer, closee] = traverse BOLT1.milli_satoshi [6000000, 4000000] 58 > let Just fee = BOLT1.satoshi 500 59 > let p2wpkh = Script . BS.append "\x00\x14" . BS.replicate 20 60 :{ 61 ghci| let close = ClosingContext { 62 ghci| clc_funding_outpoint = BT.OutPoint txid 0 63 ghci| , clc_closer_msat = closer 64 ghci| , clc_closee_msat = closee 65 ghci| , clc_closer_script = Script "\x6a" 66 ghci| , clc_closee_script = p2wpkh 0x22 67 ghci| , clc_fee = fee 68 ghci| , clc_locktime = Locktime 0 69 ghci| , clc_outputs = CloserAndCloseeOutputs 70 ghci| } 71 ghci| :} 72 > let Just tx = build_closing_tx close 73 > fmap clo_value (cltx_outputs tx) 74 Satoshi 0 :| [Satoshi 4000] 75 > BS.length (encode_closing_tx tx) 76 92 77 ``` 78 79 ## Documentation 80 81 Haddocks (API documentation, etc.) are hosted at 82 [docs.ppad.tech/bolt3](https://docs.ppad.tech/bolt3). 83 84 ## Specification 85 86 This library implements BOLT #3 as of lightning/bolts commit 87 [1aadb719][spec] (2026-09-21); a copy lives in `etc/`. Every test 88 vector in Appendices B through F is checked byte for byte. 89 90 Not implemented: 91 92 * `zero_fee_commitments` (version 3 commitment and HTLC transactions, 93 the `shared_anchor` P2A output, and Appendix H). Only the 94 `option_static_remotekey` and `option_anchors` commitment formats are 95 supported. 96 * Funding transaction construction (including Appendix G's dual-funded 97 vectors): the library provides the funding output's script and 98 witness only. 99 100 The library builds unsigned transactions; signatures are made with 101 [ppad-secp256k1][secp] over sighashes from ppad-tx. Spending 102 transactions for on-chain resolution belong to BOLT #5. 103 104 ## Performance 105 106 The aim is best-in-class performance for pure Haskell code. Run the 107 benchmarks with: 108 109 ``` 110 $ cabal bench 111 ``` 112 113 ## Security 114 115 This library has received no security audit. Secret material (seeds, 116 secret keys, per-commitment secrets and their storage) is kept out of 117 `Show` output, and private-key derivation uses constant-time 118 arithmetic. 119 120 ## Development 121 122 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 123 development shell with: 124 125 ``` 126 $ nix develop 127 ``` 128 129 Then do e.g.: 130 131 ``` 132 $ cabal repl ppad-bolt3 133 ``` 134 135 to get a REPL for the main library. 136 137 [bolt3]: https://github.com/lightning/bolts/blob/master/03-transactions.md 138 [bolt1]: https://git.ppad.tech/bolt1 139 [tx]: https://git.ppad.tech/tx 140 [secp]: https://git.ppad.tech/secp256k1 141 [spec]: https://github.com/lightning/bolts/tree/1aadb719b4007c4cea0ba6e36b08c4fb53788dee 142 [nixos]: https://nixos.org/ 143 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html