Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions delegation-toolkit/concepts/delegation/caveat-enforcers.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ When designing delegations with caveats, consider these best practices:

## Available caveat enforcers

The Delegation Toolkit provides [many out-of-the-box caveat enforcers](../../reference/caveats.md)
The Delegation Toolkit provides [out-of-the-box caveat enforcers](../../reference/caveats.md)
for common restriction patterns, including:

- Limiting target addresses and methods.
- Setting time or block number constraints.
- Restricting token transfers and approvals.
- Limiting execution frequency.

For more complex scenarios, you can also [create custom caveat enforcers](../../guides/delegation/create-custom-caveat-enforcer.md) by implementing the `ICaveatEnforcer` interface.
For other restriction patterns, you can also [create custom caveat enforcers](../../tutorials/create-custom-caveat-enforcer.md) by implementing the `ICaveatEnforcer` interface.

## Attenuating authority with redelegations

Expand Down
4 changes: 2 additions & 2 deletions delegation-toolkit/get-started/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This page provides instructions to install and set up the MetaMask Delegation To
- Install [Yarn](https://yarnpkg.com/),
[npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), or another package manager.
- If you plan to use any smart contracts (for example, to
[create a custom caveat enforcer](../guides/delegation/create-custom-caveat-enforcer.md)),
[create a custom caveat enforcer](../tutorials/create-custom-caveat-enforcer.md)),
install [Foundry](https://book.getfoundry.sh/getting-started/installation).

## Steps
Expand All @@ -33,7 +33,7 @@ npm install @metamask/delegation-toolkit
### 2. (Optional) Install the contracts

If you plan to extend the Delegation Framework smart contracts (for example, to
[create a custom caveat enforcer](../guides/delegation/create-custom-caveat-enforcer.md)), install
[create a custom caveat enforcer](../tutorials/create-custom-caveat-enforcer.md)), install
the contract package using Foundry's command-line tool, Forge:

```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,5 @@ const delegation = createDelegation({
});
```

For more granular or custom control, you can also [create custom caveat enforcers](create-custom-caveat-enforcer.md)
For more specific or custom control, you can also [create custom caveat enforcers](../../tutorials/create-custom-caveat-enforcer.md)
and add them to the caveat builder.
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
---
description: Learn how to create, deploy, and apply a custom caveat enforcer
sidebar_position: 3
description: Follow this tutorial to create, deploy, and apply a custom caveat enforcer for a delegation.
sidebar_position: 2
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Create a custom caveat enforcer

When [restricting a delegation](restrict-delegation.md), the MetaMask Delegation Toolkit provides some [out-of-the-box caveat enforcers](../../reference/caveats.md)
that cover common use cases.
For more granular or custom control, you can follow the instructions on this page to create custom caveat enforcers from scratch.
This tutorial walks you through creating a custom [caveat enforcer](../concepts/delegation/caveat-enforcers.md) and applying it to a [delegation](../concepts/delegation/index.md).

The MetaMask Delegation Toolkit includes [out-of-the-box caveat enforcers](../reference/caveats.md) that define rules and restrictions for common use cases.
For more specific control or other use cases, you can create custom caveat enforcers.
In this tutorial, you'll create and apply a caveat enforcer that only allows a delegation to be redeemed after a specific timestamp.

## Prerequisites

- [Install and set up the Delegation Toolkit.](../../get-started/install.md)
- [Configure the Delegation Toolkit.](../configure.md)
- [Install and set up the Delegation Toolkit](../get-started/install.md) in your project.
- [Configure the Delegation Toolkit.](../guides/configure.md)
- [Install Foundry and Forge.](https://getfoundry.sh/introduction/installation)
- Get an [Infura API key](/developer-tools/dashboard/get-started/create-api) from the MetaMask Developer dashboard.
- Have a MetaMask account with some Sepolia ETH to deploy your contract.
:::note
You can use the [MetaMask faucet](/developer-tools/faucet) to get Sepolia ETH.
:::

## Steps

### 1. Create the caveat enforcer

Create a contract that extends the
[`ICaveatEnforcer.sol`](https://github.com/MetaMask/delegation-framework/blob/main/src/interfaces/ICaveatEnforcer.sol)
interface.
At the root of your project, create a `contracts` directory.
In that directory, create a new contract named `AfterTimestampEnforcer.sol`.

For example, the following is a simple caveat enforcer that only allows a delegation to be redeemed after a specific timestamp.
Add the following code to `AfterTimestampEnforcer.sol`, which creates a caveat enforcer that extends the
[`ICaveatEnforcer.sol`](https://github.com/MetaMask/delegation-framework/blob/main/src/interfaces/ICaveatEnforcer.sol)
interface and only allows a delegation to be redeemed after a specific timestamp:

```solidity title="AfterTimestampEnforcer.sol"
// SPDX-License-Identifier: MIT
Expand Down Expand Up @@ -66,23 +75,28 @@ contract AfterTimestampEnforcer is CaveatEnforcer {

### 2. Deploy the caveat enforcer

Deploy your custom caveat enforcer to obtain its contract address.
For example, you can [deploy your smart contract using Forge](https://book.getfoundry.sh/forge/deploying).
Deploy your custom caveat enforcer using [Forge](https://book.getfoundry.sh/forge/deploying) to obtain its contract address.
Replace `<YOUR-API-KEY>` with your Infura API key, and `<YOUR-PRIVATE-KEY>` with the private key of your MetaMask account:

### 3. Apply the caveat enforcer
```bash
forge create src/AfterTimestampEnforcer.sol:AfterTimestampEnforcer \
--rpc-url https://sepolia.infura.io/v3/<YOUR-API-KEY> \
--private-key <YOUR-PRIVATE-KEY> \
--broadcast
```

When creating a delegation, add the `Caveat` for the custom caveat to the `CaveatBuilder`.
Learn more about [applying caveats to a delegation](restrict-delegation.md).
The Forge CLI will display the address of the deployed caveat enforcer.

The following example uses the custom `AfterTimestampEnforcer.sol` caveat enforcer to create a delegation granting
an allowance of 1,000,000 wei that can only be spent after one hour from when the delegation is created.
### 3. Apply the caveat enforcer

Specify the address of the deployed `AfterTimestampEnforcer.sol` contract, add it to the caveat builder, and create a delegation.
Learn more about [applying caveats to a delegation](../guides/delegation/restrict-delegation.md).

:::warning Important
Depending on the use case, it may be necessary to add additional caveats to restrict the delegation further.
:::
The following code snippet uses the custom caveat enforcer to create a delegation granting
a 1,000,000 wei allowance that becomes spendable one hour after it is created:

<Tabs>
<TabItem value="example.ts">
<TabItem value="delegation.ts">

```typescript
import {
Expand All @@ -94,7 +108,7 @@ import { delegatorSmartAccount } from "./config.ts";

const environment = delegatorSmartAccount.environment;

// Replace this with the address where the AfterTimestampEnforcer.sol contract is deployed.
// Replace this with the address of the deployed AfterTimestampEnforcer.sol contract.
const afterTimestampEnforcer = "0x22Ae4c4919C3aB4B5FC309713Bf707569B74876F";

const caveatBuilder = createCaveatBuilder(environment);
Expand All @@ -115,7 +129,6 @@ const delegation = createDelegation({
});
```


</TabItem>

<TabItem value="config.ts">
Expand Down Expand Up @@ -147,3 +160,8 @@ export const delegatorSmartAccount = await toMetaMaskSmartAccount({

</TabItem>
</Tabs>

You've successfully created, deployed, and applied a custom caveat enforcer!

For production use cases, you might need to add additional caveats to restrict the delegation further.
Learn more about [caveat enforcers](../concepts/delegation/caveat-enforcers.md).
8 changes: 6 additions & 2 deletions vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -735,8 +735,8 @@
"destination": "/delegation-toolkit/development/guides/delegation/execute-on-smart-accounts-behalf/"
},
{
"source": "/delegation-toolkit/development/how-to/create-delegation/:path*/",
"destination": "/delegation-toolkit/development/guides/delegation/:path*/"
"source": "/delegation-toolkit/development/how-to/create-delegation/restrict-delegation/",
"destination": "/delegation-toolkit/development/guides/delegation/restrict-delegation/"
},
{
"source": "/delegation-toolkit/development/how-to/redeem-delegation/",
Expand All @@ -755,6 +755,10 @@
"destination": "/delegation-toolkit/development/get-started/use-the-cli/"
},
{
"source": "/delegation-toolkit/development/how-to/create-delegation/create-custom-caveat-enforcer/",
"destination": "/delegation-toolkit/development/tutorials/create-custom-caveat-enforcer/"
},
{
"source": "/delegation-toolkit/development/concepts/caveat-enforcers/",
"destination": "/delegation-toolkit/development/concepts/delegation/caveat-enforcers/"
},
Expand Down
Loading