import React from "react"; import { Connection, VersionedMessage, VersionedTransaction, } from "@solana/web3.js"; import { useCluster } from "providers/cluster"; import { InstructionLogs, parseProgramLogs } from "utils/program-logs"; import { ProgramLogsCardBody } from "components/ProgramLogsCardBody"; export function SimulatorCard({ message }: { message: VersionedMessage }) { const { cluster, url } = useCluster(); const { simulate, simulating, simulationLogs: logs, simulationError, } = useSimulator(message); if (simulating) { return (

Transaction Simulation

Simulating
); } else if (!logs) { return (

Transaction Simulation

{simulationError ? ( <> Simulation Failure: {simulationError} ) : ( )}
); } return (

Transaction Simulation

); } function useSimulator(message: VersionedMessage) { const { cluster, url } = useCluster(); const [simulating, setSimulating] = React.useState(false); const [logs, setLogs] = React.useState | null>(null); const [error, setError] = React.useState(); React.useEffect(() => { setLogs(null); setSimulating(false); setError(undefined); }, [url]); const onClick = React.useCallback(() => { if (simulating) return; setError(undefined); setSimulating(true); const connection = new Connection(url, "confirmed"); (async () => { try { // Simulate without signers to skip signer verification const resp = await connection.simulateTransaction( new VersionedTransaction(message), { replaceRecentBlockhash: true } ); if (resp.value.logs === null) { throw new Error("Expected to receive logs from simulation"); } if ( resp.value.logs.length === 0 && typeof resp.value.err === "string" ) { setLogs(null); setError(resp.value.err); } else { // Prettify logs setLogs(parseProgramLogs(resp.value.logs, resp.value.err, cluster)); } } catch (err) { console.error(err); setLogs(null); if (err instanceof Error) { setError(err.message); } } finally { setSimulating(false); } })(); }, [cluster, url, message, simulating]); return { simulate: onClick, simulating, simulationLogs: logs, simulationError: error, }; }