bat-cli 0.15.0

Blockchain Auditor Toolkit (BAT)
bat-cli-0.15.0 is not a library.

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

cargo install bat-cli

Updating (update)

bat-cli update           # install the latest version published to crates.io
bat-cli update --check   # only report whether a newer version exists
bat-cli update --force   # reinstall even when already up to date

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:

bat-cli login --setup   # first time: register your Miro app credentials
bat-cli login           # opens the browser, you press Accept
bat-cli login --status  # who the token belongs to, and its scopes
bat-cli logout          # revoke it

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)
bat-cli config          # show the effective preferences and where they live
bat-cli config --edit   # re-answer them

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 TryFrom impls (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/, and node_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 Miro
  • code-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 point
  • miro code-overhaul-screenshots — deploys entry point and dependency screenshots with caller→callee arrows
  • miro entrypoint-screenshots — deploys entry point and context accounts to a selected frame
  • miro source-code-screenshots — deploys arbitrary source code screenshots
  • miro function-dependencies — deploys a function and its dependency tree
  • miro evm-auto-deployEVM: 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-run prints the layout without contacting Miro. Deployment is on demand by design — --all exists 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 metadata
  • tool open-code-overhaul-file — open a started code-overhaul file and its entry point source
  • tool get-metadata-by-id — search and open source code by metadata ID
  • tool count-code-overhaul — count to-review, started, and finished code-overhaul files
  • tool list-entry-points-path — list entry points with file paths
  • tool list-code-overhaul — list code-overhaul files and their status
  • tool 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
bat-cli init

# Start reviewing an entry point (runs sonar + deploys to Miro)
bat-cli code-overhaul start

# Finish reviewing an entry point
bat-cli code-overhaul finish

# Deploy code-overhaul frames to Miro
bat-cli miro code-overhaul-frames

# Deploy screenshots to Miro
bat-cli miro code-overhaul-screenshots

License

MIT