Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ export const walletClient = createWalletClient({

With a MetaMask smart account, you can perform the following functions:

- In conjunction with [Viem Account Abstraction clients](../configure.md), deploy the smart account
- In conjunction with [Viem Account Abstraction clients](../configure.md), [deploy the smart account](deploy-smart-account.md)
and [send user operations](send-user-operation.md).
- [Create delegations](../delegation/execute-on-smart-accounts-behalf.md) that can be used to grant specific rights and permissions to other accounts.
Smart accounts that create delegations are called *delegator accounts*.
160 changes: 160 additions & 0 deletions delegation-toolkit/guides/smart-accounts/deploy-smart-account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
description: Learn how to deploy a MetaMask smart account.
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Deploy a smart account

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

## Prerequisites

- [Install and set up the Delegation Toolkit.](../../get-started/install.md)
- [Configure the Delegation Toolkit.](../configure.md)
- [Create a MetaMask smart account.](create-smart-account.md)

## Deploy with the first user operation

When you send the first user operation from a smart account, the Delegation Toolkit checks whether the account is already deployed. If the account
is not deployed, the toolkit adds the `initCode` to the user operation to deploy the account within the
same operation. Internally, the `initCode` is encoded using the `factory` and `factoryData`.

<Tabs>
<TabItem value="example.ts">

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

</TabItem>

<TabItem value="config.ts">

```typescript
import { createPublicClient, http } from "viem";
import { createBundlerClient } from "viem/account-abstraction";
import { sepolia as chain } from "viem/chains";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import {
Implementation,
toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";


const publicClient = createPublicClient({
chain,
transport: http()
});

const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);

export const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Hybrid,
deployParams: [account.address, [], [], []],
deploySalt: "0x",
signatory: { account },
});

export const bundlerClient = createBundlerClient({
client: publicClient,
transport: http("https://public.pimlico.io/v2/11155111/rpc")
});
```

</TabItem>
</Tabs>

## Deploy manually

To deploy a smart account manually, call the [`getFactoryArgs`](../../reference/api/smart-account.md#getfactoryargs)
method from the smart account 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.

<Tabs>
<TabItem value="example.ts">

```typescript
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,
})
```

</TabItem>

<TabItem value="config.ts">

```typescript
import { createPublicClient, createWalletClient, http } from "viem";
import { sepolia as chain } from "viem/chains";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import {
Implementation,
toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";


const publicClient = createPublicClient({
chain,
transport: http()
});

const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);

export const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Hybrid,
deployParams: [account.address, [], [], []],
deploySalt: "0x",
signatory: { account },
});

const relayAccountPrivateKey = "0x121..";
const relayAccount = privateKeyToAccount(relayAccountPrivateKey)

export const walletClient = createWalletClient({
account: relayAccount,
chain,
transport: http()
})
```

</TabItem>
</Tabs>

## Next steps

- Learn more about [sending user operations](send-user-operation.md).
- To sponsor gas for end users, see how to [send a gasless transaction](send-gasless-transaction.md).
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const smartAccount = await toMetaMaskSmartAccount({

export const bundlerClient = createBundlerClient({
client: publicClient,
transport: http("https://public.pimlico.io/v2/1/rpc")
transport: http("https://public.pimlico.io/v2/11155111/rpc")
});
```

Expand Down
1 change: 1 addition & 0 deletions gator-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const sidebar = {
collapsed: false,
items: [
'guides/smart-accounts/create-smart-account',
'guides/smart-accounts/deploy-smart-account',
'guides/smart-accounts/send-user-operation',
'guides/smart-accounts/send-gasless-transaction',
'guides/smart-accounts/generate-multisig-signature',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const smartAccount = await toMetaMaskSmartAccount({

export const bundlerClient = createBundlerClient({
publicClient,
transport: http("https://public.pimlico.io/v2/1/rpc")
transport: http("https://public.pimlico.io/v2/59141/rpc")
});
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const smartAccount = await toMetaMaskSmartAccount({

export const bundlerClient = createBundlerClient({
publicClient,
transport: http("https://public.pimlico.io/v2/1/rpc")
transport: http("https://public.pimlico.io/v2/59141/rpc")
});
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const smartAccount = await toMetaMaskSmartAccount({

export const bundlerClient = createBundlerClient({
client: publicClient,
transport: http("https://public.pimlico.io/v2/1/rpc")
transport: http("https://public.pimlico.io/v2/59141/rpc")
});
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const smartAccount = await toMetaMaskSmartAccount({

export const bundlerClient = createBundlerClient({
client: publicClient,
transport: http("https://public.pimlico.io/v2/1/rpc")
transport: http("https://public.pimlico.io/v2/11155111/rpc")
});
```

Expand Down
Loading