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