How to interact with the wallet
Sign messages, send transactions, and stake SOL. The interactive demo below lets you stake real SOL to a validator.
Real Transactions
This demo submits real transactions to Solana mainnet. Staked SOL will be delegated to your chosen validator. Make sure you understand the warmup and cooldown periods before staking.
Staking Demo
Connect your wallet to stake SOL to any Solana validator. This demo uses Phantom's signAndSendTransaction method.
Sign a Message
Use signMessage for wallet verification without creating an on-chain transaction.
import { useSolana } from '@phantom/react-sdk';
function SignMessageButton() {
const { solana, isAvailable } = useSolana();
const signMessage = async () => {
if (!isAvailable || !solana) {
throw new Error('Phantom not available');
}
const message = 'Sign this message to verify your wallet';
const encodedMessage = new TextEncoder().encode(message);
const { signature, publicKey } = await solana.signMessage(
encodedMessage,
'utf8'
);
console.log('Signature:', signature);
console.log('Signed by:', publicKey.toString());
// Verify on server with tweetnacl or @solana/web3.js
return { signature, publicKey: publicKey.toString() };
};
return <button onClick={signMessage}>Sign Message</button>;
}Sign and Send Transaction
Build a transaction, then use Phantom to sign and submit it to the network.
import { useSolana } from '@phantom/react-sdk';
import {
Connection,
PublicKey,
SystemProgram,
Transaction,
} from '@solana/web3.js';
function SendSolButton({ recipient, amount }: { recipient: string; amount: number }) {
const { solana, isAvailable } = useSolana();
const sendSol = async () => {
if (!isAvailable || !solana?.publicKey) {
throw new Error('Wallet not connected');
}
const connection = new Connection(
'https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY'
);
// Build the transaction
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: solana.publicKey,
toPubkey: new PublicKey(recipient),
lamports: amount * 1e9, // Convert SOL to lamports
})
);
// Get recent blockhash
const { blockhash } = await connection.getLatestBlockhash();
transaction.recentBlockhash = blockhash;
transaction.feePayer = solana.publicKey;
// Sign and send via Phantom SDK
const { signature } = await solana.signAndSendTransaction(transaction);
console.log('Transaction sent:', signature);
return signature;
};
return <button onClick={sendSol}>Send {amount} SOL</button>;
}Build a Stake Transaction
The staking demo above uses this code to build and submit stake transactions.
import { useSolana } from '@phantom/react-sdk';
import { Keypair, PublicKey, StakeProgram, Transaction } from '@solana/web3.js';
function StakeButton({ validator, amount }: { validator: string; amount: number }) {
const { solana, isAvailable } = useSolana();
const stake = async () => {
if (!isAvailable || !solana?.publicKey) {
throw new Error('Wallet not connected');
}
const walletPubkey = solana.publicKey;
const stakeAccount = Keypair.generate();
const validatorVotePubkey = new PublicKey(validator);
const amountLamports = amount * 1_000_000_000;
// Get rent exemption (stake accounts need ~0.00228 SOL)
const rentExemption = 2282880; // Or fetch via RPC
// Build stake transaction
const transaction = new Transaction().add(
// Create stake account
StakeProgram.createAccount({
fromPubkey: walletPubkey,
stakePubkey: stakeAccount.publicKey,
authorized: {
staker: walletPubkey,
withdrawer: walletPubkey,
},
lamports: amountLamports + rentExemption,
}),
// Delegate to validator
StakeProgram.delegate({
stakePubkey: stakeAccount.publicKey,
authorizedPubkey: walletPubkey,
votePubkey: validatorVotePubkey,
})
);
// Sign with stake account keypair first
transaction.partialSign(stakeAccount);
// Sign and send via Phantom SDK
const { signature } = await solana.signAndSendTransaction(transaction);
console.log('Staked! Signature:', signature);
return signature;
};
return <button onClick={stake}>Stake {amount} SOL</button>;
}Frequently Asked Questions
How do I sign a transaction with Phantom?
Use signAndSendTransaction() to sign and broadcast in one step, or signTransaction() to get the signed transaction back for manual submission.
What is the difference between signMessage and signTransaction?
signMessage signs arbitrary data (like login verification) without creating a blockchain transaction. signTransaction signs an actual Solana transaction that will modify state on-chain.
How do I stake SOL programmatically?
Build a stake transaction using @solana-program/stake, then use Phantom's signAndSendTransaction to submit it. See the interactive demo above.
Can I simulate transactions before signing?
Yes, use the simulateTransaction RPC method before signing. This catches errors and estimates fees without submitting to the network.