Skip to content

Commit

Permalink
bridge endpoint and swap endpoint consolidation for swap data
Browse files Browse the repository at this point in the history
  • Loading branch information
Defi-Moses committed Nov 5, 2024
1 parent 7c5c4f1 commit 2782388
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 19 deletions.
62 changes: 44 additions & 18 deletions packages/rest-api/src/controllers/bridgeController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@ export const bridgeController = async (req, res) => {
fromToken,
toToken,
originUserAddress,
} = req.query
destAddress, // Optional parameter
} = req.query as {
fromChain: string
toChain: string
amount: string
fromToken: string
toToken: string
originUserAddress?: string
destAddress?: string
}

const fromTokenInfo = tokenAddressToToken(fromChain.toString(), fromToken)
const toTokenInfo = tokenAddressToToken(toChain.toString(), toToken)
Expand All @@ -37,23 +46,40 @@ export const bridgeController = async (req, res) => {
: {}
)

const payload = resp.map((quote) => {
const originQueryTokenOutInfo = tokenAddressToToken(
fromChain.toString(),
quote.originQuery.tokenOut
)
return {
...quote,
maxAmountOutStr: formatBNToString(
quote.maxAmountOut,
toTokenInfo.decimals
),
bridgeFeeFormatted: formatBNToString(
quote.feeAmount,
originQueryTokenOutInfo.decimals
),
}
})
const payload = await Promise.all(
resp.map(async (quote) => {
const originQueryTokenOutInfo = tokenAddressToToken(
fromChain.toString(),
quote.originQuery.tokenOut
)

const callData = destAddress
? await Synapse.bridge(
destAddress,
quote.routerAddress,
Number(fromChain),
Number(toChain),
fromToken,
amountInWei,
quote.originQuery,
quote.destQuery
)
: null

return {
...quote,
maxAmountOutStr: formatBNToString(
quote.maxAmountOut,
toTokenInfo.decimals
),
bridgeFeeFormatted: formatBNToString(
quote.feeAmount,
originQueryTokenOutInfo.decimals
),
callData,
}
})
)

logger.info(`Successful bridgeController response`, {
payload,
Expand Down
13 changes: 12 additions & 1 deletion packages/rest-api/src/controllers/swapController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const swapController = async (req, res) => {
return res.status(400).json({ errors: errors.array() })
}
try {
const { chain, amount, fromToken, toToken } = req.query
const { chain, amount, fromToken, toToken, address } = req.query

const fromTokenInfo = tokenAddressToToken(chain.toString(), fromToken)
const toTokenInfo = tokenAddressToToken(chain.toString(), toToken)
Expand All @@ -30,9 +30,20 @@ export const swapController = async (req, res) => {
toTokenInfo.decimals
)

const callData = address
? await Synapse.swap(
Number(chain),
address,
fromToken,
amountInWei,
quote.query
)
: null

const payload = {
...quote,
maxAmountOut: formattedMaxAmountOut,
callData,
}

logger.info(`Successful swapController response`, {
Expand Down
20 changes: 20 additions & 0 deletions packages/rest-api/src/routes/bridgeRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ const router: express.Router = express.Router()
* schema:
* type: string
* description: The address of the user on the origin chain
* - in: query
* name: destAddress
* required: false
* schema:
* type: string
* description: The destination address for the bridge transaction
* responses:
* 200:
* description: Successful response
Expand Down Expand Up @@ -101,6 +107,16 @@ const router: express.Router = express.Router()
* type: string
* bridgeFeeFormatted:
* type: string
* callData:
* type: object
* nullable: true
* properties:
* to:
* type: string
* data:
* type: string
* value:
* type: string
* example:
* - id: "01920c87-7f14-7cdf-90e1-e13b2d4af55f"
* feeAmount:
Expand Down Expand Up @@ -239,6 +255,10 @@ router.get(
.optional()
.custom((value) => isAddress(value))
.withMessage('Invalid originUserAddress address'),
check('destAddress')
.optional()
.custom((value) => isAddress(value))
.withMessage('Invalid destAddress'),
],
showFirstValidationError,
bridgeController
Expand Down
21 changes: 21 additions & 0 deletions packages/rest-api/src/routes/swapRoute.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import express from 'express'
import { check } from 'express-validator'
import { isAddress } from 'ethers/lib/utils'

import { showFirstValidationError } from '../middleware/showFirstValidationError'
import { swapController } from '../controllers/swapController'
Expand Down Expand Up @@ -44,6 +45,12 @@ const router: express.Router = express.Router()
* schema:
* type: number
* description: The amount of tokens to swap
* - in: query
* name: address
* required: false
* schema:
* type: string
* description: Optional. The address that will perform the swap. If provided, returns transaction data.
* responses:
* 200:
* description: Successful response
Expand Down Expand Up @@ -74,6 +81,16 @@ const router: express.Router = express.Router()
* rawParams:
* type: string
* description: Raw parameters for the swap
* callData:
* type: object
* nullable: true
* properties:
* to:
* type: string
* data:
* type: string
* value:
* type: string
* example:
* routerAddress: "0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a"
* maxAmountOut: "999.746386"
Expand Down Expand Up @@ -176,6 +193,10 @@ router.get(
return validSwapTokens(chain, fromToken, toToken)
})
.withMessage('Swap not supported for given tokens'),
check('address')
.optional()
.custom((value) => isAddress(value))
.withMessage('Invalid address'),
],
showFirstValidationError,
swapController
Expand Down
48 changes: 48 additions & 0 deletions packages/rest-api/src/tests/bridgeRoute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,52 @@ describe('Bridge Route with Real Synapse Service', () => {
expect(response.status).toBe(400)
expect(response.body.error).toHaveProperty('field', 'amount')
})

it('should return bridge quotes with callData when destAddress is provided', async () => {
const response = await request(app).get('/bridge').query({
fromChain: '1',
toChain: '10',
fromToken: USDC.addresses[1],
toToken: USDC.addresses[10],
amount: '1000',
destAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
})

expect(response.status).toBe(200)
expect(Array.isArray(response.body)).toBe(true)
expect(response.body.length).toBeGreaterThan(0)
expect(response.body[0]).toHaveProperty('callData')
expect(response.body[0].callData).toHaveProperty('to')
expect(response.body[0].callData).toHaveProperty('data')
expect(response.body[0].callData).toHaveProperty('value')
}, 15000)

it('should return bridge quotes without callData when destAddress is not provided', async () => {
const response = await request(app).get('/bridge').query({
fromChain: '1',
toChain: '10',
fromToken: USDC.addresses[1],
toToken: USDC.addresses[10],
amount: '1000',
})

expect(response.status).toBe(200)
expect(Array.isArray(response.body)).toBe(true)
expect(response.body.length).toBeGreaterThan(0)
expect(response.body[0].callData).toBeNull()
}, 15000)

it('should return 400 for invalid destAddress', async () => {
const response = await request(app).get('/bridge').query({
fromChain: '1',
toChain: '10',
fromToken: USDC.addresses[1],
toToken: USDC.addresses[10],
amount: '1000',
destAddress: 'invalid_address',
})

expect(response.status).toBe(400)
expect(response.body.error).toHaveProperty('message', 'Invalid destAddress')
}, 15000)
})
47 changes: 47 additions & 0 deletions packages/rest-api/src/tests/swapRoute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,51 @@ describe('Swap Route with Real Synapse Service', () => {
expect(response.status).toBe(400)
expect(response.body.error).toHaveProperty('field', 'amount')
}, 10_000)

it('should return swap quote with callData when address is provided', async () => {
const response = await request(app).get('/swap').query({
chain: '1',
fromToken: USDC.addresses[1],
toToken: DAI.addresses[1],
amount: '1000',
address: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
})

expect(response.status).toBe(200)
expect(response.body).toHaveProperty('maxAmountOut')
expect(response.body).toHaveProperty('routerAddress')
expect(response.body).toHaveProperty('query')
expect(response.body).toHaveProperty('callData')
expect(response.body.callData).toHaveProperty('to')
expect(response.body.callData).toHaveProperty('data')
expect(response.body.callData).toHaveProperty('value')
}, 10_000)

it('should return swap quote without callData when address is not provided', async () => {
const response = await request(app).get('/swap').query({
chain: '1',
fromToken: USDC.addresses[1],
toToken: DAI.addresses[1],
amount: '1000',
})

expect(response.status).toBe(200)
expect(response.body).toHaveProperty('maxAmountOut')
expect(response.body).toHaveProperty('routerAddress')
expect(response.body).toHaveProperty('query')
expect(response.body.callData).toBeNull()
}, 10_000)

it('should return 400 for invalid address', async () => {
const response = await request(app).get('/swap').query({
chain: '1',
fromToken: USDC.addresses[1],
toToken: DAI.addresses[1],
amount: '1000',
address: 'invalid_address',
})

expect(response.status).toBe(400)
expect(response.body.error).toHaveProperty('message', 'Invalid address')
}, 10_000)
})
18 changes: 18 additions & 0 deletions packages/rest-api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,15 @@
"type": "string"
},
"description": "The address of the user on the origin chain"
},
{
"in": "query",
"name": "destAddress",
"required": true,
"schema": {
"type": "string"
},
"description": "The destination address of the user on the destination chain"
}
],
"responses": {
Expand Down Expand Up @@ -1206,6 +1215,15 @@
"type": "number"
},
"description": "The amount of tokens to swap"
},
{
"in": "query",
"name": "address",
"required": true,
"schema": {
"type": "string"
},
"description": "The address of the user"
}
],
"responses": {
Expand Down

0 comments on commit 2782388

Please sign in to comment.