Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rest-api): Adds Swagger for api docs [SLT-205] #3159

Merged
merged 13 commits into from
Sep 20, 2024
1 change: 1 addition & 0 deletions packages/rest-api/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
files: ['**/*.ts'],
rules: {
'guard-for-in': 'off',
'jsdoc/check-indentation': 'off',
},
},
],
Expand Down
6 changes: 5 additions & 1 deletion packages/rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"build": "tsc",
"build:go": " ",
"build:slither": " ",
"dev": "nodemon --watch src --exec ts-node src/app.ts",
"dev": "NODE_ENV=development nodemon --watch src --exec ts-node src/app.ts",
"start": "node dist/app.js",
"lint:fix": "eslint src/**/*.ts --fix",
"lint:check": "eslint . --max-warnings=0",
Expand Down Expand Up @@ -38,10 +38,14 @@
"@babel/preset-typescript": "^7.24.7",
"@types/jest": "^29.5.13",
"@types/supertest": "^6.0.2",
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.6",
"concurrently": "^8.2.0",
"jest": "^29.7.0",
"lodash": "^4.17.21",
"nodemon": "^3.0.1",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/rest-api/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import express from 'express'
import swaggerUi from 'swagger-ui-express'

import { specs } from './swagger'
import routes from './routes'

const app = express()
const port = process.env.PORT || 3000

app.use(express.json())

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs))

app.use('/', routes)

export const server = app.listen(port, () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ethers } from 'ethers'
import { Synapse } from '../services/synapseService'
import { getTokenDecimals } from '../utils/getTokenDecimals'

export const getBridgeTxStatusController = async (req, res) => {
export const bridgeTxStatusController = async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
Expand Down Expand Up @@ -72,7 +72,7 @@ export const getBridgeTxStatusController = async (req, res) => {
} catch (err) {
res.status(500).json({
error:
'An unexpected error occurred in /getBridgeTxStatus. Please try again later.',
'An unexpected error occurred in /bridgeTxStatus. Please try again later.',
details: err.message,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ethers } from 'ethers'

import { getTokenDecimals } from '../utils/getTokenDecimals'

export const getDestinationTxController = async (req, res) => {
export const destinationTxController = async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
Expand Down Expand Up @@ -65,7 +65,7 @@ export const getDestinationTxController = async (req, res) => {
} catch (err) {
res.status(500).json({
error:
'An unexpected error occurred in /getDestinationTx. Please try again later.',
'An unexpected error occurred in /destinationTx. Please try again later.',
details: err.message,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { validationResult } from 'express-validator'

import { Synapse } from '../services/synapseService'

export const getSynapseTxIdController = async (req, res) => {
export const synapseTxIdController = async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
Expand All @@ -16,11 +16,12 @@ export const getSynapseTxIdController = async (req, res) => {
bridgeModule,
txHash
)

res.json({ synapseTxId })
} catch (err) {
res.status(500).json({
error:
'An unexpected error occurred in /getSynapseTxId. Please try again later.',
'An unexpected error occurred in /synapseTxId. Please try again later.',
details: err.message,
})
}
Expand Down
175 changes: 175 additions & 0 deletions packages/rest-api/src/routes/bridgeRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,181 @@ import { checksumAddresses } from '../middleware/checksumAddresses'

const router = express.Router()

/**
* @openapi
* /bridge:
* get:
* summary: Get quotes for bridging tokens between chains
* description: Retrieve list of detailed bridge quotes based on origin and destination chains based on tokens and amount
* parameters:
* - in: query
* name: fromChain
* required: true
* schema:
* type: integer
* description: The source chain ID
* - in: query
* name: toChain
* required: true
* schema:
* type: integer
* description: The destination chain ID
* - in: query
* name: fromToken
* required: true
* schema:
* type: string
* description: The address of the token on the source chain
* - in: query
* name: toToken
* required: true
* schema:
* type: string
* description: The address of the token on the destination chain
* - in: query
* name: amount
* required: true
* schema:
* type: number
* description: The amount of tokens to bridge
* responses:
* 200:
* description: Successful response
* content:
* application/json:
* schema:
* type: array
* items:
* type: object
* properties:
* id:
* type: string
* feeAmount:
* $ref: '#/components/schemas/BigNumber'
* feeConfig:
* type: object
* properties:
* bridgeFee:
* type: integer
* minFee:
* $ref: '#/components/schemas/BigNumber'
abtestingalpha marked this conversation as resolved.
Show resolved Hide resolved
* maxFee:
* $ref: '#/components/schemas/BigNumber'
* routerAddress:
* type: string
* maxAmountOut:
* $ref: '#/components/schemas/BigNumber'
* originQuery:
* type: object
* destQuery:
* type: object
* estimatedTime:
* type: integer
* bridgeModuleName:
* type: string
* gasDropAmount:
* $ref: '#/components/schemas/BigNumber'
* originChainId:
* type: integer
* destChainId:
* type: integer
* maxAmountOutStr:
* type: string
* bridgeFeeFormatted:
* type: string
* example:
* - id: "01920c87-7f14-7cdf-90e1-e13b2d4af55f"
* feeAmount:
* type: "BigNumber"
* hex: "0x17d78400"
* feeConfig:
* bridgeFee: 4000000
* minFee:
* type: "BigNumber"
* hex: "0x3d0900"
* maxFee:
* type: "BigNumber"
* hex: "0x17d78400"
* routerAddress: "0xd5a597d6e7ddf373a92C8f477DAAA673b0902F48"
* maxAmountOut:
* type: "BigNumber"
* hex: "0xe89bd2cb27"
* originQuery:
* routerAdapter: "0x0000000000000000000000000000000000000000"
* tokenOut: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
abtestingalpha marked this conversation as resolved.
Show resolved Hide resolved
* minAmountOut:
* type: "BigNumber"
* hex: "0xe8d4a51000"
* deadline:
* type: "BigNumber"
* hex: "0x66ecb04b"
* rawParams: "0x"
* destQuery:
* routerAdapter: "0xd5a597d6e7ddf373a92C8f477DAAA673b0902F48"
* tokenOut: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"
* minAmountOut:
* type: "BigNumber"
* hex: "0xe89bd2cb27"
* deadline:
* type: "BigNumber"
* hex: "0x66f5e873"
* rawParams: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a2dea7b81cfe3e0011d44d41c5c5142b8d9abdf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"
* estimatedTime: 1020
* bridgeModuleName: "SynapseCCTP"
* gasDropAmount:
* type: "BigNumber"
* hex: "0x0110d9316ec000"
* originChainId: 1
* destChainId: 42161
* maxAmountOutStr: "999046.695719"
* bridgeFeeFormatted: "400"
abtestingalpha marked this conversation as resolved.
Show resolved Hide resolved
* 400:
* description: Invalid input
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* type: object
* properties:
* value:
* type: string
* message:
* type: string
* field:
* type: string
* location:
* type: string
* example:
* error:
* value: "999"
* message: "Unsupported fromChain"
* field: "fromChain"
* location: "query"
* 500:
* description: Server error
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* type: string
* details:
* type: string
*
* components:
* schemas:
* BigNumber:
* type: object
* properties:
* type:
* type: string
* enum: [BigNumber]
* hex:
* type: string
*/
router.get(
'/',
checksumAddresses(['fromToken', 'toToken']),
Expand Down
Loading
Loading