Create a smart account
You can enable users to create a MetaMask smart account directly
in your dapp. Use toMetaMaskSmartAccount
to create different types of smart accounts with different signature schemes.
Prerequisites
Install and set up the Smart Accounts Kit.
Hybrid smart account
A Hybrid smart account supports both an externally owned account (EOA) owner and any number of passkey (WebAuthn) signers.
This example uses toMetaMaskSmartAccount and Viem's Wallet Client
to create a Hybrid smart account. The signer parameter also accepts Viem's Local Account and WebAuthnAccount.
See the toMetaMaskSmartAccount API reference for more information.
- example.ts
- client.ts
- signer.ts
import { publicClient } from "./client.ts"
import { walletClient } from "./signer.ts";
import {
Implementation,
toMetaMaskSmartAccount,
} from "@metamask/smart-accounts-kit";
// Some wallets like MetaMask may require you to request access to
// account addresses using walletClient.requestAddresses() first.
const [address] = await walletClient.getAddresses();
const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Hybrid,
deployParams: [address, [], [], []],
deploySalt: "0x",
signer: { walletClient },
});
import { http, createPublicClient } from "viem";
import { sepolia as chain } from "viem/chains";
const transport = http();
export const publicClient = createPublicClient({
transport,
chain,
});
import { sepolia as chain } from "viem/chains";
import { createWalletClient, custom } from "viem";
export const walletClient = createWalletClient({
chain,
transport: custom(window.ethereum!),
});
Multisig smart account
A Multisig smart account supports multiple EOA signers with a configurable threshold for execution.
This example uses toMetaMaskSmartAccount to create a
Multisig smart account with a combination of account signers and Wallet Client signers.
- example.ts
- client.ts
- signers.ts
import { publicClient } from "./client.ts";
import { account, walletClient } from "./signers.ts";
import {
Implementation,
toMetaMaskSmartAccount,
} from "@metamask/smart-accounts-kit";
const owners = [ account.address, walletClient.address ];
const signer = [ { account }, { walletClient } ];
const threshold = 2n
const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.MultiSig,
deployParams: [owners, threshold],
deploySalt: "0x",
signer,
});
import { http, createPublicClient } from "viem";
import { sepolia as chain } from "viem/chains";
const transport = http();
export const publicClient = createPublicClient({
transport,
chain,
});
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { sepolia as chain } from "viem/chains";
import { http, createWalletClient } from "viem";
// This private key will be used to generate the first signer.
const privateKey = generatePrivateKey();
export const account = privateKeyToAccount(privateKey);
// This private key will be used to generate the second signer.
const walletClientPrivateKey = generatePrivateKey();
const walletClientAccount = privateKeyToAccount(walletClientPrivateKey);
export const walletClient = createWalletClient({
account: walletClientAccount,
chain,
transport: http()
});
The number of signers must be at least equal to the threshold to generate a valid signature.
EIP-7702 smart account
An EIP-7702 smart account represents an EOA that has been upgraded to support MetaMask Smart Accounts functionality as defined by EIP-7702.
This example uses toMetaMaskSmartAccount
and Viem's privateKeyToAccount to
create an EIP-7702 smart account. This example doesn't handle the upgrade process; see the
EIP-7702 quickstart to learn how to upgrade.
The EIP-7702 implementation only works with Viem's Local Accounts. It doesn't work with a JSON-RPC Account like MetaMask.
See the Upgrade a MetaMask EOA to a smart account tutorial.
- example.ts
- client.ts
- signer.ts
import { publicClient } from "./client.ts";
import { account } from "./signer.ts";
import {
Implementation,
toMetaMaskSmartAccount,
} from "@metamask/smart-accounts-kit";
const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Stateless7702,
address: account.address,
signer: { account },
});
import { http, createPublicClient } from "viem";
import { sepolia as chain } from "viem/chains";
const transport = http();
export const publicClient = createPublicClient({
transport,
chain,
});
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
const privateKey = generatePrivateKey();
export const account = privateKeyToAccount(privateKey);
Next steps
- Configure signers to use a signer that fits your needs.
- Deploy the smart account and send user operations using Viem Account Abstraction clients.
- Create delegations to grant scoped permissions to other accounts.