diff --git a/delegation-toolkit/guides/delegation/use-delegation-scopes/function-call.md b/delegation-toolkit/guides/delegation/use-delegation-scopes/function-call.md new file mode 100644 index 00000000000..e8279164d5e --- /dev/null +++ b/delegation-toolkit/guides/delegation/use-delegation-scopes/function-call.md @@ -0,0 +1,46 @@ +--- +description: Learn how to use the function call scope for a delegation. +--- + +# 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`. + +Internally, this scope uses the [`allowedTargets`](../../../reference/caveats.md#allowedtargets) and [`allowedMethods`](../../../reference/caveats.md#allowedmethods) caveat enforcers, and +optionally uses the [`allowedCalldata`](../../../reference/caveats.md#allowedcalldata) or [`exactCalldata`](../../../reference/caveats.md#exactcalldata) caveat enforcers when those parameters are specified. + +## Prerequisites + +- [Install and set up the Delegation Toolkit.](../../../get-started/install.md) +- [Configure the Delegation Toolkit.](../../configure.md) +- [Create a delegator account.](../execute-on-smart-accounts-behalf.md#3-create-a-delegator-account) +- [Create a delegate account.](../execute-on-smart-accounts-behalf.md#4-create-a-delegate-account) + +## Function call scope + +This scope requires `targets` and `selectors` as mandatory parameters for the configuration. +You can specify the allowed methods in `selectors` and the permitted contract addresses in `targets`. + +The following example sets the delegation scope to allow the delegate to call the `approve` function on the USDC token contract. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +// USDC address on Sepolia. +const USDC_ADDRESS = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238" + +const delegation = createDelegation({ + scope: { + type: "functionCall", + targets: [USDC_ADDRESS], + selectors: ["approve(address, uint256)"] + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Next steps + +See [how to further refine the authority of a delegation](refine-scope.md) using caveat enforcers. diff --git a/delegation-toolkit/guides/delegation/use-delegation-scopes/index.md b/delegation-toolkit/guides/delegation/use-delegation-scopes/index.md new file mode 100644 index 00000000000..14d34fabde7 --- /dev/null +++ b/delegation-toolkit/guides/delegation/use-delegation-scopes/index.md @@ -0,0 +1,16 @@ +--- +description: Learn how to use the delegation scopes. +--- + +# Use delegation scopes + +When [creating a delegation](../execute-on-smart-accounts-behalf.md), you can configure a scope to define the delegation's initial authority and help prevent delegation misuse. +You can further refine this initial authority by [adding caveats to a delegation](refine-scope.md). + +The Delegation Toolkit currently supports three categories of scopes: + +| Scope type | Description | +|------------|-------------| +| [Spending limit scopes](spending-limit.md) | Restricts the spending of native, ERC-20, and ERC-721 tokens based on defined conditions. | +| [Function call scope](function-call.md) | Restricts the delegation to specific contract methods, contract addresses, or calldata. | +| [Ownership transfer scope](owernship-transfer.md) | Restricts the delegation to only allow ownership transfers, specifically the `transferOwnership` function for a specified contract. | diff --git a/delegation-toolkit/guides/delegation/use-delegation-scopes/ownership-transfer.md b/delegation-toolkit/guides/delegation/use-delegation-scopes/ownership-transfer.md new file mode 100644 index 00000000000..215fd923dd0 --- /dev/null +++ b/delegation-toolkit/guides/delegation/use-delegation-scopes/ownership-transfer.md @@ -0,0 +1,40 @@ +--- +description: Learn how to use the ownership transfer scope for a delegation. +--- + +# Use the ownership transfer scope + +The ownership transfer scope restricts a delegation to ownership transfer calls only. +For example, Alice has deployed a smart contract, and she delegates to Bob the ability to transfer ownership of that contract. + +Internally, this scope uses the [`ownershipTransfer`](../../../reference/caveats.md#ownershiptransfer) caveat enforcer. + +## Prerequisites + +- [Install and set up the Delegation Toolkit.](../../../get-started/install.md) +- [Configure the Delegation Toolkit.](../../configure.md) +- [Create a delegator account.](../execute-on-smart-accounts-behalf.md#3-create-a-delegator-account) +- [Create a delegate account.](../execute-on-smart-accounts-behalf.md#4-create-a-delegate-account) + +## Ownership transfer scope + +This scope requires a `contractAddress`, which represents the address of the deployed contract. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const contractAddress = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238" + +const delegation = createDelegation({ + scope: { + type: "ownershipTransfer", + contractAddress, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Next steps + +See [how to further refine the authority of a delegation](refine-scope.md) using caveat enforcers. diff --git a/delegation-toolkit/guides/delegation/restrict-delegation.md b/delegation-toolkit/guides/delegation/use-delegation-scopes/refine-scope.md similarity index 93% rename from delegation-toolkit/guides/delegation/restrict-delegation.md rename to delegation-toolkit/guides/delegation/use-delegation-scopes/refine-scope.md index d78aa669c67..2541a0c78f2 100644 --- a/delegation-toolkit/guides/delegation/restrict-delegation.md +++ b/delegation-toolkit/guides/delegation/use-delegation-scopes/refine-scope.md @@ -1,15 +1,16 @@ --- description: Learn how to restrict a delegation using caveat enforcers, and the available caveat types. +sidebar_label: Refine a scope toc_max_heading_level: 3 --- import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -# Restrict a delegation +# Refine a delegation scope -Use [caveat enforcers](../../concepts/delegation/caveat-enforcers.md) to apply specific rules and restrictions -to a delegation, ensuring that delegated executions are only performed under predefined circumstances. +Apply [caveat enforcers](../../concepts/delegation/caveat-enforcers.md) to a delegation to refine the initial authority defined by its [delegation scope](index.md). +Caveat enforcers ensure delegated executions are only performed under specific, predefined circumstances. A delegation has a `caveats` property, which is an array of `Caveat` objects. Each caveat is specified as follows: diff --git a/delegation-toolkit/guides/delegation/use-delegation-scopes/spending-limit.md b/delegation-toolkit/guides/delegation/use-delegation-scopes/spending-limit.md new file mode 100644 index 00000000000..43cc68cf6bf --- /dev/null +++ b/delegation-toolkit/guides/delegation/use-delegation-scopes/spending-limit.md @@ -0,0 +1,199 @@ +--- +description: Learn how to use the spending limit scopes for a delegation. +--- + +# Use spending limit scopes + +Spending limit scopes define how much a delegate can spend in native, ERC-20, or ERC-721 tokens. +You can set transfer limits with or without time-based (periodic) or streaming conditions, depending on your use case. + +## Prerequisites + +- [Install and set up the Delegation Toolkit.](../../../get-started/install.md) +- [Configure the Delegation Toolkit.](../../configure.md) +- [Create a delegator account.](../execute-on-smart-accounts-behalf.md#3-create-a-delegator-account) +- [Create a delegate account.](../execute-on-smart-accounts-behalf.md#4-create-a-delegate-account) + +## ERC-20 periodic scope + +This scope ensures a per-period limit for ERC-20 token transfers. +You set the amount and the time window. +At the start of each new period, the allowance resets. +For example, Alice creates a delegation that lets Bob spend up to 10 USDC on her behalf each day. +Bob can transfer a total of 10 USDC per day; the limit resets at the beginning of the next day. + +When this scope is applied, the toolkit automatically disables native token transfers (sets the native token transfer limit to `0`). + +Internally, this scope uses the [`erc20PeriodTransfer`](../../../reference/caveats.md#erc20periodtransfer) and [`valueLte`](../../../reference/caveats.md#valuelte) caveat enforcers. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const delegation = createDelegation({ + scope: { + type: "erc20PeriodTransfer", + tokenAddress: "0xb4aE654Aca577781Ca1c5DE8FbE60c2F423f37da", + periodAmount: 1000000000000000000n, + periodDuration: 86400, + startDate: 1743763600, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## ERC-20 streaming scope + +This scopes 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. +For example, Alice creates a delegation that allows Bob to spend 0.1 USDC per second, starting with an initial amount of 10 USDC, up to a maximum of 100 USDC. + +When this scope is applied, the toolkit automatically disables native token transfers (sets the native token transfer limit to `0`). + +Internally, this scope uses the [`erc20Streaming`](../../../reference/caveats.md#erc20streaming) and [`valueLte`](../../../reference/caveats.md#valuelte) caveat enforcers. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const delegation = createDelegation({ + scope: { + type: "erc20Streaming", + tokenAddress: "0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92", + amountPerSecond: 100n, + initialAmount: 1000000n, + maxAmount: 10000000n, + startTime: 1703980800, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## ERC-20 transfer scope + +This 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. +For example, Alice creates a delegation that allows Bob to spend up to 10 USDC without any conditions. +Bob may use the 10 USDC in a single transaction or make multiple transactions, as long as the total does not exceed 10 USDC. + +When this scope is applied, the toolkit automatically disables native token transfers (sets the native token transfer limit to `0`). + +Internally, this scope uses the [`erc20TransferAmount`](../../../reference/caveats.md#erc20transferamount) and [`valueLte`](../../../reference/caveats.md#valuelte) caveat enforcers. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const delegation = createDelegation({ + scope: { + type: "erc20TransferAmount", + tokenAddress: "0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92", + maxAmount: 10000n, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## ERC-721 scope + +This scope limits the delegation to ERC-721 token transfers only. +For example, Alice creates a delegation that allows Bob to transfer an NFT she owns on her behalf. + +Internally, this scope uses the [`erc721Transfer`](../../../reference/caveats.md#erc721transfer) caveat enforcer. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const delegation = createDelegation({ + scope: { + type: "erc721Transfer", + tokenAddress: "0x3fF528De37cd95b67845C1c55303e7685c72F319", + tokenId: 1n, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Native token periodic scope + +This scope ensures a per-period limit for native token transfers. +You set the amount and the time window. +At the start of each new period, the allowance resets. +For example, Alice creates a delegation that lets Bob spend up to 0.01 ETH on her behalf each day. +Bob can transfer a total of 0.01 ETH per day; the limit resets at the beginning of the next day. + +When this scope is applied, the toolkit automatically disables ERC-20 and ERC-721 token transfers (sets the allowed calldata to `0x`). + +Internally, this scope uses the [`exactCalldata`](../../../reference/caveats.md#exactcalldata) and [`nativeTokenPeriodTransfer`](../../../reference/caveats.md#nativetokenperiodtransfer) caveat enforcers. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const delegation = createDelegation({ + scope: { + type: "nativeTokenPeriodTransfer", + periodAmount: 1000000000000000000n, + periodDuration: 86400, + startDate: 1743763600, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Native token streaming scope + +This scopes 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. +For example, Alice creates delegation that allows Bob to spend 0.001 ETH per second, starting with an initial amount of 0.01 ETH, up to a maximum of 0.1 ETH. + +When this scope is applied, the toolkit automatically disables ERC-20 and ERC-721 token transfers (sets the allowed calldata to `0x`). + +Internally, this scope uses the [`exactCalldata`](../../../reference/caveats.md#exactcalldata) and [`nativeTokenStreaming`](../../../reference/caveats.md#nativetokenstreaming) caveat enforcers. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const delegation = createDelegation({ + scope: { + type: "nativeTokenStreaming", + amountPerSecond: 100n, + initialAmount: 1000000n, + maxAmount: 10000000n, + startTime: 1703980800, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Native token transfer scope + +This 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. +For example, Alice creates a delegation that allows Bob to spend up to 0.1 ETH without any conditions. +Bob may use the 0.1 ETH in a single transaction or make multiple transactions, as long as the total does not exceed 0.1 ETH. + +When this scope is applied, the toolkit automatically disables ERC-20 and ERC-721 token transfers (sets the allowed calldata to `0x`). + +Internally, this scope uses the [`exactCalldata`](../../../reference/caveats.md#exactcalldata) and [`nativeTokenTransferAmount`](../../../reference/caveats.md#nativetokentransferamount) caveat enforcers. + +```typescript +import { createDelegation } from "@metamask/delegation-toolkit"; + +const delegation = createDelegation({ + scope: { + type: "nativeTokenTransferAmount", + maxAmount: 1000000n, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Next steps + +See [how to further refine the authority of a delegation](refine-scope.md) using caveat enforcers. \ No newline at end of file diff --git a/delegation-toolkit/reference/delegation-scopes.md b/delegation-toolkit/reference/delegation-scopes.md new file mode 100644 index 00000000000..c316b52b871 --- /dev/null +++ b/delegation-toolkit/reference/delegation-scopes.md @@ -0,0 +1,190 @@ +--- +description: Delegation scopes reference. +--- + +# Delegation scopes + +When [creating a delegation](../guides/delegation/execute-on-smart-accounts-behalf.md), you can configure the following scopes to define the delegation's initial authority. +Learn [how to use delegation scopes](../guides/delegation/use-delegation-scopes/index.md). + +## 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. + +#### Example + +```typescript +const delegation = createDelegation({ + scope: { + type: "erc20PeriodTransfer", + tokenAddress: "0xb4aE654Aca577781Ca1c5DE8FbE60c2F423f37da", + periodAmount: 1000000000000000000n, + periodDuration: 86400, + startDate: 1743763600, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +### 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. + +#### Example + +```typescript +const delegation = createDelegation({ + scope: { + type: "erc20Streaming", + tokenAddress: "0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92", + amountPerSecond: 100n, + initialAmount: 1000000n, + maxAmount: 10000000n, + startTime: 1703980800, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +### 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. + +#### Example + +```typescript +const delegation = createDelegation({ + scope: { + type: "erc20TransferAmount", + tokenAddress: "0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92", + maxAmount: 10000n, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +### ERC-721 scope + +Limits the delegation to ERC-721 token transfers only. + +#### Example + +```typescript +const delegation = createDelegation({ + scope: { + type: "erc721Transfer", + tokenAddress: "0x3fF528De37cd95b67845C1c55303e7685c72F319", + tokenId: 1n, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +### Native token periodic scope + +Ensures a per-period limit for native token transfers. +At the start of each new period, the allowance resets. + +#### Example + +```typescript +const delegation = createDelegation({ + scope: { + type: "nativeTokenPeriodTransfer", + periodAmount: 1000000000000000000n, + periodDuration: 86400, + startDate: 1743763600, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +### 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. + +#### Example + +```typescript +const delegation = createDelegation({ + scope: { + type: "nativeTokenStreaming", + amountPerSecond: 100n, + initialAmount: 1000000n, + maxAmount: 10000000n, + startTime: 1703980800, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +### 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. + +#### Example + +```typescript +const delegation = createDelegation({ + scope: { + type: "nativeTokenTransferAmount", + maxAmount: 1000000n, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Function call scope + +Defines the specific methods, contract addresses, and calldata that are allowed for the delegation. + +#### Example + +This example sets the delegation scope to allow the delegate to call the `approve` function on the USDC token contract. + +```typescript +const delegation = createDelegation({ + scope: { + type: "functionCall", + targets: ["0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"], // USDC address on Sepolia. + selectors: ["approve(address, uint256)"] + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` + +## Ownership transfer scope + +Restricts a delegation to ownership transfer calls only. + +#### Example + +```typescript +const contractAddress = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238" + +const delegation = createDelegation({ + scope: { + type: "ownershipTransfer", + contractAddress, + }, + to: delegateAccount, + from: delegatorAccount, +}); +``` diff --git a/gator-sidebar.js b/gator-sidebar.js index ae126472ee1..3b564fd1e83 100644 --- a/gator-sidebar.js +++ b/gator-sidebar.js @@ -70,7 +70,18 @@ const sidebar = { collapsed: false, items: [ 'guides/delegation/execute-on-smart-accounts-behalf', - 'guides/delegation/restrict-delegation', + { + type: 'category', + label: 'Use delegation scopes', + collapsed: false, + link: { type: "doc", id: "guides/delegation/use-delegation-scopes/index" }, + items: [ + 'guides/delegation/use-delegation-scopes/spending-limit', + 'guides/delegation/use-delegation-scopes/function-call', + 'guides/delegation/use-delegation-scopes/ownership-transfer', + 'guides/delegation/use-delegation-scopes/refine-scope', + ], + }, ], }, ], @@ -111,6 +122,7 @@ const sidebar = { label: 'Reference', collapsed: false, items: [ + 'reference/delegation-scopes', 'reference/caveats', { type: 'category',