Skip to content

Commit

Permalink
nut04 state changes
Browse files Browse the repository at this point in the history
  • Loading branch information
elnosh committed Jul 2, 2024
1 parent 915c83c commit 3db134a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 18 deletions.
84 changes: 82 additions & 2 deletions cashu/nuts/nut04/nut04.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,50 @@
// [NUT-04]: https://github.com/cashubtc/nuts/blob/main/04.md
package nut04

import "github.com/elnosh/gonuts/cashu"
import (
"encoding/json"

"github.com/elnosh/gonuts/cashu"
)

type State int

const (
Unpaid State = iota
Paid
Pending
Issued
Unknown
)

func (state State) String() string {
switch state {
case Unpaid:
return "UNPAID"
case Paid:
return "PAID"
case Pending:
return "PENDING"
case Issued:
return "ISSUED"
default:
return "unknown"
}
}

func StringToState(state string) State {
switch state {
case "UNPAID":
return Unpaid
case "PAID":
return Paid
case "PENDING":
return Pending
case "ISSUED":
return Issued
}
return Unknown
}

type PostMintQuoteBolt11Request struct {
Amount uint64 `json:"amount"`
Expand All @@ -13,7 +56,8 @@ type PostMintQuoteBolt11Request struct {
type PostMintQuoteBolt11Response struct {
Quote string `json:"quote"`
Request string `json:"request"`
Paid bool `json:"paid"`
State State `json:"state"`
Paid bool `json:"paid"` // DEPRECATED: use State instead
Expiry int64 `json:"expiry"`
}

Expand All @@ -25,3 +69,39 @@ type PostMintBolt11Request struct {
type PostMintBolt11Response struct {
Signatures cashu.BlindedSignatures `json:"signatures"`
}

type TempQuote struct {
Quote string `json:"quote"`
Request string `json:"request"`
State string `json:"state"`
Paid bool `json:"paid"` // DEPRECATED: use State instead
Expiry int64 `json:"expiry"`
}

func (quoteResponse *PostMintQuoteBolt11Response) MarshalJSON() ([]byte, error) {
var tempQuote = TempQuote{
Quote: quoteResponse.Quote,
Request: quoteResponse.Request,
State: quoteResponse.State.String(),
Paid: quoteResponse.Paid,
Expiry: quoteResponse.Expiry,
}
return json.Marshal(tempQuote)
}

func (quoteResponse *PostMintQuoteBolt11Response) UnmarshalJSON(data []byte) error {
tempQuote := &TempQuote{}

if err := json.Unmarshal(data, tempQuote); err != nil {
return err
}

quoteResponse.Quote = tempQuote.Quote
quoteResponse.Request = tempQuote.Request
state := StringToState(tempQuote.State)
quoteResponse.State = state
quoteResponse.Paid = tempQuote.Paid
quoteResponse.Expiry = tempQuote.Expiry

return nil
}
14 changes: 11 additions & 3 deletions mint/mint.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ func (m *Mint) RequestMintQuote(method string, amount uint64, unit string) (nut0
reqMintQuoteResponse := nut04.PostMintQuoteBolt11Response{
Quote: invoice.Id,
Request: invoice.PaymentRequest,
Paid: invoice.Settled,
State: nut04.Unpaid,
Paid: invoice.Settled, // DEPRECATED: remove after wallets have upgraded
Expiry: invoice.Expiry,
}

Expand All @@ -143,15 +144,22 @@ func (m *Mint) GetMintQuoteState(method, quoteId string) (nut04.PostMintQuoteBol
msg := fmt.Sprintf("error getting invoice status: %v", err)
return nut04.PostMintQuoteBolt11Response{}, cashu.BuildCashuError(msg, cashu.InvoiceErrCode)
}
if status.Settled && status.Settled != invoice.Settled {

state := nut04.Unpaid
if status.Settled {
invoice.Settled = status.Settled
state = nut04.Paid
if invoice.Redeemed {
state = nut04.Issued
}
m.db.SaveInvoice(*invoice)
}

quoteState := nut04.PostMintQuoteBolt11Response{
Quote: invoice.Id,
Request: invoice.PaymentRequest,
Paid: invoice.Settled,
State: state,
Paid: invoice.Settled, // DEPRECATED: remove after wallets have upgraded
Expiry: invoice.Expiry,
}
return quoteState, nil
Expand Down
4 changes: 2 additions & 2 deletions mint/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func (ms *MintServer) mintRequest(rw http.ResponseWriter, req *http.Request) {
return
}

jsonRes, err := json.Marshal(reqMintResponse)
jsonRes, err := json.Marshal(&reqMintResponse)
if err != nil {
ms.writeErr(rw, req, cashu.StandardErr)
return
Expand All @@ -244,7 +244,7 @@ func (ms *MintServer) mintQuoteState(rw http.ResponseWriter, req *http.Request)
ms.writeErr(rw, req, err)
return
}
jsonRes, err := json.Marshal(mintQuoteStateResponse)
jsonRes, err := json.Marshal(&mintQuoteStateResponse)
if err != nil {
ms.writeErr(rw, req, cashu.StandardErr)
return
Expand Down
13 changes: 2 additions & 11 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,6 @@ func (w *Wallet) RequestMint(amount uint64) (*nut04.PostMintQuoteBolt11Response,
return mintResponse, nil
}

// CheckQuotePaid reports whether the mint quote has been paid
func (w *Wallet) CheckQuotePaid(quoteId string) bool {
mintQuote, err := GetMintQuoteState(w.currentMint.mintURL, quoteId)
if err != nil {
return false
}

return mintQuote.Paid
}

// MintTokens will check whether if the mint quote has been paid.
// If yes, it will create blinded messages that will send to the mint
// to get the blinded signatures.
Expand All @@ -330,7 +320,8 @@ func (w *Wallet) MintTokens(quoteId string) (cashu.Proofs, error) {
if err != nil {
return nil, err
}
if !mintQuote.Paid {
// TODO: remove usage of 'Paid' field after mints have upgraded
if !mintQuote.Paid || mintQuote.State == nut04.Unpaid {
return nil, errors.New("invoice not paid")
}

Expand Down

0 comments on commit 3db134a

Please sign in to comment.