Skip to content

Commit 77325a1

Browse files
AyushBherwani1998“AyushBherwani1998”alexandratran
authored
[Delegation Toolkit] Adds tutorial (#2246)
* adds tutorial: use passkey as backup signer * edits * update description * fixes --------- Co-authored-by: “AyushBherwani1998” <“ayush.bherwani1998@gmail.com”> Co-authored-by: Alexandra Tran <alexandratran@protonmail.com>
1 parent 2696e2b commit 77325a1

File tree

6 files changed

+183
-11
lines changed

6 files changed

+183
-11
lines changed

delegation-toolkit/concepts/smart-accounts.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ See [Create a smart account](../guides/smart-accounts/create-smart-account.md) t
4343

4444
### Hybrid smart account
4545

46-
The Hybrid smart account is a flexible implementation that supports both an externally owned account (EOA) owner and any number of P256 (passkey) signers.
46+
The Hybrid smart account is a flexible implementation that supports both an externally owned account (EOA) owner and any number of passkey (WebAuthn) signers.
4747
You can configure any of these signers as the signatory, and use them to sign any data, including user operations, on behalf of the smart account.
4848

4949
This type is referenced in the toolkit as `Implementation.Hybrid`.
5050

5151
### Multisig smart account
5252

53-
The Multisig smart account is an implementation that supports multiple signers with a configurable threshold for valid signatures, allowing for enhanced security and flexibility in account management.
54-
The signatory must have at least as many signers include as the threshold is configured for the account.
53+
The Multisig smart account is an implementation that supports multiple signers with a configurable threshold, allowing for enhanced security and flexibility in account management.
54+
A valid signature requires signatures from at least the number of signers specified by the threshold.
5555

5656
This type is referenced in the toolkit as `Implementation.Multisig`.
5757

delegation-toolkit/get-started/smart-account-quickstart/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const bundlerClient = createBundlerClient({
4646
[Create a MetaMask smart account](../../guides/smart-accounts/create-smart-account.md) to send the first user operation.
4747

4848
This example configures a Hybrid smart account,
49-
which is a flexible smart account implementation that supports both an externally owned account (EOA) owner and any number of P256 (passkey) signers:
49+
which is a flexible smart account implementation that supports both an externally owned account (EOA) owner and any number of passkey (WebAuthn) signers:
5050

5151
```typescript
5252
import { Implementation, toMetaMaskSmartAccount } from "@metamask/delegation-toolkit";

delegation-toolkit/guides/smart-accounts/create-smart-account.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import TabItem from "@theme/TabItem";
99
# Create a smart account
1010

1111
You can enable users to create a [MetaMask smart account](../../concepts/smart-accounts.md) directly in your dapp.
12-
This page provides examples of using [`toMetaMaskSmartAccount`](../../reference/api/smart-account.md#tometamasksmartaccount) with Viem Core SDK to create different types of smart accounts with different types of signatories.
12+
This page provides examples of using [`toMetaMaskSmartAccount`](../../reference/api/smart-account.md#tometamasksmartaccount) with Viem Core SDK to create different types of smart accounts with different signature schemes.
13+
An account's supported *signatories* can sign data on behalf of the smart account.
1314

1415
## Prerequisites
1516

@@ -18,7 +19,7 @@ This page provides examples of using [`toMetaMaskSmartAccount`](../../reference/
1819

1920
## Create a Hybrid smart account
2021

21-
A Hybrid smart account supports both an externally owned account (EOA) owner and any number of P256 (passkey) signers.
22+
A Hybrid smart account supports both an externally owned account (EOA) owner and any number of passkey (WebAuthn) signers.
2223
You can create a Hybrid smart account with the following types of signatories.
2324

2425
### Create a Hybrid smart account with an Account signatory
@@ -138,9 +139,9 @@ export const walletClient = createWalletClient({
138139
</TabItem>
139140
</Tabs>
140141

141-
### Create a Hybrid smart account with a WebAuthn (passkey) signatory
142+
### Create a Hybrid smart account with a passkey signatory
142143

143-
Use [`toMetaMaskSmartAccount`](../../reference/api/smart-account.md#tometamasksmartaccount) and Viem's [`toWebAuthnAccount`](https://viem.sh/account-abstraction/accounts/webauthn) to create a Hybrid smart account with a WebAuthn Account signatory:
144+
Use [`toMetaMaskSmartAccount`](../../reference/api/smart-account.md#tometamasksmartaccount) and Viem's [`toWebAuthnAccount`](https://viem.sh/account-abstraction/accounts/webauthn) to create a Hybrid smart account with a passkey (WebAuthn) signatory:
144145

145146
:::info Installation required
146147
To work with WebAuthn, install the [Ox SDK](https://oxlib.sh/).

delegation-toolkit/reference/api/smart-account.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,9 +544,9 @@ All Hybrid deploy parameters are required:
544544
| Name | Type | Description |
545545
| ---- | ---- | ----------- |
546546
| `owner` | `Hex` | The owner's account address. The owner can be the zero address, indicating that there is no owner configured. |
547-
| `p256KeyIds` | `Hex[]` | An array of key identifiers for P256 signers. |
548-
| `p256XValues` | `bigint[]` | An array of public key x-values for P256 signers. |
549-
| `p256YValues` | `bigint[]` | An array of public key y-values for P256 signers. |
547+
| `p256KeyIds` | `Hex[]` | An array of key identifiers for passkey signers. |
548+
| `p256XValues` | `bigint[]` | An array of public key x-values for passkey signers. |
549+
| `p256YValues` | `bigint[]` | An array of public key y-values for passkey signers. |
550550

551551
#### Example
552552

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"label": "Tutorials",
3+
"position": 5
4+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
---
2+
description: Follow this tutorial to use a passkey as a backup signer with a Hybrid MetaMask smart account.
3+
sidebar_position: 1
4+
---
5+
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).
9+
10+
## About passkeys
11+
12+
An externally owned account (EOA) uses the secp256k1 elliptic curve to generate key pairs and signatures.
13+
In contrast, a passkey (WebAuthn credential) uses the secp256r1 (P-256) elliptic curve to generate key pairs and signatures.
14+
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.
15+
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.
17+
This allows you to add a passkey as a backup signer for your smart account.
18+
19+
You can add passkeys during smart account creation or after the account has been deployed.
20+
This tutorial walks you through adding a passkey signer to an already deployed smart account.
21+
22+
## Prerequisites
23+
24+
- [Install and set up the Delegation Toolkit](../get-started/install) in your project.
25+
- [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.
28+
29+
## Steps
30+
31+
### 1. Create a Public Client
32+
33+
Create a [Viem Public Client](https://viem.sh/docs/clients/public) using Viem's `createPublicClient` function.
34+
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.
35+
36+
```typescript
37+
import { createPublicClient, http } from "viem";
38+
import { sepolia as chain } from "viem/chains";
39+
40+
const publicClient = createPublicClient({
41+
chain,
42+
transport: http(),
43+
});
44+
```
45+
46+
### 2. Create a Bundler Client
47+
48+
Create a [Viem Bundler Client](https://viem.sh/account-abstraction/clients/bundler) using Viem's `createBundlerClient` function.
49+
You can use the bundler service to estimate gas for user operations and submit transactions to the network.
50+
51+
```typescript
52+
import { createBundlerClient } from "viem/account-abstraction";
53+
54+
const bundlerClient = createBundlerClient({
55+
client: publicClient,
56+
transport: http("https://your-bundler-rpc.com"),
57+
});
58+
```
59+
60+
### 3. Create a Hybrid smart account
61+
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).
63+
The Hybrid implementation supports adding additional passkey signers.
64+
65+
```typescript
66+
import { Implementation, toMetaMaskSmartAccount } from "@metamask/delegation-toolkit";
67+
import { privateKeyToAccount } from "viem/accounts";
68+
69+
const account = privateKeyToAccount("0x...");
70+
71+
const smartAccount = await toMetaMaskSmartAccount({
72+
client: publicClient,
73+
implementation: Implementation.Hybrid,
74+
deployParams: [account.address, [], [], []],
75+
deploySalt: "0x",
76+
signatory: { account },
77+
});
78+
```
79+
80+
### 4. Create a passkey
81+
82+
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).
83+
84+
```ts
85+
import {
86+
createWebAuthnCredential,
87+
} from "viem/account-abstraction";
88+
89+
const credential = await createWebAuthnCredential({
90+
name: "MetaMask Smart Account",
91+
});
92+
```
93+
94+
### 5. Add the passkey as a backup signer
95+
96+
Use the `HybridDeleGator` contract namespace from the Delegation Toolkit to encode the calldata required to add the passkey signer.
97+
The encoding function needs the X and Y coordinates of the P-256 public key.
98+
Since WebAuthn credentials store a compressed public key, you need to use the [Ox SDK](https://oxlib.sh/#installation) to deserialize it, and extract the X and Y coordinates.
99+
100+
Once the calldata is prepared, send it to your smart account address to register the passkey as a backup signer.
101+
102+
```ts
103+
import { PublicKey } from "ox";
104+
import { HybridDeleGator, P256Owner } from "@metamask/delegation-toolkit/contracts";
105+
106+
// Deserialize the compressed public key.
107+
const publicKey = PublicKey.fromHex(credential.publicKey);
108+
109+
const p256Owner: P256Owner = {
110+
keyId: credential.id,
111+
x: publicKey.x,
112+
y: publicKey.y,
113+
}
114+
115+
const data = HybridDeleGator.encode.addKey({
116+
p256Owner,
117+
});
118+
119+
// Appropriate fee per gas must be determined for the specific bundler being used.
120+
const maxFeePerGas = 1n;
121+
const maxPriorityFeePerGas = 1n;
122+
123+
const userOperationHash = await bundlerClient.sendUserOperation({
124+
account: smartAccount,
125+
calls: [
126+
{
127+
to: smartAccount.address,
128+
data,
129+
},
130+
],
131+
maxFeePerGas,
132+
maxPriorityFeePerGas,
133+
});
134+
```
135+
136+
### 6. (Optional) Use the passkey signer
137+
138+
You can now use the passkey signer to access your smart account and sign transactions.
139+
If you ever lose your primary signer (private key) used in [Step 3](#3-create-a-hybrid-smart-account), you can use the passkey as a secure backup method to retain access to your smart account.
140+
141+
Use the [Viem WebAuthn Account](https://viem.sh/account-abstraction/accounts/webauthn) to configure your passkey as a MetaMask smart account signer.
142+
143+
```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";
148+
149+
// Use the deserialized public key from the previous step.
150+
const owner = Address.fromPublicKey(publicKey);
151+
152+
// Use the credential from the previous step.
153+
const webAuthnAccount = toWebAuthnAccount({ credential });
154+
155+
const smartAccount = await toMetaMaskSmartAccount({
156+
client: publicClient,
157+
implementation: Implementation.Hybrid,
158+
deployParams: [owner, [credential.id], [publicKey.x], [publicKey.y]],
159+
deploySalt: "0x",
160+
signatory: { webAuthnAccount, keyId: toHex(credential.id) },
161+
});
162+
```
163+
164+
## Next steps
165+
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.

0 commit comments

Comments
 (0)