Skip to main content

Deploy a smart account

You can deploy MetaMask Smart Accounts in two different ways. You can either deploy the smart account automatically when sending the first user operation, or use a manual approach.

Prerequisites

Sending first user operation

Whenever you send the first user operation, it checks whether the smart account is already deployed. If the account is not deployed, the initCode is added to the user operation to ensure the smart account is deployed within the same operation. Internally, the initCode is encoded using the factory and factory data.

import { bundlerClient, smartAccount } from "./config.ts";
import { parseEther } from "viem";

// Appropriate fee per gas must be determined for the specific bundler being used.
const maxFeePerGas = 1n;
const maxPriorityFeePerGas = 1n;

const userOperationHash = await bundlerClient.sendUserOperation({
account: smartAccount,
calls: [
{
to: "0x1234567890123456789012345678901234567890",
value: parseEther("1")
}
],
maxFeePerGas,
maxPriorityFeePerGas
});

Manual approach

To use the manual approach, you can call the MetaMask Smart Account getFactoryArgs method to retrieve the factory and factoryData. This allows you to use a relay account to sponsor the deployment without needing a paymaster.

The factory represents the contract address responsible for deploying the smart account, while factoryData contains the calldata that will be executed by the factory to deploy the smart account.

The relay account can be either an externally owned account (EOA) or another smart account. This example uses an EOA.

import { walletClient, smartAccount } from "./config.ts";

const { factory, factoryData } = await smartAccount.getFactoryArgs();

// Deploy smart account using relay account.
const hash = await walletClient.sendTransaction({
to: factory,
data: factoryData,
})

Next steps