-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.ts
80 lines (73 loc) · 2.17 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { createLogger } from '@/logger';
import { type Request, type Response } from 'express';
import { validationResult } from 'express-validator';
import deterministicHash from 'deterministic-object-hash';
import { type Hex, keccak256, recoverAddress, toHex } from 'viem';
import { indexerClient } from './ext/indexer';
import { env } from './env';
const logger = createLogger();
export const catchError = async <T>(
promise: Promise<T>
): Promise<[Error | undefined, T | undefined]> => {
try {
const data = await promise;
return [undefined, data];
} catch (error) {
logger.error(`catchError: Error occurred: ${error.message}`, {
stack: error.stack,
});
return [error as Error, undefined];
}
};
export const validateRequest = (req: Request, res: Response): void => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
logger.error('Validation failed', { errors: errors.array() });
res.status(400).json({
message: 'Validation failed',
errors: errors.array(),
});
}
};
export const addressFrom = (index: number): string => {
const address = index.toString(16).padStart(40, '0');
return `0x${address}`;
};
async function deterministicKeccakHash<T>(obj: T): Promise<Hex> {
const hash = await deterministicHash(obj);
return keccak256(toHex(hash));
}
export async function recoverSignerAddress<T>(
obj: T,
signature: Hex
): Promise<Hex> {
return await recoverAddress({
hash: await deterministicKeccakHash(obj),
signature,
});
}
export async function isPoolManager<T>(
obj: T,
signature: Hex,
chainId: number,
alloPoolId: string
): Promise<boolean> {
const validAddresses = await indexerClient.getRoundManager({
chainId,
alloPoolId,
});
if (env.NODE_ENV === 'development' && signature === '0xdeadbeef') {
logger.info('Skipping signature check in development mode');
return true;
}
try {
const address = await recoverSignerAddress(obj, signature);
logger.info(`Recovered address: ${address}`);
return validAddresses.some(
addr => addr.toLowerCase() === address.toLowerCase()
);
} catch {
logger.warn('Failed to recover signer address');
return false;
}
}