packages feed

ppad-bolt2-0.1.0: lib/Lightning/Protocol/BOLT2.hs

{-# OPTIONS_HADDOCK prune #-}

-- |
-- Module: Lightning.Protocol.BOLT2
-- Copyright: (c) 2025 Jared Tobin
-- License: MIT
-- Maintainer: Jared Tobin <jared@ppad.tech>
--
-- The peer protocol of the Lightning Network, per
-- [BOLT #2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md):
-- the messages for channel establishment (v1 and v2), interactive
-- transaction construction, quiescence, channel close, normal operation
-- and message retransmission.
--
-- Fundamental types (channel ids, points, signatures, amounts, TLV
-- streams) come from ppad-bolt1, transaction ids from ppad-tx, and
-- feature vectors from ppad-bolt9.
--
-- Each message has a payload codec, @encode_\<msg\>@ and
-- @decode_\<msg\>@; 'encode_message' and 'decode_message' handle
-- complete messages, including the type. Decoders consume the whole
-- payload: bytes after the fixed fields are the message's TLV stream.
-- Known TLV records are decoded into typed fields, an unknown even
-- record fails the decode, and unknown odd records are kept in the
-- message's @_tlvs@ field, so re-encoding a decoded message reproduces
-- its bytes.
--
-- The examples below assume:
--
-- >>> :set -XOverloadedStrings
-- >>> import qualified Data.ByteString as BS
-- >>> import qualified Lightning.Protocol.BOLT1 as BOLT1
-- >>> import Lightning.Protocol.BOLT2
-- >>> let Just cid = BOLT1.channel_id (BS.replicate 32 0xab)
--
-- Encode a message, and decode it again:
--
-- >>> let fee = UpdateFee cid 2500 BOLT1.empty_tlv_stream
-- >>> let Right wire = encode_message (MsgUpdateFee fee)
-- >>> BS.length wire
-- 38
-- >>> decode_message wire == Right (MsgUpdateFee fee)
-- True
--
-- Unknown odd TLV records are preserved, and unknown even ones
-- rejected:
--
-- >>> let payload = encode_update_fee fee
-- >>> fmap update_fee_tlvs (decode_update_fee (payload <> "\x05\x01\x2a"))
-- Right (TlvStream [TlvRecord {tlv_type = 5, tlv_value = "*"}])
-- >>> decode_update_fee (payload <> "\x04\x01\x2a")
-- Left (DecodeTlvError (TlvUnknownEvenType 4))

module Lightning.Protocol.BOLT2 (
  -- * Messages
    Message(..)
  , message_type

  -- ** Channel establishment v1
  , OpenChannel(..)
  , AcceptChannel(..)
  , FundingCreated(..)
  , FundingSigned(..)
  , ChannelReady(..)

  -- ** Channel establishment v2
  , OpenChannel2(..)
  , AcceptChannel2(..)

  -- ** Interactive transaction construction
  , TxAddInput(..)
  , TxAddOutput(..)
  , TxRemoveInput(..)
  , TxRemoveOutput(..)
  , TxComplete(..)
  , TxSignatures(..)
  , TxInitRbf(..)
  , TxAckRbf(..)
  , TxAbort(..)

  -- ** Channel quiescence
  , Stfu(..)

  -- ** Channel close
  , Shutdown(..)
  , ClosingComplete(..)
  , ClosingSig(..)
  , ClosingSigned(..)

  -- ** Normal operation
  , UpdateAddHtlc(..)
  , UpdateFulfillHtlc(..)
  , UpdateFailHtlc(..)
  , UpdateFailMalformedHtlc(..)
  , CommitmentSigned(..)
  , RevokeAndAck(..)
  , UpdateFee(..)

  -- ** Message retransmission
  , ChannelReestablish(..)

  -- * Field types
  , HtlcId(..)
  , SerialId(..)
  , ScriptPubKey
  , script_pubkey
  , un_script_pubkey
  , Witness
  , witness
  , un_witness
  , OnionRoutingPacket
  , onion_routing_packet
  , un_onion_routing_packet
  , OnionHash
  , onion_hash
  , un_onion_hash
  , AttributionData
  , attribution_data
  , un_attribution_data
  , FeeRange(..)
  , NextFunding(..)

  -- * Encoding and decoding messages
  , encode_message
  , decode_message
  , EncodeError(..)
  , DecodeError(..)

  -- ** Payloads
  , encode_open_channel
  , decode_open_channel
  , encode_accept_channel
  , decode_accept_channel
  , encode_funding_created
  , decode_funding_created
  , encode_funding_signed
  , decode_funding_signed
  , encode_channel_ready
  , decode_channel_ready
  , encode_open_channel2
  , decode_open_channel2
  , encode_accept_channel2
  , decode_accept_channel2
  , encode_tx_add_input
  , decode_tx_add_input
  , encode_tx_add_output
  , decode_tx_add_output
  , encode_tx_remove_input
  , decode_tx_remove_input
  , encode_tx_remove_output
  , decode_tx_remove_output
  , encode_tx_complete
  , decode_tx_complete
  , encode_tx_signatures
  , decode_tx_signatures
  , encode_tx_init_rbf
  , decode_tx_init_rbf
  , encode_tx_ack_rbf
  , decode_tx_ack_rbf
  , encode_tx_abort
  , decode_tx_abort
  , encode_stfu
  , decode_stfu
  , encode_shutdown
  , decode_shutdown
  , encode_closing_complete
  , decode_closing_complete
  , encode_closing_sig
  , decode_closing_sig
  , encode_closing_signed
  , decode_closing_signed
  , encode_update_add_htlc
  , decode_update_add_htlc
  , encode_update_fulfill_htlc
  , decode_update_fulfill_htlc
  , encode_update_fail_htlc
  , decode_update_fail_htlc
  , encode_update_fail_malformed_htlc
  , decode_update_fail_malformed_htlc
  , encode_commitment_signed
  , decode_commitment_signed
  , encode_revoke_and_ack
  , decode_revoke_and_ack
  , encode_update_fee
  , decode_update_fee
  , encode_channel_reestablish
  , decode_channel_reestablish
  ) where

import Lightning.Protocol.BOLT2.Codec
import Lightning.Protocol.BOLT2.Messages
import Lightning.Protocol.BOLT2.Types