From 7b83cd3d19c2f2f30a477ff17704e92a53112bde Mon Sep 17 00:00:00 2001 From: d4rp4t Date: Tue, 21 Apr 2026 12:11:37 +0200 Subject: [PATCH 1/3] feat: json v2 renderer --- go.mod | 3 ++- go.sum | 2 ++ internal/utils/json_renderer.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 internal/utils/json_renderer.go diff --git a/go.mod b/go.mod index 2ad7cb88..c74baace 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/lescuer97/nutmix -go 1.25.4 +go 1.26 require ( github.com/BurntSushi/toml v1.5.0 @@ -91,6 +91,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.11 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-jose/go-jose/v4 v4.1.3 // indirect + github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-macaroon-bakery/macaroonpb v1.0.0 // indirect diff --git a/go.sum b/go.sum index 091c1083..9410e519 100644 --- a/go.sum +++ b/go.sum @@ -193,6 +193,8 @@ github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 h1:vymEbVwYFP/L05h5TKQxvkXoKxNvTpjxYKdF1Nlwuao= +github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= diff --git a/internal/utils/json_renderer.go b/internal/utils/json_renderer.go new file mode 100644 index 00000000..6330af83 --- /dev/null +++ b/internal/utils/json_renderer.go @@ -0,0 +1,28 @@ +package utils + +import ( + "net/http" + + "github.com/gin-gonic/gin/render" + jsonv2 "github.com/go-json-experiment/json" +) + +type JSONV2 struct { + Data any +} + +func (r JSONV2) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + bytes, err := jsonv2.Marshal(r.Data) + if err != nil { + return err + } + _, err = w.Write(bytes) + return err +} + +func (r JSONV2) WriteContentType(w http.ResponseWriter) { + w.Header().Set("Content-Type", "application/json; charset=utf-8") +} + +var _ render.Render = JSONV2{} From 070acd623ca58f3ea284e4f7029fc253e3ef2c20 Mon Sep 17 00:00:00 2001 From: d4rp4t Date: Wed, 6 May 2026 01:31:50 +0200 Subject: [PATCH 2/3] chore: add jsonv2 decoder from gin context --- internal/utils/{json_renderer.go => json.go} | 9 +++++++++ 1 file changed, 9 insertions(+) rename internal/utils/{json_renderer.go => json.go} (66%) diff --git a/internal/utils/json_renderer.go b/internal/utils/json.go similarity index 66% rename from internal/utils/json_renderer.go rename to internal/utils/json.go index 6330af83..a5ef84cc 100644 --- a/internal/utils/json_renderer.go +++ b/internal/utils/json.go @@ -3,6 +3,7 @@ package utils import ( "net/http" + "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/render" jsonv2 "github.com/go-json-experiment/json" ) @@ -26,3 +27,11 @@ func (r JSONV2) WriteContentType(w http.ResponseWriter) { } var _ render.Render = JSONV2{} + +func JSON(c *gin.Context, code int, data any) { + c.Render(code, JSONV2{Data: data}) +} + +func DecodeJSONV2(c *gin.Context, out any) error { + return jsonv2.UnmarshalRead(c.Request.Body, out, jsonv2.RejectUnknownMembers(true)) +} From 4bd81018ba8d8dbe45de5f76bd161ad1e1c8222b Mon Sep 17 00:00:00 2001 From: d4rp4t Date: Wed, 6 May 2026 01:35:34 +0200 Subject: [PATCH 3/3] refactor(json): unify routes on utils.JSON and strict DecodeJSONV2 --- internal/routes/admin/auth.go | 8 +- internal/routes/admin/keysets.go | 11 ++- internal/routes/auth.go | 30 ++++---- internal/routes/bolt11.go | 114 ++++++++++++++--------------- internal/routes/middleware/auth.go | 13 ++-- internal/routes/mint.go | 70 +++++++++--------- 6 files changed, 123 insertions(+), 123 deletions(-) diff --git a/internal/routes/admin/auth.go b/internal/routes/admin/auth.go index b5b6af9e..5dda0eac 100644 --- a/internal/routes/admin/auth.go +++ b/internal/routes/admin/auth.go @@ -101,13 +101,13 @@ func LoginPost(mint *mint.Mint, loginKey *secp256k1.PrivateKey, adminNostrPubkey // parse data for login slog.Debug("Attempting log in") var nostrEvent nostr.Event - err := c.BindJSON(&nostrEvent) + err := utils.DecodeJSONV2(c, &nostrEvent) if err != nil { slog.Debug( "Incorrect body", slog.String(utils.LogExtraInfo, err.Error()), ) - c.JSON(400, "Malformed body request") + utils.JSON(c, 400, "Malformed body request") return } ctx := c.Request.Context() @@ -149,7 +149,7 @@ func LoginPost(mint *mint.Mint, loginKey *secp256k1.PrivateKey, adminNostrPubkey } if nostrLogin.Activated { - c.JSON(403, "This login value was already used, please reload the page") + utils.JSON(c, 403, "This login value was already used, please reload the page") return } @@ -200,7 +200,7 @@ func LoginPost(mint *mint.Mint, loginKey *secp256k1.PrivateKey, adminNostrPubkey c.SetCookie(AdminAuthKey, token, 3600, "/", "", false, true) c.Header("HX-Redirect", "/admin") - c.JSON(200, nil) + utils.JSON(c, 200, nil) } } diff --git a/internal/routes/admin/keysets.go b/internal/routes/admin/keysets.go index edf0c68f..fdf9df50 100644 --- a/internal/routes/admin/keysets.go +++ b/internal/routes/admin/keysets.go @@ -65,12 +65,11 @@ func RotateSatsSeed(adminHandler *adminHandler) gin.HandlerFunc { return func(c *gin.Context) { var rotateRequest RotateRequest if c.ContentType() == gin.MIMEJSON { - // Use Decode instead of BindJSON to have more control if needed, - // but BindJSON calls UnmarshalJSON which we defined. - err := c.BindJSON(&rotateRequest) + // JSON requests are decoded with strict unknown-field rejection. + err := utils.DecodeJSONV2(c, &rotateRequest) if err != nil { - slog.Error("BindJSON error", slog.Any("error", err)) - c.JSON(400, nil) + slog.Error("DecodeJSONV2 error", slog.Any("error", err)) + utils.JSON(c, 400, nil) return } } else { @@ -140,7 +139,7 @@ func RotateSatsSeed(adminHandler *adminHandler) gin.HandlerFunc { } if c.ContentType() == gin.MIMEJSON { - c.JSON(200, nil) + utils.JSON(c, 200, nil) } else { c.Header("HX-Trigger", "recharge-keyset") diff --git a/internal/routes/auth.go b/internal/routes/auth.go index 20b02539..d0d0e1a6 100644 --- a/internal/routes/auth.go +++ b/internal/routes/auth.go @@ -16,7 +16,7 @@ func AuthActivatedMiddleware(mint *m.Mint) gin.HandlerFunc { if !mint.Config.MINT_REQUIRE_AUTH { slog.Warn(fmt.Errorf("tried using route that does not exist because auth not being active").Error()) - c.JSON(404, "route does not exists") + utils.JSON(c, 404, "route does not exists") c.Abort() return } @@ -33,11 +33,11 @@ func v1AuthRoutes(r *gin.Engine, mint *m.Mint) { keys, err := mint.Signer.GetAuthActiveKeys() if err != nil { slog.Warn("mint.Signer.GetAuthActiveKeys()", slog.Any("error", err)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) return } - c.JSON(200, keys) + utils.JSON(c, 200, keys) }) auth.GET("/blind/keys/:id", func(c *gin.Context) { @@ -47,30 +47,30 @@ func v1AuthRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.Signer.GetAuthKeysById(id)", slog.Any("error", err)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) return } - c.JSON(200, keysets) + utils.JSON(c, 200, keysets) }) auth.GET("/blind/keysets", func(c *gin.Context) { keys, err := mint.Signer.GetAuthKeys() if err != nil { slog.Error("mint.Signer.GetAuthKeys()", slog.Any("error", err)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) return } - c.JSON(200, keys) + utils.JSON(c, 200, keys) }) auth.POST("/blind/mint", func(c *gin.Context) { var mintRequest cashu.PostMintBolt11Request - err := c.BindJSON(&mintRequest) + err := utils.DecodeJSONV2(c, &mintRequest) if err != nil { slog.Info("Incorrect body", slog.Any("error", err)) - c.JSON(400, "Malformed body request") + utils.JSON(c, 400, "Malformed body request") return } @@ -92,20 +92,20 @@ func v1AuthRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error("mint.Signer.GetKeys()", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } unit, err := mint.VerifyOutputs(tx, mintRequest.Outputs, keysets.Keysets) if err != nil { slog.Warn("mint.VerifyOutputs(mintRequest.Outputs)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } if unit != cashu.AUTH { details := `You can only use "auth" tokens in this endpoint` - c.JSON(400, cashu.ErrorCodeToResponse(cashu.UNIT_NOT_SUPPORTED, &details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.UNIT_NOT_SUPPORTED, &details)) return } @@ -118,7 +118,7 @@ func v1AuthRoutes(r *gin.Engine, mint *m.Mint) { if amountBlindMessages > mint.Config.MINT_AUTH_MAX_BLIND_TOKENS { slog.Warn("Trying to mint auth tokens over the limit") - c.JSON(400, cashu.ErrorCodeToResponse(cashu.MAXIMUM_BAT_MINT_LIMIT_EXCEEDED, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.MAXIMUM_BAT_MINT_LIMIT_EXCEEDED, nil)) return } @@ -126,7 +126,7 @@ func v1AuthRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.Signer.SignBlindMessages(mintRequest.Outputs)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -143,7 +143,7 @@ func v1AuthRoutes(r *gin.Engine, mint *m.Mint) { return } - c.JSON(200, cashu.PostMintBolt11Response{ + utils.JSON(c, 200, cashu.PostMintBolt11Response{ Signatures: blindedSignatures, }) }) diff --git a/internal/routes/bolt11.go b/internal/routes/bolt11.go index f7f41526..d3b26e6c 100644 --- a/internal/routes/bolt11.go +++ b/internal/routes/bolt11.go @@ -22,23 +22,23 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { v1.POST("/mint/quote/bolt11", func(c *gin.Context) { var mintRequest cashu.PostMintQuoteBolt11Request - err := c.BindJSON(&mintRequest) + err := utils.DecodeJSONV2(c, &mintRequest) if err != nil { slog.Info("Incorrect body", slog.Any("error", err)) - c.JSON(400, "Malformed body request") + utils.JSON(c, 400, "Malformed body request") return } if mintRequest.Amount == 0 { slog.Info("Amount missing") - c.JSON(400, "Amount missing") + utils.JSON(c, 400, "Amount missing") return } if mint.Config.PEG_OUT_ONLY { slog.Info("Peg out only enables") - c.JSON(400, cashu.ErrorCodeToResponse(cashu.MINTING_DISABLED, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.MINTING_DISABLED, nil)) return } @@ -46,7 +46,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if mintRequest.Amount > uint64(*mint.Config.PEG_IN_LIMIT_SATS) { slog.Info("Mint amount over the limit", slog.Uint64("amount", mintRequest.Amount)) - c.JSON(400, "Mint amount over the limit") + utils.JSON(c, 400, "Mint amount over the limit") return } @@ -56,7 +56,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.VerifyUnitSupport(mintRequest.Unit)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -72,14 +72,14 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("cashu.UnitFromString(mintRequest.Unit)", slog.Any("error", err), slog.Any("err", cashu.ErrUnitNotSupported)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } quoteId, err := utils.RandomHash() if err != nil { slog.Info("utils.RandomHash()", slog.Uint64("amount", mintRequest.Amount)) - c.JSON(500, "Opps! there was a problem with the mint") + utils.JSON(c, 500, "Opps! there was a problem with the mint") return } @@ -100,13 +100,13 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { resInvoice, err := mint.LightningBackend.RequestInvoice(mintRequestDB, cashu.NewAmount(unit, mintRequest.Amount)) if err != nil { slog.Info("Payment request", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } if resInvoice.PaymentRequest == "" { slog.Error("The lightning backend is not returning an invoice.") - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } @@ -130,7 +130,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { err = mint.MintDB.SaveMintRequest(tx, mintRequestDB) if err != nil { slog.Error("SaveQuoteRequest", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } @@ -141,7 +141,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { } res := mintRequestDB.PostMintQuoteBolt11Response() - c.JSON(200, res) + utils.JSON(c, 200, res) }) v1.GET("/mint/quote/bolt11/:quote", func(c *gin.Context) { @@ -165,7 +165,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint:quote mint.MintDB.GetMintRequestById(tx, quoteId)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -176,19 +176,19 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { return } if quote.State == cashu.PAID || quote.State == cashu.ISSUED { - c.JSON(200, quote) + utils.JSON(c, 200, quote) return } invoice, err := zpay32.Decode(quote.Request, mint.LightningBackend.GetNetwork()) if err != nil { slog.Warn("Mint decoding zpay32.Decode", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } quote, err = m.CheckMintRequest(mint, quote, invoice) if err != nil { slog.Warn("m.CheckMintRequest(mint, quote)", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } stateChangeTX, err := mint.MintDB.GetTx(ctx) @@ -216,17 +216,17 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { } res := quote.PostMintQuoteBolt11Response() - c.JSON(200, res) + utils.JSON(c, 200, res) }) v1.POST("/mint/bolt11", func(c *gin.Context) { var mintRequest cashu.PostMintBolt11Request - err := c.BindJSON(&mintRequest) + err := utils.DecodeJSONV2(c, &mintRequest) if err != nil { slog.Info("Incorrect body", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -234,7 +234,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn(fmt.Errorf("mint.Signer.GetKeys(). %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -256,13 +256,13 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn(" mint-resquest mint.MintDB.GetMintRequestById(tx, mintRequest.Quote)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } if mintRequestDB.Minted { slog.Warn("Quote already minted", slog.String(utils.LogExtraInfo, mintRequestDB.Quote)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.QUOTE_ALREADY_ISSUED, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.QUOTE_ALREADY_ISSUED, nil)) return } @@ -271,14 +271,14 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("Cold not verify signature", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } if !valid { slog.Warn("Invalid signature", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } } @@ -287,7 +287,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.VerifyUnitSupport(quote.Unit)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } // quote @@ -297,7 +297,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.VerifyOutputs(mintRequest.Outputs)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } err = mint.MintDB.Commit(ctx, preparationTx) @@ -316,14 +316,14 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { invoice, err := zpay32.Decode(mintRequestDB.Request, mint.LightningBackend.GetNetwork()) if err != nil { slog.Warn("Mint decoding zpay32.Decode", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } cashuUnit, err := cashu.UnitFromString(mintRequestDB.Unit) if err != nil { slog.Warn("cashu.UnitFromString(mintRequestDB.Unit)", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } cashuBlindMessage := cashu.NewAmount(cashuUnit, amountBlindMessages) @@ -336,7 +336,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { // check the amount in outputs are the same as the quote if uint64(*invoice.MilliSat) < cashuBlindMessage.Amount { slog.Info("wrong amount of milisats", slog.Int("invoice_milisats", int(*invoice.MilliSat)), slog.Int("needed_milisats", int(cashuBlindMessage.Amount))) - c.JSON(403, "Amounts in outputs are not the same") + utils.JSON(c, 403, "Amounts in outputs are not the same") return } if mintRequestDB.State == cashu.UNPAID { @@ -347,11 +347,11 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if errors.Is(err, invoices.ErrInvoiceNotFound) || strings.Contains(err.Error(), "NotFound") { slog.Warn(fmt.Errorf(".CheckMintRequest(mint, mintRequestDB, invoice): %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } slog.Warn("m.CheckMintRequest(mint, quote)", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } afterCheckTx, err := mint.MintDB.GetTx(ctx) @@ -382,7 +382,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { } if mintRequestDB.State != cashu.PAID { - c.JSON(400, cashu.ErrorCodeToResponse(cashu.REQUEST_NOT_PAID, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.REQUEST_NOT_PAID, nil)) return } slog.Debug(fmt.Sprintf("Signing blind signatures in Mint request : id %v", mintRequestDB.Quote)) @@ -390,7 +390,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error("mint.Signer.SignBlindMessages(mintRequest.Outputs)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -420,7 +420,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error(fmt.Errorf("mint.MintDB.SaveRestoreSigs(tx, recoverySigsDb): %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -435,18 +435,18 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { go mint.Observer.SendMintEvent(mintRequestDB) slog.Debug(fmt.Sprintf("returning success to client: mint quote id: %v", mintRequestDB.Quote)) // Store BlidedSignature - c.JSON(200, cashu.PostMintBolt11Response{ + utils.JSON(c, 200, cashu.PostMintBolt11Response{ Signatures: blindedSignatures, }) }) v1.POST("/melt/quote/bolt11", func(c *gin.Context) { var meltRequest cashu.PostMeltQuoteBolt11Request - err := c.BindJSON(&meltRequest) + err := utils.DecodeJSONV2(c, &meltRequest) if err != nil { slog.Info("Incorrect body", slog.Any("error", err)) - c.JSON(400, "Malformed body request") + utils.JSON(c, 400, "Malformed body request") return } @@ -454,25 +454,25 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.VerifyUnitSupport(quote.Unit)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } invoice, err := zpay32.Decode(meltRequest.Request, mint.LightningBackend.GetNetwork()) if err != nil { slog.Info("zpay32.Decode", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } if uint64(*invoice.MilliSat) == 0 { - c.JSON(400, "Invoice has no amount") + utils.JSON(c, 400, "Invoice has no amount") return } if mint.Config.PEG_OUT_LIMIT_SATS != nil { if int64(*invoice.MilliSat) > (int64(*mint.Config.PEG_OUT_LIMIT_SATS) * 1000) { - c.JSON(400, "Melt amount over the limit") + utils.JSON(c, 400, "Melt amount over the limit") return } } @@ -480,7 +480,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { quoteId, err := utils.RandomHash() if err != nil { slog.Info("utils.RandomHash()", slog.String(utils.LogExtraInfo, meltRequest.Request)) - c.JSON(500, "Opps! there was a problem with the mint") + utils.JSON(c, 500, "Opps! there was a problem with the mint") return } @@ -492,7 +492,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("cashu.UnitFromString(meltRequest.Unit)", slog.Any("error", err), slog.Any("err", cashu.ErrUnitNotSupported)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -502,7 +502,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error("cashuAmount.To(unit)", slog.Any("error", err), slog.Any("err", cashu.ErrUnitNotSupported)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -514,7 +514,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if mppAmount.Amount > cashuAmount.Amount { slog.Warn("User tried to pay mpp amount bigger than the given invoice", slog.Any("invoiceAmount", cashuAmount.Amount), slog.Any("mppAmount", mppAmount.Amount)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -524,7 +524,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if isMpp && !mint.LightningBackend.ActiveMPP() { slog.Info("Tried to do mpp when it is not available") - c.JSON(400, "Sorry! MPP is not available") + utils.JSON(c, 400, "Sorry! MPP is not available") return } @@ -533,13 +533,13 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { isInternal, err := mint.IsInternalTransaction(meltRequest.Request) if err != nil { slog.Info("mint.IsInternalTransaction(meltRequest.Request)", slog.Any("error", err)) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } if isMpp && isInternal { slog.Info("Internal MPP not allowed", slog.Any("error", err)) - c.JSON(403, "Internal MPP not allowed") + utils.JSON(c, 403, "Internal MPP not allowed") return } queryFee := uint64(0) @@ -565,7 +565,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Info("mint.LightningBackend.QueryFees(meltRequest.Request, invoice, isMpp, cashuAmount)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } dbRequest.CheckingId = feesResponse.CheckingId @@ -593,7 +593,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("SaveQuoteMeltRequest", slog.Any("error", err)) slog.Warn("dbRequest", slog.Any("db_request", dbRequest)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.UNKNOWN, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.UNKNOWN, nil)) return } @@ -604,7 +604,7 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { return } - c.JSON(200, dbRequest.GetPostMeltQuoteResponse()) + utils.JSON(c, 200, dbRequest.GetPostMeltQuoteResponse()) }) v1.GET("/melt/quote/bolt11/:quote", func(c *gin.Context) { @@ -614,20 +614,20 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.CheckMeltQuoteState(quoteId)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } - c.JSON(200, quote.GetPostMeltQuoteResponse()) + utils.JSON(c, 200, quote.GetPostMeltQuoteResponse()) }) v1.POST("/melt/bolt11", func(c *gin.Context) { var meltRequest cashu.PostMeltBolt11Request - err := c.BindJSON(&meltRequest) + err := utils.DecodeJSONV2(c, &meltRequest) if err != nil { slog.Info("Incorrect body", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -635,10 +635,10 @@ func v1bolt11Routes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.Melt(ctx, meltRequest)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } - c.JSON(200, quote) + utils.JSON(c, 200, quote) }) } diff --git a/internal/routes/middleware/auth.go b/internal/routes/middleware/auth.go index 0f85d2b2..0de48dd3 100644 --- a/internal/routes/middleware/auth.go +++ b/internal/routes/middleware/auth.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" "github.com/lescuer97/nutmix/api/cashu" "github.com/lescuer97/nutmix/internal/mint" + "github.com/lescuer97/nutmix/internal/utils" ) // ClearAuthMiddleware creates a middleware that checks for the "clear auth" header @@ -38,7 +39,7 @@ func ClearAuthMiddleware(mint *mint.Mint) gin.HandlerFunc { if err != nil { slog.Error("Could not setup oidc service during middleware.", slog.Any("error", err)) errMsg := "This is a mint connectin error with the oidc service" - c.JSON(400, cashu.ErrorCodeToResponse(cashu.CLEAR_AUTH_FAILED, &errMsg)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.CLEAR_AUTH_FAILED, &errMsg)) return } } @@ -47,7 +48,7 @@ func ClearAuthMiddleware(mint *mint.Mint) gin.HandlerFunc { clearAuth := c.GetHeader("Clear-auth") if clearAuth == "" { slog.Warn("Tried to do a clear auth without token.") - c.JSON(401, cashu.ErrorCodeToResponse(cashu.ENDPOINT_REQUIRES_CLEAR_AUTH, nil)) + utils.JSON(c, 401, cashu.ErrorCodeToResponse(cashu.ENDPOINT_REQUIRES_CLEAR_AUTH, nil)) c.Abort() return } @@ -56,7 +57,7 @@ func ClearAuthMiddleware(mint *mint.Mint) gin.HandlerFunc { err := mint.VerifyAuthClearToken(token) if err != nil { slog.Warn("mint.VerifyAuthClearToken(token)", slog.Any("error", err)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.CLEAR_AUTH_FAILED, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.CLEAR_AUTH_FAILED, nil)) return } // Header exists, continue processing @@ -95,14 +96,14 @@ func BlindAuthMiddleware(mint *mint.Mint) gin.HandlerFunc { blindAuth := c.GetHeader("Blind-auth") if blindAuth == "" { slog.Warn("Tried to do a blind auth without token.") - c.JSON(401, cashu.ErrorCodeToResponse(cashu.ENDPOINT_REQUIRES_BLIND_AUTH, nil)) + utils.JSON(c, 401, cashu.ErrorCodeToResponse(cashu.ENDPOINT_REQUIRES_BLIND_AUTH, nil)) c.Abort() return } authProof, err := cashu.DecodeAuthToken(blindAuth) if err != nil { slog.Warn("cashu.DecodeAuthToken(blindAuth)") - c.JSON(400, cashu.ErrorCodeToResponse(cashu.BLIND_AUTH_FAILED, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.BLIND_AUTH_FAILED, nil)) c.Abort() return } @@ -111,7 +112,7 @@ func BlindAuthMiddleware(mint *mint.Mint) gin.HandlerFunc { err = mint.VerifyAuthBlindToken(authProof) if err != nil { slog.Warn("mint.VerifyAuthBlindToken(authProof)", slog.Any("error", err)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.BLIND_AUTH_FAILED, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.BLIND_AUTH_FAILED, nil)) return } // Header exists, continue processing diff --git a/internal/routes/mint.go b/internal/routes/mint.go index 83f702c2..3cc0faaf 100644 --- a/internal/routes/mint.go +++ b/internal/routes/mint.go @@ -22,11 +22,11 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { keys, err := mint.Signer.GetActiveKeys() if err != nil { slog.Error("mint.Signer.GetActiveKeys()", slog.Any("error", err)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) return } - c.JSON(200, keys) + utils.JSON(c, 200, keys) }) @@ -38,11 +38,11 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn("mint.Signer.GetKeysById(id)", slog.Any("error", err)) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.KEYSET_NOT_KNOW, nil)) return } - c.JSON(200, keysets) + utils.JSON(c, 200, keysets) }) v1.GET("/keysets", func(c *gin.Context) { @@ -50,11 +50,11 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { keys, err := mint.Signer.GetKeysets() if err != nil { slog.Error("mint.Signer.GetKeys()", slog.Any("error", err)) - c.JSON(500, "Server side error") + utils.JSON(c, 500, "Server side error") return } - c.JSON(200, keys) + utils.JSON(c, 200, keys) }) v1.GET("/info", func(c *gin.Context) { @@ -126,7 +126,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { mintInfo, ok := entry.(cashu.SwapMintInfo) if !ok { slog.Error("nuts entry type mismatch", slog.String("nut", nut), slog.Any("value", entry)) - c.JSON(500, "Server side error") + utils.JSON(c, 500, "Server side error") return } // Then we modify the copy @@ -256,30 +256,30 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { Time: time.Now().Unix(), } - c.JSON(200, response) + utils.JSON(c, 200, response) }) v1.POST("/swap", func(c *gin.Context) { var swapRequest cashu.PostSwapRequest - err := c.BindJSON(&swapRequest) + err := utils.DecodeJSONV2(c, &swapRequest) if err != nil { slog.Info("Incorrect body", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } if len(swapRequest.Inputs) == 0 || len(swapRequest.Outputs) == 0 { slog.Info("Inputs or Outputs are empty") - c.JSON(400, "Inputs or Outputs are empty") + utils.JSON(c, 400, "Inputs or Outputs are empty") return } _, SecretsList, err := utils.GetAndCalculateProofsValues(&swapRequest.Inputs) if err != nil { slog.Warn("utils.GetAndCalculateProofsValues(&swapRequest.Inputs)", slog.Any("error", err)) - c.JSON(400, "Problem processing proofs") + utils.JSON(c, 400, "Problem processing proofs") return } @@ -288,7 +288,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn(fmt.Errorf("cashu.ProofsHaveSigAll(swapRequest.Inputs). %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -298,7 +298,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn(fmt.Errorf("swapRequest.ValidateSigflag(). %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } } else { @@ -307,7 +307,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn(fmt.Errorf("mint.VerifyProofsSpendConditions(swapRequest.Inputs). %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } } @@ -317,7 +317,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn(fmt.Errorf("mint.VerifyProofsBDHKE(swapRequest.Inputs). %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -340,7 +340,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Warn(fmt.Errorf("mint.VerifyInputsAndOutputs(swapRequest.Inputs, swapRequest.Outputs). %w", err).Error()) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -349,7 +349,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error("mint.MintDB.GetProofsFromSecretCurve(tx, SecretsList)", slog.String(utils.LogExtraInfo, err.Error())) - c.JSON(400, cashu.ErrorCodeToResponse(cashu.UNKNOWN, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.UNKNOWN, nil)) return } @@ -357,12 +357,12 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { slog.Debug("Proofs already spent", slog.Any("known_proofs", knownProofs)) for _, p := range knownProofs { if p.State == cashu.PROOF_PENDING { - c.JSON(400, cashu.ErrorCodeToResponse(cashu.PROOFS_PENDING, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.PROOFS_PENDING, nil)) return } } - c.JSON(400, cashu.ErrorCodeToResponse(cashu.PROOF_ALREADY_SPENT, nil)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(cashu.PROOF_ALREADY_SPENT, nil)) return } @@ -374,7 +374,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error("mint.MintDB.SaveProof(tx, swapRequest.Inputs)", slog.String(utils.LogExtraInfo, err.Error())) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(403, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 403, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -389,7 +389,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error("mint.Signer.SignBlindMessages(swapRequest.Outputs)", slog.String(utils.LogExtraInfo, err.Error())) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(400, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 400, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -415,7 +415,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { slog.Warn("mint.MintDB.SetProofsState(tx,swapRequest.Inputs , cashu.PROOF_SPENT)", slog.Any("error", err)) errorCode, details := utils.ParseErrorToCashuErrorCode(err) - c.JSON(403, cashu.ErrorCodeToResponse(errorCode, details)) + utils.JSON(c, 403, cashu.ErrorCodeToResponse(errorCode, details)) return } @@ -423,7 +423,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { if err != nil { slog.Error("database.SetRestoreSigs", slog.String(utils.LogExtraInfo, err.Error())) slog.Error("recoverySigsDb", slog.Any("recovery_sigs", recoverySigsDb)) - c.JSON(200, response) + utils.JSON(c, 200, response) return } err = mint.MintDB.Commit(ctx, afterSigningTx) @@ -433,15 +433,15 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { } go mint.Observer.SendProofsEvent(swapRequest.Inputs) - c.JSON(200, response) + utils.JSON(c, 200, response) }) v1.POST("/checkstate", func(c *gin.Context) { var checkStateRequest cashu.PostCheckStateRequest - err := c.BindJSON(&checkStateRequest) + err := utils.DecodeJSONV2(c, &checkStateRequest) if err != nil { - slog.Info("c.BindJSON(&checkStateRequest)", slog.Any("error", err)) - c.JSON(400, "Malformed Body") + slog.Info("utils.DecodeJSONV2(c, &checkStateRequest)", slog.Any("error", err)) + utils.JSON(c, 400, "Malformed Body") return } @@ -452,21 +452,21 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { states, err := m.CheckProofState(c.Request.Context(), mint, checkStateRequest.Ys) if err != nil { slog.Info("could not check proofs state", slog.Any("error", err)) - c.JSON(400, "could not validate proofs state") + utils.JSON(c, 400, "could not validate proofs state") return } checkStateResponse.States = states - c.JSON(200, checkStateResponse) + utils.JSON(c, 200, checkStateResponse) }) v1.POST("/restore", func(c *gin.Context) { var restoreRequest cashu.PostRestoreRequest - err := c.BindJSON(&restoreRequest) + err := utils.DecodeJSONV2(c, &restoreRequest) if err != nil { - slog.Info("c.BindJSON(&restoreRequest)", slog.Any("error", err)) - c.JSON(400, "Malformed body request") + slog.Info("utils.DecodeJSONV2(c, &restoreRequest)", slog.Any("error", err)) + utils.JSON(c, 400, "Malformed body request") return } @@ -485,7 +485,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { blindRecoverySigs, err := mint.MintDB.GetRestoreSigsFromBlindedMessages(tx, blindingFactors) if err != nil { slog.Error("mint.MintDB.GetRestoreSigsFromBlindedMessages(tx, blindingFactors)", slog.String(utils.LogExtraInfo, err.Error())) - c.JSON(500, "Opps!, something went wrong") + utils.JSON(c, 500, "Opps!, something went wrong") return } err = mint.MintDB.Commit(ctx, tx) @@ -503,7 +503,7 @@ func v1MintRoutes(r *gin.Engine, mint *m.Mint) { restoredBlindMessage = append(restoredBlindMessage, restoredMessage) } - c.JSON(200, cashu.PostRestoreResponse{ + utils.JSON(c, 200, cashu.PostRestoreResponse{ Outputs: restoredBlindMessage, Signatures: restoredBlindSigs, Promises: restoredBlindSigs,