> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phantom.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Resolve transaction simulation warnings

> Prepare and sign Solana transactions using Phantom's transaction simulation guidance

Prepare transactions using Phantom's guidance for the “This dApp could be malicious” simulation warning.

Phantom may show this warning when it cannot reliably predict a transaction's outcome. This recipe implements the [transaction simulation guidance](/developer-powertools/domain-and-transaction-warnings#transaction-simulation-warning) with a v0 SOL transfer.

## Prepare and sign the transaction

Call `runExample(rpcUrl, recipient)` from a button handler to send 0.001 SOL on devnet.

<Accordion title="Transaction example">
  <CodeGroup>
    ```typescript title="usage.ts" theme={null}
    import { Connection, PublicKey, SystemProgram } from "@solana/web3.js";
    import { getPhantomProvider } from "./connect";
    import { signAndSubmit } from "./transaction";

    export async function runExample(rpcUrl: string, recipient: string) {
      try {
        const provider = getPhantomProvider();
        const { publicKey } = await provider.connect();
        const connection = new Connection(rpcUrl, "confirmed");
        const instructions = [SystemProgram.transfer({
          fromPubkey: publicKey, toPubkey: new PublicKey(recipient), lamports: 1_000_000,
        })];
        const signature = await signAndSubmit(provider, connection, publicKey, instructions);
        console.log("Submitted:", signature);
        return signature;
      } catch (error) {
        console.error("Transaction failed:", error);
        throw error;
      }
    }
    ```

    ```typescript title="transaction.ts" theme={null}
    import bs58 from "bs58";
    import {
      Connection, PublicKey, TransactionMessage, VersionedTransaction,
      type Signer, type TransactionInstruction,
    } from "@solana/web3.js";
    import type { PhantomProvider } from "./connect";

    export async function prepareForApproval(
      connection: Connection, payer: PublicKey, instructions: TransactionInstruction[],
    ) {
      if (await connection.getGenesisHash() !== "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG") {
        throw new Error("RPC endpoint does not match solana:devnet.");
      }
      const { blockhash } = await connection.getLatestBlockhash("confirmed");
      const transaction = new VersionedTransaction(new TransactionMessage({
        payerKey: payer, recentBlockhash: blockhash, instructions,
      }).compileToV0Message());
      const { value: simulation } = await connection.simulateTransaction(transaction, {
        commitment: "confirmed", sigVerify: false,
      });
      if (simulation.err) throw new Error(`Simulation failed: ${JSON.stringify(simulation.err)}`);
      return { transaction, simulation };
    }

    export async function signAndSubmit(
      provider: PhantomProvider, connection: Connection, payer: PublicKey,
      instructions: TransactionInstruction[], additionalSigners: Signer[] = [],
    ) {
      const { transaction } = await prepareForApproval(connection, payer, instructions);
      // Phantom signs first; add other signatures to the transaction it returns.
      const signed = await provider.signTransaction(transaction);
      if (additionalSigners.length) signed.sign(additionalSigners);
      const signature = bs58.encode(signed.signatures[0]);
      try {
        await connection.sendRawTransaction(signed.serialize(), {
          preflightCommitment: "confirmed", skipPreflight: false,
        });
      } catch (cause) {
        throw Object.assign(new Error(`Check ${signature} before retrying.`, { cause }), { signature });
      }
      return signature;
    }
    ```
  </CodeGroup>
</Accordion>

<Accordion title="Installation and connection">
  ```bash theme={null}
  npm install @solana/web3.js@1.99.0 bs58@6.0.0
  ```

  Save `connect.ts`, `usage.ts`, and `transaction.ts` in the same directory.

  ```typescript title="connect.ts" theme={null}
  import type { PublicKey, VersionedTransaction } from "@solana/web3.js";

  export interface PhantomProvider {
    isPhantom: boolean;
    connect(): Promise<{ publicKey: PublicKey }>;
    signTransaction(transaction: VersionedTransaction): Promise<VersionedTransaction>;
  }

  export function getPhantomProvider(): PhantomProvider {
    const provider = (window as Window & {
      phantom?: { solana?: PhantomProvider };
    }).phantom?.solana;
    if (!provider?.isPhantom) throw new Error("Install the Phantom browser extension, then reload.");
    return provider;
  }
  ```
</Accordion>

The helper verifies that the RPC endpoint is on devnet before building a fresh, unsigned transaction and simulating it with `sigVerify: false`. It stops on errors, requests Phantom's signature, and submits the transaction Phantom returns with preflight enabled.

## Use your own instructions

Replace `SystemProgram.transfer` in `usage.ts` with your operation's instructions. Include required setup, cleanup, and resource budget instructions before simulating.

Use the connected wallet as the only signer when possible. If you need additional signers, pass them as the last argument to `signAndSubmit`. The helper collects their signatures after Phantom signs. Keep the wallet-returned message unchanged after signing.

When splitting a large transaction, keep complete operation groups together. See the [size and Address Lookup Table guidance](/developer-powertools/domain-and-transaction-warnings#transaction-simulation-warning).

## Confirm and test

A signature indicates submission. Wait for `confirmed` or `finalized` status and check for execution errors before showing success. If submission is uncertain, check the existing signature before retrying. Submission errors from this example include a `signature` property.

Test approval on your deployed domain. Phantom performs its own simulation and safety checks; a successful RPC simulation does not guarantee that the warning disappears.

## Next steps

* [Domain and transaction warnings](/developer-powertools/domain-and-transaction-warnings#transaction-simulation-warning): review steps if the warning persists.
* [New domain review guidance](/developer-powertools/domain-and-transaction-warnings#new-domain-warning): warnings shown when connecting to a domain.
* [Send a Solana v1 transaction](/recipes/transactions/send-solana-v1-transaction)
