-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathEventDecoder.ts
More file actions
84 lines (75 loc) · 2.71 KB
/
EventDecoder.ts
File metadata and controls
84 lines (75 loc) · 2.71 KB
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
81
82
83
84
import { create, Struct } from "superstruct";
import { Deposit, DepositRaw, DepositRawStruct, SortableEvent } from "../interfaces";
import { toAddressType } from "./AddressUtils";
import { BigNumber } from "./BigNumberUtils";
import { getMessageHash } from "./SpokeUtils";
export interface EventArgsDecoder<TRawArgs, TParsedArgs, TContext = unknown> {
struct: Struct<TRawArgs>;
parse(valid: TRawArgs, context?: TContext): TParsedArgs;
}
function decodeEvent<TRawArgs, TParsedArgs, TContext>(
raw: unknown,
decoder: EventArgsDecoder<TRawArgs, TParsedArgs, TContext>,
context?: TContext
): TParsedArgs {
const validated = create(raw, decoder.struct);
return decoder.parse(validated, context);
}
export function decodeSortableEvent<TRawArgs, TParsedArgs, TContext>(
sortableEvent: SortableEvent,
rawArgs: unknown,
decoder: EventArgsDecoder<TRawArgs, TParsedArgs, TContext>,
context?: TContext
): TParsedArgs & SortableEvent {
// Validate and parse the event-specific args from the raw log.
const parsedArgs = decodeEvent(rawArgs, decoder, context);
// Merge the parsed args with the existing SortableEvent data.
return {
...parsedArgs,
...sortableEvent,
};
}
type SpokePoolClientContext = {
chainId: number;
};
export const DepositArgsDecoder: EventArgsDecoder<
DepositRaw,
Omit<Deposit, "fromLiteChain" | "toLiteChain">,
SpokePoolClientContext
> = {
struct: DepositRawStruct,
parse: (raw, context) => {
if (!context) throw new Error("chainId context is required");
const {
// Separate out fields that are going to be re-typed
depositor,
recipient,
inputToken,
outputToken,
exclusiveRelayer,
depositId,
inputAmount,
outputAmount,
updatedRecipient,
updatedOutputAmount,
// Spread the rest of the fields
...rest
} = raw;
const parsed = {
...rest,
depositor: toAddressType(depositor, context.chainId),
recipient: toAddressType(recipient, raw.destinationChainId),
inputToken: toAddressType(inputToken, context.chainId),
outputToken: toAddressType(outputToken, raw.destinationChainId),
exclusiveRelayer: toAddressType(exclusiveRelayer, raw.destinationChainId),
depositId: BigNumber.from(depositId),
inputAmount: BigNumber.from(inputAmount),
outputAmount: BigNumber.from(outputAmount),
messageHash: getMessageHash(raw.message),
updatedRecipient:
updatedRecipient !== undefined ? toAddressType(updatedRecipient, raw.destinationChainId) : undefined,
updatedOutputAmount: updatedOutputAmount !== undefined ? BigNumber.from(updatedOutputAmount) : undefined,
} satisfies Omit<Deposit, "fromLiteChain" | "toLiteChain">;
return parsed;
},
};