# Manage session keys

### 1 - Create a Session Key

{% hint style="info" %}
When using a **Permissionless account** configured like in section **Setup Smart Account Client**, you have to skip the **Safe 7579** module installation step.&#x20;

This is unnecessary because the **Permissionless flow automatically handles module installation** during Smart Account creation via the ERC-7579 Launchpad. Including this step may lead to redundant or conflicting behavior.
{% endhint %}

{% tabs %}
{% tab title="SDK Core" %}

```typescript
import type { Address, PublicClient } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import {
    erc7579Actions,
    smartSessionActions,
    type SafeSigner,
} from "@cometh/session-keys";
import { isSmartAccountDeployed } from "permissionless";

export const COUNTER_CONTRACT_ADDRESS =
    "0x4FbF9EE4B2AF774D4617eAb027ac2901a41a7b5F";


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

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

 if (!(await isSmartAccountDeployed(
     safe7559Account?.account?.client as PublicClient, 
     safe7559Account?.account?.address as Address,
 ))) {
     safe7559Account.addSafe7579Module()
 }
        
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,
});

```

{% endtab %}

{% tab title="Permissionless" %}

```typescript
import type { Address, PublicClient } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import {
    erc7579Actions,
    smartSessionActions,
    type SafeSigner,
} from "@cometh/session-keys";
import { isSmartAccountDeployed } from "permissionless";

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,
});

```

{% endtab %}
{% endtabs %}

### 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.

<pre class="language-typescript"><code class="lang-typescript">import { SmartSessionMode } from "@cometh/session-keys";
<strong>
</strong><strong>const sessionData = {
</strong>    granter: safe7559Account?.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-${safe7559Account?.account?.address}`,
    sessionParams
);
</code></pre>

### 3 - Use the Session Key

{% tabs %}
{% tab title="SDK Core" %}

```typescript
import {
    createComethPaymasterClient,
    createSmartAccountClient,
} from "@cometh/connect-core-sdk";
import {
    toSmartSessionsSigner
    smartSessionActions,
    toSmartSessionsAccount,
} from "@cometh/session-keys";
import { privateKeyToAccount } from "viem/accounts";

const bundlerUrl = process.env.4337_BUNDLER_URL;
const paymasterUrl = process.env.4337_PAYMASTER_URL

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 toSmartSessionsAccount(
    safe7559Account?.account, 
    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),
        },
    ],
});
```

{% endtab %}

{% tab title="Permissionless" %}

```typescript
import {
    toSmartSessionsSigner
    smartSessionActions,
    toSmartSessionsAccount,
} from "@cometh/session-keys";
import { privateKeyToAccount } from "viem/accounts";
import { entryPoint07Address } from "viem/account-abstraction";
import { createSmartAccountClient} from "permissionless";
import { createPaymasterClient } from "viem/account-abstraction";
import { createPimlicoClient } from "permissionless/clients/pimlico"
import { http } from "viem";

const bundlerUrl = process.env.4337_BUNDLER_URL;
const paymasterUrl = process.env.4337_PAYMASTER_URL

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 toSmartSessionsAccount(
    safe7559Account?.account, 
    sessionKeySigner
)

const paymasterClient = await createPaymasterClient({
    transport: http(paymasterUrl)
});

const pimlicoClient = createPimlicoClient({
    transport: http(paymasterUrl),
    entryPoint: {
        address: entryPoint07Address,
        version: "0.7",
    },
})

const sessionKeyClient = createSmartAccountClient({
    account: sessionKeyAccount,
    chain,
    bundlerTransport: http(bundlerUrl, {
        retryCount: 5,
        retryDelay: 1000,
        timeout: 20_000,
    }),
    paymaster: paymasterClient,
    userOperation: {
        estimateFeesPerGas: async () => {
            return (await pimlicoClient.getUserOperationGasPrice()).fast
        },
    },
}).extend(smartSessionActions());

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

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

{% endtab %}
{% endtabs %}
