From ba36f96f4c5750046b0e678ff20740b1abe2a956 Mon Sep 17 00:00:00 2001 From: Michilis Date: Tue, 15 Jul 2025 18:03:56 +0000 Subject: [PATCH] Remove redeemId field from redeem response - Remove redeemId from successful redemption response - Remove redeemId from error response - Update swagger documentation to remove redeemId field - Update README examples to remove redeemId field - Clean up API response format for better simplicity --- README.md | 2 -- env.example | 2 +- package-lock.json | 31 +++++++++++++++++++++++++++++-- server.js | 8 -------- swagger.config.js | 6 ------ 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index cd7f0f4..ae13e14 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,6 @@ Redeem a Cashu token to a Lightning address. Lightning address is optional - if ```json { "success": true, - "redeemId": "8e99101e-d034-4d2e-9ccf-dfda24d26762", "paid": true, "amount": 21000, "invoiceAmount": 20580, @@ -94,7 +93,6 @@ Redeem a Cashu token to a Lightning address. Lightning address is optional - if ```json { "success": true, - "redeemId": "8e99101e-d034-4d2e-9ccf-dfda24d26762", "paid": true, "amount": 21000, "invoiceAmount": 20580, diff --git a/env.example b/env.example index 6a16e66..c2fc6c7 100644 --- a/env.example +++ b/env.example @@ -4,7 +4,7 @@ NODE_ENV=development # Security Configuration ALLOW_REDEEM_DOMAINS=* -API_SECRET=your-secret-key-here + # Default Lightning Address (used when no address is provided in redeem requests) DEFAULT_LIGHTNING_ADDRESS=admin@your-domain.com diff --git a/package-lock.json b/package-lock.json index f4f7a68..bc7f36a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cashu-redeem-api", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cashu-redeem-api", - "version": "1.0.0", + "version": "1.1.0", "license": "MIT", "dependencies": { "@cashu/cashu-ts": "^1.1.0", @@ -15,6 +15,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", + "express-rate-limit": "^8.0.0", "swagger-jsdoc": "^6.2.8", "swagger-ui-express": "^5.0.1", "uuid": "^10.0.0" @@ -26,6 +27,10 @@ "engines": { "node": ">=18.0.0", "npm": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/Michilis" } }, "node_modules/@apidevtools/json-schema-ref-parser": { @@ -1464,6 +1469,23 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-rate-limit": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.0.0.tgz", + "integrity": "sha512-FXEAp2ccTeN1ZSO+sPHRHWB0/CrTP5asFBjUaNeD9A0v3iPmgFbLu24vqPjiM9utszI58VGlMokjXQ0W9Dbmjw==", + "dependencies": { + "ip": "2.0.1" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1961,6 +1983,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", diff --git a/server.js b/server.js index 40772b8..91dab90 100644 --- a/server.js +++ b/server.js @@ -305,9 +305,6 @@ app.post('/api/decode', asyncHandler(async (req, res) => { * error: * type: string * example: "This token has already been spent and cannot be redeemed again" - * redeemId: - * type: string - * format: uuid * errorType: * type: string * example: "token_already_spent" @@ -324,9 +321,6 @@ app.post('/api/decode', asyncHandler(async (req, res) => { * error: * type: string * example: "Token amount is insufficient to cover the minimum fee" - * redeemId: - * type: string - * format: uuid * errorType: * type: string * example: "insufficient_funds" @@ -355,7 +349,6 @@ app.post('/api/redeem', asyncHandler(async (req, res) => { if (result.success) { const response = { success: true, - redeemId: result.redeemId, paid: result.paid, amount: result.amount, invoiceAmount: result.invoiceAmount, @@ -400,7 +393,6 @@ app.post('/api/redeem', asyncHandler(async (req, res) => { res.status(statusCode).json({ success: false, error: result.error, - redeemId: result.redeemId, errorType: statusCode === 409 ? 'token_already_spent' : statusCode === 422 ? 'insufficient_funds' : 'validation_error' }); diff --git a/swagger.config.js b/swagger.config.js index bee6044..6fc5eda 100644 --- a/swagger.config.js +++ b/swagger.config.js @@ -138,12 +138,6 @@ const options = { type: 'boolean', example: true }, - redeemId: { - type: 'string', - format: 'uuid', - description: 'Unique redemption ID for tracking', - example: '8e99101e-d034-4d2e-9ccf-dfda24d26762' - }, paid: { type: 'boolean', description: 'Whether the payment was successful',