From 541041f4a8049638a2dcc3d1aa2a246e4c98cd1d Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 6 May 2021 09:15:15 -0700 Subject: [PATCH] invoicesrpc: add ability to generate AMP invoices --- lnrpc/invoicesrpc/addinvoice.go | 54 ++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/lnrpc/invoicesrpc/addinvoice.go b/lnrpc/invoicesrpc/addinvoice.go index fe13e566..8eff43a1 100644 --- a/lnrpc/invoicesrpc/addinvoice.go +++ b/lnrpc/invoicesrpc/addinvoice.go @@ -103,6 +103,11 @@ type AddInvoiceData struct { // immediately upon receiving the payment. HodlInvoice bool + // Amp signals whether or not to create an AMP invoice. + // + // NOTE: Preimage should always be set to nil when this value is true. + Amp bool + // RouteHints are optional route hints that can each be individually used // to assist in reaching the invoice's destination. RouteHints [][]zpay32.HopHint @@ -111,6 +116,12 @@ type AddInvoiceData struct { // paymentHashAndPreimage returns the payment hash and preimage for this invoice // depending on the configuration. // +// For AMP invoices (when Amp flag is true), this method always returns a nil +// preimage. The hash value can be set externally by the user using the Hash +// field, or one will be generated randomly. The payment hash here only serves +// as a unique identifier for insertion into the invoice index, as there is +// no universal preimage for an AMP payment. +// // For MPP invoices (when Amp flag is false), this method may return nil // preimage when create a hodl invoice, but otherwise will always return a // non-nil preimage and the corresponding payment hash. The valid combinations @@ -121,6 +132,42 @@ type AddInvoiceData struct { func (d *AddInvoiceData) paymentHashAndPreimage() ( *lntypes.Preimage, lntypes.Hash, error) { + if d.Amp { + return d.ampPaymentHashAndPreimage() + } + + return d.mppPaymentHashAndPreimage() +} + +// ampPaymentHashAndPreimage returns the payment hash to use for an AMP invoice. +// The preimage will always be nil. +func (d *AddInvoiceData) ampPaymentHashAndPreimage() (*lntypes.Preimage, lntypes.Hash, error) { + switch { + + // Preimages cannot be set on AMP invoice. + case d.Preimage != nil: + return nil, lntypes.Hash{}, + errors.New("preimage set on AMP invoice") + + // If a specific hash was requested, use that. + case d.Hash != nil: + return nil, *d.Hash, nil + + // Otherwise generate a random hash value, just needs to be unique to be + // added to the invoice index. + default: + var paymentHash lntypes.Hash + if _, err := rand.Read(paymentHash[:]); err != nil { + return nil, lntypes.Hash{}, err + } + + return nil, paymentHash, nil + } +} + +// mppPaymentHashAndPreimage returns the payment hash and preimage to use for an +// MPP invoice. +func (d *AddInvoiceData) mppPaymentHashAndPreimage() (*lntypes.Preimage, lntypes.Hash, error) { var ( paymentPreimage *lntypes.Preimage paymentHash lntypes.Hash @@ -332,7 +379,12 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig, } // Set our desired invoice features and add them to our list of options. - invoiceFeatures := cfg.GenInvoiceFeatures() + var invoiceFeatures *lnwire.FeatureVector + if invoice.Amp { + invoiceFeatures = cfg.GenAmpInvoiceFeatures() + } else { + invoiceFeatures = cfg.GenInvoiceFeatures() + } options = append(options, zpay32.Features(invoiceFeatures)) // Generate and set a random payment address for this invoice. If the