> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rhinestone.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Rhinestone’s framework for creating and managing session keys. It is a powerful system for creating onchain permissions.

## Introduction

Session keys are cryptographically signed keys generated by a user’s master key (passkey, ECDSA, or multisig). Smart Sessions enables session keys to be created and used with all major smart account implementations (via ERC-7579) and is fully compatible with Rhinestone’s Warp transaction infrastructure.

Examples of the onchain permissions that can be tailored with Smart Sessions include:

* Interacting only with a specific DeFi protocol (Aave or Uniswap)
* Spending limits on ERC20s or ETH
* Timeframes for expiry after a pre-determined period
* Combining permissions (e.g., Uniswap-only, 1000 USDC limit, 3-day expiry)

Key example use cases include:

* **Skipping confirmations**: Store a session key locally for “one-click trading,” allowing seamless decentralized application (dapp) interactions without repeated signing prompts.
* **Automating transactions**: Users share a scoped key for server-side execution, enabling:
  * Subscription payments
  * Limit orders or stop orders
  * Auto-repaying loans to prevent liquidation
  * This granular control enhances security, streamlines dapp interactions, and makes Web3 more user-friendly.

## How it works

[Smart Sessions](https://github.com/erc7579/smartsessions) is built around three concepts: **owners** (who can sign), **permissions** (what they can do), and **policies** (under what conditions).

## Owners

Smart Sessions support a wide range of signing mechanisms out of the box:

* [Single ECDSA key](./signature-validators/ecdsa)
* [Multiple ECDSA keys](./signature-validators/multisig) (i.e. multisig)
* [Passkeys](./signature-validators/passkey)

You can also use custom validators to validate sessions, as long as they are [ERC-7780](https://eips.ethereum.org/EIPS/eip-7780) compatible.

## Permissions

Permissions define what calls a session is allowed to make. A permission is defined by an *ABI* and a target *address*, and lists the *functions* on that contract the session can call. The SDK derives selectors and parameter offsets from the ABI and checks parameter value types against ABI input types.

When defining multiple permissions within a session, a transaction that matches **any** specified permission is considered valid. If no permissions are specified, **any** transaction will pass.

<Info>When using smart contracts directly, you need to explicitly provide a list of valid permissions.</Info>

## Policies

Policies let you restrict the session to hit specific conditions. You can define policies at the *session* (affects the entire session) or *function* (affects a single function within a permission) level.

Supported policies include:

* [Sudo](./policies/sudo): allows any transaction
* [Call](./policies/call): allows transactions with the specified calldata
* [Spending limit](./policies/spending-limit): allows a limited value of ERC20 tokens to be transferred and approved
* [Timeframe](./policies/timeframe): allows transactions within the specified time frame
* [Usage limit](./policies/usage-limit): allows a limited number of transactions
* Value limit: allows a limited ETH value transferred

When defining multiple policies within a function, a transaction that passes **every** specified policy is considered valid. If no policies are specified, **any** transaction will pass (i.e., the sudo policy is applied).

<Info>Policies work like a logical AND. If a function has two policies, the transaction must pass both policies to be valid.</Info>

## Usage

<Warning>Smart session support is **experimental**. Expect breaking changes.</Warning>

### Installing the validation

You can install the validator during account deployment:

```ts {6-8} theme={null}
const rhinestoneAccount = await rhinestone.createAccount({
  owners: {
    type: 'ecdsa',
    accounts: [ownerAccount],
  },
  experimental_sessions: {
    enabled: true,
  },
})
```

You can also install it when the account is already deployed:

```ts theme={null}
import { experimental_enable } from '@rhinestone/sdk/actions/smart-sessions'

const transaction = await rhinestoneAccount.prepareTransaction({
  chain: base,
  calls: [experimental_enable()],
})
```

To uninstall the validator:

```ts theme={null}
import { experimental_disable } from '@rhinestone/sdk/actions/smart-sessions'

const transaction = await rhinestoneAccount.prepareTransaction({
  chain: base,
  calls: [experimental_disable()],
})
```

### Creating Sessions

To create a session, use `toSession`:

```ts theme={null}
import { toSession } from '@rhinestone/sdk/smart-sessions'

const session = toSession({
  chain: base,
  owners: {
    type: 'ecdsa',
    accounts: [sessionOwnerAccount],
  },
})
```

You can also limit the session to specific allowed permissions:

```ts {7-13} theme={null}
const session = toSession({
  chain: base,
  owners: {
    type: 'ecdsa',
    accounts: [sessionOwnerAccount],
  },
  permissions: [
    {
      abi: erc20Abi,
      address: usdcAddress,
      functions: { transfer: {} },
    },
  ],
})
```

Finally, you can constrain function parameters. The SDK derives the selector and parameter offsets from the ABI, so you reference parameters by name:

```ts {11-20} theme={null}
const session = toSession({
  chain: base,
  owners: {
    type: 'ecdsa',
    accounts: [sessionOwnerAccount],
  },
  permissions: [
    {
      abi: erc20Abi,
      address: usdcAddress,
      functions: {
        transfer: {
          params: {
            recipient: {
              condition: 'equal',
              value: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
            },
          },
        },
      },
    },
  ],
})
```

### Cross-chain permits

Use `crossChainPermits` to scope which routes, tokens, amounts, and recipients it may bridge:

```ts {7-12} theme={null}
const session = toSession({
  chain: base,
  owners: {
    type: 'ecdsa',
    accounts: [sessionOwnerAccount],
  },
  crossChainPermits: [
    {
      from: [{ chain: base, token: 'USDC' }],
      to: [{ chain: arbitrum, token: 'USDC' }],
    },
  ],
})
```

See [Cross-chain permits](./policies/cross-chain) for guardrails, recipient safety, and settlement-layer options.

### Installing sessions

To enable a session:

```ts theme={null}
import { experimental_enableSession } from '@rhinestone/sdk/actions/smart-sessions'

const sessions = [session]
const sessionDetails =
  await rhinestoneAccount.experimental_getSessionDetails(sessions)
const enableSignature =
  await rhinestoneAccount.experimental_signEnableSession(sessionDetails)
const sessionIndex = 0

const transaction = await rhinestoneAccount.prepareTransaction({
  chain,
  calls: [
    experimental_enableSession(
      session,
      enableSignature,
      sessionDetails.hashesAndChainIds,
      sessionIndex,
    ),
  ],
})
```

You can also enable session with a signature. See [Multi-Session Signature](./multi-session-signature) for more details.

### Checking session status

To check if a session is enabled:

```ts theme={null}
const isEnabled = await rhinestoneAccount.experimental_isSessionEnabled(session)
```

### Using sessions

To authorize a transaction with a session key you've enabled before:

```ts {13-16} theme={null}
const prepared = await rhinestoneAccount.prepareTransaction({
  chain,
  calls: [
    {
      to: usdcAddress,
      data: encodeFunctionData({
        abi: erc20Abi,
        functionName: 'transfer',
        args: ['0xd8da6bf26964af9d7eed9e03e53415d37aa96045', 1n],
      }),
    },
  ],
  signers: {
    type: 'experimental_session',
    session,
  },
})
const signed = await rhinestoneAccount.signTransaction(prepared)
const transactionResult = await rhinestoneAccount.submitTransaction(signed)
```

This will prompt the signature request from the session owner(s) and submit the transaction on their behalf.

<Note>You can also enable and use the smart session in one transaction using the ["enable mode"](./multi-session-signature).</Note>

### Disabling a session

To disable a single enabled session, use `experimental_disableSession`. This only removes a single session: to uninstall the validator entirely (and every session with it), use [`experimental_disable`](#installing-the-validation) instead.

```ts theme={null}
import { experimental_disableSession } from '@rhinestone/sdk/actions/smart-sessions'

const transaction = await rhinestoneAccount.prepareTransaction({
  chain,
  calls: [experimental_disableSession(session)],
})
```

## Security

Smart Sessions is a powerful tool that unlocks a bunch of new opportunities and use cases. To keep your users secure when using sessions, follow these guidelines:

* Store the session key securely. Depending on the use case, you can opt to store it in the browser or on your backend. Consider key management solutions like [KMS](https://aws.amazon.com/kms/) or [Lit Protocol](https://www.litprotocol.com).
* Stick to the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege): do not request more actions than you need.
* Guard your smart session with granular policies (e.g., restrict the amount of ETH that can be transacted through the session)
* If possible, timebox your session (e.g., make it valid for only 1 week)

<Warning>By default, the SDK creates a session that allows any transaction. Make sure you restrict it with relevant permissions and policies.</Warning>

[Reach out to us](http://t.me/kurt_larsen) if you need any help!
