skills/controller-sessions/SKILL.md
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.
npx skillsauth add cartridge-gg/docs controller-sessionsInstall 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.
Session policies define which contracts and methods your app can call.
They are required for session-based transaction execution — without policies, execute() will fail with error code 130 ("Array length mismatch") because the Controller's on-chain session validation requires a merkle proof for each call.
Without policies, Controller falls back to manual approval via the keychain modal. On local Katana, policies are required because new Controller accounts cannot be properly deployed without them.
import { SessionPolicies } from "@cartridge/controller";
const policies: SessionPolicies = {
contracts: {
"0x1234...": {
name: "My Game",
description: "Game contract interactions",
methods: [
{
name: "Move Player",
entrypoint: "move_player",
description: "Move player on the map",
},
{
name: "Attack",
entrypoint: "attack",
},
],
},
},
};
const controller = new Controller({ policies });
For approve methods, specify spending limits in hex format:
const policies: SessionPolicies = {
contracts: {
// ETH contract
"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7": {
name: "Ethereum",
methods: [
{
name: "approve",
entrypoint: "approve",
spender: "0x1234567890abcdef1234567890abcdef12345678",
amount: "0x3", // Limit: 3 ETH (hex, accounts for decimals)
},
],
},
},
};
0xffffffffffffffffffffffffffffffff for unlimited (max uint128)Pre-approve typed message signing:
const policies: SessionPolicies = {
messages: [
{
name: "Game Message",
types: {
StarknetDomain: [
{ name: "name", type: "shortstring" },
{ name: "version", type: "shortstring" },
{ name: "chainId", type: "shortstring" },
{ name: "revision", type: "shortstring" },
],
GameMessage: [
{ name: "content", type: "string" },
{ name: "timestamp", type: "felt" },
],
},
primaryType: "GameMessage",
domain: {
name: "MyGame",
version: "1",
chainId: "SN_MAIN",
revision: "1",
},
},
],
};
const controller = new Controller({
policies,
errorDisplayMode: "notification", // "modal" | "notification" | "silent"
});
| propagateSessionErrors | errorDisplayMode | Behavior |
|--------------------------|-------------------|----------|
| true | Any | Errors rejected immediately, no UI shown |
| false (default) | modal | Opens controller modal |
| false | notification | Shows clickable toast |
| false | silent | No UI, logged to console |
Return errors to your app instead of showing keychain UI:
import { Controller, ResponseCodes } from "@cartridge/controller";
const controller = new Controller({
policies,
propagateSessionErrors: true,
});
const result = await account.execute(calls);
if (result.code === ResponseCodes.SUCCESS) {
console.log("Tx hash:", result.transaction_hash);
} else if (result.code === ResponseCodes.ERROR) {
console.error(result.message, result.error);
}
Note: SessionRefreshRequired and ManualExecutionRequired always show modal regardless of settings.
For mobile apps and cross-platform logout flows:
const connector = new SessionConnector({
policies,
rpc: "https://api.cartridge.gg/x/starknet/mainnet",
chainId: "SN_MAIN",
redirectUrl: "myapp://callback",
disconnectRedirectUrl: "myapp://logout", // Where to go after logout
});
Verified policies display trust badges and streamlined approval flows.
Submit configs to @cartridge/presets for verification.
type SessionOptions = {
rpc: string; // RPC endpoint URL
chainId: string; // Chain ID
policies: SessionPolicies; // Approved transaction policies
redirectUrl: string; // URL to redirect after auth
disconnectRedirectUrl?: string; // URL to redirect after logout
signupOptions?: AuthOptions; // Auth methods to show
};
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.
data-ai
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.
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.