Skip to content

Cheatsheet

The whole Caatinga loop on one page. Every command runs inside a generated project.

ctg is the standard command; caatinga is a legacy alias (ctg buildcaatinga build).

Prerequisites

See Getting started for manual install instructions. Verify with ctg doctor.

Scaffold commands

bash
ctg init <dir>                    # template (default: react-vite-counter)
ctg init <dir> -t <template>      # explicit template (e.g. react-vite-counter)
ctg init <dir> --minimal          # CLI + Soroban stub (no frontend)
ctg zk init <dir>                 # zk-starter template
ctg zk init <dir> --minimal       # ZK-only scaffold (no frontend)
ctg zk init                       # add ZK files to current project

See Choosing a project scaffold for when to use each path.

The loop

bash
ctg init my-dapp && cd my-dapp && npm install   # scaffold — see Getting started
npx ctg doctor --network testnet --source alice # verify environment
npx ctg build counter                           # compile one contract WASM
npx ctg build                                   # compile all configured contracts
npx ctg deploy counter --network testnet --source alice
#   ↳ writes contractId to caatinga.artifacts.json
#   ↳ auto-generates TypeScript bindings (skip with --no-generate)
#   ↳ full graph deploys also run postDeploy hooks and sync frontend env when configured
npx ctg status --network testnet                # what's deployed? bindings fresh?
npm run dev                                          # frontend against the deployed contract
npx ctg invoke counter.increment --network testnet --source alice

In-place upgrade (admin-gated contracts)

When the contract exposes upgrade(new_wasm_hash) with admin auth (same contractId, new WASM):

bash
npx ctg upgrade counter --network testnet --source alice
npx ctg upgrade counter --if-changed --source alice --network testnet
npx ctg upgrade counter --source alice --generate --sync-env   # optional post-steps

For a new contract instance (no in-place entrypoint), use redeploy history instead:

bash
npx ctg deploy counter --upgrade --network testnet --source alice

See Contract upgrade.

generate is now a recovery/CI command — deploy runs it for you:

bash
npx ctg generate counter --network testnet   # regenerate one contract
npx ctg generate --network testnet           # regenerate everything deployed

Multi-contract projects can configure postDeploy hooks and frontend env output:

bash
npx ctg deploy --network testnet --source alice # full graph: deploy + wire + sync-env
npx ctg wire --network testnet --source alice   # re-run postDeploy hooks only
npx ctg sync-env --network testnet              # rewrite frontend.envFile only
npx ctg smoke --network testnet --source alice  # read-only checks from config
npx ctg regression --network testnet --source alice  # test → build → deploy --if-changed → generate → smoke

CI and regression

bash
npx ctg doctor --network testnet --strict-bindings   # fail on stale bindings
npx ctg status --network testnet --strict            # after deploy --no-generate
npx ctg ci run --network testnet --source alice --strict  # doctor + smoke in CI
ctg identity export > stellar-config.b64             # rotate CAATINGA_CI_STELLAR_CONFIG_B64

See Production readiness and Testing for workflow details.

Commands

CommandWhat it does
ctg init <dir>Scaffold a project from a template
ctg doctorCheck Node, Stellar CLI, Rust, config, artifacts, network, identity
ctg build [contract]Compile contract WASM; omit name to build all configured contracts
ctg deploy [contract]Deploy (graph-aware), record artifacts, auto-generate bindings
ctg upgrade <contract>In-place WASM upgrade on existing contractId (upload + invoke)
ctg wireRun configured postDeploy hooks against deployed contracts
ctg sync-envWrite configured frontend env vars from deploy artifacts
ctg generate [contract](Re)generate TypeScript bindings from deployed contract IDs
ctg statusTable of deployed contracts + binding freshness per network
ctg smokeRun configured read-only smoke checks with expect DSL
ctg regressionFull pipeline: test → build → deploy --if-changed → generate → smoke
ctg ci runCI helper: doctor then smoke
ctg identity export|importExport/import Stellar CLI config as base64 tarball
ctg invoke <contract.method>Call a contract method from the CLI
ctg read <contract.method>Simulate a read-only contract method (no signing)

Flags

FlagCommandsDescription
--network <name>doctor, deploy, upgrade, generate, status, invoke, wire, smoke, regression, ciNetwork from caatinga.config.ts
--source <identity>doctor, deploy, upgrade, invoke, wire, smoke, regression, ci, zk invokeLocal Stellar CLI identity that signs (never a G... address)
--forcedeployRedeploy even when artifacts already hold a contract ID
--upgradedeployRedeploy with upgrade history (new contractId)
--if-changeddeploy, upgrade, regressionSkip when local WASM hash matches artifact
--expected-hashupgradeFail before upload if local WASM hash differs
--no-buildupgradeSkip ctg build before upload
--generateupgradeRegenerate bindings after successful in-place upgrade
--sync-envupgradeSync frontend env after successful in-place upgrade
--no-generatedeploySkip automatic bindings generation (CI without binding needs)
--no-wiredeploySkip automatic postDeploy hooks after a full graph deploy
--no-sync-envdeploySkip automatic frontend env sync after a full graph deploy
--no-depsdeployDeploy a single contract without its dependsOn graph
--verify-depsdeployConfirm dependency contract IDs exist on-chain first
--no-stale-checkdeploySkip the WASM-older-than-sources warning
--strict-networkgenerateFail when network has no artifacts block
--strictstatus, doctor, ci runstatus: fail on stale bindings; doctor/ci: strict env+bindings
--strict-envdoctorFail when frontend env file drifts from artifacts
--strict-bindingsdoctorFail when bindings are stale or missing
--all-networksdoctorReport deploy/bindings matrix for every configured network
--expect <dsl>readAssert stdout with postDeploy expect DSL
--quiet / --summaryreadCompact output for large array payloads
--jsonstatusMachine-readable output for scripts

Binding freshness

status, doctor --network, and generate report binding state per contract:

StateMeaningFix
freshBindings match the deployed contractId + wasmHash
staleContract redeployed since last generatectg generate <name> --network <net>
missingNo bindings on disk (or contract not deployed)deploy, or ctg generate
unknownBindings exist but predate freshness trackingregenerate once to start tracking

Freshness is tracked by a .caatinga-bindings.json marker written next to each generated binding package.

Where things live

FileHolds
caatinga.config.tsContracts, WASM paths, networks, bindings output dir, optional buildRoot, postDeploy, postDeployRead, smoke, and frontend env mapping
caatinga.artifacts.jsonDeployed contract IDs + WASM hashes per network
frontend/.env.localOptional generated view of artifacts for custom frontends when frontend.envFile is configured
contracts/generated/<name>/Self-contained binding package generated by @stellar/stellar-sdk generate (+ freshness marker); Caatinga patches package.json so Vite resolves ./src/index.ts without a separate tsc build

Setup broken? npx ctg doctor --network testnet --source alice tells you which layer.

ZK loop

Dev/testnet only: ctg zk build runs a single-party development ceremony. Mainnet deploy/invoke with those artifacts is blocked unless you pass --allow-dev-ceremony (not for production).

bash
ctg zk init my-zk-dapp && cd my-zk-dapp && npm install
npx ctg build verifier
npx ctg zk build main
npx ctg deploy verifier --network testnet --source alice
npx ctg zk prove main
npx ctg zk invoke main --source alice

Full reference: ZK module · ZK tutorial · CLI · Errors.