bat-cli — Blockchain Auditor Toolkit
A Rust CLI that performs full codebase analysis of blockchain projects by building AST-based metadata to extract function dependencies, access control patterns, and storage layouts. It also deploys annotated code screenshots to Miro boards for manual code review.
Supports Anchor, Pinocchio, vanilla Rust (Solana), and Foundry (Solidity/EVM) projects.
Install
Updating (update)
It reads the latest version from the crates.io API, compares it numerically
against the running binary, and shells out to
cargo install bat-cli --version X --force --locked.
Authentication (login)
Miro authorization happens once per machine, not once per project:
login runs the OAuth 2.0 authorization code flow: it listens on
http://localhost:9871/callback, opens Miro in your browser, and stores the
resulting token in your user config directory. Every project picks it up
automatically, so miro_oauth_access_token in BatAuditor.toml can stay empty
(setting it still overrides the global token). Expiring tokens are refreshed
transparently.
--setup walks through creating the Miro app, including the redirect URI to
register and the boards:read / boards:write scopes. Creating the Developer
team itself has no public API, so that step stays manual — Miro offers it
automatically the first time you create an app.
One app for everybody
Only one Miro app is ever needed, no matter how many people use bat-cli.
Fill its credentials into src/batbelt/miro/app_credentials.rs and every other
user skips app creation entirely: bat-cli login opens Miro's consent page,
they pick their own team, press Accept, and that is the whole flow.
The setup screen only appears when no shared app is configured. Miro does not document PKCE and exposes no API to discover a user's apps, so without a configured app there is nothing for bat-cli to authorize against.
The values are also read from BAT_MIRO_CLIENT_ID / BAT_MIRO_CLIENT_SECRET,
at runtime or at build time — but note that cargo install bat-cli compiles on
the user's machine, where those variables are not set, so only the constants
travel with a published crate.
Preferences (config)
Everything that belongs to you rather than to a project lives in
~/.config/bat-cli/ — $XDG_CONFIG_HOME/bat-cli, or wherever
BAT_CLI_CONFIG_DIR points:
| file | holds |
|---|---|
config.toml |
auditor_name, code_editor, use_code_editor |
miro.toml |
the OAuth credentials (0600) |
Your code editor is answered once per machine, not once per audit. A project's
BatAuditor.toml still overrides any of these; whatever it leaves unset falls
back to the global file. Project-scoped settings — external_bat_metadata, and
everything in Bat.toml — stay with the project.
What it does
Initialize (init)
Detects the project framework, creates the Miro board (or picks an existing
one), writes Bat.toml and BatMetadata.json at the root of the audited
repository, and runs the initial sonar analysis. bat-cli creates no branches and
no commits.
Rescan (sonar)
init scans once. Run sonar after the source changes to rebuild
BatMetadata.json, which is what deploy reads. It parses the codebase via AST
and extracts:
Solana (Anchor / Pinocchio / vanilla Rust):
- Functions, structs, traits, enums
- Entry points and their context accounts
- Recursive function dependency graphs (caller → callee resolution across files, impl blocks, and trait impls)
- Anchor: account constraints and validations (
#[account(...)],has_one,seeds,constraint) - Pinocchio: heuristic-based check detection from
TryFromimpls (signer, writable, program-owned, mint, token accounts)
EVM (Foundry / Solidity):
- Contracts, interfaces, libraries, abstract contracts
- Functions with visibility, mutability, modifiers, and parameters
- Storage variables, events, and modifier definitions
- Inheritance resolution via C3 linearization
- Recursive function dependency graphs (caller → callee resolution across contracts and inherited functions)
- Import resolution with Foundry remappings,
lib/, andnode_modules/support - Access control detection (onlyOwner, role-based, custom modifiers)
- Solidity parsing via solar-parse — native Solidity lexer, no preprocessor workarounds
Code overhaul workflow (code-overhaul)
Structured audit workflow per entry point:
code-overhaul start— generates a template with the entry point metadata (access control, parameters, contract info, validations). Optionally deploys screenshots to Mirocode-overhaul finish— marks an entry point as reviewed
Miro board visualization (miro)
Deploys annotated code screenshots and dependency graphs to a Miro board for manual code analysis:
miro code-overhaul-frames— creates frames for each entry pointmiro code-overhaul-screenshots— deploys entry point and dependency screenshots with caller→callee arrowsmiro entrypoint-screenshots— deploys entry point and context accounts to a selected framemiro source-code-screenshots— deploys arbitrary source code screenshotsmiro function-dependencies— deploys a function and its dependency treemiro evm-auto-deploy— EVM: fully automatic deployment of an entry point's dependency graph. One frame per entry point, sized to the computed layout, with each screenshot uploaded already positioned and one connector per call site anchored to the exact calling line. Run it without arguments to pick an entry point from a list;--dry-runprints the layout without contacting Miro. Deployment is on demand by design —--allexists but a real project would put thousands of objects on one board- Interactive BFS deployment of dependency screenshots with caller→callee arrows
- Screenshots use Dracula theme with syntax highlighting via silicon
- Board URL is validated against the Miro API during setup
Utilities (tool)
tool open-source-code— open any function, struct, trait, or enum directly in your editor from metadatatool open-code-overhaul-file— open a started code-overhaul file and its entry point sourcetool get-metadata-by-id— search and open source code by metadata IDtool count-code-overhaul— count to-review, started, and finished code-overhaul filestool list-entry-points-path— list entry points with file pathstool list-code-overhaul— list code-overhaul files and their statustool customize-package-json— configure package.json log level scripts
Project structure
After bat-cli init, the audit workspace looks like:
bat-audit/
├── Bat.toml # Project config
├── BatMetadata.json # Sonar analysis cache
├── code-overhaul/
│ ├── to-review/ # Pending entry points
│ ├── started/ # In progress
│ └── finished/ # Reviewed
└── notes/
└── <auditor>-notes/
└── code-overhaul/ # Per-entry-point audit notes
Quick start
# Initialize a new audit project
# Start reviewing an entry point (runs sonar + deploys to Miro)
# Finish reviewing an entry point
# Deploy code-overhaul frames to Miro
# Deploy screenshots to Miro
License
MIT