Skip to content

Commit

Permalink
Merge pull request #63 from EigenExplorer/55-withdraw-api
Browse files Browse the repository at this point in the history
55 withdraw api
  • Loading branch information
uditdc authored May 18, 2024
2 parents ee81102 + f21fb2d commit a6a6eae
Show file tree
Hide file tree
Showing 11 changed files with 645 additions and 1 deletion.
2 changes: 2 additions & 0 deletions packages/api/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import strategiesRoutes from './strategies/strategiesRoutes'
import operatorRoutes from './operators/operatorRoutes'
import stakerRoutes from './stakers/stakerRoutes'
import metricRoutes from './metrics/metricRoutes'
import withdrawalRoutes from './withdrawals/withdrawalRoutes'

const apiRouter = express.Router()

Expand All @@ -12,5 +13,6 @@ apiRouter.use('/strategies', strategiesRoutes)
apiRouter.use('/operators', operatorRoutes)
apiRouter.use('/stakers', stakerRoutes)
apiRouter.use('/metrics', metricRoutes)
apiRouter.use('/withdrawals', withdrawalRoutes)

export default apiRouter
228 changes: 228 additions & 0 deletions packages/api/src/routes/stakers/stakerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Request, Response } from 'express'
import prisma from '../../utils/prismaClient'
import { handleAndReturnErrorResponse } from '../../schema/errors'
import { PaginationQuerySchema } from '../../schema/zod/schemas/paginationQuery'
import { getViemClient } from '../../viem/viemClient'

/**
* Route to get a list of all stakers
Expand Down Expand Up @@ -84,3 +85,230 @@ export async function getStaker(req: Request, res: Response) {
handleAndReturnErrorResponse(req, res, error)
}
}

export async function getStakerWithdrawals(req: Request, res: Response) {
// Validate query
const result = PaginationQuerySchema.safeParse(req.query)
if (!result.success) {
return handleAndReturnErrorResponse(req, res, result.error)
}

const { skip, take } = result.data

try {
const { address } = req.params
const filterQuery = { stakerAddress: address }

const withdrawalCount = await prisma.withdrawal.count({
where: filterQuery
})
const withdrawalRecords = await prisma.withdrawal.findMany({
where: filterQuery,
skip,
take,
orderBy: { startBlock: 'desc' }
})

const data = withdrawalRecords.map((withdrawal) => {
const shares = withdrawal.shares.map((s, i) => ({
strategyAddress: withdrawal.strategies[i],
shares: s
}))

return {
...withdrawal,
shares,
strategies: undefined,
startBlock: Number(withdrawal.startBlock),
createdAtBlock: Number(withdrawal.createdAtBlock),
updatedAtBlock: Number(withdrawal.updatedAtBlock)
}
})

res.send({
data,
meta: {
total: withdrawalCount,
skip,
take
}
})
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}

export async function getStakerWithdrawalsQueued(req: Request, res: Response) {
// Validate query
const result = PaginationQuerySchema.safeParse(req.query)
if (!result.success) {
return handleAndReturnErrorResponse(req, res, result.error)
}

const { skip, take } = result.data

try {
const { address } = req.params
const filterQuery = { stakerAddress: address, isCompleted: false }

const withdrawalCount = await prisma.withdrawal.count({
where: filterQuery
})
const withdrawalRecords = await prisma.withdrawal.findMany({
where: filterQuery,
skip,
take,
orderBy: { startBlock: 'desc' }
})

const data = withdrawalRecords.map((withdrawal) => {
const shares = withdrawal.shares.map((s, i) => ({
strategyAddress: withdrawal.strategies[i],
shares: s
}))

return {
...withdrawal,
shares,
strategies: undefined,
startBlock: Number(withdrawal.startBlock),
createdAtBlock: Number(withdrawal.createdAtBlock),
updatedAtBlock: Number(withdrawal.updatedAtBlock)
}
})

res.send({
data,
meta: {
total: withdrawalCount,
skip,
take
}
})
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}

export async function getStakerWithdrawalsWithdrawable(
req: Request,
res: Response
) {
// Validate query
const result = PaginationQuerySchema.safeParse(req.query)
if (!result.success) {
return handleAndReturnErrorResponse(req, res, result.error)
}

const { skip, take } = result.data

try {
const { address } = req.params

const viemClient = getViemClient()
const minDelayBlocks = await prisma.settings.findUnique({
where: { key: 'withdrawMinDelayBlocks' }
})
const minDelayBlock =
(await viemClient.getBlockNumber()) -
BigInt((minDelayBlocks?.value as string) || 0)

const filterQuery = {
stakerAddress: address,
isCompleted: false,
startBlock: { lte: minDelayBlock }
}

const withdrawalCount = await prisma.withdrawal.count({
where: filterQuery
})
const withdrawalRecords = await prisma.withdrawal.findMany({
where: filterQuery,
skip,
take,
orderBy: { startBlock: 'desc' }
})

const data = withdrawalRecords.map((withdrawal) => {
const shares = withdrawal.shares.map((s, i) => ({
strategyAddress: withdrawal.strategies[i],
shares: s
}))

return {
...withdrawal,
shares,
strategies: undefined,
startBlock: Number(withdrawal.startBlock),
createdAtBlock: Number(withdrawal.createdAtBlock),
updatedAtBlock: Number(withdrawal.updatedAtBlock)
}
})

res.send({
data,
meta: {
total: withdrawalCount,
skip,
take
}
})
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}

export async function getStakerWithdrawalsCompleted(
req: Request,
res: Response
) {
// Validate query
const result = PaginationQuerySchema.safeParse(req.query)
if (!result.success) {
return handleAndReturnErrorResponse(req, res, result.error)
}

const { skip, take } = result.data

try {
const { address } = req.params
const filterQuery = { stakerAddress: address, isCompleted: true }

const withdrawalCount = await prisma.withdrawal.count({
where: filterQuery
})
const withdrawalRecords = await prisma.withdrawal.findMany({
where: filterQuery,
skip,
take,
orderBy: { startBlock: 'desc' }
})

const data = withdrawalRecords.map((withdrawal) => {
const shares = withdrawal.shares.map((s, i) => ({
strategyAddress: withdrawal.strategies[i],
shares: s
}))

return {
...withdrawal,
shares,
strategies: undefined,
startBlock: Number(withdrawal.startBlock),
createdAtBlock: Number(withdrawal.createdAtBlock),
updatedAtBlock: Number(withdrawal.updatedAtBlock)
}
})

res.send({
data,
meta: {
total: withdrawalCount,
skip,
take
}
})
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}
17 changes: 16 additions & 1 deletion packages/api/src/routes/stakers/stakerRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import express from 'express'
import { getAllStakers, getStaker } from './stakerController'
import {
getAllStakers,
getStaker,
getStakerWithdrawals,
getStakerWithdrawalsCompleted,
getStakerWithdrawalsQueued,
getStakerWithdrawalsWithdrawable
} from './stakerController'

const router = express.Router()

router.get('/', getAllStakers)

router.get('/:address', getStaker)

router.get('/:address/withdrawals', getStakerWithdrawals)
router.get('/:address/withdrawals/queued', getStakerWithdrawalsQueued)
router.get(
'/:address/withdrawals/queued_withdrawable',
getStakerWithdrawalsWithdrawable
)
router.get('/:address/withdrawals/completed', getStakerWithdrawalsCompleted)

export default router
Loading

0 comments on commit a6a6eae

Please sign in to comment.