From 32357fd51ad811e8a61d5fead3ecf87dd7c8123c Mon Sep 17 00:00:00 2001 From: elnosh Date: Tue, 2 Jul 2024 13:56:10 -0500 Subject: [PATCH] tests for nut05 quote state --- cashu/nuts/nut05/nut05.go | 4 -- mint/mint.go | 14 ------- mint/mint_integration_test.go | 70 +++++++++++++++++++++++++++++++++++ wallet/wallet.go | 6 ++- 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/cashu/nuts/nut05/nut05.go b/cashu/nuts/nut05/nut05.go index 6a2f5da..a64dad1 100644 --- a/cashu/nuts/nut05/nut05.go +++ b/cashu/nuts/nut05/nut05.go @@ -5,7 +5,6 @@ package nut05 import ( "encoding/json" - "errors" "github.com/elnosh/gonuts/cashu" ) @@ -98,9 +97,6 @@ func (quoteResponse *PostMeltQuoteBolt11Response) UnmarshalJSON(data []byte) err quoteResponse.Amount = tempQuote.Amount quoteResponse.FeeReserve = tempQuote.FeeReserve state := StringToState(tempQuote.State) - if state == Unknown { - return errors.New("invalid state") - } quoteResponse.State = state quoteResponse.Paid = tempQuote.Paid quoteResponse.Expiry = tempQuote.Expiry diff --git a/mint/mint.go b/mint/mint.go index 03dbb88..15056ce 100644 --- a/mint/mint.go +++ b/mint/mint.go @@ -315,20 +315,6 @@ func (m *Mint) GetMeltQuoteState(method, quoteId string) (MeltQuote, error) { return MeltQuote{}, cashu.QuoteNotExistErr } - // if quote not paid, check status of payment with backend - if meltQuote.State == nut05.Unpaid { - invoice, err := m.LightningClient.InvoiceStatus(meltQuote.PaymentHash) - if err != nil { - return MeltQuote{}, cashu.BuildCashuError(err.Error(), cashu.StandardErr.Code) - } - if invoice.Settled { - meltQuote.Paid = true - meltQuote.State = nut05.Paid - meltQuote.Preimage = invoice.Preimage - m.db.SaveMeltQuote(*meltQuote) - } - } - return *meltQuote, nil } diff --git a/mint/mint_integration_test.go b/mint/mint_integration_test.go index 01dde91..036f6f3 100644 --- a/mint/mint_integration_test.go +++ b/mint/mint_integration_test.go @@ -4,6 +4,7 @@ package mint_test import ( "context" + "encoding/hex" "errors" "flag" "log" @@ -13,6 +14,7 @@ import ( btcdocker "github.com/elnosh/btc-docker-test" "github.com/elnosh/gonuts/cashu" + "github.com/elnosh/gonuts/cashu/nuts/nut05" "github.com/elnosh/gonuts/crypto" "github.com/elnosh/gonuts/mint" "github.com/elnosh/gonuts/testutils" @@ -236,6 +238,74 @@ func TestMeltRequest(t *testing.T) { if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } +} + +func TestMeltQuoteState(t *testing.T) { + invoice := lnrpc.Invoice{Value: 2000} + addInvoiceResponse, err := lnd2.Client.AddInvoice(ctx, &invoice) + if err != nil { + t.Fatalf("error creating invoice: %v", err) + } + + lookupInvoice, err := lnd2.Client.LookupInvoice(ctx, &lnrpc.PaymentHash{RHash: addInvoiceResponse.RHash}) + if err != nil { + t.Fatalf("error finding invoice: %v", err) + } + + meltRequest, err := testMint.MeltRequest(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + if err != nil { + t.Fatalf("got unexpected error in melt request: %v", err) + } + + // test invalid method + _, err = testMint.GetMeltQuoteState("strike", meltRequest.Id) + if !errors.Is(err, cashu.PaymentMethodNotSupportedErr) { + t.Fatalf("expected error '%v' but got '%v' instead", cashu.PaymentMethodNotSupportedErr, err) + } + + // test invalid quote id + _, err = testMint.GetMeltQuoteState(testutils.BOLT11_METHOD, "quote1234") + if !errors.Is(err, cashu.QuoteNotExistErr) { + t.Fatalf("expected error '%v' but got '%v' instead", cashu.PaymentMethodNotSupportedErr, err) + } + + // test before paying melt + meltQuote, err := testMint.GetMeltQuoteState(testutils.BOLT11_METHOD, meltRequest.Id) + if err != nil { + t.Fatalf("unexpected error getting melt quote state: %v", err) + } + if meltQuote.Paid { + t.Fatalf("expected quote.Paid '%v' but got '%v' instead", false, meltQuote.Paid) + } + if meltQuote.State != nut05.Unpaid { + t.Fatalf("expected quote state '%v' but got '%v' instead", nut05.Unpaid.String(), meltQuote.State.String()) + } + + // test state after melting + validProofs, err := testutils.GetValidProofsForAmount(6500, testMint, lnd2) + if err != nil { + t.Fatalf("error generating valid proofs: %v", err) + } + + melt, err := testMint.MeltTokens(testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + if err != nil { + t.Fatalf("got unexpected error in melt: %v", err) + } + + meltQuote, err = testMint.GetMeltQuoteState(testutils.BOLT11_METHOD, meltRequest.Id) + if err != nil { + t.Fatalf("unexpected error getting melt quote state: %v", err) + } + if !melt.Paid { + t.Fatal("got unexpected unpaid melt quote") + } + if meltQuote.State != nut05.Paid { + t.Fatalf("expected quote state '%v' but got '%v' instead", nut05.Paid.String(), meltQuote.State.String()) + } + preimageString := hex.EncodeToString(lookupInvoice.RPreimage) + if meltQuote.Preimage != preimageString { + t.Fatalf("expected quote preimage '%v' but got '%v' instead", preimageString, meltQuote.Preimage) + } } diff --git a/wallet/wallet.go b/wallet/wallet.go index afd807c..e6301d6 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -552,7 +552,11 @@ func (w *Wallet) Melt(invoice string, mint string) (*nut05.PostMeltQuoteBolt11Re // TODO: deprecate paid field and only use State // TODO: check for PENDING as well - paid := meltBolt11Response.Paid && meltBolt11Response.State == nut05.Paid + paid := meltBolt11Response.Paid + // if state field is present, use that instead of paid + if meltBolt11Response.State != nut05.Unknown { + paid = meltBolt11Response.State == nut05.Paid + } if !paid { // save proofs if invoice was not paid w.saveProofs(proofs)