@@ -16,6 +16,7 @@ import (
1616 "github.com/lightningnetwork/lnd/lnrpc"
1717 "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
1818 "github.com/lightningnetwork/lnd/lntypes"
19+ "github.com/lightningnetwork/lnd/lnwire"
1920 "github.com/lightningnetwork/lnd/zpay32"
2021 "google.golang.org/grpc"
2122 "google.golang.org/grpc/codes"
@@ -365,6 +366,103 @@ func (s *lightningClient) AddInvoice(ctx context.Context,
365366 return hash , resp .PaymentRequest , nil
366367}
367368
369+ // Invoice represents an invoice in lnd.
370+ type Invoice struct {
371+ // Preimage is the invoice's preimage, which is set if the invoice
372+ // is settled.
373+ Preimage * lntypes.Preimage
374+
375+ // Hash is the invoice hash.
376+ Hash lntypes.Hash
377+
378+ // Memo is an optional memo field for hte invoice.
379+ Memo string
380+
381+ // PaymentRequest is the invoice's payment request.
382+ PaymentRequest string
383+
384+ // Amount is the amount of the invoice in millisatoshis.
385+ Amount lnwire.MilliSatoshi
386+
387+ // AmountPaid is the amount that was paid for the invoice. This field
388+ // will only be set if the invoice is settled.
389+ AmountPaid lnwire.MilliSatoshi
390+
391+ // CreationDate is the time the invoice was created.
392+ CreationDate time.Time
393+
394+ // SettleDate is the time the invoice was settled.
395+ SettleDate time.Time
396+
397+ // State is the invoice's current state.
398+ State channeldb.ContractState
399+
400+ // IsKeysend indicates whether the invoice was a spontaneous payment.
401+ IsKeysend bool
402+ }
403+
404+ // LookupInvoice looks up an invoice in lnd, it will error if the invoice is
405+ // not known to lnd.
406+ func (s * lightningClient ) LookupInvoice (ctx context.Context ,
407+ hash lntypes.Hash ) (* Invoice , error ) {
408+
409+ rpcCtx , cancel := context .WithTimeout (ctx , rpcTimeout )
410+ defer cancel ()
411+
412+ rpcIn := & lnrpc.PaymentHash {
413+ RHash : hash [:],
414+ }
415+
416+ rpcCtx = s .adminMac .WithMacaroonAuth (rpcCtx )
417+ resp , err := s .client .LookupInvoice (rpcCtx , rpcIn )
418+ if err != nil {
419+ return nil , err
420+ }
421+
422+ invoice := & Invoice {
423+ Preimage : nil ,
424+ Hash : hash ,
425+ Memo : resp .Memo ,
426+ PaymentRequest : resp .PaymentRequest ,
427+ Amount : lnwire .MilliSatoshi (resp .ValueMsat ),
428+ AmountPaid : lnwire .MilliSatoshi (resp .AmtPaidMsat ),
429+ CreationDate : time .Unix (resp .CreationDate , 0 ),
430+ IsKeysend : resp .IsKeysend ,
431+ }
432+
433+ switch resp .State {
434+ case lnrpc .Invoice_OPEN :
435+ invoice .State = channeldb .ContractOpen
436+
437+ case lnrpc .Invoice_ACCEPTED :
438+ invoice .State = channeldb .ContractAccepted
439+
440+ // If the invoice is settled, it also has a non-nil preimage, which we
441+ // can set on our invoice.
442+ case lnrpc .Invoice_SETTLED :
443+ invoice .State = channeldb .ContractSettled
444+ preimage , err := lntypes .MakePreimage (resp .RPreimage )
445+ if err != nil {
446+ return nil , err
447+ }
448+ invoice .Preimage = & preimage
449+
450+ case lnrpc .Invoice_CANCELED :
451+ invoice .State = channeldb .ContractCanceled
452+
453+ default :
454+ return nil , fmt .Errorf ("unknown invoice state: %v" , resp .State )
455+ }
456+
457+ // Only set settle date if it is non-zero, because 0 unix time is
458+ // not the same as a zero time struct.
459+ if resp .SettleDate != 0 {
460+ invoice .SettleDate = time .Unix (resp .SettleDate , 0 )
461+ }
462+
463+ return invoice , nil
464+ }
465+
368466// ListTransactions returns all known transactions of the backing lnd node.
369467func (s * lightningClient ) ListTransactions (ctx context.Context ) ([]* wire.MsgTx , error ) {
370468 rpcCtx , cancel := context .WithTimeout (ctx , rpcTimeout )
0 commit comments