abstract handler typing changes

This commit is contained in:
chase-45 2023-11-01 22:19:55 -04:00
parent 57b7940a12
commit bd15f29631
6 changed files with 187 additions and 187 deletions

View File

@ -73,7 +73,7 @@ type HandlerConfig = {
type ConfigFile = {
network: Network;
supportedChains: ChainId[];
rpcs: { chain: ChainId; rpcs: string[] }[];
rpcs: { chain: ChainId; rpc: string }[];
handlers: HandlerConfig[];
};
@ -82,7 +82,7 @@ type Environment = {
configurationPath: any;
configuration: ConfigFile;
supportedChains: ChainId[];
rpcs: Map<ChainId, string[]>;
rpcs: Map<ChainId, string>;
logger: winston.Logger;
};
@ -112,21 +112,17 @@ export async function initializeEnvironment(configurationPath: string) {
}
const configRpcs = json.rpcs;
const rpcs = new Map<ChainId, string[]>();
const rpcs = new Map<ChainId, string>();
for (const chain of supportedChains) {
let rpcArray: string[] = [];
configRpcs.forEach((item: any) => {
//double equals for string/int equality
if (item.chain == chain) {
rpcArray = item.rpcs;
if (!item.rpc) {
throw new Error(`No RPC provided for chain ${chain}`);
}
rpcs.set(chain, item.rpc);
}
});
if (rpcArray.length === 0) {
throw new Error(`No RPCs provided for chain ${chain}`);
}
rpcs.set(chain, rpcArray);
}
environment = {
@ -161,16 +157,16 @@ export function createWatchers(
): AbstractWatcher[] {
const watchers: AbstractWatcher[] = [];
for (const chain of env.supportedChains) {
const rpcs = env.rpcs.get(chain);
if (!rpcs) {
throw new Error(`No RPCs provided for chain ${chain}`);
const rpc = env.rpcs.get(chain);
if (!rpc) {
throw new Error(`No RPC provided for chain ${chain}`);
}
const watcher = new EvmWatcher(
toChainName(chain) + " Watcher",
env.network,
handlers,
chain,
rpcs,
rpc,
env.logger
);
watchers.push(watcher);

View File

@ -2,17 +2,17 @@ import { ChainId, Network } from "@certusone/wormhole-sdk";
import { v4 as uuidv4 } from "uuid";
const { createHash } = require("crypto");
type SyntheticEvent = {
type SyntheticEvent<T> = {
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;
data: T;
};
export default abstract class EventHandler {
export default abstract class AbstractHandler<T> {
public name: string;
constructor(name: string) {
@ -40,7 +40,7 @@ export default abstract class EventHandler {
public abstract handleEventEvm(
chainId: ChainId,
...args: any
): Promise<SyntheticEvent[]>;
): Promise<SyntheticEvent<T>[]>;
public abstract getContractAddressEvm(
network: Network,
chainId: ChainId
@ -50,7 +50,7 @@ export default abstract class EventHandler {
//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) {
public getEventListener(handler: AbstractHandler<T>, chainId: ChainId) {
//@ts-ignore
return (...args) => {
// @ts-ignore
@ -84,8 +84,8 @@ export default abstract class EventHandler {
private wrapEvent(
chainId: ChainId,
version: number,
data: any
): SyntheticEvent {
data: T
): SyntheticEvent<T> {
return {
eventName: this.name,
eventVersion: version,

View File

@ -1,103 +1,105 @@
import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common";
import { ethers } from "ethers";
import { getEnvironment } from "../environment";
import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk";
import AbstractHandler from "./AbstractHandler";
//TODO refactor this to use the new event handler system
export {};
// import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common";
// import { ethers } from "ethers";
// import { getEnvironment } from "../environment";
// import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk";
// import AbstractHandler from "./AbstractHandler";
//TODOD consider additional fields:
// - timestamp
// - block number
// - call data
// - transaction cost
// - full transaction receipt
export type WormholeRelayerDeliveryEventRecord = {
environment: string;
chainId: ChainId;
txHash: string;
recipientContract: string;
sourceChain: number;
sequence: string;
deliveryVaaHash: string;
status: number;
gasUsed: string;
refundStatus: number;
additionalStatusInfo: string;
overridesInfo: string;
};
// //TODOD consider additional fields:
// // - timestamp
// // - block number
// // - call data
// // - transaction cost
// // - full transaction receipt
// export type WormholeRelayerDeliveryEventRecord = {
// environment: string;
// chainId: ChainId;
// txHash: string;
// recipientContract: string;
// sourceChain: number;
// sequence: string;
// deliveryVaaHash: string;
// status: number;
// gasUsed: string;
// refundStatus: number;
// additionalStatusInfo: string;
// overridesInfo: string;
// };
//TODO implement this such that it pushes the event to a database
async function persistRecord(record: WormholeRelayerDeliveryEventRecord) {
console.log(JSON.stringify(record));
}
// //TODO implement this such that it pushes the event to a database
// async function persistRecord(record: WormholeRelayerDeliveryEventRecord) {
// console.log(JSON.stringify(record));
// }
function getEventAbi(): string[] {
return [
"event Delivery(address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)",
];
}
// function getEventAbi(): string[] {
// return [
// "event Delivery(address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)",
// ];
// }
function getEventSignatureEvm(): string {
return "Delivery(address,uint16,uint64,bytes32,uint8,uint256,uint8,bytes,bytes)";
}
// function getEventSignatureEvm(): string {
// return "Delivery(address,uint16,uint64,bytes32,uint8,uint256,uint8,bytes,bytes)";
// }
async function handleEventEvm(
chainId: ChainId,
eventObj: ethers.Event
): Promise<WormholeRelayerDeliveryEventRecord> {
console.log(
`Received Delivery event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}`
);
const environment = await getEnvironment();
const txHash = eventObj.transactionHash;
var abi = getEventAbi();
var iface = new ethers.utils.Interface(abi);
var parsedLog = iface.parseLog(eventObj);
// async function handleEventEvm(
// chainId: ChainId,
// eventObj: ethers.Event
// ): Promise<SyntheticEvent<WormholeRelayerDeliveryEventRecord>> {
// console.log(
// `Received Delivery event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}`
// );
// const environment = await getEnvironment();
// const txHash = eventObj.transactionHash;
// var abi = getEventAbi();
// var iface = new ethers.utils.Interface(abi);
// var parsedLog = iface.parseLog(eventObj);
const recipientContract = parsedLog.args[0];
const sourceChain = parsedLog.args[1];
const sequence = parsedLog.args[2].toString();
const deliveryVaaHash = parsedLog.args[3];
const status = parsedLog.args[4];
const gasUsed = parsedLog.args[5].toString();
const refundStatus = parsedLog.args[6];
const additionalStatusInfo = parsedLog.args[7];
const overridesInfo = parsedLog.args[8];
// const recipientContract = parsedLog.args[0];
// const sourceChain = parsedLog.args[1];
// const sequence = parsedLog.args[2].toString();
// const deliveryVaaHash = parsedLog.args[3];
// const status = parsedLog.args[4];
// const gasUsed = parsedLog.args[5].toString();
// const refundStatus = parsedLog.args[6];
// const additionalStatusInfo = parsedLog.args[7];
// const overridesInfo = parsedLog.args[8];
return {
environment: environment.network,
chainId,
txHash,
recipientContract,
sourceChain,
sequence,
deliveryVaaHash,
status,
gasUsed,
refundStatus,
additionalStatusInfo,
overridesInfo,
};
}
// return AbstractHandler.prototype.wrapEvent(chainId, 1, {
// environment: environment.network,
// chainId,
// txHash,
// recipientContract,
// sourceChain,
// sequence,
// deliveryVaaHash,
// status,
// gasUsed,
// refundStatus,
// additionalStatusInfo,
// overridesInfo,
// });
// }
function getContractAddressEvm(network: Network, chainId: ChainId): string {
return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network);
}
// function getContractAddressEvm(network: Network, chainId: ChainId): string {
// return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network);
// }
function shouldSupportChain(network: Network, chainId: ChainId): boolean {
return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true.
//It might not be true in the future.
}
// function shouldSupportChain(network: Network, chainId: ChainId): boolean {
// return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true.
// //It might not be true in the future.
// }
const WormholeRelayerEventHandler: AbstractHandler<WormholeRelayerDeliveryEventRecord> =
{
name: "Wormhole Relayer Delivery Event Handler",
getEventSignatureEvm,
getEventAbiEvm: getEventAbi,
handleEventEvm,
persistRecord,
getContractAddressEvm,
shouldSupportChain,
getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this
};
// const WormholeRelayerEventHandler: AbstractHandler =
// {
// name: "Wormhole Relayer Delivery Event Handler",
// getEventSignatureEvm,
// getEventAbiEvm: getEventAbi,
// handleEventEvm,
// persistRecord,
// getContractAddressEvm,
// shouldSupportChain,
// getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this
// };
export default WormholeRelayerEventHandler;
// export default WormholeRelayerEventHandler;

View File

@ -1,78 +1,80 @@
import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common";
import { ethers } from "ethers";
import { getEnvironment } from "../environment";
import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk";
import AbstractHandler from "./AbstractHandler";
//TODO refactor this to use the new event handler system
export {};
// import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common";
// import { ethers } from "ethers";
// import { getEnvironment } from "../environment";
// import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk";
// import AbstractHandler from "./AbstractHandler";
//TODOD consider additional fields:
// - timestamp
// - entire transaction receipt
// - deduplication info
export type WormholeRelayerSendEventRecord = {
environment: string;
chainId: ChainId;
txHash: string;
sequence: string;
deliveryQuote: string;
paymentForExtraReceiverValue: string;
};
// //TODOD consider additional fields:
// // - timestamp
// // - entire transaction receipt
// // - deduplication info
// export type WormholeRelayerSendEventRecord = {
// environment: string;
// chainId: ChainId;
// txHash: string;
// sequence: string;
// deliveryQuote: string;
// paymentForExtraReceiverValue: string;
// };
//TODO implement this such that it pushes the event to a database
async function persistRecord(record: WormholeRelayerSendEventRecord) {
console.log(JSON.stringify(record));
}
// //TODO implement this such that it pushes the event to a database
// async function persistRecord(record: WormholeRelayerSendEventRecord) {
// console.log(JSON.stringify(record));
// }
function getEventAbiEvm(): string[] {
return [
"event SendEvent(uint64 indexed sequence, uint256 deliveryQuote, uint256 paymentForExtraReceiverValue)",
];
}
// function getEventAbiEvm(): string[] {
// return [
// "event SendEvent(uint64 indexed sequence, uint256 deliveryQuote, uint256 paymentForExtraReceiverValue)",
// ];
// }
async function handleEventEvm(
chainId: ChainId,
eventObj: ethers.Event
): Promise<WormholeRelayerSendEventRecord | null> {
console.log(
`Received Send event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}`
);
const abi = getEventAbiEvm();
var iface = new ethers.utils.Interface(abi);
var parsedLog = iface.parseLog(eventObj);
// async function handleEventEvm(
// chainId: ChainId,
// eventObj: ethers.Event
// ): Promise<WormholeRelayerSendEventRecord | null> {
// console.log(
// `Received Send event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}`
// );
// const abi = getEventAbiEvm();
// var iface = new ethers.utils.Interface(abi);
// var parsedLog = iface.parseLog(eventObj);
return {
//TODO env type broke
environment: await getEnvironment().network,
chainId: chainId,
txHash: eventObj.transactionHash,
sequence: parsedLog.args[0].toString(),
deliveryQuote: parsedLog.args[1].toString(),
paymentForExtraReceiverValue: parsedLog.args[2].toString(),
};
}
// return {
// //TODO env type broke
// environment: await getEnvironment().network,
// chainId: chainId,
// txHash: eventObj.transactionHash,
// sequence: parsedLog.args[0].toString(),
// deliveryQuote: parsedLog.args[1].toString(),
// paymentForExtraReceiverValue: parsedLog.args[2].toString(),
// };
// }
function getContractAddressEvm(network: Network, chainId: ChainId): string {
return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network);
}
// function getContractAddressEvm(network: Network, chainId: ChainId): string {
// return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network);
// }
function shouldSupportChain(network: Network, chainId: ChainId): boolean {
return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true.
//It might not be true in the future.
}
// function shouldSupportChain(network: Network, chainId: ChainId): boolean {
// return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true.
// //It might not be true in the future.
// }
function getEventSignatureEvm(): string {
return "SendEvent(uint64,uint256,uint256)";
}
// function getEventSignatureEvm(): string {
// return "SendEvent(uint64,uint256,uint256)";
// }
const WormholeRelayerSendEventHandler: AbstractHandler<WormholeRelayerSendEventRecord> =
{
name: "Wormhole Relayer Send Event Handler",
getEventSignatureEvm,
getEventAbiEvm,
handleEventEvm,
persistRecord,
getContractAddressEvm,
shouldSupportChain,
getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this
};
// const WormholeRelayerSendEventHandler: AbstractHandler<WormholeRelayerSendEventRecord> =
// {
// name: "Wormhole Relayer Send Event Handler",
// getEventSignatureEvm,
// getEventAbiEvm,
// handleEventEvm,
// persistRecord,
// getContractAddressEvm,
// shouldSupportChain,
// getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this
// };
export default WormholeRelayerSendEventHandler;
// export default WormholeRelayerSendEventHandler;

View File

@ -7,7 +7,7 @@ export default abstract class AbstractWatcher {
public environment: Network;
public events: AbstractHandler<any>[];
public chain: ChainId;
public rpcs: string[];
public rpc: string;
public logger: any;
//TODO add persistence module(s) as class fields
@ -18,14 +18,14 @@ export default abstract class AbstractWatcher {
environment: Network,
events: AbstractHandler<any>[],
chain: ChainId,
rpcs: string[],
rpc: string,
logger: any
) {
this.watcherName = watcherName;
this.environment = environment;
this.events = events;
this.chain = chain;
this.rpcs = rpcs;
this.rpc = rpc;
this.logger = logger;
}

View File

@ -8,10 +8,10 @@ export default class EvmWatcher extends AbstractWatcher {
environment: Network,
events: AbstractHandler<any>[],
chain: ChainId,
rpcs: string[],
rpc: string,
logger: any
) {
super(watcherName, environment, events, chain, rpcs, logger);
super(watcherName, environment, events, chain, rpc, logger);
}
async startWebsocketProcessor(): Promise<void> {