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

Types.hs (10496B)


      1 {-# OPTIONS_HADDOCK prune #-}
      2 {-# LANGUAGE BangPatterns #-}
      3 {-# LANGUAGE DeriveGeneric #-}
      4 
      5 -- |
      6 -- Module: Lightning.Protocol.BOLT3.Types
      7 -- Copyright: (c) 2025 Jared Tobin
      8 -- License: MIT
      9 -- Maintainer: Jared Tobin <jared@ppad.tech>
     10 --
     11 -- Core types for BOLT #3 transaction and script formats.
     12 
     13 module Lightning.Protocol.BOLT3.Types (
     14     -- * Monetary amounts (re-exported from BOLT1)
     15     Satoshi(..)
     16   , MilliSatoshi(..)
     17   , msatToSat
     18   , satToMsat
     19 
     20     -- * Keys and points
     21   , Pubkey(..)
     22   , pubkey
     23   , Seckey(..)
     24   , seckey
     25   , Point(..)
     26   , point
     27   , unPoint
     28 
     29     -- * Hashes (re-exported from BOLT1)
     30   , PaymentHash(..)
     31   , paymentHash
     32   , unPaymentHash
     33   , PaymentPreimage(..)
     34   , paymentPreimage
     35   , unPaymentPreimage
     36 
     37     -- * Transaction primitives
     38   , TxId(..)
     39   , mkTxId
     40   , OutPoint(..)
     41   , Sequence(..)
     42   , Locktime(..)
     43 
     44     -- * Channel parameters
     45   , CommitmentNumber(..)
     46   , commitment_number
     47   , next_commitment_number
     48   , ToSelfDelay(..)
     49   , CltvExpiry(..)
     50   , DustLimit(..)
     51   , FeeratePerKw(..)
     52 
     53     -- * HTLC types
     54   , HTLC(..)
     55   , HTLCDirection(..)
     56 
     57     -- * Basepoints
     58   , Basepoints(..)
     59   , PerCommitmentPoint(..)
     60   , PerCommitmentSecret(..)
     61   , perCommitmentSecret
     62   , unPerCommitmentSecret
     63   , RevocationBasepoint(..)
     64   , PaymentBasepoint(..)
     65   , DelayedPaymentBasepoint(..)
     66   , HtlcBasepoint(..)
     67 
     68     -- * Derived keys
     69   , LocalPubkey(..)
     70   , RemotePubkey(..)
     71   , LocalDelayedPubkey(..)
     72   , RemoteDelayedPubkey(..)
     73   , LocalHtlcPubkey(..)
     74   , RemoteHtlcPubkey(..)
     75   , RevocationPubkey(..)
     76   , FundingPubkey(..)
     77 
     78     -- * Script
     79   , Script(..)
     80 
     81     -- * Witness (re-exported from ppad-tx)
     82   , Witness(..)
     83 
     84     -- * Channel options
     85   , ChannelFeatures(..)
     86   , has_anchors
     87 
     88     -- * Transaction weights (constants)
     89   , commitment_weight_no_anchors
     90   , commitment_weight_anchors
     91   , htlc_timeout_weight_no_anchors
     92   , htlc_timeout_weight_anchors
     93   , htlc_success_weight_no_anchors
     94   , htlc_success_weight_anchors
     95   , htlc_output_weight
     96 
     97     -- * Dust thresholds (constants)
     98   , dust_p2pkh
     99   , dust_p2sh
    100   , dust_p2wpkh
    101   , dust_p2wsh
    102   , anchor_output_value
    103   ) where
    104 
    105 import Bitcoin.Prim.Tx (TxId(..), mkTxId, OutPoint(..), Witness(..))
    106 import Data.Word (Word16, Word32, Word64)
    107 import qualified Data.ByteString as BS
    108 import GHC.Generics (Generic)
    109 import Lightning.Protocol.BOLT1.Prim
    110   ( Satoshi(..), MilliSatoshi(..)
    111   , satToMsat, msatToSat
    112   , Point(..), point, unPoint
    113   , PaymentHash(..), paymentHash, unPaymentHash
    114   , PaymentPreimage(..), paymentPreimage, unPaymentPreimage
    115   , PerCommitmentSecret(..), perCommitmentSecret
    116   , unPerCommitmentSecret
    117   )
    118 
    119 -- keys and points -------------------------------------------------------------
    120 
    121 -- | Compressed public key (33 bytes).
    122 newtype Pubkey = Pubkey { unPubkey :: BS.ByteString }
    123   deriving (Eq, Ord, Show, Generic)
    124 
    125 -- | Parse a 33-byte compressed public key.
    126 --
    127 -- Returns Nothing if the input is not exactly 33 bytes.
    128 --
    129 -- >>> pubkey (BS.replicate 33 0x02)
    130 -- Just (Pubkey ...)
    131 -- >>> pubkey (BS.replicate 32 0x02)
    132 -- Nothing
    133 pubkey :: BS.ByteString -> Maybe Pubkey
    134 pubkey bs
    135   | BS.length bs == 33 = Just (Pubkey bs)
    136   | otherwise = Nothing
    137 {-# INLINE pubkey #-}
    138 
    139 -- | Secret key (32 bytes).
    140 newtype Seckey = Seckey { unSeckey :: BS.ByteString }
    141   deriving (Eq, Generic)
    142 
    143 -- Don't show secret keys
    144 instance Show Seckey where
    145   show _ = "Seckey <redacted>"
    146 
    147 -- | Parse a 32-byte secret key.
    148 --
    149 -- Returns Nothing if the input is not exactly 32 bytes.
    150 seckey :: BS.ByteString -> Maybe Seckey
    151 seckey bs
    152   | BS.length bs == 32 = Just (Seckey bs)
    153   | otherwise = Nothing
    154 {-# INLINE seckey #-}
    155 
    156 -- transaction primitives ------------------------------------------------------
    157 
    158 -- | Transaction input sequence number.
    159 newtype Sequence = Sequence { unSequence :: Word32 }
    160   deriving (Eq, Ord, Show, Generic)
    161 
    162 -- | Transaction locktime.
    163 newtype Locktime = Locktime { unLocktime :: Word32 }
    164   deriving (Eq, Ord, Show, Generic)
    165 
    166 -- channel parameters ----------------------------------------------------------
    167 
    168 -- | 48-bit commitment number.
    169 newtype CommitmentNumber = CommitmentNumber
    170   { unCommitmentNumber :: Word64 }
    171   deriving (Eq, Ord, Show, Generic)
    172 
    173 -- | Parse a 48-bit commitment number.
    174 --
    175 -- Returns Nothing if the value exceeds 2^48 - 1.
    176 commitment_number :: Word64 -> Maybe CommitmentNumber
    177 commitment_number n
    178   | n <= 281474976710655 = Just (CommitmentNumber n)
    179   | otherwise = Nothing
    180 {-# INLINE commitment_number #-}
    181 
    182 -- | Increment a commitment number by one.
    183 --
    184 -- Returns Nothing if the result would exceed 2^48 - 1.
    185 --
    186 -- >>> fmap next_commitment_number (commitment_number 0)
    187 -- Just (Just (CommitmentNumber {unCommitmentNumber = 1}))
    188 -- >>> fmap next_commitment_number (commitment_number 281474976710655)
    189 -- Just Nothing
    190 next_commitment_number
    191   :: CommitmentNumber -> Maybe CommitmentNumber
    192 next_commitment_number (CommitmentNumber n)
    193   | n < 281474976710655 = Just (CommitmentNumber (n + 1))
    194   | otherwise = Nothing
    195 {-# INLINE next_commitment_number #-}
    196 
    197 -- | CSV delay for to_local outputs.
    198 newtype ToSelfDelay = ToSelfDelay { unToSelfDelay :: Word16 }
    199   deriving (Eq, Ord, Show, Generic)
    200 
    201 -- | CLTV expiry for HTLCs.
    202 newtype CltvExpiry = CltvExpiry { unCltvExpiry :: Word32 }
    203   deriving (Eq, Ord, Show, Generic)
    204 
    205 -- | Dust limit threshold.
    206 newtype DustLimit = DustLimit { unDustLimit :: Satoshi }
    207   deriving (Eq, Ord, Show, Generic)
    208 
    209 -- | Fee rate in satoshis per 1000 weight units.
    210 newtype FeeratePerKw = FeeratePerKw { unFeeratePerKw :: Word32 }
    211   deriving (Eq, Ord, Show, Generic)
    212 
    213 -- HTLC types ------------------------------------------------------------------
    214 
    215 -- | Direction of an HTLC from the commitment tx owner's perspective.
    216 data HTLCDirection
    217   = HTLCOffered   -- ^ We offered this HTLC (outgoing)
    218   | HTLCReceived  -- ^ We received this HTLC (incoming)
    219   deriving (Eq, Ord, Show, Generic)
    220 
    221 -- | HTLC output details.
    222 data HTLC = HTLC
    223   { htlc_direction    :: !HTLCDirection
    224   , htlc_amount_msat  :: {-# UNPACK #-} !MilliSatoshi
    225   , htlc_payment_hash :: {-# UNPACK #-} !PaymentHash
    226   , htlc_cltv_expiry  :: {-# UNPACK #-} !CltvExpiry
    227   } deriving (Eq, Show, Generic)
    228 
    229 -- basepoints ------------------------------------------------------------------
    230 
    231 -- | Per-commitment point (used to derive keys).
    232 newtype PerCommitmentPoint = PerCommitmentPoint
    233   { unPerCommitmentPoint :: Point }
    234   deriving (Eq, Ord, Show, Generic)
    235 
    236 -- | Revocation basepoint.
    237 newtype RevocationBasepoint = RevocationBasepoint
    238   { unRevocationBasepoint :: Point }
    239   deriving (Eq, Ord, Show, Generic)
    240 
    241 -- | Payment basepoint.
    242 newtype PaymentBasepoint = PaymentBasepoint
    243   { unPaymentBasepoint :: Point }
    244   deriving (Eq, Ord, Show, Generic)
    245 
    246 -- | Delayed payment basepoint.
    247 newtype DelayedPaymentBasepoint = DelayedPaymentBasepoint
    248   { unDelayedPaymentBasepoint :: Point }
    249   deriving (Eq, Ord, Show, Generic)
    250 
    251 -- | HTLC basepoint.
    252 newtype HtlcBasepoint = HtlcBasepoint
    253   { unHtlcBasepoint :: Point }
    254   deriving (Eq, Ord, Show, Generic)
    255 
    256 -- | Collection of all basepoints for one party.
    257 data Basepoints = Basepoints
    258   { bp_revocation      :: !RevocationBasepoint
    259   , bp_payment         :: !PaymentBasepoint
    260   , bp_delayed_payment :: !DelayedPaymentBasepoint
    261   , bp_htlc            :: !HtlcBasepoint
    262   } deriving (Eq, Show, Generic)
    263 
    264 -- derived keys ----------------------------------------------------------------
    265 
    266 -- | Local pubkey.
    267 newtype LocalPubkey = LocalPubkey { unLocalPubkey :: Pubkey }
    268   deriving (Eq, Ord, Show, Generic)
    269 
    270 -- | Remote pubkey.
    271 newtype RemotePubkey = RemotePubkey
    272   { unRemotePubkey :: Pubkey }
    273   deriving (Eq, Ord, Show, Generic)
    274 
    275 -- | Local delayed pubkey.
    276 newtype LocalDelayedPubkey = LocalDelayedPubkey
    277   { unLocalDelayedPubkey :: Pubkey }
    278   deriving (Eq, Ord, Show, Generic)
    279 
    280 -- | Remote delayed pubkey.
    281 newtype RemoteDelayedPubkey = RemoteDelayedPubkey
    282   { unRemoteDelayedPubkey :: Pubkey }
    283   deriving (Eq, Ord, Show, Generic)
    284 
    285 -- | Local HTLC pubkey.
    286 newtype LocalHtlcPubkey = LocalHtlcPubkey
    287   { unLocalHtlcPubkey :: Pubkey }
    288   deriving (Eq, Ord, Show, Generic)
    289 
    290 -- | Remote HTLC pubkey.
    291 newtype RemoteHtlcPubkey = RemoteHtlcPubkey
    292   { unRemoteHtlcPubkey :: Pubkey }
    293   deriving (Eq, Ord, Show, Generic)
    294 
    295 -- | Revocation pubkey.
    296 newtype RevocationPubkey = RevocationPubkey
    297   { unRevocationPubkey :: Pubkey }
    298   deriving (Eq, Ord, Show, Generic)
    299 
    300 -- | Funding pubkey (used in 2-of-2 multisig).
    301 newtype FundingPubkey = FundingPubkey
    302   { unFundingPubkey :: Pubkey }
    303   deriving (Eq, Ord, Show, Generic)
    304 
    305 -- script ----------------------------------------------------------------------
    306 
    307 -- | Bitcoin script (serialized).
    308 newtype Script = Script { unScript :: BS.ByteString }
    309   deriving (Eq, Ord, Show, Generic)
    310 
    311 -- channel options -------------------------------------------------------------
    312 
    313 -- | Channel feature flags relevant to BOLT #3.
    314 data ChannelFeatures = ChannelFeatures
    315   { cf_option_anchors :: !Bool
    316   } deriving (Eq, Show, Generic)
    317 
    318 -- | Check if option_anchors is enabled.
    319 has_anchors :: ChannelFeatures -> Bool
    320 has_anchors = cf_option_anchors
    321 {-# INLINE has_anchors #-}
    322 
    323 -- transaction weights (constants from spec) -----------------------------------
    324 
    325 -- | Base commitment tx weight without option_anchors.
    326 commitment_weight_no_anchors :: Word64
    327 commitment_weight_no_anchors = 724
    328 
    329 -- | Base commitment tx weight with option_anchors.
    330 commitment_weight_anchors :: Word64
    331 commitment_weight_anchors = 1124
    332 
    333 -- | HTLC-timeout tx weight without option_anchors.
    334 htlc_timeout_weight_no_anchors :: Word64
    335 htlc_timeout_weight_no_anchors = 663
    336 
    337 -- | HTLC-timeout tx weight with option_anchors.
    338 htlc_timeout_weight_anchors :: Word64
    339 htlc_timeout_weight_anchors = 666
    340 
    341 -- | HTLC-success tx weight without option_anchors.
    342 htlc_success_weight_no_anchors :: Word64
    343 htlc_success_weight_no_anchors = 703
    344 
    345 -- | HTLC-success tx weight with option_anchors.
    346 htlc_success_weight_anchors :: Word64
    347 htlc_success_weight_anchors = 706
    348 
    349 -- | Weight added per HTLC output in commitment tx.
    350 htlc_output_weight :: Word64
    351 htlc_output_weight = 172
    352 
    353 -- dust thresholds (constants from Bitcoin Core) -------------------------------
    354 
    355 -- | P2PKH dust threshold (546 satoshis).
    356 dust_p2pkh :: Satoshi
    357 dust_p2pkh = Satoshi 546
    358 
    359 -- | P2SH dust threshold (540 satoshis).
    360 dust_p2sh :: Satoshi
    361 dust_p2sh = Satoshi 540
    362 
    363 -- | P2WPKH dust threshold (294 satoshis).
    364 dust_p2wpkh :: Satoshi
    365 dust_p2wpkh = Satoshi 294
    366 
    367 -- | P2WSH dust threshold (330 satoshis).
    368 dust_p2wsh :: Satoshi
    369 dust_p2wsh = Satoshi 330
    370 
    371 -- | Fixed anchor output value (330 satoshis).
    372 anchor_output_value :: Satoshi
    373 anchor_output_value = Satoshi 330