Skip to content

Commit 6eb20f5

Browse files
alexandratranbgravenorstRobItudependabot[bot]
authored
Migrate gator docs (#2045)
* Migrate gator docs * fixes * swizzle desktop sidebar * update codeowners * Add initial dropdown component. Signed-off-by: bgravenorst <[email protected]> * Add front page. Signed-off-by: bgravenorst <[email protected]> * Fix category sections. Signed-off-by: bgravenorst <[email protected]> * Inital dropdown style changes. Signed-off-by: bgravenorst <[email protected]> * Update dropdown behaviour. Signed-off-by: bgravenorst <[email protected]> * Add link to Embedded wallets (#2069) * Add embedded wallets. Signed-off-by: bgravenorst <[email protected]> * Stylesheet updates. Signed-off-by: bgravenorst <[email protected]> * Apply feedback. Signed-off-by: bgravenorst <[email protected]> --------- Signed-off-by: bgravenorst <[email protected]> * Minor update. (#2070) Signed-off-by: bgravenorst <[email protected]> * Update react-native.md (#2068) * Update react-native.md Expo Demo repo had been deleted and was a broken link. * Update sdk/quickstart/react-native.md Co-authored-by: Alexandra Carrillo <[email protected]> * Update sdk/quickstart/react-native.md Co-authored-by: Alexandra Carrillo <[email protected]> * Update react-native.md --------- Co-authored-by: Alexandra Carrillo <[email protected]> * chore(deps): bump tar-fs from 1.16.4 to 1.16.5 in the npm_and_yarn group (#2072) Bumps the npm_and_yarn group with 1 update: [tar-fs](https://github.com/mafintosh/tar-fs). Updates `tar-fs` from 1.16.4 to 1.16.5 - [Commits](https://github.com/mafintosh/tar-fs/commits) --- updated-dependencies: - dependency-name: tar-fs dependency-version: 1.16.5 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alexandra Carrillo <[email protected]> * fixes * Add front page. Signed-off-by: bgravenorst <[email protected]> * Remove dup. Signed-off-by: bgravenorst <[email protected]> * add api reference docs and fix links * minor adjustments * change file names (delegation-toolkit) and fix links * fix lint error * fix version ordering and color mode --------- Signed-off-by: bgravenorst <[email protected]> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: bgravenorst <[email protected]> Co-authored-by: Byron Gravenorst <[email protected]> Co-authored-by: RobItu <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent 64779e7 commit 6eb20f5

File tree

186 files changed

+26199
-20
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

186 files changed

+26199
-20
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
# Snaps documentation
1818
/snaps/ @MetaMask/tech-writers @MetaMask/snaps
1919

20+
# Delegation Toolkit documentation
21+
/delegation-toolkit/ @MetaMask/tech-writers @MetaMask/delegation @MetaMask/delegation-devrel
22+
2023
# SDK documentation
2124
/sdk/ @MetaMask/tech-writers @MetaMask/sdk-devs @MetaMask/sdk-devrel
2225

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"label": "Concepts",
3+
"position": 3,
4+
"link": {
5+
"type": "generated-index",
6+
"slug": "/concepts",
7+
"title": "Delegation Toolkit concepts"
8+
}
9+
}
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
---
2+
description: Learn about caveat enforcers and how they restrict delegations.
3+
sidebar_position: 4
4+
---
5+
6+
# Caveat enforcers
7+
8+
The MetaMask Delegation Toolkit provides *caveat enforcers*, which are smart contracts that implement rules and restrictions (*caveats*) on delegations.
9+
They serve as the underlying mechanism that enables conditional execution within the [Delegation Framework](delegation.md#delegation-framework).
10+
11+
A caveat enforcer acts as a gate that validates whether a delegation can be used for a particular execution. When a delegate attempts to execute an action on behalf of a delegator, each caveat enforcer specified in the delegation evaluates whether the execution meets its defined criteria.
12+
13+
:::warning Important
14+
- Without caveat enforcers, a delegation has infinite and unbounded authority to make any execution the original account can make.
15+
We strongly recommend using caveat enforcers.
16+
- Caveat enforcers safeguard the execution process but do not guarantee a final state post-redemption.
17+
Always consider the full impact of combined caveat enforcers.
18+
:::
19+
20+
## Smart contract interface
21+
22+
Caveat enforcers are Solidity contracts that implement the [`ICaveatEnforcer`](https://github.com/MetaMask/delegation-framework/blob/main/src/interfaces/ICaveatEnforcer.sol) interface:
23+
24+
```solidity
25+
// SPDX-License-Identifier: MIT AND Apache-2.0
26+
pragma solidity 0.8.23;
27+
28+
import { ModeCode } from "../utils/Types.sol";
29+
30+
/**
31+
* This is an abstract contract that exposes pre and post Execution hooks during delegation redemption.
32+
*/
33+
interface ICaveatEnforcer {
34+
/**
35+
* Enforces conditions before any actions in a batch redemption process begin.
36+
*/
37+
function beforeAllHook(
38+
bytes calldata _terms, // The terms to enforce set by the delegator.
39+
bytes calldata _args, // An optional input parameter set by the redeemer at time of invocation.
40+
ModeCode _mode, // The mode of execution for the executionCalldata.
41+
bytes calldata _executionCalldata, // The data representing the execution.
42+
bytes32 _delegationHash, // The hash of the delegation.
43+
address _delegator, // The address of the delegator.
44+
address _redeemer // The address that is redeeming the delegation.
45+
)
46+
external;
47+
48+
/**
49+
* Enforces conditions before the execution tied to a specific delegation in the redemption process.
50+
*/
51+
function beforeHook(
52+
bytes calldata _terms,
53+
bytes calldata _args,
54+
ModeCode _mode,
55+
bytes calldata _executionCalldata,
56+
bytes32 _delegationHash,
57+
address _delegator,
58+
address _redeemer
59+
)
60+
external;
61+
62+
/**
63+
* Enforces conditions after the execution tied to a specific delegation in the redemption process.
64+
*/
65+
function afterHook(
66+
bytes calldata _terms,
67+
bytes calldata _args,
68+
ModeCode _mode,
69+
bytes calldata _executionCalldata,
70+
bytes32 _delegationHash,
71+
address _delegator,
72+
address _redeemer
73+
)
74+
external;
75+
76+
/**
77+
* Enforces conditions after all actions in a batch redemption process have been executed.
78+
*/
79+
function afterAllHook(
80+
bytes calldata _terms,
81+
bytes calldata _args,
82+
ModeCode _mode,
83+
bytes calldata _executionCalldata,
84+
bytes32 _delegationHash,
85+
address _delegator,
86+
address _redeemer
87+
)
88+
external;
89+
}
90+
```
91+
92+
The interface consists of four key hook functions that are called at different stages of the delegation redemption process:
93+
94+
1. **`beforeAllHook`**: Called before any actions in a batch redemption process begin. This can be used to verify conditions that must be true for the entire batch execution.
95+
96+
2. **`beforeHook`**: Called before the execution tied to a specific delegation. This allows for pre-execution validation of conditions specific to that delegation.
97+
98+
3. **`afterHook`**: Called after the execution tied to a specific delegation completes. This can verify post-execution state changes or effects specific to that delegation.
99+
100+
4. **`afterAllHook`**: Called after all actions in a batch redemption process have completed. This enables verification of final conditions after the entire batch has executed.
101+
102+
Each of these hooks receives comprehensive information about the execution context, including:
103+
- The caveat terms specified by the delegator.
104+
- Optional arguments provided by the redeemer.
105+
- The execution mode and calldata.
106+
- The delegation hash.
107+
- The delegator and redeemer addresses.
108+
109+
### Caveat enforcer rejection
110+
111+
The most important safety feature of these hooks is their ability to block executions:
112+
113+
- If any hook determines its conditions aren't met, it will **revert** (throw an exception).
114+
- When a reversion occurs, the entire delegation redemption process is canceled.
115+
- This prevents partial or invalid executions from occurring.
116+
- No state changes from the attempted execution will be committed to the blockchain.
117+
118+
This "all-or-nothing" approach ensures that delegations only execute exactly as intended by their caveats.
119+
120+
## Caveat builder
121+
122+
While caveat enforcers operate at the smart contract level, most developers interact with them through the [`CaveatBuilder`](../how-to/create-delegation/restrict-delegation.md) interface in the MetaMask Delegation Toolkit.
123+
124+
The `CaveatBuilder` provides a developer-friendly TypeScript API that:
125+
126+
- Abstracts away the complexity of correctly formatting and encoding caveat terms.
127+
- Provides type-checking and validation for caveat parameters.
128+
- Handles the creation of the `caveats` array needed when creating a delegation.
129+
130+
Each [caveat type](../reference/caveats.md) in the `CaveatBuilder`
131+
corresponds to a specific caveat enforcer contract. For example, when you use:
132+
133+
```typescript
134+
caveatBuilder.addCaveat("allowedTargets", ["0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92"]);
135+
```
136+
137+
The builder is creating a caveat that references the
138+
[`AllowedTargetsEnforcer`](../reference/caveats.md#allowedtargets) contract address and
139+
properly encodes the provided addresses as terms for that enforcer.
140+
141+
## Caveat enforcer best practices
142+
143+
When designing delegations with caveats, consider these best practices:
144+
145+
- **Combine caveat enforcers appropriately** - Use multiple caveat enforcers to create comprehensive restrictions.
146+
147+
- **Consider caveat enforcer order** - When using caveat enforcers that modify external contract states, the order matters.
148+
For example, using [`NativeTokenPaymentEnforcer`](../reference/caveats.md#nativetokenpayment) before
149+
[`NativeBalanceChangeEnforcer`](../reference/caveats.md#nativebalancechange) might cause validation failures.
150+
151+
- **Be careful with unbounded delegations** - Always include appropriate caveat enforcers to limit what a delegate can do.
152+
153+
## Available caveat enforcers
154+
155+
The Delegation Toolkit provides [many out-of-the-box caveat enforcers](../reference/caveats.md)
156+
for common restriction patterns, including:
157+
158+
- Limiting target addresses and methods.
159+
- Setting time or block number constraints.
160+
- Restricting token transfers and approvals.
161+
- Limiting execution frequency.
162+
163+
For more complex scenarios, you can also [create custom caveat enforcers](../how-to/create-delegation/create-custom-caveat-enforcer.md) by implementing the `ICaveatEnforcer` interface.
164+
165+
## Attenuating authority with redelegations
166+
167+
When [creating chains of delegations](../how-to/create-delegation/index.md#create-a-redelegation), it's important to understand how authority flows and can be restricted.
168+
169+
Caveats applied to a chain of delegations are *accumulative*—they stack on top of each other:
170+
171+
- Each delegation in the chain inherits all restrictions from its parent delegation.
172+
- New caveats can add further restrictions, but can't remove existing ones.
173+
174+
This means that a delegate can only redelegate with equal or lesser authority than they received.
175+
176+
### Example: Narrowing permissions
177+
178+
Imagine a simple financial delegation scenario:
179+
180+
1. **Alice delegates to Bob**, allowing him to withdraw up to 100 USDC on her behalf.
181+
2. **Bob re-delegates to Carol**, but limits the permission to:
182+
- Only 50 USDC (reducing the amount).
183+
- Only before the end of the week (adding a time constraint).
184+
185+
Carol now has a more restricted version of Alice's original delegation. Bob couldn't give Carol more authority than he had (such as allowing her to withdraw 200 USDC), but he could narrow the permission.
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
description: Learn about delegation, the delegation lifecycle, and the Delegation Framework.
3+
sidebar_position: 2
4+
---
5+
6+
# Delegation
7+
8+
*Delegation* is the ability for a [smart account](smart-accounts.md) to grant permission to another smart account
9+
or externally owned account (EOA) to perform specific executions on their behalf, under defined rules and restrictions.
10+
The account that grants the permission is called the *delegator account*, while the account that receives the permission
11+
is called the *delegate account*.
12+
13+
The MetaMask Delegation Toolkit includes the following delegation features:
14+
15+
- **Caveats** - Users can use [caveat enforcers](caveat-enforcers.md) to apply rules and restrictions to delegations.
16+
For example: Alice delegates the ability to spend her USDC to Bob, limiting the amount to 100 USDC.
17+
18+
- **Chain of delegations** - Users can redelegate permissions that have been delegated to them, creating a chain of delegations across trusted parties.
19+
20+
Delegations are created using the `Delegation` type, which is specified as follows:
21+
22+
```typescript
23+
export type Delegation = {
24+
delegate: Hex; // The address to which the delegation is being granted.
25+
delegator: Hex; // The address that is granting the delegation.
26+
authority: Hex; // Hash of the parent delegation, or the constant ROOT_AUTHORITY.
27+
caveats: Caveat[]; // Caveats that restrict the authority being granted.
28+
salt: Hex; // Used to avoid hash collisions between identical delegations.
29+
signature: Hex; // Signature from the delegator account.
30+
};
31+
```
32+
33+
## Delegation lifecycle
34+
35+
The delegation lifecycle is as follows:
36+
37+
1. **Delegation creation** - A delegation is initialized, and the delegator account signs it.
38+
39+
2. **Caveat enforcement** - The caveats applied to the delegation specify conditions under which
40+
the delegation can be redeemed.
41+
42+
3. **Delegation storage** - The delegation can be stored, enabling retrieval for future redemption.
43+
44+
:::note
45+
[Storing and retrieving delegations](../experimental/store-retrieve-delegations.md) using the toolkit's
46+
`DelegationStorageClient` is an experimental feature.
47+
:::
48+
49+
4. **Delegation redemption** - The delegate (the account being granted the permission) redeems the
50+
delegation through an [ERC-4337 user operation](smart-accounts.md#account-abstraction-erc-4337),
51+
which verifies that the delegated authority is valid in order to perform the execution.
52+
53+
See [how to create a delegation](../how-to/create-delegation/index.md) to get started with the
54+
delegation lifecycle.
55+
56+
## Delegation Framework
57+
58+
The MetaMask Delegation Toolkit includes the Delegation Framework, which is a
59+
[set of comprehensively audited smart contracts](https://github.com/MetaMask/delegation-framework) that
60+
collectively handle delegator account creation, the delegation lifecycle,
61+
and caveat enforcement.
62+
It consists of the following components:
63+
64+
- **Delegator Core** - Delegator Core contains the logic for the ERC-4337 compliant delegator accounts.
65+
It defines the interface needed for the Delegation Manager to invoke executions on behalf of the accounts.
66+
67+
- **Delegator account implementations** - There are [multiple delegator account implementations](smart-accounts.md#smart-account-implementation-types),
68+
with the main difference being the signature scheme used to manage the underlying account.
69+
70+
- **Delegation Manager** - The Delegation Manager validates delegations and triggers executions
71+
on behalf of the delegator, ensuring tasks are executed accurately and securely.
72+
73+
When a delegation is redeemed, the Delegation Manager performs the following steps.
74+
It processes a single step for all redemptions before proceeding to the next one:
75+
76+
1. Validates the input data by ensuring the lengths of `permissionContexts`, `modes`, and
77+
`executionCallDatas` match, or throws `BatchDataLengthMismatch`.
78+
2. Decodes and validates the delegation, checking that the caller (`msg.sender`) is the delegate
79+
and that there are no empty signatures, or throws `InvalidDelegate`.
80+
3. Verifies delegation signatures, ensuring validity using `ECDSA` (for EOAs) or
81+
`isValidSignature` (for contracts), or throws `InvalidSignature`.
82+
4. Validates the delegation chain's authority and ensures delegations are not disabled.
83+
5. Executes the `beforeHook` for each `caveat` in the delegation, passing relevant data (`terms`,
84+
`arguments`, `mode`, `execution` `calldata`, and `delegationHash`) to the caveat enforcer.
85+
6. Calls `executeFromExecutor` to perform the delegation's execution, either by the delegator or
86+
the caller for self-authorized executions.
87+
7. Executes the `afterHook` for each `caveat`, similar to the `beforeHook`, passing required data
88+
to enforce post-execution conditions.
89+
8. Emits `RedeemedDelegation` events for each delegation that was successfully redeemed.
90+
91+
- **Caveat enforcers** - [Caveat enforcers](caveat-enforcers.md) manage rules and restrictions for delegations,
92+
providing fine-tuned control over delegated executions.
93+
94+
## Delegation redemption flow
95+
96+
This diagram illustrates how a delegation is created and subsequently redeemed on the Delegation Manager.
97+
The Delegation Manager is responsible for validating the signature of the delegation and the caveat enforcers.
98+
If everything is correct, it allows a delegate to execute an action on behalf of the delegator.
99+
100+
Learn more about the caveat enforcer hooks in the [Caveat enforcers](caveat-enforcers.md) section.
101+
102+
```mermaid
103+
%%{
104+
init: {
105+
'sequence': {
106+
'actorMargin': 25,
107+
'width': 200
108+
}
109+
}
110+
}%%
111+
112+
sequenceDiagram
113+
participant Delegator
114+
participant Delegate
115+
participant Manager as Delegation Manager
116+
participant Enforcer as Caveat enforcer
117+
118+
Delegator->>Delegator: Create delegation with caveat enforcers
119+
Delegator->>Delegator: Sign delegation
120+
Delegator->>Delegate: Send signed delegation
121+
Note right of Delegate: Hold delegation until redemption
122+
123+
Delegate->>Manager: redeemDelegations() with delegation & execution details
124+
Manager->>Delegator: isValidSignature()
125+
Delegator-->>Manager: Confirm valid (or not)
126+
127+
Manager->>Enforcer: beforeAllHook()
128+
Note right of Manager: Expect no error
129+
Manager->>Enforcer: beforeHook()
130+
Note right of Manager: Expect no error
131+
132+
Manager->>Delegator: executeFromExecutor() with execution details
133+
Delegator->>Delegator: Perform execution
134+
Note right of Manager: Expect no error
135+
136+
Manager->>Enforcer: afterHook()
137+
Note right of Manager: Expect no error
138+
Manager->>Enforcer: afterAllHook()
139+
Note right of Manager: Expect no error
140+
```

0 commit comments

Comments
 (0)