This guide takes a developer who has never used sdkt from zero to a working inspection, audit, and upgrade-safety comparison in under five minutes. Every command is copy-pasteable and runs offline (no RPC, no account, no network) unless stated otherwise.
If you only want to inspect a WASM, skip install: Web Playground.
If you have not installed sdkt yet, follow README § Quick Start first. This document assumes sdkt is on your PATH and reports a version when you run sdkt --version.
Want the on-chain path next? After this offline walkthrough, follow the Testnet walkthrough (identity → fund → deploy → invoke → events).
Choose one of the following.
A. GitHub Release binary (no Rust toolchain required):
-
Open the Releases page and download the asset for your platform:
Platform Asset Linux (x86_64) sdkt-x86_64-unknown-linux-gnu.tar.gzLinux (aarch64) sdkt-aarch64-unknown-linux-gnu.tar.gzmacOS (Intel) sdkt-x86_64-apple-darwin.tar.gzmacOS (Apple Silicon) sdkt-aarch64-apple-darwin.tar.gzWindows:
sdkt-x86_64-pc-windows-msvc.zip(v2.6.0+) orcargo install sdkt-cli(crates.io is at v2.7.0).
A2. crates.io (Rust 1.88.0+):
cargo install sdkt-cli
sdkt --version-
Extract and run:
tar -xzf sdkt-<your-platform>.tar.gz chmod +x sdkt ./sdkt --version # Optional: make it available system-wide sudo mv sdkt /usr/local/bin/
B. Build from source (requires Rust 1.88.0+):
git clone https://github.com/SaboLabs/soroban-devkit
cd soroban-devkit
cargo install --path crates/sdkt-cliVersion note: the GitHub Release carries the current repository release (v2.7.0). crates.io also publishes v2.7.0, so
cargo install sdkt-cliinstalls v2.7.0.sdkt-agentremains a repo-only prototype and is not on crates.io. For the Windows zip use the release binary or build from source (option B).
sdkt --versionExpected output (version may be newer):
sdkt 2.7.0
Then confirm the CLI is responsive:
sdkt --helpThis lists every top-level command and subcommand. sdkt commands are offline by default — only a handful (e.g. inspect, storage, health) need an RPC endpoint, and they say so explicitly.
sdkt can read the public ABI and metadata of any compiled Soroban contract WASM without a network. This repository ships two tiny fixtures you can use right now.
sdkt wasm inspect crates/sdkt-cli/tests/fixtures/us_old.wasmWhat this command does:
- Parses the WASM binary and reports its size and SHA-256 hash (useful for verifying a deployed contract matches your build).
- Lists custom sections (e.g.
contractspecv0,contractenvmetav0,contractmetav0) that Soroban attaches to every contract. - Shows exported functions and the Contract Spec — the public functions, custom types, and events the contract exposes.
Example output:
WASM Inspection Report: crates/sdkt-cli/tests/fixtures/us_old.wasm
========================================
Size: 198 bytes
SHA-256 Hash: 05befa136e7f0829a5051d97b032f355a5e65976397df90b224d141942dce46c
Version: 1
Custom Sections (1):
- contractspecv0
Exported Functions (0):
Contract Spec Available: Yes
Functions: 2
- fn transfer(1) -> 0
- fn mint(1) -> 0
Custom Types: 1
Events: 1
The two functions transfer and mint are the contract's public interface. This is the same information a frontend or integrator would need to call it.
sdkt audit performs static security analysis on contract Rust source, catching common mistakes before deployment. Point it at any contract's src/lib.rs. The example below audits a tiny throwaway contract written to a temporary file — no repository fixture is required.
cat > /tmp/example_contract.rs <<'EOF'
#![no_std]
use soroban_sdk::{contract, contractimpl, Address};
#[contract]
pub struct Token;
#[contractimpl]
impl Token {
// Guarded entrypoint — the analyzer is satisfied by require_auth().
pub fn transfer(from: Address, to: Address, amount: u64) {
from.require_auth();
let _ = (to, amount);
}
// Privileged-shaped name with no auth guard — this is what AUTH-001 flags.
pub fn admin_action(admin: Address) {
let _ = admin;
}
}
EOF
sdkt audit /tmp/example_contract.rsStatic Analysis Report: /tmp/example_contract.rs
Severity: 1 critical, 0 warning, 0 info (1 total)
[critical] AUTH-001 [Token::admin_action]: Function `Token::admin_action` looks privileged but does not call require_auth()
Interpreting the output:
- The
AUTH-001rule flags a function whose name looks privileged (admin_action) and which never callsrequire_auth(). The guardedtransfernext to it is not flagged — that is the difference the rule detects. (This is the same rule and shape as the repository's ownexamples/sample_token/src/lib.rsfixture.) Severity: 0 critical, 0 warning, 0 info (0 total)withNo issues found.means the analyzer found nothing to flag.criticalfindings (e.g.AUTH-001/002/003/004— missing auth checks) should block a deploy.warningfindings (e.g.MOVE-001— a possible move-after-use of a local) are heuristic and worth a look but are not necessarily bugs.- JSON mode (
--format json) emits the same result as structured data for CI.
Exit code:
sdkt auditexits0even when it reportscriticalfindings — the CLI does not encode finding severity into its exit status. A CI gate must therefore read the result, not just the exit code: either use the reusable Action (itsseverity-thresholdinput fails the build oncritical) or parse--format jsonand checksummary.critical.
Audit runs entirely offline and is safe to gate pull requests on — through the
Action or a summary.critical check, not the raw exit code (see the note
above). See examples.md for the audit-on-PR recipe.
Before upgrading a deployed contract, confirm the new WASM is backwards-compatible with what is already on-chain. sdkt diff --upgrade-safety diffs two WASM files and renders a breaking-change verdict.
sdkt diff \
--old-wasm crates/sdkt-cli/tests/fixtures/us_old.wasm \
--new-wasm crates/sdkt-cli/tests/fixtures/us_new.wasm \
--upgrade-safetyHow to read the verdict:
Compatible: YES— the new contract keeps every function, event, and type the old one exposed (plus any additions). Safe to upgrade.Compatible: NO— at least one Breaking change was detected. TheBreaking:block lists exactly what changed:- Removed function / event / type — something callers depended on is gone.
- Changed signature — a function's arguments or return type changed.
- The
Non-breaking:block lists safe additions (new functions, events, or types) that do not break existing integrators.
Example output:
Upgrade Safety
==============
Compatible: NO
Breaking:
- Changed signature: mint()
- Removed event: Transfer
- Removed type: Point
Non-breaking:
- Added function: balance()
- Added event: Mint
- Added type: Circle
This tells you the upgrade changes mint()'s signature and drops the Transfer event and Point type — a breaking change — while adding balance(), a Mint event, and a Circle type. Use --deny-breaking with sdkt deploy to abort an upgrade automatically if this verdict is NO.
sdkt can sign a built transaction envelope with a local ED25519 identity, without any network or secret exposure. First create an identity, then build and sign an envelope.
# Create a local signing identity (stored in the keystore, never printed)
sdkt identity generate alice
# Build an unsigned envelope (offline; fee defaults to 100 stroops,
# override with --fee <STROPS>)
sdkt tx build \
--source <SOURCE_ACCOUNT> \
--sequence <SEQ> \
--contract <CONTRACT_ID> \
--function hello \
--output unsigned.xdr
# Validate it offline, then review what you are about to sign
sdkt tx validate --envelope unsigned.xdr
sdkt tx decode unsigned.xdr
# Sign with the local identity (offline; --network selects the signature hash)
sdkt tx sign --input unsigned.xdr --output signed.xdr --identity alice --network testnetThe signed envelope in signed.xdr is ready to broadcast with sdkt tx submit --envelope signed.xdr (requires RPC) or any compatible Stellar client. Signing itself uses only the local keystore — no RPC call is made.
You now know the three core offline workflows. Continue with:
- Testnet walkthrough — on-chain loop: identity → Friendbot fund → network profile → build → deploy → invoke → call → events / storage.
- Web Playground — inspect your own
.wasmin the browser (no install). - examples.md — copy-paste recipes for every subcommand (decode, storage, tx, deploy) and CI gating patterns.
- docs/compatibility.md — which real-world Soroban contracts
sdktis validated against, and the compatibility matrix. - docs/ci-cd.md — wire
sdkt auditandsdkt diff --upgrade-safetyinto GitHub Actions to block bad PRs and unsafe releases.
For the full command reference, see docs/cli.md. For build/install options and feature flags, see docs/getting-started/installation.md.