-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathrelayer_auth_verification.ts
67 lines (56 loc) · 2.06 KB
/
relayer_auth_verification.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
import { utils } from 'ethers';
import { getProvider } from '@/utils/provider';
/**
* Verify a relayer's configuration update signature and nonce
* @param configPayload The configuration update payload
* @param signature The signature provided by the relayer
* @param nonce The nonce value to prevent replay attacks
* @throws Error if signature is invalid or nonce has been used
*/
export async function verifyRelayerSignature(
configPayload: Record<string, any>,
signature: string,
nonce: number
): Promise<void> {
try {
// Verify nonce hasn't been used before
if (await hasNonceBeenUsed(nonce)) {
throw new Error('Nonce has already been used');
}
// Add nonce to payload before verifying
const payloadWithNonce = {
...configPayload,
nonce
};
// Convert payload to string and hash it
const payloadStr = JSON.stringify(payloadWithNonce);
const messageHash = utils.keccak256(utils.toUtf8Bytes(payloadStr));
// Create signable message
const prefixedMessage = utils.arrayify(messageHash);
// Recover the address that signed the message
const recoveredAddress = utils.verifyMessage(prefixedMessage, signature);
const checksumAddress = utils.getAddress(recoveredAddress);
// Verify signer is an authorized relayer
if (!await isAuthorizedRelayer(checksumAddress)) {
throw new Error('Signer is not an authorized relayer');
}
// Store nonce as used
await storeUsedNonce(nonce);
} catch (error) {
console.error('Error verifying relayer signature:', error);
throw error;
}
}
// Helper functions that would need to be implemented:
async function hasNonceBeenUsed(nonce: number): Promise<boolean> {
// Check if nonce exists in storage
throw new Error('Not implemented');
}
async function isAuthorizedRelayer(address: string): Promise<boolean> {
// Check if address is in authorized relayer list
throw new Error('Not implemented');
}
async function storeUsedNonce(nonce: number): Promise<void> {
// Store nonce in persistent storage
throw new Error('Not implemented');
}