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 EOAExternally owned account (EOA) A private-key-controlled account with no built-in programmable execution logic. owner and any number of passkeyPasskey A cryptographic key that can be used to sign transactions instead of a private key. (WebAuthn) signersSigner An account that can sign transactions for a smart account..
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 EOAExternally owned account (EOA) A private-key-controlled account with no built-in programmable execution logic. signersSigner An account that can sign transactions for a smart account. with a configurable threshold for execution.
This example uses toMetaMaskSmartAccount to create a
Multisig smart account with a combination of account signers and Wallet ClientWallet Client An interface for interacting with blockchain accounts, executing transactions, and signing messages. 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 EOAExternally owned account (EOA) A private-key-controlled account with no built-in programmable execution logic. that has been upgraded to support MetaMask Smart AccountsMetaMask smart account A smart contract account that supports programmable behavior, delegated permissions, flexible signing options, and other advanced features. 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.