From b6c6c186a81435c2d117a8eb599025d265dfc7ca Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Mon, 29 Sep 2025 18:58:20 -0400 Subject: [PATCH] fix(docs): Added api-docs to bch-dex endpoints --- package.json | 1 + src/controllers/rest-api/entry/controller.js | 29 +++ src/controllers/rest-api/ipfs/controller.js | 49 +++- src/controllers/rest-api/offer/controller.js | 261 +++++++++++++++++++ src/controllers/rest-api/order/controller.js | 107 +++++++- src/controllers/rest-api/p2wdb/controller.js | 20 +- 6 files changed, 463 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 9941dc9..3eaea30 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "test:all": "export BCH_DEX=test && c8 --reporter=text mocha --exit --timeout 15000 --recursive test/unit test/e2e/automated/", "test:unit": "export BCH_DEX=test && c8 --reporter=text mocha --exit --timeout 15000 --recursive test/unit/", "test:e2e:auto": "export BCH_DEX=test && mocha --exit --timeout 30000 test/e2e/automated/", + "start:e2e:server": "export BCH_DEX=test && node index.js", "test:integration": "export BCH_DEX=test && mocha --exit --timeout 45000 --recursive test/integration", "test:temp": "export BCH_DEX=test && mocha --exit --timeout 15000 -g '#rate-limit' test/unit/json-rpc/", "lint": "standard --env mocha --fix", diff --git a/src/controllers/rest-api/entry/controller.js b/src/controllers/rest-api/entry/controller.js index 9cc18d1..2c43fdf 100644 --- a/src/controllers/rest-api/entry/controller.js +++ b/src/controllers/rest-api/entry/controller.js @@ -29,7 +29,36 @@ class EntryRESTControllerLib { _this = this } + /** + * @api {post} /entry Create an entry + * @apiPermission public + * @apiName CreateEntry + * @apiGroup REST Entry + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{"entry": "1234567890", "description": "1234567890", "slpAddress": "1234567890", "signature": "1234567890", "category": "1234567890"}' localhost:5001/entry + * + * @apiSuccess {Object} entry Entry object + * @apiSuccess {String} entry.id Entry ID + * @apiSuccess {String} entry.description Entry description + * @apiSuccess {String} entry.slpAddress Entry slp address + * @apiSuccess {String} entry.signature Entry signature + * @apiSuccess {String} entry.category Entry category + + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "entry": { + * "id": "1234567890", + * "description": "1234567890", + * "slpAddress": "1234567890", + * "signature": "1234567890", + * "category": "1234567890" + * } + * } + */ // No api-doc documentation because this wont be a public endpoint + // Note: this is a private endpoint, needs to be authenticated async createEntry (ctx) { try { console.log('body: ', ctx.request.body) diff --git a/src/controllers/rest-api/ipfs/controller.js b/src/controllers/rest-api/ipfs/controller.js index d883288..d5dcedf 100644 --- a/src/controllers/rest-api/ipfs/controller.js +++ b/src/controllers/rest-api/ipfs/controller.js @@ -40,11 +40,23 @@ class IpfsRESTControllerLib { * @api {get} /ipfs Get status on IPFS infrastructure * @apiPermission public * @apiName GetIpfsStatus - * @apiGroup REST BCH + * @apiGroup REST IPFS * * @apiExample Example usage: * curl -H "Content-Type: application/json" -X GET localhost:5001/ipfs * + * @apiSuccess {Object} status IPFS status object + * @apiSuccess {String} status.ipfsId IPFS ID + * @apiSuccess {String} status.multiaddrs IPFS multiaddrs + + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "status": { + * "ipfsId": "1234567890", + * "multiaddrs": ["/ip4/123.45.67.89/tcp/4001/p2p/1234567890"] + * } + * } */ async getStatus (ctx) { try { @@ -58,6 +70,16 @@ class IpfsRESTControllerLib { } } + /** + * @api {POST} /ipfs/peers Get IPFS peers + * @apiPermission public + * @apiName GetIpfsPeers + * @apiGroup REST IPFS + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "showAll": true }' localhost:5001/ipfs/peers + * + */ // Return information on IPFS peers this node is connected to. async getPeers (ctx) { try { @@ -73,6 +95,18 @@ class IpfsRESTControllerLib { } } + /** + * @api {POST} /ipfs/relays Get IPFS relays + * @apiPermission public + * @apiName GetIpfsRelays + * @apiGroup REST IPFS + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST localhost:5001/ipfs/relays + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + */ // Get data about the known Circuit Relays. Hydrate with data from peers list. async getRelays (ctx) { try { @@ -86,6 +120,17 @@ class IpfsRESTControllerLib { } } + /** + * + * @api {POST} /ipfs/connect Connect to an IPFS peer + * @apiPermission public + * @apiName ConnectToIpfsPeer + * @apiGroup REST IPFS + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "multiaddr": "/ip4/123.45.67.89/tcp/4001/p2p/1234567890", "getDetails": true }' localhost:5001/ipfs/connect + * + */ async connect (ctx) { try { const multiaddr = ctx.request.body.multiaddr @@ -107,7 +152,7 @@ class IpfsRESTControllerLib { * @api {get} /ipfs/node Get a copy of the thisNode object from helia-coord * @apiPermission public * @apiName GetThisNode - * @apiGroup REST BCH + * @apiGroup REST IPFS * * @apiExample Example usage: * curl -H "Content-Type: application/json" -X GET localhost:5001/ipfs/node diff --git a/src/controllers/rest-api/offer/controller.js b/src/controllers/rest-api/offer/controller.js index 507d0d7..e349ef6 100644 --- a/src/controllers/rest-api/offer/controller.js +++ b/src/controllers/rest-api/offer/controller.js @@ -38,6 +38,7 @@ class OfferRESTControllerLib { } // No api-doc documentation because this wont be a public endpoint + // This function has no endpoint async createOffer (ctx) { try { console.log('body: ', ctx.request.body) @@ -56,6 +57,65 @@ class OfferRESTControllerLib { this.handleError(ctx, err) } } + /** + * @api {get} /offer/list/all/:page Get all offers + * @apiPermission public + * @apiName ListOffers + * @apiGroup REST Offer + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X GET localhost:5000/offer/list/all/0 + * + * @apiSuccess {Object[]} offers Array of offer objects + * @apiSuccess {ObjectId} offers._id Offer id + * @apiSuccess {String} offers.ticker Ticker + * @apiSuccess {String} offers.tokenId Token id + * @apiSuccess {String} offers.utxoTxid Utxo transaction id + * @apiSuccess {Number} offers.utxoVout Utxo output index + * @apiSuccess {String} offers.buyOrSell Buy or sell + * @apiSuccess {Number} offers.numTokens Number of tokens + * @apiSuccess {String} offers.rateInBaseUnit Rate in base unit + * @apiSuccess {String} offers.minUnitsToExchange Minimum units to exchange + * @apiSuccess {String} offers.offerStatus Offer status + * @apiSuccess {String} offers.makerAddr Maker address + * @apiSuccess {Number} offers.timestamp Timestamp + * @apiSuccess {String} offers.displayCategory Display category + * @apiSuccess {Boolean} offers.nsfw Nsfw + * @apiSuccess {Array} offers.flags Flags + * @apiSuccess {Number} offers.messageType Message type + * @apiSuccess {Number} offers.messageClass Message class + * @apiSuccess {String} offers.nostrEventId Nostr event id + * @apiSuccess {String} offers.operatorAddress Operator address + * @apiSuccess {Number} offers.operatorPercentage Operator percentage + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "offers": [{ + * "_id": "56bd1da600a526986cf65c80", + * "tokenId": "1234567890", + * "utxoTxid": "1234567890", + * "utxoVout": 0, + * "buyOrSell": "buy", + * "numTokens": 1, + * "rateInBaseUnit": "100000000", + * "minUnitsToExchange": "100000000", + * "offerStatus": "active", + * "makerAddr": "1234567890", + * "timestamp": 1716883200, + * "displayCategory": "nft", + * "nsfw": false, + * "flags": [], + * "messageType": 1, + * "messageClass": 1, + * "nostrEventId": "1234567890", + * "operatorAddress": "1234567890", + * "operatorPercentage": 100 + * }] + * } + * + * @apiUse TokenError + */ // curl -X GET http://localhost:5700/offer/list/all/0 async listOffers (ctx) { @@ -72,6 +132,66 @@ class OfferRESTControllerLib { } } + /** + * @api {get} /offer/list/nft/:page Get all nft offers + * @apiPermission public + * @apiName ListNftOffers + * @apiGroup REST Offer + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X GET localhost:5000/offer/list/nft/0 + * + * @apiSuccess {Object[]} offers Array of offer objects + * @apiSuccess {ObjectId} offers._id Offer id + * @apiSuccess {String} offers.ticker Ticker + * @apiSuccess {String} offers.tokenId Token id + * @apiSuccess {String} offers.utxoTxid Utxo transaction id + * @apiSuccess {Number} offers.utxoVout Utxo output index + * @apiSuccess {String} offers.buyOrSell Buy or sell + * @apiSuccess {Number} offers.numTokens Number of tokens + * @apiSuccess {String} offers.rateInBaseUnit Rate in base unit + * @apiSuccess {String} offers.minUnitsToExchange Minimum units to exchange + * @apiSuccess {String} offers.offerStatus Offer status + * @apiSuccess {String} offers.makerAddr Maker address + * @apiSuccess {Number} offers.timestamp Timestamp + * @apiSuccess {String} offers.displayCategory Display category + * @apiSuccess {Boolean} offers.nsfw Nsfw + * @apiSuccess {Array} offers.flags Flags + * @apiSuccess {Number} offers.messageType Message type + * @apiSuccess {Number} offers.messageClass Message class + * @apiSuccess {String} offers.nostrEventId Nostr event id + * @apiSuccess {String} offers.operatorAddress Operator address + * @apiSuccess {Number} offers.operatorPercentage Operator percentage + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "offers": [{ + * "_id": "56bd1da600a526986cf65c80", + * "tokenId": "1234567890", + * "utxoTxid": "1234567890", + * "utxoVout": 0, + * "buyOrSell": "buy", + * "numTokens": 1, + * "rateInBaseUnit": "100000000", + * "minUnitsToExchange": "100000000", + * "offerStatus": "active", + * "makerAddr": "1234567890", + * "timestamp": 1716883200, + * "displayCategory": "nft", + * "nsfw": false, + * "flags": [], + * "messageType": 1, + * "messageClass": 1, + * "nostrEventId": "1234567890", + * "operatorAddress": "1234567890", + * "operatorPercentage": 100 + * }] + * } + * + * @apiUse TokenError + */ + // curl -X GET http://localhost:5700/offer/list/nft/0 async listNftOffers (ctx) { try { @@ -87,6 +207,65 @@ class OfferRESTControllerLib { } } + /** + * @api {get} /offer/list/fungible/:page Get all fungible offers + * @apiPermission public + * @apiName ListFungibleOffers + * @apiGroup REST Offer + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X GET localhost:5000/offer/list/fungible/0 + * + * @apiSuccess {Object[]} offers Array of offer objects + * @apiSuccess {ObjectId} offers._id Offer id + * @apiSuccess {String} offers.ticker Ticker + * @apiSuccess {String} offers.tokenId Token id + * @apiSuccess {String} offers.utxoTxid Utxo transaction id + * @apiSuccess {Number} offers.utxoVout Utxo output index + * @apiSuccess {String} offers.buyOrSell Buy or sell + * @apiSuccess {Number} offers.numTokens Number of tokens + * @apiSuccess {String} offers.rateInBaseUnit Rate in base unit + * @apiSuccess {String} offers.minUnitsToExchange Minimum units to exchange + * @apiSuccess {String} offers.offerStatus Offer status + * @apiSuccess {String} offers.makerAddr Maker address + * @apiSuccess {Number} offers.timestamp Timestamp + * @apiSuccess {String} offers.displayCategory Display category + * @apiSuccess {Boolean} offers.nsfw Nsfw + * @apiSuccess {Array} offers.flags Flags + * @apiSuccess {Number} offers.messageType Message type + * @apiSuccess {Number} offers.messageClass Message class + * @apiSuccess {String} offers.nostrEventId Nostr event id + * @apiSuccess {String} offers.operatorAddress Operator address + * @apiSuccess {Number} offers.operatorPercentage Operator percentage + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "offers": [{ + * "_id": "56bd1da600a526986cf65c80", + * "tokenId": "1234567890", + * "utxoTxid": "1234567890", + * "utxoVout": 0, + * "buyOrSell": "buy", + * "numTokens": 1, + * "rateInBaseUnit": "100000000", + * "minUnitsToExchange": "100000000", + * "offerStatus": "active", + * "makerAddr": "1234567890", + * "timestamp": 1716883200, + * "displayCategory": "fungible", + * "nsfw": false, + * "flags": [], + * "messageType": 1, + * "messageClass": 1, + * "nostrEventId": "1234567890", + * "operatorAddress": "1234567890", + * "operatorPercentage": 100 + * }] + * } + * + * @apiUse TokenError + */ // curl -X GET http://localhost:5700/offer/list/fungible/0 async listFungibleOffers (ctx) { try { @@ -102,6 +281,27 @@ class OfferRESTControllerLib { } } + /** + * @api {post} /offer/take Take an offer + * @apiPermission public + * @apiName TakeOffer + * @apiGroup REST Offer + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "nostrEventId": "1234567890" }' localhost:5010/offer/take + * + * @apiSuccess {String} eventId Event id + * @apiSuccess {String} noteId Note id + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "eventId": "1234567890", + * "noteId": "1234567890" + * } + * + * @apiUse TokenError + */ // Currently only supports 'sell' offers, and will only buy the 'numTokens' // listed in the offer. async takeOffer (ctx) { @@ -119,6 +319,67 @@ class OfferRESTControllerLib { } } + /** + * @api {get} /offer/list/addr/:addr List all offers being made by a given address + * @apiPermission public + * @apiName ListOffersByAddress + * @apiGroup REST Offer + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X GET localhost:5000/offer/list/addr/bitcoincash:qrpxtnrlhfz9wsuuse7z5k2mxmvw0r3pu5qepyhmq2 + * + * + * @apiSuccess {Object[]} offers Array of offer objects + * @apiSuccess {ObjectId} offers._id Offer id + * @apiSuccess {String} offers.ticker Ticker + * @apiSuccess {String} offers.tokenId Token id + * @apiSuccess {String} offers.utxoTxid Utxo transaction id + * @apiSuccess {Number} offers.utxoVout Utxo output index + * @apiSuccess {String} offers.buyOrSell Buy or sell + * @apiSuccess {Number} offers.numTokens Number of tokens + * @apiSuccess {String} offers.rateInBaseUnit Rate in base unit + * @apiSuccess {String} offers.minUnitsToExchange Minimum units to exchange + * @apiSuccess {String} offers.offerStatus Offer status + * @apiSuccess {String} offers.makerAddr Maker address + * @apiSuccess {Number} offers.timestamp Timestamp + * @apiSuccess {String} offers.displayCategory Display category + * @apiSuccess {Boolean} offers.nsfw Nsfw + * @apiSuccess {Array} offers.flags Flags + * @apiSuccess {Number} offers.messageType Message type + * @apiSuccess {Number} offers.messageClass Message class + * @apiSuccess {String} offers.nostrEventId Nostr event id + * @apiSuccess {String} offers.operatorAddress Operator address + * @apiSuccess {Number} offers.operatorPercentage Operator percentage + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "offers": [{ + * "_id": "56bd1da600a526986cf65c80", + * "tokenId": "1234567890", + * "utxoTxid": "1234567890", + * "utxoVout": 0, + * "buyOrSell": "buy", + * "numTokens": 1, + * "rateInBaseUnit": "100000000", + * "minUnitsToExchange": "100000000", + * "offerStatus": "active", + * "makerAddr": "bitcoincash:qrpxtnrlhfz9wsuuse7z5k2mxmvw0r3pu5qepyhmq2", + * "timestamp": 1716883200, + * "displayCategory": "fungible", + * "nsfw": false, + * "flags": [], + * "messageType": 1, + * "messageClass": 1, + * "nostrEventId": "1234567890", + * "operatorAddress": "1234567890", + * "operatorPercentage": 100 + * }] + * } + * + * @apiUse TokenError + */ + // List all offers being made by a given address. // curl -X GET http://localhost:5700/offer/list/addr/bitcoincash:qrpxtnrlhfz9wsuuse7z5k2mxmvw0r3pu5qepyhmq2 async listOffersByAddress (ctx) { diff --git a/src/controllers/rest-api/order/controller.js b/src/controllers/rest-api/order/controller.js index 8bb338e..fbf0810 100644 --- a/src/controllers/rest-api/order/controller.js +++ b/src/controllers/rest-api/order/controller.js @@ -29,7 +29,28 @@ class OrderRESTControllerLib { _this = this } - // No api-doc documentation because this wont be a public endpoint + /** + * @api {post} /order Create an order + * @apiPermission User + * @apiName CreateOrder + * @apiGroup REST Order + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{"messageType": "1", "messageClass": "1", "tokenId": "1234567890", "buyOrSell": "buy", "rateInBaseUnit": "100000000", "minUnitsToExchange": "100000000", "numTokens": "1", "makerAddr": "1234567890"}' localhost:5001/order + * + * @apiSuccess {String} eventId Event id + * @apiSuccess {String} noteId Note id + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "eventId": "1234567890", + * "noteId": "1234567890" + * } + * + * @apiUse TokenError + */ + async createOrder (ctx) { try { // console.log('body: ', ctx.request.body) @@ -49,6 +70,68 @@ class OrderRESTControllerLib { _this.handleError(ctx, err) } } + /** + * @api {get} /order/list/all/:page List all orders + * @apiPermission user + * @apiName ListOrders + * @apiGroup REST Order + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X GET localhost:5000/order/list/all/0 + * + * @apiSuccess {Object[]} orders Array of order objects + * @apiSuccess {ObjectId} orders._id Order id + * @apiSuccess {String} orders.tokenId Token id + * @apiSuccess {String} orders.ticker Ticker + * @apiSuccess {String} orders.dataType Data type + * @apiSuccess {String} orders.utxoTxid Utxo transaction id + * @apiSuccess {Number} orders.utxoVout Utxo output index + * @apiSuccess {String} orders.buyOrSell Buy or sell + * @apiSuccess {Number} orders.numTokens Number of tokens + * @apiSuccess {String} orders.rateInBaseUnit Rate in base unit + * @apiSuccess {String} orders.minUnitsToExchange Minimum units to exchange + * @apiSuccess {String} orders.offerStatus Offer status + * @apiSuccess {String} orders.makerAddr Maker address + * @apiSuccess {Number} orders.timestamp Timestamp + * @apiSuccess {String} orders.displayCategory Display category + * @apiSuccess {Boolean} orders.nsfw Nsfw + * @apiSuccess {Array} orders.flags Flags + * @apiSuccess {Number} orders.messageType Message type + * @apiSuccess {Number} orders.messageClass Message class + * @apiSuccess {String} orders.nostrEventId Nostr event id + * @apiSuccess {String} orders.operatorAddress Operator address + * @apiSuccess {Number} orders.operatorPercentage Operator percentage + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "orders": [{ + * "_id": "56bd1da600a526986cf65c80", + * "tokenId": "1234567890", + * "ticker": "BTC", + * "dataType": "offer", + * "utxoTxid": "1234567890", + * "utxoVout": 0, + * "buyOrSell": "buy", + * "numTokens": 1, + * "rateInBaseUnit": "100000000", + * "minUnitsToExchange": "100000000", + * "offerStatus": "active", + * "makerAddr": "1234567890", + * "timestamp": 1716883200, + * "displayCategory": "nft", + * "nsfw": false, + * "flags": [], + * "messageType": 1, + * "messageClass": 1, + * "nostrEventId": "1234567890", + * "operatorAddress": "1234567890", + * "operatorPercentage": 100 + * }] + * } + * + * @apiUse TokenError + */ // curl -X GET http://localhost:5700/order/list/all/0 async listOrders (ctx) { @@ -67,6 +150,28 @@ class OrderRESTControllerLib { // Delete an existing order by returning the token to the root address of // the DEX wallet. + /** + * @api {post} /order/delete Delete an order + * @apiPermission user + * @apiName DeleteOrder + * @apiGroup REST Order + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "nostrEventId": "1234567890" }' localhost:5000/order/delete + * + * @apiSuccess {String} txid Transaction id + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "txid": "1234567890" + * } + * + * @apiUse TokenError + */ + + // curl -X POST http://localhost:5700/order/delete -d '{ "nostrEventId": "1234567890" }' + async deleteOrder (ctx) { try { // console.log('body: ', ctx.request.body) diff --git a/src/controllers/rest-api/p2wdb/controller.js b/src/controllers/rest-api/p2wdb/controller.js index 6f1348e..f7c8f33 100644 --- a/src/controllers/rest-api/p2wdb/controller.js +++ b/src/controllers/rest-api/p2wdb/controller.js @@ -31,7 +31,25 @@ class P2WDBRESTControllerLib { _this = this } - // No api-doc documentation because this wont be a public endpoint + /** + * @api {post} /p2wdb Route a P2WDB webhook + * @apiPermission public + * @apiName RouteWebhook + * @apiGroup REST P2WDB + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{"data": {"dataType": "offer"} } ' localhost:5001/p2wdb + * + * @apiSuccess {String} success Success message + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "success": true + * } + */ + + // Note: verify if this is a private endpoint, needs to be authenticated async routeWebhook (ctx) { try { console.log('p2wdb REST API handler: body: ', ctx.request.body)