import { CHAIN_ID_SOLANA, ChainId, EVMChainId, isEVMChain, } from "@certusone/wormhole-sdk"; import { ParsedVaaWithBytes, RelayerApp } from "../../application.js"; import * as legacy from "./legacy-plugin-definition.js"; import { Plugin, Providers as LegacyProviders, } from "./legacy-plugin-definition.js"; import { StorageContext } from "../../storage/storage.js"; import { LoggingContext } from "../logger.middleware.js"; import { StagingAreaContext } from "../staging-area.middleware.js"; import { ProviderContext, Providers } from "../providers.middleware.js"; import { EVMWallet, SolanaWallet, Wallet, WalletContext, WalletToolBox, } from "../wallet/index.js"; import { Connection } from "@solana/web3.js"; import { JsonRpcProvider } from "@mysten/sui.js"; import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"; export type PluginContext = LoggingContext & StorageContext & StagingAreaContext & WalletContext & ProviderContext & Ext; export function legacyPluginCompat( app: RelayerApp>, plugin: Plugin, ) { const filters = plugin.getFilters(); const multiple = {} as Partial<{ [k in ChainId]: string[] }>; for (const { chainId, emitterAddress, doNotTransform } of filters) { if (multiple[chainId]?.length !== 0) { multiple[chainId] = []; } // todo: support doNotTransform option multiple[chainId]?.push(emitterAddress); } // plugin.afterSetup(providers, ) app.multiple(multiple, async (ctx: PluginContext, next) => { const { kv, vaa, vaaBytes, logger } = ctx; const vaaWithBytes = vaa as ParsedVaaWithBytes; vaaWithBytes.bytes = vaaBytes!; const providers = providersShimToLegacy(ctx.providers); const res = await plugin.consumeEvent( vaaWithBytes, kv, Object.assign(providers), ); if (!res) { return next(); } const { workflowOptions, workflowData } = res!; await plugin.handleWorkflow( { data: workflowData } as legacy.Workflow, providers, makeExecuteWrapper(ctx), ); return next(); }); } function makeExecuteWrapper(ctx: PluginContext): { (action: legacy.Action): Promise; onEVM(action: legacy.Action): Promise; onSolana(f: any): Promise; onSui(f: any): Promise; } { const execute = async ( action: legacy.Action, ) => { if (isEVMChain(action.chainId)) { ctx.wallets.onEVM( action.chainId, (wallet: WalletToolBox, chainId: ChainId) => { return action.f(walletShimToLegacy(wallet), chainId); }, ); } else if (action.chainId === CHAIN_ID_SOLANA) { return ctx.wallets.onSolana((wallet: WalletToolBox) => (action.f as legacy.ActionFunc)( walletShimToLegacy(wallet), action.chainId, ), ); } }; execute.onEVM = ( action: legacy.Action, ): Promise => { return ctx.wallets.onEVM( action.chainId as EVMChainId, (wallet: WalletToolBox) => action.f(walletShimToLegacy(wallet), action.chainId), ); }; execute.onSolana = (f: any): Promise => { return ctx.wallets.onSolana(f); }; execute.onSui = (f: any): Promise => { return ctx.wallets.onSui(f); }; return execute; } function providersShimToLegacy(providers: Providers): LegacyProviders { return { solana: providers.solana.length > 0 ? providers.solana[0] : (undefined as unknown as Connection), untyped: Object.fromEntries( Object.entries(providers.untyped).map(([chain, rpcs]) => [ chain, rpcs[0], ]), ), evm: Object.fromEntries( Object.entries(providers.evm).map(([chain, rpcs]) => [chain, rpcs[0]]), ), sui: providers.sui.length > 0 ? providers.sui[0] : (undefined as unknown as JsonRpcProvider), sei: providers.sei.length > 0 ? providers.sei[0] : (undefined as unknown as CosmWasmClient), }; } function providersShimFromLegacy(providers: LegacyProviders): Providers { return { solana: providers.solana ? [providers.solana] : [], untyped: Object.fromEntries( Object.entries(providers.untyped).map(([chain, rpc]) => [chain, [rpc]]), ), evm: Object.fromEntries( Object.entries(providers.evm).map(([chain, rpc]) => [chain, [rpc]]), ), sui: providers.sui ? [providers.sui] : [], sei: providers.sei ? [providers.sei] : [], }; } function walletShimToLegacy( wallets: WalletToolBox, // @ts-ignore ): legacy.WalletToolBox { return { ...providersShimToLegacy(wallets), wallet: wallets.wallet, }; } function walletShimFromLegacy( wallets: legacy.WalletToolBox, ): WalletToolBox { return { ...providersShimFromLegacy(wallets), wallet: wallets.wallet, async getBalance(): Promise { return "NOT IMPLEMENTED"; }, address: "NOT IMPLEMENTED", }; }