Skip to content

Multisig

With Kernel, it's possible to configure multiple signers for your smart account. The plugin that supports this functionality is named WeightedECDSAValidator, for the fact that it supports multiple ECDSA signers, each having a specific "weight."

How it works

Each signer is set up with a weight, and for any given signature, there must be enough combined weight to reach or surpass the threshold for the signature to be considered valid.

For example, let's say we have:

  • Threshold: 100
  • Weights:
    • Signer A: 100
    • Signer B: 50
    • Signer C: 50

In this case, we are setting up a multisig where either signer A alone (100 = 100), or signer B and C together (50 + 50 = 100) can provide a valid signature.

Installation

npm
npm i @zerodev/weighted-ecdsa-validator

Setting up a new multisig account

To set up a new multisig account, start by creating a validator:

import { createWeightedECDSAValidator } from "@zerodev/weighted-ecdsa-validator"
 
const multisigValidator = await createWeightedECDSAValidator(publicClient, {
  entryPoint,
  kernelVersion,
  config: {
    threshold: 100,
    signers: [
      { address: signerA.address, weight: 100 },
      { address: signerB.address, weight: 50 },
      { address: signerC.address, weight: 50 },
    ]
  },
  signers: [signerB, signerC],
})

In config, you specify the threshold and an list of signer addresses, as well as their weights.

In signers, you specify the list of signers (Viem accounts) that will be signing for this account. The combined weight of these signers must reach the threshold.

After creating the validator, you can set up a Kernel account using the validator as usual.

Using an existing multisig account

If a multisig account has already been deployed, you can skip the multisig config but specify the deployed multisig address when you create the account:

const multisigValidator = await createWeightedECDSAValidator(publicClient, {
  entryPoint,
  kernelVersion,
  signers: [signerB, signerC],
})
 
const account = await createKernelAccount(publicClient, {
  entryPoint,
  kernelVersion,
  deployedAccountAddress: '<your multisig address>',
  plugins: {
    sudo: multisigValidator,
  }
})

Updating multisig config

In many use cases, you may need to add and remove signers over time. To do so, send a UserOp that updates the config:

import { getUpdateConfigCall } from "@zerodev/weighted-ecdsa-validator"
 
// getUpdateConfigCall can be used with either sendTransaction or sendUserOperation
 
await kernelClient.sendTransaction(
  getUpdateConfigCall({
    threshold: 100,
    signers: [
      { address: signer1.address, weight: 50 },
      { address: signer2.address, weight: 50 },
      { address: signer3.address, weight: 50 },
    ]
  }),
)

Note that kernelClient here must itself be a correctly set-up instance of a multisig account client.