Session Keys for StarkNet Account Abstraction

Implement session keys on StarkNet so users authenticate once and interact many times without re-prompting. Essential for games, social apps, and trading bots.

Overview

Session keys let users authenticate once and interact with your app many times without re-prompting for passkey confirmation. Think of it like staying logged in to a website instead of entering your password on every page. The user taps their passkey once at the start of a session, and all subsequent transactions go through automatically within defined permissions and time limits.

Why Session Keys Matter

Without session keys, every transaction requires a passkey tap: send USDC, stake, buy a SKU, call a contract. With session keys, one tap covers an entire session. This is essential for:

  • - Games. Players approve once, play many turns without interruption
  • - Social apps. Like, tip, and interact without re-auth on every action
  • - Trading. Execute multiple trades in a session
  • - Subscriptions. Recurring payments without manual approval each time

Session keys require walletType: "CHIPI". They do not work with "READY" (Argent X) wallets.

Create a Session Key

Use the useCreateSessionKey hook to create a time-limited, scope-limited session:

tsximport { useCreateSessionKey } from "@chipi-stack/nextjs";

const { mutateAsync: createSession } = useCreateSessionKey();

const session = await createSession({
  encryptKey: passkeyCredential,
  wallet: userWallet,
  allowedMethods: [
    {
      contractAddress: "0x_TARGET_CONTRACT",
      entrypoint: "transfer",
    },
  ],
  expiry: Math.floor(Date.now() / 1000) + 3600, // 1 hour
  bearerToken: process.env.NEXT_PUBLIC_CHIPI_API_KEY!,
});

The allowedMethods array defines the security boundary. A session key for "transfer" cannot call "approve" or any other function. The expiry limits the time window, reducing risk even if a session key is compromised.

Execute Transactions with a Session Key

Once created, use the session key for subsequent transactions without any passkey prompt:

tsximport { useExecuteSessionTransaction } from "@chipi-stack/nextjs";

const { mutateAsync: execute } = useExecuteSessionTransaction();

await execute({
  sessionKey: session,
  wallet: userWallet,
  calls: [
    {
      contractAddress: "0x_TARGET_CONTRACT",
      entrypoint: "transfer",
      calldata: [recipientAddress, amountLow, amountHigh],
    },
  ],
  bearerToken: process.env.NEXT_PUBLIC_CHIPI_API_KEY!,
});

No encryptKey needed here. The session key replaces the passkey for authorized operations.

Manage Session Lifecycle

  • - Store the active session in React state or context
  • - Check expiry before executing. If expired, prompt the user to create a new session
  • - Revoke session keys when the user logs out or when the session is no longer needed
  • - Never create unlimited session keys. Always set an expiry
  • - Scope allowedMethods to only what's needed
  • - Store session keys securely in memory. Avoid persisting to localStorage in production

Ready to build?

Connect the Chipi MCP server and start building in minutes.

Get Started