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

# Multi-chain session

> Reuse the session signature across multiple chains

## Overview

Multi-chain session keys allow you to create and manage session keys that work across multiple blockchains with a single signature.

* **Sign once, deploy everywhere**: Create multiple sessions for different chains and sign them all at once
* **Flexible installation**: Install sessions in any order across different chains as needed
* **Reduce user friction**: Users only need to sign once instead of multiple times for each chain
* **Cross-chain automation**: Enable seamless automation across multiple chains with the same session key

The key innovation is the "enable mode", where you prepare all your sessions upfront, get a single signature from the user, and enable specific sessions on specific chains as needed.

<Info>
  While this guide focuses on multi-chain usage, you can also use this pattern on a single chain to pre-sign multiple different sessions and enable them over time as your application needs to evolve.
</Info>

<Steps>
  <Step title="Create the Sessions">
    First, define your sessions for different chains. Each session can have different owners, policies, and actions depending on your use case:

    ```ts theme={null}
    import { baseSepolia, optimismSepolia } from 'viem/chains'
    import { Session } from '@rhinestone/sdk'

    const sessions: Session[] = [
      {
        chain: baseSepolia,
        owners: {
          type: 'ecdsa',
          accounts: [sessionOwnerAccountA],
        },
        // Add specific policies and actions as needed
      },
      {
        chain: baseSepolia,
        owners: {
          type: 'ecdsa',
          accounts: [sessionOwnerAccountB],
        },
      },
      {
        chain: optimismSepolia,
        owners: {
          type: 'ecdsa',
          accounts: [sessionOwnerAccountB],
        },
      },
    ]
    ```
  </Step>

  <Step title="Enable the Session">
    To enable a session, you need to get the session details and enable data. This step prepares the session for installation on the target chain:

    ```ts theme={null}
    const sessionDetails =
      await rhinestoneAccount.experimental_getSessionDetails(sessions)
    const enableSignature =
      await rhinestoneAccount.experimental_signEnableSession(sessionDetails)
    const sessionIndex = 0 // Which session to enable
    ```

    The method returns the data needed to install the session on-chain, including the signature required to enable sessions.

    The account owner will be prompted to sign the session installation request.

    ### Reusing the Signature

    One of the most powerful features is the ability to reuse an existing signature across multiple session installations. Once you have the signature to enable a session, you can use it for future installations. For this, store the `sessionDetails` and `enableSignature` for later use.

    This pattern allows you to:

    * Pre-sign all your sessions during user onboarding
    * Enable specific sessions on-demand without additional signatures
    * Batch multiple session installations with the same signature
  </Step>

  <Step title="Use the Sessions">
    Once your sessions are enabled, you can use them to sign transactions on any supported chain:

    ```ts theme={null}
    const data = await rhinestoneAccount.prepareTransaction({
      chain,
      calls: [
        {
          to: targetAddress,
          data: transactionData,
        },
      ],
      signers: {
        type: 'experimental_session',
        session: sessions[sessionIndex],
        enableData: {
          userSignature: enableSignature,
          hashesAndChainIds: sessionDetails.hashesAndChainIds,
          sessionToEnableIndex: sessionIndex,
        },
      },
    })

    // Sign with the session key
    const signedData = await rhinestoneAccount.signTransaction(data)

    await rhinestoneAccount.submitTransaction(signedData)
    ```
  </Step>
</Steps>

## Complete Example

Here's a complete working example that demonstrates the full multi-chain session workflow:

```ts theme={null}
import {
  RhinestoneSDK,
  type Session
} from '@rhinestone/sdk'
import { zeroAddress } from 'viem'
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
import { baseSepolia, optimismSepolia } from 'viem/chains'

const ownerAccount = privateKeyToAccount('0x…')
const sessionOwnerAccount = privateKeyToAccount(generatePrivateKey())

const rhinestone = new RhinestoneSDK({
  apiKey: rhinestoneApiKey,
})
const rhinestoneAccount = await rhinestone.createAccount({
  owners: {
    type: 'ecdsa',
    accounts: [ownerAccount],
  },
})

// Define the sessions, one per chain
const sessions: Session[] = [
  {
    chain: baseSepolia,
    owners: {
      type: 'ecdsa',
      accounts: [sessionOwnerAccount],
    },
  },
  {
    chain: optimismSepolia,
    owners: {
      type: 'ecdsa',
      accounts: [sessionOwnerAccount],
    },
  },
]

// Get the session details and sign once
const sessionDetails =
  await rhinestoneAccount.experimental_getSessionDetails(sessions)
const enableSignature =
  await rhinestoneAccount.experimental_signEnableSession(sessionDetails)

// Build the per-chain sessions map with enable data
// The SDK resolves the right session and enable data automatically per chain
const signers = {
  type: 'experimental_session' as const,
  sessions: {
    [baseSepolia.id]: {
      session: sessions[0],
      enableData: {
        userSignature: enableSignature,
        hashesAndChainIds: sessionDetails.hashesAndChainIds,
        sessionToEnableIndex: 0,
      },
    },
    [optimismSepolia.id]: {
      session: sessions[1],
      enableData: {
        userSignature: enableSignature,
        hashesAndChainIds: sessionDetails.hashesAndChainIds,
        sessionToEnableIndex: 1,
      },
    },
  },
}

// Submit on Base
const dataBase = await rhinestoneAccount.prepareTransaction({
  chain: baseSepolia,
  calls: [{ to: zeroAddress, data: '0xdeadbeef' }],
  tokenRequests: [],
  signers,
})
const signedDataBase = await rhinestoneAccount.signTransaction(dataBase)
await rhinestoneAccount.submitTransaction(signedDataBase)

// Submit on Optimism (reusing the same signature and signers map)
const dataOptimism = await rhinestoneAccount.prepareTransaction({
  chain: optimismSepolia,
  calls: [{ to: zeroAddress, data: '0xdeadbeef' }],
  tokenRequests: [],
  signers,
})
const signedDataOptimism = await rhinestoneAccount.signTransaction(dataOptimism)
await rhinestoneAccount.submitTransaction(signedDataOptimism)
```
