Versioned Transactions (v0)
The v0 format and why it matters. This guide targets Agave 4.1.1 validators, Solana CLI 3.0.10, Anchor 0.32.1, and @solana/kit 7.0.0 clients.
Recipe
Quick-reference recipe card.
solana config set --url devnet
solana balanceimport { createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");When to reach for this:
- Implementing or debugging versioned transactions (v0) in production paths
- Teaching the concept to engineers new to Solana
- Auditing whether your stack matches Agave 4.1 era behavior
Working Example
import { createSolanaRpc, address } from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const slot = await rpc.getSlot().send();
const sig = "PASTE_SIGNATURE_AFTER_YOUR_TX";
const tx = await rpc
.getTransaction(sig, { encoding: "json", maxSupportedTransactionVersion: 0 })
.send();
console.log({ slot, err: tx?.meta?.err, cu: tx?.meta?.computeUnitsConsumed });use anchor_lang::prelude::*;
#[program]
pub mod demo {
use super::*;
pub fn log_slot(_ctx: Context<LogSlot>) -> Result<()> {
let clock = Clock::get()?;
msg!("slot: {}", clock.slot);
Ok(())
}
}
#[derive(Accounts)]
pub struct LogSlot {}What this demonstrates:
- RPC access patterns with @solana/kit 7.0.0
- Reading execution metadata (errors, CU) from confirmed transactions
- On-chain sysvar access in Anchor 0.32.1 programs
Deep Dive
How It Works
- The v0 format and why it matters.
- Solana's account model requires explicit account lists per instruction
- Sealevel executes non-conflicting transactions in parallel
Agave 4.1.1 Notes
- Confirmation semantics follow TowerBFT voting with PoH ordering
- Alpenglow (Votor + Rotor) is rolling out for faster finality - see Consensus section
- Local development: Surfpool 0.12.0 and LiteSVM 0.6.x
Rust Notes
// Use checked math and explicit constraints in programs
require!(amount > 0, MyError::InvalidAmount);Gotchas
- Legacy web3.js v1 snippets - API differs from Kit. Fix: use @solana/kit 7.0.0.
- Wrong cluster - devnet vs mainnet mismatch. Fix: align CLI, RPC, wallet, explorer.
- Float SOL amounts - precision loss. Fix: bigint lamports end-to-end.
- Expired blockhash - dropped txs. Fix: re-fetch blockhash and re-sign.
- Insufficient CU - OOM or budget exceeded. Fix: optimize program + set Compute Budget.
- Missing owner checks - writable account exploits. Fix: Anchor constraints on every mut account.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| @solana/kit 7.0.0 | New TypeScript clients | Maintaining legacy code temporarily |
| Solana CLI 3.0.10 | Ops and quick probes | Production transaction signing at scale |
| Surfpool 0.12.0 | Anchor integration tests | Production deployment |
| LiteSVM 0.6.x | Fast unit tests | Full network behavior validation |
FAQs
How does this apply on Agave 4.1.1?
Agave 4.1.1 fully supports v0 transactions—wallets and RPCs must set maxSupportedTransactionVersion: 0 when fetching.
What Solana CLI version should I use?
Use Solana CLI 3.0.10, which pairs with Agave 4.1.1. Install with agave-install init 4.1.1 (or your team's pin file), then verify with solana --version and agave-install --version.
Should I use @solana/kit or web3.js?
Use @solana/kit 7.0.0 for new TypeScript—typed RPC methods, smaller API surface, and examples on this page already use Kit. Keep web3.js only for legacy codebases; migrate RPC calls and transaction building incrementally.
What commitment level is recommended?
Simulate at confirmed, then poll getSignatureStatuses at confirmed for speed. Use finalized before treating token movements as settled.
How do I debug related failures?
Legacy parsers that assume legacy transactions fail on v0—enable version 0 in @solana/kit RPC calls and deserializers.
Does this work on devnet?
Yes—point CLI and RPC to https://api.devnet.solana.com. Behavior matches mainnet; only account data and economics differ.
How do compute units affect this?
v0 does not reduce CU; it reduces serialized size so you can fit more accounts and instructions per tx.
What is the Anchor 0.32.1 pattern?
Anchor 0.32.1 uses #[program], Context<T>, and #[derive(Accounts)] with explicit mut/signer constraints—run anchor build and anchor test on 0.32.1 via avm use 0.32.1.
How do I test with Surfpool 0.12.0?
Run anchor test with Surfpool 0.12.0 to simulate full transactions against a mainnet fork—especially priority-fee and v0/ALT paths.
Can LiteSVM 0.6.x cover this?
LiteSVM 0.6.x supports v0 when you include lookup table accounts in the test harness.
What changed in the Agave era?
The validator client rebranded to Agave (4.1.1), CLI 3.0.10 aligns with it, and Alpenglow work is changing finality—pin versions and read release notes each upgrade.
Where do I find related RPC methods?
getTransaction and simulateTransaction both need maxSupportedTransactionVersion: 0 for v0 txs.
Related
- Browse other pages in the
transactions-instructions-feessection for complementary topics - Solana Basics - account and transaction orientation
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.