Solana Basics
9 examples to get you started with Solana fundamentals - 6 basic and 3 intermediate. Covers accounts, programs, transactions, SOL, clusters, and the developer workflow on Agave 4.1.1.
Search across all documentation pages
9 examples to get you started with Solana fundamentals - 6 basic and 3 intermediate. Covers accounts, programs, transactions, SOL, clusters, and the developer workflow on Agave 4.1.1.
Install the Solana CLI 3.0.10 and create a default keypair on devnet.
sh -c "$(curl -sSfL https://release.anza.xyz/v3.0.10/install)"
solana --version
solana config set --url devnet
solana-keygen new --no-bip39-passphrase -o ~/.config/solana/id.json
solana airdrop 2For TypeScript client examples, use @solana/kit 7.0.0:
npm install @solana/kit@7.0.0Every address on Solana maps to an account - even if it holds zero lamports.
import { createSolanaRpc, address, lamports } from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const pubkey = address("11111111111111111111111111111111");
const { value } = await rpc.getBalance(pubkey).send();
console.log(`Balance: ${Number(lamports(value)) / 1e9} SOL`);getBalance returns lamports directly from the account's lamport fieldRelated: SOL, Lamports & Units - precision and conversions
Accounts are the single abstraction for all on-chain state.
// Conceptual layout - every account has these fields
pub struct Account {
pub lamports: u64, // SOL balance in lamports
pub data: Vec<u8>, // arbitrary byte buffer
pub owner: Pubkey, // program allowed to write data
pub executable: bool, // true for deployed programs
pub rent_epoch: u64, // rent tracking (legacy field)
}executable = true and code in dataRelated: The Solana Mental Model vs. EVM - accounts vs contracts
A transaction with one System Program instruction moves SOL between accounts.
solana transfer <RECIPIENT_PUBKEY> 0.1 --allow-unfunded-recipientTransfer instruction--allow-unfunded-recipient creates the destination if it has no account yetRelated: How a Transaction Flows - client to confirmation
Use the CLI or RPC to see instructions, signers, and compute units consumed.
solana confirm -v <SIGNATURE>-v prints each instruction's program ID, accounts, and dataRelated: Keypairs & Addresses - who signs what
Solana runs multiple independent clusters with different purposes.
solana config set --url devnet # free test SOL, public RPC
solana config set --url testnet # validator testing, less stable
solana config set --url mainnet-beta # production - real SOL
solana-test-validator # local Agave 4.1.1 nodeRelated: Clusters & Networks - when to use each
Solana targets ~400 ms slots; leaders produce blocks per slot.
solana slot
solana block-time $(solana slot)Related: Slots, Blocks & Epochs - epoch schedule details
Kit uses a functional pipe to assemble versioned transactions.
import {
createSolanaRpc,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
pipe,
address,
getSignatureFromTransaction,
signTransactionMessageWithSigners,
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const feePayer = address("YOUR_FEE_PAYER_PUBKEY");
const recipient = address("RECIPIENT_PUBKEY");
const { value: blockhash } = await rpc.getLatestBlockhash().send();
const transferIx = getTransferSolInstruction({
source: feePayer,
destination: recipient,
amount: 100_000_000n, // 0.1 SOL in lamports
});
const txMessage = pipe(
createTransactionMessage({ version: 0 }),
(m) => setTransactionMessageFeePayer(feePayer, m),
(m) => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),
(m) => appendTransactionMessageInstruction(transferIx, m),
);
// Sign with your keypair signer, then send via sendTransactionbigint lamports - never JavaScript floatsRelated: Wallets & Explorers - devnet workflow
Ed25519 keypairs are the root of identity and signing on Solana.
solana-keygen new --outfile ./dev-wallet.json --no-bip39-passphrase
solana-keygen pubkey ./dev-wallet.jsonimport { createKeyPairSignerFromBytes } from "@solana/kit";
import { readFileSync } from "node:fs";
const secret = JSON.parse(readFileSync("./dev-wallet.json", "utf8"));
const signer = await createKeyPairSignerFromBytes(Uint8Array.from(secret));
console.log(signer.address);Related: Keypairs & Addresses - signing model
Follow a transfer from client submission to finalized confirmation.
# 1. Send
SIG=$(solana transfer <RECIPIENT> 0.01 --output json | jq -r .signature)
# 2. Poll confirmation
solana confirm $SIG --commitment confirmed
# 3. Inspect in explorer
echo "https://explorer.solana.com/tx/$SIG?cluster=devnet"Related: How a Transaction Flows - full pipeline
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026