Skip to main content

Delegation scopes

When creating a delegation, you can configure the following scopes to define the delegation's initial authority. Learn how to use delegation scopes.

Spending limit scopes

ERC-20 periodic scope

Ensures a per-period limit for ERC-20 token transfers. At the start of each new period, the allowance resets.

Parameters

NameTypeRequiredDescription
tokenAddressAddressYesThe ERC-20 token contract address as a hex string.
periodAmountbigintYesThe maximum amount of tokens that can be transferred per period.
periodDurationnumberYesThe duration of each period in seconds.
startDatenumberYesThe timestamp when the first period begins in seconds.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "erc20PeriodTransfer",
tokenAddress: "0xb4aE654Aca577781Ca1c5DE8FbE60c2F423f37da",
periodAmount: 1000000000000000000n,
periodDuration: 86400,
startDate: 1743763600,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

ERC-20 streaming scope

Ensures a linear streaming transfer limit for ERC-20 tokens. Token transfers are blocked until the defined start timestamp. At the start, a specified initial amount is released, after which tokens accrue linearly at the configured rate, up to the maximum allowed amount.

Parameters

NameTypeRequiredDescription
tokenAddressAddressYesThe ERC-20 token contract address.
initialAmountbigintYesThe initial amount that can be transferred at start time.
maxAmountbigintYesThe maximum total amount that can be unlocked.
amountPerSecondbigintYesThe rate at which tokens accrue per second.
startTimenumberYesThe start timestamp in seconds.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "erc20Streaming",
tokenAddress: "0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92",
amountPerSecond: 100n,
initialAmount: 1000000n,
maxAmount: 10000000n,
startTime: 1703980800,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

ERC-20 transfer scope

Ensures that ERC-20 token transfers are limited to a predefined maximum amount. This scope is useful for setting simple, fixed transfer limits without any time-based or streaming conditions.

Parameters

NameTypeRequiredDescription
tokenAddressAddressYesThe ERC-20 token contract address.
maxAmountbigintYesThe maximum amount of tokens that can be transferred by delegate.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "erc20TransferAmount",
tokenAddress: "0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92",
maxAmount: 10000n,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

ERC-721 scope

Limits the delegation to ERC-721 token (NFT) transfers only.

Parameters

NameTypeRequiredDescription
tokenAddressAddressYesThe ERC-721 token contract address.
tokenIdbigintYesThe ID of the ERC-721 token that can be transferred by delegate.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "erc721Transfer",
tokenAddress: "0x3fF528De37cd95b67845C1c55303e7685c72F319",
tokenId: 1n,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

Native token periodic scope

Ensures a per-period limit for native token transfers. At the start of each new period, the allowance resets.

Parameters

NameTypeRequiredDescription
periodAmountbigintYesThe maximum amount of tokens that can be transferred per period.
periodDurationnumberYesThe duration of each period in seconds.
startDatenumberYesThe timestamp when the first period begins in seconds.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "nativeTokenPeriodTransfer",
periodAmount: 1000000000000000000n,
periodDuration: 86400,
startDate: 1743763600,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

Native token streaming scope

Ensures a linear streaming transfer limit for native tokens. Token transfers are blocked until the defined start timestamp. At the start, a specified initial amount is released, after which tokens accrue linearly at the configured rate, up to the maximum allowed amount.

Parameters

NameTypeRequiredDescription
initialAmountbigintYesThe initial amount that can be transferred at start time.
maxAmountbigintYesThe maximum total amount that can be unlocked.
amountPerSecondbigintYesThe rate at which tokens accrue per second.
startTimenumberYesThe start timestamp in seconds.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "nativeTokenStreaming",
amountPerSecond: 100n,
initialAmount: 1000000n,
maxAmount: 10000000n,
startTime: 1703980800,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

Native token transfer scope

Ensures that native token transfers are limited to a predefined maximum amount. This scope is useful for setting simple, fixed transfer limits without any time based or streaming conditions.

Parameters

NameTypeRequiredDescription
maxAmountbigintYesThe maximum amount of tokens that can be transferred by delegate.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "nativeTokenTransferAmount",
// 0.001 ETH in wei format.
maxAmount: 1000000000000000n,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

Function call scope

Defines the specific methods, contract addresses, and calldata that are allowed for the delegation.

Parameters

NameTypeRequiredDescription
targetsAddress[]YesThe list of addresses that the delegate is allowed to call.
selectorsMethodSelector[]YesThe list of method selectors that the delegate is allowed to call. The selector value can be 4-byte hex string, ABI function signature, or ABI function object.
allowedCalldataAllowedCalldataBuilderConfig[]NoThe list of calldata that the delegate is allowed to call.
exactCalldataExactCalldataBuilderConfigNoThe calldata that the delegate is allowed to call.

Example

This example sets the delegation scope to allow the delegate to call the approve function on the USDC token contract.

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const delegation = createDelegation({
scope: {
type: "functionCall",
targets: ["0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"], // USDC address on Sepolia.
selectors: ["approve(address, uint256)"]
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});

Ownership transfer scope

Restricts a delegation to ownership transfer calls only.

Parameters

NameTypeRequiredDescription
contractAddressAddressYesThe target contract address for which ownership transfers are allowed.

Example

import { createDelegation, getDelegatorEnvironment } from "@metamask/delegation-toolkit";
import { sepolia } from "viem/chains";

const contractAddress = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"

const delegation = createDelegation({
scope: {
type: "ownershipTransfer",
contractAddress,
},
// Address that is granting the delegation
from: "0x7E48cA6b7fe6F3d57fdd0448B03b839958416fC1",
// Address to which the delegation is being granted
to: "0x2B2dBd1D5fbeB77C4613B66e9F35dBfE12cB0488",
// Alternatively you can use environment property of MetaMask smart account.
environment: getDelegatorEnvironment(sepolia.id);
});