Analysis Commands

Once you have a transaction JSON in hand (from build, the MCP builder tools, or hand-rolled), the next step is to inspect it. The CLI ships four analysis verbs that all accept the same input shapes (JSON file path, @file.json token, inline JSON, numeric collection id where applicable, or - for stdin):

Command
Purpose

Validate / review / metadata coverage in one pass β€” the unified analysis verb

Plain-English summary, auto-detects tx vs collection

Dry-run against the indexer's simulate endpoint, returns gas + per-address balance changes

Upload to the indexer and print a shareable bitbadges.io preview URL

check and doctor (covered on the Utility Commands page) replace the old sdk review / builder verify / sdk status / builder doctor quartet.

check

bb check is the unified analysis entry point. It folds the old validate, review, and verify verbs into one command with a --depth dial.

bb check tx.json                       # full check (default)
bb check tx.json --depth structural    # validateTransaction() only
bb check tx.json --depth review        # reviewCollection() only
bb check 42 --depth review --testnet   # live collection, design audit
echo '{"messages":[...]}' | bb check -

Depth levels:

--depth

What it runs

Use when

structural

validateTransaction() only β€” uint ranges, approval criteria, structural correctness

Fast offline check before you commit JSON to disk

review

reviewCollection() only β€” design audit, standards conformance, UX checks

You're reviewing someone else's work or a live collection by id

full (default)

validate + review + design + metadata coverage, all rendered together

Pre-broadcast diligence; the most useful single-shot check

Common flags:

Flag
Description

--depth <level>

structural | review | full (default: full)

--strict

Exit 1 on warnings (criticals always exit 2)

--no-validate, --no-review, --no-metadata

Skip the corresponding section in --depth full

--design

Include the design-decisions section in --depth full's envelope payload (informational βœ“/βœ—)

--condensed

Single-line JSON envelope (smaller pipe payload)

--output-file <path>

Write the envelope to a file instead of stdout

--testnet, --local, --url

Network selection for fetching numeric collection ids

Stdout is always the universal {ok, data, warnings, error} envelope; the human-readable scorecards print to stderr (suppress with --quiet / BB_QUIET=1).

check accepts collection ids on review and full depths (fetches the collection from the indexer first). structural is offline-only and refuses numeric ids β€” pass tx JSON directly.

explain

bb explain produces a plain-English summary. Auto-detects whether the input is a transaction or a collection and routes to the right interpreter.

Input detection:

  • Single Msg { typeUrl, value: {...} } β†’ walks value through interpretTransaction()

  • Tx wrapper { messages: [{ typeUrl, value }, ...] } β†’ finds the first collection msg and explains it

  • Raw collection (no typeUrl, no messages) β†’ walks through interpretCollection()

  • Numeric <n> β†’ fetches /api/v0/collection/<n> then walks through interpretCollection()

Flags:

Flag
Description

--output-file <path>

Write the envelope to a file instead of stdout

--condensed

Single-line JSON (smaller pipe payload)

--testnet, --local, --url

Network selection for numeric collection-id fetches

Output shape

explain always emits the universal envelope. The prose interpretation lives at data.fullText; agents that want a per-message breakdown read data.messages[].

kind lets agents discriminate between transactions, raw collections, and bare messages. messages[] is empty for raw collection inputs; populated for tx wrappers and bare messages. fullText is included so callers that just want the human-readable text can jq -r .data.fullText instead of branching on shape.

Replaces the old sdk interpret-tx and sdk interpret-collection commands plus builder explain β€” one verb, auto-detect, one less mental dimension.

simulate

bb simulate dry-runs a transaction against the indexer's /api/v0/simulate endpoint. Returns the parsed events, per-address balance changes, and any errors that would have surfaced on-chain.

Flags:

Flag
Description

--creator <address>

Override the simulation context address (default: a placeholder)

--events

Dump the full raw chain events array (default: just the count)

--condensed

Single-line JSON envelope (smaller pipe payload)

--output-file <path>

Write the envelope to a file instead of stdout

--testnet, --local, --url

Network selection

Stdout is the universal envelope wrapping SimulateResult in data. The terminal-friendly per-message breakdown prints to stderr (suppress with --quiet).

Requires BITBADGES_API_KEY (or per-network override) on mainnet/testnet. Local indexers usually accept any (or no) key.

User-level approval messages (MsgUpdateUserApprovals, MsgSetIncomingApproval, etc.) are explicitly refused β€” their semantics are state-change-on-existing-collection with set/append/delete variability and dry-running them isn't meaningful. Use check instead for those.

preview

bb preview uploads a transaction to the indexer and prints a shareable bitbadges.io/builder/preview?code=... URL. Intended for handing a tx off to a non-CLI reviewer for visual inspection without giving them edit/submit rights. Lives 1 hour in the indexer's Redis cache.

Flags:

Flag
Description

--frontend-url <url>

Override the bitbadges.io frontend base for the printed URL (default: https://bitbadges.io)

--condensed

Single-line JSON envelope

--output-file <path>

Write the envelope to a file instead of stdout

--testnet, --local, --url

Network selection β€” controls which indexer hosts the preview

Stdout is the universal envelope; the URL lives at data.url, expiry at data.expiresIn.

The endpoint is intentionally open (no API key required); the unguessable code in the URL is the secret.

See also

Last updated