Upgrading to a Modular Account
Upgrading a SmartContractAccount
can be done easily using Account Kit. It just involves a simple call to a single function on the SmartAccountClient
, namely upgradeAccount
, along with the necessary call data, UpgradeToData
, for the account targeted for the upgrade. For upgrading to a Modular Account, you can use the utility function getMSCAUpgradeToData
provided by the @account-kit/smart-contracts
package to retrieve the call data for the upgrade. This process applies to any account with upgrade capabilities.
Using the Light Account as an example, here is an overview of how the upgrade can be executed using a Smart Account Client:
// @filename: lightAccountClient.ts
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";
import { sepolia } from "@account-kit/infra";
import { LocalAccountSigner } from "@aa-sdk/core";
import { generatePrivateKey } from "viem/accounts";
export const lightAccountClient = await createLightAccountAlchemyClient({
apiKey: "YOUR_API_KEY",
chain: sepolia,
signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),
});
// @filename: lightAccountClient.ts
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";
import { sepolia } from "@account-kit/infra";
import { LocalAccountSigner } from "@aa-sdk/core";
import { generatePrivateKey } from "viem/accounts";
export const lightAccountClient = await createLightAccountAlchemyClient({
apiKey: "YOUR_API_KEY",
chain: sepolia,
signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),
});
// @filename: example.js
// ---cut---
import { lightAccountClient } from "./lightAccountClient";
import { getMSCAUpgradeToData } from "@account-kit/smart-contracts";
const { createMAAccount, ...upgradeToData } = await getMSCAUpgradeToData(
lightAccountClient,
{ account: lightAccountClient.account }
);
const hash = await lightAccountClient.upgradeAccount({
upgradeTo: upgradeToData,
waitForTx: true,
});
const upgradedAccount = await createMAAccount();
That is all! Now, you can create a smart account client to connect with the upgraded account as a Modular Account.
// @filename: lightAccountClient.ts
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";
import { sepolia } from "@account-kit/infra";
import { LocalAccountSigner } from "@aa-sdk/core";
import { generatePrivateKey } from "viem/accounts";
export const lightAccountClient = await createLightAccountAlchemyClient({
apiKey: "YOUR_API_KEY",
chain: sepolia,
signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),
});
// @filename: upgradedAccount.ts
// @filename: lightAccountClient.ts
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";
import { sepolia } from "@account-kit/infra";
import { LocalAccountSigner } from "@aa-sdk/core";
import { generatePrivateKey } from "viem/accounts";
export const lightAccountClient = await createLightAccountAlchemyClient({
apiKey: "YOUR_API_KEY",
chain: sepolia,
signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),
});
// @filename: example.js
// ---cut---
import { lightAccountClient } from "./lightAccountClient";
import { getMSCAUpgradeToData } from "@account-kit/smart-contracts";
const { createMAAccount, ...upgradeToData } = await getMSCAUpgradeToData(
lightAccountClient,
{ account: lightAccountClient.account }
);
const hash = await lightAccountClient.upgradeAccount({
upgradeTo: upgradeToData,
waitForTx: true,
});
export const upgradedAccount = await createMAAccount();
// @filename: example.js
// ---cut---
import { createAlchemySmartAccountClient } from "@account-kit/infra";
import { multiOwnerPluginActions } from "@account-kit/smart-contracts";
import { upgradedAccount } from "./upgradedAccount";
const upgradedAccountClient = await createAlchemySmartAccountClient({
apiKey: "YOUR_API_KEY",
chain: lightAccountClient.chain,
account: upgradedAccount,
}).extend(multiOwnerPluginActions);
const owners = await upgradedAccountClient.readOwners();