Skip to content

How to get the installed plugins of a Modular Account

ERC-6900 Modular Accounts implements Plugin inspection interface IAccountLoupe.sol to support visibility in plugin configuration on-chain. This contract interface defines the method getInstalledPlugins() that clients can use to fetch the currently installed plugins on a Modular Account.

solidity
/// @notice Get an array of all installed plugins.
/// @return The addresses of all installed plugins.
function getInstalledPlugins() external view returns (address[] memory);

Account Kit provides a streamlined experience of interacting with Modular Account AccoutLoupe interface easily by providing accountLoupeActions defined in @alchemy/aa-accounts package. When you connect your Modular Account to SmartAccountClient you can extend the client with accountLoupeActions, which exposes a set of methods available to call the account AccountLoupe with the client connected to the account.

Get installed plugins of a Modular Account

You should first extend the SmartAcountClient connected to a Modular Account, which has AccountLoupe implemented, with accountLoupeActions for the client to include the AccountLoupe actions.

Then, you can use the getInstalledPlugins method of the accountLoupeActions extended smart account client to get the list of installed plugin addresses for the connected Modular Account.

Note

When using createModularAccountAlchemyClient in @alchemy/aa-alchemy, the SmartAccountClient comes automatically extended with multiOwnerPluginActions, pluginManagerActions, and accountLoupeActions decorators as defaults available for use.

ts
import { smartAccountClient as modularAccountClient } from "./smartAccountClient";
import { type Address } from "viem";
import { IPluginAbi, accountLoupeActions } from "@alchemy/aa-accounts";


// extend smart account client with accountLoupeActions to call AccountLoupe methods
const accountLoupeActionsExtendedClient =
  modularAccountClient.extend(accountLoupeActions);

// returns addresses of all installed plugins
const installedPlugins =
  await accountLoupeActionsExtendedClient.getInstalledPlugins({});

if (installedPlugins.length === 0) {
  console.log("account has no plugins installed.");
  return;
}

const pluginAddress: Address = installedPlugins[0] as Address;
// read plugin metadata of a plugin
const metadata = await accountLoupeActionsExtendedClient.readContract({
  address: pluginAddress,
  abi: IPluginAbi,
  functionName: "pluginMetadata",
});

console.log(JSON.stringify(metadata, null, 2));
// {
//   name: 'MultiOwnerPlugin',
//   version: '1.0.0',
// }
ts
import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy";
import { LocalAccountSigner, sepolia } from "@alchemy/aa-core";

export const chain = sepolia;

export const smartAccountClient = await createModularAccountAlchemyClient({
  apiKey: "YOUR_API_KEY",
  chain,
  // you can swap this out for any SmartAccountSigner
  signer: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"),
});

By checking if a certain plugin address exists in the list of installed plugin addresses of a Modular Account, you can check whether a particular plugin is installed or not on a Modular Account.