diff --git a/go.mod b/go.mod index 0cc9c7f..5202a7f 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 github.com/dgraph-io/badger/v4 v4.5.0 github.com/dgraph-io/ristretto v1.0.0 - github.com/elnosh/gonuts v0.3.1-0.20250123162555-7c0381a585e3 + github.com/elnosh/gonuts v0.4.2 github.com/fasthttp/websocket v1.5.12 github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 github.com/json-iterator/go v1.1.12 diff --git a/go.sum b/go.sum index ee7fccf..1a1fdb9 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,8 @@ github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fp github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= -github.com/elnosh/gonuts v0.3.1-0.20250123162555-7c0381a585e3 h1:k7evIqJ2BtFn191DgY/b03N2bMYA/iQwzr4f/uHYn20= -github.com/elnosh/gonuts v0.3.1-0.20250123162555-7c0381a585e3/go.mod h1:vgZomh4YQk7R3w4ltZc0sHwCmndfHkuX6V4sga/8oNs= +github.com/elnosh/gonuts v0.4.2 h1:/WubPAWGxTE+okJ0WPvmtEzTzpi04RGxiTHAF1FYU+M= +github.com/elnosh/gonuts v0.4.2/go.mod h1:vgZomh4YQk7R3w4ltZc0sHwCmndfHkuX6V4sga/8oNs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= diff --git a/nip60/swap.go b/nip60/swap.go index 3831e1e..1d67ae2 100644 --- a/nip60/swap.go +++ b/nip60/swap.go @@ -11,6 +11,7 @@ import ( "github.com/elnosh/gonuts/cashu/nuts/nut02" "github.com/elnosh/gonuts/cashu/nuts/nut03" "github.com/elnosh/gonuts/cashu/nuts/nut10" + "github.com/elnosh/gonuts/cashu/nuts/nut13" ) type swapSettings struct { @@ -25,10 +26,33 @@ func (w *Wallet) swapProofs( targetAmount uint64, ss swapSettings, ) (principal cashu.Proofs, change cashu.Proofs, err error) { + keysetIdList := []string{} + for i := range w.Mints { + if w.Mints[i] != mint { + keysets, err := client.GetAllKeysets(ctx, w.Mints[i]) + if err != nil { + return nil, nil, fmt.Errorf("could not get keysets for all previous keysets %s: %w", w.Mints[i], err) + } + + for j := range keysets { + keysetIdList = append(keysetIdList, keysets[j].Id) + } + } + } + keysets, err := client.GetAllKeysets(ctx, mint) if err != nil { return nil, nil, fmt.Errorf("failed to get all keysets for %s: %w", mint, err) } + + for j := range keysets { + err := nut13.CheckCollidingKeysets(keysetIdList, []string{keysets[j].Id}) + if err != nil { + return nil, nil, fmt.Errorf("encountered keyset collition for mint %s: %w", mint, err) + } + keysetIdList = append(keysetIdList, keysets[j].Id) + } + activeKeyset, err := client.GetActiveKeyset(ctx, mint) if err != nil { return nil, nil, fmt.Errorf("failed to get active keyset for %s: %w", mint, err) diff --git a/nip60/wallet.go b/nip60/wallet.go index af2f501..d70ed77 100644 --- a/nip60/wallet.go +++ b/nip60/wallet.go @@ -12,6 +12,8 @@ import ( "fiatjaf.com/nostr" "github.com/btcsuite/btcd/btcec/v2" "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/elnosh/gonuts/cashu/nuts/nut13" + "fiatjaf.com/nostr/nip60/client" ) // WalletOptions contains options for loading a wallet @@ -257,6 +259,18 @@ func (w *Wallet) AddMint(ctx context.Context, urls ...string) error { return fmt.Errorf("can't do write operations: missing PublishUpdate function") } + keysetIdList := []string{} + for i := range w.Mints { + keysets, err := client.GetAllKeysets(ctx, w.Mints[i]) + if err != nil { + return err + } + + for j := range keysets { + keysetIdList = append(keysetIdList, keysets[j].Id) + } + } + for _, url := range urls { url, err := nostr.NormalizeHTTPURL(url) if err != nil { @@ -264,6 +278,18 @@ func (w *Wallet) AddMint(ctx context.Context, urls ...string) error { } if !slices.Contains(w.Mints, url) { + keysets, err := client.GetAllKeysets(ctx, url) + if err != nil { + return err + } + + for j := range keysets { + err = nut13.CheckCollidingKeysets(keysetIdList, []string{keysets[j].Id}) + if err != nil { + return err + } + keysetIdList = append(keysetIdList, keysets[j].Id) + } w.Mints = append(w.Mints, url) } }