Thank you for your interest in contributing to the Soroban Debugger project! We welcome contributions from the community and are committed to fostering a collaborative, respectful, and productive environment.
- Development Environment Setup
- Project Setup
- Running Tests
- Fuzzing
- Code Style & Quality
- Commit Message Conventions
- Claiming and Working on Issues
- Pull Request Process
- Issue Guidelines
- Areas for Contribution
- Project Structure
- Adding or Changing Commands
- Updating Man Pages
- Code of Conduct
- Communication
- Release Process
- Git
- Rust (stable toolchain, 1.75 or later)
- Soroban CLI (for contract testing)
We recommend rustup to manage toolchains.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"Install the stable toolchain plus formatter and lints:
rustup toolchain install stable
rustup default stable
rustup component add rustfmt clippyVerify:
rustc --version
cargo --versionWe use the pre-commit framework to automatically format and lint code before each commit to prevent CI failures.
To install:
- Install
pre-commitlocally (e.g.,pip install pre-commitorbrew install pre-commit). - Run
pre-commit installin the repository root to activate the hooks.
By default, pre-commit runs strict clippy with CI-equivalent flags via the cargo-clippy hook (cargo clippy --workspace --all-targets --all-features -- -D warnings).
If your commit only changes non-Rust files (for example docs or markdown) and you need to bypass clippy for that commit, use:
SKIP=cargo-clippy git commit -m "docs: update troubleshooting guide"You can still run all hooks manually at any time:
pre-commit run --all-files- Fork the repository on GitHub.
- Clone your fork:
git clone https://github.com/<your-username>/soroban-debugger.git
cd soroban-debugger- Add the upstream remote:
git remote add upstream https://github.com/Timi16/soroban-debugger.git- Create a branch for your work:
git checkout -b feat/short-description- Build once to ensure the toolchain is working:
cargo buildcargo run -- run --contract path/to/contract.wasm --function function_nameCI runs the full workspace test suite with all features enabled. Match that locally:
cargo test --workspace --all-featuresRun a single test by name:
cargo test <test_name>Run a specific integration test file:
cargo test --test <test_file>Reproduce the benchmark regression gate locally without checking out main in place:
cargo install critcmp --version 0.1.7
bash scripts/check_benchmark_regressions.shThe script benchmarks your current branch, then benchmarks origin/main in a temporary detached worktree when available so your checkout stays on your branch throughout the comparison.
Tests should be:
- Isolated and repeatable
- Well-named and descriptive
- Covering both typical and edge cases
Add new tests for every new feature or bug fix. Place integration tests in the tests/ directory and unit tests alongside the code in src/.
Fuzzing helps discover crashes and panics in critical code paths like WASM parsing and argument parsing.
Prerequisites:
Install cargo-fuzz:
cargo install cargo-fuzzRunning a fuzz target:
# Run WASM loading fuzzer
cargo +nightly fuzz run wasm_loading
# Run argument parser fuzzer
cargo +nightly fuzz run arg_parser
# Run storage key parsing fuzzer
cargo +nightly fuzz run storage_keysBy default, fuzzers run indefinitely. You can limit the execution time with -- -max_total_time=<seconds>.
We follow standard Rust tooling and treat warnings as errors in CI.
cargo fmt --allCheck formatting (CI uses this):
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-features -- -D warningsEquivalent make target:
make lint-strict- Formatting:
- Use
cargo fmtbefore committing. Code should be auto-formatted. - Indent with 4 spaces, no tabs.
- Keep lines under 100 characters when possible.
- Use
- Linting:
- Run
cargo clippyand address all warnings before submitting code.
- Run
- Naming:
- Use
snake_casefor variables and function names. - Use
CamelCasefor type and struct names. - Use
SCREAMING_SNAKE_CASEfor constants and statics.
- Use
- Documentation:
- Document all public functions, structs, and modules using Rust doc comments (
///). - Add inline comments for complex logic.
- Document all public functions, structs, and modules using Rust doc comments (
- Testing:
- Write unit and integration tests for new features and bug fixes.
- Place integration tests in the
tests/directory.
- Error Handling:
- Prefer
Result<T, E>over panics for recoverable errors. - Use meaningful error messages.
- Prefer
- General:
- Remove unused code and imports.
- Avoid commented-out code in commits.
- Keep functions small and focused.
We use Conventional Commits (see cliff.toml). Format:
<type>(optional scope): short summary
[optional body]
[optional footer(s)]
Common types: feat, fix, docs, style, refactor, perf, test, chore.
Examples:
feat: add support for contract breakpoints
fix: resolve panic when loading invalid WASM
docs: update README with new usage example
style: reformat engine.rs for readability
refactor(debugger): extract stepper logic into module
perf: optimize storage inspection for large contracts
test: add integration tests for CLI parser
chore: update dependencies and build scripts
Tips:
- Use the imperative mood ("add", "fix", "update").
- Reference issues or PRs in the footer when applicable (e.g.,
Closes #123).
- Check the issue tracker for open issues and labels like good first issue or help wanted.
- Before starting, comment on the issue to say you want to work on it.
- If an issue is already assigned, coordinate in the thread before beginning work.
- Keep one issue per PR when possible, and link the PR to the issue.
Quick checklist before submitting a PR:
- All tests pass locally (
cargo test --workspace --all-features) - Code is formatted (
cargo fmt --all -- --check) - Clippy is clean (
cargo clippy --workspace --all-targets --all-features -- -D warnings) - Commit message follows Conventional Commits
- PR description mentions the related issue(s)
- CI/test behavior changes documented in PR description (or marked N/A — see "CI/Test Behavior Changes" section in PR template)
- If CLI flags/subcommands/help text changed, man pages regenerated (
make regen-man) and.1files committed
Steps:
- Sync with upstream before finalizing your branch:
git fetch upstream
git rebase upstream/main- Ensure all checks pass locally:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
bash scripts/test_benchmark_regressions.sh
bash scripts/check_benchmark_regressions.sh- Push your branch and open a PR against
main. - Include:
- A clear description of the change and motivation.
- The related issue number (e.g.,
Closes #123). - Test results (commands you ran).
- Request a review from project maintainers.
- Address review feedback promptly. PRs are merged after approval and CI passes.
When reporting a bug, please include:
- Steps to reproduce
- Expected and actual behavior
- Error messages and logs
- Contract WASM file (if relevant)
- Environment details (OS, Rust version, etc.)
When suggesting a feature, please include:
- A clear description of the feature
- Use cases and motivation
- Expected behavior
- Any relevant examples or references
We welcome contributions in the following areas:
Current Focus:
Upcoming:
Future:
If you have ideas outside these areas, feel free to discuss them by opening an issue.
src/cli/— Command-line interfacesrc/debugger/— Core debugging enginesrc/runtime/— WASM execution environmentsrc/inspector/— State inspection toolssrc/ui/— Terminal user interfacesrc/utils/— Utility functionstests/— Integration testsexamples/— Example usage
Soroban Debugger exposes features across the CLI, interactive REPL, and the VS Code extension. A single feature often spans CLI arguments, command handlers, documentation, man pages, and the extension's launch.json schema.
If you are adding or modifying a command or flag, please review the Contributor Command Map to ensure all relevant surfaces are updated before opening your pull request.
Man pages in man/man1/ are generated automatically from the CLI source via build.rs and clap_mangen. Do not hand-edit .1 files — changes will be overwritten on the next regeneration.
Regenerate whenever you:
- Add, remove, or rename a CLI subcommand
- Add, remove, or rename a CLI flag or argument
- Change any help text or description string
make regen-manCommit the updated .1 files alongside your CLI changes in the same PR.
The check-manpages CI job runs on every PR and push to main. It regenerates man pages into a temp directory and diffs them against the committed versions. The job fails if any drift is detected — PRs cannot be merged with stale man pages.
To verify locally before pushing:
# Regenerate from current source
make regen-man
# Verify in sync (should exit 0)
make check-manWe are committed to providing a welcoming and inclusive environment for everyone. All interactions must be respectful and constructive. Please review our Code of Conduct for details.
- For questions, open an issue or start a discussion on GitHub.
- For security concerns, please contact the maintainers directly.
- Join our community channels (if available) for real-time discussion.
Thank you for helping make Soroban Debugger better!
Releases are gated by a single unified checklist that covers Rust/CLI, analyzers, VS Code extension checks, and benchmark thresholds:
docs/release-checklist.md