modifying event handler interface

This commit is contained in:
chase-45 2023-11-01 21:59:32 -04:00
parent a9099ca22e
commit 57b7940a12
3 changed files with 119 additions and 21 deletions

View File

@ -10,10 +10,12 @@
"license": "ISC",
"dependencies": {
"@certusone/wormhole-sdk": "^0.9.21-beta.0",
"dotenv": "^16.3.1"
"dotenv": "^16.3.1",
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/koa-router": "^7.4.4",
"@types/uuid": "^9.0.6",
"@types/yargs": "^17.0.23",
"nodemon": "^2.0.20",
"prettier": "^2.8.7",
@ -2552,6 +2554,12 @@
"integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==",
"dev": true
},
"node_modules/@types/uuid": {
"version": "9.0.6",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz",
"integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
"dev": true
},
"node_modules/@types/ws": {
"version": "7.4.7",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz",
@ -4367,6 +4375,14 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
},
"node_modules/jayson/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/js-base64": {
"version": "3.7.5",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz",
@ -5159,6 +5175,14 @@
"utf-8-validate": "^5.0.2"
}
},
"node_modules/rpc-websockets/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/rpc-websockets/node_modules/ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
@ -5799,9 +5823,13 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist/bin/uuid"
}
@ -7929,6 +7957,12 @@
"integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==",
"dev": true
},
"@types/uuid": {
"version": "9.0.6",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz",
"integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
"dev": true
},
"@types/ws": {
"version": "7.4.7",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz",
@ -9378,6 +9412,11 @@
"version": "12.20.55",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}
}
},
@ -10015,6 +10054,11 @@
"ws": "^8.5.0"
},
"dependencies": {
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
@ -10497,9 +10541,9 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
},
"v8-compile-cache-lib": {
"version": "3.0.1",

View File

@ -13,7 +13,8 @@
"license": "ISC",
"dependencies": {
"@certusone/wormhole-sdk": "^0.9.21-beta.0",
"dotenv": "^16.3.1"
"dotenv": "^16.3.1",
"uuid": "^9.0.1"
},
"peerDependencies": {
"ethers": "^5",
@ -21,11 +22,12 @@
},
"devDependencies": {
"@types/koa-router": "^7.4.4",
"@types/uuid": "^9.0.6",
"@types/yargs": "^17.0.23",
"nodemon": "^2.0.20",
"prettier": "^2.8.7",
"tsx": "^3.12.7",
"ts-node": "^10.9.1",
"tsx": "^3.12.7",
"typescript": "^4.8.4",
"winston": "^3.8.2"
}

View File

@ -1,37 +1,65 @@
import { ChainId, Network } from "@certusone/wormhole-sdk";
import { v4 as uuidv4 } from "uuid";
const { createHash } = require("crypto");
export default abstract class EventHandler<T> {
type SyntheticEvent = {
eventName: string;
eventVersion: number;
eventChain: ChainId;
observationTimestamp: number;
uuid: string; //UUID for the event, good for deduping
dataHash: string; //sha256 hash of the event data, good for deduping
data: any;
};
export default abstract class EventHandler {
public name: string;
constructor(name: string) {
this.name = name;
}
public abstract getEventSignatureEvm(): string | null;
public abstract getEventAbiEvm(): string[] | null;
public abstract handleEventEvm(
chainId: ChainId,
...args: any
): Promise<T | null>;
//These top level functions must always be implemented
public abstract shouldSupportChain(
network: Network,
chainId: ChainId
): boolean;
public abstract persistRecord(record: T): Promise<void>;
//These functions must be implemented if an EVM chain is supported.
//Event to be listened for in ABI format. Example:
//"event Delivery(address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)",
public abstract getEventAbiEvm(): string[] | null;
//Event to be listened for in signature format. Example:
//"Delivery(address,uint16,uint64,bytes32,uint8,uint256,uint8,bytes,bytes)"
public abstract getEventSignatureEvm(): string | null;
//This function will be called when a subscribed event is received from the ethers provider.
//TODO pretty sure the ...args is always an ethers.Event object
public abstract handleEventEvm(
chainId: ChainId,
...args: any
): Promise<SyntheticEvent[]>;
public abstract getContractAddressEvm(
network: Network,
chainId: ChainId
): string;
public getEventListener(handler: EventHandler<any>, chainId: ChainId) {
//*** Non-abstract functions
//Wrapper function to hand into EVM rpc provider.
//The wrapper is necessary otherwise we can't figure out which chain ID the event came from.
public getEventListener(handler: EventHandler, chainId: ChainId) {
//@ts-ignore
return (...args) => {
// @ts-ignore
return handler
.handleEventEvm(chainId, ...args)
.then((record) => {
if (record) {
handler.persistRecord(record);
.then((records) => {
if (records) {
//TODO persist records. Unsure how exactly this happens atm.
//handler.persistRecord(record);
}
})
.catch((e) => {
@ -44,4 +72,28 @@ export default abstract class EventHandler<T> {
});
};
}
public getName(): string {
return this.name;
}
public generateUuid(): string {
return uuidv4();
}
private wrapEvent(
chainId: ChainId,
version: number,
data: any
): SyntheticEvent {
return {
eventName: this.name,
eventVersion: version,
eventChain: chainId,
observationTimestamp: Date.now(),
uuid: this.generateUuid(),
dataHash: createHash("sha256").update(JSON.stringify(data)).digest("hex"),
data: data,
};
}
}