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

# Smart Sessions

> Delegate permissions to session signers

## Smart Sessions

Smart Sessions allow accounts to delegate specific permissions to other signers with fine-grained control over what actions they can perform.

Enabling and using a permission with Smart Sessions is a two-step process involving setup and actual usage:

### 1. Enable Permission

The initial setup phase involves several key operations to prepare your account for session-based permissions:

* **Deploy the SCA** (if it does not exist yet).
* **Fund the SCA** to ensure gas costs or funding for your DeFi needs.
* **Bridge Funds, Unwind Positions or etc** as part of initial setup by passing extra instructions via the `instructions` array.
* **Install the Smart Sessions Module** into the SCA, ensuring the account is capable of session management.
* **Enable one or more permissions**: Define specific actions and their allowed signers.

### 2. Use Permission

Once a permission is enabled, a valid session signer is now authorized to perform the allowed actions.

* The session signer can initiate actions *within the allowed scope* (such as contract calls, swaps, mints, etc.).
* Calls made by the session signer are validated against the permission rules applied in the previous step.

## Prepare and enable permissions

Deploy accounts, fund accounts, install Smart Sessions module, and enable permissions.

```typescript theme={null}
const quote = await meeClient.getSessionQuote({ mode: 'PREPARE', ...options });
```

### Parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `mode` | `"PREPARE"` | Yes | Prepare or use a permission. |
| `enableSession` | `EnableSession` | No | Options to enable a session. |
| `smartSessionValidatorAddress` | `Address` | No | Address of the Smart Session validator to use. |
| `instructions` | `Instruction[]` | No | Array of composable instructions to be executed. |
| `feeToken` | `FeeTokenInfo` | Yes\* | Token used for gas payment. |
| `sponsorship` | `boolean` | No | Enable or disable gas sponsorship. |
| `delegate` | `boolean` | No | Enable EIP-7702 delegate mode. |
| `authorization` | `Authorization` | No | EIP-7702 authorization configuration. |
| `lowerBoundTimestamp` | `number` | No | Earliest allowed execution timestamp. |
| `upperBoundTimestamp` | `number` | No | Latest allowed execution timestamp. |
| `cleanUps` | `CleanUp[]` | No | List of cleanup instructions. |
| `simulation` | `SimulationOptions` | No | Simulation config. |

### EnableSession

| Property | Type | Required | Description |
| - | - | - | - |
| `redeemer` | `Address` | Yes | Address of the session signer. |
| `actions` | `SessionAction[]` | Yes | Allowed actions within this session. |
| `batchActions` | `boolean` | No | Whether to allow batching of actions. |
| `maxPaymentAmount` | `bigint` | No | Maximum payment amount allowed for the session. |

<Info>
  **Payment policy and fee token:** When the session token (e.g. the token used in spending limits or transfer actions) is the same as `feeToken`, the SDK merges those policies with the payment policy—the effective spending limit is increased by `maxPaymentAmount` and no duplicate payment action is added.
</Info>

### SessionAction

| **Property** | **Type** | **Required** | **Description** |
| - | - | - | - |
| `actions` | `ActionData[]` | Yes | Specific action configurations (see **ActionData**). |
| `chainId` | `number` | Yes | Chain ID where the permission is valid. |

### ActionData

| Property | Type | Required | Description |
| - | - | - | - |
| `actionTarget` | `Address` | Yes | Target contract address for this action. |
| `actionTargetSelector` | `Hex` | Yes | Function selector (4-byte signature) for the contract method. |
| `actionPolicies` | `Policy[]` | No | List of policies defining rules and restrictions on this action. |

### Example

```typescript theme={null}
const quote = await meeClient.getSessionQuote({
  mode: "PREPARE",
  enableSession: {
    redeemer: sessionSigner.address,
    actions,
  },
  simulation: { simulate: true },
  feeToken: { address: USDC, chainId: 8453 },
  trigger: {
    tokenAddress: USDC,
    chainId: 8453,
    amount: parseUnits("2", 6),
  },
});

// Store the sessions details for later use.
let sessionDetails: SessionDetail[] = [];

if (quote) {
  const { hash } = await meeClient.executeSessionQuote(quote);

  await meeClient.waitForSupertransactionReceipt({ hash });

  sessionDetails = quote.sessionDetails;
}
```

***

## Use Permission

Execute instructions using granted permissions.

```typescript theme={null}
const quote = await meeClient.getSessionQuote({ mode: 'USE', ...options });
```

### Parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `mode` | `"USE"` | Yes | Prepare or use a permission. |
| `sessionDetails` | `SessionDetails` | Yes | Session information for enabled permissions |
| `instructions` | `Instruction[]` | No | Array of instructions to be executed. |
| `feeToken` | `FeeTokenInfo` | Yes\* | Token used for gas payment. |
| `sponsorship` | `boolean` | No | Enable or disable gas sponsorship. |
| `delegate` | `boolean` | No | Enable EIP-7702 delegate mode. |
| `authorization` | `Authorization` | No | EIP-7702 authorization configuration. |
| `lowerBoundTimestamp` | `number` | No | Earliest allowed execution timestamp. |
| `upperBoundTimestamp` | `number` | No | Latest allowed execution timestamp. |
| `simulation` | `SimulationOptions` | No | Simulation config. |

### Example

```typescript theme={null}
const quote = await meeClient.getSessionQuote({
  mode: "USE",
  sessionDetails,
  simulation: { simulate: true },
  feeToken: { address: USDC, chainId: 8453 },
  instructions: [
    {
      chainId: 8453,
      calls: [{ to: CounterContract, data: "0x..." }]
    }
  ]
});

const { hash } = await meeClient.executeSessionQuote(quote);

await meeClient.waitForSupertransactionReceipt({ hash });
```

***

## Policies

### Sudo Policy

Grants unlimited permissions for specified functions.

```typescript theme={null}
const sudoPolicy = mcNexus.buildActionPolicy({ type: "sudo" })
```

<Warning>
  Use with caution, provides highest level of access.
</Warning>

***

### Universal Policy

Fine-grained parameter-level control.

```typescript theme={null}
const universalPolicy = mcNexus.buildActionPolicy({
  type: "universal",
  rules: [
    {
      condition: "equal",
      calldataOffset: calldataArgument(2),
      comparisonValue: parseUnits("10", 6),
      isLimited: false,
      usage: { limit: 0n, used: 0n }
    }
  ],
  // Configure spending limit for native token
  valueLimitPerUse: 1n
});
```

Use **`calldataArgument(n)`** to specify the calldata offset for the n-th (1-based) function argument—e.g. `calldataArgument(2)` is the second parameter. Import from `@biconomy/abstractjs`.

***

### Timeframe policy

Add fine-grained expirations to the session actions.

```typescript theme={null}
const now = Math.floor(Date.now() / 1000)
const validAfter = now
const validUntil = now + 3600

const timeframePolicy = mcNexus.buildActionPolicy({
  type: "timeframe",
  validAfter, // unix-timestamp when policy becomes active
  validUntil  // unix-timestamp when policy expires
});
```

***

### Spending limit policy

Add spending limits for the token spendings.

```typescript theme={null}
const spendingLimitsPolicy = mcNexus.buildActionPolicy({
  type: "spendingLimits",
  tokenLimits: [{ token: USDC, limit: parseUnits("10", 6) }]
});
```

***

### Usage limit policy

Add usage limits to control the session usage count.

```typescript theme={null}
const usagePolicy = mcNexus.buildActionPolicy({
  type: "usageLimit",
  limit: 5n
});
```

***

## Actions

### Frequently Used Actions

Build approve, transfer, and transferFrom actions for your session

```typescript theme={null}
const actions = mcNexus.buildSessionAction({
  type: "approve" | "transferFrom" | "transfer",
  data: {
    chainIds: [8453, 10],
    contractAddress: USDC,
    recipientAddress: "0x..." // Optional
    amountLimitPerAction: parseUnits("10", 6), // Optional
    maxAmountLimit: parseUnits("10", 6), // Optional
    usageLimit: 10n, // Optional
    validAfter: Math.floor(Date.now() / 1000), // Optional
    validUntil: Math.floor(Date.now() / 1000) + 60 * 60 * 24 // Optional
    // or
    // policies: [] // Define policies on your own. Defaults to sudo policy
  },
});
```

<Info>
  By default, sudo policy will be configured. Configure policies on your own by defining policies
</Info>

***

### Custom Actions

Build custom actions for your session

```typescript theme={null}
const functionSignature = toFunctionSelector(
  getAbiItem({ abi: CounterAbi, name: "incrementCount" })
);

const customActions = mcNexus.buildSessionAction({
  type: "custom",
  data: {
    chainIds: [8453, 10],
    contractAddress: CounterContract,
    functionSignature,
    policies: [{ type: "sudo" }] // Optional
  }
});
```

***

### Custom action batching

By default, all actions are submitted as a single atomic batch when enabling session permissions.
If you encounter issues with block gas limits on certain chains, you can break the actions into multiple smaller batches.

```typescript theme={null}
const actionOne = mcNexus.buildSessionAction({...});
const actionTwo = mcNexus.buildSessionAction({...});

const batchedActions = mcNexus.buildSessionAction({
  type: "batch",
  data: { actions: [...actionOne, ...actionTwo] }
});

const actionThree = mcNexus.buildSessionAction({...});

// Actions can be partially batched
const actions = [...batchedActions, ...actionThree];
```

<Info>
  To enable custom batching, make sure to configure `batchActions: false` in enableSession while preparing the permissions.
</Info>

***

## Check Permission Status

### meeSessionActions

Extend the MEE client with session-related methods.

```typescript theme={null}
import { meeSessionActions } from "@biconomy/abstractjs";

const sessionClient = meeClient.extend(meeSessionActions);
```

The following methods will be extended

* `isPermissionEnabled`
* `checkEnabledPermissions`

***

### isPermissionEnabled

```typescript theme={null}
const isEnabled = await sessionClient.isPermissionEnabled({
  permissionId: permission.permissionId,
  chainId: 8453
});
```

### checkEnabledPermissions

```typescript theme={null}
const enabledMap = await sessionClient.checkEnabledPermissions(sessionDetails);
// Returns: { [permissionId]: { [chainId]: boolean } }
```

***

## Complete Flow

```typescript theme={null}
// 1. User account setup
const userSigner = privateKeyToAccount("0x...");
const mcNexus = await toMultichainNexusAccount(options):
const meeClient = await createMeeClient(options);

// 2. Session signer setup
const sessionSigner = privateKeyToAccount("0x...");
const sessionMcNexus = await toMultichainNexusAccount({
  chainConfigurations: [
    {
      // ... other config
      // User McNexus address needs to be overriden here
      accountAddress: mcNexus.addressOn(chainId, true),
    },
    {
      // ... other config
      // User McNexus address needs to be overriden here
      accountAddress: mcNexus.addressOn(chainId, true),
    },
  ],
  signer: sessionSigner,
});
const sessionMeeClient = await createMeeClient(options);

// 3. Build actions for permissions
const functionSignature = toFunctionSelector(
  getAbiItem({ abi: CounterAbi, name: "incrementCount" })
);

const actions = mcNexus.buildSessionAction({
  type: "custom",
  data: {
    chainIds: [8453, 10],
    contractAddress: CounterContract,
    functionSignature
  }
});

// 4. Prepare and enable sessions
const quote = await meeClient.getSessionQuote({
  mode: "PREPARE",
  enableSession: {
    redeemer: sessionSigner.address,
    actions,
  },
  simulation: { simulate: true },
  feeToken: { address: USDC, chainId: 8453 },
  trigger: {
    tokenAddress: USDC,
    chainId: 8453,
    amount: parseUnits("2", 6),
  },
});

// Store the sessions details for later use.
let sessionDetails: SessionDetail[] = [];

if (quote) {
  const { hash } = await meeClient.executeSessionQuote(quote);

  await meeClient.waitForSupertransactionReceipt({ hash });

  if (quote.sessionDetails) sessionDetails = quote.sessionDetails;
}

// 5. Execute transaction on behalf of user via session signer
const quote = await sessionMeeClient.getSessionQuote({
  mode: "USE",
  sessionDetails,
  simulation: { simulate: true },
  feeToken: { address: USDC, chainId: 8453 },
  instructions: [
    {
      chainId: 8453,
      calls: [{ to: CounterContract, data: "0x..." }]
    }
  ]
});

const { hash } = await sessionMeeClient.executeSessionQuote(quote);

await sessionMeeClient.waitForSupertransactionReceipt({ hash });
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.