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 linkSeer: 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
| Layer | You get | When it helps |
|---|---|---|
| Source-code context | Which lines in your program binary were executed | Mapping Custom(N) / panic sites back to Rust |
| CPI tree | Nested program invocations with args and results | Token / system / sibling program failures |
| Account diffs | Pre/post lamports and data per account | Unexpected rent, wrong PDA writes, silent no-ops |
| Opcodes and registers | SVM-level steps inside each program | Hard compute / SBF edge cases |
| Logs | Program logs aligned to the same timeline | Correlate msg! with state at that step |
Where it sits in a test stack
| Tool | Role |
|---|---|
| LiteSVM | Fast in-process execution of txs in unit/integration tests |
| Surfpool | Mainnet-fork validator when you need realistic accounts |
| Trident | Guided fuzzing to find bad paths |
| Seer | Explain 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
- Reproduce with a deterministic test (fixed keypairs, fixed clock if needed).
- 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 - 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).
- Walk the CPI tree top-down: find the first program that returned Err, then the account that failed the constraint.
- 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
| Surface | Link |
|---|---|
| Product | seer.run |
| Org | devrels.xyz/organisations/seer |
| Project | devrels.xyz/projects/seer |
Resources
Keep reading
Manually guided Solana fuzzing at thousands of tx/s: define realistic instruction flows, let Trident stress account state.
CPI is how Solana programs compose. Account meta forwarding, invoke vs invoke_signed, signer seeds, the 4-deep call limit, and reading return data from the called program.
Anchor's TypeScript client is a runtime IDL interpreter. codama is a build-time code generator that emits tree-shakeable, type-safe instruction builders. The difference matters.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
