Skip to content

Commit eeaafc4

Browse files
committed
shift dtk tutorials
1 parent 886ad8d commit eeaafc4

File tree

5 files changed

+80
-89
lines changed

5 files changed

+80
-89
lines changed

delegation-toolkit/tutorials/_category_.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

delegation-toolkit/tutorials/create-custom-caveat-enforcer.md renamed to src/pages/tutorials/create-custom-caveat-enforcer.md

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
---
2-
description: Follow this tutorial to create, deploy, and apply a custom caveat enforcer for a delegation.
3-
sidebar_position: 2
2+
title: Create a custom caveat enforcer
3+
image: 'img/guides/guides-banners/custom-caveat-enforcer.png'
4+
description: Create, deploy, and apply a custom caveat enforcer for a delegation.
5+
tags: [delegation toolkit, caveat enforcer, smart contracts, ethereum]
6+
date: Aug 27, 2025
7+
author: MetaMask Developer Relations
48
---
59

6-
import Tabs from "@theme/Tabs";
10+
import Tabs from "@theme/Tabs";
711
import TabItem from "@theme/TabItem";
812

9-
# Create a custom caveat enforcer
13+
This tutorial walks you through creating a custom [caveat enforcer](/delegation-toolkit/concepts/delegation/caveat-enforcers) and applying it to a [delegation](/delegation-toolkit/concepts/delegation/).
1014

11-
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).
12-
13-
The MetaMask Delegation Toolkit includes [out-of-the-box caveat enforcers](../reference/caveats.md) that define rules and restrictions for common use cases.
15+
The MetaMask Delegation Toolkit includes [out-of-the-box caveat enforcers](/delegation-toolkit/reference/caveats) that define rules and restrictions for common use cases.
1416
For more specific control or other use cases, you can create custom caveat enforcers.
1517
In this tutorial, you'll create and apply a caveat enforcer that only allows a delegation to be redeemed after a specific timestamp.
1618

1719
## Prerequisites
1820

19-
- [Install and set up the Delegation Toolkit](../get-started/install.md) in your project.
20-
- [Configure the Delegation Toolkit.](../guides/configure.md)
21+
- [Install and set up the Delegation Toolkit](/delegation-toolkit/get-started/install) in your project.
22+
- [Configure the Delegation Toolkit.](/delegation-toolkit/guides/configure)
2123
- [Install Foundry and Forge.](https://getfoundry.sh/introduction/installation)
2224
- Get an [Infura API key](/developer-tools/dashboard/get-started/create-api) from the MetaMask Developer dashboard.
2325
- Have a MetaMask account with some Sepolia ETH to deploy your contract.
@@ -41,7 +43,7 @@ interface and only allows a delegation to be redeemed after a specific timestamp
4143
pragma solidity 0.8.23;
4244
4345
import { CaveatEnforcer } from "@delegator/src/enforcers/CaveatEnforcer.sol";
44-
import { ModeCode } from "../utils/Types.sol";
46+
import { ModeCode } from "/delegation-toolkit/utils/Types.sol";
4547
4648
contract AfterTimestampEnforcer is CaveatEnforcer {
4749
/**
@@ -90,7 +92,7 @@ The Forge CLI will display the address of the deployed caveat enforcer.
9092
### 3. Apply the caveat enforcer
9193

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

9597
The following code snippet uses the custom caveat enforcer to create a delegation granting
9698
a 1,000,000 wei allowance that becomes spendable one hour after it is created:
@@ -99,63 +101,55 @@ a 1,000,000 wei allowance that becomes spendable one hour after it is created:
99101
<TabItem value="delegation.ts">
100102

101103
```typescript
102-
import {
103-
createCaveatBuilder,
104-
createDelegation,
105-
} from "@metamask/delegation-toolkit";
106-
import { toHex } from "viem";
107-
import { delegatorSmartAccount } from "./config.ts";
104+
import { createCaveatBuilder, createDelegation } from '@metamask/delegation-toolkit'
105+
import { toHex } from 'viem'
106+
import { delegatorSmartAccount } from './config.ts'
108107

109-
const environment = delegatorSmartAccount.environment;
108+
const environment = delegatorSmartAccount.environment
110109

111110
// Replace this with the address of the deployed AfterTimestampEnforcer.sol contract.
112-
const afterTimestampEnforcer = "0x22Ae4c4919C3aB4B5FC309713Bf707569B74876F";
111+
const afterTimestampEnforcer = '0x22Ae4c4919C3aB4B5FC309713Bf707569B74876F'
113112

114-
const caveatBuilder = createCaveatBuilder(environment);
113+
const caveatBuilder = createCaveatBuilder(environment)
115114

116-
const tenAM = 10 * 60 * 60; // 10:00 AM as seconds since midnight.
115+
const tenAM = 10 * 60 * 60 // 10:00 AM as seconds since midnight.
117116

118-
const caveats = caveatBuilder
119-
.addCaveat("nativeTokenTransferAmount", 1_000_000)
120-
.addCaveat({
121-
enforcer: afterTimestampEnforcer,
122-
terms: toHex(tenAm)
123-
});
117+
const caveats = caveatBuilder.addCaveat('nativeTokenTransferAmount', 1_000_000).addCaveat({
118+
enforcer: afterTimestampEnforcer,
119+
terms: toHex(tenAm),
120+
})
124121

125122
const delegation = createDelegation({
126123
to: delegate,
127124
from: delegatorSmartAccount.address,
128-
caveats
129-
});
125+
caveats,
126+
})
130127
```
131128

132129
</TabItem>
133130

134131
<TabItem value="config.ts">
135132

136133
```typescript
137-
import { createPublicClient, http } from "viem";
138-
import { sepolia as chain } from "viem/chains";
139-
import {
140-
Implementation,
141-
toMetaMaskSmartAccount,
142-
} from "@metamask/delegation-toolkit";
134+
import { createPublicClient, http } from 'viem'
135+
import { sepolia as chain } from 'viem/chains'
136+
import { Implementation, toMetaMaskSmartAccount } from '@metamask/delegation-toolkit'
143137

144138
const publicClient = createPublicClient({
145139
chain,
146-
transport: http()
147-
});
140+
transport: http(),
141+
})
148142

149-
const privateKey = generatePrivateKey();
150-
const account = privateKeyToAccount(privateKey);
143+
const privateKey = generatePrivateKey()
144+
const account = privateKeyToAccount(privateKey)
151145

152146
export const delegatorSmartAccount = await toMetaMaskSmartAccount({
153147
client: publicClient,
154148
implementation: Implementation.Hybrid,
155149
deployParams: [account.address, [], [], []],
156-
deploySalt: "0x",
150+
deploySalt: '0x',
157151
signatory: { account },
158-
});
152+
})
159153
```
160154

161155
</TabItem>
@@ -164,4 +158,4 @@ export const delegatorSmartAccount = await toMetaMaskSmartAccount({
164158
You've successfully created, deployed, and applied a custom caveat enforcer!
165159

166160
For production use cases, you might need to add additional caveats to restrict the delegation further.
167-
Learn more about [caveat enforcers](../concepts/delegation/caveat-enforcers.md).
161+
Learn more about [caveat enforcers](/delegation-toolkit/concepts/delegation/caveat-enforcers).
Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,33 @@
11
---
2-
description: Follow this tutorial to use a passkey as a backup signer with a Hybrid MetaMask smart account.
32
sidebar_position: 1
3+
title: Use a passkey as a backup signer
4+
image: 'img/guides/guides-banners/dtk-passkey-backup.png'
5+
description: Use a passkey as a backup signer with a Hybrid MetaMask smart account.
6+
tags: [delegation toolkit, passkey, backup, signer, smart account]
7+
date: Aug 27, 2025
8+
author: MetaMask Developer Relations
49
---
510

6-
# Use a passkey as a backup signer
7-
8-
This tutorial walks you through using a passkey as a backup signer for your [MetaMask smart account](../concepts/smart-accounts).
11+
This tutorial walks you through using a passkey as a backup signer for your [MetaMask smart account](/delegation-toolkit/concepts/smart-accounts.md).
912

1013
## About passkeys
1114

1215
An externally owned account (EOA) uses the secp256k1 elliptic curve to generate key pairs and signatures.
1316
In contrast, a passkey (WebAuthn credential) uses the secp256r1 (P-256) elliptic curve to generate key pairs and signatures.
1417
Passkeys eliminate the need for traditional seed phrases that are difficult to remember, enabling a more seamless and secure way for users to access their web3 wallets.
1518

16-
MetaMask Smart Accounts offer a [Hybrid implementation](../concepts/smart-accounts.md#hybrid-smart-account), which supports signature validation for both secp256k1 and secp256r1 curves.
19+
MetaMask Smart Accounts offer a [Hybrid implementation](/delegation-toolkit/concepts/smart-accounts.md#hybrid-smart-account), which supports signature validation for both secp256k1 and secp256r1 curves.
1720
This allows you to add a passkey as a backup signer for your smart account.
1821

1922
You can add passkeys during smart account creation or after the account has been deployed.
2023
This tutorial walks you through adding a passkey signer to an already deployed smart account.
2124

2225
## Prerequisites
2326

24-
- [Install and set up the Delegation Toolkit](../get-started/install) in your project.
27+
- [Install and set up the Delegation Toolkit](/delegation-toolkit/get-started/install.md) in your project.
2528
- [Install Ox SDK](https://oxlib.sh/#installation).
26-
- [Configure the Delegation Toolkit](../guides/configure).
27-
- [Create and deploy a Hybrid smart account,](../guides/smart-accounts/create-smart-account) with a signatory from a private key.
29+
- [Configure the Delegation Toolkit](/delegation-toolkit/guides/configure.md).
30+
- [Create and deploy a Hybrid smart account,](/delegation-toolkit/guides/smart-accounts/create-smart-account.md) with a signatory from a private key.
2831

2932
## Steps
3033

@@ -34,13 +37,13 @@ Create a [Viem Public Client](https://viem.sh/docs/clients/public) using Viem's
3437
You will configure a smart account and Bundler Client with the Public Client, which you can use to query the signer's account state and interact with the blockchain network.
3538

3639
```typescript
37-
import { createPublicClient, http } from "viem";
38-
import { sepolia as chain } from "viem/chains";
40+
import { createPublicClient, http } from 'viem'
41+
import { sepolia as chain } from 'viem/chains'
3942

4043
const publicClient = createPublicClient({
4144
chain,
4245
transport: http(),
43-
});
46+
})
4447
```
4548

4649
### 2. Create a Bundler Client
@@ -49,46 +52,44 @@ Create a [Viem Bundler Client](https://viem.sh/account-abstraction/clients/bundl
4952
You can use the bundler service to estimate gas for user operations and submit transactions to the network.
5053

5154
```typescript
52-
import { createBundlerClient } from "viem/account-abstraction";
55+
import { createBundlerClient } from 'viem/account-abstraction'
5356

5457
const bundlerClient = createBundlerClient({
5558
client: publicClient,
56-
transport: http("https://your-bundler-rpc.com"),
57-
});
59+
transport: http('https://your-bundler-rpc.com'),
60+
})
5861
```
5962

6063
### 3. Create a Hybrid smart account
6164

62-
Configure the same [Hybrid smart account](../guides/smart-accounts/create-smart-account.md#create-a-hybrid-smart-account) that you created and deployed as a [prerequisite](#prerequisites).
65+
Configure the same [Hybrid smart account](/delegation-toolkit/guides/smart-accounts/create-smart-account.md#create-a-hybrid-smart-account) that you created and deployed as a [prerequisite](#prerequisites).
6366
The Hybrid implementation supports adding additional passkey signers.
6467

6568
```typescript
66-
import { Implementation, toMetaMaskSmartAccount } from "@metamask/delegation-toolkit";
67-
import { privateKeyToAccount } from "viem/accounts";
69+
import { Implementation, toMetaMaskSmartAccount } from '@metamask/delegation-toolkit'
70+
import { privateKeyToAccount } from 'viem/accounts'
6871

69-
const account = privateKeyToAccount("0x...");
72+
const account = privateKeyToAccount('0x...')
7073

7174
const smartAccount = await toMetaMaskSmartAccount({
7275
client: publicClient,
7376
implementation: Implementation.Hybrid,
7477
deployParams: [account.address, [], [], []],
75-
deploySalt: "0x",
78+
deploySalt: '0x',
7679
signatory: { account },
77-
});
80+
})
7881
```
7982

8083
### 4. Create a passkey
8184

8285
To add a passkey signer, use Viem's [`createWebAuthnCredential`](https://viem.sh/account-abstraction/accounts/webauthn/createWebAuthnCredential) function to securely register the passkey (WebAuthn credential).
8386

8487
```ts
85-
import {
86-
createWebAuthnCredential,
87-
} from "viem/account-abstraction";
88-
88+
import { createWebAuthnCredential } from 'viem/account-abstraction'
89+
8990
const credential = await createWebAuthnCredential({
90-
name: "MetaMask Smart Account",
91-
});
91+
name: 'MetaMask Smart Account',
92+
})
9293
```
9394

9495
### 5. Add the passkey as a backup signer
@@ -100,11 +101,11 @@ Since WebAuthn credentials store a compressed public key, you need to use the [O
100101
Once the calldata is prepared, send it to your smart account address to register the passkey as a backup signer.
101102

102103
```ts
103-
import { PublicKey } from "ox";
104-
import { HybridDeleGator, P256Owner } from "@metamask/delegation-toolkit/contracts";
104+
import { PublicKey } from 'ox'
105+
import { HybridDeleGator, P256Owner } from '@metamask//delegation-toolkit/contracts'
105106

106107
// Deserialize the compressed public key.
107-
const publicKey = PublicKey.fromHex(credential.publicKey);
108+
const publicKey = PublicKey.fromHex(credential.publicKey)
108109

109110
const p256Owner: P256Owner = {
110111
keyId: credential.id,
@@ -114,11 +115,11 @@ const p256Owner: P256Owner = {
114115

115116
const data = HybridDeleGator.encode.addKey({
116117
p256Owner,
117-
});
118+
})
118119

119120
// Appropriate fee per gas must be determined for the specific bundler being used.
120-
const maxFeePerGas = 1n;
121-
const maxPriorityFeePerGas = 1n;
121+
const maxFeePerGas = 1n
122+
const maxPriorityFeePerGas = 1n
122123

123124
const userOperationHash = await bundlerClient.sendUserOperation({
124125
account: smartAccount,
@@ -130,7 +131,7 @@ const userOperationHash = await bundlerClient.sendUserOperation({
130131
],
131132
maxFeePerGas,
132133
maxPriorityFeePerGas,
133-
});
134+
})
134135
```
135136

136137
### 6. (Optional) Use the passkey signer
@@ -141,27 +142,27 @@ If you ever lose your primary signer (private key) used in [Step 3](#3-create-a-
141142
Use the [Viem WebAuthn Account](https://viem.sh/account-abstraction/accounts/webauthn) to configure your passkey as a MetaMask smart account signer.
142143

143144
```ts
144-
import { Address } from "ox";
145-
import { toWebAuthnAccount } from "viem/account-abstraction";
146-
import { toHex } from "viem";
147-
import { Implementation, toMetaMaskSmartAccount } from "@metamask/delegation-toolkit";
145+
import { Address } from 'ox'
146+
import { toWebAuthnAccount } from 'viem/account-abstraction'
147+
import { toHex } from 'viem'
148+
import { Implementation, toMetaMaskSmartAccount } from '@metamask/delegation-toolkit'
148149

149150
// Use the deserialized public key from the previous step.
150-
const owner = Address.fromPublicKey(publicKey);
151+
const owner = Address.fromPublicKey(publicKey)
151152

152153
// Use the credential from the previous step.
153-
const webAuthnAccount = toWebAuthnAccount({ credential });
154+
const webAuthnAccount = toWebAuthnAccount({ credential })
154155

155156
const smartAccount = await toMetaMaskSmartAccount({
156157
client: publicClient,
157158
implementation: Implementation.Hybrid,
158159
deployParams: [owner, [credential.id], [publicKey.x], [publicKey.y]],
159-
deploySalt: "0x",
160+
deploySalt: '0x',
160161
signatory: { webAuthnAccount, keyId: toHex(credential.id) },
161-
});
162+
})
162163
```
163164

164165
## Next steps
165166

166-
- See [Create a MetaMask smart account](../guides/smart-accounts/create-smart-account.md) to learn more about smart account implementations.
167-
- See [Send a gasless transaction](../guides/smart-accounts/send-gasless-transaction.md) to learn how to sponsor gas fees when adding a passkey as a backup signer.
167+
- See [Create a MetaMask smart account](/delegation-toolkit/guides/smart-accounts/create-smart-account.md) to learn more about smart account implementations.
168+
- See [Send a gasless transaction](/delegation-toolkit/guides/smart-accounts/send-gasless-transaction.md) to learn how to sponsor gas fees when adding a passkey as a backup signer.
182 KB
Loading
259 KB
Loading

0 commit comments

Comments
 (0)