modifying event handler interface
This commit is contained in:
parent
a9099ca22e
commit
57b7940a12
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue