import * as ethers from "ethers"; import * as solana from "@solana/web3.js"; import * as sui from "@mysten/sui.js"; import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"; import { ChainId, EVMChainId, ParsedVaa, SignedVaa, } from "@certusone/wormhole-sdk"; import * as winston from "winston"; /* * Config */ // subset of common env that plugins should have access to export interface CommonPluginEnv { supportedChains: ChainConfigInfo[]; wormholeRpc: string; } export interface ChainConfigInfo { chainId: ChainId; chainName: string; nodeUrl: string; } /* * Storage */ export interface Workflow { id: WorkflowId; pluginName: string; scheduledAt?: Date; scheduledBy?: string; retryCount: number; maxRetries?: number; data: D; failedAt?: Date; errorMessage?: string; errorStacktrace?: string; completedAt?: Date; startedProcessingAt?: Date; processingBy?: string; emitterChain?: number; emitterAddress?: string; sequence?: string; } export interface ActionExecutor { (action: Action): Promise; onSolana(f: ActionFunc): Promise; onEVM(action: Action): Promise; onSui(action: Action): Promise; } export type ActionFunc = ( walletToolBox: WalletToolBox, chaindId: ChainId, ) => Promise; export interface Action { chainId: ChainId; f: ActionFunc; } export type WorkflowId = string; /* * Wallets and Providers */ export type UntypedProvider = { rpcUrl: string; }; export type EVMWallet = ethers.Wallet; export type UntypedWallet = UntypedProvider & { privateKey: string; }; export type SolanaWallet = { conn: solana.Connection; payer: solana.Keypair; }; export type Wallet = EVMWallet | SolanaWallet | UntypedWallet; export interface WalletToolBox extends Providers { wallet: T; } export interface Providers { untyped: Partial>; evm: Partial>; solana: solana.Connection; sui: sui.JsonRpcProvider; sei: CosmWasmClient; } export interface ParsedVaaWithBytes extends ParsedVaa { bytes: SignedVaa; } /* * Plugin interfaces */ // Function signature passed to the relayer-engine's `run` function // The engine will provide the config and a scoped logger export type EngineInitFn = ( engineConfig: CommonPluginEnv, logger: winston.Logger, ) => PluginType; export interface WorkflowOptions { maxRetries?: number; } export interface Plugin { pluginName: string; // String identifier for plugin pluginConfig: any; // Configuration settings for plugin shouldSpy: boolean; // Boolean toggle if relayer should connect to Guardian Network via non-validation guardiand node shouldRest: boolean; // Boolean toggle if relayer should connect to Guardian Network via REST API maxRetries?: number; afterSetup?( providers: Providers, listenerResources?: { eventSource: EventSource; db: StagingAreaKeyLock }, ): Promise; getFilters(): ContractFilter[]; // List of emitter addresses and emiiter chain ID to filter for consumeEvent( // Function to be defined in plug-in that takes as input a VAA outputs a list of actions vaa: ParsedVaaWithBytes, stagingArea: StagingAreaKeyLock, providers: Providers, extraData?: any[], ): Promise< | { workflowData: WorkflowData; workflowOptions?: WorkflowOptions; } | undefined >; handleWorkflow( workflow: Workflow, providers: Providers, execute: ActionExecutor, ): Promise; } export type EventSource = ( event: SignedVaa, extraData?: any[], ) => Promise; export type ContractFilter = { emitterAddress: string; // Emitter contract address to filter for chainId: ChainId; // Wormhole ChainID to filter for doNotTransform?: boolean; // If true, do not do chain specific transformation into wormhole emitter address format }; export interface StagingAreaKeyLock { withKey>( keys: string[], f: (kvs: KV, ctx: OpaqueTx) => Promise<{ newKV: KV; val: T }>, tx?: OpaqueTx, ): Promise; getKeys>(keys: string[]): Promise; } export type OpaqueTx = never;