> 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](/smart-accounts-kit/development/reference/glossary#delegation)**Delegation** The ability for a MetaMask smart account to authorize another account to perform specific executions on its behalf.. 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/development/get-started/install/)
- [Configure the Smart Accounts Kit.](/smart-accounts-kit/development/guides/configure-toolkit/)
- [Create a delegator account.](/smart-accounts-kit/development/guides/delegation/execute-on-smart-accounts-behalf/#3-create-a-delegator-account)
- [Create a delegate account.](/smart-accounts-kit/development/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/development/reference/delegation/caveats/#allowedtargets), [allowedMethods](/smart-accounts-kit/development/reference/delegation/caveats/#allowedmethods), and [valueLte](/smart-accounts-kit/development/reference/delegation/caveats/#valuelte) [caveat enforcers](/smart-accounts-kit/development/reference/glossary#caveat-enforcer)**Caveat enforcer** A smart contract that enforces delegation rules by validating caveat conditions during redemption hooks., and optionally uses the [allowedCalldata](/smart-accounts-kit/development/reference/delegation/caveats/#allowedcalldata) or [exactCalldata](/smart-accounts-kit/development/reference/delegation/caveats/#exactcalldata) caveat enforcers when those parameters are specified. See the [function call scope reference](/smart-accounts-kit/development/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](/smart-accounts-kit/development/reference/glossary#delegate-account)**Delegate account** The account that receives delegated authority and can redeem a delegation under its constraints. 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](/smart-accounts-kit/development/reference/glossary#delegate-account)**Delegate account** The account that receives delegated authority and can redeem a delegation under its constraints. 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/development/guides/delegation/use-delegation-scopes/constrain-scope/) using caveat enforcers.
