Generate a multisig signature
The MetaMask Delegation Toolkit supports Multisig smart accounts,
allowing you to add multiple externally owned account (EOA)
signers with a configurable execution threshold. When the threshold
is greater than 1, you can collect signatures from the required signers
and use the aggregateSignature function to combine them
into a single aggregated signature.
Prerequisites
- Install and set up the Delegation Toolkit.
- Configure the Delegation Toolkit.
- Create a Multisig smart account.
Generate a multisig signature
The following example configures a Multisig smart account with two different signers: Alice and Bob. The account has a threshold of 2, meaning that signatures from both parties are required for any execution.
- example.ts
- config.ts
import { 
  bundlerClient, 
  aliceSmartAccount, 
  bobSmartAccount,
  aliceAccount,
  bobAccount,
} from "./config.ts";
import { aggregateSignature } from "@metamask/delegation-toolkit";
const userOperation = await bundlerClient.prepareUserOperation({
  account: aliceSmartAccount,
  calls: [
    {
      target: zeroAddress,
      value: 0n,
      data: "0x",
    }
  ]
});
const aliceSignature = await aliceSmartAccount.signUserOperation(userOperation);
const bobSignature = await bobSmartAccount.signUserOperation(userOperation);
const aggregatedSignature = aggregateSignature({
  signatures: [{
    signer: aliceAccount.address,
    signature: aliceSignature,
    type: "ECDSA",
  }, {
    signer: bobAccount.address,
    signature: bobSignature,
    type: "ECDSA",
  }],
});
import { createPublicClient, http } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { createBundlerClient } from "viem/account-abstraction";
import { lineaSepolia as chain } from "viem/chains";
import { 
  Implementation, 
  toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";
const publicClient = createPublicClient({
  chain,
  transport: http()
});
const alicePrivateKey = generatePrivateKey(); 
export const aliceAccount = privateKeyToAccount(alicePrivateKey);
const bobPrivateKey = generatePrivateKey();
export const bobAccount = privateKeyToAccount(bobPrivateKey)
const signers = [ aliceAccount.address, bobAccount.address ];
const threshold = 2n
export const aliceSmartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.MultiSig,
  deployParams: [signers, threshold],
  deploySalt: "0x",
  signatory: [ { account: aliceAccount } ],
});
export const bobSmartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.MultiSig,
  deployParams: [signers, threshold],
  deploySalt: "0x",
  signatory: [ { account: bobAccount } ],
});
export const bundlerClient = createBundlerClient({
  client: publicClient,
  transport: http("https://public.pimlico.io/v2/rpc")
});