zpay32/invoice: parse payment address as type s

This commit is contained in:
Conner Fromknecht
2019-12-05 07:59:17 -08:00
parent 2bf94fa409
commit df72097f2d
2 changed files with 65 additions and 3 deletions

View File

@@ -73,6 +73,11 @@ const (
// supported or required by the receiver.
fieldType9 = 5
// fieldTypeS contains a 32-byte payment address, which is a nonce
// included in the final hop's payload to prevent intermediaries from
// probing the recipient.
fieldTypeS = 16
// maxInvoiceLength is the maximum total length an invoice can have.
// This is chosen to be the maximum number of bytes that can fit into a
// single QR code: https://en.wikipedia.org/wiki/QR_code#Storage
@@ -126,6 +131,10 @@ type Invoice struct {
// invoice.
PaymentHash *[32]byte
// PaymentAddr is the payment address to be used by payments to prevent
// probing of the destination.
PaymentAddr *[32]byte
// Destination is the public key of the target node. This will always
// be set after decoding, and can optionally be set before encoding to
// include the pubkey as an 'n' field. If this is not set before
@@ -258,6 +267,14 @@ func Features(features *lnwire.FeatureVector) func(*Invoice) {
}
}
// PaymentAddr is a functional option that allows callers of NewInvoice to set
// the desired payment address tht is advertised on the invoice.
func PaymentAddr(addr [32]byte) func(*Invoice) {
return func(i *Invoice) {
i.PaymentAddr = &addr
}
}
// NewInvoice creates a new Invoice object. The last parameter is a set of
// variadic arguments for setting optional fields of the invoice.
//
@@ -643,6 +660,14 @@ func parseTaggedFields(invoice *Invoice, fields []byte, net *chaincfg.Params) er
}
invoice.PaymentHash, err = parse32Bytes(base32Data)
case fieldTypeS:
if invoice.PaymentAddr != nil {
// We skip the field if we have already seen a
// supported one.
continue
}
invoice.PaymentAddr, err = parse32Bytes(base32Data)
case fieldTypeD:
if invoice.Description != nil {
// We skip the field if we have already seen a
@@ -1060,6 +1085,14 @@ func writeTaggedFields(bufferBase32 *bytes.Buffer, invoice *Invoice) error {
return err
}
}
if invoice.PaymentAddr != nil {
err := writeBytes32(
bufferBase32, fieldTypeS, *invoice.PaymentAddr,
)
if err != nil {
return err
}
}
return nil
}