All articles
seersolanadebuggingtestingcpianchortooling

Seer: source-level Solana transaction debugging

Turn Solana RPC tests into source-mapped traces — CPI trees, account diffs, opcodes, and VM snapshots with Seer (seer.run).

devrels.xyz/a/241short link

Seer: source-level Solana transaction debugging. seer.run turns ordinary RPC / test transactions into analysis suites: CPI call trees, account before/after diffs, program logs tied to your source lines, and VM snapshots (opcodes and registers) at each step.

What breaks without it

Default Solana debugging is a stack of approximations: simulateTransaction logs, Anchor msg! / require! strings, explorer instruction lists, and occasional solana-ledger-tool. That works until a CPI chain fails three programs deep, an account constraint is wrong only after a prior mutation, or the binary path you care about never hits a log line.

Seer's pitch is enterprise-style tracing for the SVM: keep writing tests the way you already do, then open the same transaction with source context and VM state instead of grepping logs.

Capabilities

What Seer surfaces per transaction
LayerYou getWhen it helps
Source-code contextWhich lines in your program binary were executedMapping Custom(N) / panic sites back to Rust
CPI treeNested program invocations with args and resultsToken / system / sibling program failures
Account diffsPre/post lamports and data per accountUnexpected rent, wrong PDA writes, silent no-ops
Opcodes and registersSVM-level steps inside each programHard compute / SBF edge cases
LogsProgram logs aligned to the same timelineCorrelate msg! with state at that step

Where it sits in a test stack

Debugging stack on Solana
ToolRole
LiteSVMFast in-process execution of txs in unit/integration tests
SurfpoolMainnet-fork validator when you need realistic accounts
TridentGuided fuzzing to find bad paths
SeerExplain a single failing or interesting transaction deeply

Typical loop: LiteSVM or Anchor test fails → capture signature / raw tx → open in Seer → fix constraint or CPI → re-run. Fuzz campaigns (Trident) feed Seer the interesting crashing cases.

Practical workflow

  1. Reproduce with a deterministic test (fixed keypairs, fixed clock if needed).
  2. Prefer simulation first so you do not need a landed signature:
    typescript
    const sim = await connection.simulateTransaction(tx, {
      sigVerify: false,
      commitment: "processed",
    })
    // logs + err still available; feed the same tx bytes into Seer
  3. Load the transaction in Seer with your program's build artifacts so source maps can attach (release builds without debug info give you less line context — keep a debug .so for local analysis when you can).
  4. Walk the CPI tree top-down: find the first program that returned Err, then the account that failed the constraint.
  5. Diff accounts around that step; confirm whether the bug is missing signer, wrong PDA seeds, stale data, or a token authority mismatch.

What Seer is not

  • Not a replacement for unit tests or fuzzing — it analyzes transactions you already produce.
  • Not seer.trade (markets product). Builder debugger is seer.run.
  • Not a full chain indexer — use Yellowstone / explorers for fleet-wide history; use Seer for one tx at a time.

People and links

Seer directory
SurfaceLink
Productseer.run
Orgdevrels.xyz/organisations/seer
Projectdevrels.xyz/projects/seer

Resources

Keep reading

Get new articles in your inbox

Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.

Seer: source-level Solana transaction debugging | devrels.xyz