From bded58c8c30288ad4f9ccf88221fe66b2a426b78 Mon Sep 17 00:00:00 2001 From: elnosh Date: Wed, 26 Jun 2024 17:05:48 -0500 Subject: [PATCH] return invoice status in lightning client --- cashu/cashu.go | 2 +- mint/lightning/lightning.go | 3 ++- mint/lightning/lnd.go | 15 +++++++++++---- mint/mint.go | 30 ++++++++++++++++++++---------- mint/server.go | 14 +++++++++++++- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/cashu/cashu.go b/cashu/cashu.go index 2d19e6b..cada1ed 100644 --- a/cashu/cashu.go +++ b/cashu/cashu.go @@ -173,7 +173,7 @@ var ( ProofAlreadyUsedErr = Error{Detail: "proofs already used", Code: ProofsErrCode} InvalidProofErr = Error{Detail: "invalid proof", Code: ProofsErrCode} InputsBelowOutputs = Error{Detail: "amount of input proofs is below amount of outputs", Code: ProofsErrCode} - MeltQuoteNotExistErr = Error{Detail: "melt quote does not exist", Code: QuoteErrCode} + QuoteNotExistErr = Error{Detail: "quote does not exist", Code: QuoteErrCode} InsufficientProofsAmount = Error{Detail: "insufficient amount in proofs", Code: ProofsErrCode} InvalidKeysetProof = Error{Detail: "proof from an invalid keyset", Code: ProofsErrCode} InvalidSignatureRequest = Error{Detail: "requested signature from non-active keyset", Code: KeysetErrCode} diff --git a/mint/lightning/lightning.go b/mint/lightning/lightning.go index 175ea3e..4ca5a35 100644 --- a/mint/lightning/lightning.go +++ b/mint/lightning/lightning.go @@ -12,7 +12,7 @@ const ( // Client interface to interact with a Lightning backend type Client interface { CreateInvoice(amount uint64) (Invoice, error) - InvoiceSettled(hash string) (bool, error) + InvoiceStatus(hash string) (Invoice, error) FeeReserve(amount uint64) uint64 SendPayment(request string, amount uint64) (string, error) } @@ -39,6 +39,7 @@ type Invoice struct { Id string // random id generated by mint PaymentRequest string PaymentHash string + Preimage string Settled bool Redeemed bool Amount uint64 diff --git a/mint/lightning/lnd.go b/mint/lightning/lnd.go index 5ff18b9..90329b9 100644 --- a/mint/lightning/lnd.go +++ b/mint/lightning/lnd.go @@ -99,19 +99,26 @@ func (lnd *LndClient) CreateInvoice(amount uint64) (Invoice, error) { return invoice, nil } -func (lnd *LndClient) InvoiceSettled(hash string) (bool, error) { +func (lnd *LndClient) InvoiceStatus(hash string) (Invoice, error) { hashBytes, err := hex.DecodeString(hash) if err != nil { - return false, errors.New("invalid hash provided") + return Invoice{}, errors.New("invalid hash provided") } paymentHashRequest := lnrpc.PaymentHash{RHash: hashBytes} lookupInvoiceResponse, err := lnd.grpcClient.LookupInvoice(context.Background(), &paymentHashRequest) if err != nil { - return false, fmt.Errorf("error getting invoice status: %v", err) + return Invoice{}, err } - return lookupInvoiceResponse.State == lnrpc.Invoice_SETTLED, nil + invoice := Invoice{ + PaymentRequest: lookupInvoiceResponse.PaymentRequest, + PaymentHash: hash, + Settled: lookupInvoiceResponse.State == lnrpc.Invoice_SETTLED, + Amount: uint64(lookupInvoiceResponse.Value), + } + + return invoice, nil } func (lnd *LndClient) FeeReserve(amount uint64) uint64 { diff --git a/mint/mint.go b/mint/mint.go index 91288bf..ab1da40 100644 --- a/mint/mint.go +++ b/mint/mint.go @@ -134,18 +134,25 @@ func (m *Mint) GetMintQuoteState(method, quoteId string) (nut04.PostMintQuoteBol invoice := m.db.GetInvoice(quoteId) if invoice == nil { - return nut04.PostMintQuoteBolt11Response{}, cashu.InvoiceNotExistErr + return nut04.PostMintQuoteBolt11Response{}, cashu.QuoteNotExistErr } // check if the invoice has been paid - settled, _ := m.LightningClient.InvoiceSettled(invoice.PaymentHash) - if settled != invoice.Settled { - invoice.Settled = settled + status, err := m.LightningClient.InvoiceStatus(invoice.PaymentHash) + if err != nil { + return nut04.PostMintQuoteBolt11Response{}, fmt.Errorf("error checking invoice status: %v", err) + } + if status.Settled && status.Settled != invoice.Settled { + invoice.Settled = status.Settled m.db.SaveInvoice(*invoice) } - quoteState := nut04.PostMintQuoteBolt11Response{Quote: invoice.Id, - Request: invoice.PaymentRequest, Paid: settled, Expiry: invoice.Expiry} + quoteState := nut04.PostMintQuoteBolt11Response{ + Quote: invoice.Id, + Request: invoice.PaymentRequest, + Paid: invoice.Settled, + Expiry: invoice.Expiry, + } return quoteState, nil } @@ -163,8 +170,11 @@ func (m *Mint) MintTokens(method, id string, blindedMessages cashu.BlindedMessag var blindedSignatures cashu.BlindedSignatures - settled, _ := m.LightningClient.InvoiceSettled(invoice.PaymentHash) - if settled { + status, err := m.LightningClient.InvoiceStatus(invoice.PaymentHash) + if err != nil { + return nil, fmt.Errorf("error checking invoice status: %v", err) + } + if status.Settled { if invoice.Redeemed { return nil, cashu.InvoiceTokensIssuedErr } @@ -295,7 +305,7 @@ func (m *Mint) GetMeltQuoteState(method, quoteId string) (MeltQuote, error) { meltQuote := m.db.GetMeltQuote(quoteId) if meltQuote == nil { - return MeltQuote{}, cashu.MeltQuoteNotExistErr + return MeltQuote{}, cashu.QuoteNotExistErr } return *meltQuote, nil @@ -310,7 +320,7 @@ func (m *Mint) MeltTokens(method, quoteId string, proofs cashu.Proofs) (MeltQuot meltQuote := m.db.GetMeltQuote(quoteId) if meltQuote == nil { - return MeltQuote{}, cashu.MeltQuoteNotExistErr + return MeltQuote{}, cashu.QuoteNotExistErr } proofsAmount := proofs.Amount() diff --git a/mint/server.go b/mint/server.go index 7b58ad5..234b400 100644 --- a/mint/server.go +++ b/mint/server.go @@ -191,7 +191,7 @@ func (ms *MintServer) mintRequest(rw http.ResponseWriter, req *http.Request) { reqMintResponse, err := ms.mint.RequestMintQuote(method, mintReq.Amount, mintReq.Unit) if err != nil { cashuErr, ok := err.(*cashu.Error) - // RequestMintQuote will return err from lightning backend if invoice + // note: RequestMintQuote will return err from lightning backend if invoice // generation fails. Log that err from backend but return generic response to request if ok && cashuErr.Code == cashu.InvoiceErrCode { ms.writeErr(rw, req, cashu.StandardErr, cashuErr.Error()) @@ -218,6 +218,12 @@ func (ms *MintServer) mintQuoteState(rw http.ResponseWriter, req *http.Request) mintQuoteStateResponse, err := ms.mint.GetMintQuoteState(method, quoteId) if err != nil { + // if error is from lnd, log it but throw generic response + _, ok := err.(*cashu.Error) + if !ok { + ms.writeErr(rw, req, cashu.StandardErr, err.Error()) + } + ms.writeErr(rw, req, err) return } @@ -243,6 +249,12 @@ func (ms *MintServer) mintTokensRequest(rw http.ResponseWriter, req *http.Reques blindedSignatures, err := ms.mint.MintTokens(method, mintReq.Quote, mintReq.Outputs) if err != nil { + // if error is from lnd, log it but throw generic response + _, ok := err.(*cashu.Error) + if !ok { + ms.writeErr(rw, req, cashu.StandardErr, err.Error()) + } + ms.writeErr(rw, req, err) return }