Configure client

A smart wallet client is the main interface used to interact with smart wallets and take actions like sending transactions, batching transactions, swapping, sponsoring gas, and more.

How It Works

The SmartWalletClient is a EIP-1193 compatible extension of viem’s Client which allows you to interact with smart wallets.

Prerequisites

Implementation

The useSmartAccountClient hook provides access to your smart account client using the API key and policy ID settings from [createConfig]/docs/wallets/react/quickstart/ui-customization).

React hooks only support Alchemy Signer, so ensure you set up your environment and app integration before using the client.

Don’t call methods like client.sendUserOperation() directly on the client. Instead, use React hooks like useSendCalls which provide better state management and error handling.

1import React from "react";
2import { useSmartAccountClient, useSendCalls } from "@account-kit/react";
3
4const { client } = useSmartAccountClient({});
5
6const { sendCalls, isSendingCalls, sendCallsResult } = useSendCalls({
7 client,
8});

Advanced

By default, the Smart Wallet Client will use ModularAccountV2(MAv2). This is the cheapest and most advanced Smart Account, but you can specify other smart contract account types as needed. Learn more about the different smart accounts here.

Changing the account type will deploy a different account. If you’ve already deployed an account for a user and want to change the underlying account type, you’ll need to upgrade it. Learn how to upgrade here.

React and React Native

Override the default account type using the type parameter:

  • type (string) - Defines the smart account type. Options:
    • "ModularAccountV2" (recommended and default)
    • "LightAccount"
    • "MultiOwnerLightAccount"
1import React from "react";
2import { useSmartAccountClient } from "@account-kit/react";
3
4const { client } = useSmartAccountClient({
5 type: "LightAccount",
6});

Javascript

Specify the account type when calling requestAccount using the creationHint parameter. See all parameter options.

const account = await clientWithoutAccount.requestAccount(
creationHint: {
accountType: "sma-b"
},
);
export const client = createSmartWalletClient({
...clientParams,
account: account.address,
});

API

Pass an accountType to creationHint when calling wallet_requestAccount.

Using 7702

To use EIP-7702, please see this guide. You’ll need to set additional parameters on the client.

By default, account addresses are deterministically generated from the signer address. To connect to an existing account that doesn’t match the deterministic address of your signer, specify the account address when creating the client.

React & React Native

1import React from "react";
2import { useSmartAccountClient } from "@account-kit/react";
3
4const { client } = useSmartAccountClient({
5 accountAddress: "0xYOUR_SMART_ACCOUNT_ADDR",
6});

Javascript

Pass the address to the createSmartWalletClient directly rather than calling requestAccount.

export const client = createSmartWalletClient({
...clientParams,
account: "0xYOUR_SMART_ACCOUNT_ADDR",
});

API

Pass the account address directly when preparing calls instead of calling wallet_requestAccount. See this guide and skip step 2.

Because the Smart Wallet Clients are extensions of viem’s clients, they support extensions via the .extend method. The base client already includes a number of actions by default. You can find additional details about these actions in the @aa-sdk/core documentation.

Typically, the smart account client uses the default account or the account passed into the client constructor for all of the actions you perform with the client - also known as account hositing.

If you want to manage multiple instances of an account but want to use one client for all of them, you can pass an account to the client on every action.

1import {
2 createAlchemySmartAccountClient,
3 sepolia,
4 alchemy,
5} from "@account-kit/infra";
6import { createLightAccount } from "@account-kit/smart-contracts";
7import { LocalAccountSigner } from "@aa-sdk/core";
8import { http } from "viem";
9import { generatePrivateKey } from "viem/accounts";
10
11// with account hoisting
12const transport = alchemy({ apiKey: "your-api-key" });
13const hoistedClient = createAlchemySmartAccountClient({
14 transport,
15 chain: sepolia,
16 account: await createLightAccount({
17 signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),
18 chain: sepolia,
19 transport,
20 }),
21});
22
23const signature = await hoistedClient.signMessage({ message: "Hello world! " });
24
25// without account hoisting
26const nonHoistedClient = createAlchemySmartAccountClient({
27 transport,
28 chain: sepolia,
29});
30
31const lightAccount = await createLightAccount({
32 signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),
33 chain: sepolia,
34 transport,
35});
36
37const signature2 = await nonHoistedClient.signMessage({
38 message: "Hello world! ",
39 account: lightAccount,
40});

Next Steps