> For the complete documentation index, see [llms.txt](/llms.txt).

# Use the function call scope

The function call scope defines the specific methods, contract addresses, and calldata that are allowed for the delegation. For example, Alice delegates to Bob the ability to call the `approve` function on the USDC contract, with the approval amount set to `0`.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

- [Install and set up the Smart Accounts Kit.](/smart-accounts-kit/1.0.0/get-started/install/)
- [Configure the Smart Accounts Kit.](/smart-accounts-kit/1.0.0/guides/configure-toolkit/)
- [Create a delegator account.](/smart-accounts-kit/1.0.0/guides/delegation/execute-on-smart-accounts-behalf/#3-create-a-delegator-account)
- [Create a delegate account.](/smart-accounts-kit/1.0.0/guides/delegation/execute-on-smart-accounts-behalf/#4-create-a-delegate-account)

## Function call scope[​](#function-call-scope "Direct link to Function call scope")

This scope requires `targets`, which specifies the permitted contract addresses, and `selectors`, which specifies the allowed methods.

Internally, this scope uses the [allowedTargets](/smart-accounts-kit/1.0.0/reference/delegation/caveats/#allowedtargets), [allowedMethods](/smart-accounts-kit/1.0.0/reference/delegation/caveats/#allowedmethods), and [valueLte](/smart-accounts-kit/1.0.0/reference/delegation/caveats/#valuelte) caveat enforcers, and optionally uses the [allowedCalldata](/smart-accounts-kit/1.0.0/reference/delegation/caveats/#allowedcalldata) or [exactCalldata](/smart-accounts-kit/1.0.0/reference/delegation/caveats/#exactcalldata) caveat enforcers when those parameters are specified. See the [function call scope reference](/smart-accounts-kit/1.0.0/reference/delegation/delegation-scopes/#function-call-scope) for more details.

The following example sets the delegation scope to allow the delegate to call the `approve` function on the USDC token contract:

```
import { createDelegation, ScopeType } from '@metamask/smart-accounts-kit'

// USDC address on Sepolia.
const USDC_ADDRESS = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'

const delegation = createDelegation({
  scope: {
    type: ScopeType.FunctionCall,
    targets: [USDC_ADDRESS],
    selectors: ['approve(address, uint256)'],
  },
  to: delegateAccount,
  from: delegatorAccount,
  environment: delegatorAccount.environment,
})

```

### Define allowed calldata[​](#define-allowed-calldata "Direct link to Define allowed calldata")

You can further restrict the scope by defining the `allowedCalldata`. For example, you can set `allowedCalldata` so the delegate is only permitted to call the `approve` function on the USDC token contract with an allowance value of `0`. This effectively limits the delegate to revoking ERC-20 approvals.

Usage

The `allowedCalldata` doesn't support multiple selectors. Each entry in the list represents a portion of calldata corresponding to the same function signature.

You can include or exclude specific parameters to precisely define what parts of the calldata are valid.

```
import { createDelegation, ScopeType } from '@metamask/smart-accounts-kit'
import { encodeAbiParameters, erc20Abi } from 'viem'

// USDC address on Sepolia.
const USDC_ADDRESS = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'

const delegation = createDelegation({
  scope: {
    type: ScopeType.FunctionCall,
    targets: [USDC_ADDRESS],
    selectors: ['approve(address, uint256)'],
    allowedCalldata: [
      {
        // Limits the allowance amount to be 0.
        value: encodeAbiParameters([{ name: 'amount', type: 'uint256' }], [0n]),
        // The first 4 bytes are for selector, and next 32 bytes
        // are for spender address.
        startIndex: 36,
      },
    ],
  },
  to: delegateAccount,
  from: delegatorAccount,
  environment: delegatorAccount.environment,
})

```

### Define exact calldata[​](#define-exact-calldata "Direct link to Define exact calldata")

You can define the `exactCalldata` instead of the `allowedCalldata`. For example, you can set `exactCalldata` so the delegate is permitted to call only the `approve` function on the USDC token contract, with a specific spender address and an allowance value of 0. This effectively limits the delegate to revoking ERC-20 approvals for a specific spender.

```
import { createDelegation, ScopeType } from '@metamask/smart-accounts-kit'
import { encodeFunctionData, erc20Abi } from 'viem'

// USDC address on Sepolia.
const USDC_ADDRESS = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'

const delegation = createDelegation({
  scope: {
    type: ScopeType.FunctionCall,
    targets: [USDC_ADDRESS],
    selectors: ['approve(address, uint256)'],
    exactCalldata: {
      calldata: encodeFunctionData({
        abi: erc20Abi,
        args: ['0x0227628f3F023bb0B980b67D528571c95c6DaC1c', 0n],
        functionName: 'approve',
      }),
    },
  },
  to: delegateAccount,
  from: delegatorAccount,
  environment: delegatorAccount.environment,
})

```

### Allow native token transfer[​](#allow-native-token-transfer "Direct link to Allow native token transfer")

You can set `valueLte` to allow native token transfer up to a specified amount per call. By default, this value is set to `0`. For example, Alice can allow Bob to take `0.00001` ETH as a fee each time he revokes a token approval on her behalf.

```
import { createDelegation, ScopeType } from '@metamask/smart-accounts-kit'
import { parseEther } from 'viem'

// USDC address on Sepolia.
const USDC_ADDRESS = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'

const delegation = createDelegation({
  scope: {
    type: ScopeType.FunctionCall,
    targets: [USDC_ADDRESS],
    selectors: ['approve(address, uint256)'],
    valueLte: { maxValue: parseEther('0.00001') },
  },
  to: delegateAccount,
  from: delegatorAccount,
  environment: delegatorAccount.environment,
})

```

## Next steps[​](#next-steps "Direct link to Next steps")

See [how to further constrain the authority of a delegation](/smart-accounts-kit/1.0.0/guides/delegation/use-delegation-scopes/constrain-scope/) using caveat enforcers.
