# Modular Account V2 • Getting started

> Getting started with Modular Account V2 in Wallet APIs

> For the complete documentation index, see [llms.txt](/docs/llms.txt).

Getting started with Modular Account V2 is straightforward. Below, you'll create a Modular Account V2 from a signer and send a transaction through viem's bundler client. Your MAv2 deploys onchain on the first user operation.

<Tip title="Most projects should use @alchemy/wallet-apis">
  [`@alchemy/wallet-apis`](/docs/wallets/quickstart) already uses Modular Account V2 as its default smart account — `createSmartWalletClient` gives you MAv2 plus account creation, gas estimation, and the bundler client behind a single call. This page covers the lower-level path: instantiating MAv2 directly from `@alchemy/smart-accounts` and pairing it with viem's bundler client. Use it when you need lower-level control over custom wiring.
</Tip>

## Install packages

**Prerequisites**

* minimum Typescript version of 5

**Installation**

<CodeBlocks>
  ```bash yarn
  yarn add @alchemy/smart-accounts @alchemy/aa-infra viem
  ```

  ```bash npm
  npm install @alchemy/smart-accounts @alchemy/aa-infra viem
  ```
</CodeBlocks>

<Tip title="Address calculation">
  For Modular Account V2, the address is derived from the owner and an optional `salt` (default `0n`). Same owner + same salt → same address. Pass `accountAddress` to connect to an existing account whose contract-derived address doesn't match the signer (e.g. the original owner is no longer in your control).
</Tip>

## Create a Modular Account V2

```ts twoslash modular-account-v2.ts
import { createClient } from "viem";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { sepolia } from "viem/chains";
import { alchemyTransport } from "@alchemy/common";
import { toModularAccountV2 } from "@alchemy/smart-accounts";

const ALCHEMY_API_KEY = "your-api-key"; // https://dashboard.alchemy.com/apps
const transport = alchemyTransport({ apiKey: ALCHEMY_API_KEY });

const rpcClient = createClient({ chain: sepolia, transport });

const account = await toModularAccountV2({
  client: rpcClient,
  owner: privateKeyToAccount(generatePrivateKey()),
  // mode: "7702", // optional — defaults to "default"
});
```

**Choosing which mode to use**
Two variants of Modular Account V2 are available: `default` and `7702`.

* (Recommended) `default` provides the cheapest, most flexible smart wallet.
* `7702` if you want EIP-7702 support — see the [EIP-7702 guide](/docs/wallets/transactions/using-eip-7702).

## Sending a transaction

Pair the account with viem's bundler client (and `@alchemy/aa-infra`'s fee estimator) to submit user operations.

```ts twoslash
import { createBundlerClient } from "viem/account-abstraction";
import { createClient, parseEther } from "viem";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { sepolia } from "viem/chains";
import { alchemyTransport } from "@alchemy/common";
import { toModularAccountV2 } 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 toModularAccountV2({
  client: rpcClient,
  owner: privateKeyToAccount(generatePrivateKey()),
});

const bundlerClient = createBundlerClient({
  account,
  client: rpcClient,
  chain: sepolia,
  transport,
  userOperation: { estimateFeesPerGas },
});

const hash = await bundlerClient.sendUserOperation({
  calls: [{
    to: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", // vitalik
    data: "0x",
    value: parseEther("0"),
  }],
});

console.log("UO hash:", hash, "\nMAv2 address:", account.address);
```