Skip to content

Latest commit

 

History

History
418 lines (309 loc) · 11.2 KB

File metadata and controls

418 lines (309 loc) · 11.2 KB
description Learn how to create a MetaMask smart account using Delegation Toolkit.

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

Create a smart account

You can enable users to create a MetaMask smart account directly in your dapp. This page provides examples of using toMetaMaskSmartAccount with Viem Core SDK to create different types of smart accounts with different signature schemes. An account's supported signatories can sign data on behalf of the smart account.

Prerequisites

Install and set up the Delegation Toolkit.

Create a Hybrid smart account

A Hybrid smart account supports both an externally owned account (EOA) owner and any number of passkey (WebAuthn) signers. You can create a Hybrid smart account with the following types of signers.

Create a Hybrid smart account with an Account signer

Use toMetaMaskSmartAccount, and Viem's privateKeyToAccount and generatePrivateKey, to create a Hybrid smart account with a signer from a randomly generated private key:

import { publicClient } from "./client.ts"
import { account } from "./signer.ts";
import { 
  Implementation, 
  toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";

const smartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Hybrid,
  deployParams: [account.address, [], [], []],
  deploySalt: "0x",
  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);

Create a Hybrid smart account with a Wallet Client signer

Use toMetaMaskSmartAccount and Viem's createWalletClient to create a Hybrid smart account with a Wallet Client signer:

import { publicClient } from "./client.ts"
import { walletClient } from "./signer.ts";
import { 
  Implementation, 
  toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";

const addresses = await walletClient.getAddresses();
const owner = addresses[0];

const smartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Hybrid,
  deployParams: [owner, [], [], []],
  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 { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { sepolia as chain } from "viem/chains";
import { http, createWalletClient } from "viem";

const privateKey = generatePrivateKey(); 
const account = privateKeyToAccount(privateKey);

export const walletClient = createWalletClient({
  account,
  chain,
  transport: http()
})

Create a Hybrid smart account with a passkey signer

Use toMetaMaskSmartAccount and Viem's toWebAuthnAccount to create a Hybrid smart account with a passkey (WebAuthn) signer:

:::info Installation required To work with WebAuthn, install the Ox SDK. :::

import { publicClient } from "./client.ts"
import { webAuthnAccount, credential } from "./signer.ts";
import { 
  Implementation, 
  toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";
import { Address, PublicKey } from "ox";
import { toHex } from "viem";

// Deserialize compressed public key
const publicKey = PublicKey.fromHex(credential.publicKey);

// Convert public key to address
const owner = Address.fromPublicKey(publicKey);

const smartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Hybrid,
  deployParams: [owner, [credential.id], [publicKey.x], [publicKey.y]],
  deploySalt: "0x",
  signer: { webAuthnAccount, keyId: toHex(credential.id) },
});
import { http, createPublicClient } from "viem";
import { sepolia as chain } from "viem/chains";

const transport = http(); 
export const publicClient = createPublicClient({ 
  transport, 
  chain, 
});
import { 
  createWebAuthnCredential, 
  toWebAuthnAccount, 
} from "viem/account-abstraction";
  
export const credential = await createWebAuthnCredential({
  name: "MetaMask smart account",
});

export const webAuthnAccount = toWebAuthnAccount({ credential });

Create a Multisig smart account

A Multisig smart account supports multiple EOA signers with a configurable threshold for execution. Use toMetaMaskSmartAccount to create a Multsig smart account with a combination of account signers and Wallet Client signers:

import { publicClient } from "./client.ts";
import { account, walletClient } from "./signers.ts";
import { 
  Implementation, 
  toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";

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()
});

:::note The number of signers in the signatories must be at least equal to the threshold for valid signature generation. :::

Create a Stateless 7702 smart account

A Stateless 7702 smart account represents an EOA that has been upgraded to support MetaMask Smart Accounts functionality as defined by EIP-7702.

:::note This implementation does not handle the upgrade process; see the EIP-7702 quickstart to learn how to upgrade. :::

You can create a Stateless 7702 smart account with the following types of signatories.

Create a Stateless 7702 smart account with an account signer

Use toMetaMaskSmartAccount and Viem's privateKeyToAccount to create a Stateless 7702 smart account with a signer from a private key:

import { publicClient } from "./client.ts";
import { account } from "./signer.ts";
import { 
  Implementation, 
  toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";

const smartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Stateless7702,
  address: account.address // Address of the upgraded EOA
  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);

Create a Stateless 7702 smart account with a Wallet Client signer

Use toMetaMaskSmartAccount and Viem's createWalletClient to create a Stateless 7702 smart account with a Wallet Client signer:

import { publicClient } from "./client.ts";
import { walletClient } from "./signer.ts";
import { 
  Implementation, 
  toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";

const addresses = await walletClient.getAddresses();
const address = addresses[0];

const smartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Stateless7702,
  address, // Address of the upgraded EOA
  signer: { walletClient },
});
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";

const privateKey = generatePrivateKey(); 
const account = privateKeyToAccount(privateKey);

export const walletClient = createWalletClient({
  account,
  chain,
  transport: http(),
})

Next steps

With a MetaMask smart account, you can perform the following functions: