import { createReadOnlyWormholeProgramInterface } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; import { WormholeInstructionCoder } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole/coder/instruction"; import { getPythClusterApiUrl } from "@pythnetwork/client/lib/cluster"; import { Connection, TransactionInstruction } from "@solana/web3.js"; import { MultisigInstruction, MultisigInstructionProgram, UNRECOGNIZED_INSTRUCTION, } from "."; import { decodeGovernancePayload, PythGovernanceAction, } from "../governance_payload"; import { AnchorAccounts, resolveAccountNames } from "./anchor"; export class WormholeMultisigInstruction implements MultisigInstruction { readonly program = MultisigInstructionProgram.WormholeBridge; readonly name: string; readonly args: { [key: string]: any }; readonly accounts: AnchorAccounts; readonly governanceAction: PythGovernanceAction | undefined; constructor( name: string, args: { [key: string]: any }, accounts: AnchorAccounts, governanceAction: PythGovernanceAction | undefined ) { this.name = name; this.args = args; this.accounts = accounts; this.governanceAction = governanceAction; } static fromTransactionInstruction( instruction: TransactionInstruction ): WormholeMultisigInstruction { const wormholeProgram = createReadOnlyWormholeProgramInterface( instruction.programId, new Connection(getPythClusterApiUrl("devnet")) // Hack to get a decoder, this connection won't actually be used ); const deserializedData = ( wormholeProgram.coder.instruction as WormholeInstructionCoder ).decode(instruction.data); if (deserializedData) { if (deserializedData.name === "postMessage") { const decodedGovernanceAction: PythGovernanceAction | undefined = decodeGovernancePayload((deserializedData.data as any).payload); return new WormholeMultisigInstruction( deserializedData.name, deserializedData.data, resolveAccountNames( wormholeProgram.idl, deserializedData.name, instruction ), decodedGovernanceAction ); } else { return new WormholeMultisigInstruction( deserializedData.name, deserializedData.data, resolveAccountNames( wormholeProgram.idl, deserializedData.name, instruction ), undefined ); } } else { return new WormholeMultisigInstruction( UNRECOGNIZED_INSTRUCTION, { data: instruction.data }, { named: {}, remaining: instruction.keys }, undefined ); } } }