Phantom Ecosystem Wallets & Mobile

send-sol-transaction

Build and send SOL transfers with Phantom Connect SDK, including transaction construction, signing, and verification

Ecosystem skill — independently developed and maintained by Phantom, not the Solana Foundation. No security review is performed; evaluate before use.

One command for Claude Code, Cursor, Codex, Windsurf and other agents — installs from the upstream repo (current HEAD; it ships 8 skills — pick send-sol-transaction when prompted).

$npx skills add phantom/phantom-connect-cursor-plugin

Skill contents

Send SOL Transaction

When to use

  • User asks to send SOL or transfer tokens
  • User wants to build a Solana transaction
  • User wants to implement a payment flow with Phantom

Workflow

Step 1: Build the Transaction

import {
  Connection,
  PublicKey,
  Transaction,
  SystemProgram,
  LAMPORTS_PER_SOL,
} from "@solana/web3.js";

const connection = new Connection("https://api.devnet.solana.com");

function buildTransferTransaction(
  fromPubkey: PublicKey,
  toPubkey: PublicKey,
  solAmount: number
): Transaction {
  const transaction = new Transaction().add(
    SystemProgram.transfer({
      fromPubkey,
      toPubkey,
      lamports: Math.round(solAmount * LAMPORTS_PER_SOL),
    })
  );
  return transaction;
}

Always use LAMPORTS_PER_SOL for conversion. Never hardcode 1000000000.

Step 2: Sign and Send (React SDK)

import { useSolana, useAccounts } from "@phantom/react-sdk";
import { PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL } from "@solana/web3.js";

function SendSol() {
  const solana = useSolana();
  const { accounts } = useAccounts();

  const sendTransaction = async () => {
    const solanaAccount = accounts.find((a) => a.chain === "solana");
    if (!solanaAccount) {
      console.error("No Solana account connected");
      return;
    }

    const fromPubkey = new PublicKey(solanaAccount.address);
    const toPubkey = new PublicKey("RECIPIENT_ADDRESS_HERE");

    const transaction = new Transaction().add(
      SystemProgram.transfer({
        fromPubkey,
        toPubkey,
        lamports: Math.round(0.01 * LAMPORTS_PER_SOL),
      })
    );

    try {
      const { signature } = await solana.signAndSendTransaction(transaction);
      console.log("Transaction signature:", signature);
      console.log(
        `View on Explorer: https://explorer.solana.com/tx/${signature}?cluster=devnet`
      );
    } catch (error) {
      console.error("Transaction failed:", error);
    }
  };

  return <button onClick={sendTransaction}>Send 0.01 SOL</button>;
}

Step 3: Sign and Send (Browser SDK)

import { PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL } from "@solana/web3.js";

async function sendSol(sdk: BrowserSDK) {
  const solanaAccount = sdk.accounts.find((a) => a.chain === "solana");
  if (!solanaAccount) {
    throw new Error("No Solana account connected");
  }

  const fromPubkey = new PublicKey(solanaAccount.address);
  const toPubkey = new PublicKey("RECIPIENT_ADDRESS_HERE");

  const transaction = new Transaction().add(
    SystemProgram.transfer({
      fromPubkey,
      toPubkey,
      lamports: Math.round(0.01 * LAMPORTS_PER_SOL),
    })
  );

  try {
    const { signature } = await sdk.solana.signAndSendTransaction(transaction);
    console.log("Transaction signature:", signature);
    console.log(
      `View on Explorer: https://explorer.solana.com/tx/${signature}?cluster=devnet`
    );
  } catch (error) {
    console.error("Transaction failed:", error);
  }
}

Step 4: Verify Transaction Status

async function verifyTransaction(signature: string) {
  const connection = new Connection("https://api.devnet.solana.com");

  const status = await connection.getSignatureStatus(signature);
  if (status.value?.confirmationStatus === "confirmed" ||
      status.value?.confirmationStatus === "finalized") {
    console.log("Transaction confirmed!");
  } else {
    console.log("Transaction status:", status.value);
  }
}

Critical Rules

  • Use signAndSendTransaction — NOT signTransaction. Embedded wallets do not support signTransaction.
  • Use LAMPORTS_PER_SOL for SOL-to-lamport conversion.
  • Use devnet (https://api.devnet.solana.com) for testing, mainnet-beta (https://api.mainnet-beta.solana.com) for production.
  • Always check that a Solana account is connected before attempting to build a transaction.
  • Never expose private keys — Phantom handles all signing internally.