Skip to content

Support multiple simultaneous sessions across different chains #3

@broody

Description

@broody

Problem

Currently, the CLI only supports one active session at a time. Users cannot maintain simultaneous sessions on different chains (e.g., mainnet and sepolia). This creates friction when:

  • Developers need to test on sepolia while having production access on mainnet
  • Users want to switch between networks without re-registering and re-authorizing
  • Multiple chains require different sessions (mainnet, sepolia, Cartridge SLOT)

Currently, registering a new session on a different chain overwrites the existing session.

Proposed Solution

Support multiple concurrent sessions, one per chain. Sessions should be isolated by chain_id in storage.

Storage Structure

Instead of a single session, store sessions keyed by chain_id:

~/.config/controller-cli/
  sessions/
    SN_MAIN.json          # Mainnet session
    SN_SEPOLIA.json       # Sepolia session  
    SLOT.json             # Cartridge SLOT session (future)

Or use the existing storage format with chain_id in the key (which already exists):

@cartridge/session/0x{address}/0x{chain_id}

Command Behavior

Auto-detect from --rpc-url:

# Execute on mainnet (uses mainnet session)
controller execute \
  --contract 0x... \
  --entrypoint transfer \
  --calldata 0x... \
  --rpc-url https://api.cartridge.gg/x/starknet/mainnet

# Execute on sepolia (uses sepolia session)
controller execute \
  --contract 0x... \
  --entrypoint transfer \
  --calldata 0x... \
  --rpc-url https://api.cartridge.gg/x/starknet/sepolia

Status shows all sessions:

controller status --json
{
  "status": "active",
  "sessions": {
    "SN_MAIN": {
      "address": "0x...",
      "chain_id": "SN_MAIN",
      "expires_at": 1735689600,
      "expires_in_seconds": 3600,
      "is_expired": false
    },
    "SN_SEPOLIA": {
      "address": "0x...",
      "chain_id": "SN_SEPOLIA",
      "expires_at": 1735689600,
      "expires_in_seconds": 7200,
      "is_expired": false
    }
  },
  "keypair": {
    "public_key": "0x...",
    "has_private_key": true
  }
}

Registration Flow

Sessions are registered per-chain:

# Register mainnet session
controller register-session mainnet-policy.json \
  --rpc-url https://api.cartridge.gg/x/starknet/mainnet

# Register sepolia session (doesn't overwrite mainnet)
controller register-session sepolia-policy.json \
  --rpc-url https://api.cartridge.gg/x/starknet/sepolia

Implementation Details

Changes Required

  1. Storage layer (src/commands/status.rs, src/commands/register.rs, src/commands/execute.rs):

    • Store multiple sessions keyed by chain_id
    • Load the appropriate session based on --rpc-url
  2. Status command:

    • List all available sessions
    • Show which chains have active sessions
    • Indicate current/default session
  3. Execute command:

    • Determine chain_id from --rpc-url
    • Load corresponding session for that chain
    • Error if no session exists for that chain
  4. Clear command:

    • Add optional flag to clear specific chain: controller clear --chain sepolia
    • Default behavior: clear all sessions

Error Handling

# Attempting to execute on mainnet without mainnet session
controller execute --rpc-url https://api.cartridge.gg/x/starknet/mainnet ...
{
  "status": "error",
  "error_code": "NoSessionForChain",
  "message": "No active session found for chain SN_MAIN",
  "recovery_hint": "Run 'controller register-session policy.json --rpc-url https://api.cartridge.gg/x/starknet/mainnet' to create a mainnet session"
}

Benefits

  1. Developer productivity: Switch between testnet/mainnet without re-auth
  2. Multi-chain support: Ready for Cartridge SLOT and future chains
  3. Better UX: Natural workflow for cross-chain operations
  4. LLM-friendly: LLMs can execute on appropriate chain based on user intent

Future Considerations

  • Support for custom RPC endpoints (non-Cartridge chains)
  • Session switching via --chain flag as alternative to --rpc-url
  • Default chain preference in config
  • Session synchronization across devices

Related Files

  • src/commands/status.rs - Status output
  • src/commands/register.rs - Session registration
  • src/commands/execute.rs - Session loading
  • src/commands/clear.rs - Session cleanup
  • LLM_USAGE.md - Documentation updates needed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions