abstract handler typing changes
This commit is contained in:
parent
57b7940a12
commit
bd15f29631
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Reference in New Issue