ppad-bolt3-0.0.1: Bitcoin transaction formats per BOLT #3
Copyright(c) 2025 Jared Tobin
LicenseMIT
MaintainerJared Tobin <jared@ppad.tech>
Safe HaskellNone
LanguageHaskell2010

Lightning.Protocol.BOLT3.Decode

Description

Parsing for BOLT #3 transactions and scripts.

Decodes SegWit Bitcoin transactions from raw bytes.

Synopsis

Error types

data DecodeError Source #

Errors that can occur during transaction decoding.

Constructors

InsufficientBytes !Int !Int

Expected bytes, actual bytes available

InvalidMarker !Word8

Invalid SegWit marker byte (expected 0x00)

InvalidFlag !Word8

Invalid SegWit flag byte (expected 0x01)

InvalidVarint

Malformed varint encoding

EmptyInput

No bytes to decode

Instances

Instances details
Generic DecodeError Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Associated Types

type Rep DecodeError 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep DecodeError = D1 ('MetaData "DecodeError" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) ((C1 ('MetaCons "InsufficientBytes" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int)) :+: C1 ('MetaCons "InvalidMarker" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Word8))) :+: (C1 ('MetaCons "InvalidFlag" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Word8)) :+: (C1 ('MetaCons "InvalidVarint" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "EmptyInput" 'PrefixI 'False) (U1 :: Type -> Type))))
Show DecodeError Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Eq DecodeError Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep DecodeError Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep DecodeError = D1 ('MetaData "DecodeError" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) ((C1 ('MetaCons "InsufficientBytes" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int)) :+: C1 ('MetaCons "InvalidMarker" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Word8))) :+: (C1 ('MetaCons "InvalidFlag" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Word8)) :+: (C1 ('MetaCons "InvalidVarint" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "EmptyInput" 'PrefixI 'False) (U1 :: Type -> Type))))

Raw transaction type

data RawTx Source #

A raw transaction as parsed from bytes.

Supports both legacy and SegWit transaction formats.

Constructors

RawTx 

Fields

Instances

Instances details
Generic RawTx Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Associated Types

type Rep RawTx 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawTx = D1 ('MetaData "RawTx" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawTx" 'PrefixI 'True) ((S1 ('MetaSel ('Just "rtx_version") 'SourceUnpack 'SourceStrict 'DecidedStrict) (Rec0 Word32) :*: S1 ('MetaSel ('Just "rtx_inputs") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [RawInput])) :*: (S1 ('MetaSel ('Just "rtx_outputs") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [RawOutput]) :*: (S1 ('MetaSel ('Just "rtx_witness") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [[ByteString]]) :*: S1 ('MetaSel ('Just "rtx_locktime") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Locktime)))))

Methods

from :: RawTx -> Rep RawTx x #

to :: Rep RawTx x -> RawTx #

Show RawTx Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Methods

showsPrec :: Int -> RawTx -> ShowS #

show :: RawTx -> String #

showList :: [RawTx] -> ShowS #

Eq RawTx Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Methods

(==) :: RawTx -> RawTx -> Bool #

(/=) :: RawTx -> RawTx -> Bool #

type Rep RawTx Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawTx = D1 ('MetaData "RawTx" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawTx" 'PrefixI 'True) ((S1 ('MetaSel ('Just "rtx_version") 'SourceUnpack 'SourceStrict 'DecidedStrict) (Rec0 Word32) :*: S1 ('MetaSel ('Just "rtx_inputs") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [RawInput])) :*: (S1 ('MetaSel ('Just "rtx_outputs") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [RawOutput]) :*: (S1 ('MetaSel ('Just "rtx_witness") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [[ByteString]]) :*: S1 ('MetaSel ('Just "rtx_locktime") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Locktime)))))

data RawInput Source #

A raw transaction input as parsed from bytes.

Instances

Instances details
Generic RawInput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Associated Types

type Rep RawInput 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawInput = D1 ('MetaData "RawInput" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawInput" 'PrefixI 'True) (S1 ('MetaSel ('Just "ri_outpoint") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Outpoint) :*: (S1 ('MetaSel ('Just "ri_script_sig") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString) :*: S1 ('MetaSel ('Just "ri_sequence") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Sequence))))

Methods

from :: RawInput -> Rep RawInput x #

to :: Rep RawInput x -> RawInput #

Show RawInput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Eq RawInput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawInput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawInput = D1 ('MetaData "RawInput" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawInput" 'PrefixI 'True) (S1 ('MetaSel ('Just "ri_outpoint") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Outpoint) :*: (S1 ('MetaSel ('Just "ri_script_sig") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString) :*: S1 ('MetaSel ('Just "ri_sequence") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Sequence))))

data RawOutput Source #

A raw transaction output as parsed from bytes.

Constructors

RawOutput 

Fields

Instances

Instances details
Generic RawOutput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Associated Types

type Rep RawOutput 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawOutput = D1 ('MetaData "RawOutput" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawOutput" 'PrefixI 'True) (S1 ('MetaSel ('Just "ro_value") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Satoshi) :*: S1 ('MetaSel ('Just "ro_script") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Script)))
Show RawOutput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

Eq RawOutput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawOutput Source # 
Instance details

Defined in Lightning.Protocol.BOLT3.Decode

type Rep RawOutput = D1 ('MetaData "RawOutput" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawOutput" 'PrefixI 'True) (S1 ('MetaSel ('Just "ro_value") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Satoshi) :*: S1 ('MetaSel ('Just "ro_script") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Script)))

Transaction parsing

decode_tx :: ByteString -> Either DecodeError RawTx Source #

Decode a raw Bitcoin transaction from bytes.

Handles both legacy and SegWit transaction formats.

SegWit format: * version (4 bytes LE) * marker (0x00) + flag (0x01) * input count (varint) * inputs: outpoint (32+4), scriptSig length (varint), scriptSig, sequence * output count (varint) * outputs: value (8 LE), scriptPubKey length (varint), scriptPubKey * witness data (for each input) * locktime (4 bytes LE)

>>> decode_tx rawTxBytes
Right (RawTx {...})

Witness parsing

decode_witness :: ByteString -> Either DecodeError (Witness, ByteString) Source #

Decode a witness stack for one input.

Format: varint num_items + (varint length + data) for each item

Primitive decoding

decode_varint :: ByteString -> Either DecodeError (Word64, ByteString) Source #

Decode a Bitcoin varint (CompactSize).

Encoding: * 0x00-0xFC: 1 byte * 0xFD: 2 bytes little-endian follow * 0xFE: 4 bytes little-endian follow * 0xFF: 8 bytes little-endian follow

>>> decode_varint (BS.pack [0x01])
Right (1, "")
>>> decode_varint (BS.pack [0xfd, 0x00, 0x01])
Right (256, "")

decode_le32 :: ByteString -> Either DecodeError (Word32, ByteString) Source #

Decode a little-endian 32-bit integer.

>>> decode_le32 (BS.pack [0x01, 0x00, 0x00, 0x00])
Right (1, "")

decode_le64 :: ByteString -> Either DecodeError (Word64, ByteString) Source #

Decode a little-endian 64-bit integer.

>>> decode_le64 (BS.pack [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
Right (1, "")

decode_outpoint :: ByteString -> Either DecodeError (Outpoint, ByteString) Source #

Decode a transaction outpoint (txid + output index).

Format: 32 bytes txid (little-endian) + 4 bytes index (little-endian)

>>> let txid = BS.replicate 32 0
>>> let idx = BS.pack [0x01, 0x00, 0x00, 0x00]
>>> decode_outpoint (txid <> idx)
Right (Outpoint {outpoint_txid = ..., outpoint_index = 1}, "")

decode_output :: ByteString -> Either DecodeError (RawOutput, ByteString) Source #

Decode a transaction output (value + scriptPubKey).

Format: 8 bytes value (little-endian) + varint script length + script