bolt3

Lightning transaction and script formats, per BOLT #3 (docs.ppad.tech/bolt3).
git clone git://git.ppad.tech/bolt3.git
Log | Files | Refs | README | LICENSE

Encode.hs (3100B)


      1 {-# OPTIONS_HADDOCK prune #-}
      2 {-# LANGUAGE BangPatterns #-}
      3 
      4 -- |
      5 -- Module: Lightning.Protocol.BOLT3.Encode
      6 -- Copyright: (c) 2025 Jared Tobin
      7 -- License: MIT
      8 -- Maintainer: Jared Tobin <jared@ppad.tech>
      9 --
     10 -- Serialization for BOLT #3 transactions and scripts.
     11 --
     12 -- Delegates to ppad-tx for transaction encoding.
     13 
     14 module Lightning.Protocol.BOLT3.Encode (
     15     -- * Transaction serialization
     16     encode_tx
     17   , encode_htlc_tx
     18   , encode_closing_tx
     19   , encode_tx_for_signing
     20 
     21     -- * Witness serialization
     22   , encode_witness
     23   , encode_funding_witness
     24   ) where
     25 
     26 import qualified Bitcoin.Prim.Tx as BT
     27 import qualified Data.ByteString as BS
     28 import qualified Data.ByteString.Builder as BSB
     29 import Data.Word (Word64)
     30 import Lightning.Protocol.BOLT3.Types
     31 import Lightning.Protocol.BOLT3.Tx
     32 
     33 -- transaction encoding --------------------------------------------------------
     34 
     35 -- | Encode a commitment transaction (SegWit format).
     36 --
     37 -- Returns 'Nothing' if the transaction has no outputs.
     38 encode_tx :: CommitmentTx -> Maybe BS.ByteString
     39 encode_tx = fmap BT.to_bytes . commitment_to_tx
     40 
     41 -- | Encode an HTLC transaction (SegWit format).
     42 encode_htlc_tx :: HTLCTx -> BS.ByteString
     43 encode_htlc_tx = BT.to_bytes . htlc_to_tx
     44 
     45 -- | Encode a closing transaction (SegWit format).
     46 --
     47 -- Returns 'Nothing' if the transaction has no outputs.
     48 encode_closing_tx :: ClosingTx -> Maybe BS.ByteString
     49 encode_closing_tx = fmap BT.to_bytes . closing_to_tx
     50 
     51 -- | Encode a commitment transaction for signing (stripped
     52 -- format, no witness).
     53 --
     54 -- Returns 'Nothing' if the transaction has no outputs.
     55 encode_tx_for_signing
     56   :: CommitmentTx -> Maybe BS.ByteString
     57 encode_tx_for_signing =
     58   fmap BT.to_bytes_legacy . commitment_to_tx
     59 
     60 -- witness encoding ------------------------------------------------------------
     61 
     62 -- | Encode a witness stack.
     63 --
     64 -- Format: varint item count, then for each item:
     65 -- varint length followed by item data.
     66 encode_witness :: Witness -> BS.ByteString
     67 encode_witness (Witness !items) =
     68   BT.to_strict $
     69        put_varint (fromIntegral (length items))
     70     <> foldMap put_item items
     71   where
     72     put_item :: BS.ByteString -> BSB.Builder
     73     put_item !bs =
     74          put_varint (fromIntegral (BS.length bs))
     75       <> BSB.byteString bs
     76 
     77 -- | Encode a varint to a 'BSB.Builder'.
     78 put_varint :: Word64 -> BSB.Builder
     79 put_varint !n
     80   | n < 0xFD  = BSB.word8 (fromIntegral n)
     81   | n <= 0xFFFF =
     82       BSB.word8 0xFD <> BSB.word16LE (fromIntegral n)
     83   | n <= 0xFFFFFFFF =
     84       BSB.word8 0xFE <> BSB.word32LE (fromIntegral n)
     85   | otherwise =
     86       BSB.word8 0xFF <> BSB.word64LE n
     87 {-# INLINE put_varint #-}
     88 
     89 -- | Encode a funding witness (2-of-2 multisig).
     90 --
     91 -- The witness stack is: @0 <sig1> <sig2> <witnessScript>@
     92 --
     93 -- Signatures must be ordered to match pubkey order in the
     94 -- funding script.
     95 encode_funding_witness
     96   :: BS.ByteString  -- ^ Signature for lesser pubkey
     97   -> BS.ByteString  -- ^ Signature for greater pubkey
     98   -> Script         -- ^ The funding witness script
     99   -> BS.ByteString
    100 encode_funding_witness !sig1 !sig2 (Script !ws) =
    101   encode_witness
    102     (Witness [BS.empty, sig1, sig2, ws])