Connect 4337
Cometh ConnectCometh MarketplaceCometh Checkout
  • 🚀Quick start
    • What is Connect 4337
    • Getting started
    • Supported Networks
  • 🛠️CORE FEATURES
    • Create a Wallet
    • Send transactions
    • Go Gasless
    • Sign/Verify a message
    • Retrieve a wallet address
    • Handle owners
    • Import a safe into connect
  • 🥷ADVANCED
    • Session Keys
      • Tutorial
      • Policies
        • Sudo policy
        • Action policy
    • Social recovery
    • Add a passkey signer on a different OS
    • Capabilities
      • sendCalls
      • getCallsStatus
      • getCapabilities
      • grantPermissions
    • Other signers (Auth Providers)
      • EOA wallets (Metamask, Phantom...)
      • Magic signer
      • Web3Auth signer
      • Turnkey signer
      • Privy signer
  • 🔌Integrations
    • React hooks
      • ConnectProvider
      • useAccount
      • useConnect
      • useDisconnect
      • useGetGasPrice
      • useSendTransaction
      • useSignMessage
      • useVerifyMessage
      • useWriteContract
      • Handle owners
        • useRemoveOwner
        • useValidateAddDevice
        • useCreateNewSigner
        • useAddOwner
        • useGetOwners/EnrichedOwners
      • Session Keys
        • useGrantPermission
        • useSendPermission
        • useSessionKeyClient
        • useSessionKeySigner
      • Recovery
        • useIsRecoveryActive
        • useSetUpRecovery
        • useGetRecoveryRequest
        • useCancelRecoveryRequest
    • Mobile SDKs
      • IOS
      • Android
      • React Native
    • Wagmi
  • SDK Core
    • Signers (Auth Providers)
      • EOA wallets (Metamask, Phantom...)
      • Magic signer
      • Web3Auth signer
      • Turnkey signer
      • Privy signer
    • Handle owners
    • Capabilities
      • sendCalls
      • getCallsStatus
      • getCapabilities
  • SDK Session Keys
    • Setup Smart Account Client
    • Manage session keys
    • Policies
      • Sudo policy
      • Action policy
  • 📦Bundler
    • Bundler API
      • eth_sendUserOperation
      • eth_estimateUserOperationGas
      • eth_getUserOperationByHash
      • eth_getUserOperationReceipt
      • eth_supportedEntryPoints
  • 💳Paymaster
    • Paymaster API
  • 📖RESOURCES
    • Migrate from the connect legacy SDK
    • Connect Legacy SDKs (Unity, JS)
    • FAQ
Powered by GitBook
On this page
  • 1 - Create a Session Key
  • 2 - Store the Session Key
  • 3 - Use the Session Key
  1. ADVANCED
  2. Session Keys

Tutorial

Example of a session key with an action policy.

1 - Create a Session Key

import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import {
    type ComethSmartAccountClient,
    type SafeSigner,
    erc7579Actions,
    smartSessionActions,
} from "@cometh/connect-sdk-4337";

export const COUNTER_CONTRACT_ADDRESS =
    "0x4FbF9EE4B2AF774D4617eAb027ac2901a41a7b5F";


const safe7559Account = smartAccountClient.extend(smartSessionActions())
            .extend(erc7579Actions());

const privateKey = generatePrivateKey();
const sessionOwner = privateKeyToAccount(privateKey);

const createSessionsResponse = await safe7559Account.grantPermission({
    sessionRequestedInfo: [
        {
            sessionPublicKey: sessionOwner.address,
            actionPoliciesInfo: [
                {
                    contractAddress: COUNTER_CONTRACT_ADDRESS,
                    functionSelector: toFunctionSelector(
                        "function count()"
                    ) as Hex,
                },
            ],
        },
    ],
});

await safe7559Account.waitForUserOperationReceipt({
    hash: createSessionsResponse.userOpHash,
});

2 - Store the Session Key

In our example, we will store the session key details in local storage. You are free to store it wherever you want.

import { SmartSessionMode } from "@cometh/connect-sdk-4337";

const sessionData = {
    granter: smartAccountClient?.account?.address as Address,
    privateKey: privateKey,
    sessionPublicKey: sessionOwner.address,
    description: `Session to increment a counter`,
    moduleData: {
        permissionIds: createSessionsResponse.permissionIds,
        action: createSessionsResponse.action,
        mode: SmartSessionMode.USE,
        sessions: createSessionsResponse.sessions,
    },
};

// This is for example purposes.
const sessionParams = stringify(sessionData);

localStorage.setItem(
    `session-key-${smartAccountClient?.account?.address}`,
    sessionParams
);

3 - Use the Session Key

import {
    createComethPaymasterClient,
    createSafeSmartAccount,
    createSmartAccountClient,
    smartSessionActions,
    toSmartSessionsSigner
} from "@cometh/connect-sdk-4337";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";

const apiKey = process.env.COMETH_API_KEY;
const bundlerUrl = process.env.4337_BUNDLER_URL;
const paymasterUrl = process.env.4337_PAYMASTER_URL
const publicClient = createPublicClient({
    chain,
    transport: http(),
});


const stringifiedSessionData = localStorage.getItem(
    `session-key-${WALLETADDRESS}`
);
const sessionData = parse(stringifiedSessionData);

const sessionKeySigner = await toSmartSessionsSigner(safe7559Account, 
{
    moduleData: sessionData.moduleData,
    signer: privateKeyToAccount(sessionData.privateKey),
})

const sessionKeyAccount = await createSafeSmartAccount({
    apiKey,
    chain,
    smartAccountAddress: smartAccountClient?.account?.address,
    smartSessionSigner: sessionKeySigner,
});

const paymasterClient = await createComethPaymasterClient({
    transport: http(paymasterUrl),
    chain,
});

const sessionKeyClient = createSmartAccountClient({
    account: sessionKeyAccount,
    chain,
    bundlerTransport: http(bundlerUrl),
    paymaster: paymasterClient,
    userOperation: {
        estimateFeesPerGas: async () => {
            return await paymasterClient.getUserOperationGasPrice();
        },
    },
}).extend(smartSessionActions());

const callData = encodeFunctionData({
    abi: countContractAbi,
    functionName: "count",
});

const hash = await sessionKeyClient.usePermission({
    actions: [
        {
            target: COUNTER_CONTRACT_ADDRESS,
            callData: callData,
            value: BigInt(0),
        },
    ],
});
PreviousSession KeysNextPolicies

Last updated 3 months ago

🥷