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

# Call

The call policy filters transactions by calldata and ETH value. In v2 sessions, you express it as ABI-driven *parameter rules* on a permission's function — the SDK reads the function selector and parameter offsets from the ABI for you.

## Conditions

Available conditions:

* equal ($x = A$)
* greater than ($x > A$)
* less than ($x < A$)
* greater than or equal ($x \geq A$)
* less than or equal ($x \leq A$)
* not equal ($x \neq A$)

A param rule takes one of three shapes:

* `{ condition, value, usageLimit? }` — a single comparison, using one of the conditions above.
* `{ min, max, usageLimit? }` — inclusive bounds, compiling to two comparisons the param must pass together.
* `{ anyOf: [...] }` — an allowlist of accepted values. See the [migration guide](/wallets/custom-signer/integration/migration-guide) for the rules it expands to.

## Usage

To restrict an ERC20 transfer to a single recipient:

Examples on this page use `@rhinestone/sdk`, where `rhinestone` is the `RhinestoneSDK` instance from [Create a session with a custom setup](/wallets/session-keys/custom-setup/create-a-session).

```ts {18-20} theme={null}
import { erc20Abi, parseUnits } from "viem";
import { base } from "viem/chains";

const receiver = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045";

const session = await rhinestone.createSession({
  chain: base,
  owners: {
    type: "ecdsa",
    accounts: [sessionOwnerAccount],
  },
  permissions: [
    {
      abi: erc20Abi,
      address: usdcAddress,
      functions: {
        transfer: {
          params: {
            recipient: { condition: "equal", value: receiver },
          },
        },
      },
    },
  ],
});
```

Reference parameters by name — the SDK looks them up in the ABI. Only static types are supported (`address`, `bool`, `uint*`, `int*`, `bytes1`–`bytes32`).

To bound a param on both sides, give `min` and `max` instead of a condition:

```ts {15-16} theme={null}
const session = await rhinestone.createSession({
  chain: base,
  owners: {
    type: "ecdsa",
    accounts: [sessionOwnerAccount],
  },
  permissions: [
    {
      abi: erc20Abi,
      address: usdcAddress,
      functions: {
        transfer: {
          params: {
            amount: {
              min: parseUnits("1", 6),
              max: parseUnits("10", 6),
            },
          },
        },
      },
    },
  ],
});
```

This allows transfers between 1 and 10 USDC inclusive.

### Param accumulator

Cap the total accumulated value of a param across all session uses with `usageLimit`. Useful for capping cumulative spend across calls.

```ts {13-19} theme={null}
const session = await rhinestone.createSession({
  chain: base,
  owners: {
    type: "ecdsa",
    accounts: [sessionOwnerAccount],
  },
  permissions: [
    {
      abi: erc20Abi,
      address: usdcAddress,
      functions: {
        transfer: {
          params: {
            amount: {
              condition: "lessThan",
              value: parseUnits("10", 6),
              usageLimit: parseUnits("50", 6),
            },
          },
        },
      },
    },
  ],
});
```

This caps each transfer at 10 USDC and the total across the session lifetime at 50 USDC.

### Value limit

To cap the ETH value sent on a single call, use `valueLimitPerUse` at the function level:

```ts {13} theme={null}
const session = await rhinestone.createSession({
  chain: base,
  owners: {
    type: "ecdsa",
    accounts: [sessionOwnerAccount],
  },
  permissions: [
    {
      abi: vaultAbi,
      address: vaultAddress,
      functions: {
        depositEth: {
          valueLimitPerUse: parseUnits("0.1", 18),
        },
      },
    },
  ],
});
```

This limits the value per call to 0.1 ETH.
