Session keys enable temporary, delegated transaction execution for CHIPI wallets. This page documents all available session methods.
sessions.createSessionKey()
Generate a session keypair locally. The SDK returns the data but does NOT store it.
Usage
const session = sdk.sessions.createSessionKey({
encryptKey: "user-secure-pin",
durationSeconds: 3600, // Optional, default: 21600 (6 hours)
});
Parameters
| Parameter | Type | Required | Description |
|---|
encryptKey | string | Yes | PIN to encrypt the session private key |
durationSeconds | number | No | Session duration in seconds. Default: 21600 (6 hours) |
Return Value
Returns a SessionKeyData object:
{
publicKey: string; // Stark public key (hex format)
encryptedPrivateKey: string; // AES encrypted private key
validUntil: number; // Unix timestamp (seconds)
}
Example
// Create a 1-hour gaming session
const session = sdk.sessions.createSessionKey({
encryptKey: userPin,
durationSeconds: 60 * 60, // 1 hour
});
// Store in client-side secure storage (NOT your database!)
localStorage.setItem('chipiSession', JSON.stringify(session));
console.log(`Session expires at: ${new Date(session.validUntil * 1000)}`);
Store session data only in client-side secure storage (localStorage, Secure Enclave, Keychain). Never in your backend database.
sessions.addSessionKeyToContract()
Register a session key on the CHIPI wallet smart contract. Requires owner signature.
Usage
const txHash = await sdk.sessions.addSessionKeyToContract({
encryptKey: "user-secure-pin",
wallet: {
publicKey: "0x...",
encryptedPrivateKey: "...",
walletType: "CHIPI",
},
sessionConfig: {
sessionPublicKey: session.publicKey,
validUntil: session.validUntil,
maxCalls: 100,
allowedEntrypoints: [],
},
}, bearerToken);
Parameters
| Parameter | Type | Required | Description |
|---|
encryptKey | string | Yes | PIN to decrypt owner’s private key |
wallet | WalletData | Yes | User’s wallet data with walletType: "CHIPI" |
sessionConfig.sessionPublicKey | string | Yes | Public key from createSessionKey() |
sessionConfig.validUntil | number | Yes | Unix timestamp when session expires |
sessionConfig.maxCalls | number | Yes | Maximum transactions allowed |
sessionConfig.allowedEntrypoints | string[] | Yes | Whitelisted selectors. Empty = all allowed |
bearerToken | string | Yes | Valid JWT from your auth provider |
Return Value
Returns a Promise<string> with the transaction hash.
Example
// Register session with restricted permissions
const txHash = await sdk.sessions.addSessionKeyToContract({
encryptKey: userPin,
wallet: {
publicKey: wallet.publicKey,
encryptedPrivateKey: wallet.encryptedPrivateKey,
walletType: "CHIPI",
},
sessionConfig: {
sessionPublicKey: session.publicKey,
validUntil: session.validUntil,
maxCalls: 50,
allowedEntrypoints: [
"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", // transfer
],
},
}, bearerToken);
console.log(`Session registered: https://starkscan.co/tx/${txHash}`);
This uses gasless transactions via the Chipi paymaster. Users don’t need STRK for gas.
executeTransactionWithSession()
Execute a transaction using a session key instead of the owner’s private key.
Usage
const txHash = await sdk.executeTransactionWithSession({
params: {
encryptKey: "user-secure-pin",
wallet: {
publicKey: "0x...",
encryptedPrivateKey: "...",
walletType: "CHIPI",
},
session: {
publicKey: "0x...",
encryptedPrivateKey: "...",
validUntil: 1702500000,
},
calls: [
{
contractAddress: "0x...",
entrypoint: "transfer",
calldata: ["0x...", "100", "0x0"],
},
],
},
bearerToken,
});
Parameters
| Parameter | Type | Required | Description |
|---|
params.encryptKey | string | Yes | PIN to decrypt session private key |
params.wallet | WalletData | Yes | User’s wallet data |
params.session | SessionKeyData | Yes | Session from createSessionKey() |
params.calls | Call[] | Yes | Array of contract calls to execute |
bearerToken | string | No | JWT token (uses SDK default if not provided) |
Return Value
Returns a Promise<string> with the transaction hash.
Example
// Execute transfer using session (no owner key needed!)
const txHash = await sdk.executeTransactionWithSession({
params: {
encryptKey: userPin,
wallet: { ...wallet, walletType: "CHIPI" },
session,
calls: [
{
contractAddress: USDC_CONTRACT,
entrypoint: "transfer",
calldata: [recipientAddress, amount, "0x0"],
},
],
},
bearerToken,
});
console.log(`Transfer executed: https://starkscan.co/tx/${txHash}`);
Signature Format: Session transactions use a 4-element signature [sessionPubKey, r, s, validUntil] instead of the owner’s 2-element [r, s]. The SDK handles this automatically.
sessions.revokeSessionKey()
Remove a session key’s authorization from the CHIPI wallet contract.
Usage
const txHash = await sdk.sessions.revokeSessionKey({
encryptKey: "user-secure-pin",
wallet: {
publicKey: "0x...",
encryptedPrivateKey: "...",
walletType: "CHIPI",
},
sessionPublicKey: session.publicKey,
}, bearerToken);
Parameters
| Parameter | Type | Required | Description |
|---|
encryptKey | string | Yes | PIN to decrypt owner’s private key |
wallet | WalletData | Yes | User’s wallet data with walletType: "CHIPI" |
sessionPublicKey | string | Yes | Public key of session to revoke |
bearerToken | string | Yes | Valid JWT from your auth provider |
Return Value
Returns a Promise<string> with the transaction hash.
Example
// Revoke session on logout
const handleLogout = async () => {
const sessionStr = localStorage.getItem('chipiSession');
if (sessionStr) {
const session = JSON.parse(sessionStr);
await sdk.sessions.revokeSessionKey({
encryptKey: userPin,
wallet: { ...wallet, walletType: "CHIPI" },
sessionPublicKey: session.publicKey,
}, bearerToken);
localStorage.removeItem('chipiSession');
}
await authProvider.signOut();
};
Always revoke sessions on logout to prevent unauthorized access.
sessions.getSessionData()
Query the on-chain status of a session key.
Usage
const sessionData = await sdk.sessions.getSessionData({
walletAddress: "0x...",
sessionPublicKey: "0x...",
});
Parameters
| Parameter | Type | Required | Description |
|---|
walletAddress | string | Yes | The CHIPI wallet address |
sessionPublicKey | string | Yes | Public key of the session to query |
Return Value
Returns a Promise<SessionDataResponse>:
{
isActive: boolean; // true if session is valid and not revoked
validUntil: number; // Unix timestamp of expiration
remainingCalls: number; // Transactions remaining before limit
allowedEntrypoints: string[]; // Whitelisted function selectors
}
Example
// Check session before executing
const sessionData = await sdk.sessions.getSessionData({
walletAddress: wallet.publicKey,
sessionPublicKey: session.publicKey,
});
if (!sessionData.isActive) {
console.log("Session expired or revoked - need to create new session");
return;
}
if (sessionData.remainingCalls < 5) {
console.log(`Warning: Only ${sessionData.remainingCalls} calls remaining`);
}
// Safe to proceed with transaction
await sdk.executeTransactionWithSession({ ... });
Use getSessionData() to check remaining calls before batch operations.
Error Handling
All session methods throw ChipiSessionError for session-specific failures:
import { ChipiSessionError } from "@chipi-stack/backend";
try {
await sdk.sessions.addSessionKeyToContract({ ... }, bearerToken);
} catch (error) {
if (error instanceof ChipiSessionError) {
switch (error.code) {
case "INVALID_WALLET_TYPE_FOR_SESSION":
console.error("Session keys only work with CHIPI wallets");
break;
case "SESSION_EXPIRED":
console.error("Session has expired");
break;
case "SESSION_DECRYPTION_FAILED":
console.error("Invalid PIN - could not decrypt session key");
break;
default:
console.error("Session error:", error.message);
}
}
throw error;
}
Error Codes
| Code | Description |
|---|
INVALID_WALLET_TYPE_FOR_SESSION | Wallet is not a CHIPI wallet |
SESSION_EXPIRED | Session validUntil has passed |
SESSION_NOT_REGISTERED | Session not found on contract |
SESSION_REVOKED | Session was explicitly revoked |
SESSION_MAX_CALLS_EXCEEDED | No remaining calls |
SESSION_ENTRYPOINT_NOT_ALLOWED | Called function not in whitelist |
SESSION_DECRYPTION_FAILED | Invalid PIN for decryption |
SESSION_CREATION_FAILED | Failed to generate keypair |