bolt4

Onion routing protocol, per BOLT #4 (docs.ppad.tech/bolt4).
git clone git://git.ppad.tech/bolt4.git
Log | Files | Refs | README | LICENSE

BOLT4.hs (3951B)


      1 {-# OPTIONS_HADDOCK prune #-}
      2 
      3 -- |
      4 -- Module: Lightning.Protocol.BOLT4
      5 -- Copyright: (c) 2025 Jared Tobin
      6 -- License: MIT
      7 -- Maintainer: Jared Tobin <jared@ppad.tech>
      8 --
      9 -- Onion routing for the Lightning Network, per BOLT #4
     10 -- (<https://github.com/lightning/bolts/blob/master/04-onion-routing.md>):
     11 -- onion construction and processing, returning errors, and route
     12 -- blinding.
     13 --
     14 -- The examples below assume:
     15 --
     16 -- >>> :set -XOverloadedStrings
     17 -- >>> import qualified Data.ByteString as BS
     18 -- >>> import qualified Lightning.Protocol.BOLT1 as BOLT1
     19 -- >>> import Lightning.Protocol.BOLT4
     20 --
     21 -- Construct a two-hop onion:
     22 --
     23 -- >>> let Just session = secret_key (BS.replicate 32 0x41)
     24 -- >>> let Just alice = secret_key (BS.replicate 32 0x42)
     25 -- >>> let Just bob = secret_key (BS.replicate 32 0x43)
     26 -- >>> let Just scid = BOLT1.short_channel_id 800000 1 0
     27 -- >>> let Just amt = BOLT1.milli_satoshi 100000
     28 -- >>> :{
     29 -- let alice_payload = empty_hop_payload {
     30 --         hp_amt_to_forward      = Just amt
     31 --       , hp_outgoing_cltv_value = Just 800040
     32 --       , hp_short_channel_id    = Just scid
     33 --       }
     34 --     bob_payload = empty_hop_payload {
     35 --         hp_amt_to_forward      = Just amt
     36 --       , hp_outgoing_cltv_value = Just 800000
     37 --       }
     38 --     route = [ Hop (public_key alice) alice_payload
     39 --             , Hop (public_key bob) bob_payload ]
     40 --     payment_hash = BS.replicate 32 0xff
     41 -- :}
     42 -- >>> let Right (onion, secrets) = construct session route payment_hash
     43 --
     44 -- Process it at each hop:
     45 --
     46 -- >>> let Right (Forward fwd) = process alice onion payment_hash Nothing
     47 -- >>> hp_short_channel_id (fwd_payload fwd) == Just scid
     48 -- True
     49 -- >>> let next = fwd_next_packet fwd
     50 -- >>> let Right (Receive rcv) = process bob next payment_hash Nothing
     51 -- >>> hp_outgoing_cltv_value (rcv_payload rcv)
     52 -- Just 800000
     53 --
     54 -- Fail at the final hop, wrap the error at the first, and attribute it
     55 -- at the origin:
     56 --
     57 -- >>> let tlvs = BOLT1.empty_tlv_stream
     58 -- >>> let failure = FailureMessage TemporaryNodeFailure tlvs
     59 -- >>> let Right err = construct_error (rcv_shared_secret rcv) failure
     60 -- >>> let returned = wrap_error (fwd_shared_secret fwd) err
     61 -- >>> unwrap_error secrets returned == Attributed 1 failure
     62 -- True
     63 
     64 module Lightning.Protocol.BOLT4 (
     65   -- * Keys
     66     SecretKey
     67   , secret_key
     68   , public_key
     69   , SharedSecret
     70   , shared_secret
     71   , un_shared_secret
     72 
     73   -- * Onion packets
     74   , OnionPacket(..)
     75   , HopPayloads
     76   , hop_payloads
     77   , un_hop_payloads
     78   , Hmac32
     79   , hmac32
     80   , un_hmac32
     81   , encode_onion_packet
     82   , decode_onion_packet
     83 
     84   -- * Hop payloads
     85   , HopPayload(..)
     86   , empty_hop_payload
     87   , PaymentData(..)
     88   , PaymentSecret
     89   , payment_secret
     90   , un_payment_secret
     91   , encode_hop_payload
     92   , decode_hop_payload
     93 
     94   -- * Constructing onions
     95   , Hop(..)
     96   , construct
     97   , ConstructError(..)
     98 
     99   -- * Processing onions
    100   , process
    101   , ProcessResult(..)
    102   , ForwardInfo(..)
    103   , ReceiveInfo(..)
    104   , BlindedInfo(..)
    105   , ProcessError(..)
    106 
    107   -- * Route blinding
    108   , BlindedPath(..)
    109   , BlindedHop(..)
    110   , create_blinded_path
    111   , BlindingError(..)
    112   , decrypt_recipient_data
    113   , BlindedHopData(..)
    114   , empty_blinded_hop_data
    115   , PaymentRelay(..)
    116   , PaymentConstraints(..)
    117   , encode_blinded_hop_data
    118   , decode_blinded_hop_data
    119 
    120   -- * Failure messages
    121   , FailureMessage(..)
    122   , Failure(..)
    123   , OnionHash
    124   , onion_hash
    125   , un_onion_hash
    126   , failure_code
    127   , is_badonion
    128   , is_perm
    129   , is_node
    130   , is_update
    131   , encode_failure_message
    132   , decode_failure_message
    133 
    134   -- * Returning errors
    135   , ErrorPacket(..)
    136   , construct_error
    137   , wrap_error
    138   , unwrap_error
    139   , Attribution(..)
    140 
    141   -- * Encoding errors
    142   , DecodeError(..)
    143   , EncodeError(..)
    144   ) where
    145 
    146 import Lightning.Protocol.BOLT4.Blinding
    147 import Lightning.Protocol.BOLT4.Codec
    148 import Lightning.Protocol.BOLT4.Construct
    149 import Lightning.Protocol.BOLT4.Error
    150 import Lightning.Protocol.BOLT4.Prim
    151 import Lightning.Protocol.BOLT4.Process
    152 import Lightning.Protocol.BOLT4.Types