Skip to main content

Python bindings for Sui Move package analysis and transaction replay

Project description

sui-sandbox

Python bindings for Sui Move package analysis, transaction replay, view function execution, and Move function fuzzing.

Built on sui-sandbox — runs the real Sui Move VM locally via PyO3. All functions are standalonepip install sui-sandbox is all you need.

Installation

From PyPI

pip install sui-sandbox

From source (requires Rust toolchain)

cd crates/sui-python
pip install maturin
maturin develop --release

Quick Start

import sui_sandbox

# Extract the full interface of the Sui framework
interface = sui_sandbox.extract_interface(package_id="0x2")
for mod_name, mod_data in interface["modules"].items():
    print(f"{mod_name}: {len(mod_data.get('functions', {}))} functions")

# Replay a historical transaction via Walrus (no API key needed)
result = sui_sandbox.replay(
    "At8M8D7QoW3HHXUBHHvrsdhko8hEDdLAeqkZBjNSKFk2",
    checkpoint=239615926,
)
print(f"Success: {result['local_success']}")

# Fuzz a Move function
report = sui_sandbox.fuzz_function("0x1", "u64", "max", iterations=50)
print(f"Successes: {report['outcomes']['successes']}")

API Reference

extract_interface(*, package_id=None, bytecode_dir=None, rpc_url="https://fullnode.mainnet.sui.io:443")

Extract the complete interface JSON for a Move package — all modules, structs, functions, type parameters, abilities, and fields.

Provide either package_id (fetched via GraphQL) or bytecode_dir (local directory containing bytecode_modules/*.mv files), but not both.

Returns: dict with full interface tree.

interface = sui_sandbox.extract_interface(package_id="0x1")
for mod_name, mod_data in interface["modules"].items():
    print(f"{mod_name}: {len(mod_data.get('functions', {}))} functions")

get_latest_checkpoint()

Get the latest archived checkpoint number from Walrus.

Returns: int

cp = sui_sandbox.get_latest_checkpoint()
print(f"Latest checkpoint: {cp}")

get_checkpoint(checkpoint)

Fetch a checkpoint from Walrus and return a summary.

Returns: dict with checkpoint, epoch, timestamp_ms, transaction_count, transactions (list), and object_versions_count.

data = sui_sandbox.get_checkpoint(239615926)
for tx in data["transactions"]:
    print(f"  {tx['digest']}: {tx['commands']} commands, {tx['input_objects']} inputs")

fetch_package_bytecodes(package_id, *, resolve_deps=True)

Fetch package bytecodes via GraphQL, optionally resolving transitive dependencies.

Returns: dict with packages (map of package ID to list of base64-encoded module bytecodes) and count.

pkgs = sui_sandbox.fetch_package_bytecodes("0x2", resolve_deps=True)
print(f"Fetched {pkgs['count']} packages")

json_to_bcs(type_str, object_json, package_bytecodes)

Convert a Sui object JSON representation to BCS bytes using Move type layout.

Returns: bytes

transaction_json_to_bcs(transaction_json)

Convert Snowflake-style TRANSACTION_JSON (or canonical Sui TransactionData JSON) into raw transaction BCS bytes.

This is useful when your pipeline has transaction JSON but not transaction BCS.

Returns: bytes

call_view_function(package_id, module, function, *, type_args=None, object_inputs=None, pure_inputs=None, child_objects=None, package_bytecodes=None, fetch_deps=True)

Execute a Move function in the local VM with full control over object and pure inputs.

Returns: dict with success, error, return_values, return_type_tags, gas_used.

object_inputs entries must use:

{
    "object_id": "0x...",
    "type_tag": "0x2::...",
    "bcs_bytes": [1, 2, 3],   # or bytes in Python
    "is_shared": False,       # optional
    "mutable": False,         # optional
}

Legacy compatibility: owner is also accepted as an alias for is_shared: "immutable" / "address_owned" => non-shared, "shared" => shared.

fuzz_function(package_id, module, function, *, iterations=100, seed=None, sender="0x0", gas_budget=50_000_000_000, type_args=[], fail_fast=False, max_vector_len=32, dry_run=False, fetch_deps=True)

Fuzz a Move function with randomly generated inputs.

Use dry_run=True to check parameter classification without executing.

Returns: dict with target, classification, outcomes (successes/errors), gas_profile.

# Dry run — check if function is fuzzable
info = sui_sandbox.fuzz_function("0x1", "u64", "max", dry_run=True)
print(f"Fuzzable: {info['classification']['is_fully_fuzzable']}")

# Full fuzz run
report = sui_sandbox.fuzz_function("0x1", "u64", "max", iterations=50, seed=42)
print(f"Successes: {report['outcomes']['successes']}")

import_state(*, state=None, transactions=None, objects=None, packages=None, cache_dir=None)

Import replay data from JSON/JSONL/CSV into a local replay cache.

sui_sandbox.import_state(
    transactions="exports/transactions.csv",
    objects="exports/objects.jsonl",
    packages="exports/packages.csv",
    cache_dir=".sui-cache",
)

deserialize_transaction(raw_bcs) / deserialize_package(bcs)

Decode raw BCS blobs into structured JSON for debugging or preprocessing.

replay(digest=None, *, rpc_url=..., source="hybrid", checkpoint=None, state_file=None, cache_dir=None, allow_fallback=True, prefetch_depth=3, prefetch_limit=200, auto_system_objects=True, no_prefetch=False, compare=False, analyze_only=False, verbose=False)

Replay a historical Sui transaction locally with the Move VM.

Replay source modes:

  • checkpoint=... uses Walrus (no API key needed)
  • state_file=... replays from a local exported state file
  • source="local" (or cache_dir=...) replays from imported local cache
  • otherwise uses gRPC/hybrid (requires SUI_GRPC_API_KEY)

Use analyze_only=True to inspect state hydration without executing the transaction.

Use compare=True to compare local execution results with on-chain effects.

Returns: dict — replay results (with local_success, effects, execution_path, optionally comparison) or analysis summary (with commands, inputs, objects, packages, input_summary).

# Analyze state hydration only (no VM execution)
analysis = sui_sandbox.replay(
    "At8M8D7QoW3HHXUBHHvrsdhko8hEDdLAeqkZBjNSKFk2",
    checkpoint=239615926,
    analyze_only=True,
)
print(f"Commands: {analysis['commands']}, Objects: {analysis['objects']}")

# Full replay via Walrus (no API key needed)
result = sui_sandbox.replay(
    "At8M8D7QoW3HHXUBHHvrsdhko8hEDdLAeqkZBjNSKFk2",
    checkpoint=239615926,
)
print(f"Success: {result['local_success']}")

# Full replay via local state file
result = sui_sandbox.replay(state_file="exports/replay_state.json")

# Full replay via local cache import
sui_sandbox.import_state(state="exports/replay_state.json", cache_dir=".sui-cache")
result = sui_sandbox.replay(digest="DigestHere...", source="local", cache_dir=".sui-cache")

# Full replay via gRPC with comparison
import os
os.environ["SUI_GRPC_API_KEY"] = "your-key"
result = sui_sandbox.replay("DigestHere...", compare=True)
if result.get("comparison"):
    print(f"Status match: {result['comparison']['status_match']}")

Platform Support

Pre-built wheels are available for:

  • Linux x86_64 (glibc 2.17+)
  • Linux aarch64 (glibc 2.17+)
  • macOS x86_64 (10.12+)
  • macOS aarch64 (11.0+)

Building from source requires Rust 1.80+ and Python 3.9+.

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sui_sandbox-0.19.0.tar.gz (686.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sui_sandbox-0.19.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

sui_sandbox-0.19.0-cp313-cp313-macosx_11_0_arm64.whl (6.9 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

File details

Details for the file sui_sandbox-0.19.0.tar.gz.

File metadata

  • Download URL: sui_sandbox-0.19.0.tar.gz
  • Upload date:
  • Size: 686.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.15

File hashes

Hashes for sui_sandbox-0.19.0.tar.gz
Algorithm Hash digest
SHA256 ae14f53b78eaabf18e56829f2b07b19ba3413dedd385d7387bd3fdc1a81a495e
MD5 547f7ad836570fe7019a80c3842c5b1e
BLAKE2b-256 df4c4694344a16f1396aab4971be1dece733127195693132e36beff48d5ec964

See more details on using hashes here.

File details

Details for the file sui_sandbox-0.19.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sui_sandbox-0.19.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8283fa708ab15f2571fcb1e59b2203fdc020ac97524645e8791c1de13805ea78
MD5 3b6c49db8179ed7fde45961127c2f157
BLAKE2b-256 c67cb76b5d6c53eb7b003cb1a4c5bb8f15040353dfd031beacc6bda0dc060a4e

See more details on using hashes here.

File details

Details for the file sui_sandbox-0.19.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for sui_sandbox-0.19.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cb24ad5f7d82a17fdb041446789532038803c10c91d8186ce29fe4595128db06
MD5 544db854bb6d3e9feb531667e55fdb18
BLAKE2b-256 a8ccd6db09a0c186e1536d8fb9bd9908722644ec846fd099602d43026474c669

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page