ppad-bolt4-0.1.0: lib/Lightning/Protocol/BOLT4.hs
{-# OPTIONS_HADDOCK prune #-}
-- |
-- Module: Lightning.Protocol.BOLT4
-- Copyright: (c) 2025 Jared Tobin
-- License: MIT
-- Maintainer: Jared Tobin <jared@ppad.tech>
--
-- Onion routing for the Lightning Network, per BOLT #4
-- (<https://github.com/lightning/bolts/blob/master/04-onion-routing.md>):
-- onion construction and processing, returning errors, and route
-- blinding.
--
-- The examples below assume:
--
-- >>> :set -XOverloadedStrings
-- >>> import qualified Data.ByteString as BS
-- >>> import qualified Lightning.Protocol.BOLT1 as BOLT1
-- >>> import Lightning.Protocol.BOLT4
--
-- Construct a two-hop onion:
--
-- >>> let Just session = secret_key (BS.replicate 32 0x41)
-- >>> let Just alice = secret_key (BS.replicate 32 0x42)
-- >>> let Just bob = secret_key (BS.replicate 32 0x43)
-- >>> let Just scid = BOLT1.short_channel_id 800000 1 0
-- >>> let Just amt = BOLT1.milli_satoshi 100000
-- >>> :{
-- let alice_payload = empty_hop_payload {
-- hp_amt_to_forward = Just amt
-- , hp_outgoing_cltv_value = Just 800040
-- , hp_short_channel_id = Just scid
-- }
-- bob_payload = empty_hop_payload {
-- hp_amt_to_forward = Just amt
-- , hp_outgoing_cltv_value = Just 800000
-- }
-- route = [ Hop (public_key alice) alice_payload
-- , Hop (public_key bob) bob_payload ]
-- payment_hash = BS.replicate 32 0xff
-- :}
-- >>> let Right (onion, secrets) = construct session route payment_hash
--
-- Process it at each hop:
--
-- >>> let Right (Forward fwd) = process alice onion payment_hash Nothing
-- >>> hp_short_channel_id (fwd_payload fwd) == Just scid
-- True
-- >>> let next = fwd_next_packet fwd
-- >>> let Right (Receive rcv) = process bob next payment_hash Nothing
-- >>> hp_outgoing_cltv_value (rcv_payload rcv)
-- Just 800000
--
-- Fail at the final hop, wrap the error at the first, and attribute it
-- at the origin:
--
-- >>> let tlvs = BOLT1.empty_tlv_stream
-- >>> let failure = FailureMessage TemporaryNodeFailure tlvs
-- >>> let Right err = construct_error (rcv_shared_secret rcv) failure
-- >>> let returned = wrap_error (fwd_shared_secret fwd) err
-- >>> unwrap_error secrets returned == Attributed 1 failure
-- True
module Lightning.Protocol.BOLT4 (
-- * Keys
SecretKey
, secret_key
, public_key
, SharedSecret
, shared_secret
, un_shared_secret
-- * Onion packets
, OnionPacket(..)
, HopPayloads
, hop_payloads
, un_hop_payloads
, Hmac32
, hmac32
, un_hmac32
, encode_onion_packet
, decode_onion_packet
-- * Hop payloads
, HopPayload(..)
, empty_hop_payload
, PaymentData(..)
, PaymentSecret
, payment_secret
, un_payment_secret
, encode_hop_payload
, decode_hop_payload
-- * Constructing onions
, Hop(..)
, construct
, ConstructError(..)
-- * Processing onions
, process
, ProcessResult(..)
, ForwardInfo(..)
, ReceiveInfo(..)
, BlindedInfo(..)
, ProcessError(..)
-- * Route blinding
, BlindedPath(..)
, BlindedHop(..)
, create_blinded_path
, BlindingError(..)
, decrypt_recipient_data
, BlindedHopData(..)
, empty_blinded_hop_data
, PaymentRelay(..)
, PaymentConstraints(..)
, encode_blinded_hop_data
, decode_blinded_hop_data
-- * Failure messages
, FailureMessage(..)
, Failure(..)
, OnionHash
, onion_hash
, un_onion_hash
, failure_code
, is_badonion
, is_perm
, is_node
, is_update
, encode_failure_message
, decode_failure_message
-- * Returning errors
, ErrorPacket(..)
, construct_error
, wrap_error
, unwrap_error
, Attribution(..)
-- * Encoding errors
, DecodeError(..)
, EncodeError(..)
) where
import Lightning.Protocol.BOLT4.Blinding
import Lightning.Protocol.BOLT4.Codec
import Lightning.Protocol.BOLT4.Construct
import Lightning.Protocol.BOLT4.Error
import Lightning.Protocol.BOLT4.Prim
import Lightning.Protocol.BOLT4.Process
import Lightning.Protocol.BOLT4.Types