npm.io
0.14.0 • Published 2 weeks ago

@cartridge/controller

Licence
Version
0.14.0
Deps
10
Size
3.2 MB
Vulns
0
Weekly
0
Stars
80

Controller Cover Image

Controller

Controller is a gaming specific smart contract wallet that enables seamless player onboarding and game interactions.

It supports transaction signing using Passkeys and Session Tokens.

Project structure

The project consists of several packages in the packages directory:

  • keychain - Sandboxed iframe hosted at https://x.cartridge.gg/ that fills the same role as an injected wallet like MetaMask or Rabby: holds keys, signs transactions, and prompts user for approval. Also displays account state (balances, activities, achievements).
  • controller - Main SDK implementing the account interfaces required by starknet.js. Ships two provider modes:
    • ControllerProvider (web apps) - Full-featured web wallet communicating with an embedded keychain iframe. Supports sessions as well as per-transaction approval.
    • SessionProvider (native apps) - Creates ephemeral session keys with pre-configured policies so transactions can execute without per-call approval.
  • connector - Registers configured providers through wallet-standard discovery, making them available to Starknet Start's <StarknetConfig>.

Integration examples live in examples/ (Next.js, Svelte, Node.js).

Starknet.js version support

Pick the Controller and connector line that matches the Starknet.js version your application is on:

@cartridge/controller / @cartridge/connector Starknet.js
0.13.x v8
0.14.x v10

Both packages are released together and share a version number, so keep them on the same line, and keep your application's Starknet.js dependency on the matching major. See the migration notes above before moving an existing application from 0.13.x to 0.14.x.

Requirements and Starknet.js v10 migration

Controller requires Node.js 22 or newer and depends on Starknet.js ^10.0.2. Applications upgrading from Controller 0.13.x should move their Starknet.js dependency to the same range so both resolve to a single copy. Starknet.js v10 no longer exposes provider methods through account instances, so application code should use account.provider.getChainId(), account.provider.callContract(), and account.provider.waitForTransaction().

The previous @starknet-react/core and @starknet-react/chains integration has moved to @starknet-start/react@1.0.8, with @starknet-start/chains@1.0.7, @starknet-start/providers@1.0.7, and @starknet-start/explorers@1.0.7. Starknet Start requires React 19.

Controller's marketplace and achievement integrations use @cartridge/arcade@0.4.0, whose published dependency graph is aligned on Dojo.js 2 (@dojoengine/core, @dojoengine/grpc, and @dojoengine/sdk at 2.0.0). Together, this migration requires Node.js 22, React 19, and the Starknet.js version described above. Applications should upgrade these dependencies together rather than mixing the previous Arcade 0.3 or Dojo.js 1 packages with Controller 0.14.

@starknet-start/providers@1.0.7 and @starknet-start/query@1.0.7 still resolve Starknet.js v9, so an application that installs them alongside Controller ends up with two copies of Starknet.js. This workspace collapses them with a package manager override, and applications should do the same until those packages depend on v10:

{
  "pnpm": { "overrides": { "starknet": "^10.0.2" } },
  "overrides": { "starknet": "^10.0.2" }
}

Automatic reconnection

@starknet-start/react@1.0.8 accepts an autoConnect prop on <StarknetConfig>, but it is only declared in the types — the provider never reads it, so a connected player is dropped on page reload. Until it is implemented upstream, reconnect from your own app: remember the last connector that was connected, reconnect to it on load, and forget it on disconnect.

Both React examples ship a small hook that does exactly that, intended to be copied into your own app to replicate the autoConnect feature:

It exports an AutoConnect component that renders nothing, so it can be mounted inside the provider where the hooks have access to the Starknet Start context:

import { AutoConnect } from "./useAutoConnect";

<StarknetConfig chains={[mainnet]} provider={provider} explorer={voyager}>
  <AutoConnect />
  {children}
</StarknetConfig>;

Custom Torii endpoint

Set toriiUrl when a game uses a Torii indexer that is not derived from its Slot project name:

import Controller from "@cartridge/controller";

const controller = new Controller({
  slot: "my-game-mainnet",
  toriiUrl: "https://torii.example.com",
});

An explicit toriiUrl takes precedence over slot. When toriiUrl is omitted, Controller retains the legacy Slot-derived endpoint at https://api.cartridge.gg/x/<slot>/torii.

A custom Torii is required to display custom ERC-20 and ERC-721 tokens in the Controller.

Controller client notifications

The controller emits toast notifications for wallet activity (transactions, network changes, achievements, etc.). To display them, mount <ControllerToaster /> once in your app and import its stylesheet — it is self-contained, with no extra dependencies to install:

import { ControllerToaster } from "@cartridge/controller/react";
import "@cartridge/controller/react/styles.css";

function App() {
  return (
    <>
      {/* your app */}
      <ControllerToaster />
    </>
  );
}

Toast types emitted: error, success, network, transaction, marketplace, achievement, user, setting, credits.

Optional props:

  • position — screen placement (default: bottom-right)
  • duration — display time in ms (default: 5000)
  • disabledTypes — toast types to suppress
  • collapseTransactions — minimal transaction toasts (icon only)

Development

Frontend

Install pnpm via corepack:

corepack enable pnpm

Install dependencies:

pnpm i

Run Controller with examples:

pnpm dev

This command builds all workspace dependencies first and start these servers:

The simplest way to then develop with your cartridge account is to port it over from the production keychain:

window.cartridge.importAccount("EXPORTED ACCOUNT");