Skip to content

Commit

Permalink
return invoice status in lightning client
Browse files Browse the repository at this point in the history
  • Loading branch information
elnosh committed Jun 26, 2024
1 parent 845c7a6 commit bded58c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 17 deletions.
2 changes: 1 addition & 1 deletion cashu/cashu.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
3 changes: 2 additions & 1 deletion mint/lightning/lightning.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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
Expand Down
15 changes: 11 additions & 4 deletions mint/lightning/lnd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 20 additions & 10 deletions mint/mint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
}
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down
14 changes: 13 additions & 1 deletion mint/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -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
}
Expand All @@ -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
}
Expand Down

0 comments on commit bded58c

Please sign in to comment.