Commit graph

128 commits

Author SHA1 Message Date
Jeffrey Czyz
6b3535451e
Define TlvStream::skip_signatures
Provide a helper for skipping signature TLV records from a TLV stream.
This prevents needing to duplicate the check for signature TLV records
when writing a TLV stream without signatures in an upcoming commit.
2023-01-18 15:31:48 -06:00
Jeffrey Czyz
bd0040a02b
Drop AsRef<[u8]> implementation for TlvRecord
Explicitly using TlvRecord::record_bytes makes reading the code more
obvious than hiding which bytes are used in AsRef<[u8]>::as_ref.
2023-01-18 15:31:48 -06:00
Jeffrey Czyz
ea1a68c6e6
Use explicit WithoutLength for BOLT 12 features
Most BOLT 12 features are used as the value of a TLV record and thus
don't use an explicit length. One exception is the features inside the
blinded payinfo subtype since the TLV record contains a list of them.
However, these features are also used in the BOLT 4 encrypted_data_tlv
TLV stream as a single record, where the length is implicit.

Implement Readable and Writeable for Features wrapped in WithoutLength
such that either serialization can be used where required.
2023-01-05 22:39:24 -06:00
Jeffrey Czyz
1a437f4150
Remove Option from InvoiceRequest::signature
Refunds don't have signatures and now use their own abstraction.
Therefore, signatures can be required in invoice requests as per the
spec.
2023-01-05 22:39:24 -06:00
Jeffrey Czyz
7964b9f745
Correct documentation about Refund::payer_id
The docs incorrectly stated that Refund::payer_id is for signing, where
it is only used for identifying a node if Refund::paths is not present.
2023-01-05 22:38:31 -06:00
Jeffrey Czyz
8e36737dac
Refund parsing tests
Tests for checking refund semantics when parsing invoice_request bytes
as defined by BOLT 12.
2022-12-14 16:22:44 -06:00
Jeffrey Czyz
77c082229b
Refund building tests
Tests for checking invoice_request message semantics when building a
refund as defined by BOLT 12.
2022-12-14 16:22:24 -06:00
Jeffrey Czyz
73e743fb53
Builder for creating refunds
Add a builder for creating refunds given a payer_id and other required
fields. Other settings are optional and duplicative settings will
override previous settings. Building produces a semantically valid
`invoice_request` message representing the refund, which then may be
communicated out of band (e.g., via QR code).
2022-12-14 16:20:53 -06:00
Jeffrey Czyz
d47763af57
Refund parsing from bech32 strings
Implement Bech32Encode for Refund, which supports creating and parsing
QR codes for the merchant-pays-user (i.e., offer for money) flow.
2022-12-14 16:20:53 -06:00
Jeffrey Czyz
92a53dd7aa
Refund encoding and parsing
Define an interface for BOLT 12 refunds (i.e., an `invoice_request`
message without an `offer_node_id`). A refund is more generally an
"offer for money". While it is encoded using the same TLV streams as an
`invoice_request` message, it has different semantics.
2022-12-14 16:20:40 -06:00
Jeffrey Czyz
7e81f8dcb4
Remove Option from OfferContents::signing_pubkey
Refunds (i.e., `invoice_request` without an `offer`) will have its own
contents type, so OfferContents::signing_pubkey can be required.
2022-12-13 16:05:59 -06:00
Jeffrey Czyz
04d64f0808
Check entire TLV stream instead of by field
This causes a compilation error if a new field is added but missed in
the tests.
2022-12-09 14:45:56 -06:00
Jeffrey Czyz
b25c8df648
Add BOLT 12 merkle root test for invoice_request
A BOLT 12 test vector uses an `invoice_request` message that has a
currency, which aren't supported, so using OfferBuilder::build_unchecked
is required to avoid a panic.
2022-12-09 13:28:53 -06:00
Jeffrey Czyz
984c906406
Invoice request parsing tests
Tests for checking invoice_request message semantics when parsing bytes
as defined by BOLT 12.
2022-12-09 13:28:52 -06:00
Jeffrey Czyz
d666eb6700
Invoice request building tests
Tests for checking invoice_request message semantics when building as
defined by BOLT 12.
2022-12-09 13:28:26 -06:00
Jeffrey Czyz
13ba7cc523
Builder for creating invoice requests
Add a builder for creating invoice requests for an offer given a
payer_id. Other settings may be optional depending on the offer and
duplicative settings will override previous settings. Building produces
a semantically valid `invoice_request` message for the offer, which then
can be signed for the payer_id.
2022-12-09 08:53:46 -06:00
Jeffrey Czyz
59a7bd29fe
Invoice request raw byte encoding and decoding
When reading an offer, an `invoice_request` message is sent over the
wire. Implement Writeable for encoding the message and TryFrom for
decoding it by defining in terms of TLV streams. These streams represent
content for the payer metadata (0), reflected `offer` (1-79),
`invoice_request` (80-159), and signature (240).
2022-12-09 08:53:46 -06:00
Jeffrey Czyz
a7adc7602a
Merkle root hash computation
Offers uses a merkle root hash construction for signature calculation
and verification. Add a submodule implementing this so that it can be
used when parsing and signing invoice_request and invoice messages.
2022-12-09 08:53:45 -06:00
Jeffrey Czyz
0c621646a6
Invoice request message interface and data format
Define an interface for BOLT 12 `invoice_request` messages. The
underlying format consists of the original bytes and the parsed
contents.

The bytes are later needed when constructing an `invoice` message. This
is because it must mirror all the `offer` and `invoice_request` TLV
records, including unknown ones, which aren't represented in the
contents.

The contents will be used in `invoice` messages to avoid duplication.
Some fields while required in a typical user-pays-merchant flow may not
be necessary in the merchant-pays-user flow (e.g., refund, ATM).
2022-12-09 08:53:33 -06:00
Jeffrey Czyz
3e17e7f9bb
Remove unused mut from OfferBuilder::amount_msats
Seen when removing `#[allow(unused)]` from `offers` module.
2022-12-02 15:28:02 -08:00
Jeffrey Czyz
4b8b17d72f
Reduce visibility for offer auxiliary types 2022-12-02 15:26:27 -08:00
Jeffrey Czyz
1e26a2bc19
Expose the default Quantity::one as pub 2022-11-18 11:33:07 -06:00
Jeffrey Czyz
94a07d9cae
Limit TLV stream decoding to type ranges
BOLT 12 messages are limited to a range of TLV record types. Refactor
decode_tlv_stream into a decode_tlv_stream_range macro for limiting
which types are parsed. Requires a SeekReadable trait for rewinding when
a type outside of the range is seen. This allows for composing TLV
streams of different ranges.

Updates offer parsing accordingly and adds a test demonstrating failure
if a type outside of the range is included.
2022-11-18 11:33:07 -06:00
Jeffrey Czyz
03d0a4b497
Offer parsing tests
Test semantic errors when parsing offer bytes.
2022-11-18 11:33:07 -06:00
Jeffrey Czyz
3a6d7b867e
Use SemanticError in OfferBuilder::build 2022-11-18 11:33:06 -06:00
Jeffrey Czyz
60d7ffce10
Offer parsing from bech32 strings
Add common bech32 parsing for BOLT 12 messages. The encoding is similar
to bech32 only without a checksum and with support for continuing
messages across multiple parts.

Messages implementing Bech32Encode are parsed into a TLV stream, which
is converted to the desired message content while performing semantic
checks. Checking after conversion allows for more elaborate checks of
data composed of multiple TLV records and for more meaningful error
messages.

The parsed bytes are also saved to allow creating messages with mirrored
data, even if TLV records are unknown.
2022-11-18 11:33:06 -06:00
Jeffrey Czyz
8ba09e068b
Builder for creating offers
Add a builder for creating offers given a required description and
node_id. Other settings are optional and duplicative settings will
override previous settings for non-Vec fields.
2022-11-08 13:18:15 -06:00
Jeffrey Czyz
24b63de10c
Offer message interface and data format
Define an interface for BOLT 12 `offer` messages. The underlying format
consists of the original bytes and the parsed contents.

The bytes are later needed when constructing an `invoice_request`
message. This is because it must mirror all the `offer` TLV records,
including unknown ones, which aren't represented in the contents.

The contents will be used in `invoice_request` messages to avoid
duplication. Some fields while required in a typical user-pays-merchant
flow may not be necessary in the merchant-pays-user flow (i.e., refund).
2022-11-04 15:07:01 -05:00