Guidance for installing and operating the Cartridge Controller CLI (`controller`) to create human-approved sessions and execute Starknet transactions with JSON output, explicit network selection, scoped policies, paymaster control, and error recovery.
80 stars
0 votes
0 copies
1 view
Added September 4, 2026
ai-agentspythongobashtestinggitapisecurity
Works with
cli
api
Security analysis
C71/100
criticalPipes output to a shell interpreter
mediumUses curl or wget to download content
criticalDownloads and executes remote scripts — classic supply chain attack
Installs into .claude/skills of the current project.
Are you the author of Controller Cli?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/keep-starknet-strange-controller-cli)
---
name: controller-cli
description: "Guidance for installing and operating the Cartridge Controller CLI (`controller`) to create human-approved sessions and execute Starknet transactions with JSON output, explicit network selection, scoped policies, paymaster control, and error recovery."
license: Apache-2.0
metadata:
author: keep-starknet-strange
version: "1.0.0"
org: keep-starknet-strange
compatibility: "controller-cli >=0.1.x, Python 3.8+"
keywords:
- starknet
- cartridge
- controller
- controller-cli
- session
- paymaster
- voyager
allowed-tools:
- Bash
- Read
- Write
- Grep
user-invocable: true
---
# Cartridge Controller CLI
Use this skill when you need to run the Cartridge Controller CLI (`controller-cli`) to create a scoped session (human-approved) and then execute Starknet transactions via that session.
## When to Use
- Operating Cartridge Controller sessions with explicit network and least-privilege policies.
- Running `controller` or `controller_safe.py` for human-approved Starknet transactions.
## When NOT to Use
- General Starknet scripting that does not rely on Cartridge Controller.
- Contract authoring, testing, deployment, or security audit workflows.
Related modules: [skills catalog](../README.md).
## Non-Negotiable Rules
- Always pass `--json` and treat outputs as JSON.
- Always be explicit about network. Never rely on defaults:
- `--chain-id SN_MAIN|SN_SEPOLIA`, or
- `--rpc-url <explicit url>`.
- `controller register` requires human browser authorization. Do not automate/bypass it.
- Use least-privilege policies only. Do not add token transfer permissions unless explicitly requested.
- Transaction links: use Voyager only:
- Mainnet: `https://voyager.online/tx/0x...`
- Sepolia: `https://sepolia.voyager.online/tx/0x...`
## Quick Start
```bash
curl -fsSL https://raw.githubusercontent.com/cartridge-gg/controller-cli/main/install.sh | bash
export PATH="$PATH:$HOME/.local/bin"
controller --version
```
## Safer Wrapper (Recommended)
This skill includes a small wrapper that enforces the rules above and normalizes output:
```bash
python3 scripts/controller_safe.py status
python3 scripts/controller_safe.py register --preset loot-survivor --chain-id SN_MAIN
python3 scripts/controller_safe.py execute 0xCONTRACT entrypoint 0xCALLDATA --rpc-url https://api.cartridge.gg/x/starknet/sepolia
```
Behavior:
- Adds `--json` if missing.
- Refuses to run `call|execute|register|transaction` without `--chain-id` or `--rpc-url`.
- Parses stdout as JSON.
- If `.status == "error"`, prints `error_code`, `message`, `recovery_hint` and exits non-zero.
## Deterministic Workflow
### 1) Generate Keypair
```bash
controller generate --json
```
The private key is stored locally (typically `~/.config/controller-cli/`).
### 2) Check Session Status
```bash
controller status --json
```
Common states:
- `no_session` (no keypair)
- `keypair_only` (needs registration)
- `active` (registered and not expired)
### 3) Register Session (Human Approval Required)
Requirement: a human must approve in a browser.
Option A (preferred): preset policies:
```bash
controller register --preset loot-survivor --chain-id SN_MAIN --json
```
Option B: least-privilege policy file:
```bash
controller register --file policy.json --rpc-url https://api.cartridge.gg/x/starknet/sepolia --json
```
Authorization output includes `short_url` and/or `authorization_url`:
- Display `short_url` if present; otherwise display `authorization_url`.
- Ask the user to open it and approve.
- The CLI blocks until approved or timeout (typically ~6 minutes).
### 4) Execute Transaction
Single call (positional args: contract, entrypoint, calldata):
```bash
controller execute 0xCONTRACT transfer 0xRECIPIENT,0xAMOUNT_LOW,0xAMOUNT_HIGH \
--rpc-url https://api.cartridge.gg/x/starknet/sepolia \
--json
```
Multiple calls from file:
```bash
controller execute --file calls.json --rpc-url https://api.cartridge.gg/x/starknet/sepolia --json
```
Optional confirmation wait:
```bash
controller execute --file calls.json --rpc-url https://api.cartridge.gg/x/starknet/sepolia --wait --timeout 300 --json
```
### 5) Read-Only Call (No Session Needed)
```bash
controller call 0xCONTRACT balance_of 0xADDRESS --chain-id SN_SEPOLIA --json
```
### 6) Transaction Status
```bash
controller transaction 0xTX_HASH --chain-id SN_SEPOLIA --wait --timeout 300 --json
```
### 7) Lookup Usernames / Addresses
```bash
controller lookup --usernames alice,bob --json
controller lookup --addresses 0x123...,0x456... --json
```
## Network Selection
Always be explicit about network.
Supported networks:
| Chain ID | RPC URL |
| --- | --- |
| `SN_MAIN` | `https://api.cartridge.gg/x/starknet/mainnet` |
| `SN_SEPOLIA` | `https://api.cartridge.gg/x/starknet/sepolia` |
Priority order:
1. `--rpc-url` flag
2. Stored session RPC URL (from registration)
3. Config default (lowest)
If network is ambiguous:
1. Run `controller status --json`
2. Match the session `chain_id`, or ask the user
## Paymaster Control
Default behavior uses the paymaster (free execution). If the paymaster is unavailable, the transaction fails (no silent fallback).
To self-pay with user funds:
```bash
controller execute ... --no-paymaster --json
```
## Amount Encoding (u256)
Many ERC20-style amounts are `u256` split into `(low, high)` u128 limbs.
For values that fit in u128 (most cases): set `high = 0x0`.
Example calldata:
`0xRECIPIENT,0x64,0x0`
## Error Handling
Errors are JSON:
```json
{
"status": "error",
"error_code": "ErrorType",
"message": "...",
"recovery_hint": "..."
}
```
Always branch on `error_code` and follow `recovery_hint`.
Common recoveries:
- `NoSession`: run `controller generate --json`
- `SessionExpired`: re-run `controller register ... --json`
- `ManualExecutionRequired`: policy does not authorize the call; tighten/adjust policy and re-register
- `CallbackTimeout`: user did not approve quickly enough; re-run `register` and retry
## Input Validation
Addresses must be `0x`-prefixed hex.
```bash
python3 scripts/validate_hex_address.py 0xabc...
```