Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 2 additions & 2 deletions docs/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ navigation:
contents:
- page: Overview
path: wallets/pages/transactions/overview.mdx
- page: Set up client
path: wallets/pages/concepts/smart-account-client.mdx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imo we should leave this at the bottom - the setup provided in all of the other examples is more direct and gets the job done, I'd rather people view those first. This doc goes deeper into client config, which is likely a follow-up action after getting it to work at all.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Would you rename this to something like Congifure client then? My concern was that we throw people into example and they have to look at the client.ts file and use it but dont actually know what it is

- page: Send transactions
path: wallets/pages/transactions/send-transactions/index.mdx
- page: Using EIP-7702
Expand Down Expand Up @@ -1140,8 +1142,6 @@ navigation:
- page: Types
slug: resources/types
path: wallets/pages/resources/types.mdx
- page: Smart Account Client
path: wallets/pages/concepts/smart-account-client.mdx
- page: Middleware
path: wallets/pages/concepts/middleware.mdx
- section: Smart Account Types
Expand Down
146 changes: 124 additions & 22 deletions docs/pages/concepts/smart-account-client.mdx
Original file line number Diff line number Diff line change
@@ -1,35 +1,134 @@
---
title: Smart Account Client
description: What is the Smart Account Client?
title: Set up client
description: Set up client
slug: wallets/concepts/smart-account-client
---

The [`SmartAccountClient`](https://github.com/alchemyplatform/aa-sdk/blob/main/aa-sdk/core/src/account/smartContractAccount.ts#L102-L128) is an extension of `viem`'s [Client](https://viem.sh/docs/clients/custom#build-your-own-client) which allows you to interact
with [Smart Contract Accounts](/wallets/concepts/smart-contract-account). You can use the Smart Account Client to send User Operations, sign messages with your account, sponsor gas,
and other account-related actions.
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.

The client is also EIP-1193 compliant, meaning it can easily be swapped out in place of other web3 providers (eg. `window.ethereum`).
## How It Works

## Account hoisting
The [`SmartWalletClient`](https://github.com/alchemyplatform/aa-sdk/blob/b8dad097dc537985334efe0c1cc2af4e79dc0050/account-kit/wallet-client/src/client/index.ts#L34) is a EIP-1193 compatible extension of `viem`'s [Client](https://viem.sh/docs/clients/custom#build-your-own-client) which allows you to interact with smart wallets.

## Prerequisites

- [API key](https://dashboard.alchemy.com/apps)
- [Smart wallets installed and configured in your project](/wallets/pages/react/setup)
- (Optional) [A gas policyID](https://dashboard.alchemy.com/gas-manager/policy/create)

## Implementation

<Tabs>
<Tab title="React">
<Info>
[Set up your environment](/wallets/react/quickstart/existing-project) and app integration before using the client. React hooks only support Alchemy Signer.
</Info>
The [`useSmartAccountClient`](/wallets/reference/account-kit/react/hooks/useSmartAccountClient) hook will use the API key and policy ID settings passed to [`createConfig`](/wallets/react/quickstart/ui-customization).
```tsx twoslash
import React from "react";
import { useSmartAccountClient } from "@account-kit/react";

const { client } = useSmartAccountClient({});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want this to be the "client" that the end-user is using, we want it to either be wrapped in a specific action like the useSendCalls hook, or wrapped in the useSmartWalletClient hook. If we end the guide here, they will likely assune this client is what they should use, and try to call .sendUserOperation or similar.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay. Then what would you suggest we use as the example for react and react native? No client example?

I don't rlly know what the recommendation is for this case i guess

```

</Tab>
<Tab title="React Native">
<Info>
[Set up your environment](/wallets/react-native/getting-started/app-integration) and app integration before using the client. React hooks only support Alchemy Signer.
</Info>
The [`useSmartAccountClient`](/wallets/reference/account-kit/react/hooks/useSmartAccountClient) hook will use the API key and policy ID settings passed to [`createConfig`](/wallets/react/quickstart/ui-customization).
```tsx twoslash
import React from "react";
import { useSmartAccountClient } from "@account-kit/react";

const { client } = useSmartAccountClient({});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here as above

```

</Tab>
<Tab title="Javascript">
Use the [`createSmartWalletClient`](/wallets/reference/account-kit/wallet-client/functions/createSmartWalletClient) function to create a smart wallet client. Replace the API key and policy ID with your own. Additionally, replace the signer with the signer generated during [authentication](/wallets/authentication/login-methods/email-otp#step-4-check-authentication-status).

```ts title="client.ts"

import { LocalAccountSigner } from "@aa-sdk/core";
import { alchemy, sepolia } from "@account-kit/infra";
import {
createSmartWalletClient,
type SmartWalletClientParams,
} from "@account-kit/wallet-client";

const clientParams: SmartWalletClientParams = {
transport: alchemy({ apiKey: "your-alchemy-api-key"}),
chain: sepolia,
signer: LocalAccountSigner.privateKeyToAccountSigner(
"0x-your-wallet-private-key",
),
policyId: "your-policy-id",
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing indentation here, looks funny in the preview.


const clientWithoutAccount = createSmartWalletClient(clientParams);

const account = await clientWithoutAccount.requestAccount();

export const client = createSmartWalletClient({
...clientParams,
account: account.address,
});
```
</Tab>
<Tab title="API">
When using wallet [APIs](/wallets/smart-wallet-quickstart/api), you don't need to define a client. You can start sending request with APIs directly.
</Tab>
</Tabs>

## Advanced

<Accordion title="Configuration options">
Adjust client settings by specifying additional parameters to change account type, add gas sponsorship, etc. These parameters are optional.

**Account type**

By default, the Smart Wallet Client will use [ModularAccountV2](/wallets/smart-contracts/modular-account-v2/overview). 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](/wallets/smart-contracts/choosing-a-smart-account).

- **`type`** (string) - Defines the smart account type. Options:
- `"ModularAccountV2"` (recommended and default)
- `"LightAccount"`
- `"MultiOwnerLightAccount"`
- `"MultiOwnerModularAccount"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove MultiOwnerModularAccount from the list here


<Tip>
If you're using the [React](/wallets/react/quickstart) or
[Core](/wallets/core/overview) packages, the Smart Account Clients already
handle hoisting and creation of account instances. The [Smart
Contracts](/wallets/smart-contracts/choosing-a-smart-account) package exports
client definitions for hoisted instances of the Smart Contract Accounts.
Note: 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](/wallets/smart-contracts/other-accounts/modular-account/upgrading-to-modular-account).
</Tip>

When creating a Smart Account Client, you have two options:
**Using 7702**

1. You can pass an account instance directly into the client constructor. Doing so will use that account for all of the actions you perform with the client, and you won't have to
pass in the account each time you call a method. This is known as **"account hoisting"**.
2. You can create a client without passing in an account. As a result, you'll have to pass in an account instance to each method you call on the client. This is really useful if you
want to manage multiple instances of an account in your app, and want to use one client for all of them.
To use EIP-7702, pass `"7702"`" to the `mode` in `accountParams`. This will delegate the connected EOA to a smart account. Read more [here](/wallets/transactions/using-eip-7702).

Let's see an example:
**Advanced options**
| Usage | Parameter | Type |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Smart contract account implementation | `type` | One of `"ModularAccountV2"`, `"LightAccount"`, `"MultiOwnerLightAccount"`, `"MultiOwnerModularAccount"` |
| Sponsor gas for users. Get your policy ID [here](https://dashboard.alchemy.com/gas-manager) | `policyId` | `string` |
| Simulate user operations before sending (i.e. use [`alchemyUserOperationSimulator`](/wallets/reference/account-kit/infra/functions/alchemyUserOperationSimulator)) | `useSimulation` | `boolean` |
| Custom middleware to run before requesting sponsorship | `customMiddleware` | `ClientMiddlewareFn` |
| Override fee estimation middleware (if you are using our RPCs, it's important to use the default [`alchemyFeeEstimator`](/wallets/reference/account-kit/infra/functions/alchemyFeeEstimator)) | `feeEstimator` | `ClientMiddlewareFn` |
| Override gas estimation middleware (the default middleware calls the underlying bundler RPC to `eth_estimateUserOperationGas`) | `gasEstimator` | `ClientMiddlewareFn` |
| Override middleware that signs user operation(s) | `signUserOperation` | `ClientMiddlewareFn` |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any of these are valid options - they won't change the behavior of the resulting SmartWalletClient.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And actually, these aren't valid options to pass to the JS client at all

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh really? we used to have these documented - when did that change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the advanced account params still valid like passing 7702?

| Advanced account params | `accountParams` | `AccountConfig` with the following fields: <ul><li>`mode`: `"default"` \| `"7702"`</li><li>`entryPoint`: `EntryPointDef`</li><li>`signerEntity`: `SignerEntity`</li><li>`salt`: `bigint`</li><li>`factoryAddress`: `Address`</li><li>`initCode`: `Hex`</li><li>`accountAddress`: `Address`</li></ul> |

```ts twoslash
</Accordion>
<Accordion title="Smart account client actions">
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](https://github.com/alchemyplatform/aa-sdk/tree/v4.x.x/aa-sdk/core/src/actions/smartAccount) by default. You can find additional details about these actions in the [`@aa-sdk/core` documentation](/wallets/reference/aa-sdk/core).
</Accordion>
<Accordion title="Account agnostic client">
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.

```ts
import {
createAlchemySmartAccountClient,
sepolia,
Expand Down Expand Up @@ -72,7 +171,10 @@ const signature2 = await nonHoistedClient.signMessage({
});
```

## Smart Account Client actions
</Accordion>

## Next Steps

Because the Smart Account Clients are extensions of viem's clients, they support extensions via the `.extend` method. The base client already includes a [number of actions](https://github.com/alchemyplatform/aa-sdk/tree/v4.x.x/aa-sdk/core/src/actions/smartAccount) by default.
You can find additional details about these actions in the [`@aa-sdk/core` documentation](/wallets/reference/aa-sdk/core).
- [Send transactions](/wallets/transactions/send/evm-user-ops)
- [Sponsor gas](/wallets/transactions/sponsor-gas/sponsor-gas-evm)
- [Batch transactions](wallets/transactions/send/batch-user-ops)
Loading