Skip to main content
Call policy allows you to filter out transactions based on the call data and ether value. Within a policy, you can set up to 16 rules. Each rule consists of a condition, the calldata offset, and a reference value to compare. When checking a transaction, the policy checks it against every rule. For a policy to accept a transaction, every rule of that policy should pass.

Conditions

Available conditions are:
  • equal (x=Ax = A)
  • greater than (x>Ax > A)
  • less than (x<Ax < A)
  • greater than or equal (xAx \geq A)
  • less than or equal (xAx \leq A)
  • not equal (xAx \neq A)
  • in range (AxBA \leq x \leq B)

Calldata Offset

The number of bytes to offset from the start (excluding the function selector). The resulting value is a hex string of 32 bytes. In other words, if the offset is 10, the compared value will be formed from the calldata with the starting index of 4 + 10 = 14 and an end index of 4 + 10 + 32 = 46.

Reference Value

Value to compare the calldata against. The reference value is a hex string of 32 bytes. For convenience, you can pass the hex string of a smaller length or a bigint, and the SDK will convert it for you.

Usage

To enable a call policy:
const receiver = '0xd8da6bf26964af9d7eed9e03e53415d37aa96045'

const session: Session = {
  owners: {
    type: 'ecdsa',
    accounts: [sessionOwnerAccount],
  },
  actions: [
    {
      // ERC20 transfer action
      target: usdcAddress,
      selector: toFunctionSelector(
        getAbiItem({
          abi: erc20,
          name: 'transfer',
        }),
      ),
      policies: [
        {
          type: 'universal-action',
          rules: [
            {
              condition: 'equal',
              calldataOffset: 0n,
              referenceValue: receiver,
            },
          ],
        },
      ],
    },
  ],
}
Together with an ERC20 transfer action, this policy will only allow USDC transfers to a single receiver address.

Param Accumulator

You can limit the total accumulated value of a param across all session uses. This can be helpful if you want to e.g. limit the total value of tokens passed through the session.
const session: Session = {
  owners: {
    type: 'ecdsa',
    accounts: [sessionOwnerAccount],
  },
  actions: [
    {
      // ERC20 transfer action
      policies: [
        {
          type: 'universal-action',
          rules: [
            {
              condition: 'lessThan',
              calldataOffset: 20n,
              referenceValue: parseUnits('10', 6),
              usageLimit: parseUnits('50', 6),
            },
          ],
        },
      ],
    },
  ],
}
Together with an ERC20 transfer action, this will limit the token transferred to 10 USDC per session use, and 50 USDC for a total lifespan of the session.

Value Limit

To limit the maximum value to pass for a single session use:
const receiver = '0xd8da6bf26964af9d7eed9e03e53415d37aa96045'

const session: Session = {
  owners: {
    type: 'ecdsa',
    accounts: [sessionOwnerAccount],
  },
  actions: [
    {
      // ERC20 transfer action
      policies: [
        {
          type: 'universal-action',
          valueLimitPerUse: parseUnits('0.1', 18),
          rules: [
            {
              condition: 'equal',
              calldataOffset: 0n,
              referenceValue: receiver,
            },
          ],
        },
      ],
    },
  ],
}
This will limit the value per session use to 0.1 ETH.