Skip to content

Commit

Permalink
add auth routes for tracking users
Browse files Browse the repository at this point in the history
  • Loading branch information
gowthamsundaresan committed Nov 23, 2024
1 parent 3576ec7 commit 63da809
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 3 deletions.
85 changes: 85 additions & 0 deletions packages/api/src/routes/auth/authController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import type { Request, Response } from 'express'
import { handleAndReturnErrorResponse } from '../../schema/errors'
import { EthereumAddressSchema } from '../../schema/zod/schemas/base/ethereumAddress'
import { RequestHeadersSchema } from '../../schema/zod/schemas/auth'
import prisma from '../../utils/prismaClient'

/**
* Function for route /auth/users/:address/check-status
* Returns whether a given address is registered on EE, if they are an EL staker & if we track their rewards
*
* @param req
* @param res
* @returns
*/
export async function checkUserStatus(req: Request, res: Response) {
const paramCheck = EthereumAddressSchema.safeParse(req.params.address)
if (!paramCheck.success) {
return handleAndReturnErrorResponse(req, res, paramCheck.error)
}

try {
const { address } = req.params

const user = await prisma.user.findUnique({
where: { address: address.toLowerCase() },
include: { staker: true }
})

const isRegistered = !!user
const isStaker = !!user?.staker
const isTracked = !!user?.isTracked

res.send({ isRegistered, isStaker, isTracked })
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}

/**
* Function for route /auth/users/:address/register
* Protected route, adds an address to the User table if it doesn't exist
*
* @param req
* @param res
* @returns
*/
export async function registerUser(req: Request, res: Response) {
const paramCheck = EthereumAddressSchema.safeParse(req.params.address)
if (!paramCheck.success) {
return handleAndReturnErrorResponse(req, res, paramCheck.error)
}

const headerCheck = RequestHeadersSchema.safeParse(req.headers)
if (!headerCheck.success) {
return handleAndReturnErrorResponse(req, res, headerCheck.error)
}

try {
const apiToken = headerCheck.data['X-API-Token']
const authToken = process.env.EE_AUTH_TOKEN

if (!apiToken || apiToken !== authToken) {
throw new Error('Unauthorized access.')
}

const { address } = req.params

const existingUser = await prisma.user.findUnique({
where: { address: address.toLowerCase() }
})

if (!existingUser) {
await prisma.user.create({
data: {
address: address.toLowerCase(),
isTracked: false
}
})
}

res.send({ isNewUser: !existingUser })
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}
12 changes: 12 additions & 0 deletions packages/api/src/routes/auth/authRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import express from 'express'
import routeCache from 'route-cache'
import { checkUserStatus, registerUser } from './authController'

const router = express.Router()

// API routes for /auth

router.get('/users/:address/check-status', routeCache.cacheSeconds(30), checkUserStatus)
router.post('/users/:address/register', routeCache.cacheSeconds(240), registerUser)

export default router
6 changes: 3 additions & 3 deletions packages/api/src/routes/avs/avsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ export async function getAVSRewards(req: Request, res: Response) {
currentSubmission.rewardsSubmissionHash !== submission.rewardsSubmissionHash
) {
if (currentSubmission) {
currentSubmission.totalAmount = currentTotalAmount.toString()
currentSubmission.totalAmount = currentTotalAmount.toFixed(0)
result.submissions.push(currentSubmission)
result.totalSubmissions++
}
Expand Down Expand Up @@ -596,13 +596,13 @@ export async function getAVSRewards(req: Request, res: Response) {
currentSubmission.strategies.push({
strategyAddress,
multiplier: submission.multiplier?.toString() || '0',
amount: amount.toString()
amount: amount.toFixed(0)
})
}

// Add final submission
if (currentSubmission) {
currentSubmission.totalAmount = currentTotalAmount.toString()
currentSubmission.totalAmount = currentTotalAmount.toFixed(0)
result.submissions.push(currentSubmission)
result.totalSubmissions++
result.totalRewards += currentTotalAmountEth.toNumber() // 18 decimals
Expand Down
14 changes: 14 additions & 0 deletions packages/api/src/schema/zod/schemas/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import z from '..'

export const RequestHeadersSchema = z
.object({
'x-api-token': z.string().optional()
})
.transform((headers) => {
const token = Object.keys(headers).find((key) => key.toLowerCase() === 'x-api-token')
return token
? {
'X-API-Token': headers[token]
}
: {}
})
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ CREATE TABLE "StakerTokenRewards" (
-- CreateTable
CREATE TABLE "User" (
"address" TEXT NOT NULL,
"isTracked" BOOLEAN NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "User_pkey" PRIMARY KEY ("address")
Expand All @@ -49,6 +50,9 @@ CREATE TABLE "EventLogs_DistributionRootSubmitted" (
-- CreateIndex
CREATE INDEX "StakerTokenRewards_stakerAddress_idx" ON "StakerTokenRewards"("stakerAddress");

-- CreateIndex
CREATE INDEX "User_address_idx" ON "User"("address");

-- CreateIndex
CREATE INDEX "EventLogs_DistributionRootSubmitted_rewardsCalculationEndTi_idx" ON "EventLogs_DistributionRootSubmitted"("rewardsCalculationEndTimestamp");

Expand Down
3 changes: 3 additions & 0 deletions packages/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,12 @@ model StakerTokenRewards {

model User {
address String @id
isTracked Boolean
createdAt DateTime @default(now())
staker Staker? @relation(fields: [address], references: [address])
@@index([address])
}

model Deposit {
Expand Down
16 changes: 16 additions & 0 deletions packages/seeder/src/seedStakerTokenRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ async function writeToDb(
const dbTransactions: any[] = []

if (action === 'update') {
// Delete all existing snapshots of tracked Stakers
dbTransactions.push(
prismaClient.stakerTokenRewards.deleteMany({
where: {
Expand All @@ -275,8 +276,23 @@ async function writeToDb(
}
})
)
} else {
// Mark User as tracked
dbTransactions.push(
prismaClient.user.updateMany({
where: {
address: {
in: batch.map((record) => record.stakerAddress)
}
},
data: {
isTracked: true
}
})
)
}

// Write all snapshots to db
dbTransactions.push(
prismaClient.stakerTokenRewards.createMany({
data: batch,
Expand Down

0 comments on commit 63da809

Please sign in to comment.