skills/controller-setup/SKILL.md
Integrate Cartridge Controller wallet into Starknet applications. Use when setting up Controller for the first time, installing packages, configuring chains/RPC endpoints, or troubleshooting basic integration issues. Covers installation, Controller instantiation, ControllerConnector vs SessionConnector choice, chain configuration, and package compatibility.
npx skillsauth add cartridge-gg/docs controller-setupInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Cartridge Controller is a gaming-focused smart contract wallet for Starknet with session keys, passkeys, and paymaster support.
# Basic Controller usage
pnpm add @cartridge/controller starknet
# With framework connectors (React, native apps)
pnpm add @cartridge/controller @cartridge/connector starknet
import Controller from "@cartridge/controller";
const controller = new Controller();
const account = await controller.connect();
// Ready to execute transactions
Session policies are required for session-based transaction execution.
Without policies, execute() fails with error code 130 because the Controller's session validation needs a merkle proof per call.
Without policies, Controller falls back to manual approval via the hosted keychain modal. On local Katana, policies are required because new Controller accounts cannot be properly deployed without them.
| Use Case | Connector | Key Difference |
|----------|-----------|----------------|
| Web apps with starknet-react | ControllerConnector | Keys managed via browser cookies & localStorage |
| Native/mobile apps | SessionConnector | App generates local keypair, authenticates via browser redirect |
import { ControllerConnector } from "@cartridge/connector";
const connector = new ControllerConnector({
policies, // Session policies (required for session-based execution)
signupOptions, // Optional auth methods to show
});
import { SessionConnector } from "@cartridge/connector";
import { constants } from "starknet";
const connector = new SessionConnector({
policies,
rpc: "https://api.cartridge.gg/x/starknet/mainnet",
chainId: constants.StarknetChainId.SN_MAIN,
redirectUrl: "myapp://auth-callback",
disconnectRedirectUrl: "myapp://logout", // Optional logout redirect
signupOptions: ["webauthn", "google"], // Optional auth methods
});
Session flow: App generates keypair → User authenticates in browser → Browser redirects back → App signs transactions locally.
Default RPC endpoints are provided. Override with custom chains:
import { constants } from "starknet";
const controller = new Controller({
chains: [
{ rpcUrl: "https://api.cartridge.gg/x/starknet/mainnet" },
{ rpcUrl: "https://api.cartridge.gg/x/starknet/sepolia" },
{ rpcUrl: "http://localhost:5050" }, // Local Katana
],
defaultChainId: constants.StarknetChainId.SN_MAIN,
});
When using Controller with a local Katana instance, the Katana config must deploy Controller contracts at genesis. Without this, transactions fail with "Requested contract address ... is not deployed".
Required katana.toml config:
[dev]
dev = true
no_fee = true
[cartridge]
paymaster = true # Enables paymaster AND deploys Controller contracts at genesis
[server]
http_cors_origins = "*"
Note: paymaster = true implicitly enables controllers = true.
Start Katana with config:
katana --config katana.toml
See the Katana configuration guide for all TOML options.
Defer iframe mounting until connect() is called:
const controller = new Controller({
lazyload: true,
});
type ControllerOptions = {
chains?: Chain[]; // Custom RPC endpoints
defaultChainId?: string; // Default chain (hex encoded)
policies?: SessionPolicies; // Session policies
propagateSessionErrors?: boolean; // Return errors to caller
errorDisplayMode?: "modal" | "notification" | "silent";
lazyload?: boolean; // Defer iframe mount
preset?: string; // Theme preset name
signupOptions?: AuthOptions; // Auth methods to show
};
{
"@cartridge/connector": "0.11.3-alpha.1",
"@cartridge/controller": "0.11.3-alpha.1",
"@starknet-react/core": "^5.0.1",
"@starknet-react/chains": "^5.0.1",
"starknet": "^8.1.2"
}
Cookies required: Controller sets essential cookies for initialization.
HTTPS required in dev: Use vite-plugin-mkcert for local HTTPS.
Connector outside components: Create ControllerConnector outside React components to avoid recreation on re-render.
development
Configure authentication methods for Cartridge Controller including passkeys, social login, and external wallets. Use when implementing user authentication, adding multiple signers for account recovery, customizing signup options, or integrating external wallets like MetaMask or Phantom. Covers WebAuthn passkeys, Google/Discord/Twitter OAuth, wallet connections, and dynamic authentication flows.
testing
Configure session keys and policies for Cartridge Controller to enable gasless, pre-approved transactions. Use when defining contract interaction policies, setting spending limits, configuring signed message policies, or implementing error handling for session-based transactions. Covers SessionPolicies type, policy definitions, verified sessions, and error display modes.
development
Integrate Cartridge Controller into React applications using starknet-react. Use when building React/Next.js web apps with Controller, setting up StarknetConfig provider, using hooks like useConnect/useAccount, or implementing wallet connection components. Covers ControllerConnector setup, provider configuration, and transaction execution patterns.
development
Integrate Cartridge Controller into native mobile applications (iOS, Android, React Native) and web wrappers (Capacitor). Use when building mobile games or apps that need Controller wallet functionality with local keypair signing. Covers SessionConnector for native auth flows, Controller.c FFI bindings, passkey configuration with Apple App Site Association, and platform-specific setup.