Skip to main content

Contract Commands (modal contract / modal c)

Manage contracts — create, commit, push, pull, and inspect.

Create

modal c create [OPTIONS]

Creates a new contract in the current directory.

What it creates:

.contract/           # Contract metadata
├── config.json # Contract configuration
├── commits/ # Commit storage
└── HEAD # Current commit reference
state/ # Working state directory

Options:

OptionDescription
--dir <DIR>Directory path where the contract will be created (defaults to current directory)
--output <FORMAT>Output format: text or json

Commit

modal c commit [OPTIONS]

Create a new commit from the contract working directories, a single state path, or an inline domain action.

Options:

OptionDescription
--path <PATH>State path to write for a single POST-style commit
--value <VALUE>Value for the single-path commit; strings, numbers, and JSON are accepted
--method <METHOD>Commit method for the single-path commit (default: post)
--dir <DIR>Contract directory (defaults to current directory)
--output <FORMAT>Output format: text or json
--sign <PASSFILE>Sign with a passfile path or identity name; repeat to attach multiple signatures
--all, -aCommit all changed state/, rules/, reposts/, and model/default.modality files. Staged REPOST dests emit method: repost.
--message, -m <MSG>Commit message
--action <JSON>Commit an inline JSON domain action or read it from a .json file path
--asset-id <ASSET_ID>Asset ID for CREATE commits
--quantity <QUANTITY>Asset quantity for CREATE commits
--divisibility <DIVISIBILITY>Asset divisibility for CREATE commits
--to-contract <TO_CONTRACT>Destination contract ID for SEND commits
--amount <AMOUNT>Amount for SEND commits
--send-commit-id <SEND_COMMIT_ID>Source SEND commit ID for RECV commits

Examples:

# Commit all changes with signature
modal c commit --all --sign alice -m "Add escrow rules"

# Commit all changes with multiple member signatures
modal c commit --all --sign alice --sign bob -m "Replace witness"

# Commit one state file
modal c commit --path /notes.text --value "signed update" --sign alice

# Commit a domain action
modal c commit --action '{"type":"DEPOSIT","amount":100}' --sign alice

Checkout

modal c checkout [OPTIONS]

Extract committed state to the working state/ directory.

Options:

OptionDescription
--dir <DIR>Contract directory (defaults to current directory)

Status

modal c status [OPTIONS]
modal status # alias for modal c status

Shows:

  • Current commit
  • Modified files
  • Staged changes
  • Rule validation status

Options:

OptionDescription
--dir <DIR>Contract directory (defaults to current directory)
--remote <NAME>Remote name to compare with (default: origin)
--output <FORMAT>Output format: text or json

Diff

modal c diff [OPTIONS]

Show changes between working state and committed state.

Options:

OptionDescription
--dir <DIR>Contract directory (defaults to current directory)
--output <FORMAT>Output format: text or json

Log

modal c log [OPTIONS]

Show commit history.

Options:

OptionDescription
--dir <DIR>Contract directory (defaults to current directory)
--limit <N>, -n <N>Limit number of commits shown
--output <FORMAT>Output format: text or json

Example output:

abc123 (HEAD) Add escrow rules [alice] 2024-01-15 10:30:00
def456 Initial contract setup [alice] 2024-01-15 10:00:00

Set

modal c set [OPTIONS] <PATH> <VALUE>

Set a state file value.

Options:

OptionDescription
--dir <DIR>Contract directory (defaults to current directory)

Examples:

# Set text value
modal c set /config/name.text "My Contract"

# Set boolean
modal c set /flags/active.bool true

Repost

modal c repost <SOURCE_CONTRACT> <SOURCE_PATH> [DEST_PATH]

Snapshot a value from another contract into this one so formulas can name the dest path.

Arguments:

ArgDescription
SOURCE_CONTRACTSource contract ID
SOURCE_PATHPath on the source (e.g. /parties/alice.id)
DEST_PATHOptional dest in this contract. Default: /reposts/<source_id><source_path>

Options:

OptionDescription
--from-dir <DIR>Read the source from a local contract directory instead of the hub
--dir <DIR>Dest contract directory (defaults to current directory)
modal c repost abc123 /notes/hello.text
modal c repost abc123 /parties/alice.id /parties/alice.id
modal c repost abc123 /notes/hello.text --from-dir ../source-contract
modal commit --all

Add Rule

modal c add-rule --name <NAME> [OPTIONS] <FORMULA>

Write a named rule file under rules/. The command creates rules/ if needed and wraps the formula as export default rule { starting_at $PARENT ... }.

Options:

OptionDescription
--name <NAME>Rule name written as rules/<name>.modality
--starting-at <ANCHOR>Rule anchor (default: $PARENT)
--dir <DIR>Contract directory (defaults to current directory)
modal c add-rule --name authorized \
'[] always([-signed_by(/parties/alice.id) -signed_by(/parties/bob.id)] false)'

Existing rule files are not overwritten. Run modal c commit --all after adding a rule.

AI

Configure a provider first with modal ai set. Then:

modal c ai suggest-rule <PROMPT>

Suggest a Modality rule formula from a plain-language prompt. Use the printed formula with modal c add-rule. Encodings follow the formula cookbook; witness models follow the model cookbook. If no provider is configured, the command fails with a hint to run modal ai set --provider openai|anthropic|grok|bedrock|ollama|cursor-agent.

modal c ai suggest-rule "after this commit either alice or bob must sign"
[] always([-signed_by(/parties/alice.id) -signed_by(/parties/bob.id)] false)

That printed formula is example output; yours may differ.

Set Named ID

modal c set-named-id [OPTIONS] <PATH> <NAME>

Set a .id file from a passfile path or a passfile name that resolves in the standard passfile locations.

Options:

OptionDescription
--dir <DIR>Contract directory (defaults to current directory)
modal c set-named-id /parties/alice.id alice
modal c set-named-id /parties/alice.id example/alice

Get

modal c get <PATH> [OPTIONS]

Get contract or state information.

Options:

OptionDescription
--commit <HASH>Get from specific commit
--rawOutput raw bytes
modal c get /parties/alice.id
modal c get /data/config.json --commit abc123

ID Commands

# Get contract ID
modal c id

# Get current commit ID
modal c commit-id

Push

modal c push [OPTIONS]

Push commits to a hub or chain validators.

Remote formats:

  • Hub: http://hub.example.com/contracts/<id>
  • Chain: /ip4/<addr>/tcp/<port>/p2p/<peer_id>

Options:

OptionDescription
--remote <URL>Target node multiaddress or hub URL; also saves it under the remote name
--remote-name <NAME>Remote name (default: origin)
--dir <DIR>Contract directory (defaults to current directory)
--node-dir <DIR>Node directory for identity/config when using P2P remotes
--hub-creds <FILE>Hub credentials file for HTTP hub remotes
--output <FORMAT>Output format: text or json

Pull

modal c pull [URL] [OPTIONS]

Pull commits from a hub or chain.

Options:

OptionDescription
[URL]Full contract URL to clone, such as https://hub/contracts/<id>
--remote <URL>Target node multiaddress or hub URL
--remote-name <NAME>Remote name (default: origin)
--dir <DIR>Contract directory (defaults to current directory)
--node-dir <DIR>Node directory for identity/config when using P2P remotes
--hub-creds <FILE>Hub credentials file for HTTP hub remotes
--output <FORMAT>Output format: text or json

Replay

modal c replay [OPTIONS]

Fetch a sequenced contract prefix (and posted WASM, if any) and re-check it locally. The original node is not trusted: the same accumulated rules used on sequenced apply are run again. That is independent replay.

# Stranger: fetch from a sequencer and verify
modal c replay --remote /ip4/127.0.0.1/tcp/10101/ws/p2p/<peer> \
--contract-id <id> --through <commit> --save prefix.json

# Later, offline
modal c replay --artifact prefix.json

Options:

OptionDescription
--artifact <FILE>Verify a saved replay artifact (no network)
--save <FILE>Write the fetched or local artifact as JSON
--remote <MULTIADDR>Sequencer to fetch /contract/replay from
--contract-id <ID>Contract id when fetching without --dir
--through <COMMIT>Sequenced tip to replay through
--dir <DIR>Local contract directory (used when not fetching)
--node-dir <DIR>Node directory for identity/config on P2P remotes
--output <FORMAT>Output format: text or json

Pack / Unpack

# Pack contract into portable file
modal c pack --output contract.modal

# Unpack contract file
modal c unpack contract.modal --output ./my-contract

Options:

CommandOptionDescription
pack--output <FILE>, -o <FILE>Output .contract file path
pack--dir <DIR>Contract directory (defaults to current directory)
unpack<INPUT>Input .contract file path
unpack--output <DIR>, -o <DIR>Output directory
unpack--forceOverwrite an existing output directory

Assets

modal c assets [OPTIONS]

Manage contract assets.

Options:

OptionDescription
--listList all assets
--add <PATH>Add asset
--remove <PATH>Remove asset

WASM Upload

modal c wasm-upload <WASM_FILE> [OPTIONS]

Upload a WASM module for custom predicates.

Options:

OptionDescription
--name <NAME>Module name
--sign <PASSFILE>Sign upload