Skip to content

Commit

Permalink
define sat unit in cashu package
Browse files Browse the repository at this point in the history
  • Loading branch information
elnosh committed Oct 30, 2024
1 parent b598a16 commit 0afd1b7
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 73 deletions.
34 changes: 30 additions & 4 deletions cashu/cashu.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/nutw/nutw.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
3 changes: 2 additions & 1 deletion crypto/keyset.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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,
Expand Down
16 changes: 7 additions & 9 deletions mint/mint.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ import (

const (
QuoteExpiryMins = 10
BOLT11_METHOD = "bolt11"
SAT_UNIT = "sat"
)

type Mint struct {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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,
},
Expand All @@ -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,
},
Expand All @@ -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,
Expand Down
48 changes: 24 additions & 24 deletions mint/mint_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -916,15 +916,15 @@ 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)
}

// 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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 0afd1b7

Please sign in to comment.