Skip to content

Commit

Permalink
refactoring according to comments
Browse files Browse the repository at this point in the history
  • Loading branch information
lendihop committed Jun 3, 2024
1 parent 200d220 commit 087adc4
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 53 deletions.
84 changes: 31 additions & 53 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
getEvmTokensMetadata
} from './utils/covalent';
import { CodedError } from './utils/errors';
import { withCodedExceptionHandler, withEvmQueryValidation } from './utils/express-helpers';
import { coinGeckoTokens } from './utils/gecko-tokens';
import { getExternalApiErrorPayload, isDefined, isNonEmptyString } from './utils/helpers';
import logger from './utils/logger';
Expand Down Expand Up @@ -386,68 +387,45 @@ app.get('/api/signing-nonce', (req, res) => {
}
}
});
app.get('/api/evm-balances', async (req, res) => {
try {
const { walletAddress, chainId } = req.query;

if (typeof walletAddress !== 'string') throw new Error('walletAddress is not a string');
if (typeof chainId !== 'string') throw new Error('chainId is not a string');

const data = await getEvmBalances(walletAddress, chainId);
app.get(
'/api/evm-balances',
withCodedExceptionHandler(
withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => {
const { walletAddress, chainId } = evmQueryParams;

res.status(200).send(getStringifiedResponse(data));
} catch (error: any) {
console.error(error);
const data = await getEvmBalances(walletAddress, chainId);

if (error instanceof CodedError) {
res.status(error.code).send(error.buildResponse());
} else {
res.status(500).send({ message: error?.message });
}
}
});

app.get('/api/evm-tokens-metadata', async (req, res) => {
try {
const { walletAddress, chainId } = req.query;

if (typeof walletAddress !== 'string') throw new Error('walletAddress is not a string');
if (typeof chainId !== 'string') throw new Error('chainId is not a string');
res.status(200).send(getStringifiedResponse(data));
})
)
);

const data = await getEvmTokensMetadata(walletAddress, chainId);
app.get(
'/api/evm-tokens-metadata',
withCodedExceptionHandler(
withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => {
const { walletAddress, chainId } = evmQueryParams;

res.status(200).send(getStringifiedResponse(data));
} catch (error: any) {
console.error(error);
const data = await getEvmTokensMetadata(walletAddress, chainId);

if (error instanceof CodedError) {
res.status(error.code).send(error.buildResponse());
} else {
res.status(500).send({ message: error?.message });
}
}
});

app.get('/api/evm-collectibles-metadata', async (req, res) => {
try {
const { walletAddress, chainId } = req.query;

if (typeof walletAddress !== 'string') throw new Error('walletAddress is not a string');
if (typeof chainId !== 'string') throw new Error('chainId is not a string');
res.status(200).send(getStringifiedResponse(data));
})
)
);

const data = await getEvmCollectiblesMetadata(walletAddress, chainId);
app.get(
'/api/evm-collectibles-metadata',
withCodedExceptionHandler(
withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => {
const { walletAddress, chainId } = evmQueryParams;

res.status(200).send(getStringifiedResponse(data));
} catch (error: any) {
console.error(error);
const data = await getEvmCollectiblesMetadata(walletAddress, chainId);

if (error instanceof CodedError) {
res.status(error.code).send(error.buildResponse());
} else {
res.status(500).send({ message: error?.message });
}
}
});
res.status(200).send(getStringifiedResponse(data));
})
)
);

const swaggerOptions = {
swaggerDefinition: {
Expand Down
48 changes: 48 additions & 0 deletions src/utils/express-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { NextFunction, Request, RequestHandler, Response, Router } from 'express
import { ArraySchema as IArraySchema, ObjectSchema as IObjectSchema, Schema, ValidationError } from 'yup';

import { basicAuth } from '../middlewares/basic-auth.middleware';
import { CodedError } from './errors';
import logger from './logger';
import { evmQueryParamsSchema } from './schemas';

interface ObjectStorageMethods<V> {
getByKey: (key: string) => Promise<V>;
Expand Down Expand Up @@ -33,6 +35,36 @@ export const withBodyValidation =
return handler(req, res, next);
};

interface EvmQueryParams {
walletAddress: string;
chainId: string;
}

type TypedEvmQueryRequestHandler = (
req: Request,
res: Response,
next: NextFunction,
evmQueryParams: EvmQueryParams
) => void;

export const withEvmQueryValidation =
(handler: TypedEvmQueryRequestHandler): RequestHandler =>
async (req, res, next) => {
let evmQueryParams: EvmQueryParams;

try {
evmQueryParams = await evmQueryParamsSchema.validate(req.query);
} catch (error) {
if (error instanceof ValidationError) {
return res.status(400).send({ error: error.message });
}

throw error;
}

return handler(req, res, next, evmQueryParams);
};

export const withExceptionHandler =
(handler: RequestHandler): RequestHandler =>
async (req, res, next) => {
Expand All @@ -44,6 +76,22 @@ export const withExceptionHandler =
}
};

export const withCodedExceptionHandler =
(handler: RequestHandler): RequestHandler =>
async (req, res, next) => {
try {
await handler(req, res, next);
} catch (error: any) {

Check warning on line 84 in src/utils/express-helpers.ts

View workflow job for this annotation

GitHub Actions / Checks if ts and lint works

Unexpected any. Specify a different type
logger.error(error);

if (error instanceof CodedError) {
res.status(error.code).send(error.buildResponse());
} else {
res.status(500).send({ message: error?.message });
}
}
};

interface ObjectStorageMethodsEntrypointsConfig<StoredValue, ObjectResponse, ValueResponse> {
path: string;
methods: ObjectStorageMethods<StoredValue>;
Expand Down
5 changes: 5 additions & 0 deletions src/utils/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ const adStylesOverridesSchema = objectSchema().shape({
style: styleSchema.clone().required()
});

export const evmQueryParamsSchema = objectSchema().shape({
walletAddress: nonEmptyStringSchema.clone().required('walletAddress is undefined'),
chainId: nonEmptyStringSchema.clone().required('chainId is undefined')
});

const adPlacesRulesSchema = arraySchema()
.of(
objectSchema()
Expand Down

0 comments on commit 087adc4

Please sign in to comment.