From 975dc1398fc7d4bba05f25dd671f813f6cce7d70 Mon Sep 17 00:00:00 2001 From: elnosh Date: Wed, 30 Oct 2024 10:33:47 -0500 Subject: [PATCH 1/2] mint - pass request struct to mint methods --- mint/mint.go | 67 ++++------ mint/mint_integration_test.go | 237 +++++++++++++++++++++------------- mint/server.go | 40 ++++-- testutils/utils.go | 19 ++- 4 files changed, 218 insertions(+), 145 deletions(-) diff --git a/mint/mint.go b/mint/mint.go index 354960f..28529e9 100644 --- a/mint/mint.go +++ b/mint/mint.go @@ -245,20 +245,17 @@ func (m *Mint) logDebugf(format string, args ...any) { // and returns a mint quote or an error. // The request to mint a token is explained in // NUT-04 here: https://github.com/cashubtc/nuts/blob/main/04.md. -func (m *Mint) RequestMintQuote(method string, amount uint64, unit string) (storage.MintQuote, error) { - // only support bolt11 - if method != BOLT11_METHOD { - return storage.MintQuote{}, cashu.PaymentMethodNotSupportedErr - } +func (m *Mint) RequestMintQuote(mintQuoteRequest nut04.PostMintQuoteBolt11Request) (storage.MintQuote, error) { // only support sat unit - if unit != SAT_UNIT { - errmsg := fmt.Sprintf("unit '%v' not supported", unit) + if mintQuoteRequest.Unit != SAT_UNIT { + errmsg := fmt.Sprintf("unit '%v' not supported", mintQuoteRequest.Unit) return storage.MintQuote{}, cashu.BuildCashuError(errmsg, cashu.UnitErrCode) } // check limits + requestAmount := mintQuoteRequest.Amount if m.limits.MintingSettings.MaxAmount > 0 { - if amount > m.limits.MintingSettings.MaxAmount { + if requestAmount > m.limits.MintingSettings.MaxAmount { return storage.MintQuote{}, cashu.MintAmountExceededErr } } @@ -268,14 +265,14 @@ func (m *Mint) RequestMintQuote(method string, amount uint64, unit string) (stor errmsg := fmt.Sprintf("could not get mint balance from db: %v", err) return storage.MintQuote{}, cashu.BuildCashuError(errmsg, cashu.DBErrCode) } - if balance+amount > m.limits.MaxBalance { + if balance+requestAmount > m.limits.MaxBalance { return storage.MintQuote{}, cashu.MintingDisabled } } // get an invoice from the lightning backend - m.logInfof("requesting invoice from lightning backend for %v sats", amount) - invoice, err := m.requestInvoice(amount) + m.logInfof("requesting invoice from lightning backend for %v sats", requestAmount) + invoice, err := m.requestInvoice(requestAmount) if err != nil { errmsg := fmt.Sprintf("could not generate invoice: %v", err) return storage.MintQuote{}, cashu.BuildCashuError(errmsg, cashu.LightningBackendErrCode) @@ -288,7 +285,7 @@ func (m *Mint) RequestMintQuote(method string, amount uint64, unit string) (stor } mintQuote := storage.MintQuote{ Id: quoteId, - Amount: amount, + Amount: requestAmount, PaymentRequest: invoice.PaymentRequest, PaymentHash: invoice.PaymentHash, State: nut04.Unpaid, @@ -306,11 +303,7 @@ func (m *Mint) RequestMintQuote(method string, amount uint64, unit string) (stor // GetMintQuoteState returns the state of a mint quote. // Used to check whether a mint quote has been paid. -func (m *Mint) GetMintQuoteState(method, quoteId string) (storage.MintQuote, error) { - if method != BOLT11_METHOD { - return storage.MintQuote{}, cashu.PaymentMethodNotSupportedErr - } - +func (m *Mint) GetMintQuoteState(quoteId string) (storage.MintQuote, error) { mintQuote, err := m.db.GetMintQuote(quoteId) if err != nil { return storage.MintQuote{}, cashu.QuoteNotExistErr @@ -341,15 +334,13 @@ func (m *Mint) GetMintQuoteState(method, quoteId string) (storage.MintQuote, err // MintTokens verifies whether the mint quote with id has been paid and proceeds to // sign the blindedMessages and return the BlindedSignatures if it was paid. -func (m *Mint) MintTokens(method, id string, blindedMessages cashu.BlindedMessages) (cashu.BlindedSignatures, error) { - if method != BOLT11_METHOD { - return nil, cashu.PaymentMethodNotSupportedErr - } - - mintQuote, err := m.db.GetMintQuote(id) +func (m *Mint) MintTokens(mintTokensRequest nut04.PostMintBolt11Request) (cashu.BlindedSignatures, error) { + mintQuote, err := m.db.GetMintQuote(mintTokensRequest.Quote) if err != nil { return nil, cashu.QuoteNotExistErr } + + blindedMessages := mintTokensRequest.Outputs var blindedSignatures cashu.BlindedSignatures invoicePaid := false @@ -500,16 +491,14 @@ func (m *Mint) Swap(proofs cashu.Proofs, blindedMessages cashu.BlindedMessages) // RequestMeltQuote will process a request to melt tokens and return a MeltQuote. // A melt is requested by a wallet to request the mint to pay an invoice. -func (m *Mint) RequestMeltQuote(method, request, unit string) (storage.MeltQuote, error) { - if method != BOLT11_METHOD { - return storage.MeltQuote{}, cashu.PaymentMethodNotSupportedErr - } - if unit != SAT_UNIT { - errmsg := fmt.Sprintf("unit '%v' not supported", unit) +func (m *Mint) RequestMeltQuote(meltQuoteRequest nut05.PostMeltQuoteBolt11Request) (storage.MeltQuote, error) { + if meltQuoteRequest.Unit != SAT_UNIT { + errmsg := fmt.Sprintf("unit '%v' not supported", meltQuoteRequest.Unit) return storage.MeltQuote{}, cashu.BuildCashuError(errmsg, cashu.UnitErrCode) } // check invoice passed is valid + request := meltQuoteRequest.Request bolt11, err := decodepay.Decodepay(request) if err != nil { errmsg := fmt.Sprintf("invalid invoice: %v", err) @@ -575,11 +564,7 @@ func (m *Mint) RequestMeltQuote(method, request, unit string) (storage.MeltQuote // GetMeltQuoteState returns the state of a melt quote. // Used to check whether a melt quote has been paid. -func (m *Mint) GetMeltQuoteState(ctx context.Context, method, quoteId string) (storage.MeltQuote, error) { - if method != BOLT11_METHOD { - return storage.MeltQuote{}, cashu.PaymentMethodNotSupportedErr - } - +func (m *Mint) GetMeltQuoteState(ctx context.Context, quoteId string) (storage.MeltQuote, error) { meltQuote, err := m.db.GetMeltQuote(quoteId) if err != nil { return storage.MeltQuote{}, cashu.QuoteNotExistErr @@ -675,7 +660,9 @@ func (m *Mint) removePendingProofsForQuote(quoteId string) (cashu.Proofs, error) // MeltTokens verifies whether proofs provided are valid // and proceeds to attempt payment. -func (m *Mint) MeltTokens(ctx context.Context, method, quoteId string, proofs cashu.Proofs) (storage.MeltQuote, error) { +func (m *Mint) MeltTokens(ctx context.Context, meltTokensRequest nut05.PostMeltBolt11Request) (storage.MeltQuote, error) { + proofs := meltTokensRequest.Inputs + var proofsAmount uint64 Ys := make([]string, len(proofs)) for i, proof := range proofs { @@ -689,11 +676,7 @@ func (m *Mint) MeltTokens(ctx context.Context, method, quoteId string, proofs ca Ys[i] = Yhex } - if method != BOLT11_METHOD { - return storage.MeltQuote{}, cashu.PaymentMethodNotSupportedErr - } - - meltQuote, err := m.db.GetMeltQuote(quoteId) + meltQuote, err := m.db.GetMeltQuote(meltTokensRequest.Quote) if err != nil { return storage.MeltQuote{}, cashu.QuoteNotExistErr } @@ -921,11 +904,11 @@ func (m *Mint) ProofsStateCheck(Ys []string) ([]nut07.ProofState, error) { defer cancel() m.logDebugf("checking if status of pending proofs has changed") - for quoteId, _ := range pendingQuotes { + for quoteId := range pendingQuotes { // GetMeltQuoteState will check the status of the quote // and update the db tables (pending proofs, used proofs) appropriately // if the status has changed - _, err := m.GetMeltQuoteState(ctx, BOLT11_METHOD, quoteId) + _, err := m.GetMeltQuoteState(ctx, quoteId) if err != nil { return nil, err } diff --git a/mint/mint_integration_test.go b/mint/mint_integration_test.go index 9166985..234513e 100644 --- a/mint/mint_integration_test.go +++ b/mint/mint_integration_test.go @@ -106,19 +106,15 @@ func testMain(m *testing.M) int { func TestRequestMintQuote(t *testing.T) { var mintAmount uint64 = 10000 - _, err := testMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, testutils.SAT_UNIT) + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + _, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) } - // test invalid method - _, err = testMint.RequestMintQuote("strike", mintAmount, testutils.SAT_UNIT) - if !errors.Is(err, cashu.PaymentMethodNotSupportedErr) { - t.Fatalf("expected error '%v' but got '%v' instead", cashu.PaymentMethodNotSupportedErr, err) - } - // test invalid unit - _, err = testMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, "eth") + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: "eth"} + _, err = testMint.RequestMintQuote(mintQuoteRequest) cashuErr, ok := err.(*cashu.Error) if !ok { t.Fatalf("got unexpected non-Cashu error: %v", err) @@ -130,27 +126,22 @@ func TestRequestMintQuote(t *testing.T) { func TestMintQuoteState(t *testing.T) { var mintAmount uint64 = 42000 - mintQuoteResponse, err := testMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, testutils.SAT_UNIT) + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) } keyset := testMint.GetActiveKeyset() - // test invalid method - _, err = testMint.GetMintQuoteState("strike", mintQuoteResponse.Id) - if !errors.Is(err, cashu.PaymentMethodNotSupportedErr) { - t.Fatalf("expected error '%v' but got '%v' instead", cashu.PaymentMethodNotSupportedErr, err) - } - // test invalid quote - _, err = testMint.GetMintQuoteState(testutils.BOLT11_METHOD, "mintquote1234") + _, err = testMint.GetMintQuoteState("mintquote1234") if !errors.Is(err, cashu.QuoteNotExistErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.QuoteNotExistErr, err) } // test quote state before paying invoice - quoteStateResponse, err := testMint.GetMintQuoteState(testutils.BOLT11_METHOD, mintQuoteResponse.Id) + quoteStateResponse, err := testMint.GetMintQuoteState(mintQuoteResponse.Id) if err != nil { t.Fatalf("unexpected error getting quote state: %v", err) } @@ -168,7 +159,7 @@ func TestMintQuoteState(t *testing.T) { } // test quote state after paying invoice - quoteStateResponse, err = testMint.GetMintQuoteState(testutils.BOLT11_METHOD, mintQuoteResponse.Id) + quoteStateResponse, err = testMint.GetMintQuoteState(mintQuoteResponse.Id) if err != nil { t.Fatalf("unexpected error getting quote state: %v", err) } @@ -179,13 +170,14 @@ func TestMintQuoteState(t *testing.T) { blindedMessages, _, _, err := testutils.CreateBlindedMessages(mintAmount, keyset) // mint tokens - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + mintTokensRequest := nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: blindedMessages} + _, err = testMint.MintTokens(mintTokensRequest) if err != nil { t.Fatalf("got unexpected error minting tokens: %v", err) } // test quote state after minting tokens - quoteStateResponse, err = testMint.GetMintQuoteState(testutils.BOLT11_METHOD, mintQuoteResponse.Id) + quoteStateResponse, err = testMint.GetMintQuoteState(mintQuoteResponse.Id) if err != nil { t.Fatalf("unexpected error getting quote state: %v", err) } @@ -197,23 +189,25 @@ func TestMintQuoteState(t *testing.T) { func TestMintTokens(t *testing.T) { var mintAmount uint64 = 42000 - mintQuoteResponse, err := testMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, testutils.SAT_UNIT) + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) } keyset := testMint.GetActiveKeyset() - blindedMessages, _, _, err := testutils.CreateBlindedMessages(mintAmount, keyset) // test without paying invoice - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + mintTokensRequest := nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: blindedMessages} + _, err = testMint.MintTokens(mintTokensRequest) if !errors.Is(err, cashu.MintQuoteRequestNotPaid) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MintQuoteRequestNotPaid, err) } // test invalid quote - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, "mintquote1234", blindedMessages) + mintTokensRequest = nut04.PostMintBolt11Request{Quote: "mintquote1234", Outputs: blindedMessages} + _, err = testMint.MintTokens(mintTokensRequest) if !errors.Is(err, cashu.QuoteNotExistErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.QuoteNotExistErr, err) } @@ -229,7 +223,8 @@ func TestMintTokens(t *testing.T) { // test with blinded messages over request mint amount overBlindedMessages, _, _, err := testutils.CreateBlindedMessages(mintAmount+100, keyset) - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, overBlindedMessages) + mintTokensRequest = nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: overBlindedMessages} + _, err = testMint.MintTokens(mintTokensRequest) if !errors.Is(err, cashu.OutputsOverQuoteAmountErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.OutputsOverQuoteAmountErr, err) } @@ -237,24 +232,27 @@ func TestMintTokens(t *testing.T) { // test with invalid keyset in blinded messages invalidKeyset := crypto.MintKeyset{Id: "0192384aa"} invalidKeysetMessages, _, _, err := testutils.CreateBlindedMessages(mintAmount, invalidKeyset) - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, invalidKeysetMessages) + mintTokensRequest = nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: invalidKeysetMessages} + _, err = testMint.MintTokens(mintTokensRequest) if !errors.Is(err, cashu.UnknownKeysetErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.UnknownKeysetErr, err) } - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + mintTokensRequest = nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: blindedMessages} + _, err = testMint.MintTokens(mintTokensRequest) if err != nil { t.Fatalf("got unexpected error minting tokens: %v", err) } // test already minted tokens - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + _, err = testMint.MintTokens(mintTokensRequest) if !errors.Is(err, cashu.MintQuoteAlreadyIssued) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MintQuoteAlreadyIssued, err) } // test mint with blinded messages already signed - mintQuoteResponse, err = testMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, testutils.SAT_UNIT) + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err = testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) } @@ -267,7 +265,8 @@ func TestMintTokens(t *testing.T) { t.Fatalf("error paying invoice: %v", response.PaymentError) } - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + mintTokensRequest = nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: blindedMessages} + _, err = testMint.MintTokens(mintTokensRequest) if !errors.Is(err, cashu.BlindedMessageAlreadySigned) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.BlindedMessageAlreadySigned, err) } @@ -365,15 +364,11 @@ func TestRequestMeltQuote(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } - - // test invalid method - _, err = testMint.RequestMeltQuote("strike", addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) - if !errors.Is(err, cashu.PaymentMethodNotSupportedErr) { - t.Fatalf("expected error '%v' but got '%v' instead", cashu.PaymentMethodNotSupportedErr, err) - } + paymentRequest := addInvoiceResponse.PaymentRequest // test invalid unit - _, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, "eth") + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: "eth"} + _, err = testMint.RequestMeltQuote(meltQuoteRequest) cashuErr, ok := err.(*cashu.Error) if !ok { t.Fatalf("got unexpected non-Cashu error: %v", err) @@ -383,18 +378,20 @@ func TestRequestMeltQuote(t *testing.T) { } // test invalid invoice - _, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, "invoice1111", testutils.SAT_UNIT) + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: "invoice1111", Unit: testutils.SAT_UNIT} + _, err = testMint.RequestMeltQuote(meltQuoteRequest) if err == nil { t.Fatal("expected error but got nil") } - _, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + _, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } // trying to create another melt quote with same invoice should throw error - _, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + _, err = testMint.RequestMeltQuote(meltQuoteRequest) if !errors.Is(err, cashu.MeltQuoteForRequestExists) { //if !errors.Is(err, cashu.PaymentMethodNotSupportedErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MeltQuoteForRequestExists, err) @@ -407,31 +404,27 @@ func TestMeltQuoteState(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } + paymentRequest := addInvoiceResponse.PaymentRequest lookupInvoice, err := lnd2.Client.LookupInvoice(ctx, &lnrpc.PaymentHash{RHash: addInvoiceResponse.RHash}) if err != nil { t.Fatalf("error finding invoice: %v", err) } - meltRequest, err := testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltRequest, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } - // test invalid method - _, err = testMint.GetMeltQuoteState(ctx, "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(ctx, testutils.BOLT11_METHOD, "quote1234") + _, err = testMint.GetMeltQuoteState(ctx, "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(ctx, testutils.BOLT11_METHOD, meltRequest.Id) + meltQuote, err := testMint.GetMeltQuoteState(ctx, meltRequest.Id) if err != nil { t.Fatalf("unexpected error getting melt quote state: %v", err) } @@ -445,12 +438,13 @@ func TestMeltQuoteState(t *testing.T) { t.Fatalf("error generating valid proofs: %v", err) } - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + meltTokensRequest := nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if err != nil { t.Fatalf("got unexpected error in melt: %v", err) } - meltQuote, err = testMint.GetMeltQuoteState(ctx, testutils.BOLT11_METHOD, meltRequest.Id) + meltQuote, err = testMint.GetMeltQuoteState(ctx, meltRequest.Id) if err != nil { t.Fatalf("unexpected error getting melt quote state: %v", err) } @@ -476,14 +470,17 @@ func TestMelt(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } + paymentRequest := addInvoiceResponse.PaymentRequest - meltQuote, err := testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } // test proofs amount under melt amount - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, underProofs) + meltTokensRequest := nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: underProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, cashu.InsufficientProofsAmount) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.PaymentMethodNotSupportedErr, err) } @@ -496,7 +493,8 @@ func TestMelt(t *testing.T) { // test invalid proofs validProofs[0].Secret = "some invalid secret" - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, cashu.InvalidProofErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.InvalidProofErr, err) } @@ -508,12 +506,14 @@ func TestMelt(t *testing.T) { duplicateProofs := make(cashu.Proofs, proofsLen) copy(duplicateProofs, validProofs) duplicateProofs[proofsLen-2] = duplicateProofs[proofsLen-1] - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, duplicateProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: duplicateProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, cashu.DuplicateProofs) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.DuplicateProofs, err) } - melt, err := testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + melt, err := testMint.MeltTokens(ctx, meltTokensRequest) if err != nil { t.Fatalf("got unexpected error in melt: %v", err) } @@ -522,7 +522,7 @@ func TestMelt(t *testing.T) { } // test quote already paid - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, cashu.MeltQuoteAlreadyPaid) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MeltQuoteAlreadyPaid, err) } @@ -532,12 +532,17 @@ func TestMelt(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } + paymentRequest = addInvoiceResponse.PaymentRequest + // test already used proofs - newQuote, err := testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + newQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, newQuote.Id, validProofs) + + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: newQuote.Id, Inputs: validProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, cashu.ProofAlreadyUsedErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.ProofAlreadyUsedErr, err) } @@ -568,20 +573,24 @@ func TestMelt(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } + paymentRequest = addInvoiceResponse.PaymentRequest - meltQuote, err = mintFees.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err = mintFees.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } // test proofs below needed amount with fees - _, err = mintFees.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, underProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: underProofs} + _, err = mintFees.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, cashu.InsufficientProofsAmount) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.InsufficientProofsAmount, err) } // test valid proofs accounting for fees - melt, err = mintFees.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofsWithFees) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofsWithFees} + melt, err = mintFees.MeltTokens(ctx, meltTokensRequest) if err != nil { t.Fatalf("got unexpected error in melt: %v", err) } @@ -603,8 +612,10 @@ func TestMelt(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } + paymentRequest = noRouteInvoice.PaymentRequest - meltQuote, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, noRouteInvoice.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } @@ -614,7 +625,8 @@ func TestMelt(t *testing.T) { t.Fatalf("error generating valid proofs: %v", err) } - meltResponse, err := testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + meltResponse, err := testMint.MeltTokens(ctx, meltTokensRequest) if meltResponse.State != nut05.Unpaid { // expecting unpaid since payment should have failed t.Fatalf("expected melt quote with state of '%s' but got '%s' instead", nut05.Unpaid, meltResponse.State) @@ -622,7 +634,8 @@ func TestMelt(t *testing.T) { // test internal quotes (mint and melt quotes with same invoice) var mintAmount uint64 = 42000 - mintQuoteResponse, err := testMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, testutils.SAT_UNIT) + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) } @@ -634,7 +647,11 @@ func TestMelt(t *testing.T) { t.Fatalf("error generating valid proofs: %v", err) } - meltQuote, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, mintQuoteResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{ + Request: mintQuoteResponse.PaymentRequest, + Unit: testutils.SAT_UNIT, + } + meltQuote, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } @@ -642,7 +659,8 @@ func TestMelt(t *testing.T) { t.Fatal("RequestMeltQuote did not return fee reserve of 0 for internal quote") } - melt, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, proofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: proofs} + melt, err = testMint.MeltTokens(ctx, meltTokensRequest) if err != nil { t.Fatalf("got unexpected error in melt: %v", err) } @@ -651,7 +669,8 @@ func TestMelt(t *testing.T) { } // now mint should work because quote was settled internally - _, err = testMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + mintTokensRequest := nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: blindedMessages} + _, err = testMint.MintTokens(mintTokensRequest) if err != nil { t.Fatalf("got unexpected error in mint: %v", err) } @@ -666,8 +685,10 @@ func TestPendingProofs(t *testing.T) { if err != nil { t.Fatalf("error creating hodl invoice: %v", err) } + paymentRequest := addHodlInvoiceRes.PaymentRequest - meltQuote, err := testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addHodlInvoiceRes.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } @@ -682,7 +703,8 @@ func TestPendingProofs(t *testing.T) { meltContext, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - melt, err := testMint.MeltTokens(meltContext, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + meltTokensRequest := nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + melt, err := testMint.MeltTokens(meltContext, meltTokensRequest) if err != nil { t.Fatalf("got unexpected error in melt: %v", err) } @@ -690,7 +712,7 @@ func TestPendingProofs(t *testing.T) { t.Fatalf("expected melt quote with state of '%s' but got '%s' instead", nut05.Pending, melt.State) } - meltQuote, err = testMint.GetMeltQuoteState(meltContext, testutils.BOLT11_METHOD, meltQuote.Id) + meltQuote, err = testMint.GetMeltQuoteState(meltContext, meltQuote.Id) if err != nil { t.Fatalf("unexpected error getting melt quote state: %v", err) } @@ -715,7 +737,8 @@ func TestPendingProofs(t *testing.T) { } } - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, cashu.MeltQuotePending) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MeltQuotePending, err) } @@ -734,7 +757,7 @@ func TestPendingProofs(t *testing.T) { t.Fatalf("error settling hodl invoice: %v", err) } - meltQuote, err = testMint.GetMeltQuoteState(ctx, testutils.BOLT11_METHOD, melt.Id) + meltQuote, err = testMint.GetMeltQuoteState(ctx, melt.Id) if err != nil { t.Fatalf("unexpected error getting melt quote state: %v", err) } @@ -893,14 +916,16 @@ func TestMintLimits(t *testing.T) { // test above mint max amount var mintAmount uint64 = 20000 - mintQuoteResponse, err := limitsMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, testutils.SAT_UNIT) + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err := limitsMint.RequestMintQuote(mintQuoteRequest) if !errors.Is(err, cashu.MintAmountExceededErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MintAmountExceededErr, err) } // amount below max limit mintAmount = 9500 - mintQuoteResponse, err = limitsMint.RequestMintQuote(testutils.BOLT11_METHOD, mintAmount, testutils.SAT_UNIT) + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err = limitsMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) } @@ -915,13 +940,16 @@ func TestMintLimits(t *testing.T) { if len(response.PaymentError) > 0 { t.Fatalf("error paying invoice: %v", response.PaymentError) } - blindedSignatures, err := limitsMint.MintTokens(testutils.BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + + mintTokensRequest := nut04.PostMintBolt11Request{Quote: mintQuoteResponse.Id, Outputs: blindedMessages} + blindedSignatures, err := limitsMint.MintTokens(mintTokensRequest) if err != nil { t.Fatalf("got unexpected error minting tokens: %v", err) } // test request mint that will make it go above max balance - mintQuoteResponse, err = limitsMint.RequestMintQuote(testutils.BOLT11_METHOD, 9000, testutils.SAT_UNIT) + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: 9000, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err = limitsMint.RequestMintQuote(mintQuoteRequest) if !errors.Is(err, cashu.MintingDisabled) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MintingDisabled, err) } @@ -932,8 +960,10 @@ func TestMintLimits(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } + paymentRequest := addInvoiceResponse.PaymentRequest - _, err = limitsMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + _, err = limitsMint.RequestMeltQuote(meltQuoteRequest) if !errors.Is(err, cashu.MeltAmountExceededErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MeltAmountExceededErr, err) } @@ -945,17 +975,23 @@ func TestMintLimits(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } - meltQuote, err := limitsMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + paymentRequest = addInvoiceResponse.PaymentRequest + + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err := limitsMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } - _, err = limitsMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + + meltTokensRequest := nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + _, err = limitsMint.MeltTokens(ctx, meltTokensRequest) if err != nil { t.Fatalf("got unexpected error in melt: %v", err) } // this should be within max balance now - mintQuoteResponse, err = limitsMint.RequestMintQuote(testutils.BOLT11_METHOD, 9000, testutils.SAT_UNIT) + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: 9000, Unit: testutils.SAT_UNIT} + mintQuoteResponse, err = limitsMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("got unexpected error requesting mint quote: %v", err) } @@ -1120,18 +1156,23 @@ func TestNUT11P2PK(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } - meltQuote, err := p2pkMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + paymentRequest := addInvoiceResponse.PaymentRequest + + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err := p2pkMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } - _, err = p2pkMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, lockedProofs) + meltTokensRequest := nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: lockedProofs} + _, err = p2pkMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, nut11.InvalidWitness) { t.Fatalf("expected error '%v' but got '%v' instead", nut11.InvalidWitness, err) } signedProofs, _ = testutils.AddP2PKWitnessToInputs(lockedProofs, []*btcec.PrivateKey{lock}) - _, err = p2pkMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, signedProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: signedProofs} + _, err = p2pkMint.MeltTokens(ctx, meltTokensRequest) if err != nil { t.Fatalf("unexpected error melting: %v", err) } @@ -1152,11 +1193,16 @@ func TestNUT11P2PK(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } - meltQuote, err = p2pkMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + paymentRequest = addInvoiceResponse.PaymentRequest + + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err = p2pkMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } - _, err = p2pkMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, signedProofs) + + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: signedProofs} + _, err = p2pkMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, nut11.SigAllOnlySwap) { t.Fatalf("expected error '%v' but got '%v' instead", nut11.SigAllOnlySwap, err) } @@ -1401,17 +1447,23 @@ func TestHTLC(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } - meltQuote, err := testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + paymentRequest := addInvoiceResponse.PaymentRequest + + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, lockedProofs) + + meltTokensRequest := nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: lockedProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, nut14.InvalidPreimageErr) { t.Fatalf("expected error '%v' but got '%v' instead", nut14.InvalidPreimageErr, err) } validProofs, _ = testutils.AddHTLCWitnessToInputs(lockedProofs, preimage, nil) - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs) + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: validProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if err != nil { t.Fatalf("unexpected error melting: %v", err) } @@ -1436,11 +1488,14 @@ func TestHTLC(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } - meltQuote, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addInvoiceResponse.PaymentRequest, testutils.SAT_UNIT) + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: addInvoiceResponse.PaymentRequest, Unit: testutils.SAT_UNIT} + meltQuote, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) } - _, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, lockedProofs) + + meltTokensRequest = nut05.PostMeltBolt11Request{Quote: meltQuote.Id, Inputs: lockedProofs} + _, err = testMint.MeltTokens(ctx, meltTokensRequest) if !errors.Is(err, nut11.SigAllOnlySwap) { t.Fatalf("expected error '%v' but got '%v' instead", nut11.SigAllOnlySwap, err) } diff --git a/mint/server.go b/mint/server.go index 5a44559..5bbff59 100644 --- a/mint/server.go +++ b/mint/server.go @@ -200,6 +200,10 @@ func (ms *MintServer) getKeysetById(rw http.ResponseWriter, req *http.Request) { func (ms *MintServer) mintRequest(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] + if method != BOLT11_METHOD { + ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) + return + } var mintReq nut04.PostMintQuoteBolt11Request err := decodeJsonReqBody(req, &mintReq) @@ -209,7 +213,7 @@ func (ms *MintServer) mintRequest(rw http.ResponseWriter, req *http.Request) { } ms.logRequest(req, 0, "mint request for %v %v", mintReq.Amount, mintReq.Unit) - mintQuote, err := ms.mint.RequestMintQuote(method, mintReq.Amount, mintReq.Unit) + mintQuote, err := ms.mint.RequestMintQuote(mintReq) if err != nil { cashuErr, ok := err.(*cashu.Error) // note: if there was internal error from lightning backend generating invoice @@ -244,9 +248,13 @@ func (ms *MintServer) mintRequest(rw http.ResponseWriter, req *http.Request) { func (ms *MintServer) mintQuoteState(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - quoteId := vars["quote_id"] + if method != BOLT11_METHOD { + ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) + return + } - mintQuote, err := ms.mint.GetMintQuoteState(method, quoteId) + quoteId := vars["quote_id"] + mintQuote, err := ms.mint.GetMintQuoteState(quoteId) if err != nil { cashuErr, ok := err.(*cashu.Error) // note: if there was internal error from lightning backend @@ -283,6 +291,10 @@ func (ms *MintServer) mintQuoteState(rw http.ResponseWriter, req *http.Request) func (ms *MintServer) mintTokensRequest(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] + if method != BOLT11_METHOD { + ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) + return + } var mintReq nut04.PostMintBolt11Request err := decodeJsonReqBody(req, &mintReq) @@ -291,7 +303,7 @@ func (ms *MintServer) mintTokensRequest(rw http.ResponseWriter, req *http.Reques return } - blindedSignatures, err := ms.mint.MintTokens(method, mintReq.Quote, mintReq.Outputs) + blindedSignatures, err := ms.mint.MintTokens(mintReq) if err != nil { cashuErr, ok := err.(*cashu.Error) // note: if there was internal error from lightning backend @@ -354,6 +366,10 @@ func (ms *MintServer) swapRequest(rw http.ResponseWriter, req *http.Request) { func (ms *MintServer) meltQuoteRequest(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] + if method != BOLT11_METHOD { + ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) + return + } var meltRequest nut05.PostMeltQuoteBolt11Request err := decodeJsonReqBody(req, &meltRequest) @@ -362,7 +378,7 @@ func (ms *MintServer) meltQuoteRequest(rw http.ResponseWriter, req *http.Request return } - meltQuote, err := ms.mint.RequestMeltQuote(method, meltRequest.Request, meltRequest.Unit) + meltQuote, err := ms.mint.RequestMeltQuote(meltRequest) if err != nil { cashuErr, ok := err.(*cashu.Error) // note: if there was internal error from db @@ -399,12 +415,16 @@ func (ms *MintServer) meltQuoteRequest(rw http.ResponseWriter, req *http.Request func (ms *MintServer) meltQuoteState(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - quoteId := vars["quote_id"] + if method != BOLT11_METHOD { + ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) + return + } ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - meltQuote, err := ms.mint.GetMeltQuoteState(ctx, method, quoteId) + quoteId := vars["quote_id"] + meltQuote, err := ms.mint.GetMeltQuoteState(ctx, quoteId) if err != nil { cashuErr, ok := err.(*cashu.Error) // note: if there was internal error from lightning backend @@ -443,6 +463,10 @@ func (ms *MintServer) meltQuoteState(rw http.ResponseWriter, req *http.Request) func (ms *MintServer) meltTokens(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] + if method != BOLT11_METHOD { + ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) + return + } var meltTokensRequest nut05.PostMeltBolt11Request err := decodeJsonReqBody(req, &meltTokensRequest) @@ -458,7 +482,7 @@ func (ms *MintServer) meltTokens(rw http.ResponseWriter, req *http.Request) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - meltQuote, err := ms.mint.MeltTokens(ctx, method, meltTokensRequest.Quote, meltTokensRequest.Inputs) + meltQuote, err := ms.mint.MeltTokens(ctx, meltTokensRequest) if err != nil { cashuErr, ok := err.(*cashu.Error) // note: if there was internal error from lightning backend diff --git a/testutils/utils.go b/testutils/utils.go index 9ce49e8..069f35b 100644 --- a/testutils/utils.go +++ b/testutils/utils.go @@ -20,6 +20,7 @@ import ( "github.com/decred/dcrd/dcrec/secp256k1/v4" btcdocker "github.com/elnosh/btc-docker-test" "github.com/elnosh/gonuts/cashu" + "github.com/elnosh/gonuts/cashu/nuts/nut04" "github.com/elnosh/gonuts/cashu/nuts/nut10" "github.com/elnosh/gonuts/cashu/nuts/nut11" "github.com/elnosh/gonuts/cashu/nuts/nut14" @@ -392,7 +393,8 @@ func GetBlindedSignatures(amount uint64, mint *mint.Mint, payer *btcdocker.Lnd) cashu.BlindedSignatures, error) { - mintQuoteResponse, err := mint.RequestMintQuote(BOLT11_METHOD, amount, SAT_UNIT) + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: SAT_UNIT} + mintQuoteResponse, err := mint.RequestMintQuote(mintQuoteRequest) if err != nil { return nil, nil, nil, nil, fmt.Errorf("error requesting mint quote: %v", err) } @@ -413,7 +415,11 @@ func GetBlindedSignatures(amount uint64, mint *mint.Mint, payer *btcdocker.Lnd) return nil, nil, nil, nil, fmt.Errorf("error paying invoice: %v", response.PaymentError) } - blindedSignatures, err := mint.MintTokens(BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + mintTokensRequest := nut04.PostMintBolt11Request{ + Quote: mintQuoteResponse.Id, + Outputs: blindedMessages, + } + blindedSignatures, err := mint.MintTokens(mintTokensRequest) if err != nil { return nil, nil, nil, nil, fmt.Errorf("got unexpected error minting tokens: %v", err) } @@ -480,7 +486,8 @@ func GetProofsWithSpendingCondition( mint *mint.Mint, payer *btcdocker.Lnd, ) (cashu.Proofs, error) { - mintQuoteResponse, err := mint.RequestMintQuote(BOLT11_METHOD, amount, SAT_UNIT) + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: SAT_UNIT} + mintQuoteResponse, err := mint.RequestMintQuote(mintQuoteRequest) if err != nil { return nil, fmt.Errorf("error requesting mint quote: %v", err) } @@ -503,7 +510,11 @@ func GetProofsWithSpendingCondition( return nil, fmt.Errorf("error paying invoice: %v", response.PaymentError) } - blindedSignatures, err := mint.MintTokens(BOLT11_METHOD, mintQuoteResponse.Id, blindedMessages) + mintTokensRequest := nut04.PostMintBolt11Request{ + Quote: mintQuoteResponse.Id, + Outputs: blindedMessages, + } + blindedSignatures, err := mint.MintTokens(mintTokensRequest) if err != nil { return nil, fmt.Errorf("got unexpected error minting tokens: %v", err) } From 901a0d05a47ac30f2341be79f2ce842b498fee51 Mon Sep 17 00:00:00 2001 From: elnosh Date: Wed, 30 Oct 2024 11:19:06 -0500 Subject: [PATCH 2/2] define sat unit in cashu package --- cashu/cashu.go | 34 +++++++++++++++++++--- cmd/nutw/nutw.go | 4 +-- crypto/keyset.go | 3 +- mint/mint.go | 16 +++++------ mint/mint_integration_test.go | 48 +++++++++++++++---------------- mint/server.go | 12 ++++---- testutils/utils.go | 8 ++---- wallet/wallet.go | 18 ++++++------ wallet/wallet_integration_test.go | 26 ++++++++--------- 9 files changed, 96 insertions(+), 73 deletions(-) diff --git a/cashu/cashu.go b/cashu/cashu.go index a7ab003..62aac70 100644 --- a/cashu/cashu.go +++ b/cashu/cashu.go @@ -15,9 +15,27 @@ import ( "github.com/fxamacker/cbor/v2" ) +type Unit int + +const ( + Sat Unit = iota + + BOLT11_METHOD = "bolt11" +) + +func (unit Unit) String() string { + switch unit { + case Sat: + return "sat" + default: + return "unknown" + } +} + var ( ErrInvalidTokenV3 = errors.New("invalid V3 token") ErrInvalidTokenV4 = errors.New("invalid V4 token") + ErrInvalidUnit = errors.New("invalid unit") ) // Cashu BlindedMessage. See https://github.com/cashubtc/nuts/blob/main/00.md#blindedmessage @@ -143,15 +161,19 @@ type TokenV3Proof struct { Proofs Proofs `json:"proofs"` } -func NewTokenV3(proofs Proofs, mint, unit string, includeDLEQ bool) TokenV3 { +func NewTokenV3(proofs Proofs, mint string, unit Unit, includeDLEQ bool) (TokenV3, error) { if !includeDLEQ { for i := 0; i < len(proofs); i++ { proofs[i].DLEQ = nil } } + if unit != Sat { + return TokenV3{}, ErrInvalidUnit + } + tokenProof := TokenV3Proof{Mint: mint, Proofs: proofs} - return TokenV3{Token: []TokenV3Proof{tokenProof}, Unit: unit} + return TokenV3{Token: []TokenV3Proof{tokenProof}, Unit: unit.String()}, nil } func DecodeTokenV3(tokenstr string) (*TokenV3, error) { @@ -237,7 +259,11 @@ type DLEQV4 struct { R []byte `json:"r"` } -func NewTokenV4(proofs Proofs, mint, unit string, includeDLEQ bool) (TokenV4, error) { +func NewTokenV4(proofs Proofs, mint string, unit Unit, includeDLEQ bool) (TokenV4, error) { + if unit != Sat { + return TokenV4{}, ErrInvalidUnit + } + proofsMap := make(map[string][]ProofV4) for _, proof := range proofs { C, err := hex.DecodeString(proof.C) @@ -294,7 +320,7 @@ func NewTokenV4(proofs Proofs, mint, unit string, includeDLEQ bool) (TokenV4, er i++ } - return TokenV4{MintURL: mint, Unit: unit, TokenProofs: proofsV4}, nil + return TokenV4{MintURL: mint, Unit: unit.String(), TokenProofs: proofsV4}, nil } func DecodeTokenV4(tokenstr string) (*TokenV4, error) { diff --git a/cmd/nutw/nutw.go b/cmd/nutw/nutw.go index a510f5f..e21a325 100644 --- a/cmd/nutw/nutw.go +++ b/cmd/nutw/nutw.go @@ -451,9 +451,9 @@ func send(ctx *cli.Context) error { var token cashu.Token if ctx.Bool(legacyFlag) { - token = cashu.NewTokenV3(proofsToSend, selectedMint, "sat", includeDLEQ) + token, _ = cashu.NewTokenV3(proofsToSend, selectedMint, cashu.Sat, includeDLEQ) } else { - token, err = cashu.NewTokenV4(proofsToSend, selectedMint, "sat", includeDLEQ) + token, err = cashu.NewTokenV4(proofsToSend, selectedMint, cashu.Sat, includeDLEQ) if err != nil { printErr(fmt.Errorf("could not serialize token: %v", err)) } diff --git a/crypto/keyset.go b/crypto/keyset.go index f3030c1..524d0f1 100644 --- a/crypto/keyset.go +++ b/crypto/keyset.go @@ -9,6 +9,7 @@ import ( "github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/elnosh/gonuts/cashu" "github.com/elnosh/gonuts/cashu/nuts/nut01" ) @@ -82,7 +83,7 @@ func GenerateKeyset(master *hdkeychain.ExtendedKey, index uint32, inputFeePpk ui return &MintKeyset{ Id: keysetId, - Unit: "sat", + Unit: cashu.Sat.String(), Active: true, DerivationPathIdx: index, Keys: keys, diff --git a/mint/mint.go b/mint/mint.go index 28529e9..e46b1bf 100644 --- a/mint/mint.go +++ b/mint/mint.go @@ -40,8 +40,6 @@ import ( const ( QuoteExpiryMins = 10 - BOLT11_METHOD = "bolt11" - SAT_UNIT = "sat" ) type Mint struct { @@ -247,7 +245,7 @@ func (m *Mint) logDebugf(format string, args ...any) { // NUT-04 here: https://github.com/cashubtc/nuts/blob/main/04.md. func (m *Mint) RequestMintQuote(mintQuoteRequest nut04.PostMintQuoteBolt11Request) (storage.MintQuote, error) { // only support sat unit - if mintQuoteRequest.Unit != SAT_UNIT { + if mintQuoteRequest.Unit != cashu.Sat.String() { errmsg := fmt.Sprintf("unit '%v' not supported", mintQuoteRequest.Unit) return storage.MintQuote{}, cashu.BuildCashuError(errmsg, cashu.UnitErrCode) } @@ -492,7 +490,7 @@ func (m *Mint) Swap(proofs cashu.Proofs, blindedMessages cashu.BlindedMessages) // RequestMeltQuote will process a request to melt tokens and return a MeltQuote. // A melt is requested by a wallet to request the mint to pay an invoice. func (m *Mint) RequestMeltQuote(meltQuoteRequest nut05.PostMeltQuoteBolt11Request) (storage.MeltQuote, error) { - if meltQuoteRequest.Unit != SAT_UNIT { + if meltQuoteRequest.Unit != cashu.Sat.String() { errmsg := fmt.Sprintf("unit '%v' not supported", meltQuoteRequest.Unit) return storage.MeltQuote{}, cashu.BuildCashuError(errmsg, cashu.UnitErrCode) } @@ -1371,8 +1369,8 @@ func (m *Mint) SetMintInfo(mintInfo MintInfo) { 4: nut06.NutSetting{ Methods: []nut06.MethodSetting{ { - Method: BOLT11_METHOD, - Unit: SAT_UNIT, + Method: cashu.BOLT11_METHOD, + Unit: cashu.Sat.String(), MinAmount: m.limits.MintingSettings.MinAmount, MaxAmount: m.limits.MintingSettings.MaxAmount, }, @@ -1382,8 +1380,8 @@ func (m *Mint) SetMintInfo(mintInfo MintInfo) { 5: nut06.NutSetting{ Methods: []nut06.MethodSetting{ { - Method: BOLT11_METHOD, - Unit: SAT_UNIT, + Method: cashu.BOLT11_METHOD, + Unit: cashu.Sat.String(), MinAmount: m.limits.MeltingSettings.MinAmount, MaxAmount: m.limits.MeltingSettings.MaxAmount, }, @@ -1401,7 +1399,7 @@ func (m *Mint) SetMintInfo(mintInfo MintInfo) { info := nut06.MintInfo{ Name: mintInfo.Name, - Version: "gonuts/0.2.0", + Version: "gonuts/0.3.0", Description: mintInfo.Description, LongDescription: mintInfo.LongDescription, Contact: mintInfo.Contact, diff --git a/mint/mint_integration_test.go b/mint/mint_integration_test.go index 234513e..525988a 100644 --- a/mint/mint_integration_test.go +++ b/mint/mint_integration_test.go @@ -106,7 +106,7 @@ func testMain(m *testing.M) int { func TestRequestMintQuote(t *testing.T) { var mintAmount uint64 = 10000 - mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: cashu.Sat.String()} _, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) @@ -126,7 +126,7 @@ func TestRequestMintQuote(t *testing.T) { func TestMintQuoteState(t *testing.T) { var mintAmount uint64 = 42000 - mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: cashu.Sat.String()} mintQuoteResponse, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) @@ -189,7 +189,7 @@ func TestMintQuoteState(t *testing.T) { func TestMintTokens(t *testing.T) { var mintAmount uint64 = 42000 - mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: cashu.Sat.String()} mintQuoteResponse, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) @@ -251,7 +251,7 @@ func TestMintTokens(t *testing.T) { } // test mint with blinded messages already signed - mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: cashu.Sat.String()} mintQuoteResponse, err = testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) @@ -378,13 +378,13 @@ func TestRequestMeltQuote(t *testing.T) { } // test invalid invoice - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: "invoice1111", Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: "invoice1111", Unit: cashu.Sat.String()} _, err = testMint.RequestMeltQuote(meltQuoteRequest) if err == nil { t.Fatal("expected error but got nil") } - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} _, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -411,7 +411,7 @@ func TestMeltQuoteState(t *testing.T) { t.Fatalf("error finding invoice: %v", err) } - meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltRequest, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -472,7 +472,7 @@ func TestMelt(t *testing.T) { } paymentRequest := addInvoiceResponse.PaymentRequest - meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -535,7 +535,7 @@ func TestMelt(t *testing.T) { paymentRequest = addInvoiceResponse.PaymentRequest // test already used proofs - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} newQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -575,7 +575,7 @@ func TestMelt(t *testing.T) { } paymentRequest = addInvoiceResponse.PaymentRequest - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err = mintFees.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -614,7 +614,7 @@ func TestMelt(t *testing.T) { } paymentRequest = noRouteInvoice.PaymentRequest - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -634,7 +634,7 @@ func TestMelt(t *testing.T) { // test internal quotes (mint and melt quotes with same invoice) var mintAmount uint64 = 42000 - mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: cashu.Sat.String()} mintQuoteResponse, err := testMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) @@ -649,7 +649,7 @@ func TestMelt(t *testing.T) { meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{ Request: mintQuoteResponse.PaymentRequest, - Unit: testutils.SAT_UNIT, + Unit: cashu.Sat.String(), } meltQuote, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { @@ -687,7 +687,7 @@ func TestPendingProofs(t *testing.T) { } paymentRequest := addHodlInvoiceRes.PaymentRequest - meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -916,7 +916,7 @@ func TestMintLimits(t *testing.T) { // test above mint max amount var mintAmount uint64 = 20000 - mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: cashu.Sat.String()} mintQuoteResponse, err := limitsMint.RequestMintQuote(mintQuoteRequest) if !errors.Is(err, cashu.MintAmountExceededErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MintAmountExceededErr, err) @@ -924,7 +924,7 @@ func TestMintLimits(t *testing.T) { // amount below max limit mintAmount = 9500 - mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: testutils.SAT_UNIT} + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: mintAmount, Unit: cashu.Sat.String()} mintQuoteResponse, err = limitsMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("error requesting mint quote: %v", err) @@ -948,7 +948,7 @@ func TestMintLimits(t *testing.T) { } // test request mint that will make it go above max balance - mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: 9000, Unit: testutils.SAT_UNIT} + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: 9000, Unit: cashu.Sat.String()} mintQuoteResponse, err = limitsMint.RequestMintQuote(mintQuoteRequest) if !errors.Is(err, cashu.MintingDisabled) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MintingDisabled, err) @@ -962,7 +962,7 @@ func TestMintLimits(t *testing.T) { } paymentRequest := addInvoiceResponse.PaymentRequest - meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} _, err = limitsMint.RequestMeltQuote(meltQuoteRequest) if !errors.Is(err, cashu.MeltAmountExceededErr) { t.Fatalf("expected error '%v' but got '%v' instead", cashu.MeltAmountExceededErr, err) @@ -977,7 +977,7 @@ func TestMintLimits(t *testing.T) { } paymentRequest = addInvoiceResponse.PaymentRequest - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err := limitsMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -990,7 +990,7 @@ func TestMintLimits(t *testing.T) { } // this should be within max balance now - mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: 9000, Unit: testutils.SAT_UNIT} + mintQuoteRequest = nut04.PostMintQuoteBolt11Request{Amount: 9000, Unit: cashu.Sat.String()} mintQuoteResponse, err = limitsMint.RequestMintQuote(mintQuoteRequest) if err != nil { t.Fatalf("got unexpected error requesting mint quote: %v", err) @@ -1158,7 +1158,7 @@ func TestNUT11P2PK(t *testing.T) { } paymentRequest := addInvoiceResponse.PaymentRequest - meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err := p2pkMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -1195,7 +1195,7 @@ func TestNUT11P2PK(t *testing.T) { } paymentRequest = addInvoiceResponse.PaymentRequest - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err = p2pkMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -1449,7 +1449,7 @@ func TestHTLC(t *testing.T) { } paymentRequest := addInvoiceResponse.PaymentRequest - meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest := nut05.PostMeltQuoteBolt11Request{Request: paymentRequest, Unit: cashu.Sat.String()} meltQuote, err := testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) @@ -1488,7 +1488,7 @@ func TestHTLC(t *testing.T) { if err != nil { t.Fatalf("error creating invoice: %v", err) } - meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: addInvoiceResponse.PaymentRequest, Unit: testutils.SAT_UNIT} + meltQuoteRequest = nut05.PostMeltQuoteBolt11Request{Request: addInvoiceResponse.PaymentRequest, Unit: cashu.Sat.String()} meltQuote, err = testMint.RequestMeltQuote(meltQuoteRequest) if err != nil { t.Fatalf("got unexpected error in melt request: %v", err) diff --git a/mint/server.go b/mint/server.go index 5bbff59..0d35fe2 100644 --- a/mint/server.go +++ b/mint/server.go @@ -200,7 +200,7 @@ func (ms *MintServer) getKeysetById(rw http.ResponseWriter, req *http.Request) { func (ms *MintServer) mintRequest(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - if method != BOLT11_METHOD { + if method != cashu.BOLT11_METHOD { ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) return } @@ -248,7 +248,7 @@ func (ms *MintServer) mintRequest(rw http.ResponseWriter, req *http.Request) { func (ms *MintServer) mintQuoteState(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - if method != BOLT11_METHOD { + if method != cashu.BOLT11_METHOD { ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) return } @@ -291,7 +291,7 @@ func (ms *MintServer) mintQuoteState(rw http.ResponseWriter, req *http.Request) func (ms *MintServer) mintTokensRequest(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - if method != BOLT11_METHOD { + if method != cashu.BOLT11_METHOD { ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) return } @@ -366,7 +366,7 @@ func (ms *MintServer) swapRequest(rw http.ResponseWriter, req *http.Request) { func (ms *MintServer) meltQuoteRequest(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - if method != BOLT11_METHOD { + if method != cashu.BOLT11_METHOD { ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) return } @@ -415,7 +415,7 @@ func (ms *MintServer) meltQuoteRequest(rw http.ResponseWriter, req *http.Request func (ms *MintServer) meltQuoteState(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - if method != BOLT11_METHOD { + if method != cashu.BOLT11_METHOD { ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) return } @@ -463,7 +463,7 @@ func (ms *MintServer) meltQuoteState(rw http.ResponseWriter, req *http.Request) func (ms *MintServer) meltTokens(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) method := vars["method"] - if method != BOLT11_METHOD { + if method != cashu.BOLT11_METHOD { ms.writeErr(rw, req, cashu.PaymentMethodNotSupportedErr) return } diff --git a/testutils/utils.go b/testutils/utils.go index 069f35b..f76d4be 100644 --- a/testutils/utils.go +++ b/testutils/utils.go @@ -37,9 +37,7 @@ import ( ) const ( - NUM_BLOCKS int64 = 110 - BOLT11_METHOD = "bolt11" - SAT_UNIT = "sat" + NUM_BLOCKS int64 = 110 ) func MineBlocks(bitcoind *btcdocker.Bitcoind, numBlocks int64) error { @@ -393,7 +391,7 @@ func GetBlindedSignatures(amount uint64, mint *mint.Mint, payer *btcdocker.Lnd) cashu.BlindedSignatures, error) { - mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: SAT_UNIT} + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: cashu.Sat.String()} mintQuoteResponse, err := mint.RequestMintQuote(mintQuoteRequest) if err != nil { return nil, nil, nil, nil, fmt.Errorf("error requesting mint quote: %v", err) @@ -486,7 +484,7 @@ func GetProofsWithSpendingCondition( mint *mint.Mint, payer *btcdocker.Lnd, ) (cashu.Proofs, error) { - mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: SAT_UNIT} + mintQuoteRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: cashu.Sat.String()} mintQuoteResponse, err := mint.RequestMintQuote(mintQuoteRequest) if err != nil { return nil, fmt.Errorf("error requesting mint quote: %v", err) diff --git a/wallet/wallet.go b/wallet/wallet.go index 1fa76e1..8f2f2f3 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -132,7 +132,7 @@ func LoadWallet(config Config) (*Wallet, error) { var lastActiveSatKeyset crypto.WalletKeyset for _, keyset := range walletMint.activeKeysets { _, err := hex.DecodeString(keyset.Id) - if keyset.Unit == "sat" && err == nil { + if keyset.Unit == cashu.Sat.String() && err == nil { lastActiveSatKeyset = keyset break } @@ -244,7 +244,7 @@ func GetMintActiveKeysets(mintURL string) (map[string]crypto.WalletKeyset, error } _, err := hex.DecodeString(keyset.Id) - if keyset.Unit == "sat" && err == nil { + if keyset.Unit == cashu.Sat.String() && err == nil { keys, err := crypto.MapPubKeys(keysetsResponse.Keysets[i].Keys) if err != nil { return nil, err @@ -278,7 +278,7 @@ func GetMintInactiveKeysets(mintURL string) (map[string]crypto.WalletKeyset, err inactiveKeysets := make(map[string]crypto.WalletKeyset) for _, keysetRes := range keysetsResponse.Keysets { _, err := hex.DecodeString(keysetRes.Id) - if !keysetRes.Active && keysetRes.Unit == "sat" && err == nil { + if !keysetRes.Active && keysetRes.Unit == cashu.Sat.String() && err == nil { keyset := crypto.WalletKeyset{ Id: keysetRes.Id, MintURL: mintURL, @@ -335,7 +335,7 @@ func amount(proofs []storage.DBProof) uint64 { // RequestMint requests a mint quote to the wallet's current mint // for the specified amount func (w *Wallet) RequestMint(amount uint64) (*nut04.PostMintQuoteBolt11Response, error) { - mintRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: "sat"} + mintRequest := nut04.PostMintQuoteBolt11Request{Amount: amount, Unit: cashu.Sat.String()} mintResponse, err := PostMintQuoteBolt11(w.currentMint.mintURL, mintRequest) if err != nil { return nil, err @@ -813,7 +813,7 @@ func (w *Wallet) swapToTrusted(proofs cashu.Proofs, mintFromProofs string) (uint // request melt quote from untrusted mint which will // request mint to pay invoice generated from trusted mint in previous mint request - meltRequest := nut05.PostMeltQuoteBolt11Request{Request: mintResponse.Request, Unit: "sat"} + meltRequest := nut05.PostMeltQuoteBolt11Request{Request: mintResponse.Request, Unit: cashu.Sat.String()} meltQuoteResponse, err = PostMeltQuoteBolt11(mintFromProofs, meltRequest) if err != nil { return 0, fmt.Errorf("error with melt request: %v", err) @@ -918,7 +918,7 @@ func (w *Wallet) Melt(invoice, mintURL string) (*nut05.PostMeltQuoteBolt11Respon return nil, fmt.Errorf("error decoding invoice: %v", err) } - meltRequest := nut05.PostMeltQuoteBolt11Request{Request: invoice, Unit: "sat"} + meltRequest := nut05.PostMeltQuoteBolt11Request{Request: invoice, Unit: cashu.Sat.String()} meltQuoteResponse, err := PostMeltQuoteBolt11(mintURL, meltRequest) if err != nil { return nil, err @@ -1639,7 +1639,7 @@ func (w *Wallet) getActiveSatKeyset(mintURL string) (*crypto.WalletKeyset, error for _, keyset := range allKeysets.Keysets { _, err = hex.DecodeString(keyset.Id) - if keyset.Active && keyset.Unit == "sat" && err == nil { + if keyset.Active && keyset.Unit == cashu.Sat.String() && err == nil { keysetKeys, err := GetKeysetById(mintURL, keyset.Id) if err != nil { return nil, err @@ -1715,7 +1715,7 @@ func getKeysetKeys(mintURL, id string) (map[uint64]*secp256k1.PublicKey, error) } var keys map[uint64]*secp256k1.PublicKey - if len(keysetsResponse.Keysets) > 0 && keysetsResponse.Keysets[0].Unit == "sat" { + if len(keysetsResponse.Keysets) > 0 && keysetsResponse.Keysets[0].Unit == cashu.Sat.String() { var err error keys, err = crypto.MapPubKeys(keysetsResponse.Keysets[0].Keys) if err != nil { @@ -1802,7 +1802,7 @@ func Restore(walletPath, mnemonic string, mintsToRestore []string) (cashu.Proofs } for _, keyset := range keysetsResponse.Keysets { - if keyset.Unit != "sat" { + if keyset.Unit != cashu.Sat.String() { break } diff --git a/wallet/wallet_integration_test.go b/wallet/wallet_integration_test.go index 624cb80..7208ff3 100644 --- a/wallet/wallet_integration_test.go +++ b/wallet/wallet_integration_test.go @@ -290,7 +290,7 @@ func TestReceive(t *testing.T) { if err != nil { t.Fatalf("got unexpected error in send: %v", err) } - token, _ := cashu.NewTokenV4(proofsToSend, mint2URL, testutils.SAT_UNIT, false) + token, _ := cashu.NewTokenV4(proofsToSend, mint2URL, cashu.Sat, false) // test receive swap == true _, err = testWallet.Receive(token, true) @@ -311,7 +311,7 @@ func TestReceive(t *testing.T) { if err != nil { t.Fatalf("got unexpected error in send: %v", err) } - token, _ = cashu.NewTokenV4(proofsToSend, mint2URL, testutils.SAT_UNIT, false) + token, _ = cashu.NewTokenV4(proofsToSend, mint2URL, cashu.Sat, false) // test receive swap == false _, err = testWallet.Receive(token, false) @@ -360,7 +360,7 @@ func TestReceiveFees(t *testing.T) { if err != nil { t.Fatalf("got unexpected error in send: %v", err) } - token, _ := cashu.NewTokenV4(proofsToSend, mintURL, testutils.SAT_UNIT, false) + token, _ := cashu.NewTokenV4(proofsToSend, mintURL, cashu.Sat, false) amountReceived, err := testWallet2.Receive(token, false) if err != nil { @@ -562,7 +562,7 @@ func TestWalletBalanceFees(t *testing.T) { if err != nil { t.Fatalf("unexpected error in send: %v", err) } - token, _ := cashu.NewTokenV4(proofsToSend, mintURL, testutils.SAT_UNIT, false) + token, _ := cashu.NewTokenV4(proofsToSend, mintURL, cashu.Sat, false) // test balance in receiving wallet balanceBeforeReceive := balanceTestWallet2.GetBalance() @@ -582,7 +582,7 @@ func TestWalletBalanceFees(t *testing.T) { if err != nil { t.Fatalf("unexpected error in send: %v", err) } - token, _ := cashu.NewTokenV4(proofsToSend, mintURL, testutils.SAT_UNIT, false) + token, _ := cashu.NewTokenV4(proofsToSend, mintURL, cashu.Sat, false) fees, err := testutils.Fees(proofsToSend, mintURL) if err != nil { @@ -806,7 +806,7 @@ func testWalletRestore( if err != nil { t.Fatalf("unexpected error in send: %v", err) } - token, _ := cashu.NewTokenV4(proofsToSend, mintURL, testutils.SAT_UNIT, false) + token, _ := cashu.NewTokenV4(proofsToSend, mintURL, cashu.Sat, false) _, err = testWallet2.Receive(token, false) if err != nil { @@ -818,7 +818,7 @@ func testWalletRestore( if err != nil { t.Fatalf("unexpected error in send: %v", err) } - token, _ = cashu.NewTokenV4(proofsToSend, mintURL, testutils.SAT_UNIT, false) + token, _ = cashu.NewTokenV4(proofsToSend, mintURL, cashu.Sat, false) _, err = testWallet2.Receive(token, false) if err != nil { @@ -882,7 +882,7 @@ func TestHTLC(t *testing.T) { if err != nil { t.Fatalf("unexpected error generating ecash HTLC: %v", err) } - lockedEcash, _ := cashu.NewTokenV4(htlcLockedProofs, testWallet.CurrentMint(), testutils.SAT_UNIT, false) + lockedEcash, _ := cashu.NewTokenV4(htlcLockedProofs, testWallet.CurrentMint(), cashu.Sat, false) amountReceived, err := testWallet2.ReceiveHTLC(lockedEcash, preimage) if err != nil { @@ -903,7 +903,7 @@ func TestHTLC(t *testing.T) { if err != nil { t.Fatalf("unexpected error generating ecash HTLC: %v", err) } - lockedEcash, _ = cashu.NewTokenV4(htlcLockedProofs, testWallet.CurrentMint(), testutils.SAT_UNIT, false) + lockedEcash, _ = cashu.NewTokenV4(htlcLockedProofs, testWallet.CurrentMint(), cashu.Sat, false) amountReceived, err = testWallet2.ReceiveHTLC(lockedEcash, preimage) if err != nil { @@ -997,7 +997,7 @@ func testP2PK( if err != nil { t.Fatalf("unexpected error generating locked ecash: %v", err) } - lockedEcash, _ := cashu.NewTokenV4(lockedProofs, testWallet.CurrentMint(), testutils.SAT_UNIT, false) + lockedEcash, _ := cashu.NewTokenV4(lockedProofs, testWallet.CurrentMint(), cashu.Sat, false) // try receiving invalid _, err = testWallet.Receive(lockedEcash, true) @@ -1025,7 +1025,7 @@ func testP2PK( if err != nil { t.Fatalf("unexpected error generating locked ecash: %v", err) } - lockedEcash, _ = cashu.NewTokenV4(lockedProofs, testWallet.CurrentMint(), testutils.SAT_UNIT, false) + lockedEcash, _ = cashu.NewTokenV4(lockedProofs, testWallet.CurrentMint(), cashu.Sat, false) // unlock ecash and trust mint amountReceived, err = testWallet2.Receive(lockedEcash, false) @@ -1133,7 +1133,7 @@ func TestNutshell(t *testing.T) { if err != nil { t.Fatalf("got unexpected error: %v", err) } - token, _ := cashu.NewTokenV4(proofsToSend, nutshellURL, testutils.SAT_UNIT, false) + token, _ := cashu.NewTokenV4(proofsToSend, nutshellURL, cashu.Sat, false) fees, _ := testutils.Fees(proofsToSend, nutshellURL) if proofsToSend.Amount() != sendAmount+uint64(fees) { @@ -1213,7 +1213,7 @@ func TestOverpaidFeesChange(t *testing.T) { if err != nil { t.Fatalf("got unexpected error: %v", err) } - token, _ := cashu.NewTokenV4(proofsToSend, nutshellURL, testutils.SAT_UNIT, false) + token, _ := cashu.NewTokenV4(proofsToSend, nutshellURL, cashu.Sat, false) _, err = testWallet.Receive(token, false) if err != nil { t.Fatalf("unexpected error receiving: %v", err)