Session Keys
Enable high-frequency interactions without popups
Session Keys
Session keys are temporary keys that are granted specific permissions. They allow your app to sign transactions on behalf of the user without prompting them for confirmation every time.
This is critical for:
- High-frequency trading: Place and cancel orders instantly.
- Games: Move characters or perform actions without interrupting gameplay.
- Social apps: Like posts or follow users with a single tap.
Session Key Management
Session keys enable faster transactions without biometric confirmation
No active session keys!Create one to enable faster transactions!
"use client";import { Hooks } from "rise-wallet/wagmi";import { P256, PublicKey } from "ox";export function SessionKeysWidget() { const grantPermissions = Hooks.useGrantPermissions(); const createSession = async () => { // 1. Generate Local Key Pair const privateKey = P256.randomPrivateKey(); const publicKey = PublicKey.toHex( P256.getPublicKey({ privateKey }), { includePrefix: false } ); // 2. Define Permissions const permissions = { calls: [ { to: "0x...", // Token Contract signature: "0x...", // transfer(address,uint256) } ] }; // 3. Grant Permissions on Chain await grantPermissions.mutateAsync({ key: { publicKey, type: "p256" }, expiry: Math.floor(Date.now() / 1000) + 3600, permissions, }); // 4. Store Private Key Locally localStorage.setItem("session_key", privateKey); }; return ( <Button onClick={createSession}> Create Session Key </Button> );}Creating a Session Key
You use the useGrantPermissions hook from rise-wallet/wagmi to request a new session key. You must define exactly what this key can do (permissions) and how long it lasts (expiry).
import { Hooks } from "rise-wallet/wagmi";
import { P256, PublicKey } from "ox";
// ... inside component
const grantPermissions = Hooks.useGrantPermissions();
const createSession = async () => {
// 1. Generate a local key pair (P256)
const privateKey = P256.randomPrivateKey();
const publicKey = PublicKey.toHex(P256.getPublicKey({ privateKey }), {
includePrefix: false,
});
// 2. Define Permissions (e.g., allow calling 'mint' on a specific contract)
const permissions = {
calls: [
{
to: "0x...", // Contract Address
signature: "0x...", // Function Selector
}
]
};
// 3. Request the session key from the wallet
await grantPermissions.mutateAsync({
key: { publicKey, type: "p256" },
expiry: Math.floor(Date.now() / 1000) + 3600, // 1 hour
permissions,
});
// 4. Store the private key securely (e.g., localStorage) to sign future requests
localStorage.setItem("session_key", privateKey);
};Once created, you can use the stored private key to sign and send wallet_sendPreparedCalls requests directly to the RISE RPC, bypassing the wallet popup completely.