Skip to content
Alchemy Logo

How to manage ownership of a Multi-Owner Light Account

A MultiOwnerLightAccount has one or more ECDSA or smart-contract owners. This lets your account integrate with multiple owners at once, and supports recovering the account if one owner is lost.

A MultiOwnerLightAccount (returned by toMultiOwnerLightAccount from @alchemy/smart-accounts) lets you:

  • Add or remove owners.
  • Read the current set of owners.
  • Validate ERC-4337 user operations and 1271 signatures from any owner.

Call getOwnerAddresses() directly on the account.

import { createClient } from "viem";
import { sepolia } from "viem/chains";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { alchemyTransport } from "@alchemy/common";
import { toMultiOwnerLightAccount } from "@alchemy/smart-accounts";
 
const transport = alchemyTransport({ apiKey: "your-api-key" });
const rpcClient = createClient({ chain: sepolia, transport });
 
const account = await toMultiOwnerLightAccount({
  client: rpcClient,
  owners: [privateKeyToAccount(generatePrivateKey())],
});
 
const owners = await account.getOwnerAddresses();

Encode an updateOwners call with encodeUpdateOwners, then send it from the account through viem's bundler client.

import { createBundlerClient } from "viem/account-abstraction";
import { createClient, type Address } from "viem";
import { sepolia } from "viem/chains";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { alchemyTransport } from "@alchemy/common";
import { toMultiOwnerLightAccount } from "@alchemy/smart-accounts";
import { estimateFeesPerGas } from "@alchemy/aa-infra";
 
const ALCHEMY_API_KEY = "your-api-key";
const transport = alchemyTransport({ apiKey: ALCHEMY_API_KEY });
const rpcClient = createClient({ chain: sepolia, transport });
 
const account = await toMultiOwnerLightAccount({
  client: rpcClient,
  owners: [privateKeyToAccount(generatePrivateKey())],
});
 
const bundlerClient = createBundlerClient({
  account,
  client: rpcClient,
  chain: sepolia,
  transport,
  userOperation: { estimateFeesPerGas },
});
 
const ownersToAdd: Address[] = []; // addresses to add
const ownersToRemove: Address[] = []; // addresses to remove
 
const updateData = account.encodeUpdateOwners(ownersToAdd, ownersToRemove);
 
const hash = await bundlerClient.sendUserOperation({
  calls: [{ to: account.address, data: updateData }],
});
 
const receipt = await bundlerClient.waitForUserOperationReceipt({ hash });
Was this page helpful?