Skip to main content
Session keys only work with CHIPI wallets - not ARGENT wallets. Make sure your wallet was created with walletType: "CHIPI".

Overview

Session keys allow your application to execute transactions on behalf of a user without requiring their owner private key for every action. This enables gasless, frictionless UX for gaming, DeFi automation, social apps, and more.
MethodDescription
sessions.createSessionKey()Generate a session keypair locally
sessions.addSessionKeyToContract()Register session on-chain
sessions.revokeSessionKey()Revoke a session key
sessions.getSessionData()Query session status
executeTransactionWithSession()Execute tx using session

createSessionKey

Generate a session keypair locally. This is a synchronous operation that doesn’t make network calls.
const session = browserClient.sessions.createSessionKey({
  encryptKey: "user-secure-pin",
  durationSeconds: 3600, // 1 hour (default: 6 hours)
});

console.log(session);
// {
//   publicKey: "0x...",
//   encryptedPrivateKey: "...",
//   validUntil: 1702500000
// }

// Store in client-side storage (NOT your database!)
localStorage.setItem('chipiSession', JSON.stringify(session));

Parameters

ParameterTypeRequiredDescription
encryptKeystringYesPIN to encrypt the session private key
durationSecondsnumberNoSession duration in seconds (default: 21600 = 6 hours)

Return Value

{
  publicKey: string;           // Session public key (hex)
  encryptedPrivateKey: string; // AES encrypted with encryptKey
  validUntil: number;          // Unix timestamp (seconds)
}
Never store session keys in your backend database. Store only in client-side secure storage (localStorage, sessionStorage, or platform-specific secure storage).

addSessionKeyToContract

Register a session key on the CHIPI wallet smart contract. This requires the owner’s signature (one-time setup per session).
const bearerToken = await getBearerToken();

const txHash = await browserClient.sessions.addSessionKeyToContract({
  encryptKey: "user-secure-pin",
  wallet: {
    publicKey: wallet.publicKey,
    encryptedPrivateKey: wallet.encryptedPrivateKey,
    walletType: "CHIPI",
  },
  sessionConfig: {
    sessionPublicKey: session.publicKey,
    validUntil: session.validUntil,
    maxCalls: 100,           // Maximum transactions allowed
    allowedEntrypoints: [],  // Empty = all functions allowed
  },
}, bearerToken);

console.log("Session registered:", txHash);

Parameters

ParameterTypeRequiredDescription
encryptKeystringYesOwner’s PIN to sign the registration
walletWalletDataYesWallet object with publicKey, encryptedPrivateKey, walletType
sessionConfig.sessionPublicKeystringYesFrom createSessionKey().publicKey
sessionConfig.validUntilnumberYesUnix timestamp when session expires
sessionConfig.maxCallsnumberYesMaximum transactions allowed
sessionConfig.allowedEntrypointsstring[]YesWhitelisted function selectors (empty = all)

Restricting Permissions

For enhanced security, whitelist specific function selectors:
const txHash = await browserClient.sessions.addSessionKeyToContract({
  encryptKey: pin,
  wallet: walletData,
  sessionConfig: {
    sessionPublicKey: session.publicKey,
    validUntil: session.validUntil,
    maxCalls: 10,
    allowedEntrypoints: [
      "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", // transfer
      "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", // approve
    ],
  },
}, bearerToken);

revokeSessionKey

Revoke a session key from the smart contract. After revocation, the session can no longer execute transactions.
const bearerToken = await getBearerToken();

const txHash = await browserClient.sessions.revokeSessionKey({
  encryptKey: "user-secure-pin",
  wallet: {
    publicKey: wallet.publicKey,
    encryptedPrivateKey: wallet.encryptedPrivateKey,
    walletType: "CHIPI",
  },
  sessionPublicKey: session.publicKey,
}, bearerToken);

// Clear from local storage
localStorage.removeItem('chipiSession');

console.log("Session revoked:", txHash);

Parameters

ParameterTypeRequiredDescription
encryptKeystringYesOwner’s PIN to sign the revocation
walletWalletDataYesWallet object
sessionPublicKeystringYesPublic key of session to revoke
Always revoke sessions when a user logs out to prevent unauthorized access.

getSessionData

Query session status from the smart contract. This is a read-only operation that doesn’t require gas.
const sessionData = await browserClient.sessions.getSessionData({
  walletAddress: wallet.publicKey,
  sessionPublicKey: session.publicKey,
});

console.log(sessionData);
// {
//   isActive: true,
//   validUntil: 1702500000,
//   remainingCalls: 95,
//   allowedEntrypoints: []
// }

if (sessionData.isActive) {
  console.log(`Session has ${sessionData.remainingCalls} calls remaining`);
}

Parameters

ParameterTypeRequiredDescription
walletAddressstringYesWallet address to query
sessionPublicKeystringYesSession public key to query

Return Value

{
  isActive: boolean;           // Whether session is valid
  validUntil: number;          // Expiration timestamp
  remainingCalls: number;      // Transactions remaining
  allowedEntrypoints: string[]; // Whitelisted functions
}

executeTransactionWithSession

Execute a transaction using a session key instead of the owner private key. No wallet popup required!
const bearerToken = await getBearerToken();
const session = JSON.parse(localStorage.getItem('chipiSession')!);

const txHash = await browserClient.executeTransactionWithSession({
  params: {
    encryptKey: "user-secure-pin",
    wallet: {
      publicKey: wallet.publicKey,
      encryptedPrivateKey: wallet.encryptedPrivateKey,
      walletType: "CHIPI",
    },
    session,
    calls: [
      {
        contractAddress: "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8",
        entrypoint: "transfer",
        calldata: [recipientAddress, amount, "0x0"],
      },
    ],
  },
  bearerToken,
});

console.log("Transaction executed:", txHash);

Parameters

ParameterTypeRequiredDescription
params.encryptKeystringYesPIN to decrypt the session private key
params.walletWalletDataYesWallet the session acts on behalf of
params.sessionSessionKeyDataYesSession from createSessionKey()
params.callsCall[]YesArray of contract calls
bearerTokenstringYesAuthentication token

Call Structure

{
  contractAddress: string;  // Target contract address
  entrypoint: string;       // Function name
  calldata: string[];       // Function arguments
}

Multi-Call Example

Execute multiple operations in a single transaction:
const txHash = await browserClient.executeTransactionWithSession({
  params: {
    encryptKey: pin,
    wallet: walletData,
    session,
    calls: [
      // Approve spending
      {
        contractAddress: USDC_ADDRESS,
        entrypoint: "approve",
        calldata: [SWAP_CONTRACT, amount, "0x0"],
      },
      // Execute swap
      {
        contractAddress: SWAP_CONTRACT,
        entrypoint: "swap",
        calldata: [USDC_ADDRESS, ETH_ADDRESS, amount, minReceived],
      },
    ],
  },
  bearerToken,
});

Complete Example: Gaming Session

import { ChipiBrowserSDK } from "@chipi-stack/backend";

const browserClient = new ChipiBrowserSDK({
  apiPublicKey: "pk_prod_your_public_key",
});

const GAME_CONTRACT = "0x...";
const MAKE_MOVE_SELECTOR = "0x...";

// Start a gaming session
async function startGameSession(userPin: string, bearerToken: string) {
  // Get player's wallet
  const wallet = await browserClient.getWallet({ externalUserId: "user-123" }, bearerToken);
  
  // Create 24-hour gaming session
  const session = browserClient.sessions.createSessionKey({
    encryptKey: userPin,
    durationSeconds: 24 * 60 * 60,
  });
  
  // Register with game-only permissions
  await browserClient.sessions.addSessionKeyToContract({
    encryptKey: userPin,
    wallet: { ...wallet, walletType: "CHIPI" },
    sessionConfig: {
      sessionPublicKey: session.publicKey,
      validUntil: session.validUntil,
      maxCalls: 1000,
      allowedEntrypoints: [MAKE_MOVE_SELECTOR],
    },
  }, bearerToken);
  
  // Store session
  localStorage.setItem('gameSession', JSON.stringify(session));
  
  return session;
}

// Make a move instantly - no wallet popup!
async function makeMove(moveData: string, userPin: string, bearerToken: string) {
  const session = JSON.parse(localStorage.getItem('gameSession')!);
  const wallet = await browserClient.getWallet({ externalUserId: "user-123" }, bearerToken);
  
  return browserClient.executeTransactionWithSession({
    params: {
      encryptKey: userPin,
      wallet: { ...wallet, walletType: "CHIPI" },
      session,
      calls: [{
        contractAddress: GAME_CONTRACT,
        entrypoint: "make_move",
        calldata: [moveData],
      }],
    },
    bearerToken,
  });
}

// Secure logout
async function logout(userPin: string, bearerToken: string) {
  const sessionStr = localStorage.getItem('gameSession');
  if (sessionStr) {
    const session = JSON.parse(sessionStr);
    const wallet = await browserClient.getWallet({ externalUserId: "user-123" }, bearerToken);
    
    try {
      await browserClient.sessions.revokeSessionKey({
        encryptKey: userPin,
        wallet: { ...wallet, walletType: "CHIPI" },
        sessionPublicKey: session.publicKey,
      }, bearerToken);
    } catch (e) {
      console.warn("Failed to revoke session:", e);
    }
    
    localStorage.removeItem('gameSession');
  }
}

Error Handling

ErrorCauseSolution
Session keys require CHIPI wallet typeWallet is ARGENT typeCreate wallet with walletType: "CHIPI"
Invalid encryptKeyWrong PINVerify PIN matches wallet creation
Session has expiredvalidUntil passedCreate and register a new session
Max calls exceededremainingCalls is 0Create new session with higher maxCalls
Entrypoint not allowedFunction not whitelistedRegister session with correct allowedEntrypoints

Security Best Practices

  1. Short durations - Use 1-6 hours, not days
  2. Limit calls - Set realistic maxCalls based on expected usage
  3. Whitelist functions - Restrict allowedEntrypoints to only what your app needs
  4. Revoke on logout - Always clean up sessions when user signs out
  5. Client-side storage only - Never store session keys in your database