Success!
\\n You're logged in as {user.email ?? \\\"anon\\\"}.\\ndiff --git a/.eslintignore b/.eslintignore
index 84abbe65e5..6f5f781891 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -6,4 +6,6 @@ site/.vitepress/cache/**/*
/examples/*
!/examples/ui-demo
-/examples/ui-demo/.next/*
\ No newline at end of file
+/examples/ui-demo/.next/*
+
+**/.turbo/*
\ No newline at end of file
diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml
index 22e0468d67..5163d684bf 100644
--- a/.github/actions/setup-node/action.yml
+++ b/.github/actions/setup-node/action.yml
@@ -17,15 +17,4 @@ runs:
- name: Install dependencies
run: yarn install --frozen-lockfile
- shell: bash
-
- - name: Cache Nx and Node modules
- id: cache-nx
- uses: actions/cache@v3
- with:
- path: |
- .nx
- node_modules/.cache/nx
- key: ${{ runner.os }}-nx-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-nx-
\ No newline at end of file
+ shell: bash
\ No newline at end of file
diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml
index ba0e62ac34..388e522ea9 100644
--- a/.github/workflows/on-pull-request.yml
+++ b/.github/workflows/on-pull-request.yml
@@ -26,6 +26,8 @@ jobs:
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.ALCHEMY_BOT_PAT }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
+ TURBO_TEAM: ${{ vars.TURBO_TEAM }}
steps:
- uses: actions/checkout@v3
with:
@@ -55,6 +57,8 @@ jobs:
runs-on: ubuntu-latest
env:
API_KEY: ${{ secrets.API_KEY }}
+ TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
+ TURBO_TEAM: ${{ vars.TURBO_TEAM }}
steps:
- uses: actions/checkout@v3
with:
@@ -83,14 +87,9 @@ jobs:
uses: ./.github/actions/setup-node
- name: Build
- uses: nick-fields/retry@v3
env:
API_KEY: ${{ secrets.API_KEY }}
- with:
- timeout_minutes: 5
- max_attempts: 2
- # it's ok to run the dev build here because the site gets built in vercel for each branch
- command: yarn build:dev
+ run: yarn build:dev
- name: Unit Test
run: yarn test:ci
diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml
index 78ee2b8651..9e549e2abe 100644
--- a/.github/workflows/publish-package.yml
+++ b/.github/workflows/publish-package.yml
@@ -28,6 +28,9 @@ jobs:
build_and_test_deploy:
name: Build and Publish
runs-on: ubuntu-latest
+ env:
+ TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
+ TURBO_TEAM: ${{ vars.TURBO_TEAM }}
# Needed for Publishing
permissions:
diff --git a/.gitignore b/.gitignore
index f7bbce8848..d373a4e5db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,7 @@ site/**/*.js
vocs.config.tsx.timestamp-*.mjs
bin
+**/.turbo
+
+# Turborepo
+.turbo
diff --git a/README.md b/README.md
index afa342b1f5..b459bc6258 100644
--- a/README.md
+++ b/README.md
@@ -33,4 +33,12 @@ Check out this [quickstart guide](https://accountkit.alchemy.com/react/quickstar
## Contributing
+If you are a member of the Alchemy team, make sure to run:
+
+```
+npx turbo login --sso-team=alchemy-dot-com
+```
+
+so that you can benefit from remote caching in your builds!
+
We welcome contributions to `aa-sdk`. Please see our [contributing guidelines](CONTRIBUTING.md) for more information.
diff --git a/examples/embedded-accounts-quickstart b/examples/embedded-accounts-quickstart
index e4d61eb57c..63d936ebe9 160000
--- a/examples/embedded-accounts-quickstart
+++ b/examples/embedded-accounts-quickstart
@@ -1 +1 @@
-Subproject commit e4d61eb57c094b0c566dfe8570fe04e11365e260
+Subproject commit 63d936ebe94c65e5a12e41805bee1a5e9a29ed96
diff --git a/examples/ui-demo/next.config.mjs b/examples/ui-demo/next.config.mjs
index 2831a15913..82bcc683e0 100644
--- a/examples/ui-demo/next.config.mjs
+++ b/examples/ui-demo/next.config.mjs
@@ -13,6 +13,9 @@ const nextConfig = {
},
],
},
+ eslint: {
+ ignoreDuringBuilds: true,
+ },
webpack: (config) => {
config.externals.push("pino-pretty", "lokijs", "encoding");
return config;
diff --git a/package.json b/package.json
index 19f1e7bdc2..60c2914952 100644
--- a/package.json
+++ b/package.json
@@ -22,20 +22,19 @@
"viem": "2.20.0"
},
"scripts": {
- "generate": "lerna run generate",
+ "generate": "turbo run generate",
"postgenerate": "yarn lint:write",
"preinstall": "yarn config set ignore-engines true",
"postinstall": "git submodule update --init --recursive && patch-package",
"build": "is-ci && yarn build:ci || yarn build:dev",
- "build:base": "lerna run build --verbose --ignore=alchemy-daapp --ignore=embedded-accounts-quickstart --ignore=aa-simple-dapp --ignore=ui-demo",
- "build:dev": "yarn build:base --ignore=docs",
+ "build:base": "turbo run build --filter=!embedded-accounts-quickstart --filter=!ui-demo",
+ "build:dev": "yarn build:base --filter=!docs",
"build:ci": "yarn build:base && yarn lint:write",
- "build:examples": "lerna run build",
- "clean": "yarn clean:nx && yarn clean:lerna && yarn clean:node_modules",
- "clean:nx": "nx reset",
- "clean:lerna": "lerna run clean",
- "clean:node_modules": "lerna clean && rm -rf node_modules",
- "docs:gen": "lerna run docs:gen",
+ "build:examples": "turbo run build",
+ "clean": "yarn clean:turbo && yarn clean:node_modules",
+ "clean:turbo": "turbo run clean",
+ "clean:node_modules": "lerna clean -y && rm -rf node_modules",
+ "docs:gen": "turbo run docs:gen",
"test": "vitest dev",
"test:ci": "vitest run",
"lint:write": "eslint . --fix && yarn docs:gen && prettier --write --ignore-unknown .",
@@ -64,11 +63,11 @@
"lerna": "^8.0.2",
"lint-staged": "^13.2.2",
"node-fetch": "^3.3.1",
- "nx": "^17.3.0",
"patch-package": "^8.0.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.8.8",
"prool": "^0.0.15",
+ "turbo": "^2.2.3",
"viem": "2.20.0",
"vitest": "^2.0.4",
"wagmi": "2.12.7",
diff --git a/patches/vocs+1.0.0-alpha.55.patch b/patches/vocs+1.0.0-alpha.55.patch
deleted file mode 100644
index 79e3854f57..0000000000
--- a/patches/vocs+1.0.0-alpha.55.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-diff --git a/node_modules/vocs/_lib/app/components/Sidebar.js b/node_modules/vocs/_lib/app/components/Sidebar.js
-index ab059f9..8592615 100644
---- a/node_modules/vocs/_lib/app/components/Sidebar.js
-+++ b/node_modules/vocs/_lib/app/components/Sidebar.js
-@@ -48,7 +48,7 @@ function getSidebarGroups(sidebar) {
- }
- function getActiveChildItem(items, pathname) {
- return items.find((item) => {
-- if (matchPath(pathname, item.link ?? ''))
-+ if (matchPath(pathname, item.link ?? '') && pathname !== '/')
- return true;
- if (item.link === pathname)
- return true;
-@@ -64,7 +64,7 @@ function SidebarItem(props) {
- const match = useMatch(item.link ?? '');
- const hasActiveChildItem = useMemo(() => (item.items ? Boolean(getActiveChildItem(item.items, pathname)) : false), [item.items, pathname]);
- const [collapsed, setCollapsed] = useState(() => {
-- if (match)
-+ if (match && pathname !== '/')
- return false;
- if (!item.items)
- return false;
-diff --git a/node_modules/vocs/_lib/vite/.vocs/cache/search.json b/node_modules/vocs/_lib/vite/.vocs/cache/search.json
-new file mode 100644
-index 0000000..b58e0ab
---- /dev/null
-+++ b/node_modules/vocs/_lib/vite/.vocs/cache/search.json
-@@ -0,0 +1 @@
-+"[[\"index.21a47c7927b151b016efbb50a9c6fc78c2f5415b3ef7bbe5e6d55e15bfbf4d78\",{\"mdx\":\"---\\ntitle: TODO\\ndescription: TODO\\n---\\n\\nTODO\\n\",\"document\":[]}],[\"index.1012e2991419027dacc3631d42fc7c2686578aaf499d77eaa67e5efe1891c048\",{\"mdx\":\"---\\ntitle: Sponsor Gas\\ndescription: Learn how to sponsor gas using Alchemy's infrastructure\\n---\\n\\nimport CreateGasManagerPolicySnippet from \\\"../../shared/create-gas-policy.mdx\\\";\\n\\n# Sponsor Gas\\n\\nIn the [Quickstart](/infra/quickstart), we covered an example that sends a user operation with gas sponsorship using our Gas Manager. In this guide, we'll recap how to sponsor gas using the Gas Manager, and also show you\\nhow to use other paymaster providers as well.\\n\\n## Sponsor Gas with Gas Manager\\n\\n### 1. Create gas policy\\n\\n
The SmartAccountClient
is an extension of viem
's Client which allows you to interact\\nwith Smart Contract Accounts. You can use the Smart Account Client to send User Operations, sign messages with your account, sponsor gas,\\nand other account-related actions.
The client is also EIP-1193 compliant, meaning it can easily be swapped out in place of other web3 providers (eg. window.ethereum
).
When creating a Smart Account Client, you have two options:
\\nLet's see an example:
\\nimport { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\n// with account hoisting\\n \\nconst hoistedClient = createAlchemySmartAccountClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n account: await createLightAccount({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n transport: http(sepolia.rpcUrls.alchemy.http[0]),\\n }),\\n});\\n \\nconst signature = await hoistedClient.signMessage({ message: "Hello world! " });\\n \\n// without account hoisting\\nconst nonHoistedClient = createAlchemySmartAccountClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n});\\n \\nconst lightAccount = await createLightAccount({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n transport: http(sepolia.rpcUrls.alchemy.http[0]),\\n});\\n \\nconst signature2 = await nonHoistedClient.signMessage({\\n message: "Hello world! ",\\n account: lightAccount,\\n});
\\n\",\"id\":\"pages/concepts/smart-account-client.mdx#account-hoisting\",\"isPage\":false,\"text\":\"\\nIf you're using the React or Core packages, the Smart Account Clients already handle hoisting and creation of account instances.\\nThe Smart Contracts package exports client definitions for hoisted instances of the Smart Contract Accounts.\\nWhen creating a Smart Account Client, you have two options:\\n\\nYou 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\\npass in the account each time you call a method. This is known as "account hoisting".\\nYou 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\\nwant to manage multiple instances of an account in your app, and want to use one client for all of them.\\n\\nLet's see an example:\\nimport { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\n// with account hoisting\\n \\nconst hoistedClient = createAlchemySmartAccountClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n account: await createLightAccount({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n transport: http(sepolia.rpcUrls.alchemy.http[0]),\\n }),\\n});\\n \\nconst signature = await hoistedClient.signMessage({ message: "Hello world! " });\\n \\n// without account hoisting\\nconst nonHoistedClient = createAlchemySmartAccountClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n});\\n \\nconst lightAccount = await createLightAccount({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n transport: http(sepolia.rpcUrls.alchemy.http[0]),\\n});\\n \\nconst signature2 = await nonHoistedClient.signMessage({\\n message: "Hello world! ",\\n account: lightAccount,\\n});\\n\",\"title\":\"Account hoisting\",\"titles\":[\"Smart Account Client\"]},{\"href\":\"/concepts/smart-account-client#smart-account-client-actions\",\"html\":\"\\nBecause 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 by default.\\nYou can find additional details about these actions in the @aa-sdk/core
documentation.
Below are the steps to migrate your project from older versions of the aa-sdk
and account-kit
to the latest version.
This method has been removed. Use verifyMessage
from viem.
This method is no longer used internally and has been removed. The reference impl can be found within ethers.js
.
This method was not super efficient and maintainable because it was importing all the chains from viem. That meant that if you used this method, it risked increasing your bundle size massively. Now all methods require a Chain
instead of chainId
in some places.
Certain methods required a chainId
which would be converted into a Chain
using the above method. This has been removed for the reasons above.
The Alchemy Chain
definitions have been moved from @aa-sdk/core
to @account-kit/infra
.
This method on the AccountSigner
has been renamed.
If you were creating LightAccounts for users without explicitly specifying the version (ie. in createLightAccount
or useAccount
or useSmartAccountClient
), you should manually specify the previous default of v1.1.0
.
Previously, the create*Client
(ie. createLightAccountClient
) methods used to have an account
parameter which took in the params for the underlying account. This is resulted in different APIs for both the corresponding create*AlchemyClient
(ie. createLightAccountAlchemyClient
) which had these as top-level parameters.\\nIf you were using createLightAccountClient
or similar methods, you should now pass the account parameters as top-level parameters.
This version update brings a lot of breaking changes. As we began to support Modular Accounts and their interfaces, we realized that the previous version of the SDK was not as flexible as it could have been to handle the modularity of the new account interfaces.\\nTo address this, version 3.x.x of the SDK switches to an approach more idiomatic to viem
.
We have updated our dependency to viem v2.x.x. This means you will need to update your project to use >= v2.5.0 of viem.
\\n\",\"id\":\"pages/migration-guide.mdx#viem-version\",\"isPage\":false,\"text\":\"\\nWe have updated our dependency to viem v2.x.x. This means you will need to update your project to use >= v2.5.0 of viem.\\n\",\"title\":\"Viem Version\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\"]},{\"href\":\"/migration-guide#client-smartaccountprovider--smartaccountclient\",\"html\":\"\\nThe biggest change is that the SmartAccountProvider
class has been removed and replaced with a SmartAccountClient
type that extends viem
's Client
. To get started with the new clients, you can do the following:
import { SmartAccountProvider } from "@aa-sdk/core"; \\nimport { getDefaultEntryPointAddress } from "@aa-sdk/core"; \\nimport { http } from "viem"; \\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst provider = new SmartAccountProvider({ \\nconst client = createSmartAccountClient({ \\n rpcProvider: "RPC_URL", \\n transport: http("RPC_URL"), \\n chain: sepolia,\\n entryPointAddress: getDefaultEntryPointAddress(sepolia), \\n});
\\n\",\"id\":\"pages/migration-guide.mdx#client-smartaccountprovider--smartaccountclient\",\"isPage\":false,\"text\":\"\\nThe biggest change is that the SmartAccountProvider class has been removed and replaced with a SmartAccountClient type that extends viem's Client. To get started with the new clients, you can do the following:\\nimport { SmartAccountProvider } from "@aa-sdk/core"; \\nimport { getDefaultEntryPointAddress } from "@aa-sdk/core"; \\nimport { http } from "viem"; \\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst provider = new SmartAccountProvider({ \\nconst client = createSmartAccountClient({ \\n rpcProvider: "RPC_URL", \\n transport: http("RPC_URL"), \\n chain: sepolia,\\n entryPointAddress: getDefaultEntryPointAddress(sepolia), \\n});\\n\",\"title\":\"Client: SmartAccountProvider → SmartAccountClient\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\"]},{\"href\":\"/migration-guide#client-removal-of-with-middleware-override-functions\",\"html\":\"\\nThe SmartAccountProvider
in previous versions had a number of with*
functions that mapped to the corresponding middleware functions on the provider.\\nThe concept of the middlewares is still present in this version, but their configuration has been moved to the SmartAccountClient
creator. For example,
import { SmartAccountProvider } from "@aa-sdk/core"; \\nimport { getDefaultEntryPointAddress } from "@aa-sdk/core"; \\nimport { http } from "viem"; \\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst provider = new SmartAccountProvider({ \\nconst client = createSmartAccountClient({ \\n rpcProvider: "RPC_URL", \\n transport: http("RPC_URL"), \\n chain: sepolia,\\n entryPointAddress: getDefaultEntryPointAddress(sepolia), \\n}).withGasEstimator(async () => ({ \\n gasEstimator: async (struct) => ({ \\n ...struct, \\n callGasLimit: 0n,\\n preVerificationGas: 0n,\\n verificationGasLimit: 0n,\\n }), \\n});
\\n\",\"id\":\"pages/migration-guide.mdx#client-removal-of-with-middleware-override-functions\",\"isPage\":false,\"text\":\"\\nThe SmartAccountProvider in previous versions had a number of with* functions that mapped to the corresponding middleware functions on the provider.\\nThe concept of the middlewares is still present in this version, but their configuration has been moved to the SmartAccountClient creator. For example,\\nimport { SmartAccountProvider } from "@aa-sdk/core"; \\nimport { getDefaultEntryPointAddress } from "@aa-sdk/core"; \\nimport { http } from "viem"; \\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst provider = new SmartAccountProvider({ \\nconst client = createSmartAccountClient({ \\n rpcProvider: "RPC_URL", \\n transport: http("RPC_URL"), \\n chain: sepolia,\\n entryPointAddress: getDefaultEntryPointAddress(sepolia), \\n}).withGasEstimator(async () => ({ \\n gasEstimator: async (struct) => ({ \\n ...struct, \\n callGasLimit: 0n,\\n preVerificationGas: 0n,\\n verificationGasLimit: 0n,\\n }), \\n});\\n\",\"title\":\"Client: Removal of with* middleware override functions\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\"]},{\"href\":\"/migration-guide#client-signature-changes-on-methods\",\"html\":\"\\nTo support the various ways of connecting to a smart account, the signatures of the methods on SmartAccountClient
have changed. Almost all methods now have an optional param for account
and have been converted into single argument functions that take an object with the their properties instead.
The next big change is the removal of the class-based BaseSmartContractAccount
that all accounts extended from. This has been replaced with a SmartContractAccount
type that extends viem
's Account
, and instantiation of an account is now an async
action. To get started with the new accounts (using LightAccount
as an example), you will have to make the following changes:
import {\\n LightSmartContractAccount, \\n createLightAccount, \\n getDefaultLightAccountFactoryAddress, \\n} from "@account-kit/smart-contracts";\\nimport {\\n LocalAccountSigner,\\n type Hex,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst chain = sepolia;\\n \\nconst account = new LightSmartContractAccount({ \\nconst account = await createLightAccount({ \\n rpcClient: client, \\n transport: http("RPC_URL"), \\n signer,\\n chain,\\n factoryAddress: getDefaultLightAccountFactoryAddress(chain), \\n });
\\n\",\"id\":\"pages/migration-guide.mdx#account-basesmartcontractaccount--smartcontractaccount\",\"isPage\":false,\"text\":\"\\nThe next big change is the removal of the class-based BaseSmartContractAccount that all accounts extended from. This has been replaced with a SmartContractAccount type that extends viem's Account, and instantiation of an account is now an async action. To get started with the new accounts (using LightAccount as an example), you will have to make the following changes:\\nimport {\\n LightSmartContractAccount, \\n createLightAccount, \\n getDefaultLightAccountFactoryAddress, \\n} from "@account-kit/smart-contracts";\\nimport {\\n LocalAccountSigner,\\n type Hex,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst chain = sepolia;\\n \\nconst account = new LightSmartContractAccount({ \\nconst account = await createLightAccount({ \\n rpcClient: client, \\n transport: http("RPC_URL"), \\n signer,\\n chain,\\n factoryAddress: getDefaultLightAccountFactoryAddress(chain), \\n });\\n\",\"title\":\"Account: BaseSmartContractAccount → SmartContractAccount\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\"]},{\"href\":\"/migration-guide#account-connecting-to-a-smart-account\",\"html\":\"\\nIn earlier versions, a provider could not be used with a smart account until it was connected to one using .connect
. In version 3.x.x, you have the option of keeping the two disconnected and passing the account to the client methods directly. You also have the option to hoist the account\\nso that you don't have to pass the account to every method.
import { createLightAccount } from "@account-kit/smart-contracts";\\nimport {\\n createBundlerClient,\\n createSmartAccountClientFromExisting\\n LocalAccountSigner,\\n type Hex,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "@aa-sdk/core";\\nimport { custom, http } from "viem";\\n \\nconst chain = sepolia;\\n \\nconst client = createBundlerClient({\\n chain,\\n transport: http("JSON_RPC_URL"),\\n});\\n \\n\\n// createSmartAccountClientFromExisting is a helper method that allows you\\n// to reuse a JSON RPC client to create a Smart Account client.\\nconst smartAccountClient = createSmartAccountClientFromExisting({\\n client,\\n});\\n \\nconst account = await createLightAccount({\\n signer,\\n chain,\\n transport: custom(client),\\n});\\n \\nconst { hash } = await smartAccountClient.sendUserOperation({\\n uo: {\\n target: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",\\n data: "0x",\\n value: 10n,\\n },\\n account, \\n});
\\n\",\"id\":\"pages/migration-guide.mdx#option-1-passing-the-account-to-the-client-methods\",\"isPage\":false,\"text\":\"\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport {\\n createBundlerClient,\\n createSmartAccountClientFromExisting\\n LocalAccountSigner,\\n type Hex,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "@aa-sdk/core";\\nimport { custom, http } from "viem";\\n \\nconst chain = sepolia;\\n \\nconst client = createBundlerClient({\\n chain,\\n transport: http("JSON_RPC_URL"),\\n});\\n \\n\\n// createSmartAccountClientFromExisting is a helper method that allows you\\n// to reuse a JSON RPC client to create a Smart Account client.\\nconst smartAccountClient = createSmartAccountClientFromExisting({\\n client,\\n});\\n \\nconst account = await createLightAccount({\\n signer,\\n chain,\\n transport: custom(client),\\n});\\n \\nconst { hash } = await smartAccountClient.sendUserOperation({\\n uo: {\\n target: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",\\n data: "0x",\\n value: 10n,\\n },\\n account, \\n});\\n\",\"title\":\"Option 1: Passing the Account to the Client Methods\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\",\"Account: Connecting to a Smart Account\"]},{\"href\":\"/migration-guide#option-2-hoisting-the-account\",\"html\":\"\\nHoisting the account is similar to using .connect
in previous versions. You simply create your client with an account passed in to it.
import { createLightAccount } from "@account-kit/smart-contracts";\\nimport {\\n createBundlerClient,\\n createSmartAccountClientFromExisting\\n LocalAccountSigner,\\n type Hex,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "@aa-sdk/core";\\nimport { http, custom } from "viem";\\n \\nconst chain = sepolia;\\n \\nconst client = createBundlerClient({\\n chain,\\n transport: http("JSON_RPC_URL"),\\n});\\n \\n\\nconst account = await createLightAccount({\\n signer,\\n transport: custom(client),\\n chain,\\n});\\n \\nconst smartAccountClient = createSmartAccountClientFromExisting({\\n account, \\n client,\\n});\\n \\nconst { hash } = await smartAccountClient.sendUserOperation({\\n uo: {\\n target: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",\\n data: "0x",\\n value: 10n,\\n },\\n account, \\n});
\\n\",\"id\":\"pages/migration-guide.mdx#option-2-hoisting-the-account\",\"isPage\":false,\"text\":\"\\nHoisting the account is similar to using .connect in previous versions. You simply create your client with an account passed in to it.\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport {\\n createBundlerClient,\\n createSmartAccountClientFromExisting\\n LocalAccountSigner,\\n type Hex,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "@aa-sdk/core";\\nimport { http, custom } from "viem";\\n \\nconst chain = sepolia;\\n \\nconst client = createBundlerClient({\\n chain,\\n transport: http("JSON_RPC_URL"),\\n});\\n \\n\\nconst account = await createLightAccount({\\n signer,\\n transport: custom(client),\\n chain,\\n});\\n \\nconst smartAccountClient = createSmartAccountClientFromExisting({\\n account, \\n client,\\n});\\n \\nconst { hash } = await smartAccountClient.sendUserOperation({\\n uo: {\\n target: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",\\n data: "0x",\\n value: 10n,\\n },\\n account, \\n});\\n\",\"title\":\"Option 2: Hoisting the Account\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\",\"Account: Connecting to a Smart Account\"]},{\"href\":\"/migration-guide#account-custom-accounts\",\"html\":\"\\nIn prior versions, using your own smart contract account implementations required that you extend BaseSmartContractAccount
. In version 3.x.x, you can use the toSmartContractAccount
method which will allow you to use any account with SmartAccountClient
. toSmartContractAccount
has the form of:
type toSmartContractAccount = <\\n Name extends string = string,\\n TTransport extends Transport = Transport\\n>({\\n transport,\\n chain,\\n source,\\n entryPointAddress,\\n accountAddress,\\n getAccountInitCode,\\n signMessage,\\n signTypedData,\\n encodeBatchExecute,\\n encodeExecute,\\n getDummySignature,\\n signUserOperationHash,\\n encodeUpgradeToAndCall,\\n}: ToSmartContractAccountParams<Name, TTransport>) => Promise<\\n SmartContractAccount<Name>\\n>;
\\n\",\"id\":\"pages/migration-guide.mdx#account-custom-accounts\",\"isPage\":false,\"text\":\"\\nIn prior versions, using your own smart contract account implementations required that you extend BaseSmartContractAccount. In version 3.x.x, you can use the toSmartContractAccount method which will allow you to use any account with SmartAccountClient. toSmartContractAccount has the form of:\\ntype toSmartContractAccount = <\\n Name extends string = string,\\n TTransport extends Transport = Transport\\n>({\\n transport,\\n chain,\\n source,\\n entryPointAddress,\\n accountAddress,\\n getAccountInitCode,\\n signMessage,\\n signTypedData,\\n encodeBatchExecute,\\n encodeExecute,\\n getDummySignature,\\n signUserOperationHash,\\n encodeUpgradeToAndCall,\\n}: ToSmartContractAccountParams<Name, TTransport>) => Promise<\\n SmartContractAccount<Name>\\n>;\\n\",\"title\":\"Account: Custom Accounts\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\"]},{\"href\":\"/migration-guide#account-simpleaccount-and-naniaccount-initialization-params\",\"html\":\"\\nchain
and transport
have been added to the constructor and rpcClient
has been removed.
index
is now called salt
The signTypedData
method found on SmartAccountSigner
has been updated to match the signature found on SmartContractAccount
and viem's Account
.
(params: SignTypedDataParams) => Promise<Hex>; \\n \\n<\\n const TTypedData extends TypedData | { [key: string]: unknown },\\n TPrimaryType extends string = string\\n>(\\n params: TypedDataDefinition<TTypedData, TPrimaryType>\\n) => Promise<Hex>;
\\n\",\"id\":\"pages/migration-guide.mdx#signer-signtypeddata-signature-change\",\"isPage\":false,\"text\":\"\\nThe signTypedData method found on SmartAccountSigner has been updated to match the signature found on SmartContractAccount and viem's Account.\\n(params: SignTypedDataParams) => Promise<Hex>; \\n \\n<\\n const TTypedData extends TypedData | { [key: string]: unknown },\\n TPrimaryType extends string = string\\n>(\\n params: TypedDataDefinition<TTypedData, TPrimaryType>\\n) => Promise<Hex>;\\n\",\"title\":\"Signer: signTypedData signature change\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\"]},{\"href\":\"/migration-guide#ethers-removed-methods\",\"html\":\"\\nThe with*
methods have been removed from the Provider and Signer classes.\\nThe connect
methods has been removed in favor of immutable properties on the Provider and Signer classes. See updated AccountSigner constructor below.
The getPublicErc4337Client
method has been renamed to getBundlerClient
to match the naming found in aa-core
.
The AccountSigner
now takes in a SmartContractAccount
as a param in its constructor.
The Percent
type and PercentSchema
have been removed in favor of the Multiplier
type and MultiplierSchema
.
Going forward when using the feeOptions, you can specify the Multiplier
type instead of a Percent
. The Multiplier
type is a number that represents direct multipliaction of the estimation. For example, 0.1
is 10% of the estimated value and 1
is 100% of the estimated value.
createModularAccountAlchemyClient({\\n ...\\n opts: {\\n ...\\n // The maxFeePerGas and maxPriorityFeePerGas estimated values will now be multipled by 1.5\\n feeOptions: {\\n // This was previously { percent: 50n }\\n maxFeePerGas: { multiplier: 1.5 },\\n // This was previously { percent: 25n }\\n maxPriorityFeePerGas: { multiplier: 1.25 },\\n },\\n },\\n });
\",\"id\":\"pages/migration-guide.mdx#core-transition-from-percent-to-multiplier-api-and-types\",\"isPage\":false,\"text\":\"\\nThe Percent type and PercentSchema have been removed in favor of the Multiplier type and MultiplierSchema.\\nGoing forward when using the feeOptions, you can specify the Multiplier type instead of a Percent. The Multiplier type is a number that represents direct multipliaction of the estimation. For example, 0.1 is 10% of the estimated value and 1 is 100% of the estimated value.\\ncreateModularAccountAlchemyClient({\\n ...\\n opts: {\\n ...\\n // The maxFeePerGas and maxPriorityFeePerGas estimated values will now be multipled by 1.5\\n feeOptions: {\\n // This was previously { percent: 50n }\\n maxFeePerGas: { multiplier: 1.5 },\\n // This was previously { percent: 25n }\\n maxPriorityFeePerGas: { multiplier: 1.25 },\\n },\\n },\\n });\",\"title\":\"Core: Transition from Percent to Multiplier api and types\",\"titles\":[\"Migration Guide\",\"Migrating to version 3.x.x\"]}]}],[\"index.86205aab8a6d72f2e7401f60d5be023eb735c5e3fb51e8d5406147afaef077f6\",{\"mdx\":\"---\\ntitle: Middleware\\ndescription: What is Middleware?\\n---\\n\\n# Middleware\\n\\nThe [Smart Account Client](/concepts/smart-account-client) is extended with a series of middleware. When building user operations for signing and sending, the flow can be pretty involved.\\nSending a UO requires you to get the latest nonce for an account, check if the account is deployed to set the `initCode` or `factory` and `factoryData` in the user operation, estimate fees, estimate gas, and then sign the user operation.\\nIf you want to use a paymaster, you need to generate some `dummyPaymasterAndData` to use during gas estimation, and after estimating gas you can request gas sponsorship from your paymaster.\\nMiddleware allows you to avoid having to write the same flows over and over when all you want to do is call a contract with some data or send some ETH to a destination.\\n\\n## Middleware order\\n\\n:::tip\\nWhen using the [React](/react/overview), [Core](/core/overview), or [Infra](/infra/overview) packages, the Smart Account Clients are already configured to use the appropriate middleware for your needs.\\nIf you want to sponsor gas, the Smart Account Clients in these packages abstract the relevant middleware away from you since all you need is a `policyId` to sponsor gas with Alchemy.\\n:::\\n\\nAs mentioned abve, the client can be configured with a series of middleware that always run in the same order:\\n\\n1. `dummyPaymasterAndData` - Generates a dummy paymaster and data for gas estimation if using a paymaster (default: noop)\\n2. `feeEstimator` - Estimates the fees for a user operation. If you are using our RPCs, it's important to use the [`alchemyFeeEstimator`](/reference/account-kit/infra/functions/alchemyFeeEstimator) middleware.\\n3. `gasEstimator` - Estimates the gas limits for a user operation. The default middleware calls the underlying bundler RPC to `eth_estimateUserOperationGas`.\\n4. `customMiddleware` - Allows you define custom middleware to run before requesting sponsorhip if there are any additional steps you need to take before requesting sponsorship. (default: noop)\\n5. `paymasterAndData` - Requests a gas sponsorship from a paymaster. (default: noop)\\n6. `userOperationSimulator` - Simulates a user operation to check if it will be successful. (default: noop)\\n\",\"document\":[{\"href\":\"/concepts/middleware#middleware\",\"html\":\"\\nThe Smart Account Client is extended with a series of middleware. When building user operations for signing and sending, the flow can be pretty involved.\\nSending a UO requires you to get the latest nonce for an account, check if the account is deployed to set the initCode
or factory
and factoryData
in the user operation, estimate fees, estimate gas, and then sign the user operation.\\nIf you want to use a paymaster, you need to generate some dummyPaymasterAndData
to use during gas estimation, and after estimating gas you can request gas sponsorship from your paymaster.\\nMiddleware allows you to avoid having to write the same flows over and over when all you want to do is call a contract with some data or send some ETH to a destination.
As mentioned abve, the client can be configured with a series of middleware that always run in the same order:
\\ndummyPaymasterAndData
- Generates a dummy paymaster and data for gas estimation if using a paymaster (default: noop)feeEstimator
- Estimates the fees for a user operation. If you are using our RPCs, it's important to use the alchemyFeeEstimator
middleware.gasEstimator
- Estimates the gas limits for a user operation. The default middleware calls the underlying bundler RPC to eth_estimateUserOperationGas
.customMiddleware
- Allows you define custom middleware to run before requesting sponsorhip if there are any additional steps you need to take before requesting sponsorship. (default: noop)paymasterAndData
- Requests a gas sponsorship from a paymaster. (default: noop)userOperationSimulator
- Simulates a user operation to check if it will be successful. (default: noop)The Bundler Client is similar to the Smart Account Client but is account agnostic. The Bundler Client only exposes methods for interacting directly with Bundler RPC and ETH RPC\\nmethods. The client also exposes the same methods as viem
's PublicClient
. In the vast majority of cases, you will not be using this client directly and will instead be using the Smart Account Client which wraps an instance of the Bundler Client\\nand provides the same actions as the Bundler Client.
The Bundler Client is EIP-1193 compliant, meaning it can easily be swapped out in place of other web3 providers (eg. window.ethereum
).
Similarly to the Smart Account Client, the Bundler Client is extended with a set of actions that make it easier to interact with RPC methods. The actions are all defined in @aa-sdk/core
. For detailed documentation on these methods, check out the SDK Reference Docs.
In the previous guides, we learned how to send user operations with gas sponsorship, but what happens when a user operation fails to mine? In this guide,\\nwe'll cover how to use drop and replace to resend failing user operations and ensure they get mined.
\\n\",\"id\":\"pages/infra/drop-and-replace.mdx#drop-and-replace-failing-user-operations\",\"isPage\":true,\"text\":\"\\nIn the previous guides, we learned how to send user operations with gas sponsorship, but what happens when a user operation fails to mine? In this guide,\\nwe'll cover how to use drop and replace to resend failing user operations and ensure they get mined.\\n\",\"title\":\"Drop and replace failing user operations\",\"titles\":[]},{\"href\":\"/infra/drop-and-replace#what-is-drop-and-replace\",\"html\":\"\\nIf fees change and your user operation gets stuck in the mempool, you can use drop and replace to resend the user operation with higher fees. This is most useful\\nwhen used in combination with waitForUserOperationTransaction
to ensure the transaction is mined\\nand then resend the user operation with higher fees if waiting times out.
Drop and replace works by resubmitting a user operation with the greater of:
\\nWe export a dropAndReplace
function from @aa-sdk/core
that you can use to handle this flow for you and is automatically added to the Smart Account Client.
Let's run through an example that uses drop and replace if waiting for a user operation to mine times out.
\\n\\n// @filename: client.ts\\n \\nimport { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { client } from "./client";\\n \\n// 1. send a user operation\\nconst { hash, request } = await client.sendUserOperation({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n});\\n \\ntry {\\n // 2. wait for it to be mined\\n const txHash = await client.waitForUserOperationTransaction({ hash });\\n} catch (e) {\\n // 3. if it fails, resubmit the user operation via drop and replace\\n const { hash: newHash } = await client.dropAndReplaceUserOperation({\\n uoToDrop: request,\\n });\\n \\n // 4. wait for the new user operation to be mined\\n await client.waitForUserOperationTransaction({ hash: newHash });\\n}
import { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});
In the above example, we only try to drop and replace once before failing completely, but you can build more complex retry logic using this combination of waitForUserOperationTransaction
and dropAndReplace
.
Account Kit makes it really easy to authenticate your users using a number of different authentication methods. If you followed the quickstart, then your app is already setup to authenticate users and you can skip this guide!
\\nIn this guide, we'll show you two different ways to authenticate users:
\\nAccount Kit allows you to use pre-built, highly customizable UI components to handle authenticating your users. The way you use them is very flexible since you can use the pre-built modal or even embed the Auth card directly in your application.
\\n\",\"id\":\"pages/react/authenticate-users.mdx#using-our-ui-components\",\"isPage\":false,\"text\":\"\\nAccount Kit allows you to use pre-built, highly customizable UI components to handle authenticating your users. The way you use them is very flexible since you can use the pre-built modal or even embed the Auth card directly in your application.\\n\",\"title\":\"Using our UI components\",\"titles\":[\"Authenticate users\"]},{\"href\":\"/react/authenticate-users#modal-auth\",\"html\":\"\\nAssuming your application has been set up, using UI components is the easiest way to authenticate users. All you have to do is leverage the useAuthModal
hook and provide users a CTA to open the modal.
import React from "react";\\nimport { useAuthModal } from "@account-kit/react";\\n \\nexport default function MyPage() {\\n const { openAuthModal } = useAuthModal();\\n \\n return <button onClick={openAuthModal}>Authenticate</button>;\\n}
\\nThat's it! When the user clicks that button, the modal will open and they can complete authentication. Once they are authenticated, you can use the useAccount
hook to get the logged in user's SCA address
The body of the Auth Modal is also exported for you to use directly in your application. This is useful if you don't want a modal flow for login and want a standalone page using the card.
\\nimport React from "react";\\nimport { AuthCard } from "@account-kit/react";\\n \\nexport default function MyLoginPage() {\\n return (\\n <div className="flex flex-row p-4 bg-white border border-gray-200 rounded-lg">\\n <AuthCard />\\n </div>\\n );\\n}
\\nThat's it! The user can now input their credentials and complete login. Once they are authenticated, you can use the useAccount
hook to get the logged in user's SCA address
If you don't want to use our pre-built UI components, you can also use the useAuthenticate
hook to build your own custom UI.
import React from "react";\\nimport {\\n type UseAuthenticateResult,\\n useAuthenticate,\\n} from "@account-kit/react";\\n \\n// This examples uses email authentication\\n// you can also use passkeys if the user has one created\\nexport default function MyLoginPage() {\\n const { authenticate, isPending } = useAuthenticate();\\n const [email, setEmail] = React.useState("");\\n \\n return (\\n <div>\\n <input\\n type="email"\\n value={email}\\n onChange={(e) => setEmail(e.target.value)}\\n />\\n <button onClick={() => authenticate({ type: "email", email })}>\\n Login\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/react/authenticate-users.mdx#email-authentication\",\"isPage\":false,\"text\":\"\\nimport React from "react";\\nimport {\\n type UseAuthenticateResult,\\n useAuthenticate,\\n} from "@account-kit/react";\\n \\n// This examples uses email authentication\\n// you can also use passkeys if the user has one created\\nexport default function MyLoginPage() {\\n const { authenticate, isPending } = useAuthenticate();\\n const [email, setEmail] = React.useState("");\\n \\n return (\\n <div>\\n <input\\n type="email"\\n value={email}\\n onChange={(e) => setEmail(e.target.value)}\\n />\\n <button onClick={() => authenticate({ type: "email", email })}>\\n Login\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Email authentication\",\"titles\":[\"Authenticate users\",\"Using our React hooks\"]},{\"href\":\"/react/authenticate-users#passkey-auth-with-email-backup\",\"html\":\"\\nThis approach will allow you to login or signup users using a passkey as the primary auth mechanism and register an email as a backup.
\\n\\nimport React from "react";\\nimport {\\n type UseAuthenticateResult,\\n useAuthenticate,\\n} from "@account-kit/react";\\n \\nexport default function MyLoginPage() {\\n const { authenticate, isPending } = useAuthenticate();\\n const [email, setEmail] = React.useState("");\\n \\n return (\\n <div>\\n <input\\n type="email"\\n value={email}\\n onChange={(e) => setEmail(e.target.value)}\\n />\\n <button onClick={() => authenticate({ type: "passkey", email })}>\\n Login\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/react/authenticate-users.mdx#passkey-auth-with-email-backup\",\"isPage\":false,\"text\":\"\\nThis approach will allow you to login or signup users using a passkey as the primary auth mechanism and register an email as a backup.\\nIt's important that you verify this email to be correct first! Otherwise, if a user loses their passkey, they will not be able to recover their account.\\nimport React from "react";\\nimport {\\n type UseAuthenticateResult,\\n useAuthenticate,\\n} from "@account-kit/react";\\n \\nexport default function MyLoginPage() {\\n const { authenticate, isPending } = useAuthenticate();\\n const [email, setEmail] = React.useState("");\\n \\n return (\\n <div>\\n <input\\n type="email"\\n value={email}\\n onChange={(e) => setEmail(e.target.value)}\\n />\\n <button onClick={() => authenticate({ type: "passkey", email })}>\\n Login\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Passkey auth with email backup\",\"titles\":[\"Authenticate users\",\"Using our React hooks\"]},{\"href\":\"/react/authenticate-users#existing-passkey\",\"html\":\"\\nIf your user already has a passkey, then you can authenticate with that directly. This is useful if you want to use email as a signup mechanism, but provide easier login methods for your users via passkeys.
\\nimport React from "react";\\nimport {\\n type UseAuthenticateResult,\\n useAuthenticate,\\n} from "@account-kit/react";\\n \\nexport default function MyLoginPage() {\\n const { authenticate } = useAuthenticate();\\n \\n return (\\n <div>\\n <button\\n onClick={() => authenticate({ type: "passkey", createNew: false })}\\n >\\n Login\\n </button>\\n </div>\\n );\\n}
\",\"id\":\"pages/react/authenticate-users.mdx#existing-passkey\",\"isPage\":false,\"text\":\"\\nIf your user already has a passkey, then you can authenticate with that directly. This is useful if you want to use email as a signup mechanism, but provide easier login methods for your users via passkeys.\\nimport React from "react";\\nimport {\\n type UseAuthenticateResult,\\n useAuthenticate,\\n} from "@account-kit/react";\\n \\nexport default function MyLoginPage() {\\n const { authenticate } = useAuthenticate();\\n \\n return (\\n <div>\\n <button\\n onClick={() => authenticate({ type: "passkey", createNew: false })}\\n >\\n Login\\n </button>\\n </div>\\n );\\n}\",\"title\":\"Existing Passkey\",\"titles\":[\"Authenticate users\",\"Using our React hooks\"]}]}],[\"index.2b8d86d768f660c23e73695fbeee7bef986f5ff5a8a3c862ee8e159d659e893f\",{\"mdx\":\"---\\ntitle: Types\\ndescription: Glossary of types in aa-sdk\\n---\\n\\n# Types\\n\\n## `BatchUserOperationCallData`\\n\\nAn array of `UserOperationCallData`, representing a sequence of `UserOperations` to be executed in batch by calling the `executeBatch` function on the `SmartContractAccount` contract. Check out our guide on [How to submit batch transactions](#TODO/using-smart-accounts/batch-user-operations) to learn more about batching multiple transactions into a single `UserOperation`.\\n\\n:::details[BatchUserOperationCallData]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts:BatchUserOperationCallData]\\n```\\n\\n:::\\n\\n## `BigNumberish`\\n\\nA type that can be a hexadecimal string prefixed with [`Hex`](https://viem.sh/docs/glossary/types#hex), a `bigint`, or a `number`. It is used to represent values that can be converted to or operate as big integers.\\n\\n:::details[BigNumberish]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/utils/schema.ts:BigNumberish]\\n```\\n\\n:::\\n\\n## `BigNumberishRange`\\n\\nAn object type that may contain optional `min` and `max` fields, each of which accepts a `BigNumberish` value. This type is used to specify a numerical range, including both the minimum and maximum bounds.\\n\\n:::details[BigNumberishRange]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/utils/schema.ts:BigNumberishRange]\\n```\\n\\n:::\\n\\n## `BundlerAction`\\n\\nBundler Actions are `viem` [`Actions`](https://viem.sh/docs/actions/public/introduction) that map one-to-one with \\\"public\\\" [`Bundler`](./terms#bundler) RPC methods (`eth_sendUserOperation`, `eth_getUserOperationByHash`, etc.) under the [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) and [EIP-6900](https://eips.ethereum.org/EIPS/eip-6900) standards. They are used with a [`BundlerClient`](#bundlerclient). `BundlerActions` do not require any special permissions, nor do they provide \\\"signing\\\" capabilities to the user. Examples of `BundlerActions` include retrieving the details of a specific user operation, estimating user operation gas, etc.\\n\\n:::details[BundlerAction]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/client/decorators/bundlerClient.ts:BundlerActions]\\n```\\n\\n:::\\n\\n## `BundlerClient`\\n\\n`BundlerClient` is a custom `viem` [`Client`](https://viem.sh/docs/clients/custom) we have built our own, where we extended viem's [`PublicClient`](https://viem.sh/docs/clients/public) with [`BundlerActions`](#bundleraction), which are `Actions` that provide custom functionalities of [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) and [EIP-6900](https://eips.ethereum.org/EIPS/eip-6900) standards. `BundlerClient` is an intermediary or connector that enables client applications to interact with the [`Bundler`](https://eips.ethereum.org/EIPS/eip-4337#definitions) that you are using. `BundlerClient`, because it extends `PublicClient`, supports [`Public Actions`](https://viem.sh/docs/actions/public/introduction) for client applications to connect, query, and interact with the blockchain (i.e., sending transactions, smart contract executions, data retrieval, etc.).\\n\\n:::details[BundlerClient]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/client/bundlerClient.ts:BundlerClient]\\n```\\n\\n:::\\n\\n## `ClientMiddleware`\\n\\nMiddleware represents different operations involved in the [`SmartAccountClient`](/concepts/smart-account-client) pipeline for constructing a user operation given the user inputs by populating the UO with other data, including gas fees, paymaster data, etc.\\n\\n:::details[ClientMiddleware]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/middleware/types.ts:ClientMiddleware]\\n```\\n\\n:::\\n\\n## `ClientMiddlewareConfig`\\n\\nConfiguration object to configure `ClientMiddleware` of the [`SmartAccountClient`](/concepts/smart-account-client) during the client instantiation. You can configure using this object to configure the middleware of your interest selectively.\\n\\n:::details[ClientMiddlewareFn]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/client/types.ts:ClientMiddlewareConfig]\\n```\\n\\n:::\\n\\n## `ClientMiddlewareFn`\\n\\nEach middleware is a function that takes in a user operation object, `UserOperationStruct`, performs its job to retrieve or compute the data, and populate different fields of the user operation to pass onto the next middleware in the pipeline before being signed and sent to the network. `ClientMiddlewareFn` is the function type that represents each middleware. In optional [`UserOperationOverrides`](#useroperationoverrides), and [`UserOperationFeeOptions`](https://github.com/alchemyplatform/aa-sdk/blob/v4.x.x/aa-sdk/core/src/types.ts#L55), and returns a promise that resolves to a modified `UserOperationStruct`. This function is what you specify as your overridden middleware value for applying custom logic during the `UserOperationStruct` object to be sent to the bundler for on-chain execution.\\n\\n:::details[ClientMiddlewareFn]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/middleware/types.ts:ClientMiddlewareFn]\\n```\\n\\n:::\\n\\n## `EntryPointDef`\\n\\nAn object type that defines the interface for `EntryPoint` functions for packing the user operation to the optimized data structure to enhance performance and reduce gas costs of transactions, and generating the hash of the user operation for the format compatible to the specified `Chain` and `EntryPointVersion`.\\n\\n:::details[EntryPointDef]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/entrypoint/types.ts:EntryPointDef]\\n```\\n\\n:::\\n\\n## `Multiplier`\\n\\nAn object type with a required `multipler` field, which is a `number` value with max precision of 4 decimal places.\\n\\n:::details[Multiplier]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/utils/schema.ts:Multiplier\\n```\\n\\n:::\\n\\n## `SmartAccountAuthenticator`\\n\\nAn extension of the [`SmartAccountSigner`](#smartaccountsigner) interface, this interface contains authentication-related functions in addition to the signing methods of the `SmartAccountSigner`. It provides methods to authenticate the signer (`authenticate`) as the \\\"authorized\\\" signer, often as the owner, of the `SmartContractAccount`. It also has methods to retrieve authentication details (`getAuthDetails`) about the signer instance that the user is using to authenticate to one's account.\\n\\n:::details[SmartAccountAuthenticator]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/signer/types.ts:SmartAccountAuthenticator]\\n```\\n\\n:::\\n\\n## `SmartAccountClient`\\n\\n`SmartAccountClient` is a custom `viem` `Client`, like the [`BundlerClient`](#bundlerclient), which is an intermediary or connector that enables your client application to interact with the `SmartContractAccount`. `SmartAccountClient` is analogous to the [`WalletClient`](https://viem.sh/docs/clients/wallet). The difference is that while `WalletClient` has [`WalletActions`](https://viem.sh/docs/actions/wallet/introduction) that lets your client application interact with an [Externally-owned account (EOA)](https://ethereum.org/developers/docs/accounts) with a [wallet](./terms#wallet), `SmartAccountClient` provides [`SmartAccountClientActions`](#smartaccountclientaction) for client applications to interact with `SmartContractAccounts`.\\n\\n:::details[SmartAccountClient]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/client/smartAccountClient.ts:SmartAccountClient]\\n```\\n\\n:::\\n\\n## `SmartAccountClientAction`\\n\\n`SmartAccountClientActions` are `viem` [`Actions`](https://viem.sh/docs/actions/wallet/introduction) that map one-to-one with smart contract account-related or \\\"signable\\\" actions, such as constructing user operation requests to be sent to the [`Bundler`](./terms#bundler), signing messages or user operation requests, sending user operations to the `Bundler`, upgrading accounts to different implementation address, etc. They are used with a `SmartAccountClient`. `SmartAccountClientActions` require special permissions and provide signing capabilities for `SmartContractAccounts`.\\n\\n:::details[SmartAccountClientAction]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/client/smartAccountClient.ts:SmartAccountClientActions]\\n```\\n\\n:::\\n\\n## `SmartAccountSigner`\\n\\nAn interface representing a signer capable of signing messages and typed data. It provides methods to retrieve the signer's address (`getAddress`), sign a message (`signMessage`), and sign typed data (`signTypedData`). `SmartAccountSigner` refers to the [`Signer`](./terms#signer) instance responsible for the signing activities using its private key for smart account activities. Often, the `Signer` is referred to as the `Owner` of the account as it has the authority to use the smart account on-chain with its signatures.\\n\\n:::details[SmartAccountSigner]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/signer/types.ts:SmartAccountSigner]\\n```\\n\\n:::\\n\\n## `SmartContractAccount`\\n\\nAs smart contract accounts are essentially the contract codes that operate on the blockchain, `SmartContractAccount` defines the interface with different functionalities for managing and interacting with the contract account. It includes different functionalities for creating, managing, and using your smart account. In addition to supporting all functionalities achieved with a basic [EOA](./terms#wallet) alone, `SmartContractAccount` can have custom capabilities such as automating processes or executing actions based on predefined conditions. Smart contract wallets allow users to customize how they manage their digital assets, offering a more tailored approach to handling funds securely. `SmartContractAccount` type extends `viem`'s [`Account`](https://viem.sh/docs/accounts/custom), and instantiation of an account is done using the [`toSmartContractAccount`](/reference/aa-sdk/core/functions/toSmartContractAccount) action.\\n\\n:::details[SmartContractAccount]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/account/smartContractAccount.ts:SmartContractAccount]\\n```\\n\\n:::\\n\\n## `StateOverride`\\n\\nA type defining state overrides for [`eth_call`](https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-eth#eth-call) method. An optional address-to-state mapping, where each entry specifies some state to be ephemerally overridden prior to executing the call.\\nState overrides allow you to customize the network state for the purpose of the simulation, so this feature is useful when you need to test or simulate scenarios under conditions that aren’t currently present on the live network.\\n\\n## `ToSmartContractAccountParams`\\n\\nThis type defines the parameters to the `SmartContractAccount` instantiation action, [`toSmartContractAccount`](/reference/aa-sdk/core/functions/toSmartContractAccount). You can configure this parameter to specify the [`Transport`](https://viem.sh/docs/clients/intro#transports), [`Chain`](https://viem.sh/docs/glossary/types#chain), [`EntryPointDef`](#entrypointdef), and other base functionalities of the smart account that you are creating.\\n\\n:::details[ToSmartContractAccountParams]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/account/smartContractAccount.ts:ToSmartContractAccountParams]\\n```\\n\\n:::\\n\\n## `User`\\n\\n`User` is a type that defines the model for the details of a user's Embedded Account via an Alchemy Signer. It includes the user's `email`, `orgId`, `userId`, `userId`, `address` (the EOA signer address corresponding to the user credentials), and `credentialId`. You can use the [`useUser`](/reference/account-kit/react/hooks/useUser) react hook to look up a user.\\n\\n:::details[User]\\n\\n```ts\\n// [!include ~/../account-kit/signer/src/client/types.ts:User]\\n```\\n\\n:::\\n\\n## `UserOperationCallData`\\n\\n`UserOperationCallData` is a type that represents the user's \\\"intent\\\" or the desired outcome representing a specific objective a user aims to accomplish. It includes `target` (the destination address), `data` (the [`Transaction calldata`](./terms#transaction-calldata)), and `value` (the amount value of ETH, or the native token to send). It acts as the input to the `sendUserOperation` method on [`SmartAccountClient`](#smartaccountclient).\\n\\n:::details[UserOperationCallData]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts:UserOperationCallData]\\n```\\n\\n:::\\n\\n## `UserOperationEstimateGasResponse`\\n\\nAn interface that defines the structure for the response received from the RPC method [`eth_estimateUserOperationGas`](https://docs.alchemy.com/reference/eth-estimateuseroperationgas). This response provides detailed information about the estimated gas usage for a `UserOperation`.\\n\\n:::details[UserOperationEstimateGasResponse]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts:UserOperationEstimateGasResponse]\\n```\\n\\n:::\\n\\n## `UserOperationOverrides`\\n\\nPartial structure for overriding default values in a `UserOperationStruct`, such as gas limits and fees. Available fields include `maxFeePerGas`, `maxPriorityFeePerGas`, `callGasLimit`, `preVerificationGas`, `verificationGasLimit`, `paymasterAndData`, or `nonceKey`. You can also specify a `stateOverride` to be passed into `eth_estimateUserOperationGas` during gas estimation. These override values are available from each [`ClientMiddleware`](#clientmiddleware) of the `SmartAccountClient`. Check out [`UserOperationOverrides`](https://github.com/alchemyplatform/aa-sdk/blob/v4.x.x/aa-sdk/core/src/types.ts#L97) page to learn more.\\n\\n:::details[UserOperationOverrides]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts:UserOperationOverrides]\\n```\\n\\n:::\\n\\n## `UserOperationReceipt`\\n\\nAn interface that defines the structure for the response received from the RPC method [`eth_getUserOperationReceipt`](https://docs.alchemy.com/reference/eth-getuseroperationreceipt). It includes details like sender, nonce, gas cost, and success status of the `UserOperation`.\\n\\n:::details[UserOperationReceipt]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts#UserOperationReceipt\\n```\\n\\n:::\\n\\n## `UserOperationRequest`\\n\\nInterface for the request format required for a JSON-RPC request to `eth_sendUserOperation`. It includes sender, nonce, gas limits, fees, and more fields.\\n\\n:::details[UserOperationRequest]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts#UserOperationRequest\\n```\\n\\n:::\\n\\n## `UserOperationResponse`\\n\\nAn interface that defines the structure for the response received from the RPC method [`eth_getUserOperationByHash`](https://docs.alchemy.com/reference/eth-getuseroperationbyhash), detailing the result of executing a `UserOperation`. It includes the block number, block hash, transaction hash and more information associated with the UO.\\n\\n:::details[UserOperationResponse]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts#UserOperationResponse\\n```\\n\\n:::\\n\\n## `UserOperationStruct`\\n\\nInterface for structuring a `UserOperation`, with fields similar to `UserOperationRequest` but used for building requests.\\n\\n:::details[UserOperationStruct]\\n\\n```ts\\n// [!include ~/../aa-sdk/core/src/types.ts#UserOperationStruct\\n```\\n\\n:::\\n\",\"document\":[{\"href\":\"/resources/types#types\",\"html\":\"\\n\",\"id\":\"pages/resources/types.mdx#types\",\"isPage\":true,\"text\":\"\\n\",\"title\":\"Types\",\"titles\":[]},{\"href\":\"/resources/types#batchuseroperationcalldata\",\"html\":\"\\nAn array of UserOperationCallData
, representing a sequence of UserOperations
to be executed in batch by calling the executeBatch
function on the SmartContractAccount
contract. Check out our guide on How to submit batch transactions to learn more about batching multiple transactions into a single UserOperation
.
export type BatchUserOperationCallData = Exclude<UserOperationCallData, Hex>[];
A type that can be a hexadecimal string prefixed with Hex
, a bigint
, or a number
. It is used to represent values that can be converted to or operate as big integers.
export const BigNumberishSchema = z.union([HexSchema, z.number(), z.bigint()]);
An object type that may contain optional min
and max
fields, each of which accepts a BigNumberish
value. This type is used to specify a numerical range, including both the minimum and maximum bounds.
export const BigNumberishRangeSchema = z\\n .object({\\n min: BigNumberishSchema.optional(),\\n max: BigNumberishSchema.optional(),\\n })\\n .strict();
Bundler Actions are viem
Actions
that map one-to-one with "public" Bundler
RPC methods (eth_sendUserOperation
, eth_getUserOperationByHash
, etc.) under the EIP-4337 and EIP-6900 standards. They are used with a BundlerClient
. BundlerActions
do not require any special permissions, nor do they provide "signing" capabilities to the user. Examples of BundlerActions
include retrieving the details of a specific user operation, estimating user operation gas, etc.
export type BundlerActions = {\\n /**\\n * calls `eth_estimateUserOperationGas` and returns the result\\n *\\n * @param request - the UserOperationRequest to estimate gas for\\n * @param entryPoint - the entry point address the op will be sent to\\n * @param stateOverride - the state override to use for the estimation\\n * @returns the gas estimates for the given response\\n */\\n estimateUserOperationGas<\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n >(\\n request: UserOperationRequest<TEntryPointVersion>,\\n entryPoint: Address,\\n stateOverride?: StateOverride\\n ): Promise<UserOperationEstimateGasResponse<TEntryPointVersion>>;\\n \\n /**\\n * calls `eth_sendUserOperation` and returns the hash of the sent UserOperation\\n *\\n * @param request - the UserOperationRequest to send\\n * @param entryPoint - the entry point address the op will be sent to\\n * @returns the hash of the sent UserOperation\\n */\\n sendRawUserOperation<\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n >(\\n request: UserOperationRequest<TEntryPointVersion>,\\n entryPoint: Address\\n ): Promise<Hash>;\\n \\n /**\\n * calls `eth_getUserOperationByHash` and returns the UserOperationResponse\\n *\\n * @param hash - the hash of the UserOperation to fetch\\n * @returns - the user operation if found or null\\n */\\n getUserOperationByHash(hash: Hash): Promise<UserOperationResponse | null>;\\n \\n /**\\n * calls `eth_getUserOperationReceipt` and returns the UserOperationReceipt\\n *\\n * @param hash - the hash of the UserOperation to get the receipt for\\n * @returns - a user operation receipt or null if not found\\n */\\n getUserOperationReceipt(hash: Hash): Promise<UserOperationReceipt | null>;\\n \\n /**\\n * calls `eth_supportedEntryPoints` and returns the entry points the RPC supports\\n *\\n * @returns - an array of the entrypoint addresses supported\\n */\\n getSupportedEntryPoints(): Promise<Address[]>;\\n};
BundlerClient
is a custom viem
Client
we have built our own, where we extended viem's PublicClient
with BundlerActions
, which are Actions
that provide custom functionalities of EIP-4337 and EIP-6900 standards. BundlerClient
is an intermediary or connector that enables client applications to interact with the Bundler
that you are using. BundlerClient
, because it extends PublicClient
, supports Public Actions
for client applications to connect, query, and interact with the blockchain (i.e., sending transactions, smart contract executions, data retrieval, etc.).
export type BundlerClient<T extends Transport = Transport> = Client<\\n T,\\n Chain,\\n undefined,\\n [...PublicRpcSchema, ...BundlerRpcSchema],\\n PublicActions<T, Chain> & BundlerActions\\n>;\\n \\n/**\\n * Creates a bundler client from an existing public client with the provided transport and chain.\\n *\\n * @example\\n * ```ts\\n * import { createPublicClient } from "viem";\\n * import { createBundlerClientFromExisting } from "@aa-sdk/core";\\n *\\n * const publicClient = createPublicClient(...);\\n * const bundlerClient = createBundlerClientFromExisting(publicClient);\\n * ```\\n *\\n * @param {PublicClient<T, Chain>} client The existing public client to be extended with bundler actions\\n * @returns {BundlerClient<T>} A bundler client that extends the functionality of the provided public client\\n */\\nexport const createBundlerClientFromExisting: <\\n T extends Transport | FallbackTransport = Transport\\n>(\\n client: PublicClient<T, Chain>\\n) => BundlerClient<T> = <T extends Transport | FallbackTransport = Transport>(\\n client: PublicClient<T, Chain>\\n): BundlerClient<T> => {\\n return client.extend(bundlerActions);\\n};
Middleware represents different operations involved in the SmartAccountClient
pipeline for constructing a user operation given the user inputs by populating the UO with other data, including gas fees, paymaster data, etc.
export type ClientMiddleware<\\n TContext extends UserOperationContext | undefined =\\n | UserOperationContext\\n | undefined\\n> = {\\n dummyPaymasterAndData: ClientMiddlewareFn<TContext>;\\n feeEstimator: ClientMiddlewareFn<TContext>;\\n gasEstimator: ClientMiddlewareFn<TContext>;\\n customMiddleware: ClientMiddlewareFn<TContext>;\\n paymasterAndData: ClientMiddlewareFn<TContext>;\\n userOperationSimulator: ClientMiddlewareFn<TContext>;\\n signUserOperation: ClientMiddlewareFn<TContext>;\\n};
Configuration object to configure ClientMiddleware
of the SmartAccountClient
during the client instantiation. You can configure using this object to configure the middleware of your interest selectively.
export type ClientMiddlewareConfig<\\n TContext extends UserOperationContext | undefined =\\n | UserOperationContext\\n | undefined\\n> = Partial<ClientMiddleware<TContext>>;
Each middleware is a function that takes in a user operation object, UserOperationStruct
, performs its job to retrieve or compute the data, and populate different fields of the user operation to pass onto the next middleware in the pipeline before being signed and sent to the network. ClientMiddlewareFn
is the function type that represents each middleware. In optional UserOperationOverrides
, and UserOperationFeeOptions
, and returns a promise that resolves to a modified UserOperationStruct
. This function is what you specify as your overridden middleware value for applying custom logic during the UserOperationStruct
object to be sent to the bundler for on-chain execution.
export type ClientMiddlewareFn<\\n TContext extends UserOperationContext | undefined =\\n | UserOperationContext\\n | undefined\\n> = <\\n TAccount extends SmartContractAccount,\\n C extends MiddlewareClient,\\n TEntryPointVersion extends GetEntryPointFromAccount<TAccount> = GetEntryPointFromAccount<TAccount>\\n>(\\n struct: Deferrable<UserOperationStruct<TEntryPointVersion>>,\\n args: ClientMiddlewareArgs<TAccount, C, TContext, TEntryPointVersion>\\n) => Promise<Deferrable<UserOperationStruct<TEntryPointVersion>>>;
An object type that defines the interface for EntryPoint
functions for packing the user operation to the optimized data structure to enhance performance and reduce gas costs of transactions, and generating the hash of the user operation for the format compatible to the specified Chain
and EntryPointVersion
.
export type EntryPointDef<\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion,\\n TChain extends Chain = Chain,\\n TAbi extends Abi | readonly unknown[] = Abi\\n> = {\\n version: TEntryPointVersion;\\n address: Address;\\n chain: TChain;\\n abi: GetContractParameters<Transport, TChain, Account, TAbi>["abi"];\\n getUserOperationHash: (\\n request: UserOperationRequest<TEntryPointVersion>\\n ) => Hex;\\n packUserOperation: (\\n userOperation: UserOperationRequest<TEntryPointVersion>\\n ) => Hex;\\n};
An object type with a required multipler
field, which is a number
value with max precision of 4 decimal places.
// [!include ~/../aa-sdk/core/src/utils/schema.ts:Multiplier
An extension of the SmartAccountSigner
interface, this interface contains authentication-related functions in addition to the signing methods of the SmartAccountSigner
. It provides methods to authenticate the signer (authenticate
) as the "authorized" signer, often as the owner, of the SmartContractAccount
. It also has methods to retrieve authentication details (getAuthDetails
) about the signer instance that the user is using to authenticate to one's account.
/**\\n * Extends the @interface SmartAccountSigner interface with authentication.\\n *\\n * @template AuthParams - the generic type of the authentication parameters\\n * @template AuthDetails - the generic type of the authentication details\\n * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc.\\n */\\nexport interface SmartAccountAuthenticator<AuthParams, AuthDetails, Inner = any>\\n extends SmartAccountSigner<Inner> {\\n authenticate: (params: AuthParams) => Promise<AuthDetails>;\\n \\n getAuthDetails: () => Promise<AuthDetails>;\\n}
SmartAccountClient
is a custom viem
Client
, like the BundlerClient
, which is an intermediary or connector that enables your client application to interact with the SmartContractAccount
. SmartAccountClient
is analogous to the WalletClient
. The difference is that while WalletClient
has WalletActions
that lets your client application interact with an Externally-owned account (EOA) with a wallet, SmartAccountClient
provides SmartAccountClientActions
for client applications to interact with SmartContractAccounts
.
// [!include ~/../aa-sdk/core/src/client/smartAccountClient.ts:SmartAccountClient]
SmartAccountClientActions
are viem
Actions
that map one-to-one with smart contract account-related or "signable" actions, such as constructing user operation requests to be sent to the Bundler
, signing messages or user operation requests, sending user operations to the Bundler
, upgrading accounts to different implementation address, etc. They are used with a SmartAccountClient
. SmartAccountClientActions
require special permissions and provide signing capabilities for SmartContractAccounts
.
// [!include ~/../aa-sdk/core/src/client/smartAccountClient.ts:SmartAccountClientActions]
An interface representing a signer capable of signing messages and typed data. It provides methods to retrieve the signer's address (getAddress
), sign a message (signMessage
), and sign typed data (signTypedData
). SmartAccountSigner
refers to the Signer
instance responsible for the signing activities using its private key for smart account activities. Often, the Signer
is referred to as the Owner
of the account as it has the authority to use the smart account on-chain with its signatures.
/**\\n * A signer that can sign messages and typed data.\\n *\\n * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc.\\n */\\nexport interface SmartAccountSigner<Inner = any> {\\n signerType: string;\\n inner: Inner;\\n \\n getAddress: () => Promise<Address>;\\n \\n signMessage: (message: SignableMessage) => Promise<Hex>;\\n \\n signTypedData: <\\n const TTypedData extends TypedData | { [key: string]: unknown },\\n TPrimaryType extends string = string\\n >(\\n params: TypedDataDefinition<TTypedData, TPrimaryType>\\n ) => Promise<Hex>;\\n}
As smart contract accounts are essentially the contract codes that operate on the blockchain, SmartContractAccount
defines the interface with different functionalities for managing and interacting with the contract account. It includes different functionalities for creating, managing, and using your smart account. In addition to supporting all functionalities achieved with a basic EOA alone, SmartContractAccount
can have custom capabilities such as automating processes or executing actions based on predefined conditions. Smart contract wallets allow users to customize how they manage their digital assets, offering a more tailored approach to handling funds securely. SmartContractAccount
type extends viem
's Account
, and instantiation of an account is done using the toSmartContractAccount
action.
export type SmartContractAccount<\\n Name extends string = string,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = LocalAccount<Name> & {\\n source: Name;\\n getDummySignature: () => Hex | Promise<Hex>;\\n encodeExecute: (tx: AccountOp) => Promise<Hex>;\\n encodeBatchExecute: (txs: AccountOp[]) => Promise<Hex>;\\n signUserOperationHash: (uoHash: Hex) => Promise<Hex>;\\n signMessageWith6492: (params: { message: SignableMessage }) => Promise<Hex>;\\n signTypedDataWith6492: <\\n const typedData extends TypedData | Record<string, unknown>,\\n primaryType extends keyof typedData | "EIP712Domain" = keyof typedData\\n >(\\n typedDataDefinition: TypedDataDefinition<typedData, primaryType>\\n ) => Promise<Hex>;\\n encodeUpgradeToAndCall: (params: UpgradeToAndCallParams) => Promise<Hex>;\\n getNonce(nonceKey?: bigint): Promise<bigint>;\\n getInitCode: () => Promise<Hex>;\\n isAccountDeployed: () => Promise<boolean>;\\n getFactoryAddress: () => Promise<Address>;\\n getFactoryData: () => Promise<Hex>;\\n getEntryPoint: () => EntryPointDef<TEntryPointVersion>;\\n getImplementationAddress: () => Promise<NullAddress | Address>;\\n};
A type defining state overrides for eth_call
method. An optional address-to-state mapping, where each entry specifies some state to be ephemerally overridden prior to executing the call.\\nState overrides allow you to customize the network state for the purpose of the simulation, so this feature is useful when you need to test or simulate scenarios under conditions that aren’t currently present on the live network.
This type defines the parameters to the SmartContractAccount
instantiation action, toSmartContractAccount
. You can configure this parameter to specify the Transport
, Chain
, EntryPointDef
, and other base functionalities of the smart account that you are creating.
export type ToSmartContractAccountParams<\\n Name extends string = string,\\n TTransport extends Transport = Transport,\\n TChain extends Chain = Chain,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = {\\n source: Name;\\n transport: TTransport;\\n chain: TChain;\\n entryPoint: EntryPointDef<TEntryPointVersion, TChain>;\\n accountAddress?: Address;\\n getAccountInitCode: () => Promise<Hex>;\\n getDummySignature: () => Hex | Promise<Hex>;\\n encodeExecute: (tx: AccountOp) => Promise<Hex>;\\n encodeBatchExecute?: (txs: AccountOp[]) => Promise<Hex>;\\n // if not provided, will default to just using signMessage over the Hex\\n signUserOperationHash?: (uoHash: Hex) => Promise<Hex>;\\n encodeUpgradeToAndCall?: (params: UpgradeToAndCallParams) => Promise<Hex>;\\n} & Omit<CustomSource, "signTransaction" | "address">;
User
is a type that defines the model for the details of a user's Embedded Account via an Alchemy Signer. It includes the user's email
, orgId
, userId
, userId
, address
(the EOA signer address corresponding to the user credentials), and credentialId
. You can use the useUser
react hook to look up a user.
export type User = {\\n email?: string;\\n orgId: string;\\n userId: string;\\n address: Address;\\n credentialId?: string;\\n};
UserOperationCallData
is a type that represents the user's "intent" or the desired outcome representing a specific objective a user aims to accomplish. It includes target
(the destination address), data
(the Transaction calldata
), and value
(the amount value of ETH, or the native token to send). It acts as the input to the sendUserOperation
method on SmartAccountClient
.
export type UserOperationCallData =\\n | {\\n /* the target of the call */\\n target: Address;\\n /* the data passed to the target */\\n data: Hex;\\n /* the amount of native token to send to the target (default: 0) */\\n value?: bigint;\\n }\\n | Hex;
An interface that defines the structure for the response received from the RPC method eth_estimateUserOperationGas
. This response provides detailed information about the estimated gas usage for a UserOperation
.
export interface UserOperationEstimateGasResponse<\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> {\\n /* Gas overhead of this UserOperation */\\n preVerificationGas: BigNumberish;\\n /* Actual gas used by the validation of this UserOperation */\\n verificationGasLimit: BigNumberish;\\n /* Value used by inner account execution */\\n callGasLimit: BigNumberish;\\n /*\\n * EntryPoint v0.7.0 operations only.\\n * The amount of gas to allocate for the paymaster validation code.\\n * Note: `eth_estimateUserOperationGas` does not return paymasterPostOpGasLimit.\\n */\\n paymasterVerificationGasLimit: TEntryPointVersion extends "0.7.0"\\n ? BigNumberish | undefined\\n : never;\\n}
Partial structure for overriding default values in a UserOperationStruct
, such as gas limits and fees. Available fields include maxFeePerGas
, maxPriorityFeePerGas
, callGasLimit
, preVerificationGas
, verificationGasLimit
, paymasterAndData
, or nonceKey
. You can also specify a stateOverride
to be passed into eth_estimateUserOperationGas
during gas estimation. These override values are available from each ClientMiddleware
of the SmartAccountClient
. Check out UserOperationOverrides
page to learn more.
export type UserOperationOverrides<\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = Partial<\\n {\\n callGasLimit:\\n | UserOperationStruct<TEntryPointVersion>["callGasLimit"]\\n | Multiplier;\\n maxFeePerGas:\\n | UserOperationStruct<TEntryPointVersion>["maxFeePerGas"]\\n | Multiplier;\\n maxPriorityFeePerGas:\\n | UserOperationStruct<TEntryPointVersion>["maxPriorityFeePerGas"]\\n | Multiplier;\\n preVerificationGas:\\n | UserOperationStruct<TEntryPointVersion>["preVerificationGas"]\\n | Multiplier;\\n verificationGasLimit:\\n | UserOperationStruct<TEntryPointVersion>["verificationGasLimit"]\\n | Multiplier;\\n /**\\n * This can be used to override the key used when calling `entryPoint.getNonce`\\n * It is useful when you want to use parallel nonces for user operations\\n *\\n * NOTE: not all bundlers fully support this feature and it could be that your bundler will still only include\\n * one user operation for your account in a bundle\\n */\\n nonceKey: bigint;\\n \\n /**\\n * The same state overrides for\\n * [`eth_call`](https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-eth#eth-call) method.\\n * An address-to-state mapping, where each entry specifies some state to be ephemerally overridden\\n * prior to executing the call. State overrides allow you to customize the network state for\\n * the purpose of the simulation, so this feature is useful when you need to estimate gas\\n * for user operation scenarios under conditions that aren’t currently present on the live network.\\n */\\n stateOverride: StateOverride;\\n } & UserOperationPaymasterOverrides<TEntryPointVersion>\\n>;
An interface that defines the structure for the response received from the RPC method eth_getUserOperationReceipt
. It includes details like sender, nonce, gas cost, and success status of the UserOperation
.
// [!include ~/../aa-sdk/core/src/types.ts#UserOperationReceipt
Interface for the request format required for a JSON-RPC request to eth_sendUserOperation
. It includes sender, nonce, gas limits, fees, and more fields.
// [!include ~/../aa-sdk/core/src/types.ts#UserOperationRequest
An interface that defines the structure for the response received from the RPC method eth_getUserOperationByHash
, detailing the result of executing a UserOperation
. It includes the block number, block hash, transaction hash and more information associated with the UO.
// [!include ~/../aa-sdk/core/src/types.ts#UserOperationResponse
Interface for structuring a UserOperation
, with fields similar to UserOperationRequest
but used for building requests.
// [!include ~/../aa-sdk/core/src/types.ts#UserOperationStruct
You may have noticed in the Demo App that you can allow a user to login with an existing passkey, but there's no way to sign-up with a passkey. This guide will outline\\nhow to add a passkey to a user's account after they've signed up.
\\nIf you're not sure how to authenticate your users, see this guide.
\\n\",\"id\":\"pages/react/add-passkey.mdx#add-passkey\",\"isPage\":true,\"text\":\"\\nYou may have noticed in the Demo App that you can allow a user to login with an existing passkey, but there's no way to sign-up with a passkey. This guide will outline\\nhow to add a passkey to a user's account after they've signed up.\\nIf you're not sure how to authenticate your users, see this guide.\\n\",\"title\":\"Add passkey\",\"titles\":[]},{\"href\":\"/react/add-passkey#add-a-passkey-on-sign-up\",\"html\":\"\\nThe easiest way to add a passkey to users is right when they signup! This can be done by updating your ui
config in the createConfig
call to enable the UI components to prompt the user for a passkey.
// @noErrors\\nimport { createConfig } from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\n \\nexport const config = createConfig(\\n {\\n chain: sepolia,\\n apiKey: "ALCHEMY_API_KEY",\\n },\\n {\\n illustrationStyle: "outline",\\n auth: {\\n sections: [[{ type: "email" }], [{ type: "passkey" }]],\\n addPasskeyOnSignup: true, \\n },\\n }\\n);
\\nNow, when a user signs up, they will be prompted to create a passkey.
\\n\",\"id\":\"pages/react/add-passkey.mdx#add-a-passkey-on-sign-up\",\"isPage\":false,\"text\":\"\\nThe easiest way to add a passkey to users is right when they signup! This can be done by updating your ui config in the createConfig call to enable the UI components to prompt the user for a passkey.\\n// @noErrors\\nimport { createConfig } from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\n \\nexport const config = createConfig(\\n {\\n chain: sepolia,\\n apiKey: "ALCHEMY_API_KEY",\\n },\\n {\\n illustrationStyle: "outline",\\n auth: {\\n sections: [[{ type: "email" }], [{ type: "passkey" }]],\\n addPasskeyOnSignup: true, \\n },\\n }\\n);\\nNow, when a user signs up, they will be prompted to create a passkey.\\n\",\"title\":\"Add a passkey on sign up\",\"titles\":[\"Add passkey\"]},{\"href\":\"/react/add-passkey#add-a-passkey-later\",\"html\":\"\\nWith the above config, the user will only be prompted when they first create their account in your app. If you want to add the ability to add a passkey elsewhere in your app, for example in a settings page, you can use the useAddPasskey
hook.
import React from "react";\\nimport { useAddPasskey } from "@account-kit/react";\\n \\nexport default function MyComponent() {\\n const { addPasskey, isAddingPasskey } = useAddPasskey();\\n \\n return (\\n <button\\n disabled={isAddingPasskey}\\n onClick={() => {\\n addPasskey();\\n }}\\n >\\n Add Passkey\\n </button>\\n );\\n}
\",\"id\":\"pages/react/add-passkey.mdx#add-a-passkey-later\",\"isPage\":false,\"text\":\"\\nWith the above config, the user will only be prompted when they first create their account in your app. If you want to add the ability to add a passkey elsewhere in your app, for example in a settings page, you can use the useAddPasskey hook.\\nThis hook requires that the user already be authenticated or else it will throw an error!\\nimport React from "react";\\nimport { useAddPasskey } from "@account-kit/react";\\n \\nexport default function MyComponent() {\\n const { addPasskey, isAddingPasskey } = useAddPasskey();\\n \\n return (\\n <button\\n disabled={isAddingPasskey}\\n onClick={() => {\\n addPasskey();\\n }}\\n >\\n Add Passkey\\n </button>\\n );\\n}\",\"title\":\"Add a passkey later\",\"titles\":[\"Add passkey\"]}]}],[\"index.cb1131960f585f06c6f10e3ee137e13cb3a1044b8d7a0afd5662b01c085089c1\",{\"mdx\":\"---\\ntitle: Smart Contract Account\\ndescription: What is a smart contract account in Account Kit?\\n---\\n\\n# Smart Contract Account\\n\\nThe [`SmartContractAccount`](#TODO/link-to-type) interface within Account Kit is the client-side definition of an on-chain smart contract implementation.\\nThis interface is an extension of `viem`'s [`Account`](https://viem.sh/docs/accounts/local/toAccount#toaccount) interface, and provides a way to interact with smart contract accounts in a type-safe manner.\\n\\nWithin Account Kit, implementations for Light Account and Modular Account are exported from `@account-kit/smart-contracts`. These implementations handle the logic for generating the deployment data, encoding\\nsingle and batch UO execution, and signing of messages, typed data, and UOs.\\n\\nSmart Contract Accounts are rarely used on their own, and are typically passed in to [Smart Account Client](#TODO/concepts/smart-account-client) implementations.\\nWhen using either the [React](/react/overview) or [Core](/core/overview) libraries, the connection of an account and a client are handled for you.\\n\\n## Custom accounts\\n\\nIt's also possible to use a custom account when using the [Infra](/infra/overview) library.\\nWithin `@aa-sdk/core`, a method [`toSmartContractAccount`](/reference/aa-sdk/core/functions/toSmartContractAccount) is provided so you can create an instance of your Smart Contract Account.\\n\",\"document\":[{\"href\":\"/concepts/smart-contract-account#smart-contract-account\",\"html\":\"\\nThe SmartContractAccount
interface within Account Kit is the client-side definition of an on-chain smart contract implementation.\\nThis interface is an extension of viem
's Account
interface, and provides a way to interact with smart contract accounts in a type-safe manner.
Within Account Kit, implementations for Light Account and Modular Account are exported from @account-kit/smart-contracts
. These implementations handle the logic for generating the deployment data, encoding\\nsingle and batch UO execution, and signing of messages, typed data, and UOs.
Smart Contract Accounts are rarely used on their own, and are typically passed in to Smart Account Client implementations.\\nWhen using either the React or Core libraries, the connection of an account and a client are handled for you.
\\n\",\"id\":\"pages/concepts/smart-contract-account.mdx#smart-contract-account\",\"isPage\":true,\"text\":\"\\nThe SmartContractAccount interface within Account Kit is the client-side definition of an on-chain smart contract implementation.\\nThis interface is an extension of viem's Account interface, and provides a way to interact with smart contract accounts in a type-safe manner.\\nWithin Account Kit, implementations for Light Account and Modular Account are exported from @account-kit/smart-contracts. These implementations handle the logic for generating the deployment data, encoding\\nsingle and batch UO execution, and signing of messages, typed data, and UOs.\\nSmart Contract Accounts are rarely used on their own, and are typically passed in to Smart Account Client implementations.\\nWhen using either the React or Core libraries, the connection of an account and a client are handled for you.\\n\",\"title\":\"Smart Contract Account\",\"titles\":[]},{\"href\":\"/concepts/smart-contract-account#custom-accounts\",\"html\":\"\\nIt's also possible to use a custom account when using the Infra library.\\nWithin @aa-sdk/core
, a method toSmartContractAccount
is provided so you can create an instance of your Smart Contract Account.
Once your users have been authenticated, you can start sending user operations! Account Kit makes it really easy to send user operations using React hooks.
\\nSending user operations is really easy, since all you have to do is use the useSendUserOperation
hook.\\nIf you want to sponsor the gas for a user, see our guide.
import React from "react";\\nimport {\\n type UseSendUserOperationResult,\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nexport default function MyOpSenderComponent() {\\n const { client } = useSmartAccountClient({ type: "LightAccount" });\\n \\n const { sendUserOperation, isSendingUserOperation } = useSendUserOperation({\\n client,\\n // optional parameter that will wait for the transaction to be mined before returning\\n waitForTxn: true,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendUserOperation({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n })\\n }\\n disabled={isSendingUserOperation}\\n >\\n {isSendingUserOperation ? "Sending..." : "Send UO"}\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/react/send-user-operations.mdx#single-user-operation\",\"isPage\":false,\"text\":\"\\nIn the below example, we use LightAccount as the underlying Smart Contract type. You can also use MultiOwnerModularAccount if you want to provide your users with an ERC-6900 compliant modular account,\\nor you can use MultiOwnerLightAccount if you want to support an account with multiple owners.\\nimport React from "react";\\nimport {\\n type UseSendUserOperationResult,\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nexport default function MyOpSenderComponent() {\\n const { client } = useSmartAccountClient({ type: "LightAccount" });\\n \\n const { sendUserOperation, isSendingUserOperation } = useSendUserOperation({\\n client,\\n // optional parameter that will wait for the transaction to be mined before returning\\n waitForTxn: true,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendUserOperation({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n })\\n }\\n disabled={isSendingUserOperation}\\n >\\n {isSendingUserOperation ? "Sending..." : "Send UO"}\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Single user operation\",\"titles\":[\"Send user operations\"]},{\"href\":\"/react/send-user-operations#batch-user-operation\",\"html\":\"\\nIt's also possible to send user operations in batch using the same hook.
\\nimport React from "react";\\nimport {\\n type UseSendUserOperationResult,\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nexport default function MyOpSenderComponent() {\\n const { client } = useSmartAccountClient({ type: "LightAccount" });\\n \\n const { sendUserOperation, isSendingUserOperation } = useSendUserOperation({\\n client,\\n // optional parameter that will wait for the transaction to be mined before returning\\n waitForTxn: true,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendUserOperation({\\n uo: [\\n {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n ],\\n })\\n }\\n disabled={isSendingUserOperation}\\n >\\n {isSendingUserOperation ? "Sending..." : "Send UO"}\\n </button>\\n </div>\\n );\\n}
\",\"id\":\"pages/react/send-user-operations.mdx#batch-user-operation\",\"isPage\":false,\"text\":\"\\nIt's also possible to send user operations in batch using the same hook.\\nimport React from "react";\\nimport {\\n type UseSendUserOperationResult,\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nexport default function MyOpSenderComponent() {\\n const { client } = useSmartAccountClient({ type: "LightAccount" });\\n \\n const { sendUserOperation, isSendingUserOperation } = useSendUserOperation({\\n client,\\n // optional parameter that will wait for the transaction to be mined before returning\\n waitForTxn: true,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendUserOperation({\\n uo: [\\n {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n ],\\n })\\n }\\n disabled={isSendingUserOperation}\\n >\\n {isSendingUserOperation ? "Sending..." : "Send UO"}\\n </button>\\n </div>\\n );\\n}\",\"title\":\"Batch user operation\",\"titles\":[\"Send user operations\"]}]}],[\"index.40b4feeca736e0d649ec983f115f8817eb4cb33b6bf8f221e738baef9d7c6a14\",{\"mdx\":\"---\\ntitle: Account Kit\\ndescription: Account Kit is a vertically integrated stack for building apps that support ERC-4337 smart accounts, Signer integrations, sponsoring gas, bundlers, and an SDK.\\nlayout: docs\\n---\\n\\nimport { TileButton, SmallTileRow } from \\\"../components/TileButton\\\";\\nimport { ClockForwardIcon } from \\\"../components/icons/ClockForwardIcon\\\";\\nimport { PointerIcon } from \\\"../components/icons/PointerIcon\\\";\\nimport { DotsIcon } from \\\"../components/icons/DotsIcon\\\";\\nimport { InfraIcon } from \\\"../components/icons/InfraIcon\\\";\\nimport { SmartContractIcon } from \\\"../components/icons/SmartContractIcon\\\";\\nimport { SignerIcon } from \\\"../components/icons/SignerIcon\\\";\\n\\n# Build Embedded Accounts with Account Kit\\n\\nBuild zero friction sign up and transaction flows with smart accounts. Sign up with email, login with passkeys, transact with sponsored gas, and checkout in one click with transaction batching.\\n\\nCurrent chain: {chain.name}
\\n \\n \\nAccount Kit supports multi-chain apps, allowing you to build applications that interact with multiple blockchains. This guide will show you how to set up your app to work with multiple chains.
\\n\",\"id\":\"pages/react/multi-chain-apps.mdx#multi-chain-apps\",\"isPage\":true,\"text\":\"\\nAccount Kit supports multi-chain apps, allowing you to build applications that interact with multiple blockchains. This guide will show you how to set up your app to work with multiple chains.\\n\",\"title\":\"Multi-chain Apps\",\"titles\":[]},{\"href\":\"/react/multi-chain-apps#update-your-config\",\"html\":\"\\nIn order to support multiple chains in your app, the first thing you need to do is update your createConfig
call to include the chains you want to support.
// @noErrors\\nimport { createConfig } from "@account-kit/react";\\nimport { sepolia, mainnet } from "@account-kit/infra";\\n \\nexport const config = createConfig({\\n apiKey: "ALCHEMY_API_KEY",\\n // this is the default chain\\n chain: sepolia,\\n chains: [\\n {\\n chain: mainnet, // optional: you can specify a policy ID for this chain, if you want to sponsor gas\\n policyId: "MAINNET_GAS_MANAGER_POLICY_ID",\\n },\\n {\\n chain: sepolia,\\n // optional: you can specify a policy ID for this chain, if you want to sponsor gas\\n policyId: "SEPOLIA_GAS_MANAGER_POLICY_ID",\\n },\\n ],\\n});
\\n\",\"id\":\"pages/react/multi-chain-apps.mdx#update-your-config\",\"isPage\":false,\"text\":\"\\nIn order to support multiple chains in your app, the first thing you need to do is update your createConfig call to include the chains you want to support.\\n// @noErrors\\nimport { createConfig } from "@account-kit/react";\\nimport { sepolia, mainnet } from "@account-kit/infra";\\n \\nexport const config = createConfig({\\n apiKey: "ALCHEMY_API_KEY",\\n // this is the default chain\\n chain: sepolia,\\n chains: [\\n {\\n chain: mainnet, // optional: you can specify a policy ID for this chain, if you want to sponsor gas\\n policyId: "MAINNET_GAS_MANAGER_POLICY_ID",\\n },\\n {\\n chain: sepolia,\\n // optional: you can specify a policy ID for this chain, if you want to sponsor gas\\n policyId: "SEPOLIA_GAS_MANAGER_POLICY_ID",\\n },\\n ],\\n});\\n\",\"title\":\"Update your config\",\"titles\":[\"Multi-chain Apps\"]},{\"href\":\"/react/multi-chain-apps#change-chains\",\"html\":\"\\nOnce your app is configured to use multiple chains, you can switch between them at any time using the useChain
hook.
import React from "react";\\nimport { useChain } from "@account-kit/react";\\nimport { mainnet, sepolia } from "@account-kit/infra";\\n \\nexport default function MyComponent() {\\n const { chain, setChain } = useChain();\\n \\n return (\\n <div>\\n <p>Current chain: {chain.name}</p>\\n <button onClick={() => setChain({ chain: mainnet })}>\\n Switch to Mainnet\\n </button>\\n <button onClick={() => setChain({ chain: sepolia })}>\\n Switch to Sepolia\\n </button>\\n </div>\\n );\\n}
\",\"id\":\"pages/react/multi-chain-apps.mdx#change-chains\",\"isPage\":false,\"text\":\"\\nOnce your app is configured to use multiple chains, you can switch between them at any time using the useChain hook.\\nimport React from "react";\\nimport { useChain } from "@account-kit/react";\\nimport { mainnet, sepolia } from "@account-kit/infra";\\n \\nexport default function MyComponent() {\\n const { chain, setChain } = useChain();\\n \\n return (\\n <div>\\n <p>Current chain: {chain.name}</p>\\n <button onClick={() => setChain({ chain: mainnet })}>\\n Switch to Mainnet\\n </button>\\n <button onClick={() => setChain({ chain: sepolia })}>\\n Switch to Sepolia\\n </button>\\n </div>\\n );\\n}\",\"title\":\"Change chains\",\"titles\":[\"Multi-chain Apps\"]}]}],[\"index.209524bfb9e9d700b7389bba4e6d5de62f43957887c37fc7ba93b4940976048b\",{\"mdx\":\"---\\noutline: deep\\ntitle: Choosing a Signer\\ndescription: Explore Account Kit integration guides for signers including Magic.Link, Privy, Web3Auth, EOAs, and many more!\\n---\\n\\n# What is a Signer?\\n\\nA **Signer** is a service (e.g. Magic or Turnkey) or application (e.g. MetaMask) that manages the private key and signs operations. Most web3 users today use an [Externally Owned Account (EOA)](https://ethereum.org/en/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) with a self-custodial Signer such as MetaMask to manage the private key.\\n\\nWith Account Kit, you will deploy a **smart account** for each user instead of an EOA wallet. This smart account stores the user's assets (e.g. tokens or NFTs).\\n\\nThe signer connected to the `SmartAccountClient` is used to sign messages, data including user operations and transactions. The signatures for the user operation will be only valid and execute if the signer is the owner or one of the owners of the account.\\n\\nYou can choose any Signer service or application to manage the Owner private key for the user. Using services like Magic, Turnkey, or Web3auth, you can secure the user's account with an email, social login, or passkeys. You can also use a self-custodial wallet like MetaMask as the Signer.\\n\\nThis doc provides a basic introduction to signers and the criteria you should consider when choosing which Signer to use with Account Kit in your application.\\n\\n## Role of a Signer\\n\\nThe Signer plays a crucial role in your app because it controls the user’s smart account. The Signer is responsible for:\\n\\n- Securely storing the user’s private key which controls the user’s assets\\n- Authenticating the user\\n- Protecting the user’s account from phishing attacks\\n- Signing user operations requested by the user, if and only if the user has authenticated\\n- Optionally offering account recovery methods\\n\\n## Criteria to consider\\n\\nHere are some important criteria to consider when choosing a Signer.\\n\\n- **Custody model:** Who has access to the private key?\\n - Self-Custodial: the end user controls the private key and manually approves signature requests\\n - Non-Custodial: a third-party service manages the private key or a subset of the key shares, but cannot sign transactions without the user’s involvement\\n - Custodial: a third-party service manages the private key and can sign transactions without the user’s involvement\\n- **Security model**: Assess the security model of the provider. Where is the private key stored? (on a device? in the cloud? on what cloud provider?) Is the private key encrypted? What encryption algorithm is used? Who has access to the decryption keys? This is a non-exhaustive list and we recommend doing further research.\\n- **Authentication methods:** What authentication method delivers the right balance of security, self-sovereignty, and ease-of-use for your target users?\\n - Email + Password: sign up for a smart account with an email and password.\\n - Social logins: sign up for a smart account with Google, Facebook, or other social logins.\\n - Passkeys: sign up for a smart account secured by a passkey (e.g. fingerprint or Face ID) stored on-device.\\n - Self custodial Wallet: sign up for a smart account using a self-custodial wallet such as MetaMask or Ledger.\\n- **Availability:** If the Signer service provider goes down, will users be able to sign transactions?\\n- **Key export:** Does the Signer allow the end user to export their private key? Can the user initiate an export even if the service provider has gone down? This is an important factor to ensure the user retains control of their assets no matter what happens to the service provider.\\n- **Key recovery**: If the user forgets their password or loses their passkey, what recovery methods does the Signer provide? If the provider stores a backup copy of the private key or MPC key shares, where are those backups stored and who has access to them?\\n\\n## Types of Signers\\n\\n### Non-custodial wallets\\n\\nNon-custodial wallet providers store private keys such that they cannot access the private key without the user’s involvement. For example, the user must provide a password or passkey that only they know in order to decrypt the private key stored by the provider. Users benefit from heightened security, while remaining in control of their private keys at all times. This is similar to a safety deposit box vault: the provider secures the bank vault but only the user has access to the individual safety deposit boxes (e.g. wallets).\\n\\n**Example**: Turnkey, Magic\\n\\n### MPC wallets (non-custodial)\\n\\nMulti-Party Computation (MPC) Signers split the Owner Account private key into key shares that are then distributed to a number of share holders. Share holders only know the value of their key share and transaction holders can sign transactions without revealing their key shares to other holders.\\n\\nValid signatures do not always require all shares to sign a transaction. MPC Signers can set a threshold, requiring a certain number of shares for a signature to be valid. Common configurations are 2 of 2 shares or 2 of 3 shares. By requiring multiple shares, MPC models mitigate the risks associated with a single key being compromised.\\n\\nSome MPC signers provide recovery services in which key share(s) are backed up in the service provider’s cloud, on the end user’s device, or in the end user’s cloud (e.g. iCloud or Google Drive). When evaluating an MPC provider, it’s important to under where each key share is stored.\\n\\n**Example**: Privy, Fireblocks MPC, Portal, Capsule, WalletKit\\n\\n:::details[TSS vs SSSS]\\n\\nThere are two common approaches to MPC.\\n\\nTraditionally, MPC services leveraged SSSS (Shamir’s Secret Shard Sharing). This approach generates a private key in one location and then the shares are distributed to the parties involved. When a user wants to sign, they need to retrieve N of M shares and reconstruct the key locally.\\n\\nAn improvement on SSSS is Threshold Signature Scheme (TSS). In this model, the key is never recreated during signing. Instead, each party is given the message to sign and then signs the payload locally before broadcasting the signature to the rest of the group. This allows for the key material to remain private and deconstructed.\\n\\nTSS is safer than SSSS because is possible to create the initial shares without ever constructing the original key on any one device. However, the tradeoff is that signing requires a Peer-to-Peer exchange which introduces latency.\\n\\nYou can read more about the difference between TSS and SSSS [here](https://www.dynamic.xyz/blog/the-evolution-of-multi-signature-and-multi-party-computation).\\n:::\\n\\n### Decentralized MPC network (non-custodial)\\n\\nA decentralized MPC network is an extension on the MPC approach outlined above. Instead of relying on a single, centralized service to store a key share and initiate signature requests, an MPC network distributes this responsibility across many nodes in a network. The user’s private key is split into many key shares with each share store by a different node. The user may request signatures from the network and a valid signature will be produced if and only if a threshold number of nodes agree to sign the request.\\n\\nExamples: Lit Protocol, Web3Auth (Torus Network)\\n\\n### Self-custodial wallet\\n\\nSelf-custodial wallets store the private key locally where only the end user can access it. For example, the user may store their seed phrase in a browser extension, in a mobile app using their phone’s secure enclave, or in a hardware wallet. When using a self-custodial wallet, the user is the only one with the power to sign transactions.\\n\\nSelf-custodial wallets require the user to maintain good security hygiene at all times. They also rely on the user to backup a copy of their private key in the event the wallet is lost or destroyed. If the user loses access to the device on which their private key is stored, they will have no way to recover the account unless they backed up the private key in another device or location.\\n\\n**Example**: MetaMask, Ledger\\n\\n### Custodial wallet\\n\\nCustodial wallet providers have full control over the user’s private key and sign transactions on behalf of the user. These services typically implement security measures to ensure that only the authorized user(s) can request a signature. These providers are also typically regulated entities (e.g., qualified custodians). The user must trust this service provider to securely store the private key and sign transactions if and only if the user wishes.\\n\\n**Example**: Coinbase Custody, Bitgo\\n\\n## Supported signers\\n\\n:::tip\\nWhen using the [React](/react/overview) or [Core](/core/overview) libraries, all of the account instances are created with the `AlchemyWebSigner` as an owner on the accounts.\\n:::\\n\\nThe Smart Account Signer interface is used to define an owner for [Smart Contract Accounts](/concepts/smart-contract-account).\\nThe interface takes two forms:\\n\\n1. `SmartAccountSigner` -- This is the base interface for all signer. It defines methods for signing messages and typed data, as well as getting the address of the signer.\\n2. `SmartAccountAuthenticator` -- This is an extension of the `SmartAccountSigner` that exposes additional methods for Signers that require authentication before signing.\\n\\nWithin Account Kit and `@aa-sdk/core`, we provide a number of implementations for `SmartAccountSigner` and `SmartAccountAuthenticator`:\\n\\n1. [`AlchemyWebSigner`](/reference/account-kit/signer/classes/AlchemyWebSigner/constructor) - This is an implementation of the `SmartAccountAuthenticator` that uses the our signer service to provision private keys securely\\n for end users. It allows you to authenticate your users with methods more familiar to them, such as email or social login.\\n2. [`LocalAccountSigner`](/reference/aa-sdk/core/classes/LocalAccountSigner/constructor) - This signer is useful if you have a mnemonic or private key locally that you want to use as an\\n owner of a smart contract account. This is useful for testing and development purposes.\\n3. [`WalletClientSigner`](/reference/aa-sdk/core/classes/WalletClientSigner/constructor) - This signer is useful if you want to use a [wallet client](https://viem.sh/docs/clients/wallet) as an owner.\\n Since a wallet client can wrap any [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compliant provider, this is useful if you want to use EOA extensions or 3rd party signer service SDKs.\\n\\n---\\n\\n_Disclaimer: This page refers to third-party services, products software, technology, and content (collectively, “Third-Party Services”) that may be integrated or interact with Alchemy’s software and services. Alchemy is not responsible for any Third-Party Service, or for any compatibility issues, errors, or bugs caused in whole or in part by the Third-Party Service or any update or upgrade thereto. Your use of any Third-Party Service is at your own risk. You are responsible for obtaining any associated licenses and consents to the extent necessary for you to use the Third-Party Services. Your use of the Third-Party Services may be subject to separate terms and conditions set forth by the provider (including disclaimers or warnings), separate fees or charges, or a separate privacy notice. You are responsible for understanding and complying with any such terms or privacy notice._\\n\",\"document\":[{\"href\":\"/concepts/smart-account-signer#what-is-a-signer\",\"html\":\"\\nA Signer is a service (e.g. Magic or Turnkey) or application (e.g. MetaMask) that manages the private key and signs operations. Most web3 users today use an Externally Owned Account (EOA) with a self-custodial Signer such as MetaMask to manage the private key.
\\nWith Account Kit, you will deploy a smart account for each user instead of an EOA wallet. This smart account stores the user's assets (e.g. tokens or NFTs).
\\nThe signer connected to the SmartAccountClient
is used to sign messages, data including user operations and transactions. The signatures for the user operation will be only valid and execute if the signer is the owner or one of the owners of the account.
You can choose any Signer service or application to manage the Owner private key for the user. Using services like Magic, Turnkey, or Web3auth, you can secure the user's account with an email, social login, or passkeys. You can also use a self-custodial wallet like MetaMask as the Signer.
\\nThis doc provides a basic introduction to signers and the criteria you should consider when choosing which Signer to use with Account Kit in your application.
\\n\",\"id\":\"pages/concepts/smart-account-signer.mdx#what-is-a-signer\",\"isPage\":true,\"text\":\"\\nA Signer is a service (e.g. Magic or Turnkey) or application (e.g. MetaMask) that manages the private key and signs operations. Most web3 users today use an Externally Owned Account (EOA) with a self-custodial Signer such as MetaMask to manage the private key.\\nWith Account Kit, you will deploy a smart account for each user instead of an EOA wallet. This smart account stores the user's assets (e.g. tokens or NFTs).\\nThe signer connected to the SmartAccountClient is used to sign messages, data including user operations and transactions. The signatures for the user operation will be only valid and execute if the signer is the owner or one of the owners of the account.\\nYou can choose any Signer service or application to manage the Owner private key for the user. Using services like Magic, Turnkey, or Web3auth, you can secure the user's account with an email, social login, or passkeys. You can also use a self-custodial wallet like MetaMask as the Signer.\\nThis doc provides a basic introduction to signers and the criteria you should consider when choosing which Signer to use with Account Kit in your application.\\n\",\"title\":\"What is a Signer?\",\"titles\":[]},{\"href\":\"/concepts/smart-account-signer#role-of-a-signer\",\"html\":\"\\nThe Signer plays a crucial role in your app because it controls the user’s smart account. The Signer is responsible for:
\\nHere are some important criteria to consider when choosing a Signer.
\\nNon-custodial wallet providers store private keys such that they cannot access the private key without the user’s involvement. For example, the user must provide a password or passkey that only they know in order to decrypt the private key stored by the provider. Users benefit from heightened security, while remaining in control of their private keys at all times. This is similar to a safety deposit box vault: the provider secures the bank vault but only the user has access to the individual safety deposit boxes (e.g. wallets).
\\nExample: Turnkey, Magic
\\n\",\"id\":\"pages/concepts/smart-account-signer.mdx#non-custodial-wallets\",\"isPage\":false,\"text\":\"\\nNon-custodial wallet providers store private keys such that they cannot access the private key without the user’s involvement. For example, the user must provide a password or passkey that only they know in order to decrypt the private key stored by the provider. Users benefit from heightened security, while remaining in control of their private keys at all times. This is similar to a safety deposit box vault: the provider secures the bank vault but only the user has access to the individual safety deposit boxes (e.g. wallets).\\nExample: Turnkey, Magic\\n\",\"title\":\"Non-custodial wallets\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]},{\"href\":\"/concepts/smart-account-signer#mpc-wallets-non-custodial\",\"html\":\"\\nMulti-Party Computation (MPC) Signers split the Owner Account private key into key shares that are then distributed to a number of share holders. Share holders only know the value of their key share and transaction holders can sign transactions without revealing their key shares to other holders.
\\nValid signatures do not always require all shares to sign a transaction. MPC Signers can set a threshold, requiring a certain number of shares for a signature to be valid. Common configurations are 2 of 2 shares or 2 of 3 shares. By requiring multiple shares, MPC models mitigate the risks associated with a single key being compromised.
\\nSome MPC signers provide recovery services in which key share(s) are backed up in the service provider’s cloud, on the end user’s device, or in the end user’s cloud (e.g. iCloud or Google Drive). When evaluating an MPC provider, it’s important to under where each key share is stored.
\\nExample: Privy, Fireblocks MPC, Portal, Capsule, WalletKit
\\nThere are two common approaches to MPC.
Traditionally, MPC services leveraged SSSS (Shamir’s Secret Shard Sharing). This approach generates a private key in one location and then the shares are distributed to the parties involved. When a user wants to sign, they need to retrieve N of M shares and reconstruct the key locally.
An improvement on SSSS is Threshold Signature Scheme (TSS). In this model, the key is never recreated during signing. Instead, each party is given the message to sign and then signs the payload locally before broadcasting the signature to the rest of the group. This allows for the key material to remain private and deconstructed.
TSS is safer than SSSS because is possible to create the initial shares without ever constructing the original key on any one device. However, the tradeoff is that signing requires a Peer-to-Peer exchange which introduces latency.
You can read more about the difference between TSS and SSSS here.
A decentralized MPC network is an extension on the MPC approach outlined above. Instead of relying on a single, centralized service to store a key share and initiate signature requests, an MPC network distributes this responsibility across many nodes in a network. The user’s private key is split into many key shares with each share store by a different node. The user may request signatures from the network and a valid signature will be produced if and only if a threshold number of nodes agree to sign the request.
\\nExamples: Lit Protocol, Web3Auth (Torus Network)
\\n\",\"id\":\"pages/concepts/smart-account-signer.mdx#decentralized-mpc-network-non-custodial\",\"isPage\":false,\"text\":\"\\nA decentralized MPC network is an extension on the MPC approach outlined above. Instead of relying on a single, centralized service to store a key share and initiate signature requests, an MPC network distributes this responsibility across many nodes in a network. The user’s private key is split into many key shares with each share store by a different node. The user may request signatures from the network and a valid signature will be produced if and only if a threshold number of nodes agree to sign the request.\\nExamples: Lit Protocol, Web3Auth (Torus Network)\\n\",\"title\":\"Decentralized MPC network (non-custodial)\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]},{\"href\":\"/concepts/smart-account-signer#self-custodial-wallet\",\"html\":\"\\nSelf-custodial wallets store the private key locally where only the end user can access it. For example, the user may store their seed phrase in a browser extension, in a mobile app using their phone’s secure enclave, or in a hardware wallet. When using a self-custodial wallet, the user is the only one with the power to sign transactions.
\\nSelf-custodial wallets require the user to maintain good security hygiene at all times. They also rely on the user to backup a copy of their private key in the event the wallet is lost or destroyed. If the user loses access to the device on which their private key is stored, they will have no way to recover the account unless they backed up the private key in another device or location.
\\nExample: MetaMask, Ledger
\\n\",\"id\":\"pages/concepts/smart-account-signer.mdx#self-custodial-wallet\",\"isPage\":false,\"text\":\"\\nSelf-custodial wallets store the private key locally where only the end user can access it. For example, the user may store their seed phrase in a browser extension, in a mobile app using their phone’s secure enclave, or in a hardware wallet. When using a self-custodial wallet, the user is the only one with the power to sign transactions.\\nSelf-custodial wallets require the user to maintain good security hygiene at all times. They also rely on the user to backup a copy of their private key in the event the wallet is lost or destroyed. If the user loses access to the device on which their private key is stored, they will have no way to recover the account unless they backed up the private key in another device or location.\\nExample: MetaMask, Ledger\\n\",\"title\":\"Self-custodial wallet\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]},{\"href\":\"/concepts/smart-account-signer#custodial-wallet\",\"html\":\"\\nCustodial wallet providers have full control over the user’s private key and sign transactions on behalf of the user. These services typically implement security measures to ensure that only the authorized user(s) can request a signature. These providers are also typically regulated entities (e.g., qualified custodians). The user must trust this service provider to securely store the private key and sign transactions if and only if the user wishes.
\\nExample: Coinbase Custody, Bitgo
\\n\",\"id\":\"pages/concepts/smart-account-signer.mdx#custodial-wallet\",\"isPage\":false,\"text\":\"\\nCustodial wallet providers have full control over the user’s private key and sign transactions on behalf of the user. These services typically implement security measures to ensure that only the authorized user(s) can request a signature. These providers are also typically regulated entities (e.g., qualified custodians). The user must trust this service provider to securely store the private key and sign transactions if and only if the user wishes.\\nExample: Coinbase Custody, Bitgo\\n\",\"title\":\"Custodial wallet\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]},{\"href\":\"/concepts/smart-account-signer#supported-signers\",\"html\":\"\\n\\nThe Smart Account Signer interface is used to define an owner for Smart Contract Accounts.\\nThe interface takes two forms:
\\nSmartAccountSigner
-- This is the base interface for all signer. It defines methods for signing messages and typed data, as well as getting the address of the signer.SmartAccountAuthenticator
-- This is an extension of the SmartAccountSigner
that exposes additional methods for Signers that require authentication before signing.Within Account Kit and @aa-sdk/core
, we provide a number of implementations for SmartAccountSigner
and SmartAccountAuthenticator
:
AlchemyWebSigner
- This is an implementation of the SmartAccountAuthenticator
that uses the our signer service to provision private keys securely\\nfor end users. It allows you to authenticate your users with methods more familiar to them, such as email or social login.LocalAccountSigner
- This signer is useful if you have a mnemonic or private key locally that you want to use as an\\nowner of a smart contract account. This is useful for testing and development purposes.WalletClientSigner
- This signer is useful if you want to use a wallet client as an owner.\\nSince a wallet client can wrap any EIP-1193 compliant provider, this is useful if you want to use EOA extensions or 3rd party signer service SDKs.Disclaimer: This page refers to third-party services, products software, technology, and content (collectively, “Third-Party Services”) that may be integrated or interact with Alchemy’s software and services. Alchemy is not responsible for any Third-Party Service, or for any compatibility issues, errors, or bugs caused in whole or in part by the Third-Party Service or any update or upgrade thereto. Your use of any Third-Party Service is at your own risk. You are responsible for obtaining any associated licenses and consents to the extent necessary for you to use the Third-Party Services. Your use of the Third-Party Services may be subject to separate terms and conditions set forth by the provider (including disclaimers or warnings), separate fees or charges, or a separate privacy notice. You are responsible for understanding and complying with any such terms or privacy notice.
\",\"id\":\"pages/concepts/smart-account-signer.mdx#supported-signers\",\"isPage\":false,\"text\":\"\\nWhen using the React or Core libraries, all of the account instances are created with the AlchemyWebSigner as an owner on the accounts.\\nThe Smart Account Signer interface is used to define an owner for Smart Contract Accounts.\\nThe interface takes two forms:\\n\\nSmartAccountSigner -- This is the base interface for all signer. It defines methods for signing messages and typed data, as well as getting the address of the signer.\\nSmartAccountAuthenticator -- This is an extension of the SmartAccountSigner that exposes additional methods for Signers that require authentication before signing.\\n\\nWithin Account Kit and @aa-sdk/core, we provide a number of implementations for SmartAccountSigner and SmartAccountAuthenticator:\\n\\nAlchemyWebSigner - This is an implementation of the SmartAccountAuthenticator that uses the our signer service to provision private keys securely\\nfor end users. It allows you to authenticate your users with methods more familiar to them, such as email or social login.\\nLocalAccountSigner - This signer is useful if you have a mnemonic or private key locally that you want to use as an\\nowner of a smart contract account. This is useful for testing and development purposes.\\nWalletClientSigner - This signer is useful if you want to use a wallet client as an owner.\\nSince a wallet client can wrap any EIP-1193 compliant provider, this is useful if you want to use EOA extensions or 3rd party signer service SDKs.\\n\\n\\nDisclaimer: This page refers to third-party services, products software, technology, and content (collectively, “Third-Party Services”) that may be integrated or interact with Alchemy’s software and services. Alchemy is not responsible for any Third-Party Service, or for any compatibility issues, errors, or bugs caused in whole or in part by the Third-Party Service or any update or upgrade thereto. Your use of any Third-Party Service is at your own risk. You are responsible for obtaining any associated licenses and consents to the extent necessary for you to use the Third-Party Services. Your use of the Third-Party Services may be subject to separate terms and conditions set forth by the provider (including disclaimers or warnings), separate fees or charges, or a separate privacy notice. You are responsible for understanding and complying with any such terms or privacy notice.\",\"title\":\"Supported signers\",\"titles\":[\"What is a Signer?\"]}]}],[\"index.7e294b9eca9808c27e5d6440c3ca0428f1436a2be524f457ff883a056c8556c6\",{\"mdx\":\"---\\ntitle: Send User Operations\\ndescription: Learn how to send user operations using Alchemy's infrastructure\\n---\\n\\n# Send User Operations\\n\\nOnce you've completed the [Quickstart](/infra/quickstart), you're ready to start sending user operations!\\n\\nUser operations can be sent either as single user operations or as a batch of user operations. In this guide, we'll cover both methods.\\n\\n## Single User Operation\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { client } from \\\"./client\\\";\\n\\nconst { hash } = await client.sendUserOperation({\\n uo: {\\n target: \\\"0xTARGET_ADDRESS\\\",\\n data: \\\"0x\\\",\\n value: 0n,\\n },\\n});\\n```\\n\\n```ts twoslash [client.ts] filename=\\\"client.ts\\\"\\n// [!include ~/shared/infra/client.ts]\\n```\\n\\n:::\\n\\n## Batch User Operations\\n\\nTo batch user operations, you can just pass an array of user operations to the `sendUserOperation` method.\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { client } from \\\"./client\\\";\\n\\nconst { hash } = await client.sendUserOperation({\\n uo: [\\n {\\n target: \\\"0xTARGET_ADDRESS\\\",\\n data: \\\"0x\\\",\\n value: 0n,\\n },\\n {\\n target: \\\"0xTARGET_ADDRESS_2\\\",\\n data: \\\"0x\\\",\\n value: 0n,\\n },\\n ],\\n});\\n```\\n\\n```ts twoslash [client.ts] filename=\\\"client.ts\\\"\\n// [!include ~/shared/infra/client.ts]\\n```\\n\\n:::\\n\",\"document\":[{\"href\":\"/infra/send-user-operations#send-user-operations\",\"html\":\"\\nOnce you've completed the Quickstart, you're ready to start sending user operations!
\\nUser operations can be sent either as single user operations or as a batch of user operations. In this guide, we'll cover both methods.
\\n\",\"id\":\"pages/infra/send-user-operations.mdx#send-user-operations\",\"isPage\":true,\"text\":\"\\nOnce you've completed the Quickstart, you're ready to start sending user operations!\\nUser operations can be sent either as single user operations or as a batch of user operations. In this guide, we'll cover both methods.\\n\",\"title\":\"Send User Operations\",\"titles\":[]},{\"href\":\"/infra/send-user-operations#single-user-operation\",\"html\":\"\\n// @filename: client.ts\\n \\nimport { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});\\n// @filename: client.ts\\n \\nimport { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { client } from "./client";\\n \\nconst { hash } = await client.sendUserOperation({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n});
import { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});
To batch user operations, you can just pass an array of user operations to the sendUserOperation
method.
// @filename: client.ts\\n \\nimport { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});\\n// @filename: client.ts\\n \\nimport { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { client } from "./client";\\n \\nconst { hash } = await client.sendUserOperation({\\n uo: [\\n {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n {\\n target: "0xTARGET_ADDRESS_2",\\n data: "0x",\\n value: 0n,\\n },\\n ],\\n});
import { createAlchemySmartAccountClient, sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n// You can replace this with any signer you'd like\\n// We're using a LocalAccountSigner to generate a local key to sign with\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const client = createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n policyId: "YOUR_POLICY_ID",\\n chain: sepolia,\\n account: await createLightAccount({\\n chain: sepolia,\\n transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/YOUR_API_KEY`),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n }),\\n});
The @account-kit/infra
package provides client and middleware defintions for interacting with our ERC-4337 infrastructure. It makes it really easy to use just our infra (gas manager and bundler RPC) if you'd like more control over which smart contracts or signer you're using. The guides in this section of the\\nsite will help you get started with interacting with our infrastructure directly. If you're using this package directly you will need to make a decision on:
If there's anything we can do to improve your experience with Account Kit, please tell us!
\\n\",\"id\":\"pages/resources/contact-us.mdx#contact-us\",\"isPage\":true,\"text\":\"\\nIf there's anything we can do to improve your experience with Account Kit, please tell us!\\n\",\"title\":\"Contact us\",\"titles\":[]},{\"href\":\"/resources/contact-us#feedback\",\"html\":\"\\nIf you have any questions on how to get started, start a discussion in our github.
\\nIf you are interested in an enterprise plan with Alchemy to scale your application, connect with us at https://www.alchemy.com.
\\nIf you see a issue in our code or documentation, feel free to address it yourself! See this README on contributing to Account Kit's codebase.
\\nIf you are interested in ERC-6900 or modular account development, join the outreach waitlist or our Telegram group.
\\nSuccess!
\\n You're logged in as {user.email ?? \\\"anon\\\"}.\\nBecause the Alchemy Signer has its own address
and supports signing messages as raw hashes, it is possible to use this signer as an EOA directly. To do so, you can adapt the AlchemySigner to your library of choice and leverage its signMessage
, signTypedData
, and signTransaction
methods directly. The public address of the signer can be accessed via getAddress
.
If you are using viem, then you can use the toViemAccount
method which will allow you to use the signer with a WalletClient
.
// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\nimport { createWalletClient, http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nexport const walletClient = createWalletClient({\\n transport: http("alchemy_rpc_url"),\\n chain: sepolia,\\n account: signer.toViemAccount(),\\n});
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
This hasn't been tested extensively, but it is possible to use Account Kit within a React Native application. We've built a simple example using expo here. This guide assumes you're using Expo, but the same principles should apply to a bare React Native app as well.
\\n\\n\",\"id\":\"pages/resources/react-native.mdx#using-within-react-native-applications\",\"isPage\":true,\"text\":\"\\nThis hasn't been tested extensively, but it is possible to use Account Kit within a React Native application. We've built a simple example using expo here. This guide assumes you're using Expo, but the same principles should apply to a bare React Native app as well.\\nThe Alchemy Signer is not yet supported in React Native applications. For 3rd party signer support in React Native, refer to your signer provider's documentation.\\n\",\"title\":\"Using within React Native applications\",\"titles\":[]},{\"href\":\"/resources/react-native#getting-started\",\"html\":\"\\n\",\"id\":\"pages/resources/react-native.mdx#getting-started\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Getting Started\",\"titles\":[\"Using within React Native applications\"]},{\"href\":\"/resources/react-native#upgrade-to-the-latest-beta-version-of-expo\",\"html\":\"\\nWe first need to get our environment setup. The first thing we need to do is make sure we're on the latest Beta version of Expo. The reason for this is that we need React Native version 0.74 or higher because it has TextEncoder
natively supported.
npx expo install expo@next --fix
yarn expo install expo@next --fix
Once we've got that setup, we need to setup a few shims so we can use crypto libraries in React Native.
\\n\",\"id\":\"pages/resources/react-native.mdx#set-up-shims\",\"isPage\":false,\"text\":\"\\nOnce we've got that setup, we need to setup a few shims so we can use crypto libraries in React Native.\\n\",\"title\":\"Set up shims\",\"titles\":[\"Using within React Native applications\",\"Getting Started\"]},{\"href\":\"/resources/react-native#install-shim-dependencies\",\"html\":\"\\nnpm install --save node-libs-react-native crypto-browserify stream-browserify react-native-get-random-values
yarn add node-libs-react-native crypto-browserify stream-browserify react-native-get-random-values
Create or edit your metro.config.js
file in the root of your project so that it includes the following:
// Learn more https://docs.expo.io/guides/customizing-metro\\nconst { getDefaultConfig } = require("expo/metro-config");\\n \\n/** @type {import('expo/metro-config').MetroConfig} */\\nconst config = getDefaultConfig(__dirname);\\n\\n// The following code ensures we have the necessary\\n// shims for crypto built into our project\\nconfig.resolver.extraNodeModules = {\\n ...config.resolver.extraNodeModules,\\n ...require("node-libs-react-native"),\\n crypto: require.resolve("crypto-browserify"),\\n stream: require.resolve("stream-browserify"),\\n};\\n \\nmodule.exports = config;
\\n\",\"id\":\"pages/resources/react-native.mdx#register-shim-modules-in-metro\",\"isPage\":false,\"text\":\"\\nCreate or edit your metro.config.js file in the root of your project so that it includes the following:\\n// Learn more https://docs.expo.io/guides/customizing-metro\\nconst { getDefaultConfig } = require("expo/metro-config");\\n \\n/** @type {import('expo/metro-config').MetroConfig} */\\nconst config = getDefaultConfig(__dirname);\\n\\n// The following code ensures we have the necessary\\n// shims for crypto built into our project\\nconfig.resolver.extraNodeModules = {\\n ...config.resolver.extraNodeModules,\\n ...require("node-libs-react-native"),\\n crypto: require.resolve("crypto-browserify"),\\n stream: require.resolve("stream-browserify"),\\n};\\n \\nmodule.exports = config;\\n\",\"title\":\"Register shim modules in Metro\",\"titles\":[\"Using within React Native applications\",\"Getting Started\",\"Set up shims\"]},{\"href\":\"/resources/react-native#register-global-shims\",\"html\":\"\\nImport the following packages at the top of your App.tsx
file so that libraries that depend on globals like crypto
have access to them.
import "node-libs-react-native/globals.js";\\nimport "react-native-get-random-values";\\n \\n// rest of App.tsx
\\n\",\"id\":\"pages/resources/react-native.mdx#register-global-shims\",\"isPage\":false,\"text\":\"\\nImport the following packages at the top of your App.tsx file so that libraries that depend on globals like crypto have access to them.\\nIf you're using bare React Native, you would add the above imports to your index.js file.\\nimport "node-libs-react-native/globals.js";\\nimport "react-native-get-random-values";\\n \\n// rest of App.tsx\\n\",\"title\":\"Register global shims\",\"titles\":[\"Using within React Native applications\",\"Getting Started\",\"Set up shims\"]},{\"href\":\"/resources/react-native#install-account-kit-and-build\",\"html\":\"\\nThat's it! Now you can install the packages you want from Account Kit and start building your React Native Account Abstraction app.
\\nnpm install -s @alchemy/aa-alchemy @alchemy/aa-accounts @alchemy/aa-core
yarn add @alchemy/aa-alchemy @alchemy/aa-accounts @alchemy/aa-core
The Alchemy Signer allows you to export a user's private key, allowing them a right to exit at any time. It is considered a best practice to allow your users to export their private key, as it gives them full control over their account. The private key export method does not rely on Alchemy's infrastructure, so even if Alchemy is down, a user can still export their private key.
\\n\",\"id\":\"pages/signer/export-private-key.mdx#export-private-key\",\"isPage\":true,\"text\":\"\\nThe Alchemy Signer allows you to export a user's private key, allowing them a right to exit at any time. It is considered a best practice to allow your users to export their private key, as it gives them full control over their account. The private key export method does not rely on Alchemy's infrastructure, so even if Alchemy is down, a user can still export their private key.\\n\",\"title\":\"Export private key\",\"titles\":[]},{\"href\":\"/signer/export-private-key#usage\",\"html\":\"\\nTo add export private key functionality to your app, you can use the exportPrivateKey
method on the signer.
// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport React from "react";\\nimport { useMutation } from "@tanstack/react-query";\\nimport { signer } from "./signer";\\n \\nconst TurnkeyExportWalletContainerId = "turnkey-export-wallet-container-id";\\nconst TurnkeyExportWalletElementId = "turnkey-export-wallet-element-id";\\n \\n// This allows us to style the embedded iframe\\nconst iframeCss = `\\niframe {\\n box-sizing: border-box;\\n width: 100%;\\n height: 120px;\\n border-radius: 8px;\\n border-width: 1px;\\n border-style: solid;\\n border-color: rgba(216, 219, 227, 1);\\n padding: 20px;\\n}\\n`;\\n \\nexport const ExportPrivateKeyView = () => {\\n // we are using react-query to handle loading states more easily, but feel free to use w/e state management library you prefer\\n const {\\n mutate: exportWallet,\\n isLoading,\\n data,\\n } = useMutation({\\n mutationFn: () =>\\n signer.exportWallet({\\n iframeContainerId: TurnkeyExportWalletContainerId,\\n iframeElementId: TurnkeyExportWalletElementId,\\n }),\\n });\\n \\n // Once the user clicks the button, a request will be sent to initialize private key export\\n // once the request is complete, the iframe will be rendered with either\\n // 1. the private key if the user is logged in with a passkey\\n // 2. the seed phrase if the user is logged in with email\\n return (\\n <div className="flex flex-col gap-2">\\n {!data ? (\\n <button onClick={() => exportWallet()} disabled={isLoading}>\\n Export Wallet\\n </button>\\n ) : (\\n <strong>Seed Phrase</strong>\\n )}\\n <div\\n className="w-full"\\n style={{ display: !data ? "none" : "block" }}\\n id={TurnkeyExportWalletContainerId}\\n >\\n <style>{iframeCss}</style>\\n </div>\\n </div>\\n );\\n};
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
In almost all cases, yes, you will get the same address on all chains as long as the connecting signer address is the same! The deployment address is a function of the address of owner/signer address, the account implementation (e.g. latest version of Light Account), and the salt (you can optionally specify this). If all three of those remain the same, then you deploy the smart account at the same contract address.
There are two scenarios where you would get a different contract address:
Your smart account will be deployed when the first UserOperation
(UO) is sent from the account. The first UO must be sent with a non-zero initCode
. aa-sdk will handle generation of this initCode
for you using getAccountInitCode
.
It is unlikely you will need to frequently update the Light Account contract itself, however it is possible if needed. Light Account has UUPSUpgradeable
which adds upgrade methods on the account itself. To upgrade an account you will need to send a UserOperation
using the method upgradeTo
or upgradeToAndCall
, depending on whether or not you need to initialize the new implementation.
Yes! The optional salt value on Light Account enables the ability to have multiple accounts under a single signer. This value defaults to 0. You can set it when you create light account.
Simple Account's support upgradeToAndCall
implemented by openzeppelin UUPSUpgradeable contract. This allows you to upgrade from Simple Account to Light Account without changing the smart contract account address. Using upgradeToAndCall
will update the underlying implementation contract on the account while the account address and assets will stay the same.
You can call upgradeToAndCall
on the Simple Account with these params:
newImplementation
: Latest LightAccount implementation address (found here - make sure to use the implementation address, not the factory address)\\ndata
: encoded version of the initialize
function with anOwner
parameter set to the owner on the account, usually the same owner as what the account used as Simple Account.\\nIt is very important that the initialize
step is encoded correctly to ensure the account does not get into a risky state where someone else could call initialize on it with one's signer and take control of your account. You can call owner()
on the account after the upgrade to ensure it is assigned correctly.
This can be called on the existing smart contract account by sending a user operation that calls execute
(or executeBatch
) and has that call upgradeToAndCall
(the same way you would make the account send calls to other addresses).
If the UserOperation
(meta-transaction for 4337 accounts) is correctly priced and submitted a few hundred milliseconds prior to a new block getting created, it will typically get placed in the next block. This is because the Bundler needs time to create/propagate its transaction. You can think of it as 1 extra block time worth of latency, but we are working towards improving this latency.
This can happen when UserOperation
s (UOs) become underpriced, frequently due to fee market movement between when gas and fees are estimations and when the UO is actually submitted.
You may experience this when calling the waitForUserOperationTransaction
method. It may throw an error if it does not find the UO in a mined Transaction within its retry limits.
You can mitigate this by defining a more flexible retry period when constructing a Client
(i.e. txMaxRetries
, txRetryIntervalMs
, txRetryMultiplier
in opts
). If your UO continues to be delayed beyond a limit you are willing to wait, you can resubmit it using dropAndReplaceUserOperation
.
Right now, UserOperation
s are sent to a private mempool for all networks other than Polygon, where there is no way to do this. We are actively involved in proposals for a peer-to-peer mempool standard.
Yes! Check out this guide.
Our bundler estimates gas and submits UserOperation
s (UOs) under the hood of the aa-sdk. Our gas estimations are just that, estimations that optimize for UOs landing on chain, and you may need to adjust gas limits based on your needs using overrides.
Learn more about gas estimation and how it is implemented in our Bundler.
There are many nuances and edge cases that our bundler considers especially for L2’s. Learn more here.
We recommend adding error handling when sending a UO to handle potential gas and fee changes due to market movement. Learn more about frequent errors.
Gas sponsorship is available on testnet for all tiers. For support on mainnet, you must be on a paying tier (i.e. Growth tier and above). Learn more about our different pricing tiers here.
We front the gas for your application and put the USD equivalent on your bill at the end of the month. No need to worry about pre-funding the Gas Manager or conversions, we’ve got you covered! You can follow this guide for more details on how to sponsor UserOperation
s.
You can find details of Gas Manager limits depending on your tier here.
Currently, we don’t support this, but we are actively exploring. Please reach out if you are interested as we would love your input in our spec.
In your Gas Manager policy, you can configure spending rules per address, per app, and/or policy wide limits. See how to set up these policies here.
Gas Manager policies can only be tied to one app. Make sure you are using the API Key that is associated with the app the Gas Manager policy is configured for, or create a new policy for the app you are using.
Precheck failed errors are often related to gas and/or fees. Our Bundler follows standard ERC 4337 implementation for gas and fee checks in order to 1) ensure your UserOperation
s (UOs) land on chain and to 2) protect the Bundler from potential attacks in order to support scalability.
These errors are often related to market movement between the time when gas and fees are estimated and the time when UOs are submitted to the bundler. This fluctuation in the market is especially variant on testnet. To ensure your UO is included in a block, we currently reject sending any UOs that are underpriced compared to the network rate .
To handle these errors, we recommend you use our override fields to increase buffers on top of our estimates and implement retry mechanisms as needed.
Our gas and fee estimations are just that, estimations, but we are always working to improve these estimates!
Currently our Bundler allows max 10M gas in aggregate between preVerificationGas
, verificationGasLimit
, and callGasLimit
. To reduce the gas needed, try reducing the size of your call data and/or sending your call data in multiple UserOperation
s rather than one.
waitForUserOperationTransaction
may throw this error if it does not find the mined User Operation within its retry limits.
You can mitigate this by defining a more flexible retry period when constructing a Client
(i.e. txMaxRetries
, txRetryIntervalMs
, txRetryMultiplier
in opts
).
If your UserOperation
continues to be delayed beyond a limit you are willing to wait, you can resubmit the user operation using dropAndReplaceUserOperation
.
No, the aa-sdk
repo does not offically support React Native. It is on our radar!
Currently we have a strong dependency on Viem, which requires several global features, such as TextEncoder
and crypto
, that are absent in React Native's environment. See more about Viem's capability here.
However, we have created a small PoC using Expo that you can find here. For more information on how to use Account Kit within a React Native application see the guide.
\",\"id\":\"pages/resources/faqs.mdx#does-the-aa-sdk-repo-support-react-native\",\"isPage\":false,\"text\":\"\\nNo, the aa-sdk repo does not offically support React Native. It is on our radar!\\nCurrently we have a strong dependency on Viem, which requires several global features, such as TextEncoder and crypto, that are absent in React Native's environment. See more about Viem's capability here.\\nHowever, we have created a small PoC using Expo that you can find here. For more information on how to use Account Kit within a React Native application see the guide.\",\"title\":\"Does the aa-sdk repo support React Native?\",\"titles\":[\"Frequently asked questions\",\"Other Support\"]}]}],[\"index.bb046e25c6943ddd115cdb14f2c2cfa7414b808670b75895de1c928be8ae35d2\",{\"mdx\":\"---\\ntitle: Terms\\ndescription: Glossary of terms related to Account Kit\\n---\\n\\n# Terms\\n\\n## Account Kit\\n\\nAccount Kit is a framework designed to embed smart accounts in web3 applications. It includes a set of tools such as [Signer integrations](/concepts/smart-account-signer), [Gas Manager](https://docs.alchemy.com/docs/gas-manager-services) and [Bundler](https://docs.alchemy.com/docs/bundler-services) utilities that unlock features such as [gas sponsorship](#TODO/using-smart-accounts/sponsoring-gas/gas-manager), [batched transactions](#TODO/using-smart-accounts/batch-user-operations) and email/social login. With its user-friendly suite of SDKs, known as [aa-sdk](https://github.com/alchemyplatform/aa-sdk), Account Kit makes it easy to deploy smart accounts, manage `UserOperation`s, and handle gas sponsorship, streamlining the entire process with minimal coding effort.\\n\\n## Bundler\\n\\nA network participant in the [ERC-4337](#erc-4337) standard that collects and submits `UserOperations` (UOs) to the blockchain, handling the associated gas fees, in exchange for payment during UO processing either directly from the user or from a [Paymaster](https://www.alchemy.com/overviews/what-is-a-paymaster). Alchemy’s implementation of a bundler is called [Rundler](https://github.com/alchemyplatform/rundler). It is written in Rust and designed to achieve high performance and reliability.\\n\\n## Client\\n\\nBuilt on top of `viem`, we have built our own [`Client`](https://viem.sh/docs/clients/custom) extended with custom functionality as a [`BundlerClient`](/resources/types#BundlerClient) and [`SmartAccountClient`](/resources/types#SmartAccountClient) compliant to EIP-4337 and EIP-6900 standards. `Client`, in general, is an intermediary or connector that enables interactions between client applications and your `SmartAccount` (either `LightAccount` or `ModularAccount`) or the `Bundler`.\\n\\n## EntryPoint\\n\\nA standardized smart contract that acts as the primary gateway for processing `UserOperations` (UOs) on the blockchain. It receives bundled UOs from [`Bundlers`](#bundler) and verifies and executes these operations according to predefined rules, ensuring security and adherence to user-specified conditions. `EntryPoint` contract is a singleton contract to execute bundles of `UserOperation`s. `Bundler`s whitelist the supported `EntryPoint`.\\n\\n## ERC-4337\\n\\nA standard authored by the [Ethereum Foundation](https://ethereum.foundation/) for [account abstraction](https://docs.alchemy.com/docs/introduction-to-account-abstraction), establishing a uniform interface for all smart accounts. This standard also outlines the roles and functionalities of [Bundlers](https://docs.alchemy.com/docs/bundler-services), [Paymasters](https://www.alchemy.com/overviews/what-is-a-paymaster), and [`EntryPoint`](#entrypoint). Reference: https://eips.ethereum.org/EIPS/eip-4337\\n\\n## ERC-6492\\n\\nA standard designed for verifying signatures from smart accounts that haven't been deployed yet. It is important for account abstraction, allowing decentralized applications (dApps) to authenticate user signatures even before the user's smart account is deployed. The deployment of these accounts typically occurs during the user's first transaction, making [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492) essential for early interaction verification between users and dApps.\\n\\n## ERC-6900\\n\\nA [standard for modular accounts](https://eips.ethereum.org/EIPS/eip-6900) authored by Alchemy and [Yoav](https://github.com/yoavw) (one of the authors of ERC-4337) from the Ethereum Foundation. It defines standard interfaces for Modular Accounts ([`Modular Accounts`](#modular-account)) capable of supporting all standard-conformant [`Plugins`](#plugin).\\n\\n## Gas Manager\\n\\n[`Gas Manager`](https://docs.alchemy.com/docs/gas-manager-services) is the Alchemy’s [Paymaster](#paymaster) service. With robust security and customizability, Alchemy Gas Manager allows you to easily and securely sponsor the gas fees for users of your applications. Gas Managers authenticate transactions and ensure payments are carried out only when specific conditions are fulfilled, significantly reducing the chances of fraud and errors. Additionally, Gas Managers allow you to set granular rules for sponsoring your user's gas fees, so you can determine precisely when and how the gas fees will be sponsored. Head over to [Gas Manager](https://docs.alchemy.com/docs/gas-manager-services) documentation to learn more.\\n\\n## Light Account\\n\\n[Light Account](#TODO/smart-contracts/light-account/) is a collection of lightweight, production-ready [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) smart accounts developed by Alchemy. It builds on top of Ethereum Foundation's canonical [SimpleAccount](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol) to add key improvements such as ownership transfers, multiple owners, ERC-1271 signature support, and gas optimizations. It has been audited [multiple](https://github.com/alchemyplatform/light-account/blob/develop/audits/2024-01-09_quantstamp_aa8196b.pdf) [times](https://github.com/alchemyplatform/light-account/blob/develop/audits/2024-04-26_quantstamp_93f46a2.pdf) by Quantstamp.\\n\\n## Magic Link Authentication\\n\\nA magic link is a one-time use link sent to a user during the authentication process. After entering their username, the user is sent a URL, either to the user's email address or their mobile phone via text. The user clicks to authenticate themselves without entering a password, and for some, this might seem like \\\"magic,\\\" thus the name. Magic links are attractive because it is a simple way to remove the need for a customer to generate and remember a password from the process.\\n\\n## Modular Account\\n\\nA type of smart account enabled by the [ERC-6900](https://eips.ethereum.org/EIPS/eip-6900) standard and characterized by its [modular structure](#TODO/smart-contracts/modular-account/). This structure segments different functionalities of the account into distinct, independently upgradeable modules or plugins. Each plugin can have specific functions such as validation, execution, or hooks, enabling the smart account to extend its capabilities or modify its behavior without altering the core account logic. Modular Accounts enhance the flexibility, upgradeability, and interoperability of [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) smart accounts. Modular Account contracts have been audited by both [Spearbit](https://github.com/alchemyplatform/modular-account/blob/develop/audits/2024-01-31_spearbit_0e3fd1e.pdf) and [Quantstamp](https://github.com/alchemyplatform/modular-account/blob/develop/audits/2024-02-19_quantstamp_0e3fd1e.pdf).\\n\\nimport Bbp from \\\"./bbp.mdx\\\";\\n\\nAccount Kit is designed to be flexible and allow you to use any Signer you want. If you choose not use our signer, you can either:
\\nSmartAccountSigner
(exported in @aa-sdk/core
).viem
's WalletClient
and the WalletClientSigner
(exported in @aa-sdk/core
).Then you can use your Signer as an owner on Smart Contracts exported from @account-kit/smart-contracts
and with our infra Smart Account Clients exported from @account-kit/infra
.
Smart accounts in Account Kit expect an implementation of SmartAccountSigner
to work in Account Kit. We also include a SmartAccountAuthenticator
interface that extends SmartAccountSigner
and wraps any SDKs you may wish to use as part of the implementation of your own Signer.
import type { Address } from "abitype";\\nimport type {\\n Hex,\\n SignableMessage,\\n TypedData,\\n TypedDataDefinition,\\n} from "viem";\\n \\n/**\\n * Extends the @interface SmartAccountSigner interface with authentication.\\n *\\n * @template AuthParams - the generic type of the authentication parameters\\n * @template AuthDetails - the generic type of the authentication details\\n * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc.\\n */\\nexport interface SmartAccountAuthenticator<AuthParams, AuthDetails, Inner = any>\\n extends SmartAccountSigner<Inner> {\\n authenticate: (params: AuthParams) => Promise<AuthDetails>;\\n \\n getAuthDetails: () => Promise<AuthDetails>;\\n}\\n \\n/**\\n * A signer that can sign messages and typed data.\\n *\\n * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc.\\n */\\nexport interface SmartAccountSigner<Inner = any> {\\n signerType: string;\\n inner: Inner;\\n \\n getAddress: () => Promise<Address>;\\n \\n signMessage: (message: SignableMessage) => Promise<Hex>;\\n \\n signTypedData: <\\n const TTypedData extends TypedData | { [key: string]: unknown },\\n TPrimaryType extends string = string\\n >(\\n params: TypedDataDefinition<TTypedData, TPrimaryType>\\n ) => Promise<Hex>;\\n}
\\n\",\"id\":\"pages/signer/custom-signer.mdx#1-implementing-smartaccountauthenticator-or-smartaccountsigner\",\"isPage\":false,\"text\":\"\\nSmart accounts in Account Kit expect an implementation of SmartAccountSigner to work in Account Kit. We also include a SmartAccountAuthenticator interface that extends SmartAccountSigner and wraps any SDKs you may wish to use as part of the implementation of your own Signer.\\nimport type { Address } from "abitype";\\nimport type {\\n Hex,\\n SignableMessage,\\n TypedData,\\n TypedDataDefinition,\\n} from "viem";\\n \\n/**\\n * Extends the @interface SmartAccountSigner interface with authentication.\\n *\\n * @template AuthParams - the generic type of the authentication parameters\\n * @template AuthDetails - the generic type of the authentication details\\n * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc.\\n */\\nexport interface SmartAccountAuthenticator<AuthParams, AuthDetails, Inner = any>\\n extends SmartAccountSigner<Inner> {\\n authenticate: (params: AuthParams) => Promise<AuthDetails>;\\n \\n getAuthDetails: () => Promise<AuthDetails>;\\n}\\n \\n/**\\n * A signer that can sign messages and typed data.\\n *\\n * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc.\\n */\\nexport interface SmartAccountSigner<Inner = any> {\\n signerType: string;\\n inner: Inner;\\n \\n getAddress: () => Promise<Address>;\\n \\n signMessage: (message: SignableMessage) => Promise<Hex>;\\n \\n signTypedData: <\\n const TTypedData extends TypedData | { [key: string]: unknown },\\n TPrimaryType extends string = string\\n >(\\n params: TypedDataDefinition<TTypedData, TPrimaryType>\\n ) => Promise<Hex>;\\n}\\n\",\"title\":\"1. Implementing SmartAccountAuthenticator or SmartAccountSigner\",\"titles\":[\"How to use your own Account Signer\"]},{\"href\":\"/signer/custom-signer#2-using-walletclientsigner\",\"html\":\"\\nViem allows you to create a WalletClient
, which can be used to wrap local or JSON RPC based wallets. You can see the complete docs for leveraging the WalletClient
here.
We support a SmartAccountSigner
implementation called WalletClientSigner
that makes it really easy to use a viem WalletClient
as a signer on your Smart Contract Account. If your Signer is EIP-1193 compliant, it is really easy to use with WalletClient
. Let's take a look at a simple example:
// @noErrors\\nimport { WalletClientSigner, type SmartAccountSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst externalProvider = window.ethereum; // or anyother EIP-1193 provider\\n \\nconst walletClient = createWalletClient({\\n chain: sepolia, // can provide a different chain here\\n transport: custom(externalProvider),\\n});\\n \\nexport const signer: SmartAccountSigner = new WalletClientSigner(\\n walletClient,\\n "json-rpc" // signerType\\n);
\",\"id\":\"pages/signer/custom-signer.mdx#2-using-walletclientsigner\",\"isPage\":false,\"text\":\"\\nViem allows you to create a WalletClient, which can be used to wrap local or JSON RPC based wallets. You can see the complete docs for leveraging the WalletClient here.\\nWe support a SmartAccountSigner implementation called WalletClientSigner that makes it really easy to use a viem WalletClient as a signer on your Smart Contract Account. If your Signer is EIP-1193 compliant, it is really easy to use with WalletClient. Let's take a look at a simple example:\\n// @noErrors\\nimport { WalletClientSigner, type SmartAccountSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst externalProvider = window.ethereum; // or anyother EIP-1193 provider\\n \\nconst walletClient = createWalletClient({\\n chain: sepolia, // can provide a different chain here\\n transport: custom(externalProvider),\\n});\\n \\nexport const signer: SmartAccountSigner = new WalletClientSigner(\\n walletClient,\\n "json-rpc" // signerType\\n);\",\"title\":\"2. Using WalletClientSigner\",\"titles\":[\"How to use your own Account Signer\"]}]}],[\"index.dc72b27a1db406772d6a2fbdecc6c69103f27e71982853dd12c41c89ec135f7e\",{\"mdx\":\"---\\ntitle: Server Side Rendering\\ndescription: An overview on how to use React Hooks with Server Side Rendering\\n---\\n\\n# Server Side Rendering (SSR)\\n\\nWhen using the React hooks exported by Account Kit in a server-side rendered setting, you will see inconsistencies of the user state between the server and the client. This will lead to flashes of content when a user is logged in. To avoid this, the account state can be optimistically loaded on the server and passed to the client.\\n\\nTo enable this setting, you can set `ssr: true` when creating a config.\\n\\n```ts twoslash [config.ts]\\n// @noErrors\\nimport { createConfig } from \\\"@account-kit/react\\\";\\nimport { sepolia } from \\\"@account-kit/infra\\\";\\n\\nexport const config = createConfig({\\n // required\\n rpcUrl: \\\"/api/rpc\\\",\\n chain: sepolia,\\n ssr: true, // [!code ++]\\n});\\n```\\n\\nThis setting will defer hydration of the account state to the client after the initial mount.\\n\\n## Persisting the Account State\\n\\n### Cookie Storage\\n\\nTo consistently pass the state between the server and the client, you can pass in a cookie storage to the `config` object created above. The cookie storage allows the client state to be written serialized to a cookie which can be passed along to the server on each request. This allows the server to have access to certain parts of the account state when rendering, ensuring a consistent render between client and server (eg. user's address displayed in the top nav). Instances which can only be created on the client will still not be available on the server, however. This includes the signer or smart contract account instances.\\n\\n```ts twoslash [config.ts]\\n// @noErrors\\nimport {\\n createConfig,\\n cookieStorage, // [!code ++]\\n} from \\\"@account-kit/react\\\";\\nimport { sepolia } from \\\"@account-kit/infra\\\";\\nimport { QueryClient } from \\\"@tanstack/react-query\\\";\\n\\nexport const queryClient = new QueryClient();\\n\\n// [!code focus:99]\\nexport const config = createConfig({\\n // required\\n rpcUrl: \\\"/api/rpc\\\",\\n chain: sepolia,\\n ssr: true, // [!code ++]\\n storage: cookieStorage, // [!code ++]\\n});\\n```\\n\\nNow, depending on your application, you can get the state from cookies and pass in the `initialState` to the `AlchemyAccountProvider` to hydrate the account state on the client.\\n\\n### Next.js App Directory\\n\\nIf you are using NextJS App Directory, you can read the cookie state and pass it to the providers like so:\\n\\n:::code-group\\n\\n```tsx twoslash [layout.tsx]\\n// @noErrors\\nimport React from \\\"react\\\";\\nimport { cookieToInitialState } from \\\"@account-kit/core\\\";\\nimport type { Metadata } from \\\"next\\\";\\nimport { Inter } from \\\"next/font/google\\\";\\nimport { headers } from \\\"next/headers\\\";\\nimport { config } from \\\"./config\\\";\\nimport \\\"./globals.css\\\";\\nimport { Providers } from \\\"./providers\\\";\\n\\nconst inter = Inter({ subsets: [\\\"latin\\\"] });\\n\\nexport const metadata: Metadata = {\\n title: \\\"Embedded Accounts Getting Started\\\",\\n description: \\\"Embedded Accounts Quickstart Guide\\\",\\n};\\n\\nexport default function RootLayout({\\n children,\\n}: Readonly<{\\n children: React.ReactNode;\\n}>) {\\n // This will allow us to persist state across page boundaries\\n const initialState = cookieToInitialState(\\n config,\\n headers().get(\\\"cookie\\\") ?? undefined\\n );\\n\\n return (\\n \\n \\n When using the React hooks exported by Account Kit in a server-side rendered setting, you will see inconsistencies of the user state between the server and the client. This will lead to flashes of content when a user is logged in. To avoid this, the account state can be optimistically loaded on the server and passed to the client.
\\nTo enable this setting, you can set ssr: true
when creating a config.
// @noErrors\\nimport { createConfig } from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\n \\nexport const config = createConfig({\\n // required\\n rpcUrl: "/api/rpc",\\n chain: sepolia,\\n ssr: true, \\n});
\\nThis setting will defer hydration of the account state to the client after the initial mount.
\\n\",\"id\":\"pages/react/ssr.mdx#server-side-rendering-ssr\",\"isPage\":true,\"text\":\"\\nWhen using the React hooks exported by Account Kit in a server-side rendered setting, you will see inconsistencies of the user state between the server and the client. This will lead to flashes of content when a user is logged in. To avoid this, the account state can be optimistically loaded on the server and passed to the client.\\nTo enable this setting, you can set ssr: true when creating a config.\\n// @noErrors\\nimport { createConfig } from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\n \\nexport const config = createConfig({\\n // required\\n rpcUrl: "/api/rpc",\\n chain: sepolia,\\n ssr: true, \\n});\\nThis setting will defer hydration of the account state to the client after the initial mount.\\n\",\"title\":\"Server Side Rendering (SSR)\",\"titles\":[]},{\"href\":\"/react/ssr#persisting-the-account-state\",\"html\":\"\\n\",\"id\":\"pages/react/ssr.mdx#persisting-the-account-state\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Persisting the Account State\",\"titles\":[\"Server Side Rendering (SSR)\"]},{\"href\":\"/react/ssr#cookie-storage\",\"html\":\"\\nTo consistently pass the state between the server and the client, you can pass in a cookie storage to the config
object created above. The cookie storage allows the client state to be written serialized to a cookie which can be passed along to the server on each request. This allows the server to have access to certain parts of the account state when rendering, ensuring a consistent render between client and server (eg. user's address displayed in the top nav). Instances which can only be created on the client will still not be available on the server, however. This includes the signer or smart contract account instances.
// @noErrors\\nimport {\\n createConfig,\\n cookieStorage, \\n} from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\nimport { QueryClient } from "@tanstack/react-query";\\n \\nexport const queryClient = new QueryClient();\\n \\n\\nexport const config = createConfig({\\n // required\\n rpcUrl: "/api/rpc",\\n chain: sepolia,\\n ssr: true, \\n storage: cookieStorage, \\n});
\\nNow, depending on your application, you can get the state from cookies and pass in the initialState
to the AlchemyAccountProvider
to hydrate the account state on the client.
If you are using NextJS App Directory, you can read the cookie state and pass it to the providers like so:
\\n// @noErrors\\nimport React from "react";\\nimport { cookieToInitialState } from "@account-kit/core";\\nimport type { Metadata } from "next";\\nimport { Inter } from "next/font/google";\\nimport { headers } from "next/headers";\\nimport { config } from "./config";\\nimport "./globals.css";\\nimport { Providers } from "./providers";\\n \\nconst inter = Inter({ subsets: ["latin"] });\\n \\nexport const metadata: Metadata = {\\n title: "Embedded Accounts Getting Started",\\n description: "Embedded Accounts Quickstart Guide",\\n};\\n \\nexport default function RootLayout({\\n children,\\n}: Readonly<{\\n children: React.ReactNode;\\n}>) {\\n // This will allow us to persist state across page boundaries\\n const initialState = cookieToInitialState(\\n config,\\n headers().get("cookie") ?? undefined\\n );\\n \\n return (\\n <html lang="en">\\n <body className={inter.className}>\\n <Providers initialState={initialState}>{children}</Providers>\\n </body>\\n </html>\\n );\\n}
// @noErrors\\n"use client";\\n \\nimport React from "react";\\nimport { AlchemyClientState } from "@account-kit/core";\\nimport { AlchemyAccountProvider } from "@account-kit/react";\\nimport { QueryClientProvider } from "@tanstack/react-query";\\nimport { PropsWithChildren, Suspense } from "react";\\nimport { config, queryClient } from "./config";\\n \\nexport const Providers = (\\n props: PropsWithChildren<{ initialState?: AlchemyClientState }>\\n) => {\\n return (\\n <Suspense>\\n <QueryClientProvider client={queryClient}>\\n <AlchemyAccountProvider\\n config={config}\\n queryClient={queryClient}\\n initialState={props.initialState}\\n >\\n {props.children}\\n </AlchemyAccountProvider>\\n </QueryClientProvider>\\n </Suspense>\\n );\\n};
// @noErrors\\nimport { createConfig, cookieStorage } from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\nimport { QueryClient } from "@tanstack/react-query";\\n \\nexport const queryClient = new QueryClient();\\n \\nexport const config = createConfig({\\n rpcUrl: "/api/rpc",\\n chain: sepolia,\\n ssr: true,\\n storage: cookieStorage,\\n});
Coming soon!
\\n\",\"id\":\"pages/react/ssr.mdx#nextjs-pages-directory\",\"isPage\":false,\"text\":\"\\nComing soon!\\n\",\"title\":\"Next.js Pages Directory\",\"titles\":[\"Server Side Rendering (SSR)\",\"Persisting the Account State\"]},{\"href\":\"/react/ssr#vanilla-ssr\",\"html\":\"\\nComing soon!
\",\"id\":\"pages/react/ssr.mdx#vanilla-ssr\",\"isPage\":false,\"text\":\"\\nComing soon!\",\"title\":\"Vanilla SSR\",\"titles\":[\"Server Side Rendering (SSR)\",\"Persisting the Account State\"]}]}],[\"index.85f0c79f0a4b5e69a1c7e77ca0195d62b0efe00bb6ac95703a18b642100e25f8\",{\"mdx\":\"---\\ntitle: Signer Quickstart\\ndescription: Get started with the Alchemy Signer\\n---\\n\\nimport GetApiKeysSnippet from \\\"../../shared/get-api-key.mdx\\\";\\n\\n# Signer Quickstart\\n\\nGetting started with the Signer is very similar to [getting started with React](/react/quickstart).\\n\\n## Get your API key and create an account config\\n\\nBy default, AlchemyWebSigner
user sessions are cached in localStorage
for 15 minutes.
You can customize session length by passing a sessionConfig
to your AlchemyWebSigner
constructor.
You can check if the user has an active session with the following command:
\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\n// NOTE: this method throws if there is no authenticated user\\n// so we return null in the case of an error\\nconst user = await signer.getAuthDetails().catch(() => null);
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
If there is an existing session, then your signer is ready for use! If not, see the section above for logging users in.
\",\"id\":\"pages/signer/user-sessions.mdx#user-sessions\",\"isPage\":true,\"text\":\"\\nBy default, AlchemyWebSigner user sessions are cached in localStorage for 15 minutes.\\nYou can customize session length by passing a sessionConfig to your AlchemyWebSigner constructor.\\nYou can check if the user has an active session with the following command:\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\n// NOTE: this method throws if there is no authenticated user\\n// so we return null in the case of an error\\nconst user = await signer.getAuthDetails().catch(() => null);import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\nIf there is an existing session, then your signer is ready for use! If not, see the section above for logging users in.\",\"title\":\"User sessions\",\"titles\":[]}]}],[\"index.f612b47ba82362a827ce3c9d25bd042dc6a9f82fcec65d96e591ec6d5de3f716\",{\"mdx\":\"---\\ntitle: Passkey Login\\ndescription: Authenticate a user using a passkey\\n---\\n\\n# Passkey Login\\n\\nIf a user has added a passkey to their account, or they initially signed up with a passkey, you can easily log them in with that passkey.\\n\\n## Authenticate a user with email and passkey\\n\\nIf you want to allow sign-up and login with a passkey, you can ask the user for an email to associate with their passkey. This way, they can log in with their email and passkey in the future. Under the hood, the email is also used to check if an account exists already so you can have a unified sign-up and login flow.\\n\\n:::danger\\nIt's important that you validate this email before creating an account for the user. This is to prevent users from losing access to their wallets if they lose their device.\\n:::\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { signer } from \\\"./signer\\\";\\n\\nconst result = await signer.authenticate({\\n type: \\\"passkey\\\",\\n email: \\\"user@mail.com\\\",\\n});\\n```\\n\\n```ts twoslash [signer] filename=\\\"signer.ts\\\"\\n// [!include ~/shared/signer/signer.ts]\\n```\\n\\n:::\\n\\n## Authenticate an anonymous user\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { signer } from \\\"./signer\\\";\\n\\nconst result = await signer.authenticate({\\n type: \\\"passkey\\\",\\n createNew: false,\\n});\\n```\\n\\n```ts twoslash [signer] filename=\\\"signer.ts\\\"\\n// [!include ~/shared/signer/signer.ts]\\n```\\n\\n:::\\n\",\"document\":[{\"href\":\"/signer/authentication/passkey-login#passkey-login\",\"html\":\"\\nIf a user has added a passkey to their account, or they initially signed up with a passkey, you can easily log them in with that passkey.
\\n\",\"id\":\"pages/signer/authentication/passkey-login.mdx#passkey-login\",\"isPage\":true,\"text\":\"\\nIf a user has added a passkey to their account, or they initially signed up with a passkey, you can easily log them in with that passkey.\\n\",\"title\":\"Passkey Login\",\"titles\":[]},{\"href\":\"/signer/authentication/passkey-login#authenticate-a-user-with-email-and-passkey\",\"html\":\"\\nIf you want to allow sign-up and login with a passkey, you can ask the user for an email to associate with their passkey. This way, they can log in with their email and passkey in the future. Under the hood, the email is also used to check if an account exists already so you can have a unified sign-up and login flow.
\\n\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\nconst result = await signer.authenticate({\\n type: "passkey",\\n email: "user@mail.com",\\n});
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\nconst result = await signer.authenticate({\\n type: "passkey",\\n createNew: false,\\n});
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
The SmartAccountClient
within @aa-sdk/core
is unopinionated about which paymaster you use, so you can connect to any paymaster really simply. Configuration is done using the paymasterAndData
config option when you call createSmartAccountClient
.
import { createSmartAccountClient } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst chain = sepolia;\\nconst client = createSmartAccountClient({\\n chain,\\n transport: http("RPC_URL"),\\n // sets the dummy paymasterAndData with paymaster address appended with some dummy paymasterData\\n // that looks like a valid paymasterData\\n dummyPaymasterAndData: async (userop) => ({\\n ...userop,\\n paymasterAndData: `0x<PAYMASTER_ADDRESS><PAYMASTER_DUMMY_DATA>`,\\n }),\\n paymasterAndData: async (userop, opts) => {\\n // call your paymaster here to sponsor the userop\\n // leverage the `opts` field to apply any overrides\\n return {\\n ...userop,\\n paymasterAndData: "0xresponsefromprovider",\\n };\\n },\\n});
\",\"id\":\"pages/infra/third-party/paymaster.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst chain = sepolia;\\nconst client = createSmartAccountClient({\\n chain,\\n transport: http("RPC_URL"),\\n // sets the dummy paymasterAndData with paymaster address appended with some dummy paymasterData\\n // that looks like a valid paymasterData\\n dummyPaymasterAndData: async (userop) => ({\\n ...userop,\\n paymasterAndData: `0x<PAYMASTER_ADDRESS><PAYMASTER_DUMMY_DATA>`,\\n }),\\n paymasterAndData: async (userop, opts) => {\\n // call your paymaster here to sponsor the userop\\n // leverage the `opts` field to apply any overrides\\n return {\\n ...userop,\\n paymasterAndData: "0xresponsefromprovider",\\n };\\n },\\n});\",\"title\":\"Usage\",\"titles\":[\"Using a third-party paymaster\"]}]}],[\"index.5395587e8c93a69eecb8b3c8a7399ed5f52aa15fc1d04b3c4f542a0e484db3ca\",{\"mdx\":\"---\\ntitle: Choosing a Smart Account\\ndescription: Learn about different smart account implementations to use with\\n Account Kit, a vertically integrated stack for building apps that support\\n ERC-4337 and ERC-6900.\\n---\\n\\n# Choosing a Smart Account\\n\\n## What is a Smart Account?\\n\\nA smart account is an [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) smart account. You can use it to manage assets, execute transactions (known as `UserOperation`s), and more. There are many different implementations of a smart account, including [Modular Account](/smart-contracts/modular-account/) and [Light Account](/smart-contracts/light-account/).\\n\\n## Modular Account\\n\\n[Modular Account](/smart-contracts/modular-account/) is an enterprise-grade smart contract account designed from the ground up for ERC-4337. It is highly secure, gas optimized, and endlessly customizable with ERC-6900 plugins. With our pre-built plugins, it supports multiple owners (1-of-n), multisig thresholds (m-of-n), and session keys with scoped permissions.\\n\\nModular Account is the first [ERC-6900](https://eips.ethereum.org/EIPS/eip-6900) account implementation, making it infinitely extensible with custom plugins. Plug and play from a selection of existing plugins, including session keys and multisig, or write your own to customize the account for your app. We have created three pre-built plugins available today: [`MultiOwnerPlugin`](#TODO/smart-contracts/using-smart-accounts/transfer-ownership/modular-account), [`SessionKeyPlugin`](#TODO/smart-contracts/using-smart-accounts/session-keys/), and [`MultisigPlugin`](/smart-contracts/modular-account/multisig-plugin/). We're actively building new plugins and look forward to what new plugins you create!\\n\\nFor most applications, we recommend using **Modular Account**. Suppose you have already deployed Light Account in the past. In that case, you can follow [Upgrading to a Modular Account](/smart-contracts/modular-account/upgrading-to-modular-account) guide to easily upgrade your account from Light Account to Modular Account using Account Kit and unlock an ecosystem of plugins for your smart account stack.\\n\\nModular Account has been audited by both [Spearbit](https://github.com/alchemyplatform/modular-account/blob/develop/audits/2024-01-31_spearbit_0e3fd1e.pdf) and [Quantstamp](https://github.com/alchemyplatform/modular-account/blob/develop/audits/2024-02-19_quantstamp_0e3fd1e.pdf). It is fully [open source](https://github.com/alchemyplatform/modular-account) and supported by a [Bug Bounty](https://hackerone.com/alchemyplatform) program. It is [deployed](/smart-contracts/modular-account/deployments) on multiple networks and their respective testnets.\\n\\n## Light Account\\n\\n[Light Account](/smart-contracts/light-account) is a collection of lightweight, production-ready [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) smart accounts. It builds on top of Ethereum Foundation's canonical [SimpleAccount](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol) to add key improvements such as ownership transfers, multiple owners, ERC-1271 signature support, and gas optimizations.\\n\\nIt is fully [open source](https://github.com/alchemyplatform/light-account) and has been audited [multiple](https://github.com/alchemyplatform/light-account/blob/develop/audits/2024-01-09_quantstamp_aa8196b.pdf) [times](https://github.com/alchemyplatform/light-account/blob/develop/audits/2024-04-26_quantstamp_93f46a2.pdf) by Quantstamp. It is [deployed](/smart-contracts/light-account/deployments) on multiple networks and their respective testnets.\\n\\n## Use your own Account\\n\\nAccount Kit also makes it easy to use your own smart account implementation. To learn how, see our guide on how to [use your own account](/smart-contracts/custom/using-your-own).\\n\",\"document\":[{\"href\":\"/smart-contracts/choosing-a-smart-account#choosing-a-smart-account\",\"html\":\"\\n\",\"id\":\"pages/smart-contracts/choosing-a-smart-account.mdx#choosing-a-smart-account\",\"isPage\":true,\"text\":\"\\n\",\"title\":\"Choosing a Smart Account\",\"titles\":[]},{\"href\":\"/smart-contracts/choosing-a-smart-account#what-is-a-smart-account\",\"html\":\"\\nA smart account is an ERC-4337 smart account. You can use it to manage assets, execute transactions (known as UserOperation
s), and more. There are many different implementations of a smart account, including Modular Account and Light Account.
Modular Account is an enterprise-grade smart contract account designed from the ground up for ERC-4337. It is highly secure, gas optimized, and endlessly customizable with ERC-6900 plugins. With our pre-built plugins, it supports multiple owners (1-of-n), multisig thresholds (m-of-n), and session keys with scoped permissions.
\\nModular Account is the first ERC-6900 account implementation, making it infinitely extensible with custom plugins. Plug and play from a selection of existing plugins, including session keys and multisig, or write your own to customize the account for your app. We have created three pre-built plugins available today: MultiOwnerPlugin
, SessionKeyPlugin
, and MultisigPlugin
. We're actively building new plugins and look forward to what new plugins you create!
For most applications, we recommend using Modular Account. Suppose you have already deployed Light Account in the past. In that case, you can follow Upgrading to a Modular Account guide to easily upgrade your account from Light Account to Modular Account using Account Kit and unlock an ecosystem of plugins for your smart account stack.
\\nModular Account has been audited by both Spearbit and Quantstamp. It is fully open source and supported by a Bug Bounty program. It is deployed on multiple networks and their respective testnets.
\\n\",\"id\":\"pages/smart-contracts/choosing-a-smart-account.mdx#modular-account\",\"isPage\":false,\"text\":\"\\nModular Account is an enterprise-grade smart contract account designed from the ground up for ERC-4337. It is highly secure, gas optimized, and endlessly customizable with ERC-6900 plugins. With our pre-built plugins, it supports multiple owners (1-of-n), multisig thresholds (m-of-n), and session keys with scoped permissions.\\nModular Account is the first ERC-6900 account implementation, making it infinitely extensible with custom plugins. Plug and play from a selection of existing plugins, including session keys and multisig, or write your own to customize the account for your app. We have created three pre-built plugins available today: MultiOwnerPlugin, SessionKeyPlugin, and MultisigPlugin. We're actively building new plugins and look forward to what new plugins you create!\\nFor most applications, we recommend using Modular Account. Suppose you have already deployed Light Account in the past. In that case, you can follow Upgrading to a Modular Account guide to easily upgrade your account from Light Account to Modular Account using Account Kit and unlock an ecosystem of plugins for your smart account stack.\\nModular Account has been audited by both Spearbit and Quantstamp. It is fully open source and supported by a Bug Bounty program. It is deployed on multiple networks and their respective testnets.\\n\",\"title\":\"Modular Account\",\"titles\":[\"Choosing a Smart Account\"]},{\"href\":\"/smart-contracts/choosing-a-smart-account#light-account\",\"html\":\"\\nLight Account is a collection of lightweight, production-ready ERC-4337 smart accounts. It builds on top of Ethereum Foundation's canonical SimpleAccount to add key improvements such as ownership transfers, multiple owners, ERC-1271 signature support, and gas optimizations.
\\nIt is fully open source and has been audited multiple times by Quantstamp. It is deployed on multiple networks and their respective testnets.
\\n\",\"id\":\"pages/smart-contracts/choosing-a-smart-account.mdx#light-account\",\"isPage\":false,\"text\":\"\\nLight Account is a collection of lightweight, production-ready ERC-4337 smart accounts. It builds on top of Ethereum Foundation's canonical SimpleAccount to add key improvements such as ownership transfers, multiple owners, ERC-1271 signature support, and gas optimizations.\\nIt is fully open source and has been audited multiple times by Quantstamp. It is deployed on multiple networks and their respective testnets.\\n\",\"title\":\"Light Account\",\"titles\":[\"Choosing a Smart Account\"]},{\"href\":\"/smart-contracts/choosing-a-smart-account#use-your-own-account\",\"html\":\"\\nAccount Kit also makes it easy to use your own smart account implementation. To learn how, see our guide on how to use your own account.
\",\"id\":\"pages/smart-contracts/choosing-a-smart-account.mdx#use-your-own-account\",\"isPage\":false,\"text\":\"\\nAccount Kit also makes it easy to use your own smart account implementation. To learn how, see our guide on how to use your own account.\",\"title\":\"Use your own Account\",\"titles\":[\"Choosing a Smart Account\"]}]}],[\"index.c0632a8022ee70245e01466af9ee944dd478134985532a1a4b8db24399a38b58\",{\"mdx\":\"---\\ntitle: Light Account • Deployments\\ndescription: Deployment addresses\\n---\\n\\n# Deployments\\n\\nThe following tables list the deployed factory and account implementation contract addresses for `LightAccount` and `MultiOwnerLightAccount` on different chains. Deployments for prior versions can be found in the [light-account](https://github.com/alchemyplatform/light-account/tree/develop/deployments) repo.\\n\\n## `LightAccount` (v2.0.0)\\n\\n| Chain | Factory Address | Account Implementation |\\n| ---------------- | -------------------------------------------- | -------------------------------------------- |\\n| Eth Mainnet | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Eth Sepolia | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Polygon Mainnet | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Polygon Amoy | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Optimism | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Optimism Sepolia | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Arbitrum | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Arbitrum Sepolia | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Base | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Base Sepolia | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Zora Mainnet | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Zora Sepolia | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Fraxtal Mainnet | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n| Fraxtal Sepolia | `0x0000000000400CdFef5E2714E63d8040b700BC24` | `0x8E8e658E22B12ada97B402fF0b044D6A325013C7` |\\n\\n## `LightAccount` (v1.1.0)\\n\\n| Chain | Factory Address | Account Implementation |\\n| ---------------- | -------------------------------------------- | -------------------------------------------- |\\n| Eth Mainnet | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Eth Sepolia | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Polygon Mainnet | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Polygon Amoy | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Optimism | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Optimism Sepolia | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Arbitrum | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Arbitrum Sepolia | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Base | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Base Sepolia | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Zora Mainnet | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Zora Sepolia | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Fraxtal Mainnet | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n| Fraxtal Sepolia | `0x00004EC70002a32400f8ae005A26081065620D20` | `0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba` |\\n\\n## `MultiOwnerLightAccount` (v2.0.0)\\n\\n| Chain | Factory Address | Account Implementation |\\n| ---------------- | -------------------------------------------- | -------------------------------------------- |\\n| Eth Mainnet | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Eth Sepolia | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Polygon Mainnet | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Polygon Mumbai | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Polygon Amoy | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Optimism | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Optimism Sepolia | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Arbitrum | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Arbitrum Sepolia | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Base | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Base Sepolia | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Zora Mainnet | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Zora Sepolia | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Fraxtal Mainnet | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n| Fraxtal Sepolia | `0x000000000019d2Ee9F2729A65AfE20bb0020AefC` | `0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D` |\\n\",\"document\":[{\"href\":\"/smart-contracts/light-account/deployments#deployments\",\"html\":\"\\nThe following tables list the deployed factory and account implementation contract addresses for LightAccount
and MultiOwnerLightAccount
on different chains. Deployments for prior versions can be found in the light-account repo.
Chain | Factory Address | Account Implementation |
---|---|---|
Eth Mainnet | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Eth Sepolia | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Polygon Mainnet | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Polygon Amoy | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Optimism | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Optimism Sepolia | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Arbitrum | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Arbitrum Sepolia | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Base | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Base Sepolia | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Zora Mainnet | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Zora Sepolia | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Fraxtal Mainnet | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Fraxtal Sepolia | 0x0000000000400CdFef5E2714E63d8040b700BC24 | 0x8E8e658E22B12ada97B402fF0b044D6A325013C7 |
Chain | Factory Address | Account Implementation |
---|---|---|
Eth Mainnet | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Eth Sepolia | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Polygon Mainnet | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Polygon Amoy | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Optimism | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Optimism Sepolia | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Arbitrum | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Arbitrum Sepolia | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Base | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Base Sepolia | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Zora Mainnet | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Zora Sepolia | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Fraxtal Mainnet | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Fraxtal Sepolia | 0x00004EC70002a32400f8ae005A26081065620D20 | 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba |
Chain | Factory Address | Account Implementation |
---|---|---|
Eth Mainnet | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Eth Sepolia | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Polygon Mainnet | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Polygon Mumbai | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Polygon Amoy | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Optimism | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Optimism Sepolia | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Arbitrum | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Arbitrum Sepolia | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Base | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Base Sepolia | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Zora Mainnet | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Zora Sepolia | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Fraxtal Mainnet | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Fraxtal Sepolia | 0x000000000019d2Ee9F2729A65AfE20bb0020AefC | 0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D |
Not all smart account implementations support transferring the ownership (e.g. SimpleAccount
). However, a number of the accounts in this guide and in Account Kit do, including our LightAccount
! Let's see a few different ways we can transfer ownership of an Account (using LightAccount
as an example).
LightAccount
exposes the following method which allows the existing owner to transfer ownership to a new owner address:
function transferOwnership(address newOwner) public virtual onlyOwner
\\nThere a number of ways you can call this method using Account Kit.
\\n\",\"id\":\"pages/smart-contracts/transfer-ownership/light-account.mdx#usage\",\"isPage\":false,\"text\":\"\\nLightAccount exposes the following method which allows the existing owner to transfer ownership to a new owner address:\\nfunction transferOwnership(address newOwner) public virtual onlyOwner\\nThere a number of ways you can call this method using Account Kit.\\n\",\"title\":\"Usage\",\"titles\":[\"How to transfer ownership of LightAccount\"]},{\"href\":\"/smart-contracts/transfer-ownership/light-account#1-using-transferownership-client-action\",\"html\":\"\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { lightAccountClient } from "./client";\\nimport { createLightAccountClient } from "@account-kit/smart-contracts";\\n \\n// this will return the signer of the smart account you want to transfer ownerhip to\\nconst newOwner = LocalAccountSigner.mnemonicToAccountSigner(NEW_OWNER_MNEMONIC);\\nconst accountAddress = lightAccountClient.getAddress();\\n \\n\\nconst hash = lightAccountClient.transferOwnership({\\n newOwner,\\n waitForTxn: true,\\n});\\n \\n// after transaction is mined on the network,\\n// create a new light account client for the transferred Light Account\\nconst transferredClient = await createLightAccountClient({\\n transport: custom(smartAccountClient),\\n chain: smartAccountClient.chain,\\n signer: newOwner,\\n accountAddress, // NOTE: you MUST specify the original smart account address to connect using the new owner/signer\\n version: "v2.0.0", // NOTE: if the version of the light account is not v2.0.0, it must be specified here\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n});
Since @alchemy/aa-accounts
exports a LightAccount
ABI, the above approach makes it easy to transfer ownership. That said, you can also directly call sendUserOperation
to execute the ownership transfer. As you will see below, however, it is a bit verbose:
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { encodeFunctionData } from "viem";\\nimport { lightAccountClient } from "./client";\\n \\n// this will return the address of the smart account you want to transfer ownerhip of\\nconst accountAddress = lightAccountClient.getAddress();\\nconst newOwner = "0x..."; // the address of the new owner\\n \\n\\nconst result = await lightAccountClient.sendUserOperation({\\n to: accountAddress,\\n data: lightAccountClient.encodeTransferOwnership(newOwner),\\n});\\n// wait for txn with UO to be mined\\nawait lightAccountClient.waitForUserOperationTransaction(result);
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n});
See the LightAccount
docs for more details about our `LightAccount implementation.
You are not limited to the accounts defined in @account-kit/smart-contracts
. The SmartAccountClient
can be used with any smart account because it only relies on the SmartContractAccount
interface. This means you can use your own smart account implementation with Account Kit.
import { getVersion060EntryPoint, toSmartContractAccount } from "@aa-sdk/core";\\nimport { http, type SignableMessage } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst myAccount = await toSmartContractAccount({\\n /// REQUIRED PARAMS ///\\n source: "MyAccount",\\n transport: http("RPC_URL"),\\n chain: sepolia,\\n // The EntryPointDef that your account is compatible with\\n entryPoint: getVersion060EntryPoint(sepolia),\\n // This should return a concatenation of your `factoryAddress` and the `callData` for your factory's create account method\\n getAccountInitCode: () => "0x{factoryAddress}{callData}",\\n // an invalid signature that doesn't cause your account to revert during validation\\n getDummySignature: () => "0x1234...",\\n // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method\\n encodeExecute: (uo) => "....",\\n signMessage: ({ message }: SignableMessage) => "0x...",\\n signTypedData: (typedData) => "0x000",\\n \\n /// OPTIONAL PARAMS ///\\n // if you already know your account's address, pass that in here to avoid generating a new counterfactual\\n accountAddress: Address,\\n // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method\\n encodeBatchExecute: (uos) => "0x...",\\n // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here\\n signUserOperationHash: (hash) => "0x...",\\n // allows you to define the calldata for upgrading your account\\n encodeUpgradeToAndCall: (params) => "0x...",\\n});
\\nTo use your account, you will need to pass it into a SmartAccountClient
.
import { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst client = createAlchemySmartAccountClient({\\n // created above\\n account: myAccount,\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n});
\\n\",\"id\":\"pages/smart-contracts/custom/using-your-own.mdx#using-your-own-smart-account\",\"isPage\":true,\"text\":\"\\nYou are not limited to the accounts defined in @account-kit/smart-contracts. The SmartAccountClient can be used with any smart account because it only relies on the SmartContractAccount interface. This means you can use your own smart account implementation with Account Kit.\\nimport { getVersion060EntryPoint, toSmartContractAccount } from "@aa-sdk/core";\\nimport { http, type SignableMessage } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst myAccount = await toSmartContractAccount({\\n /// REQUIRED PARAMS ///\\n source: "MyAccount",\\n transport: http("RPC_URL"),\\n chain: sepolia,\\n // The EntryPointDef that your account is compatible with\\n entryPoint: getVersion060EntryPoint(sepolia),\\n // This should return a concatenation of your `factoryAddress` and the `callData` for your factory's create account method\\n getAccountInitCode: () => "0x{factoryAddress}{callData}",\\n // an invalid signature that doesn't cause your account to revert during validation\\n getDummySignature: () => "0x1234...",\\n // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method\\n encodeExecute: (uo) => "....",\\n signMessage: ({ message }: SignableMessage) => "0x...",\\n signTypedData: (typedData) => "0x000",\\n \\n /// OPTIONAL PARAMS ///\\n // if you already know your account's address, pass that in here to avoid generating a new counterfactual\\n accountAddress: Address,\\n // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method\\n encodeBatchExecute: (uos) => "0x...",\\n // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here\\n signUserOperationHash: (hash) => "0x...",\\n // allows you to define the calldata for upgrading your account\\n encodeUpgradeToAndCall: (params) => "0x...",\\n});\\nTo use your account, you will need to pass it into a SmartAccountClient.\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@aa-sdk/core";\\n \\nconst client = createAlchemySmartAccountClient({\\n // created above\\n account: myAccount,\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n});\\n\",\"title\":\"Using your own Smart Account\",\"titles\":[]},{\"href\":\"/smart-contracts/custom/using-your-own#lightsmartcontractaccount-as-an-example\",\"html\":\"\\nWe have built an extension of the eth-infinitism SimpleAccount
called LightAccount.sol. You can learn more about Light Account in the Light Account documentation.
We provide an implementation of SmartContractAccount
that works with LightAccount.sol
, which can be used as an example of how to implement your own Smart Contract Account:
import {\\n createBundlerClient,\\n getAccountAddress,\\n getEntryPoint,\\n type Address,\\n type EntryPointDef,\\n type SmartAccountSigner,\\n} from "@aa-sdk/core";\\nimport {\\n concatHex,\\n encodeFunctionData,\\n type Chain,\\n type Hex,\\n type Transport,\\n} from "viem";\\nimport { LightAccountAbi_v1 } from "../abis/LightAccountAbi_v1.js";\\nimport { LightAccountAbi_v2 } from "../abis/LightAccountAbi_v2.js";\\nimport { LightAccountFactoryAbi_v1 } from "../abis/LightAccountFactoryAbi_v1.js";\\nimport { LightAccountFactoryAbi_v2 } from "../abis/LightAccountFactoryAbi_v2.js";\\nimport type {\\n LightAccountEntryPointVersion,\\n LightAccountVersion,\\n} from "../types.js";\\nimport {\\n AccountVersionRegistry,\\n LightAccountUnsupported1271Factories,\\n defaultLightAccountVersion,\\n getDefaultLightAccountFactoryAddress,\\n} from "../utils.js";\\nimport {\\n createLightAccountBase,\\n type CreateLightAccountBaseParams,\\n type LightAccountBase,\\n} from "./base.js";\\n \\nexport type LightAccount<\\n TSigner extends SmartAccountSigner = SmartAccountSigner,\\n TLightAccountVersion extends LightAccountVersion<"LightAccount"> = LightAccountVersion<"LightAccount">\\n> = LightAccountBase<TSigner, "LightAccount", TLightAccountVersion> & {\\n encodeTransferOwnership: (newOwner: Address) => Hex;\\n getOwnerAddress: () => Promise<Address>;\\n};\\n \\nexport type CreateLightAccountParams<\\n TTransport extends Transport = Transport,\\n TSigner extends SmartAccountSigner = SmartAccountSigner,\\n TLightAccountVersion extends LightAccountVersion<"LightAccount"> = LightAccountVersion<"LightAccount">\\n> = Omit<\\n CreateLightAccountBaseParams<\\n "LightAccount",\\n TLightAccountVersion,\\n TTransport,\\n TSigner\\n >,\\n | "getAccountInitCode"\\n | "entryPoint"\\n | "version"\\n | "abi"\\n | "accountAddress"\\n | "type"\\n> & {\\n salt?: bigint;\\n initCode?: Hex;\\n accountAddress?: Address;\\n factoryAddress?: Address;\\n version?: TLightAccountVersion;\\n entryPoint?: EntryPointDef<\\n LightAccountEntryPointVersion<"LightAccount", TLightAccountVersion>,\\n Chain\\n >;\\n};\\n \\nexport async function createLightAccount<\\n TTransport extends Transport = Transport,\\n TSigner extends SmartAccountSigner = SmartAccountSigner,\\n TLightAccountVersion extends LightAccountVersion<"LightAccount"> = "v2.0.0"\\n>(\\n config: CreateLightAccountParams<TTransport, TSigner, TLightAccountVersion>\\n): Promise<LightAccount<TSigner, TLightAccountVersion>>;\\n \\n/**\\n * Creates a light account based on the provided parameters such as transport, chain, signer, init code, and more. Ensures that an account is configured and returned with various capabilities, such as transferring ownership and retrieving the owner's address.\\n *\\n * @example\\n * ```ts\\n * import { createLightAccount } from "@account-kit/smart-contracts";\\n * import { LocalAccountSigner } from "@aa-sdk/core";\\n * import { sepolia } from "viem/chains";\\n * import { http, generatePrivateKey } from "viem"\\n *\\n * const account = await createLightAccount({\\n * chain: sepolia,\\n * transport: http("RPC_URL"),\\n * signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey())\\n * });\\n * ```\\n *\\n * @param {CreateLightAccountParams} config The parameters for creating a light account\\n * @returns {Promise<LightAccount>} A promise that resolves to a `LightAccount` object containing the created account information and methods\\n */\\nexport async function createLightAccount({\\n transport,\\n chain,\\n signer,\\n initCode,\\n version = defaultLightAccountVersion(),\\n entryPoint = getEntryPoint(chain, {\\n version: AccountVersionRegistry["LightAccount"][version]\\n .entryPointVersion as any,\\n }),\\n accountAddress,\\n factoryAddress = getDefaultLightAccountFactoryAddress(chain, version),\\n salt: salt_ = 0n,\\n}: CreateLightAccountParams): Promise<LightAccount> {\\n const client = createBundlerClient({\\n transport,\\n chain,\\n });\\n \\n const accountAbi =\\n version === "v2.0.0" ? LightAccountAbi_v2 : LightAccountAbi_v1;\\n const factoryAbi =\\n version === "v2.0.0"\\n ? LightAccountFactoryAbi_v1\\n : LightAccountFactoryAbi_v2;\\n \\n const getAccountInitCode = async () => {\\n if (initCode) return initCode;\\n \\n const salt = LightAccountUnsupported1271Factories.has(\\n factoryAddress.toLowerCase() as Address\\n )\\n ? 0n\\n : salt_;\\n \\n return concatHex([\\n factoryAddress,\\n encodeFunctionData({\\n abi: factoryAbi,\\n functionName: "createAccount",\\n args: [await signer.getAddress(), salt],\\n }),\\n ]);\\n };\\n \\n const address = await getAccountAddress({\\n client,\\n entryPoint,\\n accountAddress,\\n getAccountInitCode,\\n });\\n \\n const account = await createLightAccountBase<\\n "LightAccount",\\n LightAccountVersion<"LightAccount">,\\n Transport,\\n SmartAccountSigner\\n >({\\n transport,\\n chain,\\n signer,\\n abi: accountAbi,\\n type: "LightAccount",\\n version,\\n entryPoint,\\n accountAddress: address,\\n getAccountInitCode,\\n });\\n \\n return {\\n ...account,\\n \\n encodeTransferOwnership: (newOwner: Address) => {\\n return encodeFunctionData({\\n abi: accountAbi,\\n functionName: "transferOwnership",\\n args: [newOwner],\\n });\\n },\\n async getOwnerAddress(): Promise<Address> {\\n const callResult = await client.readContract({\\n address,\\n abi: accountAbi,\\n functionName: "owner",\\n });\\n \\n if (callResult == null) {\\n throw new Error("could not get on-chain owner");\\n }\\n \\n return callResult;\\n },\\n };\\n}
For your reference, this is the definition of the toSmartContractAccount
interface as pulled from the source code:
:::details SmartContractAccount
\\nimport {\\n getContract,\\n hexToBytes,\\n trim,\\n type Address,\\n type Chain,\\n type CustomSource,\\n type Hex,\\n type LocalAccount,\\n type PublicClient,\\n type SignableMessage,\\n type Transport,\\n type TypedData,\\n type TypedDataDefinition,\\n} from "viem";\\nimport { toAccount } from "viem/accounts";\\nimport { createBundlerClient } from "../client/bundlerClient.js";\\nimport type {\\n EntryPointDef,\\n EntryPointRegistryBase,\\n EntryPointVersion,\\n} from "../entrypoint/types.js";\\nimport {\\n BatchExecutionNotSupportedError,\\n FailedToGetStorageSlotError,\\n GetCounterFactualAddressError,\\n SignTransactionNotSupportedError,\\n UpgradesNotSupportedError,\\n} from "../errors/account.js";\\nimport { InvalidRpcUrlError } from "../errors/client.js";\\nimport { InvalidEntryPointError } from "../errors/entrypoint.js";\\nimport { Logger } from "../logger.js";\\nimport type { SmartAccountSigner } from "../signer/types.js";\\nimport { wrapSignatureWith6492 } from "../signer/utils.js";\\nimport type { NullAddress } from "../types.js";\\nimport type { IsUndefined } from "../utils/types.js";\\n \\nexport type AccountOp = {\\n target: Address;\\n value?: bigint;\\n data: Hex | "0x";\\n};\\n \\nexport enum DeploymentState {\\n UNDEFINED = "0x0",\\n NOT_DEPLOYED = "0x1",\\n DEPLOYED = "0x2",\\n}\\n \\nexport type GetEntryPointFromAccount<\\n TAccount extends SmartContractAccount | undefined,\\n TAccountOverride extends SmartContractAccount = SmartContractAccount\\n> = GetAccountParameter<\\n TAccount,\\n TAccountOverride\\n> extends SmartContractAccount<string, infer TEntryPointVersion>\\n ? TEntryPointVersion\\n : EntryPointVersion;\\n \\nexport type GetAccountParameter<\\n TAccount extends SmartContractAccount | undefined =\\n | SmartContractAccount\\n | undefined,\\n TAccountOverride extends SmartContractAccount = SmartContractAccount\\n> = IsUndefined<TAccount> extends true\\n ? { account: TAccountOverride }\\n : { account?: TAccountOverride };\\n \\nexport type UpgradeToAndCallParams = {\\n upgradeToAddress: Address;\\n upgradeToInitData: Hex;\\n};\\n \\nexport type SmartContractAccountWithSigner<\\n Name extends string = string,\\n TSigner extends SmartAccountSigner = SmartAccountSigner,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = SmartContractAccount<Name, TEntryPointVersion> & {\\n getSigner: () => TSigner;\\n};\\n \\n/**\\n * Determines if the given SmartContractAccount has a signer associated with it.\\n *\\n * @example\\n * ```ts\\n * import { toSmartContractAccount } from "@aa-sdk/core";\\n *\\n * const account = await toSmartContractAccount(...);\\n *\\n * console.log(isSmartAccountWithSigner(account)); // false: the base account does not have a publicly accessible signer\\n * ```\\n *\\n * @param {SmartContractAccount} account The account to check.\\n * @returns {boolean} true if the account has a signer, otherwise false.\\n */\\nexport const isSmartAccountWithSigner = (\\n account: SmartContractAccount\\n): account is SmartContractAccountWithSigner => {\\n return "getSigner" in account;\\n};\\n \\nexport type SmartContractAccount<\\n Name extends string = string,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = LocalAccount<Name> & {\\n source: Name;\\n getDummySignature: () => Hex | Promise<Hex>;\\n encodeExecute: (tx: AccountOp) => Promise<Hex>;\\n encodeBatchExecute: (txs: AccountOp[]) => Promise<Hex>;\\n signUserOperationHash: (uoHash: Hex) => Promise<Hex>;\\n signMessageWith6492: (params: { message: SignableMessage }) => Promise<Hex>;\\n signTypedDataWith6492: <\\n const typedData extends TypedData | Record<string, unknown>,\\n primaryType extends keyof typedData | "EIP712Domain" = keyof typedData\\n >(\\n typedDataDefinition: TypedDataDefinition<typedData, primaryType>\\n ) => Promise<Hex>;\\n encodeUpgradeToAndCall: (params: UpgradeToAndCallParams) => Promise<Hex>;\\n getNonce(nonceKey?: bigint): Promise<bigint>;\\n getInitCode: () => Promise<Hex>;\\n isAccountDeployed: () => Promise<boolean>;\\n getFactoryAddress: () => Promise<Address>;\\n getFactoryData: () => Promise<Hex>;\\n getEntryPoint: () => EntryPointDef<TEntryPointVersion>;\\n getImplementationAddress: () => Promise<NullAddress | Address>;\\n};\\n \\nexport interface AccountEntryPointRegistry<Name extends string = string>\\n extends EntryPointRegistryBase<\\n SmartContractAccount<Name, EntryPointVersion>\\n > {\\n "0.6.0": SmartContractAccount<Name, "0.6.0">;\\n "0.7.0": SmartContractAccount<Name, "0.7.0">;\\n}\\n \\nexport type ToSmartContractAccountParams<\\n Name extends string = string,\\n TTransport extends Transport = Transport,\\n TChain extends Chain = Chain,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = {\\n source: Name;\\n transport: TTransport;\\n chain: TChain;\\n entryPoint: EntryPointDef<TEntryPointVersion, TChain>;\\n accountAddress?: Address;\\n getAccountInitCode: () => Promise<Hex>;\\n getDummySignature: () => Hex | Promise<Hex>;\\n encodeExecute: (tx: AccountOp) => Promise<Hex>;\\n encodeBatchExecute?: (txs: AccountOp[]) => Promise<Hex>;\\n // if not provided, will default to just using signMessage over the Hex\\n signUserOperationHash?: (uoHash: Hex) => Promise<Hex>;\\n encodeUpgradeToAndCall?: (params: UpgradeToAndCallParams) => Promise<Hex>;\\n} & Omit<CustomSource, "signTransaction" | "address">;\\n \\n/**\\n * Parses the factory address and factory calldata from the provided account initialization code (initCode).\\n *\\n * @example\\n * ```ts\\n * import { parseFactoryAddressFromAccountInitCode } from "@aa-sdk/core";\\n *\\n * const [address, calldata] = parseFactoryAddressFromAccountInitCode("0xAddressCalldata");\\n * ```\\n *\\n * @param {Hex} initCode The initialization code from which to parse the factory address and calldata\\n * @returns {[Address, Hex]} A tuple containing the parsed factory address and factory calldata\\n */\\nexport const parseFactoryAddressFromAccountInitCode = (\\n initCode: Hex\\n): [Address, Hex] => {\\n const factoryAddress: Address = `0x${initCode.substring(2, 42)}`;\\n const factoryCalldata: Hex = `0x${initCode.substring(42)}`;\\n return [factoryAddress, factoryCalldata];\\n};\\n \\nexport type GetAccountAddressParams = {\\n client: PublicClient;\\n entryPoint: EntryPointDef;\\n accountAddress?: Address;\\n getAccountInitCode: () => Promise<Hex>;\\n};\\n \\n/**\\n * Retrieves the account address. Uses a provided `accountAddress` if available; otherwise, it computes the address using the entry point contract and the initial code.\\n *\\n * @example\\n * ```ts\\n * import { getEntryPoint, getAccountAddress } from "@aa-sdk/core";\\n *\\n * const accountAddress = await getAccountAddress({\\n * client,\\n * entryPoint: getEntryPoint(chain),\\n * getAccountInitCode: async () => "0x{factoryAddress}{factoryCallData}",\\n * });\\n * ```\\n *\\n * @param {GetAccountAddressParams} params The configuration object\\n * @param {PublicClient} params.client A public client instance to interact with the blockchain\\n * @param {EntryPointDef} params.entryPoint The entry point definition which includes the address and ABI\\n * @param {Address} params.accountAddress Optional existing account address\\n * @param {() => Promise<Hex>} params.getAccountInitCode A function that returns a Promise resolving to a Hex string representing the initial code of the account\\n * @returns {Promise<Address>} A promise that resolves to the account address\\n */\\nexport const getAccountAddress = async ({\\n client,\\n entryPoint,\\n accountAddress,\\n getAccountInitCode,\\n}: GetAccountAddressParams) => {\\n if (accountAddress) return accountAddress;\\n \\n const entryPointContract = getContract({\\n address: entryPoint.address,\\n abi: entryPoint.abi,\\n client,\\n });\\n \\n const initCode = await getAccountInitCode();\\n Logger.verbose("[BaseSmartContractAccount](getAddress) initCode: ", initCode);\\n \\n try {\\n await entryPointContract.simulate.getSenderAddress([initCode]);\\n } catch (err: any) {\\n Logger.verbose(\\n "[BaseSmartContractAccount](getAddress) getSenderAddress err: ",\\n err\\n );\\n if (err.cause?.data?.errorName === "SenderAddressResult") {\\n Logger.verbose(\\n "[BaseSmartContractAccount](getAddress) entryPoint.getSenderAddress result:",\\n err.cause.data.args[0]\\n );\\n \\n return err.cause.data.args[0] as Address;\\n }\\n \\n if (err.details === "Invalid URL") {\\n throw new InvalidRpcUrlError();\\n }\\n }\\n \\n throw new GetCounterFactualAddressError();\\n};\\n \\nexport async function toSmartContractAccount<\\n Name extends string = string,\\n TTransport extends Transport = Transport,\\n TChain extends Chain = Chain,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n>({\\n transport,\\n chain,\\n entryPoint,\\n source,\\n accountAddress,\\n getAccountInitCode,\\n signMessage,\\n signTypedData,\\n encodeBatchExecute,\\n encodeExecute,\\n getDummySignature,\\n signUserOperationHash,\\n encodeUpgradeToAndCall,\\n}: ToSmartContractAccountParams<\\n Name,\\n TTransport,\\n TChain,\\n TEntryPointVersion\\n>): Promise<SmartContractAccount<Name, TEntryPointVersion>>;\\n \\n/**\\n * Converts an account to a smart contract account and sets up various account-related methods using the provided parameters like transport, chain, entry point, and other utilities.\\n *\\n * @example\\n * ```ts\\n * import { http, type SignableMessage } from "viem";\\n * import { sepolia } from "viem/chains";\\n *\\n * const myAccount = await toSmartContractAccount({\\n * /// REQUIRED PARAMS ///\\n * source: "MyAccount",\\n * transport: http("RPC_URL"),\\n * chain: sepolia,\\n * // The EntryPointDef that your account is com"patible with\\n * entryPoint: getEntryPoint(sepolia, { version: "0.6.0" }),\\n * // This should return a concatenation of your `factoryAddress` and the `callData` for your factory's create account method\\n * getAccountInitCode: async () => "0x{factoryAddress}{callData}",\\n * // an invalid signature that doesn't cause your account to revert during validation\\n * getDummySignature: () => "0x1234...",\\n * // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method\\n * encodeExecute: async (uo) => "0xcalldata",\\n * signMessage: async ({ message }: { message: SignableMessage }) => "0x...",\\n * signTypedData: async (typedData) => "0x000",\\n *\\n * /// OPTIONAL PARAMS ///\\n * // if you already know your account's address, pass that in here to avoid generating a new counterfactual\\n * accountAddress: "0xaddressoverride",\\n * // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method\\n * encodeBatchExecute: async (uos) => "0x...",\\n * // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here\\n * signUserOperationHash: async (hash) => "0x...",\\n * // allows you to define the calldata for upgrading your account\\n * encodeUpgradeToAndCall: async (params) => "0x...",\\n * });\\n * ```\\n *\\n * @param {ToSmartContractAccountParams} params the parameters required for converting to a smart contract account\\n * @param {Transport} params.transport the transport mechanism used for communication\\n * @param {Chain} params.chain the blockchain chain used in the account\\n * @param {EntryPoint} params.entryPoint the entry point of the smart contract\\n * @param {string} params.source the source identifier for the account\\n * @param {Address} [params.accountAddress] the address of the account\\n * @param {() => Promise<Hex>} params.getAccountInitCode a function to get the initial state code of the account\\n * @param {(message: { message: SignableMessage }) => Promise<Hex>} params.signMessage a function to sign a message\\n * @param {(typedDataDefinition: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>} params.signTypedData a function to sign typed data\\n * @param {(transactions: Transaction[]) => Hex} [params.encodeBatchExecute] a function to encode batch transactions\\n * @param {(tx: Transaction) => Hex} params.encodeExecute a function to encode a single transaction\\n * @param {() => Promise<Hex>} params.getDummySignature a function to get a dummy signature\\n * @param {(uoHash: Hex) => Promise<Hex>} [params.signUserOperationHash] a function to sign user operations\\n * @param {(implementationAddress: Address, implementationCallData: Hex) => Hex} [params.encodeUpgradeToAndCall] a function to encode upgrade call\\n * @returns {Promise<SmartContractAccount>} a promise that resolves to a SmartContractAccount object with methods and properties for interacting with the smart contract account\\n */\\nexport async function toSmartContractAccount(\\n params: ToSmartContractAccountParams\\n): Promise<SmartContractAccount> {\\n const {\\n transport,\\n chain,\\n entryPoint,\\n source,\\n accountAddress,\\n getAccountInitCode,\\n signMessage,\\n signTypedData,\\n encodeBatchExecute,\\n encodeExecute,\\n getDummySignature,\\n signUserOperationHash,\\n encodeUpgradeToAndCall,\\n } = params;\\n \\n const client = createBundlerClient({\\n // we set the retry count to 0 so that viem doesn't retry during\\n // getting the address. That call always reverts and without this\\n // viem will retry 3 times, making this call very slow\\n transport: (opts) => transport({ ...opts, chain, retryCount: 0 }),\\n chain,\\n });\\n \\n const entryPointContract = getContract({\\n address: entryPoint.address,\\n abi: entryPoint.abi,\\n client,\\n });\\n \\n const accountAddress_ = await getAccountAddress({\\n client,\\n entryPoint: entryPoint,\\n accountAddress,\\n getAccountInitCode,\\n });\\n \\n let deploymentState = DeploymentState.UNDEFINED;\\n \\n const getInitCode = async () => {\\n if (deploymentState === DeploymentState.DEPLOYED) {\\n return "0x";\\n }\\n const contractCode = await client.getBytecode({\\n address: accountAddress_,\\n });\\n \\n if ((contractCode?.length ?? 0) > 2) {\\n deploymentState = DeploymentState.DEPLOYED;\\n return "0x";\\n } else {\\n deploymentState = DeploymentState.NOT_DEPLOYED;\\n }\\n \\n return getAccountInitCode();\\n };\\n \\n const signUserOperationHash_ =\\n signUserOperationHash ??\\n (async (uoHash: Hex) => {\\n return signMessage({ message: { raw: hexToBytes(uoHash) } });\\n });\\n \\n const getFactoryAddress = async (): Promise<Address> =>\\n parseFactoryAddressFromAccountInitCode(await getAccountInitCode())[0];\\n \\n const getFactoryData = async (): Promise<Hex> =>\\n parseFactoryAddressFromAccountInitCode(await getAccountInitCode())[1];\\n \\n const encodeUpgradeToAndCall_ =\\n encodeUpgradeToAndCall ??\\n (() => {\\n throw new UpgradesNotSupportedError(source);\\n });\\n \\n const isAccountDeployed = async () => {\\n const initCode = await getInitCode();\\n return initCode === "0x";\\n };\\n \\n const getNonce = async (nonceKey = 0n): Promise<bigint> => {\\n if (!(await isAccountDeployed())) {\\n return 0n;\\n }\\n \\n return entryPointContract.read.getNonce([\\n accountAddress_,\\n nonceKey,\\n ]) as Promise<bigint>;\\n };\\n \\n const account = toAccount({\\n address: accountAddress_,\\n signMessage,\\n signTypedData,\\n signTransaction: () => {\\n throw new SignTransactionNotSupportedError();\\n },\\n });\\n \\n const create6492Signature = async (isDeployed: boolean, signature: Hex) => {\\n if (isDeployed) {\\n return signature;\\n }\\n \\n const [factoryAddress, factoryCalldata] =\\n parseFactoryAddressFromAccountInitCode(await getAccountInitCode());\\n \\n return wrapSignatureWith6492({\\n factoryAddress,\\n factoryCalldata,\\n signature,\\n });\\n };\\n \\n const signMessageWith6492 = async (message: { message: SignableMessage }) => {\\n const [isDeployed, signature] = await Promise.all([\\n isAccountDeployed(),\\n account.signMessage(message),\\n ]);\\n \\n return create6492Signature(isDeployed, signature);\\n };\\n \\n const signTypedDataWith6492 = async <\\n const typedData extends TypedData | Record<string, unknown>,\\n primaryType extends keyof typedData | "EIP712Domain" = keyof typedData\\n >(\\n typedDataDefinition: TypedDataDefinition<typedData, primaryType>\\n ): Promise<Hex> => {\\n const [isDeployed, signature] = await Promise.all([\\n isAccountDeployed(),\\n account.signTypedData(typedDataDefinition),\\n ]);\\n \\n return create6492Signature(isDeployed, signature);\\n };\\n \\n const getImplementationAddress = async (): Promise<NullAddress | Address> => {\\n const storage = await client.getStorageAt({\\n address: account.address,\\n // This is the default slot for the implementation address for Proxies\\n slot: "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",\\n });\\n \\n if (storage == null) {\\n throw new FailedToGetStorageSlotError(\\n "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",\\n "Proxy Implementation Address"\\n );\\n }\\n \\n return trim(storage);\\n };\\n \\n if (entryPoint.version !== "0.6.0" && entryPoint.version !== "0.7.0") {\\n throw new InvalidEntryPointError(chain, entryPoint.version);\\n }\\n \\n return {\\n ...account,\\n source,\\n // TODO: I think this should probably be signUserOperation instead\\n // and allow for generating the UO hash based on the EP version\\n signUserOperationHash: signUserOperationHash_,\\n getFactoryAddress,\\n getFactoryData,\\n encodeBatchExecute:\\n encodeBatchExecute ??\\n (() => {\\n throw new BatchExecutionNotSupportedError(source);\\n }),\\n encodeExecute,\\n getDummySignature,\\n getInitCode,\\n encodeUpgradeToAndCall: encodeUpgradeToAndCall_,\\n getEntryPoint: () => entryPoint,\\n isAccountDeployed,\\n getNonce,\\n signMessageWith6492,\\n signTypedDataWith6492,\\n getImplementationAddress,\\n };\\n}
\\n:::
\",\"id\":\"pages/smart-contracts/custom/using-your-own.mdx#the-tosmartcontractaccount-method\",\"isPage\":false,\"text\":\"\\nFor your reference, this is the definition of the toSmartContractAccount interface as pulled from the source code:\\n:::details SmartContractAccount\\nimport {\\n getContract,\\n hexToBytes,\\n trim,\\n type Address,\\n type Chain,\\n type CustomSource,\\n type Hex,\\n type LocalAccount,\\n type PublicClient,\\n type SignableMessage,\\n type Transport,\\n type TypedData,\\n type TypedDataDefinition,\\n} from "viem";\\nimport { toAccount } from "viem/accounts";\\nimport { createBundlerClient } from "../client/bundlerClient.js";\\nimport type {\\n EntryPointDef,\\n EntryPointRegistryBase,\\n EntryPointVersion,\\n} from "../entrypoint/types.js";\\nimport {\\n BatchExecutionNotSupportedError,\\n FailedToGetStorageSlotError,\\n GetCounterFactualAddressError,\\n SignTransactionNotSupportedError,\\n UpgradesNotSupportedError,\\n} from "../errors/account.js";\\nimport { InvalidRpcUrlError } from "../errors/client.js";\\nimport { InvalidEntryPointError } from "../errors/entrypoint.js";\\nimport { Logger } from "../logger.js";\\nimport type { SmartAccountSigner } from "../signer/types.js";\\nimport { wrapSignatureWith6492 } from "../signer/utils.js";\\nimport type { NullAddress } from "../types.js";\\nimport type { IsUndefined } from "../utils/types.js";\\n \\nexport type AccountOp = {\\n target: Address;\\n value?: bigint;\\n data: Hex | "0x";\\n};\\n \\nexport enum DeploymentState {\\n UNDEFINED = "0x0",\\n NOT_DEPLOYED = "0x1",\\n DEPLOYED = "0x2",\\n}\\n \\nexport type GetEntryPointFromAccount<\\n TAccount extends SmartContractAccount | undefined,\\n TAccountOverride extends SmartContractAccount = SmartContractAccount\\n> = GetAccountParameter<\\n TAccount,\\n TAccountOverride\\n> extends SmartContractAccount<string, infer TEntryPointVersion>\\n ? TEntryPointVersion\\n : EntryPointVersion;\\n \\nexport type GetAccountParameter<\\n TAccount extends SmartContractAccount | undefined =\\n | SmartContractAccount\\n | undefined,\\n TAccountOverride extends SmartContractAccount = SmartContractAccount\\n> = IsUndefined<TAccount> extends true\\n ? { account: TAccountOverride }\\n : { account?: TAccountOverride };\\n \\nexport type UpgradeToAndCallParams = {\\n upgradeToAddress: Address;\\n upgradeToInitData: Hex;\\n};\\n \\nexport type SmartContractAccountWithSigner<\\n Name extends string = string,\\n TSigner extends SmartAccountSigner = SmartAccountSigner,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = SmartContractAccount<Name, TEntryPointVersion> & {\\n getSigner: () => TSigner;\\n};\\n \\n/**\\n * Determines if the given SmartContractAccount has a signer associated with it.\\n *\\n * @example\\n * ```ts\\n * import { toSmartContractAccount } from "@aa-sdk/core";\\n *\\n * const account = await toSmartContractAccount(...);\\n *\\n * console.log(isSmartAccountWithSigner(account)); // false: the base account does not have a publicly accessible signer\\n * ```\\n *\\n * @param {SmartContractAccount} account The account to check.\\n * @returns {boolean} true if the account has a signer, otherwise false.\\n */\\nexport const isSmartAccountWithSigner = (\\n account: SmartContractAccount\\n): account is SmartContractAccountWithSigner => {\\n return "getSigner" in account;\\n};\\n \\nexport type SmartContractAccount<\\n Name extends string = string,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = LocalAccount<Name> & {\\n source: Name;\\n getDummySignature: () => Hex | Promise<Hex>;\\n encodeExecute: (tx: AccountOp) => Promise<Hex>;\\n encodeBatchExecute: (txs: AccountOp[]) => Promise<Hex>;\\n signUserOperationHash: (uoHash: Hex) => Promise<Hex>;\\n signMessageWith6492: (params: { message: SignableMessage }) => Promise<Hex>;\\n signTypedDataWith6492: <\\n const typedData extends TypedData | Record<string, unknown>,\\n primaryType extends keyof typedData | "EIP712Domain" = keyof typedData\\n >(\\n typedDataDefinition: TypedDataDefinition<typedData, primaryType>\\n ) => Promise<Hex>;\\n encodeUpgradeToAndCall: (params: UpgradeToAndCallParams) => Promise<Hex>;\\n getNonce(nonceKey?: bigint): Promise<bigint>;\\n getInitCode: () => Promise<Hex>;\\n isAccountDeployed: () => Promise<boolean>;\\n getFactoryAddress: () => Promise<Address>;\\n getFactoryData: () => Promise<Hex>;\\n getEntryPoint: () => EntryPointDef<TEntryPointVersion>;\\n getImplementationAddress: () => Promise<NullAddress | Address>;\\n};\\n \\nexport interface AccountEntryPointRegistry<Name extends string = string>\\n extends EntryPointRegistryBase<\\n SmartContractAccount<Name, EntryPointVersion>\\n > {\\n "0.6.0": SmartContractAccount<Name, "0.6.0">;\\n "0.7.0": SmartContractAccount<Name, "0.7.0">;\\n}\\n \\nexport type ToSmartContractAccountParams<\\n Name extends string = string,\\n TTransport extends Transport = Transport,\\n TChain extends Chain = Chain,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n> = {\\n source: Name;\\n transport: TTransport;\\n chain: TChain;\\n entryPoint: EntryPointDef<TEntryPointVersion, TChain>;\\n accountAddress?: Address;\\n getAccountInitCode: () => Promise<Hex>;\\n getDummySignature: () => Hex | Promise<Hex>;\\n encodeExecute: (tx: AccountOp) => Promise<Hex>;\\n encodeBatchExecute?: (txs: AccountOp[]) => Promise<Hex>;\\n // if not provided, will default to just using signMessage over the Hex\\n signUserOperationHash?: (uoHash: Hex) => Promise<Hex>;\\n encodeUpgradeToAndCall?: (params: UpgradeToAndCallParams) => Promise<Hex>;\\n} & Omit<CustomSource, "signTransaction" | "address">;\\n \\n/**\\n * Parses the factory address and factory calldata from the provided account initialization code (initCode).\\n *\\n * @example\\n * ```ts\\n * import { parseFactoryAddressFromAccountInitCode } from "@aa-sdk/core";\\n *\\n * const [address, calldata] = parseFactoryAddressFromAccountInitCode("0xAddressCalldata");\\n * ```\\n *\\n * @param {Hex} initCode The initialization code from which to parse the factory address and calldata\\n * @returns {[Address, Hex]} A tuple containing the parsed factory address and factory calldata\\n */\\nexport const parseFactoryAddressFromAccountInitCode = (\\n initCode: Hex\\n): [Address, Hex] => {\\n const factoryAddress: Address = `0x${initCode.substring(2, 42)}`;\\n const factoryCalldata: Hex = `0x${initCode.substring(42)}`;\\n return [factoryAddress, factoryCalldata];\\n};\\n \\nexport type GetAccountAddressParams = {\\n client: PublicClient;\\n entryPoint: EntryPointDef;\\n accountAddress?: Address;\\n getAccountInitCode: () => Promise<Hex>;\\n};\\n \\n/**\\n * Retrieves the account address. Uses a provided `accountAddress` if available; otherwise, it computes the address using the entry point contract and the initial code.\\n *\\n * @example\\n * ```ts\\n * import { getEntryPoint, getAccountAddress } from "@aa-sdk/core";\\n *\\n * const accountAddress = await getAccountAddress({\\n * client,\\n * entryPoint: getEntryPoint(chain),\\n * getAccountInitCode: async () => "0x{factoryAddress}{factoryCallData}",\\n * });\\n * ```\\n *\\n * @param {GetAccountAddressParams} params The configuration object\\n * @param {PublicClient} params.client A public client instance to interact with the blockchain\\n * @param {EntryPointDef} params.entryPoint The entry point definition which includes the address and ABI\\n * @param {Address} params.accountAddress Optional existing account address\\n * @param {() => Promise<Hex>} params.getAccountInitCode A function that returns a Promise resolving to a Hex string representing the initial code of the account\\n * @returns {Promise<Address>} A promise that resolves to the account address\\n */\\nexport const getAccountAddress = async ({\\n client,\\n entryPoint,\\n accountAddress,\\n getAccountInitCode,\\n}: GetAccountAddressParams) => {\\n if (accountAddress) return accountAddress;\\n \\n const entryPointContract = getContract({\\n address: entryPoint.address,\\n abi: entryPoint.abi,\\n client,\\n });\\n \\n const initCode = await getAccountInitCode();\\n Logger.verbose("[BaseSmartContractAccount](getAddress) initCode: ", initCode);\\n \\n try {\\n await entryPointContract.simulate.getSenderAddress([initCode]);\\n } catch (err: any) {\\n Logger.verbose(\\n "[BaseSmartContractAccount](getAddress) getSenderAddress err: ",\\n err\\n );\\n if (err.cause?.data?.errorName === "SenderAddressResult") {\\n Logger.verbose(\\n "[BaseSmartContractAccount](getAddress) entryPoint.getSenderAddress result:",\\n err.cause.data.args[0]\\n );\\n \\n return err.cause.data.args[0] as Address;\\n }\\n \\n if (err.details === "Invalid URL") {\\n throw new InvalidRpcUrlError();\\n }\\n }\\n \\n throw new GetCounterFactualAddressError();\\n};\\n \\nexport async function toSmartContractAccount<\\n Name extends string = string,\\n TTransport extends Transport = Transport,\\n TChain extends Chain = Chain,\\n TEntryPointVersion extends EntryPointVersion = EntryPointVersion\\n>({\\n transport,\\n chain,\\n entryPoint,\\n source,\\n accountAddress,\\n getAccountInitCode,\\n signMessage,\\n signTypedData,\\n encodeBatchExecute,\\n encodeExecute,\\n getDummySignature,\\n signUserOperationHash,\\n encodeUpgradeToAndCall,\\n}: ToSmartContractAccountParams<\\n Name,\\n TTransport,\\n TChain,\\n TEntryPointVersion\\n>): Promise<SmartContractAccount<Name, TEntryPointVersion>>;\\n \\n/**\\n * Converts an account to a smart contract account and sets up various account-related methods using the provided parameters like transport, chain, entry point, and other utilities.\\n *\\n * @example\\n * ```ts\\n * import { http, type SignableMessage } from "viem";\\n * import { sepolia } from "viem/chains";\\n *\\n * const myAccount = await toSmartContractAccount({\\n * /// REQUIRED PARAMS ///\\n * source: "MyAccount",\\n * transport: http("RPC_URL"),\\n * chain: sepolia,\\n * // The EntryPointDef that your account is com"patible with\\n * entryPoint: getEntryPoint(sepolia, { version: "0.6.0" }),\\n * // This should return a concatenation of your `factoryAddress` and the `callData` for your factory's create account method\\n * getAccountInitCode: async () => "0x{factoryAddress}{callData}",\\n * // an invalid signature that doesn't cause your account to revert during validation\\n * getDummySignature: () => "0x1234...",\\n * // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method\\n * encodeExecute: async (uo) => "0xcalldata",\\n * signMessage: async ({ message }: { message: SignableMessage }) => "0x...",\\n * signTypedData: async (typedData) => "0x000",\\n *\\n * /// OPTIONAL PARAMS ///\\n * // if you already know your account's address, pass that in here to avoid generating a new counterfactual\\n * accountAddress: "0xaddressoverride",\\n * // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method\\n * encodeBatchExecute: async (uos) => "0x...",\\n * // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here\\n * signUserOperationHash: async (hash) => "0x...",\\n * // allows you to define the calldata for upgrading your account\\n * encodeUpgradeToAndCall: async (params) => "0x...",\\n * });\\n * ```\\n *\\n * @param {ToSmartContractAccountParams} params the parameters required for converting to a smart contract account\\n * @param {Transport} params.transport the transport mechanism used for communication\\n * @param {Chain} params.chain the blockchain chain used in the account\\n * @param {EntryPoint} params.entryPoint the entry point of the smart contract\\n * @param {string} params.source the source identifier for the account\\n * @param {Address} [params.accountAddress] the address of the account\\n * @param {() => Promise<Hex>} params.getAccountInitCode a function to get the initial state code of the account\\n * @param {(message: { message: SignableMessage }) => Promise<Hex>} params.signMessage a function to sign a message\\n * @param {(typedDataDefinition: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>} params.signTypedData a function to sign typed data\\n * @param {(transactions: Transaction[]) => Hex} [params.encodeBatchExecute] a function to encode batch transactions\\n * @param {(tx: Transaction) => Hex} params.encodeExecute a function to encode a single transaction\\n * @param {() => Promise<Hex>} params.getDummySignature a function to get a dummy signature\\n * @param {(uoHash: Hex) => Promise<Hex>} [params.signUserOperationHash] a function to sign user operations\\n * @param {(implementationAddress: Address, implementationCallData: Hex) => Hex} [params.encodeUpgradeToAndCall] a function to encode upgrade call\\n * @returns {Promise<SmartContractAccount>} a promise that resolves to a SmartContractAccount object with methods and properties for interacting with the smart contract account\\n */\\nexport async function toSmartContractAccount(\\n params: ToSmartContractAccountParams\\n): Promise<SmartContractAccount> {\\n const {\\n transport,\\n chain,\\n entryPoint,\\n source,\\n accountAddress,\\n getAccountInitCode,\\n signMessage,\\n signTypedData,\\n encodeBatchExecute,\\n encodeExecute,\\n getDummySignature,\\n signUserOperationHash,\\n encodeUpgradeToAndCall,\\n } = params;\\n \\n const client = createBundlerClient({\\n // we set the retry count to 0 so that viem doesn't retry during\\n // getting the address. That call always reverts and without this\\n // viem will retry 3 times, making this call very slow\\n transport: (opts) => transport({ ...opts, chain, retryCount: 0 }),\\n chain,\\n });\\n \\n const entryPointContract = getContract({\\n address: entryPoint.address,\\n abi: entryPoint.abi,\\n client,\\n });\\n \\n const accountAddress_ = await getAccountAddress({\\n client,\\n entryPoint: entryPoint,\\n accountAddress,\\n getAccountInitCode,\\n });\\n \\n let deploymentState = DeploymentState.UNDEFINED;\\n \\n const getInitCode = async () => {\\n if (deploymentState === DeploymentState.DEPLOYED) {\\n return "0x";\\n }\\n const contractCode = await client.getBytecode({\\n address: accountAddress_,\\n });\\n \\n if ((contractCode?.length ?? 0) > 2) {\\n deploymentState = DeploymentState.DEPLOYED;\\n return "0x";\\n } else {\\n deploymentState = DeploymentState.NOT_DEPLOYED;\\n }\\n \\n return getAccountInitCode();\\n };\\n \\n const signUserOperationHash_ =\\n signUserOperationHash ??\\n (async (uoHash: Hex) => {\\n return signMessage({ message: { raw: hexToBytes(uoHash) } });\\n });\\n \\n const getFactoryAddress = async (): Promise<Address> =>\\n parseFactoryAddressFromAccountInitCode(await getAccountInitCode())[0];\\n \\n const getFactoryData = async (): Promise<Hex> =>\\n parseFactoryAddressFromAccountInitCode(await getAccountInitCode())[1];\\n \\n const encodeUpgradeToAndCall_ =\\n encodeUpgradeToAndCall ??\\n (() => {\\n throw new UpgradesNotSupportedError(source);\\n });\\n \\n const isAccountDeployed = async () => {\\n const initCode = await getInitCode();\\n return initCode === "0x";\\n };\\n \\n const getNonce = async (nonceKey = 0n): Promise<bigint> => {\\n if (!(await isAccountDeployed())) {\\n return 0n;\\n }\\n \\n return entryPointContract.read.getNonce([\\n accountAddress_,\\n nonceKey,\\n ]) as Promise<bigint>;\\n };\\n \\n const account = toAccount({\\n address: accountAddress_,\\n signMessage,\\n signTypedData,\\n signTransaction: () => {\\n throw new SignTransactionNotSupportedError();\\n },\\n });\\n \\n const create6492Signature = async (isDeployed: boolean, signature: Hex) => {\\n if (isDeployed) {\\n return signature;\\n }\\n \\n const [factoryAddress, factoryCalldata] =\\n parseFactoryAddressFromAccountInitCode(await getAccountInitCode());\\n \\n return wrapSignatureWith6492({\\n factoryAddress,\\n factoryCalldata,\\n signature,\\n });\\n };\\n \\n const signMessageWith6492 = async (message: { message: SignableMessage }) => {\\n const [isDeployed, signature] = await Promise.all([\\n isAccountDeployed(),\\n account.signMessage(message),\\n ]);\\n \\n return create6492Signature(isDeployed, signature);\\n };\\n \\n const signTypedDataWith6492 = async <\\n const typedData extends TypedData | Record<string, unknown>,\\n primaryType extends keyof typedData | "EIP712Domain" = keyof typedData\\n >(\\n typedDataDefinition: TypedDataDefinition<typedData, primaryType>\\n ): Promise<Hex> => {\\n const [isDeployed, signature] = await Promise.all([\\n isAccountDeployed(),\\n account.signTypedData(typedDataDefinition),\\n ]);\\n \\n return create6492Signature(isDeployed, signature);\\n };\\n \\n const getImplementationAddress = async (): Promise<NullAddress | Address> => {\\n const storage = await client.getStorageAt({\\n address: account.address,\\n // This is the default slot for the implementation address for Proxies\\n slot: "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",\\n });\\n \\n if (storage == null) {\\n throw new FailedToGetStorageSlotError(\\n "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",\\n "Proxy Implementation Address"\\n );\\n }\\n \\n return trim(storage);\\n };\\n \\n if (entryPoint.version !== "0.6.0" && entryPoint.version !== "0.7.0") {\\n throw new InvalidEntryPointError(chain, entryPoint.version);\\n }\\n \\n return {\\n ...account,\\n source,\\n // TODO: I think this should probably be signUserOperation instead\\n // and allow for generating the UO hash based on the EP version\\n signUserOperationHash: signUserOperationHash_,\\n getFactoryAddress,\\n getFactoryData,\\n encodeBatchExecute:\\n encodeBatchExecute ??\\n (() => {\\n throw new BatchExecutionNotSupportedError(source);\\n }),\\n encodeExecute,\\n getDummySignature,\\n getInitCode,\\n encodeUpgradeToAndCall: encodeUpgradeToAndCall_,\\n getEntryPoint: () => entryPoint,\\n isAccountDeployed,\\n getNonce,\\n signMessageWith6492,\\n signTypedDataWith6492,\\n getImplementationAddress,\\n };\\n}\\n:::\",\"title\":\"The toSmartContractAccount Method\",\"titles\":[\"Using your own Smart Account\"]}]}],[\"index.3ec62e7d5e7de514dde7dc4c4ad2891803dfeab5d69dde3010776a64f3c5dbe7\",{\"mdx\":\"---\\ntitle: Modular Account Smart Contract\\ndescription: Follow this guide to use Modular Accounts with Account Kit, a\\n vertically integrated stack for building apps that support ERC-4337 and\\n ERC-6900.\\n---\\n\\n# Modular Account\\n\\n## Overview\\n\\nModular Account is an ERC-4337 smart account that supports customizable features with ERC-6900 plugins. It is fully production-ready with multiple security audits, three prebuilt plugins in `MultiOwnerPlugin`, `SessionKeyPlugin`, and `MultisigPlugin`, and the capability to support any custom account behavior you need.\\n\\n## Why Modular Account?\\n\\n### Make the most of Account Abstraction\\n\\nSmart accounts unlock lots of customizable ways to improve the wallet experience. Still, it requires writing this behavior into the smart contract for the account, which is difficult and security-critical. Modular Account uses the [ERC-6900](https://eips.ethereum.org/EIPS/eip-6900) framework to simplify creating powerful features for smart accounts. We have created three plugins to level up your smart accounts, and we look forward to what new plugins you create!\\n\\n### Multi Owner Plugin\\n\\nThe Multi Owner plugin lets your smart accounts have one or more ECDSA or SCA owners. This allows your account to integrate with multiple signers simultaneously and supports recovering your account if one is lost.\\n\\nRead more about Multi Owner Plugin and how to get started with Modular Account [here](#TODO/smart-contracts/using-smart-accounts/transfer-ownership/modular-account)!\\n\\n### Session Key Plugin\\n\\nThe Session Key plugin lets your smart account add additional signers with specific permissions to your account.\\nSession keys can be customized and configured to:\\n\\n- Contract Restrictions: restrict to only interact with specific contracts and/or a subset of their methods\\n- Spending Limits: spend up to a set amount of ERC-20 tokens or native token amount\\n- Time Period: expire after specific time periods\\n\\nSession keys let you streamline interactions by reducing confirmation steps or automating actions on behalf of the account. These features are kept secure through the permission system, which protects the account from malicious use of the session key.\\n\\nRead more about installing and using the Session Key plugin [here](#TODO/smart-contracts/using-smart-accounts/session-keys/)!\\n\\n### Multisig Plugin\\n\\nThe Multisig plugin allows your account to have multiple ECDSA or SCA signers and require multiple signatures to perform actions on the account. This is commonly referred to as a k-of-n signature scheme and would create Modular Accounts that are similar to [Gnosis Safe](https://safe.global/) accounts. This plugin is recommended for accounts that require maximum security.\\n\\nRead more about Multisig Plugin [here](/smart-contracts/modular-account/multisig-plugin/)!\\n\\n### Full compatibility\\n\\nModular Account also supports the same baseline set of account abstraction features as Light Account: sponsoring gas, batching transactions, rotating owners, and checking ERC-1271 signatures.\\n\\n### Build your own Plugin\\n\\nHave an idea for more account features? Modular Account supports ERC-6900 for installing and uninstalling additional plugins to your account, letting you fully customize the account logic.\\n\\nCheck out the plugin development guide [here](https://www.notion.so/alchemotion/How-to-write-an-ERC-6900-Plugin-8ef518630b1a43a1b301723925407ec5?utm_content=8ef51863-0b1a-43a1-b301-723925407ec5&utm_campaign=T06RY9YKG&n=slack&n=slack_link_unfurl&pvs=6) if you’re interested!\\n\\n### Secure, audited, open source\\n\\nModular Account has been audited by Spearbit and Quanstamp. You can find the audit reports [here](https://github.com/alchemyplatform/modular-account/tree/develop/audits). Modular Account is fully open source, so you can validate the [source code](https://github.com/alchemyplatform/modular-account).\\n\\nimport Bbp from \\\"../../resources/bbp.mdx\\\";\\n\\nThe Multi Owner plugin lets your smart accounts have one or more ECDSA or SCA owners. This lets your account integrate with multiple signers at once, and supports recovering your account if one signer is lost.
\\nThe Multi-Owner Plugin is able to:
\\nAll Modular Accounts have MultiOwnerPlugin
pre-installed upon creation, exposing following methods for account owners to update (add or remove) and read the current owners of the account:
/// @notice Update owners of the account. Owners can update owners.\\n/// @param ownersToAdd The address array of owners to be added.\\n/// @param ownersToRemove The address array of owners to be removed.\\nfunction updateOwners(address[] memory ownersToAdd, address[] memory ownersToRemove) external;\\n \\n/// @notice Get the owners of `account`.\\n/// @param account The account to get the owners of.\\n/// @return The addresses of the owners of the account.\\nfunction ownersOf(address account) external view returns (address[] memory);
\\nWhen you connect your Modular Account to SmartAccountClient
you can extend the client with multiOwnerPluginActions
, which exposes a set of methods available to call the installed MultiOwnerPlugin
with the client connected to the account.
You should first extend the SmartAccountClient
connected to a Modular Account, which already comes with MultiOwnerPlugin
installed upon creation, with client to multiOwnerPluginActions
for the client to include the MultiOwnerPlugin
actions.
Then, you can use the readOwners
method of the multiOwnerPluginActions
extended smart account client to check if a given address is one of the current owners of a Modular Account.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\n \\nconst ownerToCheck = "0x..."; // the address of the account to check the ownership of\\n \\n// returns a boolean whether an address is an owner of account or not\\nconst isOwner = await modularAccountClient.isOwnerOf({\\n address: ownerToCheck,\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
You can use the readOwners
method on the multiOwnerPluginActions
extended smart account client to fetch all current owners of the connected Modular Account.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\n \\n// owners is an array of the addresses of the account owners\\nconst owners = await modularAccountClient.readOwners();
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
You can use the updateOwners
method on the multiOwnerPluginActions
extended smart account client to add or remove owners from the Modular Account.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\n \\nconst ownersToAdd = []; // the addresses of owners to be added\\nconst ownersToRemove = []; // the addresses of owners to be removed\\n \\nconst result = await modularAccountClient.updateOwners({\\n args: [ownersToAdd, ownersToRemove],\\n});\\n \\nconst txHash = await modularAccountClient.waitForUserOperationTransaction(\\n result\\n);
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
Upgrading a SmartContractAccount
can be done easily using Account Kit. It just involves a simple call to a single function on the SmartAccountClient
, namely upgradeAccount
, along with the necessary call data, UpgradeToData
, for the account targeted for the upgrade. For upgrading to a Modular Account, you can use the utility function getMSCAUpgradeToData
provided by the @account-kit/smart-contracts
package to retrieve the call data for the upgrade. This process applies to any account with upgrade capabilities.
Using the Light Account as an example, here is an overview of how the upgrade can be executed using a Smart Account Client:
\\n// @filename: lightAccountClient.ts\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n// @filename: lightAccountClient.ts\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { lightAccountClient } from "./lightAccountClient";\\nimport { getMSCAUpgradeToData } from "@account-kit/smart-contracts";\\n \\nconst { createMAAccount, ...upgradeToData } = await getMSCAUpgradeToData(\\n lightAccountClient,\\n { account: lightAccountClient.account }\\n);\\n \\nconst hash = await lightAccountClient.upgradeAccount({\\n upgradeTo: upgradeToData,\\n waitForTx: true,\\n});\\n \\nconst upgradedAccount = await createMAAccount();
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
That is all! Now, you can create a smart account client to connect with the upgraded account as a Modular Account.
\\n// @filename: lightAccountClient.ts\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n// @filename: upgradedAccount.ts\\n \\n// @filename: lightAccountClient.ts\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { lightAccountClient } from "./lightAccountClient";\\nimport { getMSCAUpgradeToData } from "@account-kit/smart-contracts";\\n \\nconst { createMAAccount, ...upgradeToData } = await getMSCAUpgradeToData(\\n lightAccountClient,\\n { account: lightAccountClient.account }\\n);\\n \\nconst hash = await lightAccountClient.upgradeAccount({\\n upgradeTo: upgradeToData,\\n waitForTx: true,\\n});\\n \\nexport const upgradedAccount = await createMAAccount();\\n// @filename: example.js\\n \\n// ---cut---\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { multiOwnerPluginActions } from "@account-kit/smart-contracts";\\nimport { upgradedAccount } from "./upgradedAccount";\\n \\nconst upgradedAccountClient = await createAlchemySmartAccountClient({\\n apiKey: "YOUR_API_KEY",\\n chain: lightAccountClient.chain,\\n account: upgradedAccount,\\n}).extend(multiOwnerPluginActions);\\n \\nconst owners = await upgradedAccountClient.readOwners();
// @filename: lightAccountClient.ts\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n// @filename: lightAccountClient.ts\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { lightAccountClient } from "./lightAccountClient";\\nimport { getMSCAUpgradeToData } from "@account-kit/smart-contracts";\\n \\nconst { createMAAccount, ...upgradeToData } = await getMSCAUpgradeToData(\\n lightAccountClient,\\n { account: lightAccountClient.account }\\n);\\n \\nconst hash = await lightAccountClient.upgradeAccount({\\n upgradeTo: upgradeToData,\\n waitForTx: true,\\n});\\n \\nexport const upgradedAccount = await createMAAccount();
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "YOUR_API_KEY",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
A MultiOwnerLightAccount
has one or more ECDSA or SCA owners. This lets your account integrate with multiple signers at once, and supports recovering your account if one signer is lost.
The MultiOwnerLightAccount
is able to:
When you connect your MultiOwnerLightAccount
to SmartAccountClient
you can extend the client with multiOwnerLightAccountClientActions
, which exposes a set of methods available to call the MultiOwnerLightAccount
with the client connected to the account.
You can use the getOwnerAddresses
method on the MultiOwnerLightAccount
object, which can be accessed from a connected client.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const multiOwnerLightAccountClient =\\n await createMultiOwnerLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n });\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const multiOwnerLightAccountClient =\\n await createMultiOwnerLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n });\\n// @filename: example.js\\n \\n// ---cut---\\nimport { multiOwnerLightAccountClient } from "./client";\\n \\nconst owners = await multiOwnerLightAccountClient.account.getOwnerAddresses();
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const multiOwnerLightAccountClient =\\n await createMultiOwnerLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n });
You can use the updateOwners
method on the multiOwnerLightAccountClientActions
extended smart account client to add or remove owners from the MultiOwnerLightAccount
.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const multiOwnerLightAccountClient =\\n await createMultiOwnerLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n });\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const multiOwnerLightAccountClient =\\n await createMultiOwnerLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n });\\n// @filename: example.js\\n \\n// ---cut---\\nimport { multiOwnerLightAccountClient } from "./client";\\n \\nconst ownersToAdd = []; // the addresses of owners to be added\\nconst ownersToRemove = []; // the addresses of owners to be removed\\n \\nconst opHash = await multiOwnerLightAccountClient.updateOwners({\\n ownersToAdd,\\n ownersToRemove,\\n});\\n \\nconst txHash =\\n await multiOwnerLightAccountClient.waitForUserOperationTransaction({\\n hash: opHash,\\n });
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const multiOwnerLightAccountClient =\\n await createMultiOwnerLightAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain: sepolia,\\n apiKey: "YOUR_API_KEY",\\n });
Light Account is a collection of lightweight ERC-4337 smart accounts. We started with the Ethereum Foundation's canonical SimpleAccount and added key improvements. It is fully production-ready multiple audits, gas optimizations, and ERC-1271 signature support. Additionally, Light Account supports ownership transfers to ensure you and your users don't get locked into a particular signer.
\\n\",\"id\":\"pages/smart-contracts/light-account/#overview\",\"isPage\":false,\"text\":\"\\nLight Account is a collection of lightweight ERC-4337 smart accounts. We started with the Ethereum Foundation's canonical SimpleAccount and added key improvements. It is fully production-ready multiple audits, gas optimizations, and ERC-1271 signature support. Additionally, Light Account supports ownership transfers to ensure you and your users don't get locked into a particular signer.\\n\",\"title\":\"Overview\",\"titles\":[\"Light Account\"]},{\"href\":\"/smart-contracts/light-account#light-account-variants\",\"html\":\"\\nLight Account has two variants catered to particular use cases. Both variants inherit the characteristics and features listed above.
\\n\",\"id\":\"pages/smart-contracts/light-account/#light-account-variants\",\"isPage\":false,\"text\":\"\\nLight Account has two variants catered to particular use cases. Both variants inherit the characteristics and features listed above.\\n\",\"title\":\"Light Account variants\",\"titles\":[\"Light Account\"]},{\"href\":\"/smart-contracts/light-account#lightaccount\",\"html\":\"\\nThis is the default variant of Light Account that supports a single ECDSA or SCA owner. It is slightly more gas efficient than MultiOwnerLightAccount
, and can be useful when you want to maximally optimize for gas spend or ensure that only one signer has access to the account at any given time.
LightAccount
comes in versions v1.1.0 and v2.0.0, which make use of the v0.6 and v0.7 entry points respectively.
For backwards compatibility, LightAccount
defaults to version v2.0.0. However, once a version is chosen and the Light Account is created, the version must remain consistent in order for the Light Account client to work with the existing Light Account.
Multi-Owner Light Account is a variant of Light Account that supports multiple ECDSA or SCA owners at once rather than a single one. Each owner has full control over the account, including the ability to add or remove other owners. This lets your account integrate with multiple signers at once, and supports recovering your account if one signer is lost.
\\nMulti-Owner Light Account uses v0.7 of the entry point.
\\n\",\"id\":\"pages/smart-contracts/light-account/#multiownerlightaccount\",\"isPage\":false,\"text\":\"\\nMulti-Owner Light Account is a variant of Light Account that supports multiple ECDSA or SCA owners at once rather than a single one. Each owner has full control over the account, including the ability to add or remove other owners. This lets your account integrate with multiple signers at once, and supports recovering your account if one signer is lost.\\nMulti-Owner Light Account uses v0.7 of the entry point.\\n\",\"title\":\"MultiOwnerLightAccount\",\"titles\":[\"Light Account\",\"Light Account variants\"]},{\"href\":\"/smart-contracts/light-account#developer-links\",\"html\":\"\\n\",\"id\":\"pages/smart-contracts/light-account/#developer-links\",\"isPage\":false,\"text\":\"\\n\\nLight Account deployment addresses\\nLight Account Github repo\\nQuantstamp audit report\\n\",\"title\":\"Developer links\",\"titles\":[\"Light Account\"]}]}],[\"index.4b8fabf6a37f99f859b2a6e5939de24c06dd8493f350284f4148f9d28bcafa13\",{\"mdx\":\"---\\ntitle: Modular Account • Getting started\\ndescription: Getting started with Modular Account in Account Kit\\n---\\n\\n# Getting started with Modular Account\\n\\nIt is easy to get started with Modular Account! We will show you two different ways using Alchemy Infra or 3rd party infra.\\n\\n## Install packages\\n\\nFirst, install the the `@account-kit/smart-contracts` package.\\n\\n:::code-group\\n\\n```bash [yarn]\\nyarn add @account-kit/smart-contracts\\n# if using alchemy infra\\nyarn add @account-kit/infra\\n```\\n\\n```bash [npm]\\nyarn add @account-kit/smart-contracts\\n# if using alchemy infra\\nyarn add @account-kit/infra\\n```\\n\\n:::\\n\\n## With Alchemy Infra\\n\\nThen you can do the following:\\n\\n```ts twoslash\\nimport { createModularAccountAlchemyClient } from \\\"@account-kit/smart-contracts\\\";\\nimport { sepolia } from \\\"@account-kit/infra\\\";\\nimport { LocalAccountSigner } from \\\"@aa-sdk/core\\\";\\nimport { generatePrivateKey } from \\\"viem/accounts\\\";\\n\\nconst alchemyAccountClient = await createModularAccountAlchemyClient({\\n apiKey: \\\"your-api-key\\\",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n```\\n\\n:::tip[Address calculation]\\nFor Modular Account, the address of the smart account will be calculated as a combination of [the owners and the salt](https://github.com/alchemyplatform/modular-account/blob/v1.0.x/src/factory/MultiOwnerModularAccountFactory.sol#L79-L82). You will get the same smart account address each time you supply the same `owners`, the signer(s) used to create the account for the first time. You can also optionally supply `salt` if you want a different address for the same `owners` param (the default salt is `0n`).\\n\\nIf you want to use a signer to connect to an account whose address does not map to the contract-generated address, you can supply the `accountAddress` to connect with the account of interest. In that case, the `signer` address is not used for address calculation, but only for signing the operation.\\n:::\\n\\n## With 3rd-party infra\\n\\nIf you're using a 3rd-party for infra, we also expose a client that you can use to interact with Modular Account using other RPC providers.\\n\\n```ts twoslash\\nimport { createMultiOwnerModularAccountClient } from \\\"@account-kit/smart-contracts\\\";\\nimport { LocalAccountSigner } from \\\"@aa-sdk/core\\\";\\nimport { sepolia } from \\\"viem/chains\\\";\\nimport { http } from \\\"viem\\\";\\nimport { generatePrivateKey } from \\\"viem/accounts\\\";\\n\\nconst accountClient = await createMultiOwnerModularAccountClient({\\n chain: sepolia,\\n transport: http(\\\"RPC_URL\\\"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n```\\n\\nNext, if you want to use a different `signer` with a smart account signer, check out [choosing a signer](/signer/what-is-a-signer). Otherwise, if you are ready to get on-chain, go to [send user operations](/infra/send-user-operations).\\n\",\"document\":[{\"href\":\"/smart-contracts/modular-account/getting-started#getting-started-with-modular-account\",\"html\":\"\\nIt is easy to get started with Modular Account! We will show you two different ways using Alchemy Infra or 3rd party infra.
\\n\",\"id\":\"pages/smart-contracts/modular-account/getting-started.mdx#getting-started-with-modular-account\",\"isPage\":true,\"text\":\"\\nIt is easy to get started with Modular Account! We will show you two different ways using Alchemy Infra or 3rd party infra.\\n\",\"title\":\"Getting started with Modular Account\",\"titles\":[]},{\"href\":\"/smart-contracts/modular-account/getting-started#install-packages\",\"html\":\"\\nFirst, install the the @account-kit/smart-contracts
package.
yarn add @account-kit/smart-contracts\\n# if using alchemy infra\\nyarn add @account-kit/infra
yarn add @account-kit/smart-contracts\\n# if using alchemy infra\\nyarn add @account-kit/infra
Then you can do the following:
\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nconst alchemyAccountClient = await createModularAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\\n\",\"id\":\"pages/smart-contracts/modular-account/getting-started.mdx#with-alchemy-infra\",\"isPage\":false,\"text\":\"\\nThen you can do the following:\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nconst alchemyAccountClient = await createModularAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\nAddress calculationFor Modular Account, the address of the smart account will be calculated as a combination of the owners and the salt. You will get the same smart account address each time you supply the same owners, the signer(s) used to create the account for the first time. You can also optionally supply salt if you want a different address for the same owners param (the default salt is 0n).If you want to use a signer to connect to an account whose address does not map to the contract-generated address, you can supply the accountAddress to connect with the account of interest. In that case, the signer address is not used for address calculation, but only for signing the operation.\\n\",\"title\":\"With Alchemy Infra\",\"titles\":[\"Getting started with Modular Account\"]},{\"href\":\"/smart-contracts/modular-account/getting-started#with-3rd-party-infra\",\"html\":\"\\nIf you're using a 3rd-party for infra, we also expose a client that you can use to interact with Modular Account using other RPC providers.
\\nimport { createMultiOwnerModularAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nconst accountClient = await createMultiOwnerModularAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\nNext, if you want to use a different signer
with a smart account signer, check out choosing a signer. Otherwise, if you are ready to get on-chain, go to send user operations.
ERC-6900 Modular Accounts implements Plugin manager interface IPluginManager.sol
to support installing and uninstalling plugins on a Modular Account. This contract interface defines the method installPlugin()
and uninstallPlugin()
that clients can use to install or uninstall plugins on a Modular Account.
Account Kit provides a streamlined experience of interacting with the Modular Account AccoutLoupe interface easily by providing pluginManagerActions
defined in @account-kit/smart-contracts
package. When you connect your Modular Account to SmartAccountClient
you can extend the client with pluginManagerActions
, which exposes a set of methods available to call the account AccountLoupe
with the client connected to the account.
There are two ways to install plugins. The first method is to use the pluginManagerActions
's generic installPlugin
method, but this method requires the PluginGenConfig
configure the correct plugin dependencies and function references for the plugin.
Account Kit provides a more robust, easier way to install plugins with pluginActions
. Each plugin comes with the its own pluginActions
that includes already configured install method, named install<PluginName>
, for installing any plugin of interest. For example, MultiOwnerPlugin
has multiOwnerPluginActions
that includes installMultiOwnerPlugin()
method, and SessionKeyPlugin
has sessionKeyPluginActions
that includes installSessionKeyPlugin()
method, all exported from the @account-kit/smart-contracts
package.
This guide will use the SessionKeyPlugin
as an example to show how you can install SessionKeyPlugin
easily using the SmartAccountClient
extended with sessionKeyPluginActions
.
You should first extend the SmartAccountClient
connected to a Modular Account with sessionKeyPluginActions
.
Then, you can use the installSessionKeyPlugin()
method exposed on sessionKeyPluginActions
extended smart account client to install the session key plugin for the connected account.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\nimport { sessionKeyPluginActions } from "@account-kit/smart-contracts";\\n \\n\\n// extend smart account client with sessionKeyPluginActions to call SessionKeyPlugin methods\\nconst sessionKeyExtendedClient = modularAccountClient.extend(\\n sessionKeyPluginActions\\n);\\n \\nconst { hash } = await sessionKeyExtendedClient.installSessionKeyPlugin({\\n // 1st arg is the initial set of session keys\\n // 2nd arg is the tags for the session keys\\n // 3rd arg is the initial set of permissions\\n args: [[], [], []],\\n});\\n \\nawait client.waitForUserOperationTransaction({ hash });
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
Refer to the Session Key section to learn more about using the SessionKeyPlugin
.
On the other hand, uninstalling plugins usually does not involve configuring contract dependencies or function references. You can use the pluginManagerActions
's generic uninstallPlugin
method to uninstall a particular plugin of interest.\\nFirst, extend the SmartAccountClient
connected to a Modular Account with pluginManagerActions
.
Then, you can use the uninstallPlugin()
method exposed on pluginManagerActions
extended smart account client to uninstall the session key plugin for the connected account.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { chain, modularAccountClient } from "./client";\\nimport { SessionKeyPlugin } from "@account-kit/smart-contracts";\\n \\nconst { hash } = await modularAccountClient.uninstallPlugin({\\n pluginAddress: SessionKeyPlugin.meta.addresses[chain.id],\\n});\\n \\nawait modularAccountClient.waitForUserOperationTransaction({ hash });
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
As mentioned above, you should not uninstall the multiowner plugin from a Modular Account in a single action. This will leave your account without a validator, no owner, and therefore will be unusable.
\\nRecommended flow today: Rather than switch ownership post creation, use createModularAccountAlchemyClient
OR the createMultisigAccountAlchemyClient
on account creation directly depending on if you want multi-owner or multi-sig ownership respectively.
Problem: In order to switch from multi-owner (installed in Modular Account by default) to multi-sig, you will need to batch call an uninstall of the multi-owner plugin and an install of the multi-sig plugin. It is required to batch these steps! If you uninstall the multi-owner plugin in a single action, the account will no longer have a validation function, and will be bricked (unusable).
\\nSolution for extending Modular Account AFTER deployment: You will need to manually encode 1) the uninstall of the multi-owner plugin and 2) the install of the multi-sig plugin and batch those together in one UO (using encodeFunctionData
and batching using sendUserOperation
). We are working to make this workflow easier in the next SDK version.
See a working example in this discussion.
\\nAfter uninstalling and installing successfully, you will then be able to use the Multisig Account Client to sign and send UOs.
\",\"id\":\"pages/smart-contracts/install-plugins.mdx#extend-modular-account-with-multisig\",\"isPage\":false,\"text\":\"\\nAs mentioned above, you should not uninstall the multiowner plugin from a Modular Account in a single action. This will leave your account without a validator, no owner, and therefore will be unusable.\\nRecommended flow today: Rather than switch ownership post creation, use createModularAccountAlchemyClient OR the createMultisigAccountAlchemyClient on account creation directly depending on if you want multi-owner or multi-sig ownership respectively.\\nProblem: In order to switch from multi-owner (installed in Modular Account by default) to multi-sig, you will need to batch call an uninstall of the multi-owner plugin and an install of the multi-sig plugin. It is required to batch these steps! If you uninstall the multi-owner plugin in a single action, the account will no longer have a validation function, and will be bricked (unusable).\\nSolution for extending Modular Account AFTER deployment: You will need to manually encode 1) the uninstall of the multi-owner plugin and 2) the install of the multi-sig plugin and batch those together in one UO (using encodeFunctionData and batching using sendUserOperation). We are working to make this workflow easier in the next SDK version.\\nSee a working example in this discussion.\\nAfter uninstalling and installing successfully, you will then be able to use the Multisig Account Client to sign and send UOs.\",\"title\":\"Extend Modular Account with Multisig\",\"titles\":[\"How to install and uninstall plugins on a Modular Account\",\"2. Uninstalling the Session Key Plugin\"]}]}],[\"index.30d58f29d8bac96a8c9367628ef2f932310b0e98b2d7c23d2779e552afc045bf\",{\"mdx\":\"---\\ntitle: Session Key Supported Permissions\\ndescription: All permissions the Alchemy Session Key Plugin supports.\\n---\\n\\n# Supported Permissions\\n\\n### Time range\\n\\nSupports a start time and an end time for each session key.\\n\\n### Access control lists\\n\\nSupports either an allowlist or a denylist for addresses. Optionally, access control lists may also specify specific functions on contracts to allow or deny.\\n\\n### ERC-20 spending Limits\\n\\nSupports limiting how much of a specific ERC-20 token a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 100 USDC per week).\\n\\n### Native token spending limits\\n\\nSupports limiting how much of the native token, e.g. ETH or MATIC, a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).\\n\\n### Gas spending limits\\n\\nSupports limiting how much of the native token (e.g. ETH or MATIC) a session key can spend on gas. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).\\n\\nAlternatively, you can also require that a session key uses a specific paymaster address, instead of spending the account’s native token for gas.\\n\\n## Importance of Gas Limits\\n\\nGas spend limits are critically important to protecting the account. If you are using a session key, you should configure either a required paymaster rule or a gas spend limit. Failing to do so could allow a compromised session key to drain the account’s native token balance.\\n\\nNote that the gas limit is tracked in terms of native token units (wei), not in units of gas. The gas usage of a user operation is considered to be the maximum gas a user operation can spend, i.e. `total gas limit * maxFeePerGas`. This can overestimate when compared to the actual gas cost of each user operation.\\n\\n## Default values\\n\\nPermissions start with the following default values:\\n\\n| Permission | Default Value |\\n| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |\\n| Access control list | Type: allowlistSupports a start time and an end time for each session key.
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#time-range\",\"isPage\":false,\"text\":\"\\nSupports a start time and an end time for each session key.\\n\",\"title\":\"Time range\",\"titles\":[\"Supported Permissions\",null]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#access-control-lists\",\"html\":\"\\nSupports either an allowlist or a denylist for addresses. Optionally, access control lists may also specify specific functions on contracts to allow or deny.
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#access-control-lists\",\"isPage\":false,\"text\":\"\\nSupports either an allowlist or a denylist for addresses. Optionally, access control lists may also specify specific functions on contracts to allow or deny.\\n\",\"title\":\"Access control lists\",\"titles\":[\"Supported Permissions\",null]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#erc-20-spending-limits\",\"html\":\"\\nSupports limiting how much of a specific ERC-20 token a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 100 USDC per week).
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#erc-20-spending-limits\",\"isPage\":false,\"text\":\"\\nSupports limiting how much of a specific ERC-20 token a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 100 USDC per week).\\n\",\"title\":\"ERC-20 spending Limits\",\"titles\":[\"Supported Permissions\",null]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#native-token-spending-limits\",\"html\":\"\\nSupports limiting how much of the native token, e.g. ETH or MATIC, a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#native-token-spending-limits\",\"isPage\":false,\"text\":\"\\nSupports limiting how much of the native token, e.g. ETH or MATIC, a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).\\n\",\"title\":\"Native token spending limits\",\"titles\":[\"Supported Permissions\",null]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#gas-spending-limits\",\"html\":\"\\nSupports limiting how much of the native token (e.g. ETH or MATIC) a session key can spend on gas. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).
\\nAlternatively, you can also require that a session key uses a specific paymaster address, instead of spending the account’s native token for gas.
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#gas-spending-limits\",\"isPage\":false,\"text\":\"\\nSupports limiting how much of the native token (e.g. ETH or MATIC) a session key can spend on gas. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).\\nAlternatively, you can also require that a session key uses a specific paymaster address, instead of spending the account’s native token for gas.\\n\",\"title\":\"Gas spending limits\",\"titles\":[\"Supported Permissions\",null]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#importance-of-gas-limits\",\"html\":\"\\nGas spend limits are critically important to protecting the account. If you are using a session key, you should configure either a required paymaster rule or a gas spend limit. Failing to do so could allow a compromised session key to drain the account’s native token balance.
\\nNote that the gas limit is tracked in terms of native token units (wei), not in units of gas. The gas usage of a user operation is considered to be the maximum gas a user operation can spend, i.e. total gas limit * maxFeePerGas
. This can overestimate when compared to the actual gas cost of each user operation.
Permissions start with the following default values:
\\nPermission | Default Value |
---|---|
Access control list | Type: allowlist The list starts empty. When the allowlist is empty, all calls will be denied. |
Time range | Unlimited |
Native token spend limit | 0 This means all calls spending the native token will be denied, unless the limit is updated or removed. |
ERC-20 spend limit | Unset. If you want to enabled an ERC-20 spend limit, add the ERC-20 token contract to the access control list and set the spending limit amount. |
Gas spend limits | Unset. When defining the session key’s permissions, you should specify either a gas spending limit or a required paymaster. |
To construct the data to set a key's permissions, you will need to use the SessionKeyPermissionBuilder
class. This will allow you to specify a series of updates, and when complete, you may generate the encoded data to perform all updates at once.
The permissions data may be specified in 3 places:
\\nonInstall
data, setting the intial permissions for a session key added at install time.addSessionKey
.updateKeyPermissions
function, to change the permissions of an existing key.// Let's create an initial permission set for the session key giving it an eth spend limit\\nconst keyPermissions = new SessionKeyPermissionsBuilder()\\n .setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n })\\n // this will allow the session key plugin to interact with all addresses\\n .setContractAccessControlType(SessionKeyAccessListType.ALLOW_ALL_ACCESS)\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n });
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#generating-the-permissions\",\"isPage\":false,\"text\":\"\\n// Let's create an initial permission set for the session key giving it an eth spend limit\\nconst keyPermissions = new SessionKeyPermissionsBuilder()\\n .setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n })\\n // this will allow the session key plugin to interact with all addresses\\n .setContractAccessControlType(SessionKeyAccessListType.ALLOW_ALL_ACCESS)\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n });\\n\",\"title\":\"Generating the permissions\",\"titles\":[\"Supported Permissions\",\"Using the PermissionsBuilder\",\"Gas spending limits\"]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#example-permissions-in-plugin-install-data\",\"html\":\"\\n const result = await client.installSessionKeyPlugin({\\n // 1st arg is the initial set of session keys\\n // 2nd arg is the tags for the session keys\\n // 3rd arg is the initial set of permissions\\n args: [\\n [await sessionKeySigner.getAddress()],\\n [zeroHash],\\n [keyPermissions.encode()],\\n ],\\n });
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#example-permissions-in-plugin-install-data\",\"isPage\":false,\"text\":\"\\n const result = await client.installSessionKeyPlugin({\\n // 1st arg is the initial set of session keys\\n // 2nd arg is the tags for the session keys\\n // 3rd arg is the initial set of permissions\\n args: [\\n [await sessionKeySigner.getAddress()],\\n [zeroHash],\\n [keyPermissions.encode()],\\n ],\\n });\\n\",\"title\":\"Example: Permissions in plugin install data\",\"titles\":[\"Supported Permissions\",\"Using the PermissionsBuilder\",\"Gas spending limits\"]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#example-initial-permissions-for-a-new-key\",\"html\":\"\\n const result = await client.addSessionKey({\\n key: "0x1234123412341234123412341234123412341234", // Session key address\\n tag: keccak256(new TextEncoder().encode("session-key-tag")), // Session key tag\\n permissions: keyPermissions.encode(), // Initial permissions\\n });
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#example-initial-permissions-for-a-new-key\",\"isPage\":false,\"text\":\"\\n const result = await client.addSessionKey({\\n key: "0x1234123412341234123412341234123412341234", // Session key address\\n tag: keccak256(new TextEncoder().encode("session-key-tag")), // Session key tag\\n permissions: keyPermissions.encode(), // Initial permissions\\n });\\n\",\"title\":\"Example: Initial permissions for a new key\",\"titles\":[\"Supported Permissions\",\"Using the PermissionsBuilder\",\"Gas spending limits\"]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#exmaple-updating-a-session-keys-permissions\",\"html\":\"\\nThis example updates a key's time range, but leaves other permissions to their current values.
\\n const result = await client.updateSessionKeyPermissions({\\n key: "0x1234123412341234123412341234123412341234", // Session key address\\n // add other permissions to the builder, if needed\\n permissions: new SessionKeyPermissionsBuilder()\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n })\\n .encode(),\\n });
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#exmaple-updating-a-session-keys-permissions\",\"isPage\":false,\"text\":\"\\nThis example updates a key's time range, but leaves other permissions to their current values.\\n const result = await client.updateSessionKeyPermissions({\\n key: "0x1234123412341234123412341234123412341234", // Session key address\\n // add other permissions to the builder, if needed\\n permissions: new SessionKeyPermissionsBuilder()\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n })\\n .encode(),\\n });\\n\",\"title\":\"Exmaple: Updating a session key's permissions\",\"titles\":[\"Supported Permissions\",\"Using the PermissionsBuilder\",\"Gas spending limits\"]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#permissions-builder-full-reference\",\"html\":\"\\nimport { encodeFunctionData, type Address, type Hex } from "viem";\\nimport { SessionKeyPermissionsUpdatesAbi } from "./SessionKeyPermissionsUpdatesAbi.js";\\n \\nexport enum SessionKeyAccessListType {\\n ALLOWLIST = 0,\\n DENYLIST = 1,\\n ALLOW_ALL_ACCESS = 2,\\n}\\n \\nexport type ContractAccessEntry = {\\n // The contract address to add or remove.\\n contractAddress: Address;\\n // Whether the contract address should be on the list.\\n isOnList: boolean;\\n // Whether to check selectors for the contract address.\\n checkSelectors: boolean;\\n};\\n \\nexport type ContractMethodEntry = {\\n // The contract address to add or remove.\\n contractAddress: Address;\\n // The function selector to add or remove.\\n methodSelector: Hex;\\n // Whether the function selector should be on the list.\\n isOnList: boolean;\\n};\\n \\nexport type TimeRange = {\\n validFrom: number;\\n validUntil: number;\\n};\\n \\nexport type NativeTokenLimit = {\\n spendLimit: bigint;\\n // The time interval over which the spend limit is enforced. If unset, there is no time\\n /// interval by which the limit is refreshed.\\n refreshInterval?: number;\\n};\\n \\nexport type Erc20TokenLimit = {\\n tokenAddress: Address;\\n spendLimit: bigint;\\n // The time interval over which the spend limit is enforced. If unset, there is no time\\n /// interval by which the limit is refreshed.\\n refreshInterval?: number;\\n};\\n \\n// uint256 spendLimit, uint48 refreshInterval\\nexport type GasSpendLimit = {\\n // The amount, in wei, of native tokens that a session key can spend on gas.\\n // Note that this is not the same as the gas limit for a user operation, which is measured in units of gas.\\n // This tracks gas units * gas price.\\n spendLimit: bigint;\\n // The time interval over which the spend limit is enforced. If unset, there is no time\\n /// interval by which the limit is refreshed.\\n refreshInterval?: number;\\n};\\n \\n/**\\n * A builder for creating the hex-encoded data for updating session key permissions.\\n */\\nexport class SessionKeyPermissionsBuilder {\\n private _contractAccessControlType: SessionKeyAccessListType =\\n SessionKeyAccessListType.ALLOWLIST;\\n private _contractAddressAccessEntrys: ContractAccessEntry[] = [];\\n private _contractMethodAccessEntrys: ContractMethodEntry[] = [];\\n private _timeRange?: TimeRange;\\n private _nativeTokenSpendLimit?: NativeTokenLimit;\\n private _erc20TokenSpendLimits: Erc20TokenLimit[] = [];\\n private _gasSpendLimit?: GasSpendLimit;\\n private _requiredPaymaster?: Address;\\n \\n /**\\n * Sets the access control type for the contract and returns the current instance for method chaining.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.setContractAccessControlType(SessionKeyAccessListType.ALLOWLIST);\\n * ```\\n *\\n * @param {SessionKeyAccessListType} aclType The access control type for the session key\\n * @returns {SessionKeyPermissionsBuilder} The current instance for method chaining\\n */\\n public setContractAccessControlType(aclType: SessionKeyAccessListType) {\\n this._contractAccessControlType = aclType;\\n return this;\\n }\\n \\n /**\\n * Adds a contract access entry to the internal list of contract address access entries.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.addContractAddressAccessEntry({\\n * contractAddress: "0x1234",\\n * isOnList: true,\\n * checkSelectors: true,\\n * });\\n * ```\\n *\\n * @param {ContractAccessEntry} entry the contract access entry to be added\\n * @returns {SessionKeyPermissionsBuilder} the instance of the current class for chaining\\n */\\n public addContractAddressAccessEntry(entry: ContractAccessEntry) {\\n this._contractAddressAccessEntrys.push(entry);\\n return this;\\n }\\n \\n /**\\n * Adds a contract method entry to the `_contractMethodAccessEntrys` array.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.addContractAddressAccessEntry({\\n * contractAddress: "0x1234",\\n * methodSelector: "0x45678",\\n * isOnList: true,\\n * });\\n * ```\\n *\\n * @param {ContractMethodEntry} entry The contract method entry to be added\\n * @returns {SessionKeyPermissionsBuilder} The instance of the class for method chaining\\n */\\n public addContractFunctionAccessEntry(entry: ContractMethodEntry) {\\n this._contractMethodAccessEntrys.push(entry);\\n return this;\\n }\\n \\n /**\\n * Sets the time range for an object and returns the object itself for chaining.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.setTimeRange({\\n * validFrom: Date.now(),\\n * validUntil: Date.now() + (15 * 60 * 1000),\\n * });\\n * ```\\n *\\n * @param {TimeRange} timeRange The time range to be set\\n * @returns {SessionKeyPermissionsBuilder} The current object for method chaining\\n */\\n public setTimeRange(timeRange: TimeRange) {\\n this._timeRange = timeRange;\\n return this;\\n }\\n \\n /**\\n * Sets the native token spend limit and returns the instance for chaining.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.setNativeTokenSpendLimit({\\n * spendLimit: 1000000000000000000n,\\n * refreshInterval: 3600,\\n * });\\n * ```\\n *\\n * @param {NativeTokenLimit} limit The limit to set for native token spending\\n * @returns {SessionKeyPermissionsBuilder} The instance for chaining\\n */\\n public setNativeTokenSpendLimit(limit: NativeTokenLimit) {\\n this._nativeTokenSpendLimit = limit;\\n return this;\\n }\\n \\n /**\\n * Adds an ERC20 token spend limit to the list of limits and returns the updated object.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.addErc20TokenSpendLimit({\\n * tokenAddress: "0x1234",\\n * spendLimit: 1000000000000000000n,\\n * refreshInterval: 3600,\\n * });\\n * ```\\n *\\n * @param {Erc20TokenLimit} limit The ERC20 token spend limit to be added\\n * @returns {object} The updated object with the new ERC20 token spend limit\\n */\\n public addErc20TokenSpendLimit(limit: Erc20TokenLimit) {\\n this._erc20TokenSpendLimits.push(limit);\\n return this;\\n }\\n \\n /**\\n * Sets the gas spend limit and returns the current instance for method chaining.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.setGasSpendLimit({\\n * spendLimit: 1000000000000000000n,\\n * refreshInterval: 3600,\\n * });\\n * ```\\n *\\n * @param {GasSpendLimit} limit - The gas spend limit to be set\\n * @returns {SessionKeyPermissionsBuilder} The current instance for chaining\\n */ public setGasSpendLimit(limit: GasSpendLimit) {\\n this._gasSpendLimit = limit;\\n return this;\\n }\\n \\n /**\\n * Sets the required paymaster address.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.setRequiredPaymaster("0x1234");\\n * ```\\n *\\n * @param {Address} paymaster the address of the paymaster to be set\\n * @returns {SessionKeyPermissionsBuilder} the current instance for method chaining\\n */\\n public setRequiredPaymaster(paymaster: Address) {\\n this._requiredPaymaster = paymaster;\\n return this;\\n }\\n \\n /**\\n * Encodes various function calls into an array of hexadecimal strings based on the provided permissions and limits.\\n *\\n * @example\\n * ```ts\\n * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n *\\n * const builder = new SessionKeyPermissionsBuilder();\\n * builder.setRequiredPaymaster("0x1234");\\n * const encoded = builder.encode();\\n * ```\\n *\\n * @returns {Hex[]} An array of encoded hexadecimal strings representing the function calls for setting access control, permissions, and limits.\\n */\\n public encode(): Hex[] {\\n return [\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "setAccessListType",\\n args: [this._contractAccessControlType],\\n }),\\n ...this._contractAddressAccessEntrys.map((entry) =>\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "updateAccessListAddressEntry",\\n args: [entry.contractAddress, entry.isOnList, entry.checkSelectors],\\n })\\n ),\\n ...this._contractMethodAccessEntrys.map((entry) =>\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "updateAccessListFunctionEntry",\\n args: [entry.contractAddress, entry.methodSelector, entry.isOnList],\\n })\\n ),\\n this.encodeIfDefined(\\n (timeRange) =>\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "updateTimeRange",\\n args: [timeRange.validFrom, timeRange.validUntil],\\n }),\\n this._timeRange\\n ),\\n this.encodeIfDefined(\\n (nativeSpendLimit) =>\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "setNativeTokenSpendLimit",\\n args: [\\n nativeSpendLimit.spendLimit,\\n nativeSpendLimit.refreshInterval ?? 0,\\n ],\\n }),\\n this._nativeTokenSpendLimit\\n ),\\n ...this._erc20TokenSpendLimits.map((erc20SpendLimit) =>\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "setERC20SpendLimit",\\n args: [\\n erc20SpendLimit.tokenAddress,\\n erc20SpendLimit.spendLimit,\\n erc20SpendLimit.refreshInterval ?? 0,\\n ],\\n })\\n ),\\n this.encodeIfDefined(\\n (spendLimit) =>\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "setGasSpendLimit",\\n args: [spendLimit.spendLimit, spendLimit.refreshInterval ?? 0],\\n }),\\n this._gasSpendLimit\\n ),\\n this.encodeIfDefined(\\n (paymaster) =>\\n encodeFunctionData({\\n abi: SessionKeyPermissionsUpdatesAbi,\\n functionName: "setRequiredPaymaster",\\n args: [paymaster],\\n }),\\n this._requiredPaymaster\\n ),\\n ].filter((x) => x !== "0x");\\n }\\n \\n private encodeIfDefined<T>(encode: (param: T) => Hex, param?: T): Hex {\\n if (!param) return "0x";\\n \\n return encode(param);\\n }\\n}
You may wish to view the current permissions of a given session key. This can be done using view functions defined by the Session Key Plugin.
\\nHere's an example of viewing all permissions in TypeScript:
\\nconst sessionKeyPluginView = SessionKeyPlugin.getContract(client).read;\\nconst accountAddress = client.getAddress();\\nconst sessionKeyAddress = await sessionKeySigner.getAddress();\\n \\nconst exampleTargetAddress = "0x4567456745674567456745674567456745674567";\\nconst exampleTargetSelector = "0x78907890";\\nconst exampleERC20Address = "0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";\\n \\n// Using session key permissions view functions\\n \\n// The key's current access control type. One of:\\n// - SessionKeyAccessListType.ALLOWLIST\\n// - SessionKeyAccessListType.DENYLIST\\n// - SessionKeyAccessListType.ALLOW_ALL_ACCESS\\nconst accessControlType = await sessionKeyPluginView.getAccessControlType([\\n accountAddress,\\n sessionKeyAddress,\\n]);\\n \\n// - Whether or not the address is on the access control list (either allowlist or denylist, depending on setting).\\n// - Whether or not the function selectors should be checked for the target address (checked according to the access control type).\\nconst [isTargetAddressOnList, checkSelectors] =\\n await sessionKeyPluginView.getAccessControlEntry([\\n accountAddress,\\n sessionKeyAddress,\\n exampleTargetAddress,\\n ]);\\n \\n// Whether or not the selector is on the access control list\\nconst isTargetSelectorOnList =\\n await sessionKeyPluginView.isSelectorOnAccessControlList([\\n accountAddress,\\n sessionKeyAddress,\\n exampleTargetAddress,\\n exampleTargetSelector,\\n ]);\\n \\n// The start and end timestamp of a key.\\n// If either is zero, that means the value is unset.\\nconst [validAfter, validUntil] = await sessionKeyPluginView.getKeyTimeRange([\\n accountAddress,\\n sessionKeyAddress,\\n]);\\n \\n// The native token spending limit of a key. Details below\\nconst nativeTokenSpendingLimit =\\n await sessionKeyPluginView.getNativeTokenSpendLimitInfo([\\n accountAddress,\\n sessionKeyAddress,\\n ]);\\n \\nconst {\\n hasLimit: hasNativeTokenSpendLimit, // Whether or not a native token spending limit is enforced on the session key\\n limit: nativeTokenSpendLimit, // The limit's maximum value. If a refresh interval is set, this is the max per interval.\\n limitUsed: nativeTokenSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval.\\n refreshInterval: nativeTokenRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit.\\n lastUsedTime: nativeTokenLastUsedTime, // The start of the latest interval, if using the refresh interval.\\n} = nativeTokenSpendingLimit;\\n \\n// The spending limit for an ERC-20 token.\\nconst erc20SpendingLimit = await sessionKeyPluginView.getERC20SpendLimitInfo([\\n accountAddress,\\n sessionKeyAddress,\\n exampleERC20Address,\\n]);\\n \\nconst {\\n hasLimit: hasErc20TokenSpendLimit, // Whether or not an ERC-20 token spending limit is enforced on the session key for this token address.\\n limit: erc20TokenSpendLimit, // The limit's maximum value. If a refresh interval is set, this is the max per interval.\\n limitUsed: erc20TokenSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval.\\n refreshInterval: erc20TokenRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit.\\n lastUsedTime: erc20TokenLastUsedTime, // The start of the latest interval, if using the refresh interval.\\n} = erc20SpendingLimit;\\n \\n// - The spending limit on gas for a given session key, measured in wei.\\n// - Whether or not the spending limit will reset in the next interval, if a refresh interval is set.\\nconst [gasSpendingLimit, shouldReset] =\\n await sessionKeyPluginView.getGasSpendLimit([\\n accountAddress,\\n sessionKeyAddress,\\n ]);\\n \\nconst {\\n hasLimit: hasGasSpendLimit, // Whether or not a gas spending limit is enforced on the session key\\n limit: gasSpendLimit, // The gas limit's maximum spend amount, in wei. If a refresh interval is set, this is the max per interval.\\n limitUsed: gasSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval.\\n refreshInterval: gasRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit.\\n lastUsedTime: gasLastUsedTime, // The start of the latest interval, if using the refresh interval.\\n} = gasSpendingLimit;\\n \\n// The paymaster address required for a given session key.\\n// If there is no required paymaster, this will return the zero address.\\nconst requiredPaymaster = await sessionKeyPluginView.getRequiredPaymaster([\\n accountAddress,\\n sessionKeyAddress,\\n]);
\\n\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#reading-permissions\",\"isPage\":false,\"text\":\"\\nYou may wish to view the current permissions of a given session key. This can be done using view functions defined by the Session Key Plugin.\\nHere's an example of viewing all permissions in TypeScript:\\nconst sessionKeyPluginView = SessionKeyPlugin.getContract(client).read;\\nconst accountAddress = client.getAddress();\\nconst sessionKeyAddress = await sessionKeySigner.getAddress();\\n \\nconst exampleTargetAddress = "0x4567456745674567456745674567456745674567";\\nconst exampleTargetSelector = "0x78907890";\\nconst exampleERC20Address = "0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";\\n \\n// Using session key permissions view functions\\n \\n// The key's current access control type. One of:\\n// - SessionKeyAccessListType.ALLOWLIST\\n// - SessionKeyAccessListType.DENYLIST\\n// - SessionKeyAccessListType.ALLOW_ALL_ACCESS\\nconst accessControlType = await sessionKeyPluginView.getAccessControlType([\\n accountAddress,\\n sessionKeyAddress,\\n]);\\n \\n// - Whether or not the address is on the access control list (either allowlist or denylist, depending on setting).\\n// - Whether or not the function selectors should be checked for the target address (checked according to the access control type).\\nconst [isTargetAddressOnList, checkSelectors] =\\n await sessionKeyPluginView.getAccessControlEntry([\\n accountAddress,\\n sessionKeyAddress,\\n exampleTargetAddress,\\n ]);\\n \\n// Whether or not the selector is on the access control list\\nconst isTargetSelectorOnList =\\n await sessionKeyPluginView.isSelectorOnAccessControlList([\\n accountAddress,\\n sessionKeyAddress,\\n exampleTargetAddress,\\n exampleTargetSelector,\\n ]);\\n \\n// The start and end timestamp of a key.\\n// If either is zero, that means the value is unset.\\nconst [validAfter, validUntil] = await sessionKeyPluginView.getKeyTimeRange([\\n accountAddress,\\n sessionKeyAddress,\\n]);\\n \\n// The native token spending limit of a key. Details below\\nconst nativeTokenSpendingLimit =\\n await sessionKeyPluginView.getNativeTokenSpendLimitInfo([\\n accountAddress,\\n sessionKeyAddress,\\n ]);\\n \\nconst {\\n hasLimit: hasNativeTokenSpendLimit, // Whether or not a native token spending limit is enforced on the session key\\n limit: nativeTokenSpendLimit, // The limit's maximum value. If a refresh interval is set, this is the max per interval.\\n limitUsed: nativeTokenSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval.\\n refreshInterval: nativeTokenRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit.\\n lastUsedTime: nativeTokenLastUsedTime, // The start of the latest interval, if using the refresh interval.\\n} = nativeTokenSpendingLimit;\\n \\n// The spending limit for an ERC-20 token.\\nconst erc20SpendingLimit = await sessionKeyPluginView.getERC20SpendLimitInfo([\\n accountAddress,\\n sessionKeyAddress,\\n exampleERC20Address,\\n]);\\n \\nconst {\\n hasLimit: hasErc20TokenSpendLimit, // Whether or not an ERC-20 token spending limit is enforced on the session key for this token address.\\n limit: erc20TokenSpendLimit, // The limit's maximum value. If a refresh interval is set, this is the max per interval.\\n limitUsed: erc20TokenSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval.\\n refreshInterval: erc20TokenRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit.\\n lastUsedTime: erc20TokenLastUsedTime, // The start of the latest interval, if using the refresh interval.\\n} = erc20SpendingLimit;\\n \\n// - The spending limit on gas for a given session key, measured in wei.\\n// - Whether or not the spending limit will reset in the next interval, if a refresh interval is set.\\nconst [gasSpendingLimit, shouldReset] =\\n await sessionKeyPluginView.getGasSpendLimit([\\n accountAddress,\\n sessionKeyAddress,\\n ]);\\n \\nconst {\\n hasLimit: hasGasSpendLimit, // Whether or not a gas spending limit is enforced on the session key\\n limit: gasSpendLimit, // The gas limit's maximum spend amount, in wei. If a refresh interval is set, this is the max per interval.\\n limitUsed: gasSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval.\\n refreshInterval: gasRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit.\\n lastUsedTime: gasLastUsedTime, // The start of the latest interval, if using the refresh interval.\\n} = gasSpendingLimit;\\n \\n// The paymaster address required for a given session key.\\n// If there is no required paymaster, this will return the zero address.\\nconst requiredPaymaster = await sessionKeyPluginView.getRequiredPaymaster([\\n accountAddress,\\n sessionKeyAddress,\\n]);\\n\",\"title\":\"Reading Permissions\",\"titles\":[\"Supported Permissions\"]},{\"href\":\"/smart-contracts/session-keys/supported-permissions#permission-view-functions\",\"html\":\"\\nThe following view functions are declared by the session key plugin and used to read information about permissions. These are the functions used in the example above.
\\nenum ContractAccessControlType {\\n ALLOWLIST, // Allowlist is default\\n DENYLIST,\\n ALLOW_ALL_ACCESS // Disables contract access control, any address and selector are allowed.\\n}\\n \\n// Struct returned by view functions to provide information about a session key's spend limit.\\n// Used for native token, ERC-20, and gas spend limits.\\nstruct SpendLimitInfo {\\n bool hasLimit;\\n uint256 limit;\\n uint256 limitUsed;\\n uint48 refreshInterval;\\n uint48 lastUsedTime;\\n}\\n \\n/// @notice Get the access control type for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return The access control type for the session key on the account.\\nfunction getAccessControlType(address account, address sessionKey)\\n external\\n view\\n returns (ContractAccessControlType);\\n \\n/// @notice Get an access control entry for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @param targetAddress The target address to check.\\n/// @return isOnList Whether the target address is on the list (either allowlist or blocklist depending on the\\n/// access control type).\\n/// @return checkSelectors Whether the target address should be checked for selectors during permissions\\n/// enforcement.\\nfunction getAccessControlEntry(address account, address sessionKey, address targetAddress)\\n external\\n view\\n returns (bool isOnList, bool checkSelectors);\\n \\n/// @notice Get whether a selector is on the access control list for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @param targetAddress The target address to check.\\n/// @param selector The selector to check.\\n/// @return isOnList Whether the selector is on the list (either allowlist or blocklist depending on the\\n/// access control type).\\nfunction isSelectorOnAccessControlList(\\n address account,\\n address sessionKey,\\n address targetAddress,\\n bytes4 selector\\n) external view returns (bool isOnList);\\n \\n/// @notice Get the active time range for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return validAfter The time after which the session key is valid.\\n/// @return validUntil The time until which the session key is valid.\\nfunction getKeyTimeRange(address account, address sessionKey)\\n external\\n view\\n returns (uint48 validAfter, uint48 validUntil);\\n \\n/// @notice Get the native token spend limit for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return A struct with fields describing the state of native token spending limits on this session key.\\nfunction getNativeTokenSpendLimitInfo(address account, address sessionKey)\\n external\\n view\\n returns (SpendLimitInfo memory);\\n \\n/// @notice Get the gas spend limit for a session key on an account.\\n/// Note that this spend limit is measured in wei, not units of gas.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return info A struct with fields describing the state of gas spending limits on this session key.\\n/// @return shouldReset Whether this session key must be reset by calling `resetSessionKeyGasLimitTimestamp`\\n/// before it can be used.\\nfunction getGasSpendLimit(address account, address sessionKey)\\n external\\n view\\n returns (SpendLimitInfo memory info, bool shouldReset);\\n \\n/// @notice Get the ERC20 spend limit for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @param token The token to check.\\n/// @return A struct with fields describing the state of ERC20 spending limits on this session key.\\nfunction getERC20SpendLimitInfo(address account, address sessionKey, address token)\\n external\\n view\\n returns (SpendLimitInfo memory);\\n \\n/// @notice Get the required paymaster address for a session key on an account, if any.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return The required paymaster address for this session key on this account, or the zero address if the\\n/// rule is disabled.\\nfunction getRequiredPaymaster(address account, address sessionKey) external view returns (address);
\",\"id\":\"pages/smart-contracts/session-keys/supported-permissions.mdx#permission-view-functions\",\"isPage\":false,\"text\":\"\\nThe following view functions are declared by the session key plugin and used to read information about permissions. These are the functions used in the example above.\\nenum ContractAccessControlType {\\n ALLOWLIST, // Allowlist is default\\n DENYLIST,\\n ALLOW_ALL_ACCESS // Disables contract access control, any address and selector are allowed.\\n}\\n \\n// Struct returned by view functions to provide information about a session key's spend limit.\\n// Used for native token, ERC-20, and gas spend limits.\\nstruct SpendLimitInfo {\\n bool hasLimit;\\n uint256 limit;\\n uint256 limitUsed;\\n uint48 refreshInterval;\\n uint48 lastUsedTime;\\n}\\n \\n/// @notice Get the access control type for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return The access control type for the session key on the account.\\nfunction getAccessControlType(address account, address sessionKey)\\n external\\n view\\n returns (ContractAccessControlType);\\n \\n/// @notice Get an access control entry for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @param targetAddress The target address to check.\\n/// @return isOnList Whether the target address is on the list (either allowlist or blocklist depending on the\\n/// access control type).\\n/// @return checkSelectors Whether the target address should be checked for selectors during permissions\\n/// enforcement.\\nfunction getAccessControlEntry(address account, address sessionKey, address targetAddress)\\n external\\n view\\n returns (bool isOnList, bool checkSelectors);\\n \\n/// @notice Get whether a selector is on the access control list for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @param targetAddress The target address to check.\\n/// @param selector The selector to check.\\n/// @return isOnList Whether the selector is on the list (either allowlist or blocklist depending on the\\n/// access control type).\\nfunction isSelectorOnAccessControlList(\\n address account,\\n address sessionKey,\\n address targetAddress,\\n bytes4 selector\\n) external view returns (bool isOnList);\\n \\n/// @notice Get the active time range for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return validAfter The time after which the session key is valid.\\n/// @return validUntil The time until which the session key is valid.\\nfunction getKeyTimeRange(address account, address sessionKey)\\n external\\n view\\n returns (uint48 validAfter, uint48 validUntil);\\n \\n/// @notice Get the native token spend limit for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return A struct with fields describing the state of native token spending limits on this session key.\\nfunction getNativeTokenSpendLimitInfo(address account, address sessionKey)\\n external\\n view\\n returns (SpendLimitInfo memory);\\n \\n/// @notice Get the gas spend limit for a session key on an account.\\n/// Note that this spend limit is measured in wei, not units of gas.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return info A struct with fields describing the state of gas spending limits on this session key.\\n/// @return shouldReset Whether this session key must be reset by calling `resetSessionKeyGasLimitTimestamp`\\n/// before it can be used.\\nfunction getGasSpendLimit(address account, address sessionKey)\\n external\\n view\\n returns (SpendLimitInfo memory info, bool shouldReset);\\n \\n/// @notice Get the ERC20 spend limit for a session key on an account.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @param token The token to check.\\n/// @return A struct with fields describing the state of ERC20 spending limits on this session key.\\nfunction getERC20SpendLimitInfo(address account, address sessionKey, address token)\\n external\\n view\\n returns (SpendLimitInfo memory);\\n \\n/// @notice Get the required paymaster address for a session key on an account, if any.\\n/// @param account The account to check.\\n/// @param sessionKey The session key to check.\\n/// @return The required paymaster address for this session key on this account, or the zero address if the\\n/// rule is disabled.\\nfunction getRequiredPaymaster(address account, address sessionKey) external view returns (address);\",\"title\":\"Permission View Functions\",\"titles\":[\"Supported Permissions\",\"Reading Permissions\"]}]}],[\"index.c01590abb59f6b20683195c3ebb88d2042dfcaa40709178fdf5075668482b17e\",{\"mdx\":\"---\\ntitle: Add Passkey\\ndescription: Learn how to add a passkey to a user account\\n---\\n\\n# Add Passkey\\n\\nIf your user has already authenticated with an email or passkey, you can also add a new passkey to their account. This is\\nuseful in the case that you want to give your users a more convenient method of logging in or if they want to add more devices\\nto their account.\\n\\n## Add a passkey\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { signer } from \\\"./signer\\\";\\n\\n// NOTE: this assumes you have already authenticated the user\\n// you can further customize the Credential Creation Options here\\nawait signer.addPasskey({});\\n```\\n\\n```ts twoslash [signer] filename=\\\"signer.ts\\\"\\n// [!include ~/shared/signer/signer.ts]\\n```\\n\\n:::\\n\",\"document\":[{\"href\":\"/signer/authentication/add-passkey#add-passkey\",\"html\":\"\\nIf your user has already authenticated with an email or passkey, you can also add a new passkey to their account. This is\\nuseful in the case that you want to give your users a more convenient method of logging in or if they want to add more devices\\nto their account.
\\n\",\"id\":\"pages/signer/authentication/add-passkey.mdx#add-passkey\",\"isPage\":true,\"text\":\"\\nIf your user has already authenticated with an email or passkey, you can also add a new passkey to their account. This is\\nuseful in the case that you want to give your users a more convenient method of logging in or if they want to add more devices\\nto their account.\\n\",\"title\":\"Add Passkey\",\"titles\":[]},{\"href\":\"/signer/authentication/add-passkey#add-a-passkey\",\"html\":\"\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\n// NOTE: this assumes you have already authenticated the user\\n// you can further customize the Credential Creation Options here\\nawait signer.addPasskey({});
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
One of the low level packages available in Account Kit is our Smart Contracts package. This package contains all of the smart contract interfaces and utilities you need to use any of our\\nsecure, audited smart contracts.
\\nIn these guides, we'll show you how to pick and choose the right smart contract for you and how to use them in your application.
\\n\",\"id\":\"pages/smart-contracts/overview.mdx#smart-contracts-overview\",\"isPage\":true,\"text\":\"\\nOne of the low level packages available in Account Kit is our Smart Contracts package. This package contains all of the smart contract interfaces and utilities you need to use any of our\\nsecure, audited smart contracts.\\nIn these guides, we'll show you how to pick and choose the right smart contract for you and how to use them in your application.\\nFor the easiest integration, we recommend using @account-kit/react or @account-kit/core which support all of the contracts in this package by default.\",\"title\":\"Smart Contracts Overview\",\"titles\":[]}]}],[\"index.35b8f6d1383dc26de2d04a39078e9e498f615d9e510a8a1dafc4381ab5c62377\",{\"mdx\":\"---\\ntitle: Getting started with Session Keys\\ndescription: Learn how to use Alchemy's Session Key Plugin.\\n---\\n\\n# Getting started with Session Keys\\n\\n`@account-kit/smart-contracts` exports all of the definitions you need to use session keys with a Modular Account. We provide a simple `SessionKeySigner` class that generates session keys on the client and can be used as the `signer` for the Multi Owner Modular Account.\\nWe also export the necessary decorators which can be used to extend your `modularAccountClient` to make interacting with session keys easy.\\n\\n## Usage\\n\\nLet's take a look at a full example that demonstrates how to use session keys with a Modular Account.\\n\\n```ts twoslash\\n// [!include ~/shared/smart-contracts/session-keys/full-example.ts]\\n```\\n\\n## Breaking it down\\n\\n### Determine where the session key is stored\\n\\nSession keys can be held on the client side or on a backend agent. Client side session keys are useful for skipping confirmations, and agent side keys are useful for automations.\\n\\nIn the above example, we use a client-side key using the `SessionKeySigner` exported from `@account-kit/smart-contracts`.\\n\\n```ts twoslash\\nimport { SessionKeySigner } from \\\"@account-kit/smart-contracts\\\";\\n\\nconst sessionKeySigner = new SessionKeySigner();\\n```\\n\\nIf you are using backend agent controlled session keys, then the agent should generate the private key and send only the address to the client. This protects the private key by not exposing it to the user.\\n\\n### Extend your client with Modular Account Decorators\\n\\nThe base `modularAccountClient` and `AlchemymodularAccountClient`, only include base functionality for sending user operations. If you are using a `ModularAccount`, then you will want to extend your client with the various decorators exported by `@account-kit/smart-contracts`.\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { modularAccountClient } from \\\"./client\\\";\\nimport { sessionKeyPluginActions } from \\\"@account-kit/smart-contracts\\\";\\n\\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);\\n```\\n\\n```ts [client.ts] filename=\\\"client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/modular-account-client.ts]\\n```\\n\\n:::\\n\\n### Check if the Session Key Plugin is installed\\n\\nBefore you can start using session keys, you need to check whether the user’s account has the session key plugin installed. You can perform this check using the account loupe decorator, which lets you inspect the state of installed plugins on a Modular Account.\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { modularAccountClient } from \\\"./client\\\";\\nimport {\\n accountLoupeActions,\\n multiOwnerPluginActions,\\n sessionKeyPluginActions,\\n pluginManagerActions,\\n} from \\\"@account-kit/smart-contracts\\\";\\n\\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);\\n\\n//---cut---\\n\\nimport { SessionKeyPlugin } from \\\"@account-kit/smart-contracts\\\";\\n\\n// 1. check if the plugin is installed\\nconst isPluginInstalled = await modularAccountClient\\n .getInstalledPlugins({})\\n // This checks using the default address for the chain, but you can always pass in your own plugin address here as an override\\n .then((x) => x.includes(SessionKeyPlugin.meta.addresses[chain.id]));\\n```\\n\\n```ts [client.ts] filename=\\\"client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/modular-account-client.ts]\\n```\\n\\n:::\\n\\n### Install the Session Key Plugin\\n\\nIf the Session Key Plugin is not yet installed, you need to install it before it can be used. To simplify the workflow, it is also possible to batch the plugin installation along with creating session keys and performing other actions, which combines all of these steps into one user operation.\\n\\n:::code-group\\n\\n```ts [example.ts] twoslash\\nimport { modularAccountClient } from \\\"./client\\\";\\nimport {\\n accountLoupeActions,\\n multiOwnerPluginActions,\\n sessionKeyPluginActions,\\n pluginManagerActions,\\n} from \\\"@account-kit/smart-contracts\\\";\\n\\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);\\n\\nimport { SessionKeyPlugin } from \\\"@account-kit/smart-contracts\\\";\\n\\n// 1. check if the plugin is installed\\nconst isPluginInstalled = await extendedClient\\n .getInstalledPlugins({})\\n // This checks using the default address for the chain, but you can always pass in your own plugin address here as an override\\n .then((x) => x.includes(SessionKeyPlugin.meta.addresses[chain.id]));\\n\\n//---cut---\\nimport { SessionKeyPermissionsBuilder } from \\\"@account-kit/smart-contracts\\\";\\n\\n// 2. if the plugin is not installed, then install it and set up the session key\\nif (!isPluginInstalled) {\\n // lets create an initial permission set for the session key giving it an eth spend limit\\n // if we don't set anything here, then the key will have 0 permissions\\n const initialPermissions =\\n new SessionKeyPermissionsBuilder().setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n });\\n\\n const { hash } = await extendedClient.installSessionKeyPlugin({\\n // 1st arg is the initial set of session keys\\n // 2nd arg is the tags for the session keys\\n // 3rd arg is the initial set of permissions\\n args: [\\n [await sessionKeySigner.getAddress()],\\n [zeroHash],\\n [initialPermissions.encode()],\\n ],\\n });\\n\\n await extendedClient.waitForUserOperationTransaction({ hash });\\n}\\n```\\n\\n```ts [client.ts] filename=\\\"client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/modular-account-client.ts]\\n```\\n\\n:::\\n\\n### Construct the initial set of permissions\\n\\nSession keys are powerful because of permissions that limit what actions they can take. When you add a session key, you should also specify the initial permissions that apply over the key.\\n\\nSee the [Supported Permissions](/smart-contracts/session-keys/supported-permissions#using-the-permissionsbuilder) page for more information on how to used the permissions builder.\\n\\nLet's use the permission builder to build a set of permissions that sets a spend limit:\\n\\n:::code-group\\n\\n```ts [example.ts] twoslash\\nimport { modularAccountClient } from \\\"./client\\\";\\nimport {\\n accountLoupeActions,\\n multiOwnerPluginActions,\\n sessionKeyPluginActions,\\n pluginManagerActions,\\n} from \\\"@account-kit/smart-contracts\\\";\\n\\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);\\n\\n//---cut---\\nimport { SessionKeyPermissionsBuilder } from \\\"@account-kit/smart-contracts\\\";\\n\\nconst initialPermissions =\\n new SessionKeyPermissionsBuilder().setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n });\\n\\nconst result = await extendedClient.updateKeyPermissions({\\n args: [sessionKeyAddress, initialPermissions.encode()],\\n});\\n```\\n\\n```ts [client.ts] filename=\\\"client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/modular-account-client.ts]\\n```\\n\\n:::\\n\\n## Managing Session Keys\\n\\nThe Session Key Plugin allows you to:\\n\\n- Add session keys, and set the key's initial permissions.\\n- Remove session keys.\\n- Update key permissions.\\n- Rotate session keys. This action replaces the previous session key with a new session key, while keeping the existing permissions.\\n\\n### Add a Session Key\\n\\nSession keys can be added either during installation, or using the `addSessionKey` function.\\n\\n:::code-group\\n\\n```ts [add-session-key.ts] twoslash\\nimport { SessionKeyPermissionsBuilder } from \\\"@account-kit/smart-contracts\\\";\\nimport { keccak256 } from \\\"viem\\\";\\nimport { client } from \\\"./base-client\\\";\\n\\nconst result = await client.addSessionKey({\\n key: \\\"0xSessionKeyAddress\\\",\\n // tag is an identifier for the emitted SessionKeyAdded event\\n tag: keccak256(new TextEncoder().encode(\\\"session-key-tag\\\")),\\n permissions: new SessionKeyPermissionsBuilder().encode(),\\n});\\n```\\n\\n```ts [base-client.ts] filename=\\\"base-client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/session-keys/base-client.ts]\\n```\\n\\n:::\\n\\n### Remove a Session Key\\n\\nSession keys can be removed using the `removeSessionKey` function.\\n:::code-group\\n\\n```ts [remove-session-key.ts] twoslash\\nimport { client } from \\\"./base-client\\\";\\n\\nconst result = await client.removeSessionKey({\\n key: \\\"0xSessionKeyAddress\\\",\\n});\\n```\\n\\n```ts [base-client.ts] filename=\\\"base-client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/session-keys/base-client.ts]\\n```\\n\\n:::\\n\\n### Update a Key's permissions\\n\\nSession key permissions can be edited after creation using the `updateKeyPermissions` function. Note that you should configure initial permissions when the key is added, and not rely on a second user operation to set the permissions.\\n:::code-group\\n\\n```ts [update-session-key.ts] twoslash\\nimport { SessionKeyPermissionsBuilder } from \\\"@account-kit/smart-contracts\\\";\\nimport { client } from \\\"./base-client\\\";\\n\\nconst result = await client.updateSessionKeyPermissions({\\n key: \\\"0xSessionKeyAddress\\\",\\n // add other permissions to the builder\\n permissions: new SessionKeyPermissionsBuilder()\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n })\\n .encode(),\\n});\\n```\\n\\n```ts [base-client.ts] filename=\\\"base-client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/session-keys/base-client.ts]\\n```\\n\\n:::\\n\\n### Rotate a Session Key\\n\\nIf the key is no longer available, but there exists a tag identifying a previous session key configured for your application, you may instead choose to rotate the previous key’s permissions. This can be performed using `rotateKey` .\\n:::code-group\\n\\n```ts [rotate-session-key.ts] twoslash\\nimport { client } from \\\"./base-client.js\\\";\\n\\nconst result = await client.rotateSessionKey({\\n oldKey: \\\"0xOldKey\\\",\\n newKey: \\\"0xNewKey\\\",\\n});\\n```\\n\\n```ts [base-client.ts] filename=\\\"base-client.ts\\\" twoslash\\n// [!include ~/shared/smart-contracts/session-keys/base-client.ts]\\n```\\n\\n:::\\n\",\"document\":[{\"href\":\"/smart-contracts/session-keys/getting-started#getting-started-with-session-keys\",\"html\":\"\\n@account-kit/smart-contracts
exports all of the definitions you need to use session keys with a Modular Account. We provide a simple SessionKeySigner
class that generates session keys on the client and can be used as the signer
for the Multi Owner Modular Account.\\nWe also export the necessary decorators which can be used to extend your modularAccountClient
to make interacting with session keys easy.
Let's take a look at a full example that demonstrates how to use session keys with a Modular Account.
\\n/* eslint-disable @typescript-eslint/no-unused-vars */\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n SessionKeyAccessListType,\\n SessionKeyPermissionsBuilder,\\n SessionKeyPlugin,\\n SessionKeySigner,\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\nimport { zeroHash } from "viem";\\n \\nconst chain = sepolia;\\n// this is the signer to connect with the account, later we will create a new client using a session key signe\\nconst signer = LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC");\\nconst sessionKeySigner = new SessionKeySigner();\\nconst client = (\\n await createModularAccountAlchemyClient({\\n chain,\\n apiKey: "ALCHEMY_API_KEY",\\n signer,\\n })\\n).extend(sessionKeyPluginActions);\\n \\n// 1. check if the plugin is installed\\nconst isPluginInstalled = await client\\n .getInstalledPlugins({})\\n // This checks using the default address for the chain, but you can always pass in your own plugin address here as an override\\n .then((x) => x.includes(SessionKeyPlugin.meta.addresses[chain.id]));\\n \\n// 2. if the plugin is not installed, then install it and set up the session key\\nif (!isPluginInstalled) {\\n // lets create an initial permission set for the session key giving it an eth spend limit\\n const initialPermissions = new SessionKeyPermissionsBuilder()\\n .setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n })\\n // this will allow the session key plugin to interact with all addresses\\n .setContractAccessControlType(SessionKeyAccessListType.ALLOW_ALL_ACCESS)\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n });\\n \\n const { hash } = await client.installSessionKeyPlugin({\\n // 1st arg is the initial set of session keys\\n // 2nd arg is the tags for the session keys\\n // 3rd arg is the initial set of permissions\\n args: [\\n [await sessionKeySigner.getAddress()],\\n [zeroHash],\\n [initialPermissions.encode()],\\n ],\\n });\\n \\n await client.waitForUserOperationTransaction({ hash });\\n}\\n \\n// 3. set up a client that's using our session key\\nconst sessionKeyClient = (\\n await createModularAccountAlchemyClient({\\n chain,\\n signer: sessionKeySigner,\\n apiKey: "ALCHEMY_API_KEY",\\n // this is important because it tells the client to use our previously deployed account\\n accountAddress: client.getAddress(),\\n })\\n).extend(sessionKeyPluginActions);\\n \\n// 4. send a user operation using the session key\\nconst result = await sessionKeyClient.executeWithSessionKey({\\n args: [\\n [\\n {\\n target: "0x1234123412341234123412341234123412341234",\\n value: 1n,\\n data: "0x",\\n },\\n ],\\n await sessionKeySigner.getAddress(),\\n ],\\n});
\\n\",\"id\":\"pages/smart-contracts/session-keys/getting-started.mdx#usage\",\"isPage\":false,\"text\":\"\\nLet's take a look at a full example that demonstrates how to use session keys with a Modular Account.\\n/* eslint-disable @typescript-eslint/no-unused-vars */\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n SessionKeyAccessListType,\\n SessionKeyPermissionsBuilder,\\n SessionKeyPlugin,\\n SessionKeySigner,\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\nimport { zeroHash } from "viem";\\n \\nconst chain = sepolia;\\n// this is the signer to connect with the account, later we will create a new client using a session key signe\\nconst signer = LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC");\\nconst sessionKeySigner = new SessionKeySigner();\\nconst client = (\\n await createModularAccountAlchemyClient({\\n chain,\\n apiKey: "ALCHEMY_API_KEY",\\n signer,\\n })\\n).extend(sessionKeyPluginActions);\\n \\n// 1. check if the plugin is installed\\nconst isPluginInstalled = await client\\n .getInstalledPlugins({})\\n // This checks using the default address for the chain, but you can always pass in your own plugin address here as an override\\n .then((x) => x.includes(SessionKeyPlugin.meta.addresses[chain.id]));\\n \\n// 2. if the plugin is not installed, then install it and set up the session key\\nif (!isPluginInstalled) {\\n // lets create an initial permission set for the session key giving it an eth spend limit\\n const initialPermissions = new SessionKeyPermissionsBuilder()\\n .setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n })\\n // this will allow the session key plugin to interact with all addresses\\n .setContractAccessControlType(SessionKeyAccessListType.ALLOW_ALL_ACCESS)\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n });\\n \\n const { hash } = await client.installSessionKeyPlugin({\\n // 1st arg is the initial set of session keys\\n // 2nd arg is the tags for the session keys\\n // 3rd arg is the initial set of permissions\\n args: [\\n [await sessionKeySigner.getAddress()],\\n [zeroHash],\\n [initialPermissions.encode()],\\n ],\\n });\\n \\n await client.waitForUserOperationTransaction({ hash });\\n}\\n \\n// 3. set up a client that's using our session key\\nconst sessionKeyClient = (\\n await createModularAccountAlchemyClient({\\n chain,\\n signer: sessionKeySigner,\\n apiKey: "ALCHEMY_API_KEY",\\n // this is important because it tells the client to use our previously deployed account\\n accountAddress: client.getAddress(),\\n })\\n).extend(sessionKeyPluginActions);\\n \\n// 4. send a user operation using the session key\\nconst result = await sessionKeyClient.executeWithSessionKey({\\n args: [\\n [\\n {\\n target: "0x1234123412341234123412341234123412341234",\\n value: 1n,\\n data: "0x",\\n },\\n ],\\n await sessionKeySigner.getAddress(),\\n ],\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"Getting started with Session Keys\"]},{\"href\":\"/smart-contracts/session-keys/getting-started#breaking-it-down\",\"html\":\"\\n\",\"id\":\"pages/smart-contracts/session-keys/getting-started.mdx#breaking-it-down\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Breaking it down\",\"titles\":[\"Getting started with Session Keys\"]},{\"href\":\"/smart-contracts/session-keys/getting-started#determine-where-the-session-key-is-stored\",\"html\":\"\\nSession keys can be held on the client side or on a backend agent. Client side session keys are useful for skipping confirmations, and agent side keys are useful for automations.
\\nIn the above example, we use a client-side key using the SessionKeySigner
exported from @account-kit/smart-contracts
.
import { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst sessionKeySigner = new SessionKeySigner();
\\nIf you are using backend agent controlled session keys, then the agent should generate the private key and send only the address to the client. This protects the private key by not exposing it to the user.
\\n\",\"id\":\"pages/smart-contracts/session-keys/getting-started.mdx#determine-where-the-session-key-is-stored\",\"isPage\":false,\"text\":\"\\nSession keys can be held on the client side or on a backend agent. Client side session keys are useful for skipping confirmations, and agent side keys are useful for automations.\\nIn the above example, we use a client-side key using the SessionKeySigner exported from @account-kit/smart-contracts.\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst sessionKeySigner = new SessionKeySigner();\\nIf you are using backend agent controlled session keys, then the agent should generate the private key and send only the address to the client. This protects the private key by not exposing it to the user.\\n\",\"title\":\"Determine where the session key is stored\",\"titles\":[\"Getting started with Session Keys\",\"Breaking it down\"]},{\"href\":\"/smart-contracts/session-keys/getting-started#extend-your-client-with-modular-account-decorators\",\"html\":\"\\nThe base modularAccountClient
and AlchemymodularAccountClient
, only include base functionality for sending user operations. If you are using a ModularAccount
, then you will want to extend your client with the various decorators exported by @account-kit/smart-contracts
.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\nimport { sessionKeyPluginActions } from "@account-kit/smart-contracts";\\n \\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
Before you can start using session keys, you need to check whether the user’s account has the session key plugin installed. You can perform this check using the account loupe decorator, which lets you inspect the state of installed plugins on a Modular Account.
\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\nimport {\\n accountLoupeActions,\\n multiOwnerPluginActions,\\n sessionKeyPluginActions,\\n pluginManagerActions,\\n} from "@account-kit/smart-contracts";\\n \\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);\\n \\n//---cut---\\n \\nimport { SessionKeyPlugin } from "@account-kit/smart-contracts";\\n \\n// 1. check if the plugin is installed\\nconst isPluginInstalled = await modularAccountClient\\n .getInstalledPlugins({})\\n // This checks using the default address for the chain, but you can always pass in your own plugin address here as an override\\n .then((x) => x.includes(SessionKeyPlugin.meta.addresses[chain.id]));
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
If the Session Key Plugin is not yet installed, you need to install it before it can be used. To simplify the workflow, it is also possible to batch the plugin installation along with creating session keys and performing other actions, which combines all of these steps into one user operation.
\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\nimport {\\n accountLoupeActions,\\n multiOwnerPluginActions,\\n sessionKeyPluginActions,\\n pluginManagerActions,\\n} from "@account-kit/smart-contracts";\\n \\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);\\n \\nimport { SessionKeyPlugin } from "@account-kit/smart-contracts";\\n \\n// 1. check if the plugin is installed\\nconst isPluginInstalled = await extendedClient\\n .getInstalledPlugins({})\\n // This checks using the default address for the chain, but you can always pass in your own plugin address here as an override\\n .then((x) => x.includes(SessionKeyPlugin.meta.addresses[chain.id]));\\n \\n//---cut---\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\n// 2. if the plugin is not installed, then install it and set up the session key\\nif (!isPluginInstalled) {\\n // lets create an initial permission set for the session key giving it an eth spend limit\\n // if we don't set anything here, then the key will have 0 permissions\\n const initialPermissions =\\n new SessionKeyPermissionsBuilder().setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n });\\n \\n const { hash } = await extendedClient.installSessionKeyPlugin({\\n // 1st arg is the initial set of session keys\\n // 2nd arg is the tags for the session keys\\n // 3rd arg is the initial set of permissions\\n args: [\\n [await sessionKeySigner.getAddress()],\\n [zeroHash],\\n [initialPermissions.encode()],\\n ],\\n });\\n \\n await extendedClient.waitForUserOperationTransaction({ hash });\\n}
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
Session keys are powerful because of permissions that limit what actions they can take. When you add a session key, you should also specify the initial permissions that apply over the key.
\\nSee the Supported Permissions page for more information on how to used the permissions builder.
\\nLet's use the permission builder to build a set of permissions that sets a spend limit:
\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\nimport {\\n accountLoupeActions,\\n multiOwnerPluginActions,\\n sessionKeyPluginActions,\\n pluginManagerActions,\\n} from "@account-kit/smart-contracts";\\n \\nconst extendedClient = modularAccountClient.extend(sessionKeyPluginActions);\\n \\n//---cut---\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst initialPermissions =\\n new SessionKeyPermissionsBuilder().setNativeTokenSpendLimit({\\n spendLimit: 1000000n,\\n });\\n \\nconst result = await extendedClient.updateKeyPermissions({\\n args: [sessionKeyAddress, initialPermissions.encode()],\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
The Session Key Plugin allows you to:
\\nSession keys can be added either during installation, or using the addSessionKey
function.
// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: example.js\\n \\n// ---cut---\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\nimport { keccak256 } from "viem";\\nimport { client } from "./base-client";\\n \\nconst result = await client.addSessionKey({\\n key: "0xSessionKeyAddress",\\n // tag is an identifier for the emitted SessionKeyAdded event\\n tag: keccak256(new TextEncoder().encode("session-key-tag")),\\n permissions: new SessionKeyPermissionsBuilder().encode(),\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);
Session keys can be removed using the removeSessionKey
function.
// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: example.js\\n \\n// ---cut---\\nimport { client } from "./base-client";\\n \\nconst result = await client.removeSessionKey({\\n key: "0xSessionKeyAddress",\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);
Session key permissions can be edited after creation using the updateKeyPermissions
function. Note that you should configure initial permissions when the key is added, and not rely on a second user operation to set the permissions.
// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: example.js\\n \\n// ---cut---\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\nimport { client } from "./base-client";\\n \\nconst result = await client.updateSessionKeyPermissions({\\n key: "0xSessionKeyAddress",\\n // add other permissions to the builder\\n permissions: new SessionKeyPermissionsBuilder()\\n .setTimeRange({\\n validFrom: Math.round(Date.now() / 1000),\\n // valid for 1 hour\\n validUntil: Math.round(Date.now() / 1000 + 60 * 60),\\n })\\n .encode(),\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);
If the key is no longer available, but there exists a tag identifying a previous session key configured for your application, you may instead choose to rotate the previous key’s permissions. This can be performed using rotateKey
.
// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: base-client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);\\n// @filename: example.js\\n \\n// ---cut---\\nimport { client } from "./base-client.js";\\n \\nconst result = await client.rotateSessionKey({\\n oldKey: "0xOldKey",\\n newKey: "0xNewKey",\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport {\\n createModularAccountAlchemyClient,\\n sessionKeyPluginActions,\\n} from "@account-kit/smart-contracts";\\n \\nexport const client = (\\n await createModularAccountAlchemyClient({\\n chain: sepolia,\\n signer: LocalAccountSigner.mnemonicToAccountSigner("MNEMONIC"),\\n apiKey: "ALCHEMY_API_KEY",\\n })\\n).extend(sessionKeyPluginActions);
The SmartAccountClient
within @aa-sdk/core
is unopinionated about which bundler you use, so you can connect to any RPC provider really simply.
If we look at the example for creating a SmartAccountClient
:
import { createSmartAccountClient } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst client = createSmartAccountClient({\\n transport: http("https://polygon-mumbai.g.alchemy.com/v2/demo"),\\n chain: sepolia,\\n});
\\nYou can see that we set the transport
to http("https://polygon-mumbai.g.alchemy.com/v2/demo")
. You can swap out that the url in the http
function to\\nany other provider's URL.
It might be the case that you want to use a different RPC provider for your bundler traffic and your node traffic. This is a common use case, and you can do this by leveraging the split
transport and passing it to your createSmartAccountClient
call. For example:
import { split } from "@aa-sdk/core";\\nimport { createPublicClient, http } from "viem";\\n \\nconst bundlerMethods = [\\n "eth_sendUserOperation",\\n "eth_estimateUserOperationGas",\\n "eth_getUserOperationReceipt",\\n "eth_getUserOperationByHash",\\n "eth_supportedEntryPoints",\\n];\\n \\nconst clientWithSplit = createPublicClient({\\n transport: split({\\n overrides: [\\n {\\n methods: bundlerMethods,\\n transport: http("BUNDLER_RPC_URL"),\\n },\\n ],\\n fallback: http("OTHER_RPC_URL"),\\n }),\\n});
\\n\",\"id\":\"pages/infra/third-party/bundlers.mdx#splitting-bundler-traffic-and-node-rpc-traffic\",\"isPage\":false,\"text\":\"\\nIt might be the case that you want to use a different RPC provider for your bundler traffic and your node traffic. This is a common use case, and you can do this by leveraging the split transport and passing it to your createSmartAccountClient call. For example:\\nimport { split } from "@aa-sdk/core";\\nimport { createPublicClient, http } from "viem";\\n \\nconst bundlerMethods = [\\n "eth_sendUserOperation",\\n "eth_estimateUserOperationGas",\\n "eth_getUserOperationReceipt",\\n "eth_getUserOperationByHash",\\n "eth_supportedEntryPoints",\\n];\\n \\nconst clientWithSplit = createPublicClient({\\n transport: split({\\n overrides: [\\n {\\n methods: bundlerMethods,\\n transport: http("BUNDLER_RPC_URL"),\\n },\\n ],\\n fallback: http("OTHER_RPC_URL"),\\n }),\\n});\\n\",\"title\":\"Splitting Bundler traffic and Node RPC traffic\",\"titles\":[\"Using a different RPC Provider\"]},{\"href\":\"/infra/third-party/bundlers#zora-and-fraxtal\",\"html\":\"\\nUsing a split Bundler and Node RPC setup is required for Fraxtal, Fraxtal Testnet, Zora, and Zora Sepolia networks since Alchemy currently only supports Account Abstraction endpoints for those networks. Please refer to documentation from Frax and Zora about RPC options.
\",\"id\":\"pages/infra/third-party/bundlers.mdx#zora-and-fraxtal\",\"isPage\":false,\"text\":\"\\nUsing a split Bundler and Node RPC setup is required for Fraxtal, Fraxtal Testnet, Zora, and Zora Sepolia networks since Alchemy currently only supports Account Abstraction endpoints for those networks. Please refer to documentation from Frax and Zora about RPC options.\",\"title\":\"Zora and Fraxtal\",\"titles\":[\"Using a different RPC Provider\"]}]}],[\"index.2f597d245fe91588b51b6df377784d0f5c63947b287c5dbd1bab1a60527fd52b\",{\"mdx\":\"---\\ntitle: Introduction to using Session Keys\\ndescription: Learn about Alchemy's ERC-6900 Compatible Session Key Plugin.\\n---\\n\\n# Session Key Plugin overview\\n\\nThe Session Key plugin lets your smart account add additional signers to your Modular Account with specific permissions.\\n\\n## Why Session Keys?\\n\\n### Skip duplicate confirmations\\n\\nSession keys unlock a simplified authentication process by allowing users to interact with apps without needing to confirm each action using their primary key. Instead, users create a session key with permissions specific to the app, then the app can use that key for future actions. This speeds up the user interaction and provides a smoother experience.\\n\\n### Automate actions\\n\\nWith the ability to delegate specific permissions to session keys, users can automate actions within predefined limits. Session keys can be used to streamline processes like recurring payments, contract interactions, or any activity that benefits from automation.\\n\\n### Enhance security with permissions\\n\\nBy using session keys, the exposure of the main private key is minimized. Even if a session key is compromised, the attacker would not gain access to the user's main account and funds. This layered approach to security helps in mitigating risks associated with key management.\\n\\n## Supported permissions\\n\\nThe session key plugin supports the following types of permissions for each key:\\n\\n### Time range\\n\\nSupports a start time and an end time for each key.\\n\\n### Access control lists\\n\\nSupports either an allowlist or a denylist for addresses. Optionally, access control lists may also specify specific functions on contracts to allow or deny.\\n\\n### ERC-20 spending Limits\\n\\nSupports limiting how much of a specific ERC-20 token a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 100 USDC per week).\\n\\n### Native token spending limits\\n\\nSupports limiting how much of the native token, e.g. ETH or MATIC, a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).\\n\\n### Gas spending limits\\n\\nSupports limiting how much of the native token (e.g. ETH or MATIC) a session key can spend on gas. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).\\n\\nAlternatively, you can also require that a session key uses a specific paymaster address, instead of spending the account’s native token for gas.\\n\\nNote that the gas limit is tracked in terms of native token units (wei), not in units of gas. The gas usage of a user operation is considered to be the maximum gas a user operation can spend, i.e. `total gas limit * maxFeePerGas`. This can overestimate when compared to the actual gas cost of each user operation.\\n\",\"document\":[{\"href\":\"/smart-contracts/session-keys#session-key-plugin-overview\",\"html\":\"\\nThe Session Key plugin lets your smart account add additional signers to your Modular Account with specific permissions.
\\n\",\"id\":\"pages/smart-contracts/session-keys/#session-key-plugin-overview\",\"isPage\":true,\"text\":\"\\nThe Session Key plugin lets your smart account add additional signers to your Modular Account with specific permissions.\\n\",\"title\":\"Session Key Plugin overview\",\"titles\":[]},{\"href\":\"/smart-contracts/session-keys#why-session-keys\",\"html\":\"\\n\",\"id\":\"pages/smart-contracts/session-keys/#why-session-keys\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Why Session Keys?\",\"titles\":[\"Session Key Plugin overview\"]},{\"href\":\"/smart-contracts/session-keys#skip-duplicate-confirmations\",\"html\":\"\\nSession keys unlock a simplified authentication process by allowing users to interact with apps without needing to confirm each action using their primary key. Instead, users create a session key with permissions specific to the app, then the app can use that key for future actions. This speeds up the user interaction and provides a smoother experience.
\\n\",\"id\":\"pages/smart-contracts/session-keys/#skip-duplicate-confirmations\",\"isPage\":false,\"text\":\"\\nSession keys unlock a simplified authentication process by allowing users to interact with apps without needing to confirm each action using their primary key. Instead, users create a session key with permissions specific to the app, then the app can use that key for future actions. This speeds up the user interaction and provides a smoother experience.\\n\",\"title\":\"Skip duplicate confirmations\",\"titles\":[\"Session Key Plugin overview\",\"Why Session Keys?\"]},{\"href\":\"/smart-contracts/session-keys#automate-actions\",\"html\":\"\\nWith the ability to delegate specific permissions to session keys, users can automate actions within predefined limits. Session keys can be used to streamline processes like recurring payments, contract interactions, or any activity that benefits from automation.
\\n\",\"id\":\"pages/smart-contracts/session-keys/#automate-actions\",\"isPage\":false,\"text\":\"\\nWith the ability to delegate specific permissions to session keys, users can automate actions within predefined limits. Session keys can be used to streamline processes like recurring payments, contract interactions, or any activity that benefits from automation.\\n\",\"title\":\"Automate actions\",\"titles\":[\"Session Key Plugin overview\",\"Why Session Keys?\"]},{\"href\":\"/smart-contracts/session-keys#enhance-security-with-permissions\",\"html\":\"\\nBy using session keys, the exposure of the main private key is minimized. Even if a session key is compromised, the attacker would not gain access to the user's main account and funds. This layered approach to security helps in mitigating risks associated with key management.
\\n\",\"id\":\"pages/smart-contracts/session-keys/#enhance-security-with-permissions\",\"isPage\":false,\"text\":\"\\nBy using session keys, the exposure of the main private key is minimized. Even if a session key is compromised, the attacker would not gain access to the user's main account and funds. This layered approach to security helps in mitigating risks associated with key management.\\n\",\"title\":\"Enhance security with permissions\",\"titles\":[\"Session Key Plugin overview\",\"Why Session Keys?\"]},{\"href\":\"/smart-contracts/session-keys#supported-permissions\",\"html\":\"\\nThe session key plugin supports the following types of permissions for each key:
\\n\",\"id\":\"pages/smart-contracts/session-keys/#supported-permissions\",\"isPage\":false,\"text\":\"\\nThe session key plugin supports the following types of permissions for each key:\\n\",\"title\":\"Supported permissions\",\"titles\":[\"Session Key Plugin overview\"]},{\"href\":\"/smart-contracts/session-keys#time-range\",\"html\":\"\\nSupports a start time and an end time for each key.
\\n\",\"id\":\"pages/smart-contracts/session-keys/#time-range\",\"isPage\":false,\"text\":\"\\nSupports a start time and an end time for each key.\\n\",\"title\":\"Time range\",\"titles\":[\"Session Key Plugin overview\",\"Supported permissions\"]},{\"href\":\"/smart-contracts/session-keys#access-control-lists\",\"html\":\"\\nSupports either an allowlist or a denylist for addresses. Optionally, access control lists may also specify specific functions on contracts to allow or deny.
\\n\",\"id\":\"pages/smart-contracts/session-keys/#access-control-lists\",\"isPage\":false,\"text\":\"\\nSupports either an allowlist or a denylist for addresses. Optionally, access control lists may also specify specific functions on contracts to allow or deny.\\n\",\"title\":\"Access control lists\",\"titles\":[\"Session Key Plugin overview\",\"Supported permissions\"]},{\"href\":\"/smart-contracts/session-keys#erc-20-spending-limits\",\"html\":\"\\nSupports limiting how much of a specific ERC-20 token a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 100 USDC per week).
\\n\",\"id\":\"pages/smart-contracts/session-keys/#erc-20-spending-limits\",\"isPage\":false,\"text\":\"\\nSupports limiting how much of a specific ERC-20 token a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 100 USDC per week).\\n\",\"title\":\"ERC-20 spending Limits\",\"titles\":[\"Session Key Plugin overview\",\"Supported permissions\"]},{\"href\":\"/smart-contracts/session-keys#native-token-spending-limits\",\"html\":\"\\nSupports limiting how much of the native token, e.g. ETH or MATIC, a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).
\\n\",\"id\":\"pages/smart-contracts/session-keys/#native-token-spending-limits\",\"isPage\":false,\"text\":\"\\nSupports limiting how much of the native token, e.g. ETH or MATIC, a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).\\n\",\"title\":\"Native token spending limits\",\"titles\":[\"Session Key Plugin overview\",\"Supported permissions\"]},{\"href\":\"/smart-contracts/session-keys#gas-spending-limits\",\"html\":\"\\nSupports limiting how much of the native token (e.g. ETH or MATIC) a session key can spend on gas. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).
\\nAlternatively, you can also require that a session key uses a specific paymaster address, instead of spending the account’s native token for gas.
\\nNote that the gas limit is tracked in terms of native token units (wei), not in units of gas. The gas usage of a user operation is considered to be the maximum gas a user operation can spend, i.e. total gas limit * maxFeePerGas
. This can overestimate when compared to the actual gas cost of each user operation.
It is easy to get started with Light Account! We will show you how to create and send user operations for both LightAccount
and MultiOwnerLightAccount
using @alchemy/aa-alchemy
.
npm i @account-kit/smart-contracts
yarn add@account-kit/smart-contracts
The code snippets below demonstrate how to use LightAccount
and MultiOwnerLightAccount
with Account Kit. They create the account and send a UserOperation
from it.
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
import { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst lightAccountClient = await createMultiOwnerLightAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
It is possible to create wallets for users using just a passkey. This is useful for creating wallets for users if you don't want to go through the magic link flow.
\\n\\n\",\"id\":\"pages/signer/authentication/passkey-signup.mdx#passkey-signup\",\"isPage\":true,\"text\":\"\\nIt is possible to create wallets for users using just a passkey. This is useful for creating wallets for users if you don't want to go through the magic link flow.\\nIf you create a passkey without an email associated with the user, you risk your users losing access to their wallets if they lose their device.\\n\",\"title\":\"Passkey Signup\",\"titles\":[]},{\"href\":\"/signer/authentication/passkey-signup#authenticate-a-user-with-email-and-passkey\",\"html\":\"\\nIf you want to allow sign-up and login with a passkey, you can ask the user for an email to associate with their passkey. This way, they can log in with their email or passkey in the future. Under the hood, the email is also used to check if an account exists already so you can have a unified sign-up and login flow.
\\n\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\nconst result = await signer.authenticate({\\n type: "passkey",\\n email: "user@mail.com",\\n});
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\nconst result = await signer.authenticate({\\n type: "passkey",\\n createNew: true,\\n username: "SOME_USER_NAME_OR_PASSKEY_IDENTIFIER",\\n});
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
A Signer is a service (e.g. Magic or Turnkey) or application (e.g. MetaMask) that manages the private key and signs operations. Most web3 users today use an Externally Owned Account (EOA) with a self-custodial Signer such as MetaMask to manage the private key.
\\nWith Account Kit, you will deploy a smart account for each user instead of an EOA wallet. This smart account stores the user’s assets (e.g. tokens or NFTs).
\\nThe signer connected to the SmartAccountClient
is used to sign messages, data including user operations and transactions. The signatures for the user operation will be only valid and execute if the signer is the owner or one of the owners of the account.
You can choose any Signer service or application to manage the Owner private key for the user. Using services like Magic, Turnkey, or Web3auth, you can secure the user’s account with an email, social login, or passkeys. You can also use a self-custodial wallet like MetaMask as the Signer.
\\nThis doc provides a basic introduction to signers and the criteria you should consider when choosing which Signer to use with Account Kit in your application.
\\n\",\"id\":\"pages/signer/what-is-a-signer.mdx#what-is-a-signer\",\"isPage\":true,\"text\":\"\\nA Signer is a service (e.g. Magic or Turnkey) or application (e.g. MetaMask) that manages the private key and signs operations. Most web3 users today use an Externally Owned Account (EOA) with a self-custodial Signer such as MetaMask to manage the private key.\\nWith Account Kit, you will deploy a smart account for each user instead of an EOA wallet. This smart account stores the user’s assets (e.g. tokens or NFTs).\\nThe signer connected to the SmartAccountClient is used to sign messages, data including user operations and transactions. The signatures for the user operation will be only valid and execute if the signer is the owner or one of the owners of the account.\\nYou can choose any Signer service or application to manage the Owner private key for the user. Using services like Magic, Turnkey, or Web3auth, you can secure the user’s account with an email, social login, or passkeys. You can also use a self-custodial wallet like MetaMask as the Signer.\\nThis doc provides a basic introduction to signers and the criteria you should consider when choosing which Signer to use with Account Kit in your application.\\n\",\"title\":\"What is a Signer?\",\"titles\":[]},{\"href\":\"/signer/what-is-a-signer#role-of-a-signer\",\"html\":\"\\nThe Signer plays a crucial role in your app because it controls the user’s smart account. The Signer is responsible for:
\\nAccount Kit is compatible with any EIP-1193 provider. Many of the most popular signers can be configured in minutes through our integration signer guides.
\\nIf you want to use another Signer, you can integrate any other Signer by wrapping it in an EIP-1193 provider or using SmartAccountSigner
to adapt non-standard Signer.
Here are some important criteria to consider when choosing a Signer.
\\nNon-custodial wallet providers store private keys such that they cannot access the private key without the user’s involvement. For example, the user must provide a password or passkey that only they know in order to decrypt the private key stored by the provider. Users benefit from heightened security, while remaining in control of their private keys at all times. This is similar to a safety deposit box vault: the provider secures the bank vault but only the user has access to the individual safety deposit boxes (e.g. wallets).
\\nExample: Turnkey, Magic
\\n\",\"id\":\"pages/signer/what-is-a-signer.mdx#non-custodial-wallets\",\"isPage\":false,\"text\":\"\\nNon-custodial wallet providers store private keys such that they cannot access the private key without the user’s involvement. For example, the user must provide a password or passkey that only they know in order to decrypt the private key stored by the provider. Users benefit from heightened security, while remaining in control of their private keys at all times. This is similar to a safety deposit box vault: the provider secures the bank vault but only the user has access to the individual safety deposit boxes (e.g. wallets).\\nExample: Turnkey, Magic\\n\",\"title\":\"Non-custodial wallets\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]},{\"href\":\"/signer/what-is-a-signer#mpc-wallets-non-custodial\",\"html\":\"\\nMulti-Party Computation (MPC) Signers split the Owner Account private key into key shares that are then distributed to a number of share holders. Share holders only know the value of their key share and transaction holders can sign transactions without revealing their key shares to other holders.
\\nValid signatures do not always require all shares to sign a transaction. MPC Signers can set a threshold, requiring a certain number of shares for a signature to be valid. Common configurations are 2 of 2 shares or 2 of 3 shares. By requiring multiple shares, MPC models mitigate the risks associated with a single key being compromised.
\\nSome MPC signers provide recovery services in which key share(s) are backed up in the service provider’s cloud, on the end user’s device, or in the end user’s cloud (e.g. iCloud or Google Drive). When evaluating an MPC provider, it’s important to under where each key share is stored.
\\nExample: Privy, Fireblocks MPC, Portal, Capsule, WalletKit
\\nThere are two common approaches to MPC.
Traditionally, MPC services leveraged SSSS (Shamir’s Secret Shard Sharing). This approach generates a private key in one location and then the shares are distributed to the parties involved. When a user wants to sign, they need to retrieve N of M shares and reconstruct the key locally.
An improvement on SSSS is Threshold Signature Scheme (TSS). In this model, the key is never recreated during signing. Instead, each party is given the message to sign and then signs the payload locally before broadcasting the signature to the rest of the group. This allows for the key material to remain private and deconstructed.
TSS is safer than SSSS because is possible to create the initial shares without ever constructing the original key on any one device. However, the tradeoff is that signing requires a Peer-to-Peer exchange which introduces latency.
You can read more about the difference between TSS and SSSS here.\\nYou can read more about the difference between TSS and SSSS here.
A decentralized MPC network is an extension on the MPC approach outlined above. Instead of relying on a single, centralized service to store a key share and initiate signature requests, an MPC network distributes this responsibility across many nodes in a network. The user’s private key is split into many key shares with each share store by a different node. The user may request signatures from the network and a valid signature will be produced if and only if a threshold number of nodes agree to sign the request.
\\nExamples: Lit Protocol, Web3Auth (Torus Network)
\\n\",\"id\":\"pages/signer/what-is-a-signer.mdx#decentralized-mpc-network-non-custodial\",\"isPage\":false,\"text\":\"\\nA decentralized MPC network is an extension on the MPC approach outlined above. Instead of relying on a single, centralized service to store a key share and initiate signature requests, an MPC network distributes this responsibility across many nodes in a network. The user’s private key is split into many key shares with each share store by a different node. The user may request signatures from the network and a valid signature will be produced if and only if a threshold number of nodes agree to sign the request.\\nExamples: Lit Protocol, Web3Auth (Torus Network)\\n\",\"title\":\"Decentralized MPC network (non-custodial)\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]},{\"href\":\"/signer/what-is-a-signer#self-custodial-wallet\",\"html\":\"\\nSelf-custodial wallets store the private key locally where only the end user can access it. For example, the user may store their seed phrase in a browser extension, in a mobile app using their phone’s secure enclave, or in a hardware wallet. When using a self-custodial wallet, the user is the only one with the power to sign transactions.
\\nSelf-custodial wallets require the user to maintain good security hygiene at all times. They also rely on the user to backup a copy of their private key in the event the wallet is lost or destroyed. If the user loses access to the device on which their private key is stored, they will have no way to recover the account unless they backed up the private key in another device or location.
\\nExample: MetaMask, Ledger
\\n\",\"id\":\"pages/signer/what-is-a-signer.mdx#self-custodial-wallet\",\"isPage\":false,\"text\":\"\\nSelf-custodial wallets store the private key locally where only the end user can access it. For example, the user may store their seed phrase in a browser extension, in a mobile app using their phone’s secure enclave, or in a hardware wallet. When using a self-custodial wallet, the user is the only one with the power to sign transactions.\\nSelf-custodial wallets require the user to maintain good security hygiene at all times. They also rely on the user to backup a copy of their private key in the event the wallet is lost or destroyed. If the user loses access to the device on which their private key is stored, they will have no way to recover the account unless they backed up the private key in another device or location.\\nExample: MetaMask, Ledger\\n\",\"title\":\"Self-custodial wallet\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]},{\"href\":\"/signer/what-is-a-signer#custodial-wallet\",\"html\":\"\\nCustodial wallet providers have full control over the user’s private key and sign transactions on behalf of the user. These services typically implement security measures to ensure that only the authorized user(s) can request a signature. These providers are also typically regulated entities (e.g., qualified custodians). The user must trust this service provider to securely store the private key and sign transactions if and only if the user wishes.
\\nExample: Coinbase Custody, Bitgo
\\nDisclaimer: This page refers to third-party services, products software, technology, and content (collectively, “Third-Party Services”) that may be integrated or interact with Alchemy’s software and services. Alchemy is not responsible for any Third-Party Service, or for any compatibility issues, errors, or bugs caused in whole or in part by the Third-Party Service or any update or upgrade thereto. Your use of any Third-Party Service is at your own risk. You are responsible for obtaining any associated licenses and consents to the extent necessary for you to use the Third-Party Services. Your use of the Third-Party Services may be subject to separate terms and conditions set forth by the provider (including disclaimers or warnings), separate fees or charges, or a separate privacy notice. You are responsible for understanding and complying with any such terms or privacy notice.
\",\"id\":\"pages/signer/what-is-a-signer.mdx#custodial-wallet\",\"isPage\":false,\"text\":\"\\nCustodial wallet providers have full control over the user’s private key and sign transactions on behalf of the user. These services typically implement security measures to ensure that only the authorized user(s) can request a signature. These providers are also typically regulated entities (e.g., qualified custodians). The user must trust this service provider to securely store the private key and sign transactions if and only if the user wishes.\\nExample: Coinbase Custody, Bitgo\\n\\nDisclaimer: This page refers to third-party services, products software, technology, and content (collectively, “Third-Party Services”) that may be integrated or interact with Alchemy’s software and services. Alchemy is not responsible for any Third-Party Service, or for any compatibility issues, errors, or bugs caused in whole or in part by the Third-Party Service or any update or upgrade thereto. Your use of any Third-Party Service is at your own risk. You are responsible for obtaining any associated licenses and consents to the extent necessary for you to use the Third-Party Services. Your use of the Third-Party Services may be subject to separate terms and conditions set forth by the provider (including disclaimers or warnings), separate fees or charges, or a separate privacy notice. You are responsible for understanding and complying with any such terms or privacy notice.\",\"title\":\"Custodial wallet\",\"titles\":[\"What is a Signer?\",\"Types of Signers\"]}]}],[\"index.18d25d21beda261f0017b6dbd2c0079ed8d1b34a364603c29e6dacff65179014\",{\"mdx\":\"---\\ntitle: Modular Account • Deployments\\ndescription: Deployment addresses\\n---\\n\\n# Deployments\\n\\nThe following tables list the deployed factory and account implementation contract addresses for `ModularAccount` and some compatible plugins on different chains. Deployments for prior versions can be found in the [modular-account](https://github.com/alchemyplatform/modular-account/tree/develop/deployments) repo.\\n\\n## Account\\n\\n| Chain | Factory Address | Account Implementation |\\n| ---------------- | -------------------------------------------- | -------------------------------------------- |\\n| Eth Mainnet | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Eth Sepolia | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Polygon Mainnet | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Polygon Mumbai | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Polygon Amoy | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Optimism | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Optimism Sepolia | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Arbitrum | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Arbitrum Sepolia | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Base | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Base Sepolia | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Zora Mainnet | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Zora Sepolia | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Fraxtal Mainnet | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n| Fraxtal Sepolia | `0x000000e92D78D90000007F0082006FDA09BD5f11` | `0x0046000000000151008789797b54fdb500E2a61e` |\\n\\n## MultiOwnerPlugin\\n\\n| Chain | Plugin Address |\\n| ---------------- | -------------------------------------------- |\\n| Eth Mainnet | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Eth Sepolia | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Polygon Mainnet | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Polygon Mumbai | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Polygon Amoy | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Optimism | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Optimism Sepolia | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Arbitrum | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Arbitrum Sepolia | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Base | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Base Sepolia | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Zora Mainnet | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Zora Sepolia | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Fraxtal Mainnet | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n| Fraxtal Sepolia | `0xcE0000007B008F50d762D155002600004cD6c647` |\\n\\n## SessionKeyPlugin\\n\\n| Chain | Plugin Address |\\n| ---------------- | -------------------------------------------- |\\n| Eth Mainnet | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Eth Sepolia | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Polygon Mainnet | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Polygon Mumbai | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Polygon Amoy | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Optimism | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Optimism Sepolia | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Arbitrum | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Arbitrum Sepolia | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Base | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Base Sepolia | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Zora Mainnet | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Zora Sepolia | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Fraxtal Mainnet | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n| Fraxtal Sepolia | `0x0000003E0000a96de4058e1E02a62FaaeCf23d8d` |\\n\",\"document\":[{\"href\":\"/smart-contracts/modular-account/deployments#deployments\",\"html\":\"\\nThe following tables list the deployed factory and account implementation contract addresses for ModularAccount
and some compatible plugins on different chains. Deployments for prior versions can be found in the modular-account repo.
Chain | Factory Address | Account Implementation |
---|---|---|
Eth Mainnet | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Eth Sepolia | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Polygon Mainnet | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Polygon Mumbai | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Polygon Amoy | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Optimism | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Optimism Sepolia | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Arbitrum | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Arbitrum Sepolia | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Base | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Base Sepolia | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Zora Mainnet | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Zora Sepolia | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Fraxtal Mainnet | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Fraxtal Sepolia | 0x000000e92D78D90000007F0082006FDA09BD5f11 | 0x0046000000000151008789797b54fdb500E2a61e |
Chain | Plugin Address |
---|---|
Eth Mainnet | 0xcE0000007B008F50d762D155002600004cD6c647 |
Eth Sepolia | 0xcE0000007B008F50d762D155002600004cD6c647 |
Polygon Mainnet | 0xcE0000007B008F50d762D155002600004cD6c647 |
Polygon Mumbai | 0xcE0000007B008F50d762D155002600004cD6c647 |
Polygon Amoy | 0xcE0000007B008F50d762D155002600004cD6c647 |
Optimism | 0xcE0000007B008F50d762D155002600004cD6c647 |
Optimism Sepolia | 0xcE0000007B008F50d762D155002600004cD6c647 |
Arbitrum | 0xcE0000007B008F50d762D155002600004cD6c647 |
Arbitrum Sepolia | 0xcE0000007B008F50d762D155002600004cD6c647 |
Base | 0xcE0000007B008F50d762D155002600004cD6c647 |
Base Sepolia | 0xcE0000007B008F50d762D155002600004cD6c647 |
Zora Mainnet | 0xcE0000007B008F50d762D155002600004cD6c647 |
Zora Sepolia | 0xcE0000007B008F50d762D155002600004cD6c647 |
Fraxtal Mainnet | 0xcE0000007B008F50d762D155002600004cD6c647 |
Fraxtal Sepolia | 0xcE0000007B008F50d762D155002600004cD6c647 |
Chain | Plugin Address |
---|---|
Eth Mainnet | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Eth Sepolia | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Polygon Mainnet | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Polygon Mumbai | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Polygon Amoy | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Optimism | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Optimism Sepolia | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Arbitrum | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Arbitrum Sepolia | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Base | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Base Sepolia | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Zora Mainnet | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Zora Sepolia | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Fraxtal Mainnet | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
Fraxtal Sepolia | 0x0000003E0000a96de4058e1E02a62FaaeCf23d8d |
ERC-6900 Modular Accounts implements Plugin inspection interface IAccountLoupe.sol
to support visibility in plugin configuration on-chain. This contract interface defines the method getInstalledPlugins()
that clients can use to fetch the currently installed plugins on a Modular Account.
/// @notice Get an array of all installed plugins.\\n/// @return The addresses of all installed plugins.\\nfunction getInstalledPlugins() external view returns (address[] memory);
\\nAccount Kit provides a streamlined experience of interacting with Modular Account AccoutLoupe interface easily by providing accountLoupeActions
defined in @account-kit/smart-contracts
package. When you connect your Modular Account to SmartAccountClient
you can extend the client with accountLoupeActions
, which exposes a set of methods available to call the account AccountLoupe
with the client connected to the account.
You should first extend the SmartAcountClient
connected to a Modular Account, which has AccountLoupe
implemented, with accountLoupeActions
for the client to include the AccountLoupe
actions.
Then, you can use the getInstalledPlugins
method of the accountLoupeActions
extended smart account client to get the list of installed plugin addresses for the connected Modular Account.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\nimport { IPluginAbi } from "@account-kit/smart-contracts";\\n \\n// returns addresses of all installed plugins\\nconst installedPlugins = await modularAccountClient.getInstalledPlugins({});\\n \\nif (installedPlugins.length === 0) {\\n console.log("account has no plugins installed.");\\n return;\\n}\\n \\nconst pluginAddress = installedPlugins[0];\\n// read plugin metadata of a plugin\\nconst metadata = await modularAccountClient.readContract({\\n address: pluginAddress,\\n abi: IPluginAbi,\\n functionName: "pluginMetadata",\\n});\\n \\nconsole.log(JSON.stringify(metadata, null, 2));\\n// {\\n// name: 'MultiOwnerPlugin',\\n// version: '1.0.0',\\n// }
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});
By checking if a certain plugin address exists in the list of installed plugin addresses of a Modular Account, you can check whether a particular plugin is installed or not on a Modular Account.
\",\"id\":\"pages/smart-contracts/get-installed-plugins.mdx#get-installed-plugins-of-a-modular-account\",\"isPage\":false,\"text\":\"\\nYou should first extend the SmartAcountClient connected to a Modular Account, which has AccountLoupe implemented, with accountLoupeActions for the client to include the AccountLoupe actions.\\nThen, you can use the getInstalledPlugins method of the accountLoupeActions extended smart account client to get the list of installed plugin addresses for the connected Modular Account.\\nNoteWhen using createModularAccountAlchemyClient in @account-kit/smart-contracts, the SmartAccountClient comes automatically extended with multiOwnerPluginActions, pluginManagerActions, and accountLoupeActions decorators as defaults available for use.\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { modularAccountClient } from "./client";\\nimport { IPluginAbi } from "@account-kit/smart-contracts";\\n \\n// returns addresses of all installed plugins\\nconst installedPlugins = await modularAccountClient.getInstalledPlugins({});\\n \\nif (installedPlugins.length === 0) {\\n console.log("account has no plugins installed.");\\n return;\\n}\\n \\nconst pluginAddress = installedPlugins[0];\\n// read plugin metadata of a plugin\\nconst metadata = await modularAccountClient.readContract({\\n address: pluginAddress,\\n abi: IPluginAbi,\\n functionName: "pluginMetadata",\\n});\\n \\nconsole.log(JSON.stringify(metadata, null, 2));\\n// {\\n// name: 'MultiOwnerPlugin',\\n// version: '1.0.0',\\n// }import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nexport const chain = sepolia;\\n \\nexport const modularAccountClient = await createModularAccountAlchemyClient({\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n chain,\\n apiKey: "YOUR_API_KEY",\\n});\\nBy checking if a certain plugin address exists in the list of installed plugin addresses of a Modular Account, you can check whether a particular plugin is installed or not on a Modular Account.\",\"title\":\"Get installed plugins of a Modular Account\",\"titles\":[\"How to get the installed plugins of a Modular Account\"]}]}],[\"index.03f9ad9a09e3f3c345aa0107c4bedd24d1490d959193725c297deaa68ad28487\",{\"mdx\":\"---\\ntitle: Email Magic Link Authentication\\ndescription: Authenticate a user using an email magic link\\n---\\n\\n# Email Magic Link Authentication\\n\\nEmail magic link authentication allows you to login and signup users using an email address. Your users will receive a link in their inbox which will redirect them to your site (configured in the dashboard) to complete login.\\n\\n:::tip\\nFor setting up an account config, see the [Signer Quickstart](/signer/quickstart).\\n:::\\n\\n## Authenticate a user\\n\\n:::code-group\\n\\n```ts twoslash [example.ts]\\nimport { signer } from \\\"./signer\\\";\\n\\n// send the email\\nawait signer.authenticate({\\n type: \\\"email\\\",\\n email: \\\"user@mail.com\\\",\\n});\\n\\n// later once the user has clicked the link\\nconst url = new URL(window.location.href);\\nconst bundle = url.searchParams.get(\\\"bundle\\\");\\nif (!bundle) {\\n throw new Error(\\\"No bundle found in URL\\\");\\n}\\n\\nawait signer.authenticate({\\n type: \\\"email\\\",\\n bundle,\\n});\\n```\\n\\n```ts twoslash [signer] filename=\\\"signer.ts\\\"\\n// [!include ~/shared/signer/signer.ts]\\n```\\n\\n:::\\n\",\"document\":[{\"href\":\"/signer/authentication/email-magic-link#email-magic-link-authentication\",\"html\":\"\\nEmail magic link authentication allows you to login and signup users using an email address. Your users will receive a link in their inbox which will redirect them to your site (configured in the dashboard) to complete login.
\\n\\n\",\"id\":\"pages/signer/authentication/email-magic-link.mdx#email-magic-link-authentication\",\"isPage\":true,\"text\":\"\\nEmail magic link authentication allows you to login and signup users using an email address. Your users will receive a link in their inbox which will redirect them to your site (configured in the dashboard) to complete login.\\nFor setting up an account config, see the Signer Quickstart.\\n\",\"title\":\"Email Magic Link Authentication\",\"titles\":[]},{\"href\":\"/signer/authentication/email-magic-link#authenticate-a-user\",\"html\":\"\\n// @filename: signer.ts\\n \\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { signer } from "./signer";\\n \\n// send the email\\nawait signer.authenticate({\\n type: "email",\\n email: "user@mail.com",\\n});\\n \\n// later once the user has clicked the link\\nconst url = new URL(window.location.href);\\nconst bundle = url.searchParams.get("bundle");\\nif (!bundle) {\\n throw new Error("No bundle found in URL");\\n}\\n \\nawait signer.authenticate({\\n type: "email",\\n bundle,\\n});
import { AlchemyWebSigner } from "@account-kit/signer";\\n \\nexport const signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n apiKey: "API_KEY",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
The Alchemy Signer is a SmartAccountSigner
that is powered by Alchemy's Signer Infrastructure. Using the Alchemy Signer, you can get started building embedded accounts with just an Alchemy API key!
When using Account Kit with React via @account-kit/react
or @account-kit/core
, the assumption is that you're using the Alchemy Signer with our smart contract implementations and our Bundler and Gas Manager infrastructure.\\nHowever, you can also use the Alchemy Signer as a standalone signer with your own smart contracts or 3rd party infrastructure. In these guides, you'll learn more about how to choose a signer and how to use our signer directly via\\nthe @account-kit/signer
package to log users in with email auth, and create a embedded account with our signer to enable email, passkeys (i.e. biometrics), and soon social auth flows!
Creates a bundler client from an existing public client with the provided transport and chain.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClientFromExisting.mdx#createbundlerclientfromexisting\",\"isPage\":true,\"text\":\"\\nCreates a bundler client from an existing public client with the provided transport and chain.\\n\",\"title\":\"createBundlerClientFromExisting\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClientFromExisting#import\",\"html\":\"\\nimport { createBundlerClientFromExisting } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClientFromExisting.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createBundlerClientFromExisting } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"createBundlerClientFromExisting\"]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClientFromExisting#usage\",\"html\":\"\\nimport { createPublicClient } from "viem";\\nimport { createBundlerClientFromExisting } from "@aa-sdk/core";\\n \\nconst publicClient = createPublicClient(...);\\nconst bundlerClient = createBundlerClientFromExisting(publicClient);
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClientFromExisting.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createPublicClient } from "viem";\\nimport { createBundlerClientFromExisting } from "@aa-sdk/core";\\n \\nconst publicClient = createPublicClient(...);\\nconst bundlerClient = createBundlerClientFromExisting(publicClient);\\n\",\"title\":\"Usage\",\"titles\":[\"createBundlerClientFromExisting\"]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClientFromExisting#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClientFromExisting.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createBundlerClientFromExisting\"]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClientFromExisting#client\",\"html\":\"\\nPublicClient<T, Chain>
\\nThe existing public client to be extended with bundler actions
BundlerClient<T>
\\nA bundler client that extends the functionality of the provided public client
Builds a user operation using the provided client and operation parameters. Ensures that the account exists and the client is compatible.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperation.mdx#builduseroperation\",\"isPage\":true,\"text\":\"\\nBuilds a user operation using the provided client and operation parameters. Ensures that the account exists and the client is compatible.\\n\",\"title\":\"buildUserOperation\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperation#import\",\"html\":\"\\nimport { buildUserOperation } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperation.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { buildUserOperation } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"buildUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperation#usage\",\"html\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with buildUserOperation\\nconst client = createSmartAccountClient(...);\\nconst result = await client.buildUserOperation({\\nuo: {\\ntarget: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\n},\\naccount, // only required if the client above is not connected to an account\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperation.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with buildUserOperation\\nconst client = createSmartAccountClient(...);\\nconst result = await client.buildUserOperation({\\nuo: {\\ntarget: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\n},\\naccount, // only required if the client above is not connected to an account\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"buildUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperation#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperation.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"buildUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperation#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nthe client instance used to build the user operation
BuildUserOperationParameters<TAccount, TContext, TEntryPointVersion>
\\nthe parameters required to build the user operation, including account, overrides, and context
Promise<UserOperationStruct<TEntryPointVersion>>
\\na promise that resolves to a UserOperationStruct
object containing the built user operation details
Creates a Bundler Client using the provided configuration parameters, including chain and optional type.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClient.mdx#createbundlerclient\",\"isPage\":true,\"text\":\"\\nCreates a Bundler Client using the provided configuration parameters, including chain and optional type.\\n\",\"title\":\"createBundlerClient\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClient#import\",\"html\":\"\\nimport { createBundlerClient } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createBundlerClient } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"createBundlerClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClient#usage\",\"html\":\"\\nimport { createBundlerClient } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst client = createBundlerClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createBundlerClient } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst client = createBundlerClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createBundlerClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createBundlerClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createBundlerClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/createBundlerClient#args\",\"html\":\"\\nPublicClientConfig & { type?: string }
\\nConfiguration for creating the Bundler Client, including parameters for the chain, transport, and optional type
BundlerClient
\\nThe created Bundler Client with extended public and bundler actions
This function verifies the eligibility of the connected account for gas sponsorship concerning the upcoming UserOperation
(UO) that is intended to be sent.\\nInternally, this method invokes buildUserOperation
, which navigates through the middleware pipeline, including the PaymasterMiddleware
. Its purpose is to construct the UO struct meant for transmission to the bundler. Following the construction of the UO struct, this function verifies if the resulting structure contains a non-empty paymasterAndData
field.\\nYou can utilize this method before sending the user operation to confirm its eligibility for gas sponsorship. Depending on the outcome, it allows you to tailor the user experience accordingly, based on eligibility.
import { checkGasSponsorshipEligibility } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/checkGasSponsorshipEligibility.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { checkGasSponsorshipEligibility } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"checkGasSponsorshipEligibility\"]},{\"href\":\"/reference/aa-sdk/core/functions/checkGasSponsorshipEligibility#usage\",\"html\":\"\\nimport { smartAccountClient } from "./smartAccountClient";\\n\\nconst eligible = await smartAccountClient.checkGasSponsorshipEligibility({\\n uo: {\\n data: "0xCalldata",\\n target: "0xTarget",\\n value: 0n,\\n },\\n});\\n \\nconsole.log(\\n `User Operation is ${\\n eligible ? "eligible" : "ineligible"\\n } for gas sponsorship.`\\n);
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/checkGasSponsorshipEligibility.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { smartAccountClient } from "./smartAccountClient";\\n\\nconst eligible = await smartAccountClient.checkGasSponsorshipEligibility({\\n uo: {\\n data: "0xCalldata",\\n target: "0xTarget",\\n value: 0n,\\n },\\n});\\n \\nconsole.log(\\n `User Operation is ${\\n eligible ? "eligible" : "ineligible"\\n } for gas sponsorship.`\\n);\\n\",\"title\":\"Usage\",\"titles\":[\"checkGasSponsorshipEligibility\"]},{\"href\":\"/reference/aa-sdk/core/functions/checkGasSponsorshipEligibility#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/checkGasSponsorshipEligibility.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"checkGasSponsorshipEligibility\"]},{\"href\":\"/reference/aa-sdk/core/functions/checkGasSponsorshipEligibility#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nthe smart account client to use for making RPC calls
SendUserOperationParameters
\\ncontaining the user operation, account, context, and overrides
Promise<boolean>
\\na Promise containing a boolean indicating if the account is elgibile for sponsorship
A viem client decorator that provides Bundler specific actions.\\nThese actions include estimating gas for user operations, sending raw user operations, retrieving user operations by hash, getting supported entry points, and getting user operation receipts.
\\nNOTE: this is already added to the client returned from createBundlerClient
import { bundlerActions } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/bundlerActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { bundlerActions } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"bundlerActions\"]},{\"href\":\"/reference/aa-sdk/core/functions/bundlerActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/bundlerActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"bundlerActions\"]},{\"href\":\"/reference/aa-sdk/core/functions/bundlerActions#client\",\"html\":\"\\nTClient
\\nThe client instance that will be used to perform bundler actions
BundlerActions
\\nAn object containing various bundler-related actions that can be executed using the provided client
Converts a coin type to its corresponding blockchain chain based on a predefined mapping.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChain.mdx#convertcointypetochain\",\"isPage\":true,\"text\":\"\\nConverts a coin type to its corresponding blockchain chain based on a predefined mapping.\\n\",\"title\":\"convertCoinTypeToChain\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChain#import\",\"html\":\"\\nimport { convertCoinTypeToChain } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChain.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { convertCoinTypeToChain } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"convertCoinTypeToChain\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChain#usage\",\"html\":\"\\nimport { convertChainIdToCoinType, convertCoinTypeToChain } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst coinType = convertChainIdToCoinType(sepolia.id);\\nconst chain = convertCoinTypeToChain(coinType);
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChain.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { convertChainIdToCoinType, convertCoinTypeToChain } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst coinType = convertChainIdToCoinType(sepolia.id);\\nconst chain = convertCoinTypeToChain(coinType);\\n\",\"title\":\"Usage\",\"titles\":[\"convertCoinTypeToChain\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChain#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChain.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"convertCoinTypeToChain\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChain#cointype\",\"html\":\"\\nnumber
\\nThe numerical identifier for the coin type
Chain
\\nThe corresponding blockchain chain
Converts a given chain ID to a coin type, following specific standards for mainnet and non-mainnet chains.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertChainIdToCoinType.mdx#convertchainidtocointype\",\"isPage\":true,\"text\":\"\\nConverts a given chain ID to a coin type, following specific standards for mainnet and non-mainnet chains.\\n\",\"title\":\"convertChainIdToCoinType\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/convertChainIdToCoinType#import\",\"html\":\"\\nimport { convertChainIdToCoinType } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertChainIdToCoinType.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { convertChainIdToCoinType } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"convertChainIdToCoinType\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertChainIdToCoinType#usage\",\"html\":\"\\nimport { convertChainIdToCoinType } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst coinType = convertChainIdToCoinType(sepolia.id);
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertChainIdToCoinType.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { convertChainIdToCoinType } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst coinType = convertChainIdToCoinType(sepolia.id);\\n\",\"title\":\"Usage\",\"titles\":[\"convertChainIdToCoinType\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertChainIdToCoinType#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertChainIdToCoinType.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"convertChainIdToCoinType\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertChainIdToCoinType#chainid\",\"html\":\"\\nnumber
\\nthe blockchain chain ID that you want to convert to a coin type
number
\\nthe corresponding coin type for the given chain ID
Recursively converts all values in an object to hex strings
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/deepHexlify.mdx#deephexlify\",\"isPage\":true,\"text\":\"\\nRecursively converts all values in an object to hex strings\\n\",\"title\":\"deepHexlify\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/deepHexlify#import\",\"html\":\"\\nimport { deepHexlify } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/deepHexlify.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { deepHexlify } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"deepHexlify\"]},{\"href\":\"/reference/aa-sdk/core/functions/deepHexlify#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/deepHexlify.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"deepHexlify\"]},{\"href\":\"/reference/aa-sdk/core/functions/deepHexlify#obj\",\"html\":\"\\nany
any
\\nobject with all of its values hexlified
Performs buildUserOperationFromTx
in batch and builds into a single, yet to be signed UserOperation
(UO) struct. The output user operation struct will be filled with all gas fields (and paymaster data if a paymaster is used) based on the transactions data (to
, data
, value
, maxFeePerGas
, maxPriorityFeePerGas
) computed using the configured ClientMiddlewares
on the SmartAccountClient
import { buildUserOperationFromTx } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperationFromTx.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { buildUserOperationFromTx } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"buildUserOperationFromTx\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperationFromTx#usage\",\"html\":\"\\nimport type { RpcTransactionRequest } from "viem";\\nimport { smartAccountClient } from "./smartAccountClient";\\n\\n// buildUserOperationFromTx converts a traditional Ethereum transaction and returns\\n// the unsigned user operation struct after constructing the user operation struct\\n// through the middleware pipeline\\nconst tx: RpcTransactionRequest = {\\nfrom, // ignored\\nto,\\ndata: encodeFunctionData({\\nabi: ContractABI.abi,\\nfunctionName: "func",\\nargs: [arg1, arg2, ...],\\n}),\\n};\\nconst uoStruct = await smartAccountClient.buildUserOperationFromTx(tx);\\n \\n// signUserOperation signs the above unsigned user operation struct built\\n// using the account connected to the smart account client\\nconst request = await smartAccountClient.signUserOperation({ uoStruct });\\n \\n// You can use the BundlerAction `sendRawUserOperation` (packages/core/src/actions/bundler/sendRawUserOperation.ts)\\n// to send the signed user operation request to the bundler, requesting the bundler to send the signed uo to the\\n// EntryPoint contract pointed at by the entryPoint address parameter\\nconst entryPointAddress = client.account.getEntryPoint().address;\\nconst uoHash = await smartAccountClient.sendRawUserOperation({ request, entryPoint: entryPointAddress });
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperationFromTx.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport type { RpcTransactionRequest } from "viem";\\nimport { smartAccountClient } from "./smartAccountClient";\\n\\n// buildUserOperationFromTx converts a traditional Ethereum transaction and returns\\n// the unsigned user operation struct after constructing the user operation struct\\n// through the middleware pipeline\\nconst tx: RpcTransactionRequest = {\\nfrom, // ignored\\nto,\\ndata: encodeFunctionData({\\nabi: ContractABI.abi,\\nfunctionName: "func",\\nargs: [arg1, arg2, ...],\\n}),\\n};\\nconst uoStruct = await smartAccountClient.buildUserOperationFromTx(tx);\\n \\n// signUserOperation signs the above unsigned user operation struct built\\n// using the account connected to the smart account client\\nconst request = await smartAccountClient.signUserOperation({ uoStruct });\\n \\n// You can use the BundlerAction `sendRawUserOperation` (packages/core/src/actions/bundler/sendRawUserOperation.ts)\\n// to send the signed user operation request to the bundler, requesting the bundler to send the signed uo to the\\n// EntryPoint contract pointed at by the entryPoint address parameter\\nconst entryPointAddress = client.account.getEntryPoint().address;\\nconst uoHash = await smartAccountClient.sendRawUserOperation({ request, entryPoint: entryPointAddress });\\n\",\"title\":\"Usage\",\"titles\":[\"buildUserOperationFromTx\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperationFromTx#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperationFromTx.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"buildUserOperationFromTx\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperationFromTx#client\",\"html\":\"\\nClient<Transport, TChain, TAccount>
\\nthe smart account client to use for RPC requests
SendTransactionParameters
\\nthe send tx parameters
UserOperationOverrides
\\noptional overrides to use for any of the fields
TContext
\\nif the smart account client requires additinoal context for building UOs
Promise<UserOperationStruct<TEntryPointVersion>>
\\na Promise containing the built user operation
In the usage guide, for a threshold of k
signatures, we obtain the first signature with proposeUserOperation
and the next k-2
signatures with signMultisigUserOperation
. In practice, since signers would likely use different clients and sign at different times, the client or dapp will need to store the first k-1
signatures. This would be loaded and combined with the final signature to be used with sendUserOperation
.
Gas estimations must be performed for user operations before the first signature is obtained. This is done in aa-sdk with built in gas and fee estimation middlewares.
\\nWe perform gas estimation assuming that the k
signatures to be obtained are EOAs, and not other smart accounts. In the case that smart accounts own a modular account, the validation step could require more gas. If used with default gas estimation, it would cause the user operation to fail with an insufficient gas error.
In these cases, clients are expected to implement their own gas estimations for the signature validation step, and use gas overrides when first calling proposeUserOperation
.
For normal User Operations, gas prices and values have to be decided before the first signer's signature (and the paymaster's signature, if used). However, since it might take time to gather the k
signatures, it is likely that when the k
th signature is collected, the network gas values would have changed significantly. In this case, the account would be overpaying on gas, or the User Operation would be underpriced, and the k
signatures have to be collected again on a new User Operation.
This multisig plugin includes a variable gas feature to address this problem. The fee values selected and signed over by the first k-1
signers are treated as a "maximum fee" and the k
th signer is able to choose final fee values to use based on the current network conditions. With this feature, there is no longer a risk of overpaying, or having to re-collect the k
signatures.
However, note that the use of this feature would likely not work with regular paymaster services, including Alchemy's Gas Manager product.
\",\"id\":\"pages/smart-contracts/modular-account/multisig-plugin/details.mdx#variable-gas-feature\",\"isPage\":false,\"text\":\"\\nFor normal User Operations, gas prices and values have to be decided before the first signer's signature (and the paymaster's signature, if used). However, since it might take time to gather the k signatures, it is likely that when the kth signature is collected, the network gas values would have changed significantly. In this case, the account would be overpaying on gas, or the User Operation would be underpriced, and the k signatures have to be collected again on a new User Operation.\\nThis multisig plugin includes a variable gas feature to address this problem. The fee values selected and signed over by the first k-1 signers are treated as a "maximum fee" and the kth signer is able to choose final fee values to use based on the current network conditions. With this feature, there is no longer a risk of overpaying, or having to re-collect the k signatures.\\nHowever, note that the use of this feature would likely not work with regular paymaster services, including Alchemy's Gas Manager product.\",\"title\":\"Variable Gas Feature\",\"titles\":[\"Multisig Plugin Technical Details\"]}]}],[\"index.167c9755beb47826efa85f00f525870faa942c4ad5aa3a20ca4df888c6220d7a\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: allEqual\\ndescription: Overview of the allEqual method\\n---\\n\\n# allEqual\\n\\nUtility method for checking if the passed in values are all equal (strictly)\\n\\n## Import\\n\\n```ts\\nimport { allEqual } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Parameters\\n\\n### params\\n\\n`...any[]`\\n\\n- values to check\\n\\n## Returns\\n\\n`boolean`\\na boolean indicating if all values are the same\\n\",\"document\":[{\"href\":\"/reference/aa-sdk/core/functions/allEqual#allequal\",\"html\":\"\\nUtility method for checking if the passed in values are all equal (strictly)
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/allEqual.mdx#allequal\",\"isPage\":true,\"text\":\"\\nUtility method for checking if the passed in values are all equal (strictly)\\n\",\"title\":\"allEqual\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/allEqual#import\",\"html\":\"\\nimport { allEqual } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/allEqual.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { allEqual } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"allEqual\"]},{\"href\":\"/reference/aa-sdk/core/functions/allEqual#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/allEqual.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"allEqual\"]},{\"href\":\"/reference/aa-sdk/core/functions/allEqual#params\",\"html\":\"\\n...any[]
boolean
\\na boolean indicating if all values are the same
Converts a coin type to a chain ID based on predefined mappings. This function follows ENSIP-9 for coin type 60 and ENSIP-11 for other coin types.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChainId.mdx#convertcointypetochainid\",\"isPage\":true,\"text\":\"\\nConverts a coin type to a chain ID based on predefined mappings. This function follows ENSIP-9 for coin type 60 and ENSIP-11 for other coin types.\\n\",\"title\":\"convertCoinTypeToChainId\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChainId#import\",\"html\":\"\\nimport { convertCoinTypeToChainId } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChainId.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { convertCoinTypeToChainId } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"convertCoinTypeToChainId\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChainId#usage\",\"html\":\"\\nimport {\\n convertChainIdToCoinType,\\n convertCoinTypeToChainId,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst coinType = convertChainIdToCoinType(sepolia.id);\\nconst chainId = convertCoinTypeToChainId(coinType);
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChainId.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport {\\n convertChainIdToCoinType,\\n convertCoinTypeToChainId,\\n} from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst coinType = convertChainIdToCoinType(sepolia.id);\\nconst chainId = convertCoinTypeToChainId(coinType);\\n\",\"title\":\"Usage\",\"titles\":[\"convertCoinTypeToChainId\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChainId#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/convertCoinTypeToChainId.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"convertCoinTypeToChainId\"]},{\"href\":\"/reference/aa-sdk/core/functions/convertCoinTypeToChainId#cointype\",\"html\":\"\\nnumber
\\nthe coin type to be converted to a chain ID
number
\\nthe corresponding chain ID
Initialize a Multisig Modular Account client and set the n
accounts as signers.
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});
\\n\",\"id\":\"pages/smart-contracts/modular-account/multisig-plugin/getting-started.mdx#1-create-a-multisig-account-client\",\"isPage\":false,\"text\":\"\\nInitialize a Multisig Modular Account client and set the n accounts as signers.\\nIt is recommended to use the createMultisigAccountAlchemyClient directly to create new accounts with multi-sig ownership, rather than extending the Modular Account client.If you have an existing Modular Account (which has multi-owner plugin by default), please see details here for installing the plugin before proceeding.\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n\",\"title\":\"1. Create a Multisig Account Client\",\"titles\":[\"Getting started with the Multisig Plugin\"]},{\"href\":\"/smart-contracts/modular-account/multisig-plugin/getting-started#3-propose-a-user-operation\",\"html\":\"\\nTo propose a new user operation for review by the multisig signers, you will use the proposeUserOperation
method. This estimates gas, constructs the user operation struct, and if gasManagerConfig
is used then it attempts to use a paymaster. Lastly, a signature is generated with the pre-provided signer.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { multisigAccountClient } from "./client";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst {\\n request,\\n aggregatedSignature,\\n signatureObj: firstSig,\\n} = await multisigAccountClient.proposeUserOperation({\\n uo: {\\n target: targetAddress,\\n data: "0x",\\n },\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});
Next, you have to collect the next k-2 signatures, excluding the first signature which you already provided and the last signature which we'll deal with in step 5 when we send the user operation. Each member of the multisig can sign with the signMultisigUserOperation
method.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { signers, owners, threshold } from "./client";\\n \\nconst multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain,\\n signer: signers[1], // using the second signer\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n \\nconst { aggregatedSignature, signatureObj: secondSig } =\\n await multisigAccountClient.signMultisigUserOperation({\\n account: multisigAccountClient.account,\\n // output from step 1, and from this step if k-2 > 1\\n signatures: [previousAggregatedSignature],\\n userOperationRequest: request,\\n });
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});
After collecting k-1 signatures, you're ready to collect the last signature and send the user operation. This is done with the sendUserOperation
method. sendUserOperation
also formats this aggregated signature, sorting its parts in ascending order by owner address as expected by the Multisig Plugin smart contract.
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { signers, owners, threshold } from "./client";\\n \\nconst multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain,\\n // using the last signer\\n signer: signers[2],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n \\nconst result = await multisigAccountClient.sendUserOperation({\\n uo: request.callData,\\n context: {\\n aggregatedSignature,\\n signatures: [firstSig, secondSig],\\n userOpSignatureType: "ACTUAL",\\n },\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});
By default, we use the variable gas feature in the Multisig Plugin smart contract. For this, we need userOpSignatureType
to be set to "ACTUAL". If you do not wish to use this feature, gas overrides should be passed in sendUserOperation
, and userOpSignatureType
should be set to "UPPERLIMIT".
// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: client.ts\\n \\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});\\n// @filename: example.js\\n \\n// ---cut---\\nimport { multisigAccountClient } from "./client";\\n \\nconst result = await multisigAccountClient.sendUserOperation({\\n uo: request.callData,\\n overrides: {\\n callGasLimit: request.callGasLimit,\\n verificationGasLimit: request.verificationGasLimit,\\n preVerificationGas: request.preVerificationGas,\\n maxFeePerGas: request.maxFeePerGas,\\n maxPriorityFeePerGas: request.maxPriorityFeePerGas,\\n },\\n context: {\\n aggregatedSignature,\\n signatures: [firstSig, secondSig],\\n userOpSignatureType: "UPPERLIMIT",\\n },\\n});
import { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC = "YOUR MNEMONIC";\\n \\n// Creating a 3/3 multisig account\\nexport const signers = [\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 0 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 1 }\\n ),\\n LocalAccountSigner.mnemonicToAccountSigner(\\n MODULAR_MULTISIG_ACCOUNT_OWNER_MNEMONIC,\\n { accountIndex: 2 }\\n ),\\n];\\n \\nexport const threshold = 3n;\\n \\nexport const owners = await Promise.all(signers.map((s) => s.getAddress()));\\n \\nexport const multisigAccountClient = await createMultisigAccountAlchemyClient({\\n chain: sepolia,\\n signer: signers[0],\\n owners,\\n threshold,\\n apiKey: "YOUR_API_KEY",\\n});
That's it! You've initialized a modular account with three multisig members, proposed a user operation, collected the necessary signatures, and sent the user operation to the bundler.
\\nFor more info, check out the technical details of the multisig plugin.
\",\"id\":\"pages/smart-contracts/modular-account/multisig-plugin/getting-started.mdx#conclusion\",\"isPage\":false,\"text\":\"\\nThat's it! You've initialized a modular account with three multisig members, proposed a user operation, collected the necessary signatures, and sent the user operation to the bundler.\\nFor more info, check out the technical details of the multisig plugin.\",\"title\":\"Conclusion\",\"titles\":[\"Getting started with the Multisig Plugin\"]}]}],[\"index.ddcd7910de3f0c24f73be6c3b1cc05803b1dd01ab18862a5bd68e6b2563ee25f\",{\"mdx\":\"---\\ntitle: TODO\\ndescription: TODO\\n---\\n\\nTODO: this should also be autogenerated and just inherit from the README for the given package.\\n\",\"document\":[]}],[\"index.7a0ee5f536f76e43aa5b9e3ac228a84c96b07c0abeeaa471ab482b2d6a68c305\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: asyncPipe\\ndescription: Overview of the asyncPipe method\\n---\\n\\n# asyncPipe\\n\\nUtility function that allows for piping a series of async functions together\\n\\n## Import\\n\\n```ts\\nimport { asyncPipe } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Parameters\\n\\n### fns\\n\\n`((s: S, o?: O, f?: F) => PromiseUtility function that allows for piping a series of async functions together
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/asyncPipe.mdx#asyncpipe\",\"isPage\":true,\"text\":\"\\nUtility function that allows for piping a series of async functions together\\n\",\"title\":\"asyncPipe\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/asyncPipe#import\",\"html\":\"\\nimport { asyncPipe } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/asyncPipe.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { asyncPipe } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"asyncPipe\"]},{\"href\":\"/reference/aa-sdk/core/functions/asyncPipe#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/asyncPipe.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"asyncPipe\"]},{\"href\":\"/reference/aa-sdk/core/functions/asyncPipe#fns\",\"html\":\"\\n((s: S, o?: O, f?: F) => Promise<S>)[]
S
\\nresult of the pipe
Performs buildUserOperationFromTx
in batch and builds into a single,\\nyet to be signed UserOperation
(UO) struct. The output user operation struct\\nwill be filled with all gas fields (and paymaster data if a paymaster is used)\\nbased on the transactions data (to
, data
, value
, maxFeePerGas
,\\nmaxPriorityFeePerGas
) computed using the configured ClientMiddlewares on the SmartAccountClient.
import { buildUserOperationFromTxs } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperationFromTxs.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { buildUserOperationFromTxs } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"buildUserOperationFromTxs\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperationFromTxs#usage\",\"html\":\"\\nimport type { RpcTransactionRequest } from "viem";\\nimport { smartAccountClient } from "./smartAccountClient";\\n \\nconst requests: RpcTransactionRequest[] = [\\n{\\nfrom, // ignored\\nto,\\ndata: encodeFunctionData({\\n abi: ContractABI.abi,\\n functionName: "func",\\n args: [arg1, arg2, ...],\\n}),\\n},\\n{\\nfrom, // ignored\\nto,\\ndata: encodeFunctionData({\\n abi: ContractABI.abi,\\n functionName: "func",\\n args: [arg1, arg2, ...],\\n}),\\n},\\n];\\nconst uoStruct = await smartAccountClient.buildUserOperationFromTxs({\\nrequests,\\n});\\n \\n// signUserOperation signs the above unsigned user operation struct built\\n// using the account connected to the smart account client\\nconst request = await smartAccountClient.signUserOperation({ uoStruct });\\n \\n// You can use the BundlerAction `sendRawUserOperation` (packages/core/src/actions/bundler/sendRawUserOperation.ts)\\n// to send the signed user operation request to the bundler, requesting the bundler to send the signed uo to the\\n// EntryPoint contract pointed at by the entryPoint address parameter\\nconst entryPointAddress = client.account.getEntryPoint().address;\\nconst uoHash = await smartAccountClient.sendRawUserOperation({\\nrequest,\\nentryPoint: entryPointAddress,\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperationFromTxs.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport type { RpcTransactionRequest } from "viem";\\nimport { smartAccountClient } from "./smartAccountClient";\\n \\nconst requests: RpcTransactionRequest[] = [\\n{\\nfrom, // ignored\\nto,\\ndata: encodeFunctionData({\\n abi: ContractABI.abi,\\n functionName: "func",\\n args: [arg1, arg2, ...],\\n}),\\n},\\n{\\nfrom, // ignored\\nto,\\ndata: encodeFunctionData({\\n abi: ContractABI.abi,\\n functionName: "func",\\n args: [arg1, arg2, ...],\\n}),\\n},\\n];\\nconst uoStruct = await smartAccountClient.buildUserOperationFromTxs({\\nrequests,\\n});\\n \\n// signUserOperation signs the above unsigned user operation struct built\\n// using the account connected to the smart account client\\nconst request = await smartAccountClient.signUserOperation({ uoStruct });\\n \\n// You can use the BundlerAction `sendRawUserOperation` (packages/core/src/actions/bundler/sendRawUserOperation.ts)\\n// to send the signed user operation request to the bundler, requesting the bundler to send the signed uo to the\\n// EntryPoint contract pointed at by the entryPoint address parameter\\nconst entryPointAddress = client.account.getEntryPoint().address;\\nconst uoHash = await smartAccountClient.sendRawUserOperation({\\nrequest,\\nentryPoint: entryPointAddress,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"buildUserOperationFromTxs\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperationFromTxs#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/buildUserOperationFromTxs.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"buildUserOperationFromTxs\"]},{\"href\":\"/reference/aa-sdk/core/functions/buildUserOperationFromTxs#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nthe smart account client to use to make RPC calls
BuildTransactionParameters
\\nan object containing the requests to build as well as, the account if not hoisted, the context, the overrides, and optionally a flag to enable signing of the UO via the underlying middleware
Promise<BuildUserOperationFromTransactionsResult<TEntryPointVersion>>
\\na Promise containing the built user operation
Creates a smart account client using the provided configuration. This client handles various Ethereum transactions and message signing operations.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClient.mdx#createsmartaccountclient\",\"isPage\":true,\"text\":\"\\nCreates a smart account client using the provided configuration. This client handles various Ethereum transactions and message signing operations.\\n\",\"title\":\"createSmartAccountClient\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClient#import\",\"html\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"createSmartAccountClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClient#usage\",\"html\":\"\\nimport { createSmartAccountClient, toSmartContractAccount } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst client = createSmartAccountClient({\\nchain: sepolia,\\ntransport: http("RPC_URL"),\\n// optionally hoist the account\\naccount: toSmartContractAccount(...),\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient, toSmartContractAccount } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst client = createSmartAccountClient({\\nchain: sepolia,\\ntransport: http("RPC_URL"),\\n// optionally hoist the account\\naccount: toSmartContractAccount(...),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createSmartAccountClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createSmartAccountClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClient#config\",\"html\":\"\\nSmartAccountClientConfig
\\nThe configuration for creating the smart account client
SmartAccountClient
\\nA smart account client capable of handling transactions, message signing, and other operations on a smart account
Default fee estimator middleware function that estimates the maximum fee per gas and maximum priority fee per gas for a given client and applies the necessary overrides and fee options.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultFeeEstimator.mdx#defaultfeeestimator\",\"isPage\":true,\"text\":\"\\nDefault fee estimator middleware function that estimates the maximum fee per gas and maximum priority fee per gas for a given client and applies the necessary overrides and fee options.\\n\",\"title\":\"defaultFeeEstimator\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/defaultFeeEstimator#import\",\"html\":\"\\nimport { defaultFeeEstimator } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultFeeEstimator.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { defaultFeeEstimator } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"defaultFeeEstimator\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultFeeEstimator#usage\",\"html\":\"\\nimport { createSmartAccountClient, defaultFeeEstimator, createBundlerClient } from "@aa-sdk/core";\\n \\nconst bundlerClient = createBundlerClient(...);\\n \\n// NOTE: this is already provided by the smart account client\\nconst client = createSmartAccountClient({\\nfeeEstimator: defaultFeeEstimator(bundlerClient),\\n...otherParams\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultFeeEstimator.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient, defaultFeeEstimator, createBundlerClient } from "@aa-sdk/core";\\n \\nconst bundlerClient = createBundlerClient(...);\\n \\n// NOTE: this is already provided by the smart account client\\nconst client = createSmartAccountClient({\\nfeeEstimator: defaultFeeEstimator(bundlerClient),\\n...otherParams\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"defaultFeeEstimator\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultFeeEstimator#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultFeeEstimator.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"defaultFeeEstimator\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultFeeEstimator#client\",\"html\":\"\\nC
\\nThe client to perform the fee estimation
ClientMiddlewareFn
\\nA middleware function that takes in the struct and options, estimates the fees, and updates the struct with the estimated fees
Provides a default middleware function for signing user operations with a client account. This function validates the request and adds the signature to it.\\nThis is already included in the client returned from createSmartAccountClient
import { defaultUserOpSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultUserOpSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { defaultUserOpSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"defaultUserOpSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultUserOpSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultUserOpSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"defaultUserOpSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultUserOpSigner#struct\",\"html\":\"\\nUserOperationStruct
\\nThe user operation structure to be signed
*
\\nThe middleware context containing the client and account information
Client
\\nThe client object, which should include account and chain information
Account
\\nOptional, the account used for signing, defaults to the client's account if not provided
Promise<UserOperationStruct>
\\nA promise that resolves to the signed user operation structure
Description default gas estimator middleware for SmartAccountClient
\\nYou can override this middleware with your custom gas estimator middleware\\nby passing it to the client constructor
import { defaultGasEstimator } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultGasEstimator.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { defaultGasEstimator } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"defaultGasEstimator\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultGasEstimator#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultGasEstimator.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"defaultGasEstimator\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultGasEstimator#client\",\"html\":\"\\nMiddlewareClient
\\nsmart account client instance to apply the middleware to
ClientMiddlewareFn
\\nmiddleware execution function used to estimate gas for user operations
Creates a smart account client using an existing client and specific configuration. This function can be used to reuse a pre-existing BundlerClient while customizing other aspects of the smart account.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting.mdx#createsmartaccountclientfromexisting\",\"isPage\":true,\"text\":\"\\nCreates a smart account client using an existing client and specific configuration. This function can be used to reuse a pre-existing BundlerClient while customizing other aspects of the smart account.\\n\",\"title\":\"createSmartAccountClientFromExisting\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting#import\",\"html\":\"\\nimport { createSmartAccountClientFromExisting } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClientFromExisting } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"createSmartAccountClientFromExisting\"]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting#usage\",\"html\":\"\\nimport {\\ncreateBundlerClient,\\ncreateSmartAccountClientFromExisting,\\ntoSmartContractAccount\\n} from "@aa-sdk/core";\\n \\nconst bundlerClient = createBundlerClient(...);\\nconst client = createSmartAccountClientFromExisting({\\nclient,\\naccount: toSmartContractAccount(...),\\n})
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport {\\ncreateBundlerClient,\\ncreateSmartAccountClientFromExisting,\\ntoSmartContractAccount\\n} from "@aa-sdk/core";\\n \\nconst bundlerClient = createBundlerClient(...);\\nconst client = createSmartAccountClientFromExisting({\\nclient,\\naccount: toSmartContractAccount(...),\\n})\\n\",\"title\":\"Usage\",\"titles\":[\"createSmartAccountClientFromExisting\"]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createSmartAccountClientFromExisting\"]},{\"href\":\"/reference/aa-sdk/core/functions/createSmartAccountClientFromExisting#config\",\"html\":\"\\nOmit<SmartAccountClientConfig, "transport" | "chain"> & {client: BundlerClient}
\\nthe configuration object which includes the client
SmartAccountClient
\\nA smart account client created from the existing BundlerClient
Middleware function that sets the paymasterAndData
field in the given struct based on the entry point version of the account.\\nThis is the default used by createSmartAccountClient
and is not necessary to be used directly.
import { defaultPaymasterAndData } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultPaymasterAndData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { defaultPaymasterAndData } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"defaultPaymasterAndData\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultPaymasterAndData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/defaultPaymasterAndData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"defaultPaymasterAndData\"]},{\"href\":\"/reference/aa-sdk/core/functions/defaultPaymasterAndData#struct\",\"html\":\"\\nUserOperationStruct
\\nthe user operation structure to be modified
{ account: Account }
\\nan object containing the account information
Promise<UserOperationStruct>
\\na promise that resolves to the modified user operation structure
Drops an existing user operation and replaces it with a new one while ensuring the appropriate fees and overrides are applied.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/dropAndReplaceUserOperation.mdx#dropandreplaceuseroperation\",\"isPage\":true,\"text\":\"\\nDrops an existing user operation and replaces it with a new one while ensuring the appropriate fees and overrides are applied.\\n\",\"title\":\"dropAndReplaceUserOperation\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/dropAndReplaceUserOperation#import\",\"html\":\"\\nimport { dropAndReplaceUserOperation } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/dropAndReplaceUserOperation.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { dropAndReplaceUserOperation } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"dropAndReplaceUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/dropAndReplaceUserOperation#usage\",\"html\":\"\\nimport {\\ncreateSmartAccountClient,\\n} from "@aa-sdk/core";\\n \\n// smart account client is already extended with dropAndReplaceUserOperation\\nconst client = createSmartAccountClient(...);\\nconst { request } = await client.sendUserOperation(...);\\nconst result = await client.dropAndReplaceUserOperation({\\nuoToDrop: request,\\naccount, // only required if the client above is not connected to an account\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/dropAndReplaceUserOperation.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport {\\ncreateSmartAccountClient,\\n} from "@aa-sdk/core";\\n \\n// smart account client is already extended with dropAndReplaceUserOperation\\nconst client = createSmartAccountClient(...);\\nconst { request } = await client.sendUserOperation(...);\\nconst result = await client.dropAndReplaceUserOperation({\\nuoToDrop: request,\\naccount, // only required if the client above is not connected to an account\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"dropAndReplaceUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/dropAndReplaceUserOperation#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/dropAndReplaceUserOperation.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"dropAndReplaceUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/dropAndReplaceUserOperation#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance with the transport, chain, and account information
DropAndReplaceUserOperationParameters<TAccount, TContext>
\\nThe parameters required for dropping and replacing the user operation including the account, operation to drop, overrides, and context
Promise<SendUserOperationResult<TEntryPointVersion>>
\\nA promise that resolves to the result of sending the new user operation
Middleware function for interacting with ERC-7677 enabled clients. It supports resolving paymaster and data fields for user operations.\\nThis middleware assumes that your RPC provider supports the ERC-7677 methods (pm_getPaymasterStubData and pm_getPaymasterData).
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/erc7677Middleware.mdx#erc7677middleware\",\"isPage\":true,\"text\":\"\\nMiddleware function for interacting with ERC-7677 enabled clients. It supports resolving paymaster and data fields for user operations.\\nThis middleware assumes that your RPC provider supports the ERC-7677 methods (pm_getPaymasterStubData and pm_getPaymasterData).\\n\",\"title\":\"erc7677Middleware\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/erc7677Middleware#import\",\"html\":\"\\nimport { erc7677Middleware } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/erc7677Middleware.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { erc7677Middleware } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"erc7677Middleware\"]},{\"href\":\"/reference/aa-sdk/core/functions/erc7677Middleware#usage\",\"html\":\"\\nimport { createSmartAccountClient, erc7677Middleware } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst client = createSmartAccountClient({\\n transport: http("rpc-url"),\\n chain: sepolia,\\n // this assumes that your RPC provider supports the ERC-7677 methods AND takes no context\\n ...erc7677Middleware(),\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/erc7677Middleware.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient, erc7677Middleware } from "@aa-sdk/core";\\nimport { http } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst client = createSmartAccountClient({\\n transport: http("rpc-url"),\\n chain: sepolia,\\n // this assumes that your RPC provider supports the ERC-7677 methods AND takes no context\\n ...erc7677Middleware(),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"erc7677Middleware\"]},{\"href\":\"/reference/aa-sdk/core/functions/erc7677Middleware#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/erc7677Middleware.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"erc7677Middleware\"]},{\"href\":\"/reference/aa-sdk/core/functions/erc7677Middleware#params\",\"html\":\"\\nErc7677MiddlewareParams<TContext>
\\nMiddleware parameters including context function or object. Context can be resolved dynamically by passing in a function which takes in the context at the time of sending a user op
Pick<ClientMiddlewareConfig, "dummyPaymasterAndData" | "paymasterAndData">
\\nAn object containing middleware functions dummyPaymasterAndData
and paymasterAndData
for processing user operations with the paymaster data
Filters out properties with undefined or null values from the provided object.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/filterUndefined.mdx#filterundefined\",\"isPage\":true,\"text\":\"\\nFilters out properties with undefined or null values from the provided object.\\n\",\"title\":\"filterUndefined\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/filterUndefined#import\",\"html\":\"\\nimport { filterUndefined } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/filterUndefined.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { filterUndefined } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"filterUndefined\"]},{\"href\":\"/reference/aa-sdk/core/functions/filterUndefined#usage\",\"html\":\"\\nimport { filterUndefined } from "@aa-sdk/core";\\n \\nconst result = filterUndefined({\\n foo: undefined,\\n bar: null,\\n baz: "baz",\\n}); // { baz: "baz" }
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/filterUndefined.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { filterUndefined } from "@aa-sdk/core";\\n \\nconst result = filterUndefined({\\n foo: undefined,\\n bar: null,\\n baz: "baz",\\n}); // { baz: "baz" }\\n\",\"title\":\"Usage\",\"titles\":[\"filterUndefined\"]},{\"href\":\"/reference/aa-sdk/core/functions/filterUndefined#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/filterUndefined.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"filterUndefined\"]},{\"href\":\"/reference/aa-sdk/core/functions/filterUndefined#obj\",\"html\":\"\\nT
\\nthe object from which to remove properties with undefined or null values
T
\\nthe object with undefined or null properties removed
Parses the factory address and factory calldata from the provided account initialization code (initCode).
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode.mdx#parsefactoryaddressfromaccountinitcode\",\"isPage\":true,\"text\":\"\\nParses the factory address and factory calldata from the provided account initialization code (initCode).\\n\",\"title\":\"parseFactoryAddressFromAccountInitCode\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode#import\",\"html\":\"\\nimport { parseFactoryAddressFromAccountInitCode } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { parseFactoryAddressFromAccountInitCode } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"parseFactoryAddressFromAccountInitCode\"]},{\"href\":\"/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode#usage\",\"html\":\"\\nimport { parseFactoryAddressFromAccountInitCode } from "@aa-sdk/core";\\n \\nconst [address, calldata] =\\n parseFactoryAddressFromAccountInitCode("0xAddressCalldata");
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { parseFactoryAddressFromAccountInitCode } from "@aa-sdk/core";\\n \\nconst [address, calldata] =\\n parseFactoryAddressFromAccountInitCode("0xAddressCalldata");\\n\",\"title\":\"Usage\",\"titles\":[\"parseFactoryAddressFromAccountInitCode\"]},{\"href\":\"/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"parseFactoryAddressFromAccountInitCode\"]},{\"href\":\"/reference/aa-sdk/core/functions/parseFactoryAddressFromAccountInitCode#initcode\",\"html\":\"\\nHex
\\nThe initialization code from which to parse the factory address and calldata
[Address, Hex]
\\nA tuple containing the parsed factory address and factory calldata
Checks if the given value is a valid key of the EntryPointRegistry.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isEntryPointVersion.mdx#isentrypointversion\",\"isPage\":true,\"text\":\"\\nChecks if the given value is a valid key of the EntryPointRegistry.\\n\",\"title\":\"isEntryPointVersion\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/isEntryPointVersion#import\",\"html\":\"\\nimport { isEntryPointVersion } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isEntryPointVersion.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { isEntryPointVersion } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"isEntryPointVersion\"]},{\"href\":\"/reference/aa-sdk/core/functions/isEntryPointVersion#usage\",\"html\":\"\\nimport { isEntryPointVersion } from "@aa-sdk/core";\\n \\nconst valid = isEntryPointVersion("0.6.0");\\nconst invalid = isEntryPointVersion("0.8.0");
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isEntryPointVersion.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { isEntryPointVersion } from "@aa-sdk/core";\\n \\nconst valid = isEntryPointVersion("0.6.0");\\nconst invalid = isEntryPointVersion("0.8.0");\\n\",\"title\":\"Usage\",\"titles\":[\"isEntryPointVersion\"]},{\"href\":\"/reference/aa-sdk/core/functions/isEntryPointVersion#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isEntryPointVersion.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"isEntryPointVersion\"]},{\"href\":\"/reference/aa-sdk/core/functions/isEntryPointVersion#value\",\"html\":\"\\n*
\\nThe value to be checked
boolean
\\ntrue if the value is a valid key of EntryPointRegistry, false otherwise
Converts a ethers.js Signer to a SmartAccountSigner
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/functions/convertEthersSignerToAccountSigner.mdx#convertetherssignertoaccountsigner\",\"isPage\":true,\"text\":\"\\nConverts a ethers.js Signer to a SmartAccountSigner\\n\",\"title\":\"convertEthersSignerToAccountSigner\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/functions/convertEthersSignerToAccountSigner#import\",\"html\":\"\\nimport { convertEthersSignerToAccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/functions/convertEthersSignerToAccountSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { convertEthersSignerToAccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"convertEthersSignerToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/ethers/functions/convertEthersSignerToAccountSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/functions/convertEthersSignerToAccountSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"convertEthersSignerToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/ethers/functions/convertEthersSignerToAccountSigner#signer\",\"html\":\"\\nSigner
SmartAccountSigner<Signer>
\\na signer that can be used to sign and send user operations
Retrieves the entry point definition for the specified chain and version, falling back to the default version if not provided. Throws an error if the entry point address cannot be found.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/getEntryPoint.mdx#getentrypoint\",\"isPage\":true,\"text\":\"\\nRetrieves the entry point definition for the specified chain and version, falling back to the default version if not provided. Throws an error if the entry point address cannot be found.\\n\",\"title\":\"getEntryPoint\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/getEntryPoint#import\",\"html\":\"\\nimport { getEntryPoint } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/getEntryPoint.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getEntryPoint } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"getEntryPoint\"]},{\"href\":\"/reference/aa-sdk/core/functions/getEntryPoint#usage\",\"html\":\"\\nimport { getEntryPoint } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst entryPoint060 = getEntryPoint(sepolia);\\nconst entryPoint070 = getEntryPoint(sepolia, { version: "0.7.0" });
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/getEntryPoint.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getEntryPoint } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\n \\nconst entryPoint060 = getEntryPoint(sepolia);\\nconst entryPoint070 = getEntryPoint(sepolia, { version: "0.7.0" });\\n\",\"title\":\"Usage\",\"titles\":[\"getEntryPoint\"]},{\"href\":\"/reference/aa-sdk/core/functions/getEntryPoint#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/getEntryPoint.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getEntryPoint\"]},{\"href\":\"/reference/aa-sdk/core/functions/getEntryPoint#chain\",\"html\":\"\\nChain
\\nThe chain for which the entry point is being retrieved
GetEntryPointOptions<TEntryPointVersion>
\\nOptions containing the version and address overrides for the entry point
EntryPointDefRegistry<TChain>[EntryPointVersion]
\\nThe entry point definition for the specified chain and version
Picks the specified keys from an object and returns a new object containing only those key-value pairs.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/pick.mdx#pick\",\"isPage\":true,\"text\":\"\\nPicks the specified keys from an object and returns a new object containing only those key-value pairs.\\n\",\"title\":\"pick\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/pick#import\",\"html\":\"\\nimport { pick } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/pick.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { pick } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"pick\"]},{\"href\":\"/reference/aa-sdk/core/functions/pick#usage\",\"html\":\"\\nimport { pick } from "@aa-sdk/core";\\n \\nconst picked = pick(\\n {\\n foo: "foo",\\n bar: "bar",\\n },\\n ["foo"]\\n); // { foo: "foo" }
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/pick.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { pick } from "@aa-sdk/core";\\n \\nconst picked = pick(\\n {\\n foo: "foo",\\n bar: "bar",\\n },\\n ["foo"]\\n); // { foo: "foo" }\\n\",\"title\":\"Usage\",\"titles\":[\"pick\"]},{\"href\":\"/reference/aa-sdk/core/functions/pick#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/pick.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"pick\"]},{\"href\":\"/reference/aa-sdk/core/functions/pick#obj\",\"html\":\"\\nRecord<string, unknown>
\\nThe object from which to pick keys
string|string[]
\\nA single key or an array of keys to pick from the object
Record<string, unknown>
\\nA new object containing only the picked key-value pairs
Determines if the given SmartContractAccount has a signer associated with it.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSmartAccountWithSigner.mdx#issmartaccountwithsigner\",\"isPage\":true,\"text\":\"\\nDetermines if the given SmartContractAccount has a signer associated with it.\\n\",\"title\":\"isSmartAccountWithSigner\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/isSmartAccountWithSigner#import\",\"html\":\"\\nimport { isSmartAccountWithSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSmartAccountWithSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { isSmartAccountWithSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"isSmartAccountWithSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSmartAccountWithSigner#usage\",\"html\":\"\\nimport { toSmartContractAccount } from "@aa-sdk/core";\\n \\nconst account = await toSmartContractAccount(...);\\n \\nconsole.log(isSmartAccountWithSigner(account)); // false: the base account does not have a publicly accessible signer
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSmartAccountWithSigner.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { toSmartContractAccount } from "@aa-sdk/core";\\n \\nconst account = await toSmartContractAccount(...);\\n \\nconsole.log(isSmartAccountWithSigner(account)); // false: the base account does not have a publicly accessible signer\\n\",\"title\":\"Usage\",\"titles\":[\"isSmartAccountWithSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSmartAccountWithSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSmartAccountWithSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"isSmartAccountWithSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSmartAccountWithSigner#account\",\"html\":\"\\nSmartContractAccount
\\nThe account to check.
boolean
\\ntrue if the account has a signer, otherwise false.
Checks if the provided object is a SmartAccountSigner
.
import { isSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { isSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"isSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSigner#usage\",\"html\":\"\\nimport { isSigner, LocalAccountSigner } from "@aa-sdk/core";\\n \\nconst signer = new LocalAccountSigner(...);\\nconsole.log(isSigner(signer)); // true
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSigner.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { isSigner, LocalAccountSigner } from "@aa-sdk/core";\\n \\nconst signer = new LocalAccountSigner(...);\\nconsole.log(isSigner(signer)); // true\\n\",\"title\":\"Usage\",\"titles\":[\"isSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"isSigner\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSigner#signer\",\"html\":\"\\nany
\\nthe object to check
boolean
\\nA boolean indicating whether the object is a SmartAccountSigner
Retrieves the account address. Uses a provided accountAddress
if available; otherwise, it computes the address using the entry point contract and the initial code.
import { getAccountAddress } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/getAccountAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getAccountAddress } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"getAccountAddress\"]},{\"href\":\"/reference/aa-sdk/core/functions/getAccountAddress#usage\",\"html\":\"\\nimport { getEntryPoint, getAccountAddress } from "@aa-sdk/core";\\n \\nconst accountAddress = await getAccountAddress({\\n client,\\n entryPoint: getEntryPoint(chain),\\n getAccountInitCode: async () => "0x{factoryAddress}{factoryCallData}",\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/getAccountAddress.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getEntryPoint, getAccountAddress } from "@aa-sdk/core";\\n \\nconst accountAddress = await getAccountAddress({\\n client,\\n entryPoint: getEntryPoint(chain),\\n getAccountInitCode: async () => "0x{factoryAddress}{factoryCallData}",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"getAccountAddress\"]},{\"href\":\"/reference/aa-sdk/core/functions/getAccountAddress#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/getAccountAddress.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getAccountAddress\"]},{\"href\":\"/reference/aa-sdk/core/functions/getAccountAddress#params\",\"html\":\"\\nGetAccountAddressParams
\\nThe configuration object
PublicClient
\\nA public client instance to interact with the blockchain
EntryPointDef
\\nThe entry point definition which includes the address and ABI
Address
\\nOptional existing account address
() => Promise<Hex>
\\nA function that returns a Promise resolving to a Hex string representing the initial code of the account
Promise<Address>
\\nA promise that resolves to the account address
Converts a cookie into an initial state object
\\n\",\"id\":\"pages/reference/account-kit/core/functions/cookieToInitialState.mdx#cookietoinitialstate\",\"isPage\":true,\"text\":\"\\nConverts a cookie into an initial state object\\n\",\"title\":\"cookieToInitialState\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/cookieToInitialState#import\",\"html\":\"\\nimport { cookieToInitialState } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/cookieToInitialState.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { cookieToInitialState } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"cookieToInitialState\"]},{\"href\":\"/reference/account-kit/core/functions/cookieToInitialState#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/cookieToInitialState.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"cookieToInitialState\"]},{\"href\":\"/reference/account-kit/core/functions/cookieToInitialState#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config containing the client store
string | undefined
\\noptional cookie string
StoredState | undefined
\\nthe deserialized AlchemyClientState if the cookie exists, otherwise undefined
Provides a set of smart account client actions to decorate the provided client. These actions include building and signing user operations, sending transactions, and more.
\\nNOTE: this is already added to clients returned from createSmartAccountClient
import { smartAccountClientActions } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/smartAccountClientActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { smartAccountClientActions } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"smartAccountClientActions\"]},{\"href\":\"/reference/aa-sdk/core/functions/smartAccountClientActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/smartAccountClientActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"smartAccountClientActions\"]},{\"href\":\"/reference/aa-sdk/core/functions/smartAccountClientActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client to bind the smart account actions to
BaseSmartAccountClientActions<TChain, TAccount, TContext>
\\nAn object containing various smart account client actions
Sends transactions using the provided client and transaction parameters. This function builds user operations from the transactions, sends them, and waits for the transaction to be mined.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransactions.mdx#sendtransactions\",\"isPage\":true,\"text\":\"\\nSends transactions using the provided client and transaction parameters. This function builds user operations from the transactions, sends them, and waits for the transaction to be mined.\\n\",\"title\":\"sendTransactions\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransactions#import\",\"html\":\"\\nimport { sendTransactions } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransactions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { sendTransactions } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"sendTransactions\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransactions#usage\",\"html\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with sendTransactions\\nconst client = createSmartAccountClient(...);\\nconst result = await client.sendTransactions({\\nrequests: [{\\nto: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\n}],\\naccount, // only required if the client above is not connected to an account\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransactions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with sendTransactions\\nconst client = createSmartAccountClient(...);\\nconst result = await client.sendTransactions({\\nrequests: [{\\nto: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\n}],\\naccount, // only required if the client above is not connected to an account\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"sendTransactions\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransactions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransactions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"sendTransactions\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransactions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client used to send the transactions
SendTransactionsParameters<TAccount, TContext>
\\nThe parameters for sending the transactions, including requests, overrides, account, and context
Promise<Hex>
\\nA promise that resolves to the transaction hash of the sent transactions
Use this method to assert that a client is a BaseSmartAccountClient.\\nUseful for narrowing the type of the client down when used within the\\nsmart account client decorators
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSmartAccountClient.mdx#issmartaccountclient\",\"isPage\":true,\"text\":\"\\nUse this method to assert that a client is a BaseSmartAccountClient.\\nUseful for narrowing the type of the client down when used within the\\nsmart account client decorators\\n\",\"title\":\"isSmartAccountClient\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/isSmartAccountClient#import\",\"html\":\"\\nimport { isSmartAccountClient } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSmartAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { isSmartAccountClient } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"isSmartAccountClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSmartAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/isSmartAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"isSmartAccountClient\"]},{\"href\":\"/reference/aa-sdk/core/functions/isSmartAccountClient#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\na viem client
boolean
\\ntrue if the client is a SmartAccountClient
Returns the default state for an account of a supported type.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/defaultAccountState.mdx#defaultaccountstate\",\"isPage\":true,\"text\":\"\\nReturns the default state for an account of a supported type.\\n\",\"title\":\"defaultAccountState\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/defaultAccountState#import\",\"html\":\"\\nimport { defaultAccountState } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/defaultAccountState.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { defaultAccountState } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"defaultAccountState\"]},{\"href\":\"/reference/account-kit/core/functions/defaultAccountState#usage\",\"html\":\"\\nimport { defaultAccountState } from "@account-kit/core";\\n \\nconst defaultLightAccountState = defaultAccountState<"LightAccount">();
\\n\",\"id\":\"pages/reference/account-kit/core/functions/defaultAccountState.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { defaultAccountState } from "@account-kit/core";\\n \\nconst defaultLightAccountState = defaultAccountState<"LightAccount">();\\n\",\"title\":\"Usage\",\"titles\":[\"defaultAccountState\"]},{\"href\":\"/reference/account-kit/core/functions/defaultAccountState#returns\",\"html\":\"\\nAccountState<T>
\\nThe default state for the specified account type
The Split Transport allows you to split RPC traffic for specific methods across\\ndifferent RPC providers. This is done by specifying the methods you want handled\\nspecially as overrides and providing a fallback transport for all other methods.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/split.mdx#split\",\"isPage\":true,\"text\":\"\\nThe Split Transport allows you to split RPC traffic for specific methods across\\ndifferent RPC providers. This is done by specifying the methods you want handled\\nspecially as overrides and providing a fallback transport for all other methods.\\n\",\"title\":\"split\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/split#import\",\"html\":\"\\nimport { split } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/split.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { split } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"split\"]},{\"href\":\"/reference/aa-sdk/core/functions/split#usage\",\"html\":\"\\nimport { createPublicClient, http } from "viem";\\nimport { split } from "@aa-sdk/core";\\n \\nconst bundlerMethods = [\\n "eth_sendUserOperation",\\n "eth_estimateUserOperationGas",\\n "eth_getUserOperationReceipt",\\n "eth_getUserOperationByHash",\\n "eth_supportedEntryPoints",\\n];\\n \\nconst clientWithSplit = createPublicClient({\\n transport: split({\\n overrides: [\\n {\\n methods: bundlerMethods,\\n transport: http(BUNDLER_RPC_URL),\\n },\\n ],\\n fallback: http(OTHER_RPC_URL),\\n }),\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/split.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createPublicClient, http } from "viem";\\nimport { split } from "@aa-sdk/core";\\n \\nconst bundlerMethods = [\\n "eth_sendUserOperation",\\n "eth_estimateUserOperationGas",\\n "eth_getUserOperationReceipt",\\n "eth_getUserOperationByHash",\\n "eth_supportedEntryPoints",\\n];\\n \\nconst clientWithSplit = createPublicClient({\\n transport: split({\\n overrides: [\\n {\\n methods: bundlerMethods,\\n transport: http(BUNDLER_RPC_URL),\\n },\\n ],\\n fallback: http(OTHER_RPC_URL),\\n }),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"split\"]},{\"href\":\"/reference/aa-sdk/core/functions/split#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/split.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"split\"]},{\"href\":\"/reference/aa-sdk/core/functions/split#params\",\"html\":\"\\nSplitTransportParams
\\nsplit transport configuration containing the methods overrides and fallback transport
CustomTransport
\\na viem Transport that splits traffic
Waits for a user operation transaction to be confirmed by checking the receipt periodically until it is found or a maximum number of retries is reached.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/waitForUserOperationTransaction.mdx#waitforuseroperationtransaction\",\"isPage\":true,\"text\":\"\\nWaits for a user operation transaction to be confirmed by checking the receipt periodically until it is found or a maximum number of retries is reached.\\n\",\"title\":\"waitForUserOperationTransaction\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/waitForUserOperationTransaction#import\",\"html\":\"\\nimport { waitForUserOperationTransaction } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/waitForUserOperationTransaction.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { waitForUserOperationTransaction } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"waitForUserOperationTransaction\"]},{\"href\":\"/reference/aa-sdk/core/functions/waitForUserOperationTransaction#usage\",\"html\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with waitForUserOperationTransaction\\nconst client = createSmartAccountClient(...);\\nconst result = await client.waitForUserOperationTransaction({\\nhash: "0x...",\\nretries: {...} // optional param to configure the retry amounts\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/waitForUserOperationTransaction.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with waitForUserOperationTransaction\\nconst client = createSmartAccountClient(...);\\nconst result = await client.waitForUserOperationTransaction({\\nhash: "0x...",\\nretries: {...} // optional param to configure the retry amounts\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"waitForUserOperationTransaction\"]},{\"href\":\"/reference/aa-sdk/core/functions/waitForUserOperationTransaction#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/waitForUserOperationTransaction.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"waitForUserOperationTransaction\"]},{\"href\":\"/reference/aa-sdk/core/functions/waitForUserOperationTransaction#client\",\"html\":\"\\nClient<TTransport, TChain, any>
\\nThe client instance used to interact with the blockchain
WaitForUserOperationTxParameters
\\nThe parameters for the transaction to wait for
Hex
\\nThe transaction hash to wait for
WaitForUserOperationTxParameters["retries"]
\\nOptional retry parameters
number
\\nThe maximum number of retry attempts
number
\\nThe interval in milliseconds between retries
number
\\nThe multiplier for the interval between retries
Promise<Hex>
\\nA promise that resolves to the transaction hash when the transaction is confirmed
Sends a transaction using the provided client, arguments, optional overrides, and context.\\nThis sends a UO and then waits for it to be mined
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransaction.mdx#sendtransaction\",\"isPage\":true,\"text\":\"\\nSends a transaction using the provided client, arguments, optional overrides, and context.\\nThis sends a UO and then waits for it to be mined\\n\",\"title\":\"sendTransaction\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransaction#import\",\"html\":\"\\nimport { sendTransaction } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransaction.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { sendTransaction } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"sendTransaction\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransaction#usage\",\"html\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with sendTransaction\\nconst client = createSmartAccountClient(...);\\nconst result = await client.sendTransaction({\\nto: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\naccount, // only required if the client above is not connected to an account\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransaction.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\n// smart account client is already extended with sendTransaction\\nconst client = createSmartAccountClient(...);\\nconst result = await client.sendTransaction({\\nto: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\naccount, // only required if the client above is not connected to an account\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"sendTransaction\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransaction#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendTransaction.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"sendTransaction\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendTransaction#client\",\"html\":\"\\nClient<Transport, TChain, TAccount>
\\nThe client to send the transaction through
SendTransactionParameters<TChain, TAccount, TChainOverride>
\\nThe parameters required to send the transaction
UserOperationOverrides<TEntryPointVersion>
\\nOptional overrides for the user operation
UserOperationContext
\\nOptional context for the user operation
Promise<Hex>
\\nA promise that resolves to a hex string representing the transaction hash
Wraps a given signature with additional data following the EIP-6492 standard.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/wrapSignatureWith6492.mdx#wrapsignaturewith6492\",\"isPage\":true,\"text\":\"\\nWraps a given signature with additional data following the EIP-6492 standard.\\n\",\"title\":\"wrapSignatureWith6492\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/wrapSignatureWith6492#import\",\"html\":\"\\nimport { wrapSignatureWith6492 } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/wrapSignatureWith6492.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { wrapSignatureWith6492 } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"wrapSignatureWith6492\"]},{\"href\":\"/reference/aa-sdk/core/functions/wrapSignatureWith6492#usage\",\"html\":\"\\nimport { wrapSignatureWith6492 } from "@aa-sdk/core";\\n \\nconst signature = wrapSignatureWith6492({\\n factoryAddress: "0x...",\\n factoryCalldata: "0x...",\\n signature: "0x...",\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/wrapSignatureWith6492.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { wrapSignatureWith6492 } from "@aa-sdk/core";\\n \\nconst signature = wrapSignatureWith6492({\\n factoryAddress: "0x...",\\n factoryCalldata: "0x...",\\n signature: "0x...",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"wrapSignatureWith6492\"]},{\"href\":\"/reference/aa-sdk/core/functions/wrapSignatureWith6492#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/wrapSignatureWith6492.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"wrapSignatureWith6492\"]},{\"href\":\"/reference/aa-sdk/core/functions/wrapSignatureWith6492#params\",\"html\":\"\\nSignWith6492Params
\\nThe parameters to wrap the signature
Hex
\\nThe address of the factory
Hex
\\nThe calldata for the factory
Hex
\\nThe original signature that needs to be wrapped
Hash
\\nThe wrapped signature
Converts an account to a smart contract account and sets up various account-related methods using the provided parameters like transport, chain, entry point, and other utilities.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toSmartContractAccount.mdx#tosmartcontractaccount\",\"isPage\":true,\"text\":\"\\nConverts an account to a smart contract account and sets up various account-related methods using the provided parameters like transport, chain, entry point, and other utilities.\\n\",\"title\":\"toSmartContractAccount\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/toSmartContractAccount#import\",\"html\":\"\\nimport { toSmartContractAccount } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toSmartContractAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { toSmartContractAccount } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"toSmartContractAccount\"]},{\"href\":\"/reference/aa-sdk/core/functions/toSmartContractAccount#usage\",\"html\":\"\\nimport { http, type SignableMessage } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst myAccount = await toSmartContractAccount({\\n /// REQUIRED PARAMS ///\\n source: "MyAccount",\\n transport: http("RPC_URL"),\\n chain: sepolia,\\n // The EntryPointDef that your account is com"patible with\\n entryPoint: getEntryPoint(sepolia, { version: "0.6.0" }),\\n // This should return a concatenation of your `factoryAddress` and the `callData` for your factory's create account method\\n getAccountInitCode: async () => "0x{factoryAddress}{callData}",\\n // an invalid signature that doesn't cause your account to revert during validation\\n getDummySignature: () => "0x1234...",\\n // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method\\n encodeExecute: async (uo) => "0xcalldata",\\n signMessage: async ({ message }: { message: SignableMessage }) => "0x...",\\n signTypedData: async (typedData) => "0x000",\\n \\n /// OPTIONAL PARAMS ///\\n // if you already know your account's address, pass that in here to avoid generating a new counterfactual\\n accountAddress: "0xaddressoverride",\\n // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method\\n encodeBatchExecute: async (uos) => "0x...",\\n // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here\\n signUserOperationHash: async (hash) => "0x...",\\n // allows you to define the calldata for upgrading your account\\n encodeUpgradeToAndCall: async (params) => "0x...",\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toSmartContractAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { http, type SignableMessage } from "viem";\\nimport { sepolia } from "viem/chains";\\n \\nconst myAccount = await toSmartContractAccount({\\n /// REQUIRED PARAMS ///\\n source: "MyAccount",\\n transport: http("RPC_URL"),\\n chain: sepolia,\\n // The EntryPointDef that your account is com"patible with\\n entryPoint: getEntryPoint(sepolia, { version: "0.6.0" }),\\n // This should return a concatenation of your `factoryAddress` and the `callData` for your factory's create account method\\n getAccountInitCode: async () => "0x{factoryAddress}{callData}",\\n // an invalid signature that doesn't cause your account to revert during validation\\n getDummySignature: () => "0x1234...",\\n // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method\\n encodeExecute: async (uo) => "0xcalldata",\\n signMessage: async ({ message }: { message: SignableMessage }) => "0x...",\\n signTypedData: async (typedData) => "0x000",\\n \\n /// OPTIONAL PARAMS ///\\n // if you already know your account's address, pass that in here to avoid generating a new counterfactual\\n accountAddress: "0xaddressoverride",\\n // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method\\n encodeBatchExecute: async (uos) => "0x...",\\n // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here\\n signUserOperationHash: async (hash) => "0x...",\\n // allows you to define the calldata for upgrading your account\\n encodeUpgradeToAndCall: async (params) => "0x...",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"toSmartContractAccount\"]},{\"href\":\"/reference/aa-sdk/core/functions/toSmartContractAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toSmartContractAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"toSmartContractAccount\"]},{\"href\":\"/reference/aa-sdk/core/functions/toSmartContractAccount#params\",\"html\":\"\\nToSmartContractAccountParams
\\nthe parameters required for converting to a smart contract account
Transport
\\nthe transport mechanism used for communication
Chain
\\nthe blockchain chain used in the account
EntryPoint
\\nthe entry point of the smart contract
string
\\nthe source identifier for the account
Address
\\nthe address of the account
() => Promise<Hex>
\\na function to get the initial state code of the account
(message: { message: SignableMessage }) => Promise<Hex>
\\na function to sign a message
(typedDataDefinition: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>
\\na function to sign typed data
(transactions: Transaction[]) => Hex
\\na function to encode batch transactions
(tx: Transaction) => Hex
\\na function to encode a single transaction
() => Promise<Hex>
\\na function to get a dummy signature
(uoHash: Hex) => Promise<Hex>
\\na function to sign user operations
(implementationAddress: Address, implementationCallData: Hex) => Hex
\\na function to encode upgrade call
Promise<SmartContractAccount>
\\na promise that resolves to a SmartContractAccount object with methods and properties for interacting with the smart contract account
Sends a user operation or batch of user operations using the connected account. Before executing, sendUserOperation will run the user operation through the middleware pipeline.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendUserOperation.mdx#senduseroperation\",\"isPage\":true,\"text\":\"\\nSends a user operation or batch of user operations using the connected account. Before executing, sendUserOperation will run the user operation through the middleware pipeline.\\n\",\"title\":\"sendUserOperation\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/sendUserOperation#import\",\"html\":\"\\nimport { sendUserOperation } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendUserOperation.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { sendUserOperation } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"sendUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendUserOperation#usage\",\"html\":\"\\nimport { createSmartAccountClient, toSmartContractAccount } from "@aa-sdk/core";\\n \\nconst account = await toSmartContractAccount(...);\\nconst result = await createSmartAccountClient(...).sendUserOperation({\\nuo: {\\ntarget: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\n}\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendUserOperation.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createSmartAccountClient, toSmartContractAccount } from "@aa-sdk/core";\\n \\nconst account = await toSmartContractAccount(...);\\nconst result = await createSmartAccountClient(...).sendUserOperation({\\nuo: {\\ntarget: "0x...",\\ndata: "0x...", // or "0x",\\nvalue: 0n, // optional\\n}\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"sendUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendUserOperation#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/sendUserOperation.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"sendUserOperation\"]},{\"href\":\"/reference/aa-sdk/core/functions/sendUserOperation#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nthe smart account client to use for RPC requests
SendUserOperationParameters<TAccount, TContext>
\\ncontains the UO or batch to send, context, overrides, and account if not hoisted on the client
Promise<SendUserOperationResult<TEntryPointVersion>>
\\na Promise containing the result of the user operation
Converts an array of objects into a record (object) where each key is determined by the specified selector and the value is determined by the provided function.
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toRecord.mdx#torecord\",\"isPage\":true,\"text\":\"\\nConverts an array of objects into a record (object) where each key is determined by the specified selector and the value is determined by the provided function.\\n\",\"title\":\"toRecord\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/toRecord#import\",\"html\":\"\\nimport { toRecord } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toRecord.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { toRecord } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"toRecord\"]},{\"href\":\"/reference/aa-sdk/core/functions/toRecord#usage\",\"html\":\"\\nimport { toRecord } from "@aa-sdk/core";\\nimport { sepolia, mainnet } from "viem/chains";\\n \\nconst addressesByChain = toRecord([sepolia, mainnet], "id", () => "0x..."); // { [sepolia.id]: "0x...", [mainnet.id]: "0x..." }
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toRecord.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { toRecord } from "@aa-sdk/core";\\nimport { sepolia, mainnet } from "viem/chains";\\n \\nconst addressesByChain = toRecord([sepolia, mainnet], "id", () => "0x..."); // { [sepolia.id]: "0x...", [mainnet.id]: "0x..." }\\n\",\"title\":\"Usage\",\"titles\":[\"toRecord\"]},{\"href\":\"/reference/aa-sdk/core/functions/toRecord#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/toRecord.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"toRecord\"]},{\"href\":\"/reference/aa-sdk/core/functions/toRecord#array\",\"html\":\"\\nT[]
\\nThe array of objects to convert to a record
K
\\nThe key used to select the property that will become the record's key
(item: T) => V
\\nThe function that transforms each item in the array into the record's value
Record<T[K], V>
\\nThe resulting record object
Creates an AlchemyAccountsConfig object that can be used in conjunction with\\nthe actions exported from @account-kit/core
.
The config contains core and client stores that can be used to manage account state\\nin your application.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/createConfig.mdx#createconfig\",\"isPage\":true,\"text\":\"\\nCreates an AlchemyAccountsConfig object that can be used in conjunction with\\nthe actions exported from @account-kit/core.\\nThe config contains core and client stores that can be used to manage account state\\nin your application.\\n\",\"title\":\"createConfig\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/createConfig#import\",\"html\":\"\\nimport { createConfig } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/createConfig.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createConfig } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"createConfig\"]},{\"href\":\"/reference/account-kit/core/functions/createConfig#usage\",\"html\":\"\\nimport { createConfig } from "@account-kit/core";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst config = createConfig({\\n chain: sepolia,\\n apiKey: "your-api-key",\\n});
\\n\",\"id\":\"pages/reference/account-kit/core/functions/createConfig.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createConfig } from "@account-kit/core";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst config = createConfig({\\n chain: sepolia,\\n apiKey: "your-api-key",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createConfig\"]},{\"href\":\"/reference/account-kit/core/functions/createConfig#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/createConfig.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createConfig\"]},{\"href\":\"/reference/account-kit/core/functions/createConfig#params\",\"html\":\"\\nCreateConfigProps
\\nThe parameters to create the config with
AlchemyAccountsConfig
\\nAn alchemy account config object containing the core and client store
Function to create cookie based Storage
\\n\",\"id\":\"pages/reference/account-kit/core/functions/cookieStorage.mdx#cookiestorage\",\"isPage\":true,\"text\":\"\\nFunction to create cookie based Storage\\n\",\"title\":\"cookieStorage\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/cookieStorage#import\",\"html\":\"\\nimport { cookieStorage } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/cookieStorage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { cookieStorage } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"cookieStorage\"]},{\"href\":\"/reference/account-kit/core/functions/cookieStorage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/cookieStorage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"cookieStorage\"]},{\"href\":\"/reference/account-kit/core/functions/cookieStorage#config\",\"html\":\"\\n{sessionLength: number}
\\noptional config object that allows you to set the session length
number
\\nthe length of the session in milliseconds
Storage
\\nan instance of a browser storage object that leverages cookies
Noop middleware that does nothing and passes the arguments through
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/noopMiddleware.mdx#noopmiddleware\",\"isPage\":true,\"text\":\"\\nNoop middleware that does nothing and passes the arguments through\\n\",\"title\":\"noopMiddleware\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/noopMiddleware#import\",\"html\":\"\\nimport { noopMiddleware } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/noopMiddleware.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { noopMiddleware } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"noopMiddleware\"]},{\"href\":\"/reference/aa-sdk/core/functions/noopMiddleware#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/noopMiddleware.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"noopMiddleware\"]},{\"href\":\"/reference/aa-sdk/core/functions/noopMiddleware#args\",\"html\":\"\\nDeferrable<UserOperationStruct<TEntryPointVersion>>
\\nthe client middleware arguments passed to the middleware
Promise<Deferrable<UserOperationStruct<TEntryPointVersion>>>
\\nthe arguments passed to the middleware and returned as is without modification
function that takes in ClientMiddlewareConfig used during client initiation\\nand returns the middleware actions object that the smart account client extends with
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/middlewareActions.mdx#middlewareactions\",\"isPage\":true,\"text\":\"\\nfunction that takes in ClientMiddlewareConfig used during client initiation\\nand returns the middleware actions object that the smart account client extends with\\n\",\"title\":\"middlewareActions\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/middlewareActions#import\",\"html\":\"\\nimport { middlewareActions } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/middlewareActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { middlewareActions } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"middlewareActions\"]},{\"href\":\"/reference/aa-sdk/core/functions/middlewareActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/middlewareActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"middlewareActions\"]},{\"href\":\"/reference/aa-sdk/core/functions/middlewareActions#overrides\",\"html\":\"\\nClientMiddlewareConfig
\\nconfig used during client initiation for overriding default middlewares
(client: MiddlewareClient<TTransport, TChain, TAccount>) => { middleware: ClientMiddleware }
\\nmiddleware actions object
Converts a ethersjs Wallet to a SmartAccountSigner
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/functions/convertWalletToAccountSigner.mdx#convertwallettoaccountsigner\",\"isPage\":true,\"text\":\"\\nConverts a ethersjs Wallet to a SmartAccountSigner\\n\",\"title\":\"convertWalletToAccountSigner\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/functions/convertWalletToAccountSigner#import\",\"html\":\"\\nimport { convertWalletToAccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/functions/convertWalletToAccountSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { convertWalletToAccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"convertWalletToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/ethers/functions/convertWalletToAccountSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/functions/convertWalletToAccountSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"convertWalletToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/ethers/functions/convertWalletToAccountSigner#wallet\",\"html\":\"\\nWallet
SmartAccountSigner<Wallet>
\\na signer that can be used to sign and send user operations
Await all of the properties of a Deferrable object
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/resolveProperties.mdx#resolveproperties\",\"isPage\":true,\"text\":\"\\nAwait all of the properties of a Deferrable object\\n\",\"title\":\"resolveProperties\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/functions/resolveProperties#import\",\"html\":\"\\nimport { resolveProperties } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/resolveProperties.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { resolveProperties } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"resolveProperties\"]},{\"href\":\"/reference/aa-sdk/core/functions/resolveProperties#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/functions/resolveProperties.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"resolveProperties\"]},{\"href\":\"/reference/aa-sdk/core/functions/resolveProperties#object\",\"html\":\"\\nDeferrable<T>
Promise<T>
\\nthe object with its properties resolved
Creates an account of a specified type using the provided parameters and configuration. Supports creating LightAccount and MultiOwnerModularAccount types.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/createAccount.mdx#createaccount\",\"isPage\":true,\"text\":\"\\nCreates an account of a specified type using the provided parameters and configuration. Supports creating LightAccount and MultiOwnerModularAccount types.\\n\",\"title\":\"createAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/createAccount#import\",\"html\":\"\\nimport { createAccount } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/createAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createAccount } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"createAccount\"]},{\"href\":\"/reference/account-kit/core/functions/createAccount#usage\",\"html\":\"\\nimport { createAccount } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst account = createAccount(\\n {\\n type: "LightAccount",\\n },\\n config\\n);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/createAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createAccount } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst account = createAccount(\\n {\\n type: "LightAccount",\\n },\\n config\\n);\\n\",\"title\":\"Usage\",\"titles\":[\"createAccount\"]},{\"href\":\"/reference/account-kit/core/functions/createAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/createAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createAccount\"]},{\"href\":\"/reference/account-kit/core/functions/createAccount#params\",\"html\":\"\\nCreateAccountParams<TAccount>
\\nThe parameters required to create the account, including the type and account parameters
AlchemyAccountsConfig
\\nThe configuration object for Alchemy accounts
Promise<SupportedAccounts>
\\nA promise that resolves to the created account object
Disconnects the current signer, accounts, and clears the store.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/disconnect.mdx#disconnect\",\"isPage\":true,\"text\":\"\\nDisconnects the current signer, accounts, and clears the store.\\n\",\"title\":\"disconnect\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/disconnect#import\",\"html\":\"\\nimport { disconnect } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/disconnect.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { disconnect } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"disconnect\"]},{\"href\":\"/reference/account-kit/core/functions/disconnect#usage\",\"html\":\"\\nimport { disconnect, createConfig } from "@account-kit/core";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst config = createConfig({\\n chain: sepolia,\\n apiKey: "your-api-key",\\n});\\n \\nawait disconnect(config);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/disconnect.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { disconnect, createConfig } from "@account-kit/core";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst config = createConfig({\\n chain: sepolia,\\n apiKey: "your-api-key",\\n});\\n \\nawait disconnect(config);\\n\",\"title\":\"Usage\",\"titles\":[\"disconnect\"]},{\"href\":\"/reference/account-kit/core/functions/disconnect#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/disconnect.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"disconnect\"]},{\"href\":\"/reference/account-kit/core/functions/disconnect#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nThe configuration containing the store to be cleared
Retrieves the account of the specified type from the client store based on the provided configuration.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getAccount.mdx#getaccount\",\"isPage\":true,\"text\":\"\\nRetrieves the account of the specified type from the client store based on the provided configuration.\\n\",\"title\":\"getAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/getAccount#import\",\"html\":\"\\nimport { getAccount } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getAccount } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"getAccount\"]},{\"href\":\"/reference/account-kit/core/functions/getAccount#usage\",\"html\":\"\\nimport { getAccount } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst { account, status } = getAccount(\\n {\\n type: "LightAccount",\\n },\\n config\\n);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getAccount } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst { account, status } = getAccount(\\n {\\n type: "LightAccount",\\n },\\n config\\n);\\n\",\"title\":\"Usage\",\"titles\":[\"getAccount\"]},{\"href\":\"/reference/account-kit/core/functions/getAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/getAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getAccount\"]},{\"href\":\"/reference/account-kit/core/functions/getAccount#params\",\"html\":\"\\nGetAccountParams<TAccount>
\\nThe parameters containing the type of the account to retrieve
AlchemyAccountsConfig
\\nThe configuration containing the client store
GetAccountResult<TAccount>
\\nThe result which includes the account if found and its status
Retrieves the BundlerClient from the core store of the given AlchemyAccountsConfig.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getBundlerClient.mdx#getbundlerclient\",\"isPage\":true,\"text\":\"\\nRetrieves the BundlerClient from the core store of the given AlchemyAccountsConfig.\\n\",\"title\":\"getBundlerClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/getBundlerClient#import\",\"html\":\"\\nimport { getBundlerClient } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getBundlerClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getBundlerClient } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"getBundlerClient\"]},{\"href\":\"/reference/account-kit/core/functions/getBundlerClient#usage\",\"html\":\"\\n// see `createConfig` for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst bundlerClient = getBundlerClient(config);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getBundlerClient.mdx#usage\",\"isPage\":false,\"text\":\"\\n// see `createConfig` for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst bundlerClient = getBundlerClient(config);\\n\",\"title\":\"Usage\",\"titles\":[\"getBundlerClient\"]},{\"href\":\"/reference/account-kit/core/functions/getBundlerClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/getBundlerClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getBundlerClient\"]},{\"href\":\"/reference/account-kit/core/functions/getBundlerClient#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nThe configuration object containing the core store.
ClientWithAlchemyMethods
\\nThe BundlerClient from the core store.
Will hydrate the client store with the provided initial state if one is provided.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/hydrate.mdx#hydrate\",\"isPage\":true,\"text\":\"\\nWill hydrate the client store with the provided initial state if one is provided.\\n\",\"title\":\"hydrate\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/hydrate#import\",\"html\":\"\\nimport { hydrate } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/hydrate.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { hydrate } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"hydrate\"]},{\"href\":\"/reference/account-kit/core/functions/hydrate#usage\",\"html\":\"\\nimport { hydrate, cookieToInitialState } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst initialState = cookieToInitialState(document.cookie);\\nconst { onMount } = hydrate(config, initialState);\\n// call onMount once your component has mounted
\\n\",\"id\":\"pages/reference/account-kit/core/functions/hydrate.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { hydrate, cookieToInitialState } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst initialState = cookieToInitialState(document.cookie);\\nconst { onMount } = hydrate(config, initialState);\\n// call onMount once your component has mounted\\n\",\"title\":\"Usage\",\"titles\":[\"hydrate\"]},{\"href\":\"/reference/account-kit/core/functions/hydrate#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/hydrate.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"hydrate\"]},{\"href\":\"/reference/account-kit/core/functions/hydrate#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe config containing the client store
StoredState
\\noptional param detailing the initial ClientState
{ onMount: () => Promise<void> }
\\nan object containing an onMount function that can be called when your component first renders on the client
Creates a light account based on the provided parameters such as transport, chain, signer, init code, and more. Ensures that an account is configured and returned with various capabilities, such as transferring ownership and retrieving the owner's address.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccount.mdx#createlightaccount\",\"isPage\":true,\"text\":\"\\nCreates a light account based on the provided parameters such as transport, chain, signer, init code, and more. Ensures that an account is configured and returned with various capabilities, such as transferring ownership and retrieving the owner's address.\\n\",\"title\":\"createLightAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccount#import\",\"html\":\"\\nimport { createLightAccount } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createLightAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccount#usage\",\"html\":\"\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createLightAccount({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createLightAccount({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createLightAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createLightAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccount#config\",\"html\":\"\\nCreateLightAccountParams
\\nThe parameters for creating a light account
Promise<LightAccount>
\\nA promise that resolves to a LightAccount
object containing the created account information and methods
Watches for changes to the bundler client within the given configuration and triggers a callback when changes occur.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchBundlerClient.mdx#watchbundlerclient\",\"isPage\":true,\"text\":\"\\nWatches for changes to the bundler client within the given configuration and triggers a callback when changes occur.\\n\",\"title\":\"watchBundlerClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/watchBundlerClient#import\",\"html\":\"\\nimport { watchBundlerClient } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchBundlerClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { watchBundlerClient } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"watchBundlerClient\"]},{\"href\":\"/reference/account-kit/core/functions/watchBundlerClient#usage\",\"html\":\"\\nimport { watchBundlerClient } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchBundlerClient(config)(console.log);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchBundlerClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { watchBundlerClient } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchBundlerClient(config)(console.log);\\n\",\"title\":\"Usage\",\"titles\":[\"watchBundlerClient\"]},{\"href\":\"/reference/account-kit/core/functions/watchBundlerClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchBundlerClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"watchBundlerClient\"]},{\"href\":\"/reference/account-kit/core/functions/watchBundlerClient#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nThe configuration object containing the core store
(onChange: (bundlerClient: ClientWithAlchemyMethods) => void) => (() => void)
\\nA function accepting a callback function to invoke when the bundler client changes and returns a function to unsubscribe from the store
Creates a multi-owner light account using the provided parameters, including transport, chain, signer, initialization code, version, account address, factory address, salt, and owners. Ensures the owners list is deduplicated, ordered, and valid.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount.mdx#createmultiownerlightaccount\",\"isPage\":true,\"text\":\"\\nCreates a multi-owner light account using the provided parameters, including transport, chain, signer, initialization code, version, account address, factory address, salt, and owners. Ensures the owners list is deduplicated, ordered, and valid.\\n\",\"title\":\"createMultiOwnerLightAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount#import\",\"html\":\"\\nimport { createMultiOwnerLightAccount } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerLightAccount } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultiOwnerLightAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount#usage\",\"html\":\"\\nimport { createMultiOwnerLightAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createMultiOwnerLightAccount({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerLightAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createMultiOwnerLightAccount({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultiOwnerLightAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultiOwnerLightAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccount#config\",\"html\":\"\\nCreateMultiOwnerLightAccountParams
\\nThe parameters for creating a multi-owner light account
Promise<MultiOwnerLightAccount>
\\nA promise that resolves to a MultiOwnerLightAccount
object containing the created account information and methods
This method will use the current state in the client store and attempt to restore\\nconnected instances of previously used accounts and the signer.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/reconnect.mdx#reconnect\",\"isPage\":true,\"text\":\"\\nThis method will use the current state in the client store and attempt to restore\\nconnected instances of previously used accounts and the signer.\\n\",\"title\":\"reconnect\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/reconnect#import\",\"html\":\"\\nimport { reconnect } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/reconnect.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { reconnect } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"reconnect\"]},{\"href\":\"/reference/account-kit/core/functions/reconnect#usage\",\"html\":\"\\nimport { reconnect } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nawait reconnect(config);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/reconnect.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { reconnect } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nawait reconnect(config);\\n\",\"title\":\"Usage\",\"titles\":[\"reconnect\"]},{\"href\":\"/reference/account-kit/core/functions/reconnect#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/reconnect.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"reconnect\"]},{\"href\":\"/reference/account-kit/core/functions/reconnect#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config which contains the client store
Retrieves the signer status from the client's store in the provided configuration.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSignerStatus.mdx#getsignerstatus\",\"isPage\":true,\"text\":\"\\nRetrieves the signer status from the client's store in the provided configuration.\\n\",\"title\":\"getSignerStatus\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/getSignerStatus#import\",\"html\":\"\\nimport { getSignerStatus } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSignerStatus.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getSignerStatus } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"getSignerStatus\"]},{\"href\":\"/reference/account-kit/core/functions/getSignerStatus#usage\",\"html\":\"\\nimport { getSignerStatus } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst signerStatus = getSignerStatus(config);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSignerStatus.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getSignerStatus } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nconst signerStatus = getSignerStatus(config);\\n\",\"title\":\"Usage\",\"titles\":[\"getSignerStatus\"]},{\"href\":\"/reference/account-kit/core/functions/getSignerStatus#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSignerStatus.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getSignerStatus\"]},{\"href\":\"/reference/account-kit/core/functions/getSignerStatus#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nThe configuration object containing the client store
SignerStatus
\\nThe current signer status from the client store
Finds predecessors for each provided key and returns them in the struct ISessionKeyPlugin.SessionKeyToRemove[]
.
import { buildSessionKeysToRemoveStruct } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/buildSessionKeysToRemoveStruct.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { buildSessionKeysToRemoveStruct } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"buildSessionKeysToRemoveStruct\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/buildSessionKeysToRemoveStruct#usage\",\"html\":\"\\nimport { buildSessionKeysToRemoveStruct } from "@account-kit/smart-contracts";\\n \\nconst client = createSmartAccountClient(...);\\n \\nconst keysToRemove = await buildSessionKeysToRemoveStruct(client, {\\nkeys: ["0x...", "0x..."],\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/buildSessionKeysToRemoveStruct.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { buildSessionKeysToRemoveStruct } from "@account-kit/smart-contracts";\\n \\nconst client = createSmartAccountClient(...);\\n \\nconst keysToRemove = await buildSessionKeysToRemoveStruct(client, {\\nkeys: ["0x...", "0x..."],\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"buildSessionKeysToRemoveStruct\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/buildSessionKeysToRemoveStruct#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/buildSessionKeysToRemoveStruct.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"buildSessionKeysToRemoveStruct\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/buildSessionKeysToRemoveStruct#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance used to interact with the smart account
BuildSessionKeysToRemoveStructParams<TAccount>
\\nArguments to configure the session key removal process
Promise<{ sessionKey: Address; predecessor: Address }[]>
\\nA promise that resolves to an array of objects each containing a session key and its predecessor
Returns the currently logged in user if using an SCA with the AlchemySigner\\nor the connected EOA details.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getUser.mdx#getuser\",\"isPage\":true,\"text\":\"\\nReturns the currently logged in user if using an SCA with the AlchemySigner\\nor the connected EOA details.\\n\",\"title\":\"getUser\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/getUser#import\",\"html\":\"\\nimport { getUser } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getUser.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getUser } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"getUser\"]},{\"href\":\"/reference/account-kit/core/functions/getUser#usage\",\"html\":\"\\nimport { getUser } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst user = getUser(config);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getUser.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getUser } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst user = getUser(config);\\n\",\"title\":\"Usage\",\"titles\":[\"getUser\"]},{\"href\":\"/reference/account-kit/core/functions/getUser#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/getUser.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getUser\"]},{\"href\":\"/reference/account-kit/core/functions/getUser#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config containing app state
GetUserResult
\\nthe user if the signer or an EOA are connected
If there is a signer attached to the client state, it will return it.\\nThe signer should always be null on the server, and will be set on the client\\nif the store was properly hydrated.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSigner.mdx#getsigner\",\"isPage\":true,\"text\":\"\\nIf there is a signer attached to the client state, it will return it.\\nThe signer should always be null on the server, and will be set on the client\\nif the store was properly hydrated.\\n\",\"title\":\"getSigner\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/getSigner#import\",\"html\":\"\\nimport { getSigner } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getSigner } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"getSigner\"]},{\"href\":\"/reference/account-kit/core/functions/getSigner#usage\",\"html\":\"\\nimport { getSigner } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst signer = getSigner(config);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSigner.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getSigner } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst signer = getSigner(config);\\n\",\"title\":\"Usage\",\"titles\":[\"getSigner\"]},{\"href\":\"/reference/account-kit/core/functions/getSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/getSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getSigner\"]},{\"href\":\"/reference/account-kit/core/functions/getSigner#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nThe account config which contains the client store
AlchemyWebSigner | null
\\nthe instance of the signer present in the store if it exists, otherwise null
Subscribe to changes to the active connection
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchConnection.mdx#watchconnection\",\"isPage\":true,\"text\":\"\\nSubscribe to changes to the active connection\\n\",\"title\":\"watchConnection\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/watchConnection#import\",\"html\":\"\\nimport { watchConnection } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchConnection.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { watchConnection } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"watchConnection\"]},{\"href\":\"/reference/account-kit/core/functions/watchConnection#usage\",\"html\":\"\\nimport { watchConnection } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchConnection(config)(console.log);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchConnection.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { watchConnection } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchConnection(config)(console.log);\\n\",\"title\":\"Usage\",\"titles\":[\"watchConnection\"]},{\"href\":\"/reference/account-kit/core/functions/watchConnection#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchConnection.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"watchConnection\"]},{\"href\":\"/reference/account-kit/core/functions/watchConnection#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config
(onChange: (connection: Connection) => void) => (() => void)
\\na function which accepts an onChange callback that will be fired when the connection changes and returns a function to unsubscribe from the store
Allows you to change the current chain in the core store. Note, this chain\\nmust be one of the chains configured in your original createConfig call.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/setChain.mdx#setchain\",\"isPage\":true,\"text\":\"\\nAllows you to change the current chain in the core store. Note, this chain\\nmust be one of the chains configured in your original createConfig call.\\n\",\"title\":\"setChain\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/setChain#import\",\"html\":\"\\nimport { setChain } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/setChain.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { setChain } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"setChain\"]},{\"href\":\"/reference/account-kit/core/functions/setChain#usage\",\"html\":\"\\nimport { setChain } from "@account-kit/core";\\nimport { config } from "./config";\\nimport { sepolia } from "@account-kit/infra";\\n \\nawait setChain(config, sepolia);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/setChain.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { setChain } from "@account-kit/core";\\nimport { config } from "./config";\\nimport { sepolia } from "@account-kit/infra";\\n \\nawait setChain(config, sepolia);\\n\",\"title\":\"Usage\",\"titles\":[\"setChain\"]},{\"href\":\"/reference/account-kit/core/functions/setChain#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/setChain.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setChain\"]},{\"href\":\"/reference/account-kit/core/functions/setChain#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe accounts config object
Chain
\\nthe chain to change to. It must be present in the connections config object
Watches for changes to a specific type of account and triggers the provided callback function when changes occur.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchAccount.mdx#watchaccount\",\"isPage\":true,\"text\":\"\\nWatches for changes to a specific type of account and triggers the provided callback function when changes occur.\\n\",\"title\":\"watchAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/watchAccount#import\",\"html\":\"\\nimport { watchAccount } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { watchAccount } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"watchAccount\"]},{\"href\":\"/reference/account-kit/core/functions/watchAccount#usage\",\"html\":\"\\nimport { watchAccount } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchAccount("LightAccount", config)(console.log);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { watchAccount } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchAccount("LightAccount", config)(console.log);\\n\",\"title\":\"Usage\",\"titles\":[\"watchAccount\"]},{\"href\":\"/reference/account-kit/core/functions/watchAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"watchAccount\"]},{\"href\":\"/reference/account-kit/core/functions/watchAccount#type\",\"html\":\"\\nTAccount
\\nThe type of account to watch
AlchemyAccountsConfig
\\nThe configuration containing client store settings
(onChange: (account: GetAccountResult<TAccount>) => void) => (() => void)
\\nA function that accepts a callback to be called when the account changes and returns a function to unsubscribe from the store
Creates a light account client using the provided parameters, including account information, transport mechanism, blockchain chain, and additional client configurations. This function first creates a light account and then uses it to create a smart account client, extending it with light account client actions.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountClient.mdx#createlightaccountclient\",\"isPage\":true,\"text\":\"\\nCreates a light account client using the provided parameters, including account information, transport mechanism, blockchain chain, and additional client configurations. This function first creates a light account and then uses it to create a smart account client, extending it with light account client actions.\\n\",\"title\":\"createLightAccountClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountClient#import\",\"html\":\"\\nimport { createLightAccountClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createLightAccountClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createLightAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountClient#usage\",\"html\":\"\\nimport { createLightAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createLightAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createLightAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createLightAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createLightAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createLightAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountClient#params\",\"html\":\"\\nCreateLightAccountClientParams
\\nThe parameters for creating a light account client
Promise<SmartAccountClient>
\\nA promise that resolves to a SmartAccountClient
object containing the created account information and methods
Creates a multi-owner light account Alchemy client using the provided configuration.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient.mdx#createmultiownerlightaccountalchemyclient\",\"isPage\":true,\"text\":\"\\nCreates a multi-owner light account Alchemy client using the provided configuration.\\n\",\"title\":\"createMultiOwnerLightAccountAlchemyClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient#import\",\"html\":\"\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultiOwnerLightAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient#usage\",\"html\":\"\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst lightAccountClient = await createMultiOwnerLightAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst lightAccountClient = await createMultiOwnerLightAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultiOwnerLightAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultiOwnerLightAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountAlchemyClient#config\",\"html\":\"\\nAlchemyMultiOwnerLightAccountClientConfig
\\nThe configuration for creating the Alchemy client
Promise<AlchemySmartAccountClient>
\\nA promise that resolves to an AlchemySmartAccountClient
object containing the created account information and methods
Watches for changes to the user in the client store and triggers the provided callback when a change is detected.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchUser.mdx#watchuser\",\"isPage\":true,\"text\":\"\\nWatches for changes to the user in the client store and triggers the provided callback when a change is detected.\\n\",\"title\":\"watchUser\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/watchUser#import\",\"html\":\"\\nimport { watchUser } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchUser.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { watchUser } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"watchUser\"]},{\"href\":\"/reference/account-kit/core/functions/watchUser#usage\",\"html\":\"\\nimport { watchUser } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchUser(config)(console.log);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchUser.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { watchUser } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchUser(config)(console.log);\\n\",\"title\":\"Usage\",\"titles\":[\"watchUser\"]},{\"href\":\"/reference/account-kit/core/functions/watchUser#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchUser.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"watchUser\"]},{\"href\":\"/reference/account-kit/core/functions/watchUser#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe configuration containing the client store
(onChange: (user: User) => void) => (() => void)
\\na function which accepts a callback that fires when the user changes and returns a function to unsubscribe from the user updates
Watches the signer status in the client store and triggers the provided callback function when the status changes.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSignerStatus.mdx#watchsignerstatus\",\"isPage\":true,\"text\":\"\\nWatches the signer status in the client store and triggers the provided callback function when the status changes.\\n\",\"title\":\"watchSignerStatus\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/watchSignerStatus#import\",\"html\":\"\\nimport { watchSignerStatus } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSignerStatus.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { watchSignerStatus } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"watchSignerStatus\"]},{\"href\":\"/reference/account-kit/core/functions/watchSignerStatus#usage\",\"html\":\"\\nimport { watchSignerStatus } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchSignerStatus(config)(console.log);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSignerStatus.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { watchSignerStatus } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchSignerStatus(config)(console.log);\\n\",\"title\":\"Usage\",\"titles\":[\"watchSignerStatus\"]},{\"href\":\"/reference/account-kit/core/functions/watchSignerStatus#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSignerStatus.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"watchSignerStatus\"]},{\"href\":\"/reference/account-kit/core/functions/watchSignerStatus#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nThe configuration object containing the client store
(onChange: (status: SignerStatus) => void) => (() => void)
\\nA function that accepts a callback to be called when the signer status changes which returns a function to unsubscribe from the store
Creates an Alchemy smart account client connected to a Light Account instance.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient.mdx#createlightaccountalchemyclient\",\"isPage\":true,\"text\":\"\\nCreates an Alchemy smart account client connected to a Light Account instance.\\n\",\"title\":\"createLightAccountAlchemyClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient#import\",\"html\":\"\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createLightAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient#usage\",\"html\":\"\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst lightAccountClient = await createLightAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createLightAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createLightAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createLightAccountAlchemyClient#config\",\"html\":\"\\nAlchemyLightAccountClientConfig
\\nThe configuration for setting up the Alchemy Light Account Client
Promise<AlchemySmartAccountClient>
\\nA promise that resolves to an AlchemySmartAccountClient
object containing the created client
Subscribe to changes of the signer instance on the client store.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSigner.mdx#watchsigner\",\"isPage\":true,\"text\":\"\\nSubscribe to changes of the signer instance on the client store.\\n\",\"title\":\"watchSigner\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/watchSigner#import\",\"html\":\"\\nimport { watchSigner } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { watchSigner } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"watchSigner\"]},{\"href\":\"/reference/account-kit/core/functions/watchSigner#usage\",\"html\":\"\\nimport { watchSigner } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchSigner(config)(console.log);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSigner.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { watchSigner } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchSigner(config)(console.log);\\n\",\"title\":\"Usage\",\"titles\":[\"watchSigner\"]},{\"href\":\"/reference/account-kit/core/functions/watchSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"watchSigner\"]},{\"href\":\"/reference/account-kit/core/functions/watchSigner#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config containing the client store
(onChange: (chain: AlchemyWebSigner) => void) => (() => void)
\\na function which accepts an onChange callback that will be fired when the signer changes and returns a function to unsubscribe from the store
Used to get the connection for the currently active chain
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getConnection.mdx#getconnection\",\"isPage\":true,\"text\":\"\\nUsed to get the connection for the currently active chain\\n\",\"title\":\"getConnection\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/getConnection#import\",\"html\":\"\\nimport { getConnection } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getConnection.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getConnection } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"getConnection\"]},{\"href\":\"/reference/account-kit/core/functions/getConnection#usage\",\"html\":\"\\nimport { getConnection } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst connection = getConnection(config);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getConnection.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getConnection } from "@account-kit/core";\\nimport { config } from "./config";\\n \\nconst connection = getConnection(config);\\n\",\"title\":\"Usage\",\"titles\":[\"getConnection\"]},{\"href\":\"/reference/account-kit/core/functions/getConnection#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/getConnection.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getConnection\"]},{\"href\":\"/reference/account-kit/core/functions/getConnection#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config
Connection
\\na connection object for the current active chain
Combines multiple signatures with provided upper limit values for gas fees and returns the concatenated result.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/combineSignatures.mdx#combinesignatures\",\"isPage\":true,\"text\":\"\\nCombines multiple signatures with provided upper limit values for gas fees and returns the concatenated result.\\n\",\"title\":\"combineSignatures\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/combineSignatures#import\",\"html\":\"\\nimport { combineSignatures } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/combineSignatures.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { combineSignatures } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"combineSignatures\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/combineSignatures#usage\",\"html\":\"\\nimport { combineSignatures } from "@account-kit/smart-contracts";\\n \\nconst combinedSignature = combineSignatures({\\n// this is the upper limit pre-verification gas\\nupperLimitPvg: "0x01",\\nupperLimitMaxFeePerGas: "0x02",\\nupperLimitMaxPriorityFeePerGas: "0x03",\\nsignatures: [{\\nsignerType: "EOA",\\nuserOpSigType: "UPPERLIMIT",\\nsigner: `0x...`,\\nsignature: `0x...`,\\n}]\\nusingMaxValues: false,\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/combineSignatures.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { combineSignatures } from "@account-kit/smart-contracts";\\n \\nconst combinedSignature = combineSignatures({\\n// this is the upper limit pre-verification gas\\nupperLimitPvg: "0x01",\\nupperLimitMaxFeePerGas: "0x02",\\nupperLimitMaxPriorityFeePerGas: "0x03",\\nsignatures: [{\\nsignerType: "EOA",\\nuserOpSigType: "UPPERLIMIT",\\nsigner: `0x...`,\\nsignature: `0x...`,\\n}]\\nusingMaxValues: false,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"combineSignatures\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/combineSignatures#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/combineSignatures.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"combineSignatures\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/combineSignatures#params\",\"html\":\"\\nCombineSignaturesParams
\\nThe function parameters
Hex
\\nThe concatenated result of padding and formatting the provided values and signatures
Gets the currently active chain
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getChain.mdx#getchain\",\"isPage\":true,\"text\":\"\\nGets the currently active chain\\n\",\"title\":\"getChain\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/getChain#import\",\"html\":\"\\nimport { getChain } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/getChain.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getChain } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"getChain\"]},{\"href\":\"/reference/account-kit/core/functions/getChain#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/getChain.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getChain\"]},{\"href\":\"/reference/account-kit/core/functions/getChain#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config object
Chain
\\nthe currently active chain
Creates a modular account Alchemy client with the provided configuration.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient.mdx#createmodularaccountalchemyclient\",\"isPage\":true,\"text\":\"\\nCreates a modular account Alchemy client with the provided configuration.\\n\",\"title\":\"createModularAccountAlchemyClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient#import\",\"html\":\"\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createModularAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient#usage\",\"html\":\"\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst alchemyAccountClient = await createModularAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst alchemyAccountClient = await createModularAccountAlchemyClient({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createModularAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createModularAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createModularAccountAlchemyClient#config\",\"html\":\"\\nAlchemyModularAccountClientConfig
\\nThe configuration for creating the Alchemy client
Promise<AlchemySmartAccountClient>
\\nA promise that resolves to an AlchemySmartAccountClient
configured with the desired plugins and actions
Allows you to subscribe to changes of the chain in the client store.
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchChain.mdx#watchchain\",\"isPage\":true,\"text\":\"\\nAllows you to subscribe to changes of the chain in the client store.\\n\",\"title\":\"watchChain\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/functions/watchChain#import\",\"html\":\"\\nimport { watchChain } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchChain.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { watchChain } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"watchChain\"]},{\"href\":\"/reference/account-kit/core/functions/watchChain#usage\",\"html\":\"\\nimport { watchChain } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchChain(config)(console.log);
\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchChain.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { watchChain } from "@account-kit/core";\\n// see createConfig for more information on how to create a config\\nimport { config } from "./config";\\n \\nwatchChain(config)(console.log);\\n\",\"title\":\"Usage\",\"titles\":[\"watchChain\"]},{\"href\":\"/reference/account-kit/core/functions/watchChain#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/functions/watchChain.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"watchChain\"]},{\"href\":\"/reference/account-kit/core/functions/watchChain#config\",\"html\":\"\\nAlchemyAccountsConfig
\\nthe account config object
(onChange: (chain: Chain) => void) => (() => void)
\\na function which accepts an onChange callback that will be fired when the chain changes and returns a function to unsubscribe from the store
Provides a set of actions for account loupe operations using the specified client.\\nNOTE: this is already added to the client when using any of the Modular Account Clients.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/accountLoupeActions.mdx#accountloupeactions\",\"isPage\":true,\"text\":\"\\nProvides a set of actions for account loupe operations using the specified client.\\nNOTE: this is already added to the client when using any of the Modular Account Clients.\\n\",\"title\":\"accountLoupeActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/accountLoupeActions#import\",\"html\":\"\\nimport { accountLoupeActions } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/accountLoupeActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { accountLoupeActions } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"accountLoupeActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/accountLoupeActions#usage\",\"html\":\"\\nimport { accountLoupeActions } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...).extend(accountLoupeActions);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/accountLoupeActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { accountLoupeActions } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...).extend(accountLoupeActions);\\n\",\"title\":\"Usage\",\"titles\":[\"accountLoupeActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/accountLoupeActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/accountLoupeActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"accountLoupeActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/accountLoupeActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nthe client to be used for executing the account loupe actions
AccountLoupeActions<TAccount>
\\nan object containing account loupe actions like getExecutionFunctionConfig
, getExecutionHooks
, getPreValidationHooks
, and getInstalledPlugins
Creates a multi-owner light account client using the provided parameters. It first creates a multi-owner light account and then creates a smart account client with the provided configurations.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient.mdx#createmultiownerlightaccountclient\",\"isPage\":true,\"text\":\"\\nCreates a multi-owner light account client using the provided parameters. It first creates a multi-owner light account and then creates a smart account client with the provided configurations.\\n\",\"title\":\"createMultiOwnerLightAccountClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient#import\",\"html\":\"\\nimport { createMultiOwnerLightAccountClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerLightAccountClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultiOwnerLightAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient#usage\",\"html\":\"\\nimport { createMultiOwnerLightAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createMultiOwnerLightAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerLightAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createMultiOwnerLightAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultiOwnerLightAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultiOwnerLightAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerLightAccountClient#params\",\"html\":\"\\nCreateMultiOwnerLightAccountClientParams
\\nthe configuration for creating the multi-owner light account client
Promise<SmartAccountClient>
\\na promise that resolves to a SmartAccountClient
containing the created account client and relevant methods
Creates a multi-owner modular account with the given parameters, including transport, chain, signer, account address, initialization code, entry point, factory address, owners, and salt.\\nEnsures that the owners are unique, ordered, and non-zero.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount.mdx#createmultiownermodularaccount\",\"isPage\":true,\"text\":\"\\nCreates a multi-owner modular account with the given parameters, including transport, chain, signer, account address, initialization code, entry point, factory address, owners, and salt.\\nEnsures that the owners are unique, ordered, and non-zero.\\n\",\"title\":\"createMultiOwnerModularAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount#import\",\"html\":\"\\nimport { createMultiOwnerModularAccount } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerModularAccount } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultiOwnerModularAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount#usage\",\"html\":\"\\nimport { createMultiOwnerModularAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createMultiOwnerModularAccount({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerModularAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem";\\n \\nconst account = await createMultiOwnerModularAccount({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultiOwnerModularAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultiOwnerModularAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccount#config\",\"html\":\"\\nCreateMultiOwnerModularAccountParams
\\nConfiguration parameters for creating a multi-owner modular account
Promise<MultiOwnerModularAccount>
\\nA promise that resolves to a MultiOwnerModularAccount
object containing the created account information and methods
Creates a multi-owner modular account client with the provided parameters including account, transport, chain, and additional client configuration. This function uses a modular account and extends it with various plugin actions.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient.mdx#createmultiownermodularaccountclient\",\"isPage\":true,\"text\":\"\\nCreates a multi-owner modular account client with the provided parameters including account, transport, chain, and additional client configuration. This function uses a modular account and extends it with various plugin actions.\\n\",\"title\":\"createMultiOwnerModularAccountClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient#import\",\"html\":\"\\nimport { createMultiOwnerModularAccountClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerModularAccountClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultiOwnerModularAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient#usage\",\"html\":\"\\nimport { createMultiOwnerModularAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nconst accountClient = await createMultiOwnerModularAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultiOwnerModularAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nconst accountClient = await createMultiOwnerModularAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultiOwnerModularAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultiOwnerModularAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultiOwnerModularAccountClient#config\",\"html\":\"\\nCreateMultiOwnerModularAccountClientParams
\\nThe parameters for creating the multi-owner modular account client
Promise<SmartAccountClient>
\\nA promise that resolves to a SmartAccountClient
instance with extended plugin actions
Creates a multisig modular account client using the provided parameters including account details, transport, chain, and additional client configuration. This function constructs the multisig modular account and extends it with various actions to create a comprehensive client.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient.mdx#createmultisigmodularaccountclient\",\"isPage\":true,\"text\":\"\\nCreates a multisig modular account client using the provided parameters including account details, transport, chain, and additional client configuration. This function constructs the multisig modular account and extends it with various actions to create a comprehensive client.\\n\",\"title\":\"createMultisigModularAccountClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient#import\",\"html\":\"\\nimport { createMultisigModularAccountClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultisigModularAccountClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultisigModularAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient#usage\",\"html\":\"\\nimport { createMultisigModularAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nconst accountClient = await createMultisigModularAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n owners: [], // other owners on the account\\n threshold: 2, // 2 of N signatures\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultisigModularAccountClient } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http } from "viem";\\nimport { generatePrivateKey } from "viem/accounts";\\n \\nconst accountClient = await createMultisigModularAccountClient({\\n chain: sepolia,\\n transport: http("RPC_URL"),\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n owners: [], // other owners on the account\\n threshold: 2, // 2 of N signatures\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultisigModularAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultisigModularAccountClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccountClient#config\",\"html\":\"\\nCreateMultisigModularAccountClientParams
\\nthe parameters for configuring the multisig modular account client
Promise<SmartAccountClient<Transport, Chain, MultisigModularAccount<SmartAccountSigner>, {}, SmartAccountClientRpcSchema, MultisigUserOperationContext>>
\\na promise that resolves to a SmartAccountClient
object extended with the multisig modular account and additional actions
Creates a multisig modular account using the provided parameters, including transport, chain, signer, account address, and other account settings. It configures the account with multiple owners and the specified threshold.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccount.mdx#createmultisigmodularaccount\",\"isPage\":true,\"text\":\"\\nCreates a multisig modular account using the provided parameters, including transport, chain, signer, account address, and other account settings. It configures the account with multiple owners and the specified threshold.\\n\",\"title\":\"createMultisigModularAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccount#import\",\"html\":\"\\nimport { createMultisigModularAccount } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultisigModularAccount } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultisigModularAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccount#usage\",\"html\":\"\\nimport { createMultisigModularAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem"\\n \\nconst account = await createMultisigModularAccount({\\nchain: sepolia,\\ntransport: http("RPC_URL"),\\nsigner: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\nowners: [...], // other owners on the account\\nthreshold: 2, // 2 of N signatures\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultisigModularAccount } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "viem/chains";\\nimport { http, generatePrivateKey } from "viem"\\n \\nconst account = await createMultisigModularAccount({\\nchain: sepolia,\\ntransport: http("RPC_URL"),\\nsigner: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\nowners: [...], // other owners on the account\\nthreshold: 2, // 2 of N signatures\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultisigModularAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigModularAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultisigModularAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigModularAccount#config\",\"html\":\"\\nCreateMultisigModularAccountParams
\\nThe parameters for creating a multisig modular account.
Promise<MultisigModularAccount>
\\nA promise that resolves to a MultisigModularAccount
object containing the created account information and methods.
Get the default light account version for the given light account type
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/defaultLightAccountVersion.mdx#defaultlightaccountversion\",\"isPage\":true,\"text\":\"\\nGet the default light account version for the given light account type\\n\",\"title\":\"defaultLightAccountVersion\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/defaultLightAccountVersion#import\",\"html\":\"\\nimport { defaultLightAccountVersion } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/defaultLightAccountVersion.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { defaultLightAccountVersion } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"defaultLightAccountVersion\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/defaultLightAccountVersion#returns\",\"html\":\"\\nLightAccountVersion<TLightAccountType>
\\nthe default version for the given light account type
Creates an Alchemy client for a multisig account using the provided configuration.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient.mdx#createmultisigaccountalchemyclient\",\"isPage\":true,\"text\":\"\\nCreates an Alchemy client for a multisig account using the provided configuration.\\n\",\"title\":\"createMultisigAccountAlchemyClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient#import\",\"html\":\"\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"createMultisigAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient#usage\",\"html\":\"\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem"\\n \\nconst alchemyAccountClient = await createMultisigAccountAlchemyClient({\\napiKey: "your-api-key",\\nchain: sepolia,\\nsigner: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\nowners: [...], // other owners on the account\\nthreshold: 2, // 2 of N signatures\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createMultisigAccountAlchemyClient } from "@account-kit/smart-contracts";\\nimport { sepolia } from "@account-kit/infra";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem"\\n \\nconst alchemyAccountClient = await createMultisigAccountAlchemyClient({\\napiKey: "your-api-key",\\nchain: sepolia,\\nsigner: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\nowners: [...], // other owners on the account\\nthreshold: 2, // 2 of N signatures\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createMultisigAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createMultisigAccountAlchemyClient\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/createMultisigAccountAlchemyClient#config\",\"html\":\"\\nAlchemyMultisigAccountClientConfig
\\nThe configuration for the Alchemy multisig account client
Promise<AlchemySmartAccountClient<Transport, Chain | undefined, MultisigModularAccount<SmartAccountSigner>, MultisigPluginActions<MultisigModularAccount<SmartAccountSigner>> & PluginManagerActions<MultisigModularAccount<SmartAccountSigner>> & AccountLoupeActions<MultisigModularAccount<SmartAccountSigner>>, MultisigUserOperationContext>>
\\nA promise that resolves to an Alchemy Smart Account Client for multisig accounts with extended functionalities.
Utility method returning the default light account factory address given a Chain object
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultLightAccountFactoryAddress.mdx#getdefaultlightaccountfactoryaddress\",\"isPage\":true,\"text\":\"\\nUtility method returning the default light account factory address given a Chain object\\n\",\"title\":\"getDefaultLightAccountFactoryAddress\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultLightAccountFactoryAddress#import\",\"html\":\"\\nimport { getDefaultLightAccountFactoryAddress } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultLightAccountFactoryAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getDefaultLightAccountFactoryAddress } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getDefaultLightAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultLightAccountFactoryAddress#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultLightAccountFactoryAddress.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getDefaultLightAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultLightAccountFactoryAddress#chain\",\"html\":\"\\nChain
LightAccountVersion
Address
\\nan for the given chain
Formats a collection of Signature objects into a single aggregated signature.\\nThe format is in the form of EOA_SIGS | CONTRACT_SIG_DATAS. The signatures are ordered\\nby signer address. The EOA SIGS contain the 65 signautre data for EOA signers and 65 bytes containing SIGNER | OFFSET | V for contract signers.\\nThe OFFSET is used to fetch the signature data from the CONTRACT_SIG_DATAS.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/formatSignatures.mdx#formatsignatures\",\"isPage\":true,\"text\":\"\\nFormats a collection of Signature objects into a single aggregated signature.\\nThe format is in the form of EOA_SIGS | CONTRACT_SIG_DATAS. The signatures are ordered\\nby signer address. The EOA SIGS contain the 65 signautre data for EOA signers and 65 bytes containing SIGNER | OFFSET | V for contract signers.\\nThe OFFSET is used to fetch the signature data from the CONTRACT_SIG_DATAS.\\n\",\"title\":\"formatSignatures\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/formatSignatures#import\",\"html\":\"\\nimport { formatSignatures } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/formatSignatures.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { formatSignatures } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"formatSignatures\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/formatSignatures#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/formatSignatures.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"formatSignatures\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/formatSignatures#signatures\",\"html\":\"\\nSignature[]
\\nthe array of Signature objects to combine into the correct aggregated signature format excluding the upper limits
boolean
\\na boolean indicating wether or not the UserOperation is using the UPPER_LIMIT for the gas and fee values
Hex
\\nthe Hex representation of the signature
Determines the type of signer (Externally Owned Account (EOA) or CONTRACT) based on the provided client, signature, and signer.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getSignerType.mdx#getsignertype\",\"isPage\":true,\"text\":\"\\nDetermines the type of signer (Externally Owned Account (EOA) or CONTRACT) based on the provided client, signature, and signer.\\n\",\"title\":\"getSignerType\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getSignerType#import\",\"html\":\"\\nimport { getSignerType } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getSignerType.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getSignerType } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getSignerType\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getSignerType#usage\",\"html\":\"\\nimport { getSignerType } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { createPublicClient, generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey());\\nconst client = createPublicClient(...);\\nconst signature = signer.signMessage("Hello World");\\n \\nconst signerType = await getSignerType({ client, signature, signer }); // EOA
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getSignerType.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getSignerType } from "@account-kit/smart-contracts";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { createPublicClient, generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey());\\nconst client = createPublicClient(...);\\nconst signature = signer.signMessage("Hello World");\\n \\nconst signerType = await getSignerType({ client, signature, signer }); // EOA\\n\",\"title\":\"Usage\",\"titles\":[\"getSignerType\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getSignerType#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getSignerType.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getSignerType\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getSignerType#params\",\"html\":\"\\nGetSignerTypeParams<TTransport, TChain>
\\nthe parameters including the client, signature, and signer
Promise<SignerType>
\\nA promise that resolves to the signer type, which is either "EOA" or "CONTRACT"
Utility method returning the default multi owner msca factory address given a chain
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerModularAccountFactoryAddress.mdx#getdefaultmultiownermodularaccountfactoryaddress\",\"isPage\":true,\"text\":\"\\nUtility method returning the default multi owner msca factory address given a chain\\n\",\"title\":\"getDefaultMultiOwnerModularAccountFactoryAddress\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerModularAccountFactoryAddress#import\",\"html\":\"\\nimport { getDefaultMultiOwnerModularAccountFactoryAddress } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerModularAccountFactoryAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getDefaultMultiOwnerModularAccountFactoryAddress } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getDefaultMultiOwnerModularAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerModularAccountFactoryAddress#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerModularAccountFactoryAddress.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getDefaultMultiOwnerModularAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerModularAccountFactoryAddress#chain\",\"html\":\"\\nChain
\\nthe chain object for which to get the address
Address
\\nthe address for the given chain
Get the light account version definition for the given light account and chain
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getLightAccountVersionForAccount.mdx#getlightaccountversionforaccount\",\"isPage\":true,\"text\":\"\\nGet the light account version definition for the given light account and chain\\n\",\"title\":\"getLightAccountVersionForAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getLightAccountVersionForAccount#import\",\"html\":\"\\nimport { getLightAccountVersionForAccount } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getLightAccountVersionForAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getLightAccountVersionForAccount } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getLightAccountVersionForAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getLightAccountVersionForAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getLightAccountVersionForAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getLightAccountVersionForAccount\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getLightAccountVersionForAccount#account\",\"html\":\"\\nLightAccountBase
\\nthe light account to get the version for
Chain
Promise<LightAccountVersionConfig>
\\nthe light account version definition for the given light account and chain
Utility method returning the default multi owner light account factory address given a Chain object
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerLightAccountFactoryAddress.mdx#getdefaultmultiownerlightaccountfactoryaddress\",\"isPage\":true,\"text\":\"\\nUtility method returning the default multi owner light account factory address given a Chain object\\n\",\"title\":\"getDefaultMultiOwnerLightAccountFactoryAddress\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerLightAccountFactoryAddress#import\",\"html\":\"\\nimport { getDefaultMultiOwnerLightAccountFactoryAddress } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerLightAccountFactoryAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getDefaultMultiOwnerLightAccountFactoryAddress } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getDefaultMultiOwnerLightAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerLightAccountFactoryAddress#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerLightAccountFactoryAddress.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getDefaultMultiOwnerLightAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultiOwnerLightAccountFactoryAddress#chain\",\"html\":\"\\nChain
string
Address
\\nan Address for the given chain
Retrieves the initialization data for a multi-owner modular account. Throws an error if the client's chain is not found or if the multi-owner plugin address is not retrievable.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMAInitializationData.mdx#getmainitializationdata\",\"isPage\":true,\"text\":\"\\nRetrieves the initialization data for a multi-owner modular account. Throws an error if the client's chain is not found or if the multi-owner plugin address is not retrievable.\\n\",\"title\":\"getMAInitializationData\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMAInitializationData#import\",\"html\":\"\\nimport { getMAInitializationData } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMAInitializationData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getMAInitializationData } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getMAInitializationData\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMAInitializationData#usage\",\"html\":\"\\nimport { getMAInitializationData } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...);\\nconst initializationData = await getMAInitializationData({\\nclient,\\nsignerAddress: "0x...", // or array of signers\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMAInitializationData.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getMAInitializationData } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...);\\nconst initializationData = await getMAInitializationData({\\nclient,\\nsignerAddress: "0x...", // or array of signers\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"getMAInitializationData\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMAInitializationData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMAInitializationData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getMAInitializationData\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMAInitializationData#params\",\"html\":\"\\nGetMAInitializationDataParams<TTransport, TChain, TAccount>
\\nthe parameters for getting initialization data
SmartAccountClient<TTransport, TChain, TAccount>
\\nthe smart account client
Address | Address[]
\\nthe address of the signer or an array of signer addresses
Address
\\noptional address of the multi-owner plugin
Promise<UpgradeToData>
\\na promise that resolves to the initialization data required for upgrading to a multi-owner modular account
Utility method returning the default multi sig msca factory address given a chain
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultisigModularAccountFactoryAddress.mdx#getdefaultmultisigmodularaccountfactoryaddress\",\"isPage\":true,\"text\":\"\\nUtility method returning the default multi sig msca factory address given a chain\\n\",\"title\":\"getDefaultMultisigModularAccountFactoryAddress\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultisigModularAccountFactoryAddress#import\",\"html\":\"\\nimport { getDefaultMultisigModularAccountFactoryAddress } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultisigModularAccountFactoryAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getDefaultMultisigModularAccountFactoryAddress } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getDefaultMultisigModularAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultisigModularAccountFactoryAddress#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getDefaultMultisigModularAccountFactoryAddress.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getDefaultMultisigModularAccountFactoryAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getDefaultMultisigModularAccountFactoryAddress#chain\",\"html\":\"\\nChain
\\nthe chain object for which to get the address
Address
\\nthe address for the given chain
Retrieves the data necessary to upgrade to a Multi-Signature Contract Account (MSCA) and provides a method to create a Multi-Owner Modular Account.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData.mdx#getmscaupgradetodata\",\"isPage\":true,\"text\":\"\\nRetrieves the data necessary to upgrade to a Multi-Signature Contract Account (MSCA) and provides a method to create a Multi-Owner Modular Account.\\n\",\"title\":\"getMSCAUpgradeToData\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData#import\",\"html\":\"\\nimport { getMSCAUpgradeToData } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getMSCAUpgradeToData } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getMSCAUpgradeToData\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData#usage\",\"html\":\"\\nimport { createLightAccountClient, getMSCAUpgradeToData } from "@account-kit/smart-contracts";\\n \\nconst client = createLightAccountClient(...);\\nconst upgradeData = await getMSCAUpgradeToData(client, {});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createLightAccountClient, getMSCAUpgradeToData } from "@account-kit/smart-contracts";\\n \\nconst client = createLightAccountClient(...);\\nconst upgradeData = await getMSCAUpgradeToData(client, {});\\n\",\"title\":\"Usage\",\"titles\":[\"getMSCAUpgradeToData\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getMSCAUpgradeToData\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/getMSCAUpgradeToData#client\",\"html\":\"\\nSmartAccountClient<TTransport, TChain, TAccount>
\\nThe smart account client
GetMSCAUpgradeToData<TSigner, TAccount>
\\nThe arguments required for the upgrade
Promise<UpgradeToData & { createMAAccount: () => Promise<MultiOwnerModularAccount<TSigner>>}>
\\nA promise that resolves to upgrade data augmented with a function to create a Multi-Owner Modular Account
Generates client actions for a multi-owner light account, including the ability to update owners.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions.mdx#multiownerlightaccountclientactions\",\"isPage\":true,\"text\":\"\\nGenerates client actions for a multi-owner light account, including the ability to update owners.\\n\",\"title\":\"multiOwnerLightAccountClientActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions#import\",\"html\":\"\\nimport { multiOwnerLightAccountClientActions } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { multiOwnerLightAccountClientActions } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"multiOwnerLightAccountClientActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions#usage\",\"html\":\"\\nimport { multiOwnerLightAccountClientActions, createMultiOwnerLightAccount } from "@account-kit/smart-contracts";\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst smartAccountClient = createAlchemySmartAccountClient({\\naccount: await createMultiOwnerLightAccount(...),\\napiKey: "your-api-key",\\nchain: sepolia,\\n}).extend(multiOwnerLightAccountClientActions);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { multiOwnerLightAccountClientActions, createMultiOwnerLightAccount } from "@account-kit/smart-contracts";\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst smartAccountClient = createAlchemySmartAccountClient({\\naccount: await createMultiOwnerLightAccount(...),\\napiKey: "your-api-key",\\nchain: sepolia,\\n}).extend(multiOwnerLightAccountClientActions);\\n\",\"title\":\"Usage\",\"titles\":[\"multiOwnerLightAccountClientActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"multiOwnerLightAccountClientActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerLightAccountClientActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nthe client for interacting with the multi-owner light account
MultiOwnerLightAccountClientActions<TSigner, TAccount>
\\nan object containing the client actions specifically for a multi-owner light account
Installs a plugin on a smart account via the client, sending the user operation with the appropriate parameters.\\nNOTE: it's recommended to just use the installPlugin action returned from generated plugins
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/installPlugin.mdx#installplugin\",\"isPage\":true,\"text\":\"\\nInstalls a plugin on a smart account via the client, sending the user operation with the appropriate parameters.\\nNOTE: it's recommended to just use the installPlugin action returned from generated plugins\\n\",\"title\":\"installPlugin\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/installPlugin#import\",\"html\":\"\\nimport { installPlugin } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/installPlugin.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { installPlugin } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"installPlugin\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/installPlugin#usage\",\"html\":\"\\nimport { installPlugin, createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst client = createModularAccountAlchemyClient(...);\\n \\nconst hash = await installPlugin(client, {\\npluginAddress: "0x...",\\nmanifestHash: "0x...",\\ndependencies: [], // this is defined by the plugin you're installing\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/installPlugin.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { installPlugin, createModularAccountAlchemyClient } from "@account-kit/smart-contracts";\\n \\nconst client = createModularAccountAlchemyClient(...);\\n \\nconst hash = await installPlugin(client, {\\npluginAddress: "0x...",\\nmanifestHash: "0x...",\\ndependencies: [], // this is defined by the plugin you're installing\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"installPlugin\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/installPlugin#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/installPlugin.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"installPlugin\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/installPlugin#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client configured to the smart account on which the plugin will be installed
InstallPluginParams<TAccount, TContext>
\\nThe parameters required to install the plugin, including overrides, context, and account information
Promise<any>
\\nA promise that resolves once the plugin installation operation is sent
Provides a set of actions for managing a light account client, including transferring ownership.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/lightAccountClientActions.mdx#lightaccountclientactions\",\"isPage\":true,\"text\":\"\\nProvides a set of actions for managing a light account client, including transferring ownership.\\n\",\"title\":\"lightAccountClientActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/lightAccountClientActions#import\",\"html\":\"\\nimport { lightAccountClientActions } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/lightAccountClientActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { lightAccountClientActions } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"lightAccountClientActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/lightAccountClientActions#usage\",\"html\":\"\\nimport { lightAccountClientActions, createLightAccount } from "@account-kit/smart-contracts";\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst smartAccountClient = createAlchemySmartAccountClient({\\naccount: await createLightAccount(...),\\napiKey: "your-api-key",\\nchain: sepolia,\\n}).extend(lightAccountClientActions);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/lightAccountClientActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { lightAccountClientActions, createLightAccount } from "@account-kit/smart-contracts";\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst smartAccountClient = createAlchemySmartAccountClient({\\naccount: await createLightAccount(...),\\napiKey: "your-api-key",\\nchain: sepolia,\\n}).extend(lightAccountClientActions);\\n\",\"title\":\"Usage\",\"titles\":[\"lightAccountClientActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/lightAccountClientActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/lightAccountClientActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"lightAccountClientActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/lightAccountClientActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance for which to provide the light account actions
LightAccountClientActions<TSigner, TAccount>
\\nAn object containing the available light account client actions
Creates actions for the MultiOwner plugin, including reading owners and checking ownership.\\nNOTE: this is already added to the client returned from createMultiOwnerModularAccountClient
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions.mdx#multiownerpluginactions\",\"isPage\":true,\"text\":\"\\nCreates actions for the MultiOwner plugin, including reading owners and checking ownership.\\nNOTE: this is already added to the client returned from createMultiOwnerModularAccountClient\\n\",\"title\":\"multiOwnerPluginActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions#import\",\"html\":\"\\nimport { multiOwnerPluginActions } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { multiOwnerPluginActions } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"multiOwnerPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions#usage\",\"html\":\"\\nimport { multiOwnerPluginActions } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...).extend(multiOwnerPluginActions);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { multiOwnerPluginActions } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...).extend(multiOwnerPluginActions);\\n\",\"title\":\"Usage\",\"titles\":[\"multiOwnerPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"multiOwnerPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multiOwnerPluginActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nthe client instance containing the transport, chain, and account information
MultiOwnerPluginActions<TAccount>
\\nan object containing the actions for the MultiOwner plugin, such as readOwners
and isOwnerOf
Provides actions for managing a multisig plugin within the specified client, including reading owners, checking ownership, getting the threshold, proposing user operations, and signing multisig user operations.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multisigPluginActions.mdx#multisigpluginactions\",\"isPage\":true,\"text\":\"\\nProvides actions for managing a multisig plugin within the specified client, including reading owners, checking ownership, getting the threshold, proposing user operations, and signing multisig user operations.\\n\",\"title\":\"multisigPluginActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multisigPluginActions#import\",\"html\":\"\\nimport { multisigPluginActions } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multisigPluginActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { multisigPluginActions } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"multisigPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multisigPluginActions#usage\",\"html\":\"\\nimport { createModularAccountAlchemyClient, multisigPluginActions } from "@account-kit/smart-contracts";\\n \\nconst client = createModularAccountAlchemyClient(...).extend(multisigPluginActions);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multisigPluginActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createModularAccountAlchemyClient, multisigPluginActions } from "@account-kit/smart-contracts";\\n \\nconst client = createModularAccountAlchemyClient(...).extend(multisigPluginActions);\\n\",\"title\":\"Usage\",\"titles\":[\"multisigPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multisigPluginActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multisigPluginActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"multisigPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multisigPluginActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance configured with transport, chain, and account information
MultisigPluginActions<TAccount>
\\nAn object containing methods to perform actions related to the multisig plugin
A signer middleware to be used with Multisig Account Clients.\\nThis middleware handles correctly aggregating signatures passed through\\nas context when sending UserOperations, proposing UserOperations, or adding signatures to a UserOperation.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multisigSignatureMiddleware.mdx#multisigsignaturemiddleware\",\"isPage\":true,\"text\":\"\\nA signer middleware to be used with Multisig Account Clients.\\nThis middleware handles correctly aggregating signatures passed through\\nas context when sending UserOperations, proposing UserOperations, or adding signatures to a UserOperation.\\n\",\"title\":\"multisigSignatureMiddleware\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multisigSignatureMiddleware#import\",\"html\":\"\\nimport { multisigSignatureMiddleware } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multisigSignatureMiddleware.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { multisigSignatureMiddleware } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"multisigSignatureMiddleware\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multisigSignatureMiddleware#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/multisigSignatureMiddleware.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"multisigSignatureMiddleware\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/multisigSignatureMiddleware#struct\",\"html\":\"\\nDeferrable<UserOperationStruct<TEntryPointVersion>>
\\nthe user operation struct to be signed
ClientMiddlewareArgs<TAccount, C, TContext, TEntryPointVersion>
\\nthe parameters to be passed to the middleware
UserOperationOverrides<TEntryPointVersion>
\\nthe account to be used for signing
MiddlewareClient
\\nthe smart account client that will be used for RPC requests
MultisigUserOperationContext
\\nthe context object containing the signatures to be aggregated MultisigUserOperationContext
Promise<Deferrable<UserOperationStruct<TEntryPointVersion>>>
\\na Promise containing a UserOperation with an aggregated signature in the signature
field
Paymaster middleware factory that uses Alchemy's Gas Manager for sponsoring transactions.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyGasManagerMiddleware.mdx#alchemygasmanagermiddleware\",\"isPage\":true,\"text\":\"\\nPaymaster middleware factory that uses Alchemy's Gas Manager for sponsoring transactions.\\n\",\"title\":\"alchemyGasManagerMiddleware\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/alchemyGasManagerMiddleware#import\",\"html\":\"\\nimport { alchemyGasManagerMiddleware } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyGasManagerMiddleware.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { alchemyGasManagerMiddleware } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"alchemyGasManagerMiddleware\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyGasManagerMiddleware#usage\",\"html\":\"\\n \\nimport { sepolia } from "@account-kit/infra";\\nimport { http } from "viem";\\n \\nconst client = createSmartAccountClient({\\n http("rpc-url"),\\n sepolia,\\n alchemyErc7677Middleware("policyId")\\n);
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyGasManagerMiddleware.mdx#usage\",\"isPage\":false,\"text\":\"\\n \\nimport { sepolia } from "@account-kit/infra";\\nimport { http } from "viem";\\n \\nconst client = createSmartAccountClient({\\n http("rpc-url"),\\n sepolia,\\n alchemyErc7677Middleware("policyId")\\n);\\n\",\"title\":\"Usage\",\"titles\":[\"alchemyGasManagerMiddleware\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyGasManagerMiddleware#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyGasManagerMiddleware.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"alchemyGasManagerMiddleware\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyGasManagerMiddleware#policyid\",\"html\":\"\\nstring
\\nthe policyId for Alchemy's gas manager
Pick<ClientMiddlewareConfig, "dummyPaymasterAndData" | "paymasterAndData">
\\npartial client middleware configuration containing dummyPaymasterAndData
and paymasterAndData
Function that estimates the transaction fees using Alchemy methods for a given client.\\nIt fetches the latest block and estimates the max priority fee per gas, applying any overrides or fee options provided.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyFeeEstimator.mdx#alchemyfeeestimator\",\"isPage\":true,\"text\":\"\\nFunction that estimates the transaction fees using Alchemy methods for a given client.\\nIt fetches the latest block and estimates the max priority fee per gas, applying any overrides or fee options provided.\\n\",\"title\":\"alchemyFeeEstimator\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/alchemyFeeEstimator#import\",\"html\":\"\\nimport { alchemyFeeEstimator } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyFeeEstimator.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { alchemyFeeEstimator } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"alchemyFeeEstimator\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyFeeEstimator#usage\",\"html\":\"\\nimport { alchemyFeeEstimator, createAlchemyPublicRpcClient } from "@account-kit/infra";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst bundlerClient = createAlchemyPublicRpcClient(...);\\nconst client = createSmartAccountClient({\\nfeeEstimator: alchemyFeeEstimator(bundlerClient),\\n...otherParams\\n});
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyFeeEstimator.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { alchemyFeeEstimator, createAlchemyPublicRpcClient } from "@account-kit/infra";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst bundlerClient = createAlchemyPublicRpcClient(...);\\nconst client = createSmartAccountClient({\\nfeeEstimator: alchemyFeeEstimator(bundlerClient),\\n...otherParams\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"alchemyFeeEstimator\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyFeeEstimator#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyFeeEstimator.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"alchemyFeeEstimator\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyFeeEstimator#client\",\"html\":\"\\nClientWithAlchemyMethods
\\nThe client with Alchemy methods
ClientMiddlewareFn
\\nA middleware function that takes a transaction structure and fee options, and returns the augmented structure with estimated fees
Provides actions for managing plugins on a given client, including installing and uninstalling plugins.\\nNOTE: this is provided by default when using a modular account client
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/pluginManagerActions.mdx#pluginmanageractions\",\"isPage\":true,\"text\":\"\\nProvides actions for managing plugins on a given client, including installing and uninstalling plugins.\\nNOTE: this is provided by default when using a modular account client\\n\",\"title\":\"pluginManagerActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/pluginManagerActions#import\",\"html\":\"\\nimport { pluginManagerActions } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/pluginManagerActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { pluginManagerActions } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"pluginManagerActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/pluginManagerActions#usage\",\"html\":\"\\nimport { pluginManagerActions } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...).extend(pluginManagerActions);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/pluginManagerActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { pluginManagerActions } from "@account-kit/smart-contracts";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst client = createSmartAccountClient(...).extend(pluginManagerActions);\\n\",\"title\":\"Usage\",\"titles\":[\"pluginManagerActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/pluginManagerActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/pluginManagerActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"pluginManagerActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/pluginManagerActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance on which to manage plugins
PluginManagerActions<TAccount>
\\nAn object containing functions to install and uninstall plugins
Takes an aggregated signature and threshold and splits it into its components
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/splitAggregatedSignature.mdx#splitaggregatedsignature\",\"isPage\":true,\"text\":\"\\nTakes an aggregated signature and threshold and splits it into its components\\n\",\"title\":\"splitAggregatedSignature\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/splitAggregatedSignature#import\",\"html\":\"\\nimport { splitAggregatedSignature } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/splitAggregatedSignature.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { splitAggregatedSignature } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"splitAggregatedSignature\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/splitAggregatedSignature#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/splitAggregatedSignature.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"splitAggregatedSignature\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/splitAggregatedSignature#args\",\"html\":\"\\nSplitAggregateSignatureParams<TAccount>
Hex
number
SmartContractAccount
UserOperationRequest<TEntryPointVersion>
Promise<SplitAggregateSignatureResult>
\\nthe signature split into its upper limits and current signatures
Provides a set of actions for interacting with the Alchemy Smart Account client, including the ability to simulate user operations.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyActions.mdx#alchemyactions\",\"isPage\":true,\"text\":\"\\nProvides a set of actions for interacting with the Alchemy Smart Account client, including the ability to simulate user operations.\\n\",\"title\":\"alchemyActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/alchemyActions#import\",\"html\":\"\\nimport { alchemyActions } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { alchemyActions } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"alchemyActions\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyActions#usage\",\"html\":\"\\nimport { alchemyActions } from "@account-kit/infra";\\nimport { createPublicClient } from "viem";\\n \\nconst client = createPublicClient(...);\\nconst clientWithAlchemyActions = client.extend(alchemyActions);
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { alchemyActions } from "@account-kit/infra";\\nimport { createPublicClient } from "viem";\\n \\nconst client = createPublicClient(...);\\nconst clientWithAlchemyActions = client.extend(alchemyActions);\\n\",\"title\":\"Usage\",\"titles\":[\"alchemyActions\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"alchemyActions\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance used to perform actions
AlchemySmartAccountClientActions<TAccount, TContext>
\\nAn object containing Alchemy Smart Account client actions
Creates actions for managing session keys in a smart contract associated with a client, including adding, removing, rotating, and updating session key permissions.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions.mdx#sessionkeypluginactions\",\"isPage\":true,\"text\":\"\\nCreates actions for managing session keys in a smart contract associated with a client, including adding, removing, rotating, and updating session key permissions.\\n\",\"title\":\"sessionKeyPluginActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions#import\",\"html\":\"\\nimport { sessionKeyPluginActions } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { sessionKeyPluginActions } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"sessionKeyPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions#usage\",\"html\":\"\\nimport { createModularAccountAlchemyClient, sessionKeyPluginActions } from "@account-kit/smart-contracts";\\n \\nconst client = createModularAccountAlchemyClient(...).extend(sessionKeyPluginActions);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createModularAccountAlchemyClient, sessionKeyPluginActions } from "@account-kit/smart-contracts";\\n \\nconst client = createModularAccountAlchemyClient(...).extend(sessionKeyPluginActions);\\n\",\"title\":\"Usage\",\"titles\":[\"sessionKeyPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"sessionKeyPluginActions\"]},{\"href\":\"/reference/account-kit/smart-contracts/functions/sessionKeyPluginActions#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance to use for managing session keys
SessionKeyPluginActions<TAccount>
\\nAn object containing methods for session key management and interaction with the smart contract
Given an instance of the Alchemy SDK, returns a smart account client decorator which contains actions for interacting Alchemy's enhanced APIs.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyEnhancedApiActions.mdx#alchemyenhancedapiactions\",\"isPage\":true,\"text\":\"\\nGiven an instance of the Alchemy SDK, returns a smart account client decorator which contains actions for interacting Alchemy's enhanced APIs.\\n\",\"title\":\"alchemyEnhancedApiActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/alchemyEnhancedApiActions#import\",\"html\":\"\\nimport { alchemyEnhancedApiActions } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyEnhancedApiActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { alchemyEnhancedApiActions } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"alchemyEnhancedApiActions\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyEnhancedApiActions#usage\",\"html\":\"\\nimport { Alchemy } from "alchemy-sdk";\\nimport { alchemyEnhancedApiActions } from "@account-kit/infra";\\nimport { alchemySCAClient } from "./client";\\n \\nconst alchemy = new Alchemy(...);\\nconst enhancedApiDecorator = alchemyEnhancedApiActions(alchemy);\\nconst withEnhancedApis = alchemySCAClient.extend(enhancedApiDecorator);
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyEnhancedApiActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Alchemy } from "alchemy-sdk";\\nimport { alchemyEnhancedApiActions } from "@account-kit/infra";\\nimport { alchemySCAClient } from "./client";\\n \\nconst alchemy = new Alchemy(...);\\nconst enhancedApiDecorator = alchemyEnhancedApiActions(alchemy);\\nconst withEnhancedApis = alchemySCAClient.extend(enhancedApiDecorator);\\n\",\"title\":\"Usage\",\"titles\":[\"alchemyEnhancedApiActions\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyEnhancedApiActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyEnhancedApiActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"alchemyEnhancedApiActions\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyEnhancedApiActions#alchemy\",\"html\":\"\\nAlchemy
\\nThe Alchemy instance containing the SDK client
(client: AlchemySmartAccountClient) => AlchemyEnhancedApis
\\nA client decorator for Alchemy Smart Account clients that adds the enhanced API methods
Creates an Alchemy smart account client using the provided configuration options, including account details, gas manager configuration, and custom middleware.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemySmartAccountClient.mdx#createalchemysmartaccountclient\",\"isPage\":true,\"text\":\"\\nCreates an Alchemy smart account client using the provided configuration options, including account details, gas manager configuration, and custom middleware.\\n\",\"title\":\"createAlchemySmartAccountClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemySmartAccountClient#import\",\"html\":\"\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemySmartAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"createAlchemySmartAccountClient\"]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemySmartAccountClient#usage\",\"html\":\"\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra/chain";\\n \\nconst client = createAlchemySmartAccountClient({\\n chain: sepolia,\\n apiKey: "your-api-key",\\n});
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemySmartAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createAlchemySmartAccountClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra/chain";\\n \\nconst client = createAlchemySmartAccountClient({\\n chain: sepolia,\\n apiKey: "your-api-key",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createAlchemySmartAccountClient\"]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemySmartAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemySmartAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createAlchemySmartAccountClient\"]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemySmartAccountClient#config\",\"html\":\"\\nAlchemySmartAccountClientConfig
\\nThe configuration for creating the Alchemy smart account client
AlchemySmartAccountClient
\\nAn instance of AlchemySmartAccountClient
configured based on the provided options
A middleware function to be used during simulation of user operations which leverages Alchemy's RPC uo simulation method.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyUserOperationSimulator.mdx#alchemyuseroperationsimulator\",\"isPage\":true,\"text\":\"\\nA middleware function to be used during simulation of user operations which leverages Alchemy's RPC uo simulation method.\\n\",\"title\":\"alchemyUserOperationSimulator\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/alchemyUserOperationSimulator#import\",\"html\":\"\\nimport { alchemyUserOperationSimulator } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyUserOperationSimulator.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { alchemyUserOperationSimulator } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"alchemyUserOperationSimulator\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyUserOperationSimulator#usage\",\"html\":\"\\nimport { alchemyUserOperationSimulator, createAlchemyPublicRpcClient } from "@account-kit/infra";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst bundlerClient = createAlchemyPublicRpcClient(...);\\nconst client = createSmartAccountClient({\\nuserOperationSimulator: alchemyUserOperationSimulator(bundlerClient),\\n...otherParams\\n});
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyUserOperationSimulator.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { alchemyUserOperationSimulator, createAlchemyPublicRpcClient } from "@account-kit/infra";\\nimport { createSmartAccountClient } from "@aa-sdk/core";\\n \\nconst bundlerClient = createAlchemyPublicRpcClient(...);\\nconst client = createSmartAccountClient({\\nuserOperationSimulator: alchemyUserOperationSimulator(bundlerClient),\\n...otherParams\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"alchemyUserOperationSimulator\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyUserOperationSimulator#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/alchemyUserOperationSimulator.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"alchemyUserOperationSimulator\"]},{\"href\":\"/reference/account-kit/infra/functions/alchemyUserOperationSimulator#client\",\"html\":\"\\nC
\\nThe client object with Alchemy methods
ClientMiddlewareFn
\\nA middleware function to simulate and process user operations
Creates an Alchemy public RPC client with the provided chain, connection configuration, and optional fetch options. The client has alchemy methods and can dynamically update HTTP headers.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemyPublicRpcClient.mdx#createalchemypublicrpcclient\",\"isPage\":true,\"text\":\"\\nCreates an Alchemy public RPC client with the provided chain, connection configuration, and optional fetch options. The client has alchemy methods and can dynamically update HTTP headers.\\n\",\"title\":\"createAlchemyPublicRpcClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemyPublicRpcClient#import\",\"html\":\"\\nimport { createAlchemyPublicRpcClient } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemyPublicRpcClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createAlchemyPublicRpcClient } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"createAlchemyPublicRpcClient\"]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemyPublicRpcClient#usage\",\"html\":\"\\nimport { createAlchemyPublicRpcClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst client = createAlchemyPublicRpcClient({\\n chain: sepolia,\\n connectionConfig: {\\n apiKey: "your-api-key",\\n },\\n});
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemyPublicRpcClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { createAlchemyPublicRpcClient } from "@account-kit/infra";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst client = createAlchemyPublicRpcClient({\\n chain: sepolia,\\n connectionConfig: {\\n apiKey: "your-api-key",\\n },\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createAlchemyPublicRpcClient\"]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemyPublicRpcClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/createAlchemyPublicRpcClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createAlchemyPublicRpcClient\"]},{\"href\":\"/reference/account-kit/infra/functions/createAlchemyPublicRpcClient#params\",\"html\":\"\\n{connectionConfig: ConnectionConfig,chain: Chain,fetchOptions?: NoUndefined<HttpTransportConfig["fetchOptions"]>}
\\nThe parameters for creating the Alchemy public RPC client
ConnectionConfig
\\nThe connection configuration containing the RPC URL and API key
Chain
\\nThe blockchain chain configuration
NoUndefined<HttpTransportConfig["fetchOptions"]>
\\nOptional fetch configuration for HTTP transport
ClientWithAlchemyMethods
\\nA client object tailored with Alchemy methods and capabilities to interact with the blockchain
Defines an Alchemy chain configuration by adding an Alchemy-specific RPC base URL to the chain's RPC URLs.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/defineAlchemyChain.mdx#definealchemychain\",\"isPage\":true,\"text\":\"\\nDefines an Alchemy chain configuration by adding an Alchemy-specific RPC base URL to the chain's RPC URLs.\\n\",\"title\":\"defineAlchemyChain\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/defineAlchemyChain#import\",\"html\":\"\\nimport { defineAlchemyChain } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/defineAlchemyChain.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { defineAlchemyChain } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"defineAlchemyChain\"]},{\"href\":\"/reference/account-kit/infra/functions/defineAlchemyChain#usage\",\"html\":\"\\nimport { defineAlchemyChain } from "@account-kit/infra";\\nimport { sepolia } from "viem/chains";\\n \\nconst chain = defineAlchemyChain({\\n chain: sepolia,\\n rpcBaseUrl: "https://eth-sepolia.g.alchemy.com/v2",\\n});
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/defineAlchemyChain.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { defineAlchemyChain } from "@account-kit/infra";\\nimport { sepolia } from "viem/chains";\\n \\nconst chain = defineAlchemyChain({\\n chain: sepolia,\\n rpcBaseUrl: "https://eth-sepolia.g.alchemy.com/v2",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"defineAlchemyChain\"]},{\"href\":\"/reference/account-kit/infra/functions/defineAlchemyChain#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/defineAlchemyChain.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"defineAlchemyChain\"]},{\"href\":\"/reference/account-kit/infra/functions/defineAlchemyChain#params\",\"html\":\"\\nAlchemyChainConfig
\\nThe parameters for defining the Alchemy chain
Chain
\\nThe original chain configuration
string
\\nThe Alchemy-specific RPC base URL
Chain
\\nThe updated chain configuration with the Alchemy RPC URL added
Retrieves the Alchemy paymaster address for the given chain. Returns different addresses based on the chain ID.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getAlchemyPaymasterAddress.mdx#getalchemypaymasteraddress\",\"isPage\":true,\"text\":\"\\nRetrieves the Alchemy paymaster address for the given chain. Returns different addresses based on the chain ID.\\n\",\"title\":\"getAlchemyPaymasterAddress\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/getAlchemyPaymasterAddress#import\",\"html\":\"\\nimport { getAlchemyPaymasterAddress } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getAlchemyPaymasterAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getAlchemyPaymasterAddress } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"getAlchemyPaymasterAddress\"]},{\"href\":\"/reference/account-kit/infra/functions/getAlchemyPaymasterAddress#usage\",\"html\":\"\\nimport { sepolia, getAlchemyPaymasterAddress } from "@account-kit/infra";\\n \\nconst paymasterAddress = getAlchemyPaymasterAddress(sepolia);
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getAlchemyPaymasterAddress.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { sepolia, getAlchemyPaymasterAddress } from "@account-kit/infra";\\n \\nconst paymasterAddress = getAlchemyPaymasterAddress(sepolia);\\n\",\"title\":\"Usage\",\"titles\":[\"getAlchemyPaymasterAddress\"]},{\"href\":\"/reference/account-kit/infra/functions/getAlchemyPaymasterAddress#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getAlchemyPaymasterAddress.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getAlchemyPaymasterAddress\"]},{\"href\":\"/reference/account-kit/infra/functions/getAlchemyPaymasterAddress#chain\",\"html\":\"\\nChain
\\nThe chain for which the paymaster address is required
Address
\\nThe Alchemy paymaster address corresponding to the specified chain
Provider for Alchemy accounts.
\\n\",\"id\":\"pages/reference/account-kit/react/components/AlchemyAccountProvider.mdx#alchemyaccountprovider\",\"isPage\":true,\"text\":\"\\nProvider for Alchemy accounts.\\n\",\"title\":\"AlchemyAccountProvider\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/components/AlchemyAccountProvider#import\",\"html\":\"\\nimport { AlchemyAccountProvider } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/components/AlchemyAccountProvider.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemyAccountProvider } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"AlchemyAccountProvider\"]},{\"href\":\"/reference/account-kit/react/components/AlchemyAccountProvider#usage\",\"html\":\"\\nimport { AlchemyAccountProvider, createConfig } from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\nimport { QueryClient, QueryClientProvider } from "@tanstack/react-query";\\n \\nconst config = createConfig({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n});\\n \\nconst queryClient = new QueryClient();\\n \\nfunction App({ children }: React.PropsWithChildren) {\\n return (\\n <QueryClientProvider queryClient={queryClient}>\\n <AlchemyAccountProvider config={config} queryClient={queryClient}>\\n {children}\\n </AlchemyAccountProvider>\\n </QueryClientProvider>\\n );\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/components/AlchemyAccountProvider.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyAccountProvider, createConfig } from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\nimport { QueryClient, QueryClientProvider } from "@tanstack/react-query";\\n \\nconst config = createConfig({\\n apiKey: "your-api-key",\\n chain: sepolia,\\n});\\n \\nconst queryClient = new QueryClient();\\n \\nfunction App({ children }: React.PropsWithChildren) {\\n return (\\n <QueryClientProvider queryClient={queryClient}>\\n <AlchemyAccountProvider config={config} queryClient={queryClient}>\\n {children}\\n </AlchemyAccountProvider>\\n </QueryClientProvider>\\n );\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"AlchemyAccountProvider\"]},{\"href\":\"/reference/account-kit/react/components/AlchemyAccountProvider#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/components/AlchemyAccountProvider.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"AlchemyAccountProvider\"]},{\"href\":\"/reference/account-kit/react/components/AlchemyAccountProvider#props\",\"html\":\"\\nReact.PropsWithChildren<AlchemyAccountsProviderProps>
\\nalchemy accounts provider props
AlchemyAccountsConfig
\\nthe acccount config generated using createConfig
QueryClient
\\nthe react-query query client to use
AlchemyAccountsUIConfig
\\noptional UI configuration
React.ReactNode | undefined
\\nreact components that should have this accounts context
React.JSX.Element
\\nThe element to wrap your application in for Alchemy Accounts context.
Checks if a given client is an Alchemy Smart Account Client. The goal of this check is to ensure that the client supports certain RPC methods.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/isAlchemySmartAccountClient.mdx#isalchemysmartaccountclient\",\"isPage\":true,\"text\":\"\\nChecks if a given client is an Alchemy Smart Account Client. The goal of this check is to ensure that the client supports certain RPC methods.\\n\",\"title\":\"isAlchemySmartAccountClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/isAlchemySmartAccountClient#import\",\"html\":\"\\nimport { isAlchemySmartAccountClient } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/isAlchemySmartAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { isAlchemySmartAccountClient } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"isAlchemySmartAccountClient\"]},{\"href\":\"/reference/account-kit/infra/functions/isAlchemySmartAccountClient#usage\",\"html\":\"\\nimport { isAlchemySmartAccountClient } from "@account-kit/infra";\\n \\nif (isAlchemySmartAccountClient(client)) {\\n // do things with the client as an Alchemy Smart Account Client\\n}
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/isAlchemySmartAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { isAlchemySmartAccountClient } from "@account-kit/infra";\\n \\nif (isAlchemySmartAccountClient(client)) {\\n // do things with the client as an Alchemy Smart Account Client\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"isAlchemySmartAccountClient\"]},{\"href\":\"/reference/account-kit/infra/functions/isAlchemySmartAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/isAlchemySmartAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"isAlchemySmartAccountClient\"]},{\"href\":\"/reference/account-kit/infra/functions/isAlchemySmartAccountClient#client\",\"html\":\"\\nClient<TTransport, TChain, TAccount>
\\nThe client instance to be checked
boolean
\\ntrue
if the client is an Alchemy Smart Account Client, otherwise false
Retrieves the default user operation fee options for a given chain. Adjusts fees for specific chains like Arbitrum and Optimism.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions.mdx#getdefaultuseroperationfeeoptions\",\"isPage\":true,\"text\":\"\\nRetrieves the default user operation fee options for a given chain. Adjusts fees for specific chains like Arbitrum and Optimism.\\n\",\"title\":\"getDefaultUserOperationFeeOptions\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions#import\",\"html\":\"\\nimport { getDefaultUserOperationFeeOptions } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { getDefaultUserOperationFeeOptions } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"getDefaultUserOperationFeeOptions\"]},{\"href\":\"/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions#usage\",\"html\":\"\\nimport { getDefaultUserOperationFeeOptions } from "@account-kit/infra";\\nimport { arbitrum } from "@account-kit/infra";\\n \\nconst feeOpts = getDefaultUserOperationFeeOptions(arbitrum);
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { getDefaultUserOperationFeeOptions } from "@account-kit/infra";\\nimport { arbitrum } from "@account-kit/infra";\\n \\nconst feeOpts = getDefaultUserOperationFeeOptions(arbitrum);\\n\",\"title\":\"Usage\",\"titles\":[\"getDefaultUserOperationFeeOptions\"]},{\"href\":\"/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getDefaultUserOperationFeeOptions\"]},{\"href\":\"/reference/account-kit/infra/functions/getDefaultUserOperationFeeOptions#chain\",\"html\":\"\\nChain
\\nThe blockchain chain for which to get the fee options
UserOperationFeeOptions
\\nAn object containing the default fee options for user operations on the specified chain
Simulates user operation changes including asset changes for a specified user operation and returns the resulting state changes.
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/simulateUserOperationChanges.mdx#simulateuseroperationchanges\",\"isPage\":true,\"text\":\"\\nSimulates user operation changes including asset changes for a specified user operation and returns the resulting state changes.\\n\",\"title\":\"simulateUserOperationChanges\",\"titles\":[]},{\"href\":\"/reference/account-kit/infra/functions/simulateUserOperationChanges#import\",\"html\":\"\\nimport { simulateUserOperationChanges } from "@account-kit/infra";
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/simulateUserOperationChanges.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { simulateUserOperationChanges } from "@account-kit/infra";\\n\",\"title\":\"Import\",\"titles\":[\"simulateUserOperationChanges\"]},{\"href\":\"/reference/account-kit/infra/functions/simulateUserOperationChanges#usage\",\"html\":\"\\nimport { simulateUserOperationChanges, createAlchemyPublicRpcClient } from "@account-kit/infra";\\n \\nconst client = createAlchemyPublicRpcClient(...);\\nconst response = await simulateUserOperationChanges(client, {\\nuo: ...\\n});
\\n\",\"id\":\"pages/reference/account-kit/infra/functions/simulateUserOperationChanges.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { simulateUserOperationChanges, createAlchemyPublicRpcClient } from "@account-kit/infra";\\n \\nconst client = createAlchemyPublicRpcClient(...);\\nconst response = await simulateUserOperationChanges(client, {\\nuo: ...\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"simulateUserOperationChanges\"]},{\"href\":\"/reference/account-kit/infra/functions/simulateUserOperationChanges#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/infra/functions/simulateUserOperationChanges.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"simulateUserOperationChanges\"]},{\"href\":\"/reference/account-kit/infra/functions/simulateUserOperationChanges#client\",\"html\":\"\\nClient<Transport, TChain, TAccount, AlchemyRpcSchema>
\\nThe client instance used to send the simulation request
SendUserOperationParameters<TAccount>
\\nThe parameters of the user operation including the account and other overrides
Promise<SimulateUserOperationAssetChangesResponse>
\\nA promise that resolves to the response of the simulation showing the asset changes
React component containing an Auth view with configured auth methods\\nand options based on the config passed to the AlchemyAccountProvider
\\n\",\"id\":\"pages/reference/account-kit/react/components/AuthCard.mdx#authcard\",\"isPage\":true,\"text\":\"\\nReact component containing an Auth view with configured auth methods\\nand options based on the config passed to the AlchemyAccountProvider\\n\",\"title\":\"AuthCard\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/components/AuthCard#import\",\"html\":\"\\nimport { AuthCard } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/components/AuthCard.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AuthCard } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"AuthCard\"]},{\"href\":\"/reference/account-kit/react/components/AuthCard#usage\",\"html\":\"\\nimport { AuthCard, useAlchemyAccountContext } from "@account-kit/react";\\n \\nfunction ComponentWithAuthCard() {\\n // assumes you've passed in a UI config to the Account Provider\\n // you can also directly set the properties on the AuthCard component\\n const { uiConfig } = useAlchemyAccountContext();\\n \\n return <AuthCard {...uiConfig!.auth} />;\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/components/AuthCard.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AuthCard, useAlchemyAccountContext } from "@account-kit/react";\\n \\nfunction ComponentWithAuthCard() {\\n // assumes you've passed in a UI config to the Account Provider\\n // you can also directly set the properties on the AuthCard component\\n const { uiConfig } = useAlchemyAccountContext();\\n \\n return <AuthCard {...uiConfig!.auth} />;\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"AuthCard\"]},{\"href\":\"/reference/account-kit/react/components/AuthCard#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/components/AuthCard.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"AuthCard\"]},{\"href\":\"/reference/account-kit/react/components/AuthCard#props\",\"html\":\"\\nAuthCardProps
\\nCard Props
JSX.Element
\\na react component containing the AuthCard
Wraps the createConfig
that is exported from @aa-sdk/core
to allow passing\\nan additional argument, the configuration object for the Auth Components UI\\n(the modal and AuthCard).
import { createConfig } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/functions/createConfig.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { createConfig } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"createConfig\"]},{\"href\":\"/reference/account-kit/react/functions/createConfig#usage\",\"html\":\"\\nimport { sepolia } from "@account-kit/infra";\\nimport { AlchemyAccountsUIConfig, createConfig } from "@account-kit/react";\\nimport { QueryClient } from "@tanstack/react-query";\\n \\nconst uiConfig: AlchemyAccountsUIConfig = {\\n illustrationStyle: "linear",\\n auth: {\\n sections: [[{ type: "email" }], [{ type: "passkey" }]],\\n addPasskeyOnSignup: true,\\n },\\n};\\n \\nconst config = createConfig(\\n {\\n rpcUrl: "/api/rpc",\\n chain: sepolia,\\n ssr: true,\\n },\\n uiConfig\\n);\\n \\nexport const queryClient = new QueryClient();
\\n\",\"id\":\"pages/reference/account-kit/react/functions/createConfig.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { sepolia } from "@account-kit/infra";\\nimport { AlchemyAccountsUIConfig, createConfig } from "@account-kit/react";\\nimport { QueryClient } from "@tanstack/react-query";\\n \\nconst uiConfig: AlchemyAccountsUIConfig = {\\n illustrationStyle: "linear",\\n auth: {\\n sections: [[{ type: "email" }], [{ type: "passkey" }]],\\n addPasskeyOnSignup: true,\\n },\\n};\\n \\nconst config = createConfig(\\n {\\n rpcUrl: "/api/rpc",\\n chain: sepolia,\\n ssr: true,\\n },\\n uiConfig\\n);\\n \\nexport const queryClient = new QueryClient();\\n\",\"title\":\"Usage\",\"titles\":[\"createConfig\"]},{\"href\":\"/reference/account-kit/react/functions/createConfig#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/functions/createConfig.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createConfig\"]},{\"href\":\"/reference/account-kit/react/functions/createConfig#props\",\"html\":\"\\nCreateConfigProps
\\nfor creating an alchemy account config
AlchemyAccountsUIConfig
\\n(optional) configuration to use for the Auth Components UI
AlchemyAccountsConfigWithUI
\\nan alchemy account config object containing the core and client store, as well as the UI config
Creates a new AccountSigner with the given ethers Provider and Smart Contract Account
\\n\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/constructor.mdx#accountsigner\",\"isPage\":true,\"text\":\"\\nCreates a new AccountSigner with the given ethers Provider and Smart Contract Account\\nAccountSigner extends Signer, see the docs for Signer for all supported methods.\\n\",\"title\":\"AccountSigner\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/constructor#import\",\"html\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"AccountSigner\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/constructor#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/constructor.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n\",\"title\":\"Usage\",\"titles\":[\"AccountSigner\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"AccountSigner\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/constructor#provider\",\"html\":\"\\nEthersProviderAdapter
\\nthe ethers provider to use
TAccount
\\nthe smart contract account that will be used to sign user ops and send them
Retrieves the BundlerClient instance from the provider.
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/getBundlerClient.mdx#getbundlerclient\",\"isPage\":true,\"text\":\"\\nRetrieves the BundlerClient instance from the provider.\\n\",\"title\":\"getBundlerClient\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/getBundlerClient#import\",\"html\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/getBundlerClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"getBundlerClient\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/getBundlerClient#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst bundler = signer.getBundlerClient();
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/getBundlerClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst bundler = signer.getBundlerClient();\\n\",\"title\":\"Usage\",\"titles\":[\"getBundlerClient\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/getBundlerClient#returns\",\"html\":\"\\nBundlerClient<Transport>
\\nThe BundlerClient instance
Sets the provider for the account signer and returns the updated account signer instance.\\nNote: this is not necessary since the Provider is required by the constructor. This is useful\\nif you want to change the provider after the account signer has been created.
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/connect.mdx#connect\",\"isPage\":true,\"text\":\"\\nSets the provider for the account signer and returns the updated account signer instance.\\nNote: this is not necessary since the Provider is required by the constructor. This is useful\\nif you want to change the provider after the account signer has been created.\\n\",\"title\":\"connect\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/connect#import\",\"html\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/connect.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"connect\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/connect#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nsigner.connect(provider);
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/connect.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nsigner.connect(provider);\\n\",\"title\":\"Usage\",\"titles\":[\"connect\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/connect#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/connect.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"connect\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/connect#provider\",\"html\":\"\\nEthersProviderAdapter
\\nthe provider to be set for the account signer
AccountSigner<TAccount>
\\nthe updated account signer instance
Returns the account address if the account exists.
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/getAddress.mdx#getaddress\",\"isPage\":true,\"text\":\"\\nReturns the account address if the account exists.\\n\",\"title\":\"getAddress\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/getAddress#import\",\"html\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/getAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/getAddress#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst address = await signer.getAddress();
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/getAddress.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst address = await signer.getAddress();\\n\",\"title\":\"Usage\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/getAddress#returns\",\"html\":\"\\nPromise<string>
\\na promise that resolves to the account address
Throws an error indicating that transaction signing is not supported and advises to use sendUserOperation
instead.
import { AccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/signTransaction.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"signTransaction\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/signTransaction#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/signTransaction.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signTransaction\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/signTransaction#_transaction\",\"html\":\"\\nDeferrable<TransactionRequest>
\\nThe transaction request
Signs a message using the associated account.
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/signMessage.mdx#signmessage\",\"isPage\":true,\"text\":\"\\nSigns a message using the associated account.\\n\",\"title\":\"signMessage\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/signMessage#import\",\"html\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/signMessage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/signMessage#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst message = await signer.signMessage("hello");
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/signMessage.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst message = await signer.signMessage("hello");\\n\",\"title\":\"Usage\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/signMessage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/signMessage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/signMessage#message\",\"html\":\"\\nstring | Uint8Array
\\nthe message to be signed
Promise<string>
\\na promise that resolves to the signed message
Sends a transaction using the account provider and returns the transaction response.
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction.mdx#sendtransaction\",\"isPage\":true,\"text\":\"\\nSends a transaction using the account provider and returns the transaction response.\\n\",\"title\":\"sendTransaction\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction#import\",\"html\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"sendTransaction\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst tx = await signer.sendTransaction({\\n to: "0x1234567890123456789012345678901234567890",\\n value: "0x0",\\n data: "0x",\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\nimport { http } from "viem";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter();\\nconst signer = new AccountSigner(provider, account);\\n \\nconst tx = await signer.sendTransaction({\\n to: "0x1234567890123456789012345678901234567890",\\n value: "0x0",\\n data: "0x",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"sendTransaction\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"sendTransaction\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/AccountSigner/sendTransaction#transaction\",\"html\":\"\\nDeferrable<TransactionRequest>
\\nthe transaction request to be sent
Promise<TransactionResponse>
\\na promise that resolves to the transaction response
Hook to subscribe to account state and interactions, including creation, connection, and status monitoring. It synchronizes with external store updates and provides status-dependent results.\\nThe supported account types are: LightAccount, MultiOwnerLightAccount, and MultiOwnerModularAccount.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAccount.mdx#useaccount\",\"isPage\":true,\"text\":\"\\nHook to subscribe to account state and interactions, including creation, connection, and status monitoring. It synchronizes with external store updates and provides status-dependent results.\\nThe supported account types are: LightAccount, MultiOwnerLightAccount, and MultiOwnerModularAccount.\\n\",\"title\":\"useAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useAccount#import\",\"html\":\"\\nimport { useAccount } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useAccount } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useAccount\"]},{\"href\":\"/reference/account-kit/react/hooks/useAccount#usage\",\"html\":\"\\nimport { useAccount } from "@account-kit/react";\\n \\nconst { account, address, isLoadingAccount } = useAccount({\\n type: "LightAccount",\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useAccount } from "@account-kit/react";\\n \\nconst { account, address, isLoadingAccount } = useAccount({\\n type: "LightAccount",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useAccount\"]},{\"href\":\"/reference/account-kit/react/hooks/useAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useAccount\"]},{\"href\":\"/reference/account-kit/react/hooks/useAccount#params\",\"html\":\"\\nUseAccountProps<TAccount>
\\nThe parameters required for account management, including account type, specific account parameters, and optional mutation arguments
UseAccountResult<TAccount>
\\nAn object containing the account information, address, and loading state
A custom hook to handle the addition of a passkey, which includes executing a mutation with optional parameters.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAddPasskey.mdx#useaddpasskey\",\"isPage\":true,\"text\":\"\\nA custom hook to handle the addition of a passkey, which includes executing a mutation with optional parameters.\\n\",\"title\":\"useAddPasskey\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useAddPasskey#import\",\"html\":\"\\nimport { useAddPasskey } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAddPasskey.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useAddPasskey } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useAddPasskey\"]},{\"href\":\"/reference/account-kit/react/hooks/useAddPasskey#usage\",\"html\":\"\\nimport { useAddPasskey } from "@account-kit/react";\\n \\nconst { addPasskey, isAddingPasskey, error } = useAddPasskey({\\n // these are optional\\n onSuccess: () => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAddPasskey.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useAddPasskey } from "@account-kit/react";\\n \\nconst { addPasskey, isAddingPasskey, error } = useAddPasskey({\\n // these are optional\\n onSuccess: () => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useAddPasskey\"]},{\"href\":\"/reference/account-kit/react/hooks/useAddPasskey#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAddPasskey.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useAddPasskey\"]},{\"href\":\"/reference/account-kit/react/hooks/useAddPasskey#mutationargs\",\"html\":\"\\nUseAddPasskeyMutationArgs
\\nOptional arguments for the mutation used for adding a passkey
UseAddPasskeyResult
\\nAn object containing the addPasskey
function, a boolean isAddingPasskey
to track the mutation status, and any error encountered
Internal Only hook used to access the alchemy account context.\\nThis hook is meant to be consumed by other hooks exported by this package.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAlchemyAccountContext.mdx#usealchemyaccountcontext\",\"isPage\":true,\"text\":\"\\nInternal Only hook used to access the alchemy account context.\\nThis hook is meant to be consumed by other hooks exported by this package.\\n\",\"title\":\"useAlchemyAccountContext\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useAlchemyAccountContext#import\",\"html\":\"\\nimport { useAlchemyAccountContext } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAlchemyAccountContext.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useAlchemyAccountContext } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useAlchemyAccountContext\"]},{\"href\":\"/reference/account-kit/react/hooks/useAlchemyAccountContext#usage\",\"html\":\"\\nimport { useAlchemyAccountContext } from "@account-kit/react";\\n \\nconst { config, queryClient } = useAlchemyAccountContext();
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAlchemyAccountContext.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useAlchemyAccountContext } from "@account-kit/react";\\n \\nconst { config, queryClient } = useAlchemyAccountContext();\\n\",\"title\":\"Usage\",\"titles\":[\"useAlchemyAccountContext\"]},{\"href\":\"/reference/account-kit/react/hooks/useAlchemyAccountContext#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAlchemyAccountContext.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useAlchemyAccountContext\"]},{\"href\":\"/reference/account-kit/react/hooks/useAlchemyAccountContext#override\",\"html\":\"\\nAlchemyAccountContextProps
\\noptional context override that can be used to return a custom context
AlchemyAccountContextProps
\\nThe alchemy account context if one exists
Provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthenticate.mdx#useauthenticate\",\"isPage\":true,\"text\":\"\\nProvides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations.\\n\",\"title\":\"useAuthenticate\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useAuthenticate#import\",\"html\":\"\\nimport { useAuthenticate } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthenticate.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useAuthenticate } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useAuthenticate\"]},{\"href\":\"/reference/account-kit/react/hooks/useAuthenticate#usage\",\"html\":\"\\nimport { useAuthenticate } from "@account-kit/react";\\n \\nconst { authenticate, authenticateAsync, isPending, error } = useAuthenticate({\\n // these are optional\\n onSuccess: () => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthenticate.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useAuthenticate } from "@account-kit/react";\\n \\nconst { authenticate, authenticateAsync, isPending, error } = useAuthenticate({\\n // these are optional\\n onSuccess: () => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useAuthenticate\"]},{\"href\":\"/reference/account-kit/react/hooks/useAuthenticate#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthenticate.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useAuthenticate\"]},{\"href\":\"/reference/account-kit/react/hooks/useAuthenticate#mutationargs\",\"html\":\"\\nUseAuthenticateMutationArgs
\\nOptional mutation arguments to configure the authentication mutation
UseAuthenticateResult
\\nAn object containing functions and state for handling user authentication, including methods for synchronously and asynchronously executing the authentication
A hook that returns the open and close functions for the Auth Modal if uiConfig\\nis enabled on the Account Provider
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthModal.mdx#useauthmodal\",\"isPage\":true,\"text\":\"\\nA hook that returns the open and close functions for the Auth Modal if uiConfig\\nis enabled on the Account Provider\\n\",\"title\":\"useAuthModal\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useAuthModal#import\",\"html\":\"\\nimport { useAuthModal } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthModal.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useAuthModal } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useAuthModal\"]},{\"href\":\"/reference/account-kit/react/hooks/useAuthModal#usage\",\"html\":\"\\nimport { useAuthModal } from "@account-kit/react";\\n \\nconst ComponentWithAuthModal = () => {\\n const { openAuthModal } = useAuthModal();\\n \\n return (\\n <div>\\n <button onClick={openAuthModal}>Login</button>\\n </div>\\n );\\n};
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthModal.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useAuthModal } from "@account-kit/react";\\n \\nconst ComponentWithAuthModal = () => {\\n const { openAuthModal } = useAuthModal();\\n \\n return (\\n <div>\\n <button onClick={openAuthModal}>Login</button>\\n </div>\\n );\\n};\\n\",\"title\":\"Usage\",\"titles\":[\"useAuthModal\"]},{\"href\":\"/reference/account-kit/react/hooks/useAuthModal#returns\",\"html\":\"\\nUseAuthModalResult
\\nan object containing methods for opening or closing the auth modal
Returns the error returned from the current auth step, if it exists
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthError.mdx#useautherror\",\"isPage\":true,\"text\":\"\\nReturns the error returned from the current auth step, if it exists\\n\",\"title\":\"useAuthError\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useAuthError#import\",\"html\":\"\\nimport { useAuthError } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthError.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useAuthError } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useAuthError\"]},{\"href\":\"/reference/account-kit/react/hooks/useAuthError#usage\",\"html\":\"\\nimport { useAuthError } from "@account-kit/react";\\n \\nconst error = useAuthError();\\n \\nif (error) {\\n console.error("Error occurred during auth step", error);\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useAuthError.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useAuthError } from "@account-kit/react";\\n \\nconst error = useAuthError();\\n \\nif (error) {\\n console.error("Error occurred during auth step", error);\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"useAuthError\"]},{\"href\":\"/reference/account-kit/react/hooks/useAuthError#returns\",\"html\":\"\\nUseAuthErrorResult
\\nthe current Error object
A hook that allows you to leverage client decorators to execute actions\\nand await them in your UX. This is particularly useful for using Plugins\\nwith Modular Accounts.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useClientActions.mdx#useclientactions\",\"isPage\":true,\"text\":\"\\nA hook that allows you to leverage client decorators to execute actions\\nand await them in your UX. This is particularly useful for using Plugins\\nwith Modular Accounts.\\n\",\"title\":\"useClientActions\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useClientActions#import\",\"html\":\"\\nimport { useClientActions } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useClientActions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useClientActions } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useClientActions\"]},{\"href\":\"/reference/account-kit/react/hooks/useClientActions#usage\",\"html\":\"\\nconst Foo = () => {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n const { executeAction } = useClientActions({\\n client,\\n pluginActions: sessionKeyPluginActions,\\n });\\n \\n executeAction({\\n functionName: "isAccountSessionKey",\\n args: [{ key: "0x0" }],\\n });\\n};
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useClientActions.mdx#usage\",\"isPage\":false,\"text\":\"\\nconst Foo = () => {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n const { executeAction } = useClientActions({\\n client,\\n pluginActions: sessionKeyPluginActions,\\n });\\n \\n executeAction({\\n functionName: "isAccountSessionKey",\\n args: [{ key: "0x0" }],\\n });\\n};\\n\",\"title\":\"Usage\",\"titles\":[\"useClientActions\"]},{\"href\":\"/reference/account-kit/react/hooks/useClientActions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useClientActions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useClientActions\"]},{\"href\":\"/reference/account-kit/react/hooks/useClientActions#args\",\"html\":\"\\nUseClientActionsProps<TTransport, TChain, TActions>
\\nthe hooks arguments highlighted below
SmartAccountClient
\\nthe smart account client returned from useSmartAccountClient
object
\\nthe smart account client decorator you want to execute actions from
UseClientActionsResult<TActions>
\\nan object containing methods to execute the actions as well loading and error states
Custom hook to get a bundler client using the Alchemy account context.\\nIt uses useSyncExternalStore
to watch for any changes in the bundler client configuration and provides the updated bundler client.
import { useBundlerClient } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useBundlerClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useBundlerClient } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useBundlerClient\"]},{\"href\":\"/reference/account-kit/react/hooks/useBundlerClient#usage\",\"html\":\"\\nimport { useBundlerClient } from "@account-kit/react";\\n \\nconst bundlerClient = useBundlerClient();
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useBundlerClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useBundlerClient } from "@account-kit/react";\\n \\nconst bundlerClient = useBundlerClient();\\n\",\"title\":\"Usage\",\"titles\":[\"useBundlerClient\"]},{\"href\":\"/reference/account-kit/react/hooks/useBundlerClient#returns\",\"html\":\"\\nBundlerClient
\\nThe bundler client based on the current Alchemy account configuration
Current Chain: {chain.id}
\\n \\nA hook that returns the current chain as well as a function to set the chain.\\nNote: when calling setChain
the chain that's passed in must be defined in\\nyour initial createConfig
call.
import { useChain } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useChain.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useChain } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useChain\"]},{\"href\":\"/reference/account-kit/react/hooks/useChain#usage\",\"html\":\"\\nimport { useChain } from "@account-kit/react";\\n// Assuming the chain sepolia is defined in your initial createConfig call\\nimport { sepolia } from "@account-kit/infra";\\n \\nfunction ComponentUsingChain() {\\n const { chain, setChain, isSettingChain } = useChain();\\n \\n return (\\n <div>\\n <p>Current Chain: {chain.id}</p>\\n <button\\n onClick={() => setChain({ chain: sepolia })}\\n disabled={isSettingChain}\\n >\\n Set Chain\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useChain.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useChain } from "@account-kit/react";\\n// Assuming the chain sepolia is defined in your initial createConfig call\\nimport { sepolia } from "@account-kit/infra";\\n \\nfunction ComponentUsingChain() {\\n const { chain, setChain, isSettingChain } = useChain();\\n \\n return (\\n <div>\\n <p>Current Chain: {chain.id}</p>\\n <button\\n onClick={() => setChain({ chain: sepolia })}\\n disabled={isSettingChain}\\n >\\n Set Chain\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"useChain\"]},{\"href\":\"/reference/account-kit/react/hooks/useChain#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useChain.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useChain\"]},{\"href\":\"/reference/account-kit/react/hooks/useChain#mutationargs\",\"html\":\"\\nUseChainParams
\\noptional properties which contain mutation arg overrides
UseChainResult
\\nan object containing the current chain and a function to set the chain as well as loading state of setting the chain
A hook that returns the current connection
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useConnection.mdx#useconnection\",\"isPage\":true,\"text\":\"\\nA hook that returns the current connection\\n\",\"title\":\"useConnection\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useConnection#import\",\"html\":\"\\nimport { useConnection } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useConnection.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useConnection } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useConnection\"]},{\"href\":\"/reference/account-kit/react/hooks/useConnection#returns\",\"html\":\"\\nConnection
\\nthe current connection
Custom hook that handles the drop and replace user operation for a given client and mutation arguments.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useDropAndReplaceUserOperation.mdx#usedropandreplaceuseroperation\",\"isPage\":true,\"text\":\"\\nCustom hook that handles the drop and replace user operation for a given client and mutation arguments.\\n\",\"title\":\"useDropAndReplaceUserOperation\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useDropAndReplaceUserOperation#import\",\"html\":\"\\nimport { useDropAndReplaceUserOperation } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useDropAndReplaceUserOperation.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useDropAndReplaceUserOperation } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useDropAndReplaceUserOperation\"]},{\"href\":\"/reference/account-kit/react/hooks/useDropAndReplaceUserOperation#usage\",\"html\":\"\\nimport {\\n useDropAndReplaceUserOperation,\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nexport function ComponentWithDropAndReplaceUO() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n const { sendUserOperationAsync, isSendingUserOperation } =\\n useSendUserOperation({\\n client,\\n });\\n const { dropAndReplaceUserOperation, isDroppingAndReplacingUserOperation } =\\n useDropAndReplaceUserOperation({\\n client,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={async () => {\\n const { request } = await sendUserOperationAsync({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n });\\n \\n dropAndReplaceUserOperation({\\n uoToDrop: request,\\n });\\n }}\\n disabled={isSendingUserOperation || isDroppingAndReplacingUserOperation}\\n >\\n {isSendingUserOperation\\n ? "Sending..."\\n : isDroppingAndReplacingUserOperation\\n ? "Replacing..."\\n : "Send then Replace UO"}\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useDropAndReplaceUserOperation.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport {\\n useDropAndReplaceUserOperation,\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nexport function ComponentWithDropAndReplaceUO() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n const { sendUserOperationAsync, isSendingUserOperation } =\\n useSendUserOperation({\\n client,\\n });\\n const { dropAndReplaceUserOperation, isDroppingAndReplacingUserOperation } =\\n useDropAndReplaceUserOperation({\\n client,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={async () => {\\n const { request } = await sendUserOperationAsync({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n });\\n \\n dropAndReplaceUserOperation({\\n uoToDrop: request,\\n });\\n }}\\n disabled={isSendingUserOperation || isDroppingAndReplacingUserOperation}\\n >\\n {isSendingUserOperation\\n ? "Sending..."\\n : isDroppingAndReplacingUserOperation\\n ? "Replacing..."\\n : "Send then Replace UO"}\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"useDropAndReplaceUserOperation\"]},{\"href\":\"/reference/account-kit/react/hooks/useDropAndReplaceUserOperation#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useDropAndReplaceUserOperation.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useDropAndReplaceUserOperation\"]},{\"href\":\"/reference/account-kit/react/hooks/useDropAndReplaceUserOperation#config\",\"html\":\"\\nUseDropAndReplaceUserOperationArgs<TEntryPointVersion, TAccount>
\\nThe configuration parameters including the client and other mutation arguments
UseDropAndReplaceUserOperationResult<TEntryPointVersion, TAccount>
\\nThe result containing the mutation function, result data, loading state, and any error
Re-exported wagmi hook for connecting an EOA. This hook\\nuses the internal wagmi config though so that the state\\nis in sync with the rest of the Alchemy Account hook state
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useConnect.mdx#useconnect\",\"isPage\":true,\"text\":\"\\nRe-exported wagmi hook for connecting an EOA. This hook\\nuses the internal wagmi config though so that the state\\nis in sync with the rest of the Alchemy Account hook state\\n\",\"title\":\"useConnect\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useConnect#import\",\"html\":\"\\nimport { useConnect } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useConnect.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useConnect } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useConnect\"]},{\"href\":\"/reference/account-kit/react/hooks/useConnect#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useConnect.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useConnect\"]},{\"href\":\"/reference/account-kit/react/hooks/useConnect#params\",\"html\":\"\\nUseMutationParameters
\\nmutation parameters to use for the connect mutation
UseConnectReturnType
\\nthe wagmi useConnect return type
A hook use to export the private key for an account. It returns the mutation functions to kick off the export process, as well as a component to render the account recovery details in an iframe.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useExportAccount.mdx#useexportaccount\",\"isPage\":true,\"text\":\"\\nA hook use to export the private key for an account. It returns the mutation functions to kick off the export process, as well as a component to render the account recovery details in an iframe.\\n\",\"title\":\"useExportAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useExportAccount#import\",\"html\":\"\\nimport { useExportAccount } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useExportAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useExportAccount } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useExportAccount\"]},{\"href\":\"/reference/account-kit/react/hooks/useExportAccount#usage\",\"html\":\"\\nimport { useExportAccount } from "@account-kit/react";\\n \\nconst {\\n exportAccount,\\n isExported,\\n isExporting,\\n error,\\n ExportAccountComponent,\\n} = useExportAccount({\\n params: {\\n iframeContainerId: "my-iframe-container",\\n },\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useExportAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useExportAccount } from "@account-kit/react";\\n \\nconst {\\n exportAccount,\\n isExported,\\n isExporting,\\n error,\\n ExportAccountComponent,\\n} = useExportAccount({\\n params: {\\n iframeContainerId: "my-iframe-container",\\n },\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useExportAccount\"]},{\"href\":\"/reference/account-kit/react/hooks/useExportAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useExportAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useExportAccount\"]},{\"href\":\"/reference/account-kit/react/hooks/useExportAccount#args\",\"html\":\"\\nUseExportAccountMutationArgs
\\nOptional arguments for the mutation and export parameters
UseExportAccountResult
\\nAn object containing the export state, possible error, and the export account function and component
Provides a hook to log out a user, disconnecting the signer and triggering the disconnectAsync function.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useLogout.mdx#uselogout\",\"isPage\":true,\"text\":\"\\nProvides a hook to log out a user, disconnecting the signer and triggering the disconnectAsync function.\\n\",\"title\":\"useLogout\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useLogout#import\",\"html\":\"\\nimport { useLogout } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useLogout.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useLogout } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useLogout\"]},{\"href\":\"/reference/account-kit/react/hooks/useLogout#usage\",\"html\":\"\\nimport { useLogout } from "@account-kit/react";\\n \\nconst { logout, isLoggingOut, error } = useLogout({\\n // these are optional\\n onSuccess: () => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useLogout.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useLogout } from "@account-kit/react";\\n \\nconst { logout, isLoggingOut, error } = useLogout({\\n // these are optional\\n onSuccess: () => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useLogout\"]},{\"href\":\"/reference/account-kit/react/hooks/useLogout#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useLogout.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useLogout\"]},{\"href\":\"/reference/account-kit/react/hooks/useLogout#mutationargs\",\"html\":\"\\nUseLogoutMutationArgs
\\noptional arguments to customize the mutation behavior
UseLogoutResult
\\nan object containing the logout function, a boolean indicating if logout is in progress, and any error encountered during logout
Send a TX request as a user operation and wait for it to be mined
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransaction.mdx#usesendtransaction\",\"isPage\":true,\"text\":\"\\nSend a TX request as a user operation and wait for it to be mined\\n\",\"title\":\"useSendTransaction\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransaction#import\",\"html\":\"\\nimport { useSendTransaction } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransaction.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSendTransaction } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSendTransaction\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransaction#usage\",\"html\":\"\\nimport { useSendTransaction, useSmartAccountClient } from "@account-kit/react";\\n \\nfunction ComponentWithSendTransaction() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n \\n const { sendTransaction, isSendingTransaction } = useSendTransaction({\\n client,\\n onSuccess: (hash) => {\\n // [optional] Do something with the hash\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendTransaction({\\n to: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n account: "0xACCOUNT_ADDRESS",\\n chain: sepolia,\\n // ... other parameters\\n })\\n }\\n disabled={isSendingTransaction}\\n >\\n {isSendingTransaction ? "Sending..." : "Send Txn"}\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransaction.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useSendTransaction, useSmartAccountClient } from "@account-kit/react";\\n \\nfunction ComponentWithSendTransaction() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n \\n const { sendTransaction, isSendingTransaction } = useSendTransaction({\\n client,\\n onSuccess: (hash) => {\\n // [optional] Do something with the hash\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendTransaction({\\n to: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n account: "0xACCOUNT_ADDRESS",\\n chain: sepolia,\\n // ... other parameters\\n })\\n }\\n disabled={isSendingTransaction}\\n >\\n {isSendingTransaction ? "Sending..." : "Send Txn"}\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"useSendTransaction\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransaction#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransaction.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useSendTransaction\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransaction#params\",\"html\":\"\\nUseSendTransactionArgs
parameters for sending a transaction
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransaction.mdx#params\",\"isPage\":false,\"text\":\"\\nUseSendTransactionArgs\\n\\n\\nparameters for sending a transaction\\n\",\"title\":\"params\",\"titles\":[\"useSendTransaction\",\"Parameters\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransaction#returns\",\"html\":\"\\nUseSendTransactionResult
\\nfunctions and state for sending txs
Allows you to send a batch of transactions as a single user operation and await\\nthe transaction to be mined.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransactions.mdx#usesendtransactions\",\"isPage\":true,\"text\":\"\\nAllows you to send a batch of transactions as a single user operation and await\\nthe transaction to be mined.\\n\",\"title\":\"useSendTransactions\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransactions#import\",\"html\":\"\\nimport { useSendTransactions } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransactions.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSendTransactions } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSendTransactions\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransactions#usage\",\"html\":\"\\nimport { useSendTransactions, useSmartAccountClient } from "@account-kit/react";\\nimport { toHex } from "viem";\\n \\nfunction ComponentWithSendTransactions() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n \\n const { sendTransactions, isSendingTransactions } = useSendTransactions({\\n client,\\n onSuccess: (hash) => {\\n // [optional] Do something with the hash\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendTransactions({\\n requests: [\\n {\\n from: "0xACCOUNT_ADDRESS",\\n to: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: toHex(0n),\\n },\\n ],\\n // ... other parameters (account, context, overrides)\\n })\\n }\\n disabled={isSendingTransactions}\\n >\\n {isSendingTransactions ? "Sending..." : "Send Txns"}\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransactions.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useSendTransactions, useSmartAccountClient } from "@account-kit/react";\\nimport { toHex } from "viem";\\n \\nfunction ComponentWithSendTransactions() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n \\n const { sendTransactions, isSendingTransactions } = useSendTransactions({\\n client,\\n onSuccess: (hash) => {\\n // [optional] Do something with the hash\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendTransactions({\\n requests: [\\n {\\n from: "0xACCOUNT_ADDRESS",\\n to: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: toHex(0n),\\n },\\n ],\\n // ... other parameters (account, context, overrides)\\n })\\n }\\n disabled={isSendingTransactions}\\n >\\n {isSendingTransactions ? "Sending..." : "Send Txns"}\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"useSendTransactions\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransactions#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendTransactions.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useSendTransactions\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendTransactions#params\",\"html\":\"\\nUseSendTransactionsArgs<TAccount>
\\nparameters for sending transactions
UseSendTransactionsResult<TAccount, TContext, TEntryPointVersion>
\\na collection of functions and state for sending transactions
A hook that returns functions for sending user operations.\\nYou can also optionally wait for a user operation to be mined before returning.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendUserOperation.mdx#usesenduseroperation\",\"isPage\":true,\"text\":\"\\nA hook that returns functions for sending user operations.\\nYou can also optionally wait for a user operation to be mined before returning.\\n\",\"title\":\"useSendUserOperation\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSendUserOperation#import\",\"html\":\"\\nimport { useSendUserOperation } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendUserOperation.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSendUserOperation } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSendUserOperation\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendUserOperation#usage\",\"html\":\"\\nimport {\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nfunction ComponentWithSendUserOperation() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n const { sendUserOperation, isSendingUserOperation } = useSendUserOperation({\\n client,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendUserOperation({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n })\\n }\\n disabled={isSendingUserOperation}\\n >\\n {isSendingUserOperation ? "Sending..." : "Send UO"}\\n </button>\\n </div>\\n );\\n}
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendUserOperation.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport {\\n useSendUserOperation,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nfunction ComponentWithSendUserOperation() {\\n const { client } = useSmartAccountClient({\\n type: "MultiOwnerModularAccount",\\n });\\n const { sendUserOperation, isSendingUserOperation } = useSendUserOperation({\\n client,\\n onSuccess: ({ hash, request }) => {\\n // [optional] Do something with the hash and request\\n },\\n onError: (error) => {\\n // [optional] Do something with the error\\n },\\n // [optional] ...additional mutationArgs\\n });\\n \\n return (\\n <div>\\n <button\\n onClick={() =>\\n sendUserOperation({\\n uo: {\\n target: "0xTARGET_ADDRESS",\\n data: "0x",\\n value: 0n,\\n },\\n })\\n }\\n disabled={isSendingUserOperation}\\n >\\n {isSendingUserOperation ? "Sending..." : "Send UO"}\\n </button>\\n </div>\\n );\\n}\\n\",\"title\":\"Usage\",\"titles\":[\"useSendUserOperation\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendUserOperation#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSendUserOperation.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useSendUserOperation\"]},{\"href\":\"/reference/account-kit/react/hooks/useSendUserOperation#params\",\"html\":\"\\nUseSendUserOperationArgs<TEntryPointVersion, TAccount>
\\nthe parameters for the hook including the client, a flag to wait for tx mining, and mutation args
UseSendUserOperationResult<TEntryPointVersion, TAccount>
\\nfunctions and state for sending UOs
Custom hook to sign a message using the provided client.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignMessage.mdx#usesignmessage\",\"isPage\":true,\"text\":\"\\nCustom hook to sign a message using the provided client.\\n\",\"title\":\"useSignMessage\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSignMessage#import\",\"html\":\"\\nimport { useSignMessage } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignMessage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSignMessage } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSignMessage\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignMessage#usage\",\"html\":\"\\nimport { useSignMessage, useSmartAccountClient } from "@account-kit/react";\\n \\nconst { client } = useSmartAccountClient({ type: "LightAccount" });\\nconst {\\n signMessage,\\n signMessageAsync,\\n signedMessage,\\n isSigningMessage,\\n error,\\n} = useSignMessage({\\n client,\\n // these are optional\\n onSuccess: (result) => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignMessage.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useSignMessage, useSmartAccountClient } from "@account-kit/react";\\n \\nconst { client } = useSmartAccountClient({ type: "LightAccount" });\\nconst {\\n signMessage,\\n signMessageAsync,\\n signedMessage,\\n isSigningMessage,\\n error,\\n} = useSignMessage({\\n client,\\n // these are optional\\n onSuccess: (result) => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useSignMessage\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignMessage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignMessage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useSignMessage\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignMessage#config\",\"html\":\"\\nUseSignMessageArgs
\\nThe configuration arguments for the hook, including the client and additional mutation arguments
UseSignMessageResult
\\nAn object containing methods and state for signing messages
Hook to get the signer status, optionally using an override configuration.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignerStatus.mdx#usesignerstatus\",\"isPage\":true,\"text\":\"\\nHook to get the signer status, optionally using an override configuration.\\n\",\"title\":\"useSignerStatus\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSignerStatus#import\",\"html\":\"\\nimport { useSignerStatus } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignerStatus.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSignerStatus } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSignerStatus\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignerStatus#usage\",\"html\":\"\\nimport { useSignerStatus } from "@account-kit/react";\\n \\nconst signerStatus = useSignerStatus();
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignerStatus.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useSignerStatus } from "@account-kit/react";\\n \\nconst signerStatus = useSignerStatus();\\n\",\"title\":\"Usage\",\"titles\":[\"useSignerStatus\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignerStatus#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignerStatus.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useSignerStatus\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignerStatus#override\",\"html\":\"\\nAlchemyAccountContextProps
\\noptional configuration to override the default context
UseSignerStatusResult
\\nthe current state of the signer
Hook for signing typed data, supporting both connected accounts and clients.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignTypedData.mdx#usesigntypeddata\",\"isPage\":true,\"text\":\"\\nHook for signing typed data, supporting both connected accounts and clients.\\n\",\"title\":\"useSignTypedData\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSignTypedData#import\",\"html\":\"\\nimport { useSignTypedData } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignTypedData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSignTypedData } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSignTypedData\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignTypedData#usage\",\"html\":\"\\nimport { useSignTypedData, useSmartAccountClient } from "@account-kit/react";\\n \\nconst { client } = useSmartAccountClient({ type: "LightAccount" });\\nconst {\\n signTypedData,\\n signTypedDataAsync,\\n signedTypedData,\\n isSigningTypedData,\\n error,\\n} = useSignTypedData({\\n client,\\n // these are optional\\n onSuccess: (result) => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignTypedData.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useSignTypedData, useSmartAccountClient } from "@account-kit/react";\\n \\nconst { client } = useSmartAccountClient({ type: "LightAccount" });\\nconst {\\n signTypedData,\\n signTypedDataAsync,\\n signedTypedData,\\n isSigningTypedData,\\n error,\\n} = useSignTypedData({\\n client,\\n // these are optional\\n onSuccess: (result) => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useSignTypedData\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignTypedData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSignTypedData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useSignTypedData\"]},{\"href\":\"/reference/account-kit/react/hooks/useSignTypedData#args\",\"html\":\"\\nUseSignTypedDataArgs
\\nThe arguments for the hook, including client and mutation-related arguments
UseSignTypedDataResult
\\nAn object containing methods and state related to the sign typed data mutation process
Hook for accessing the current Alchemy signer within a React component. It uses a synchronous external store for updates.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSigner.mdx#usesigner\",\"isPage\":true,\"text\":\"\\nHook for accessing the current Alchemy signer within a React component. It uses a synchronous external store for updates.\\n\",\"title\":\"useSigner\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSigner#import\",\"html\":\"\\nimport { useSigner } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSigner } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSigner\"]},{\"href\":\"/reference/account-kit/react/hooks/useSigner#usage\",\"html\":\"\\nimport { useSigner } from "@account-kit/react";\\n \\nconst signer = useSigner();
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSigner.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useSigner } from "@account-kit/react";\\n \\nconst signer = useSigner();\\n\",\"title\":\"Usage\",\"titles\":[\"useSigner\"]},{\"href\":\"/reference/account-kit/react/hooks/useSigner#returns\",\"html\":\"\\nAlchemyWebSigner | null
\\nThe current Alchemy signer or null if none is available
Uses the provided smart account client parameters to create or retrieve an existing smart account client, handling different types of accounts including LightAccount, MultiOwnerLightAccount, and MultiOwnerModularAccount.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSmartAccountClient.mdx#usesmartaccountclient\",\"isPage\":true,\"text\":\"\\nUses the provided smart account client parameters to create or retrieve an existing smart account client, handling different types of accounts including LightAccount, MultiOwnerLightAccount, and MultiOwnerModularAccount.\\n\",\"title\":\"useSmartAccountClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useSmartAccountClient#import\",\"html\":\"\\nimport { useSmartAccountClient } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSmartAccountClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useSmartAccountClient } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useSmartAccountClient\"]},{\"href\":\"/reference/account-kit/react/hooks/useSmartAccountClient#usage\",\"html\":\"\\nimport { useSmartAccountClient } from "@account-kit/react";\\n \\nconst { client, address, isLoadingClient } = useSmartAccountClient({\\ntype: "LightAccount",\\naccountParams: {...}, // optional params to further configure the account\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSmartAccountClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useSmartAccountClient } from "@account-kit/react";\\n \\nconst { client, address, isLoadingClient } = useSmartAccountClient({\\ntype: "LightAccount",\\naccountParams: {...}, // optional params to further configure the account\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useSmartAccountClient\"]},{\"href\":\"/reference/account-kit/react/hooks/useSmartAccountClient#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useSmartAccountClient.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useSmartAccountClient\"]},{\"href\":\"/reference/account-kit/react/hooks/useSmartAccountClient#props\",\"html\":\"\\nUseSmartAccountClientProps
\\nThe properties required to use the smart account client, including account parameters, type, and additional client parameters.
UseSmartAccountClientResult
\\nAn object containing the smart account client, the address, and a loading state.
Connects the Provider to an Account and returns a Signer
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/connectToAccount.mdx#connecttoaccount\",\"isPage\":true,\"text\":\"\\nConnects the Provider to an Account and returns a Signer\\n\",\"title\":\"connectToAccount\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/connectToAccount#import\",\"html\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/connectToAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"connectToAccount\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/connectToAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/connectToAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"connectToAccount\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/connectToAccount#account\",\"html\":\"\\nSmartContractAccount
AccountSigner
\\nan AccountSigner that can be used to sign and send user operations
A React hook that returns the current user information, either from an External Owned Account (EOA) or from the client store. It uses the Alchemy account context and synchronizes with external store updates.
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useUser.mdx#useuser\",\"isPage\":true,\"text\":\"\\nA React hook that returns the current user information, either from an External Owned Account (EOA) or from the client store. It uses the Alchemy account context and synchronizes with external store updates.\\n\",\"title\":\"useUser\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useUser#import\",\"html\":\"\\nimport { useUser } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useUser.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useUser } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useUser\"]},{\"href\":\"/reference/account-kit/react/hooks/useUser#usage\",\"html\":\"\\nimport { useUser } from "@account-kit/react";\\n \\nconst user = useUser();
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useUser.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { useUser } from "@account-kit/react";\\n \\nconst user = useUser();\\n\",\"title\":\"Usage\",\"titles\":[\"useUser\"]},{\"href\":\"/reference/account-kit/react/hooks/useUser#returns\",\"html\":\"\\nUseUserResult
\\nThe user information, including address, orgId, userId, and type. If the user is not connected, it returns null.
Creates an instance of EthersProviderAdapter from an ethers.js JsonRpcProvider.
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/fromEthersProvider.mdx#fromethersprovider\",\"isPage\":true,\"text\":\"\\nCreates an instance of EthersProviderAdapter from an ethers.js JsonRpcProvider.\\n\",\"title\":\"fromEthersProvider\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/fromEthersProvider#import\",\"html\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/fromEthersProvider.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"fromEthersProvider\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/fromEthersProvider#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/fromEthersProvider.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"fromEthersProvider\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/fromEthersProvider#provider\",\"html\":\"\\nJsonRpcProvider
\\nthe ethers JSON RPC provider to convert
Chain
\\nthe chain to connect to
EthersProviderAdapter
\\nan instance of EthersProviderAdapter
Custom hook to wait for a user operation transaction and manage its state (pending, error, result).
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useWaitForUserOperationTransaction.mdx#usewaitforuseroperationtransaction\",\"isPage\":true,\"text\":\"\\nCustom hook to wait for a user operation transaction and manage its state (pending, error, result).\\n\",\"title\":\"useWaitForUserOperationTransaction\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useWaitForUserOperationTransaction#import\",\"html\":\"\\nimport { useWaitForUserOperationTransaction } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useWaitForUserOperationTransaction.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useWaitForUserOperationTransaction } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useWaitForUserOperationTransaction\"]},{\"href\":\"/reference/account-kit/react/hooks/useWaitForUserOperationTransaction#usage\",\"html\":\"\\nimport {\\n useWaitForUserOperationTransaction,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nconst { client } = useSmartAccountClient({ type: "LightAccount" });\\nconst {\\n waitForUserOperationTransaction,\\n waitForUserOperationTransactionResult,\\n isWaitingForUserOperationTransaction,\\n error,\\n} = useWaitForUserOperationTransaction({\\n client,\\n // these are optional\\n onSuccess: (result) => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useWaitForUserOperationTransaction.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport {\\n useWaitForUserOperationTransaction,\\n useSmartAccountClient,\\n} from "@account-kit/react";\\n \\nconst { client } = useSmartAccountClient({ type: "LightAccount" });\\nconst {\\n waitForUserOperationTransaction,\\n waitForUserOperationTransactionResult,\\n isWaitingForUserOperationTransaction,\\n error,\\n} = useWaitForUserOperationTransaction({\\n client,\\n // these are optional\\n onSuccess: (result) => {\\n // do something on success\\n },\\n onError: (error) => console.error(error),\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"useWaitForUserOperationTransaction\"]},{\"href\":\"/reference/account-kit/react/hooks/useWaitForUserOperationTransaction#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useWaitForUserOperationTransaction.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"useWaitForUserOperationTransaction\"]},{\"href\":\"/reference/account-kit/react/hooks/useWaitForUserOperationTransaction#config\",\"html\":\"\\nUseWaitForUserOperationTransactionArgs
\\nConfiguration object containing the client
UseWaitForUserOperationTransactionResult
\\nAn object containing methods and state related to waiting for a user operation transaction
Creates a new ClientOnlyPropertyError
\\n\\n\",\"id\":\"pages/reference/account-kit/core/classes/ClientOnlyPropertyError/constructor.mdx#clientonlypropertyerror\",\"isPage\":true,\"text\":\"\\nCreates a new ClientOnlyPropertyError\\nClientOnlyPropertyError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"ClientOnlyPropertyError\",\"titles\":[]},{\"href\":\"/reference/account-kit/core/classes/ClientOnlyPropertyError/constructor#import\",\"html\":\"\\nimport { ClientOnlyPropertyError } from "@account-kit/core";
\\n\",\"id\":\"pages/reference/account-kit/core/classes/ClientOnlyPropertyError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { ClientOnlyPropertyError } from "@account-kit/core";\\n\",\"title\":\"Import\",\"titles\":[\"ClientOnlyPropertyError\"]},{\"href\":\"/reference/account-kit/core/classes/ClientOnlyPropertyError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/core/classes/ClientOnlyPropertyError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"ClientOnlyPropertyError\"]},{\"href\":\"/reference/account-kit/core/classes/ClientOnlyPropertyError/constructor#property\",\"html\":\"\\nstring
\\nthe name of the property that is only available on the client
Rewrites the send method to use the account provider's EIP-1193\\ncompliant request method
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/send.mdx#send\",\"isPage\":true,\"text\":\"\\nRewrites the send method to use the account provider's EIP-1193\\ncompliant request method\\n\",\"title\":\"send\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/send#import\",\"html\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/send.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"send\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/send#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/send.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"send\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/send#method\",\"html\":\"\\nany
any[]
Promise<any>
\\nthe result of the RPC call
Configures and initializes the account provider based on the given options.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor.mdx#ethersprovideradapter\",\"isPage\":true,\"text\":\"\\nConfigures and initializes the account provider based on the given options.\\nEthersProviderAdapter extends JsonRpcProvider, see the docs for JsonRpcProvider for all supported methods.\\n\",\"title\":\"EthersProviderAdapter\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor#import\",\"html\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"EthersProviderAdapter\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter({\\n account,\\n chain: sepolia,\\n rpcProvider: "https://eth-sepolia.g.alchemy.com/v2/your-api-key",\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter({\\n account,\\n chain: sepolia,\\n rpcProvider: "https://eth-sepolia.g.alchemy.com/v2/your-api-key",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"EthersProviderAdapter\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"EthersProviderAdapter\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/constructor#opts\",\"html\":\"\\nEthersProviderAdapterOpts
\\nThe options for setting up the ethers provider adapter
Custom hook to manage and update the UI configuration. This hook retrieves the UI config from the context, syncs it with the local state, and updates it if necessary.\\nNOTE: this hook is mainly meant to be used internally, but provides utility if you need your UI config to be dynamic
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useUiConfig.mdx#useuiconfig\",\"isPage\":true,\"text\":\"\\nCustom hook to manage and update the UI configuration. This hook retrieves the UI config from the context, syncs it with the local state, and updates it if necessary.\\nNOTE: this hook is mainly meant to be used internally, but provides utility if you need your UI config to be dynamic\\n\",\"title\":\"useUiConfig\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/hooks/useUiConfig#import\",\"html\":\"\\nimport { useUiConfig } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useUiConfig.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { useUiConfig } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"useUiConfig\"]},{\"href\":\"/reference/account-kit/react/hooks/useUiConfig#usage\",\"html\":\"\\nimport {\\n createConfig,\\n useUiConfig,\\n DEFAULT_UI_CONFIG,\\n} from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst config = createConfig(\\n {\\n apiKey: "you-api-key",\\n chain: sepolia,\\n },\\n DEFAULT_UI_CONFIG\\n);\\n \\n// somewhere in a component...\\n \\nconst { updateConfig, ...uiConfig } = useUiConfig();
\\n\",\"id\":\"pages/reference/account-kit/react/hooks/useUiConfig.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport {\\n createConfig,\\n useUiConfig,\\n DEFAULT_UI_CONFIG,\\n} from "@account-kit/react";\\nimport { sepolia } from "@account-kit/infra";\\n \\nconst config = createConfig(\\n {\\n apiKey: "you-api-key",\\n chain: sepolia,\\n },\\n DEFAULT_UI_CONFIG\\n);\\n \\n// somewhere in a component...\\n \\nconst { updateConfig, ...uiConfig } = useUiConfig();\\n\",\"title\":\"Usage\",\"titles\":[\"useUiConfig\"]},{\"href\":\"/reference/account-kit/react/hooks/useUiConfig#returns\",\"html\":\"\\nAlchemyAccountsUIConfigWithDefaults & {updateConfig: (partial: AlchemyAccountsUIConfig) => void}
\\nthe configuration object along with an update function
Creates and returns a BundlerClient using the existing account provider's transport and chain.
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/getBundlerClient.mdx#getbundlerclient\",\"isPage\":true,\"text\":\"\\nCreates and returns a BundlerClient using the existing account provider's transport and chain.\\n\",\"title\":\"getBundlerClient\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/getBundlerClient#import\",\"html\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/getBundlerClient.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { EthersProviderAdapter } from "@aa-sdk/ethers";\\n\",\"title\":\"Import\",\"titles\":[\"getBundlerClient\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/getBundlerClient#usage\",\"html\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter({\\n account,\\n chain: sepolia,\\n rpcProvider: "https://eth-sepolia.g.alchemy.com/v2/your-api-key",\\n});\\n \\nconst bundlerClient = provider.getBundlerClient();
\\n\",\"id\":\"pages/reference/aa-sdk/ethers/classes/EthersProviderAdapter/getBundlerClient.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AccountSigner, EthersProviderAdapter } from "@aa-sdk/ethers";\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { sepolia } from "@account-kit/infra";\\nimport { createLightAccount } from "@account-kit/smart-contracts";\\n \\nconst account = await createLightAccount({\\n transport: http("https://rpc.testnet.aepps.com"),\\n chain: sepolia,\\n signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey()),\\n});\\n \\nconst provider = new EthersProviderAdapter({\\n account,\\n chain: sepolia,\\n rpcProvider: "https://eth-sepolia.g.alchemy.com/v2/your-api-key",\\n});\\n \\nconst bundlerClient = provider.getBundlerClient();\\n\",\"title\":\"Usage\",\"titles\":[\"getBundlerClient\"]},{\"href\":\"/reference/aa-sdk/ethers/classes/EthersProviderAdapter/getBundlerClient#returns\",\"html\":\"\\nBundlerClient<Transport>
\\nA bundler client configured with the existing account provider.
Adds a contract access entry to the internal list of contract address access entries.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry.mdx#addcontractaddressaccessentry\",\"isPage\":true,\"text\":\"\\nAdds a contract access entry to the internal list of contract address access entries.\\n\",\"title\":\"addContractAddressAccessEntry\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"addContractAddressAccessEntry\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.addContractAddressAccessEntry({\\n contractAddress: "0x1234",\\n isOnList: true,\\n checkSelectors: true,\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.addContractAddressAccessEntry({\\n contractAddress: "0x1234",\\n isOnList: true,\\n checkSelectors: true,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"addContractAddressAccessEntry\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"addContractAddressAccessEntry\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractAddressAccessEntry#entry\",\"html\":\"\\nContractAccessEntry
\\nthe contract access entry to be added
SessionKeyPermissionsBuilder
\\nthe instance of the current class for chaining
Adds an ERC20 token spend limit to the list of limits and returns the updated object.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit.mdx#adderc20tokenspendlimit\",\"isPage\":true,\"text\":\"\\nAdds an ERC20 token spend limit to the list of limits and returns the updated object.\\n\",\"title\":\"addErc20TokenSpendLimit\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"addErc20TokenSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.addErc20TokenSpendLimit({\\n tokenAddress: "0x1234",\\n spendLimit: 1000000000000000000n,\\n refreshInterval: 3600,\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.addErc20TokenSpendLimit({\\n tokenAddress: "0x1234",\\n spendLimit: 1000000000000000000n,\\n refreshInterval: 3600,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"addErc20TokenSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"addErc20TokenSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addErc20TokenSpendLimit#limit\",\"html\":\"\\nErc20TokenLimit
\\nThe ERC20 token spend limit to be added
object
\\nThe updated object with the new ERC20 token spend limit
Encodes various function calls into an array of hexadecimal strings based on the provided permissions and limits.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/encode.mdx#encode\",\"isPage\":true,\"text\":\"\\nEncodes various function calls into an array of hexadecimal strings based on the provided permissions and limits.\\n\",\"title\":\"encode\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/encode#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/encode.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"encode\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/encode#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setRequiredPaymaster("0x1234");\\nconst encoded = builder.encode();
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/encode.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setRequiredPaymaster("0x1234");\\nconst encoded = builder.encode();\\n\",\"title\":\"Usage\",\"titles\":[\"encode\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/encode#returns\",\"html\":\"\\nHex[]
\\nAn array of encoded hexadecimal strings representing the function calls for setting access control, permissions, and limits.
Adds a contract method entry to the _contractMethodAccessEntrys
array.
import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractFunctionAccessEntry.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"addContractFunctionAccessEntry\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractFunctionAccessEntry#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.addContractAddressAccessEntry({\\n contractAddress: "0x1234",\\n methodSelector: "0x45678",\\n isOnList: true,\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractFunctionAccessEntry.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.addContractAddressAccessEntry({\\n contractAddress: "0x1234",\\n methodSelector: "0x45678",\\n isOnList: true,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"addContractFunctionAccessEntry\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractFunctionAccessEntry#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractFunctionAccessEntry.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"addContractFunctionAccessEntry\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/addContractFunctionAccessEntry#entry\",\"html\":\"\\nContractMethodEntry
\\nThe contract method entry to be added
SessionKeyPermissionsBuilder
\\nThe instance of the class for method chaining
Initializes a new instance of a session key signer with the provided configuration. This will set the signerType
, storageKey
, and storageType
. It will also manage the session key, either fetching it from storage or generating a new one if it doesn't exist.
import { SessionKeySigner } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"SessionKeySigner\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/constructor#usage\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/constructor.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\n\",\"title\":\"Usage\",\"titles\":[\"SessionKeySigner\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"SessionKeySigner\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/constructor#config_\",\"html\":\"\\nSessionKeySignerConfig
\\nthe configuration for initializing the session key signer
Sets the required paymaster address.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster.mdx#setrequiredpaymaster\",\"isPage\":true,\"text\":\"\\nSets the required paymaster address.\\n\",\"title\":\"setRequiredPaymaster\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"setRequiredPaymaster\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setRequiredPaymaster("0x1234");
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setRequiredPaymaster("0x1234");\\n\",\"title\":\"Usage\",\"titles\":[\"setRequiredPaymaster\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setRequiredPaymaster\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setRequiredPaymaster#paymaster\",\"html\":\"\\nAddress
\\nthe address of the paymaster to be set
SessionKeyPermissionsBuilder
\\nthe current instance for method chaining
Sets the access control type for the contract and returns the current instance for method chaining.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType.mdx#setcontractaccesscontroltype\",\"isPage\":true,\"text\":\"\\nSets the access control type for the contract and returns the current instance for method chaining.\\n\",\"title\":\"setContractAccessControlType\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"setContractAccessControlType\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setContractAccessControlType(SessionKeyAccessListType.ALLOWLIST);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setContractAccessControlType(SessionKeyAccessListType.ALLOWLIST);\\n\",\"title\":\"Usage\",\"titles\":[\"setContractAccessControlType\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setContractAccessControlType\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setContractAccessControlType#acltype\",\"html\":\"\\nSessionKeyAccessListType
\\nThe access control type for the session key
SessionKeyPermissionsBuilder
\\nThe current instance for method chaining
Sets the native token spend limit and returns the instance for chaining.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit.mdx#setnativetokenspendlimit\",\"isPage\":true,\"text\":\"\\nSets the native token spend limit and returns the instance for chaining.\\n\",\"title\":\"setNativeTokenSpendLimit\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"setNativeTokenSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setNativeTokenSpendLimit({\\n spendLimit: 1000000000000000000n,\\n refreshInterval: 3600,\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setNativeTokenSpendLimit({\\n spendLimit: 1000000000000000000n,\\n refreshInterval: 3600,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"setNativeTokenSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setNativeTokenSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setNativeTokenSpendLimit#limit\",\"html\":\"\\nNativeTokenLimit
\\nThe limit to set for native token spending
SessionKeyPermissionsBuilder
\\nThe instance for chaining
Sets the time range for an object and returns the object itself for chaining.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange.mdx#settimerange\",\"isPage\":true,\"text\":\"\\nSets the time range for an object and returns the object itself for chaining.\\n\",\"title\":\"setTimeRange\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"setTimeRange\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setTimeRange({\\n validFrom: Date.now(),\\n validUntil: Date.now() + 15 * 60 * 1000,\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setTimeRange({\\n validFrom: Date.now(),\\n validUntil: Date.now() + 15 * 60 * 1000,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"setTimeRange\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setTimeRange\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setTimeRange#timerange\",\"html\":\"\\nTimeRange
\\nThe time range to be set
SessionKeyPermissionsBuilder
\\nThe current object for method chaining
Sets the gas spend limit and returns the current instance for method chaining.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit.mdx#setgasspendlimit\",\"isPage\":true,\"text\":\"\\nSets the gas spend limit and returns the current instance for method chaining.\\n\",\"title\":\"setGasSpendLimit\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit#import\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"setGasSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit#usage\",\"html\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setGasSpendLimit({\\n spendLimit: 1000000000000000000n,\\n refreshInterval: 3600,\\n});
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts";\\n \\nconst builder = new SessionKeyPermissionsBuilder();\\nbuilder.setGasSpendLimit({\\n spendLimit: 1000000000000000000n,\\n refreshInterval: 3600,\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"setGasSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setGasSpendLimit\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeyPermissionsBuilder/setGasSpendLimit#limit\",\"html\":\"\\nGasSpendLimit
SessionKeyPermissionsBuilder
\\nThe current instance for chaining
Generates a new private key and stores it in the storage.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/generateNewKey.mdx#generatenewkey\",\"isPage\":true,\"text\":\"\\nGenerates a new private key and stores it in the storage.\\n\",\"title\":\"generateNewKey\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/generateNewKey#import\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/generateNewKey.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"generateNewKey\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/generateNewKey#usage\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconst newSessionKey = signer.generateNewKey();
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/generateNewKey.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconst newSessionKey = signer.generateNewKey();\\n\",\"title\":\"Usage\",\"titles\":[\"generateNewKey\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/generateNewKey#returns\",\"html\":\"\\nAddress
\\nThe public address of the new key.
An async function that retrieves the address using the inner object's getAddress
method.
import { SessionKeySigner } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/getAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/getAddress#usage\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconst sessionKeyAddress = await signer.getAddress();
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/getAddress.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconst sessionKeyAddress = await signer.getAddress();\\n\",\"title\":\"Usage\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/getAddress#returns\",\"html\":\"\\nPromise<string>
\\nA promise that resolves to the address as a string
Signs a message using the inner signer.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage.mdx#signmessage\",\"isPage\":true,\"text\":\"\\nSigns a message using the inner signer.\\n\",\"title\":\"signMessage\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage#import\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage#usage\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconst sessionKeyAddress = await signer.signMessage("hello");
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconst sessionKeyAddress = await signer.signMessage("hello");\\n\",\"title\":\"Usage\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signMessage#msg\",\"html\":\"\\nSignableMessage
\\nThe message to sign
Promise<Hex>
\\nA promise that resolves to the signed message
Signs the provided typed data using the inner signer.
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData.mdx#signtypeddata\",\"isPage\":true,\"text\":\"\\nSigns the provided typed data using the inner signer.\\n\",\"title\":\"signTypedData\",\"titles\":[]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData#import\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n\",\"title\":\"Import\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData#usage\",\"html\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconsole.log(\\n await signer.signTypedData({\\n types: {\\n Message: [{ name: "content", type: "string" }],\\n },\\n primaryType: "Message",\\n message: { content: "Hello" },\\n })\\n);
\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { SessionKeySigner } from "@account-kit/smart-contracts";\\n \\nconst signer = new SessionKeySigner();\\nconsole.log(\\n await signer.signTypedData({\\n types: {\\n Message: [{ name: "content", type: "string" }],\\n },\\n primaryType: "Message",\\n message: { content: "Hello" },\\n })\\n);\\n\",\"title\":\"Usage\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/account-kit/smart-contracts/classes/SessionKeySigner/signTypedData#params\",\"html\":\"\\nTypedDataDefinition<TTypedData, TPrimaryType>
\\nThe parameters containing the typed data definition and primary type.
Promise<string>
\\nA promise that resolves to the signed typed data as a string.
Constructor for initializing an error message indicating that an account could not be found to execute the specified action.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/AccountNotFoundError/constructor.mdx#accountnotfounderror\",\"isPage\":true,\"text\":\"\\nConstructor for initializing an error message indicating that an account could not be found to execute the specified action.\\nAccountNotFoundError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"AccountNotFoundError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/AccountNotFoundError/constructor#import\",\"html\":\"\\nimport { AccountNotFoundError } from "@aa-sdk/core";
\",\"id\":\"pages/reference/aa-sdk/core/classes/AccountNotFoundError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountNotFoundError } from "@aa-sdk/core";\",\"title\":\"Import\",\"titles\":[\"AccountNotFoundError\"]}]}],[\"index.2a57ce322fa212fe4cbcaa885f21ff7ad4084241a02b41ff26853718b46cb512\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: EntryPointNotFoundError\\ndescription: Overview of the EntryPointNotFoundError method\\n---\\n\\n# EntryPointNotFoundError\\n\\nConstructs an error message indicating that no default entry point exists for the given chain and entry point version.\\n:::note\\n`EntryPointNotFoundError` extends `BaseError`, see the docs for BaseError for all supported methods.\\n:::\\n\\n## Import\\n\\n```ts\\nimport { EntryPointNotFoundError } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Parameters\\n\\n### chain\\n\\n`Chain`\\nThe blockchain network for which the entry point is being queried\\n\\n### entryPointVersion\\n\\n`any`\\nThe version of the entry point for which no default exists\\n\",\"document\":[{\"href\":\"/reference/aa-sdk/core/classes/EntryPointNotFoundError/constructor#entrypointnotfounderror\",\"html\":\"\\nConstructs an error message indicating that no default entry point exists for the given chain and entry point version.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/EntryPointNotFoundError/constructor.mdx#entrypointnotfounderror\",\"isPage\":true,\"text\":\"\\nConstructs an error message indicating that no default entry point exists for the given chain and entry point version.\\nEntryPointNotFoundError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"EntryPointNotFoundError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/EntryPointNotFoundError/constructor#import\",\"html\":\"\\nimport { EntryPointNotFoundError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/EntryPointNotFoundError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { EntryPointNotFoundError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"EntryPointNotFoundError\"]},{\"href\":\"/reference/aa-sdk/core/classes/EntryPointNotFoundError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/EntryPointNotFoundError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"EntryPointNotFoundError\"]},{\"href\":\"/reference/aa-sdk/core/classes/EntryPointNotFoundError/constructor#chain\",\"html\":\"\\nChain
\\nThe blockchain network for which the entry point is being queried
any
\\nThe version of the entry point for which no default exists
Custom error message constructor for failing to get a specific storage slot.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/FailedToGetStorageSlotError/constructor.mdx#failedtogetstoragesloterror\",\"isPage\":true,\"text\":\"\\nCustom error message constructor for failing to get a specific storage slot.\\nFailedToGetStorageSlotError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"FailedToGetStorageSlotError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/FailedToGetStorageSlotError/constructor#import\",\"html\":\"\\nimport { FailedToGetStorageSlotError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/FailedToGetStorageSlotError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { FailedToGetStorageSlotError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"FailedToGetStorageSlotError\"]},{\"href\":\"/reference/aa-sdk/core/classes/FailedToGetStorageSlotError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/FailedToGetStorageSlotError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"FailedToGetStorageSlotError\"]},{\"href\":\"/reference/aa-sdk/core/classes/FailedToGetStorageSlotError/constructor#slot\",\"html\":\"\\nstring
\\nThe storage slot that failed to be accessed or retrieved
string
\\nA description of the storage slot, for additional context in the error message
Constructs an error indicating that an account of the specified type requires an owner to execute.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/AccountRequiresOwnerError/constructor.mdx#accountrequiresownererror\",\"isPage\":true,\"text\":\"\\nConstructs an error indicating that an account of the specified type requires an owner to execute.\\nAccountRequiresOwnerError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"AccountRequiresOwnerError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/AccountRequiresOwnerError/constructor#import\",\"html\":\"\\nimport { AccountRequiresOwnerError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/AccountRequiresOwnerError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AccountRequiresOwnerError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"AccountRequiresOwnerError\"]},{\"href\":\"/reference/aa-sdk/core/classes/AccountRequiresOwnerError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/AccountRequiresOwnerError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"AccountRequiresOwnerError\"]},{\"href\":\"/reference/aa-sdk/core/classes/AccountRequiresOwnerError/constructor#accounttype\",\"html\":\"\\nstring
\\nThe type of account that requires an owner
Constructs an error indicating an invalid entry point version for a specific chain.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidEntryPointError/constructor.mdx#invalidentrypointerror\",\"isPage\":true,\"text\":\"\\nConstructs an error indicating an invalid entry point version for a specific chain.\\nInvalidEntryPointError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"InvalidEntryPointError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidEntryPointError/constructor#import\",\"html\":\"\\nimport { InvalidEntryPointError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidEntryPointError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { InvalidEntryPointError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"InvalidEntryPointError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidEntryPointError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidEntryPointError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"InvalidEntryPointError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidEntryPointError/constructor#chain\",\"html\":\"\\nChain
\\nThe chain object containing information about the blockchain
any
\\nThe entry point version that is invalid
Creates an instance of an error with a message indicating an invalid RPC URL.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidRpcUrlError/constructor.mdx#invalidrpcurlerror\",\"isPage\":true,\"text\":\"\\nCreates an instance of an error with a message indicating an invalid RPC URL.\\nInvalidRpcUrlError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"InvalidRpcUrlError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidRpcUrlError/constructor#import\",\"html\":\"\\nimport { InvalidRpcUrlError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidRpcUrlError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { InvalidRpcUrlError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"InvalidRpcUrlError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidRpcUrlError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidRpcUrlError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"InvalidRpcUrlError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidRpcUrlError/constructor#rpcurl\",\"html\":\"\\nstring
\\nThe invalid RPC URL that caused the error
Initializes a new instance of the error message with a default message indicating that no chain was supplied to the client.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/ChainNotFoundError/constructor.mdx#chainnotfounderror\",\"isPage\":true,\"text\":\"\\nInitializes a new instance of the error message with a default message indicating that no chain was supplied to the client.\\nChainNotFoundError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"ChainNotFoundError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/ChainNotFoundError/constructor#import\",\"html\":\"\\nimport { ChainNotFoundError } from "@aa-sdk/core";
\",\"id\":\"pages/reference/aa-sdk/core/classes/ChainNotFoundError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { ChainNotFoundError } from "@aa-sdk/core";\",\"title\":\"Import\",\"titles\":[\"ChainNotFoundError\"]}]}],[\"index.8d675115fbc208f6cb8301d845b178b882eeb09fe06b95f65ca2492ed19033d1\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: InvalidUserOperationError\\ndescription: Overview of the InvalidUserOperationError method\\n---\\n\\n# InvalidUserOperationError\\n\\nCreates an instance of InvalidUserOperationError.\\n\\nInvalidUserOperationError constructor\\n:::note\\n`InvalidUserOperationError` extends `BaseError`, see the docs for BaseError for all supported methods.\\n:::\\n\\n## Import\\n\\n```ts\\nimport { InvalidUserOperationError } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Parameters\\n\\n### uo\\n\\n`UserOperationStruct`\\nthe invalid user operation struct\\n\",\"document\":[{\"href\":\"/reference/aa-sdk/core/classes/InvalidUserOperationError/constructor#invaliduseroperationerror\",\"html\":\"\\nCreates an instance of InvalidUserOperationError.
\\nInvalidUserOperationError constructor
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidUserOperationError/constructor.mdx#invaliduseroperationerror\",\"isPage\":true,\"text\":\"\\nCreates an instance of InvalidUserOperationError.\\nInvalidUserOperationError constructor\\nInvalidUserOperationError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"InvalidUserOperationError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidUserOperationError/constructor#import\",\"html\":\"\\nimport { InvalidUserOperationError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidUserOperationError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { InvalidUserOperationError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"InvalidUserOperationError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidUserOperationError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidUserOperationError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"InvalidUserOperationError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidUserOperationError/constructor#uo\",\"html\":\"\\nUserOperationStruct
\\nthe invalid user operation struct
Constructs an error message indicating that batch execution is not supported by the specified account type.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/BatchExecutionNotSupportedError/constructor.mdx#batchexecutionnotsupportederror\",\"isPage\":true,\"text\":\"\\nConstructs an error message indicating that batch execution is not supported by the specified account type.\\nBatchExecutionNotSupportedError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"BatchExecutionNotSupportedError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/BatchExecutionNotSupportedError/constructor#import\",\"html\":\"\\nimport { BatchExecutionNotSupportedError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/BatchExecutionNotSupportedError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BatchExecutionNotSupportedError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"BatchExecutionNotSupportedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/BatchExecutionNotSupportedError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/BatchExecutionNotSupportedError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"BatchExecutionNotSupportedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/BatchExecutionNotSupportedError/constructor#accounttype\",\"html\":\"\\nstring
\\nthe type of account that does not support batch execution
Constructs an error message indicating that no default factory was found for the given account type, chain, and entry point version.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/DefaultFactoryNotDefinedError/constructor.mdx#defaultfactorynotdefinederror\",\"isPage\":true,\"text\":\"\\nConstructs an error message indicating that no default factory was found for the given account type, chain, and entry point version.\\nDefaultFactoryNotDefinedError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"DefaultFactoryNotDefinedError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/DefaultFactoryNotDefinedError/constructor#import\",\"html\":\"\\nimport { DefaultFactoryNotDefinedError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/DefaultFactoryNotDefinedError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { DefaultFactoryNotDefinedError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"DefaultFactoryNotDefinedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/DefaultFactoryNotDefinedError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/DefaultFactoryNotDefinedError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"DefaultFactoryNotDefinedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/DefaultFactoryNotDefinedError/constructor#accounttype\",\"html\":\"\\nstring
\\nthe type of account
Chain
\\nthe blockchain chain
EntryPointVersion
\\nthe entry point version
Logs an informational message to the console if the logging level is set to INFO.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/info.mdx#info\",\"isPage\":true,\"text\":\"\\nLogs an informational message to the console if the logging level is set to INFO.\\n\",\"title\":\"info\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/info#import\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/info.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"info\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/info#usage\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.info("Something is happening");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/info.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.info("Something is happening");\\n\",\"title\":\"Usage\",\"titles\":[\"info\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/info#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/info.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"info\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/info#msg\",\"html\":\"\\nstring
\\nthe message to log
...any[]
\\nadditional arguments to log alongside the message
Constructor for initializing an error message indicating the failure of fetching the counter-factual address.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/GetCounterFactualAddressError/constructor.mdx#getcounterfactualaddresserror\",\"isPage\":true,\"text\":\"\\nConstructor for initializing an error message indicating the failure of fetching the counter-factual address.\\nGetCounterFactualAddressError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"GetCounterFactualAddressError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/GetCounterFactualAddressError/constructor#import\",\"html\":\"\\nimport { GetCounterFactualAddressError } from "@aa-sdk/core";
\",\"id\":\"pages/reference/aa-sdk/core/classes/GetCounterFactualAddressError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { GetCounterFactualAddressError } from "@aa-sdk/core";\",\"title\":\"Import\",\"titles\":[\"GetCounterFactualAddressError\"]}]}],[\"index.16bb156efa2868a18ba461f7e93b0dc4827453767b0c5ec31a53fe68902d2b83\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: IncompatibleClientError\\ndescription: Overview of the IncompatibleClientError method\\n---\\n\\n# IncompatibleClientError\\n\\nThrows an error when the client type does not match the expected client type.\\n:::note\\n`IncompatibleClientError` extends `BaseError`, see the docs for BaseError for all supported methods.\\n:::\\n\\n## Import\\n\\n```ts\\nimport { IncompatibleClientError } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Parameters\\n\\n### expectedClient\\n\\n`string`\\nThe expected type of the client.\\n\\n### method\\n\\n`string`\\nThe method that was called.\\n\\n### client\\n\\n`Client`\\nThe client instance.\\n\",\"document\":[{\"href\":\"/reference/aa-sdk/core/classes/IncompatibleClientError/constructor#incompatibleclienterror\",\"html\":\"\\nThrows an error when the client type does not match the expected client type.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/IncompatibleClientError/constructor.mdx#incompatibleclienterror\",\"isPage\":true,\"text\":\"\\nThrows an error when the client type does not match the expected client type.\\nIncompatibleClientError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"IncompatibleClientError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/IncompatibleClientError/constructor#import\",\"html\":\"\\nimport { IncompatibleClientError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/IncompatibleClientError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { IncompatibleClientError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"IncompatibleClientError\"]},{\"href\":\"/reference/aa-sdk/core/classes/IncompatibleClientError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/IncompatibleClientError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"IncompatibleClientError\"]},{\"href\":\"/reference/aa-sdk/core/classes/IncompatibleClientError/constructor#expectedclient\",\"html\":\"\\nstring
\\nThe expected type of the client.
string
\\nThe method that was called.
Client
\\nThe client instance.
Logs an error message to the console if the logging condition is met.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/error.mdx#error\",\"isPage\":true,\"text\":\"\\nLogs an error message to the console if the logging condition is met.\\n\",\"title\":\"error\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/error#import\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/error.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"error\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/error#usage\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.error("An error occurred while processing the request");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/error.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.error("An error occurred while processing the request");\\n\",\"title\":\"Usage\",\"titles\":[\"error\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/error#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/error.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"error\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/error#msg\",\"html\":\"\\nstring
\\nThe primary error message to be logged
...any[]
\\nAdditional arguments to be logged along with the error message
Constructs an error message when an invalid signer type is passed to SmartAccountSigner.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidSignerTypeError/constructor.mdx#invalidsignertypeerror\",\"isPage\":true,\"text\":\"\\nConstructs an error message when an invalid signer type is passed to SmartAccountSigner.\\nInvalidSignerTypeError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"InvalidSignerTypeError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidSignerTypeError/constructor#import\",\"html\":\"\\nimport { InvalidSignerTypeError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidSignerTypeError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { InvalidSignerTypeError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"InvalidSignerTypeError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidSignerTypeError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/InvalidSignerTypeError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"InvalidSignerTypeError\"]},{\"href\":\"/reference/aa-sdk/core/classes/InvalidSignerTypeError/constructor#signertype\",\"html\":\"\\nstring
\\nAn optional parameter specifying the signer type. If not provided, a default error message will be used.
Throws an error indicating that signing a transaction is not supported by smart contracts.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/SignTransactionNotSupportedError/constructor.mdx#signtransactionnotsupportederror\",\"isPage\":true,\"text\":\"\\nThrows an error indicating that signing a transaction is not supported by smart contracts.\\nSignTransactionNotSupportedError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"SignTransactionNotSupportedError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/SignTransactionNotSupportedError/constructor#import\",\"html\":\"\\nimport { SignTransactionNotSupportedError } from "@aa-sdk/core";
\",\"id\":\"pages/reference/aa-sdk/core/classes/SignTransactionNotSupportedError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SignTransactionNotSupportedError } from "@aa-sdk/core";\",\"title\":\"Import\",\"titles\":[\"SignTransactionNotSupportedError\"]}]}],[\"index.4d02de016bfe402be37fe0cd328748f840746e88d62884ac91e541ef5c3e07e4\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: IncorrectAccountType\\ndescription: Overview of the IncorrectAccountType method\\n---\\n\\n# IncorrectAccountType\\n\\nConstructs an error object indicating that the expected account type does not match the actual account type.\\n:::note\\n`IncorrectAccountType` extends `BaseError`, see the docs for BaseError for all supported methods.\\n:::\\n\\n## Import\\n\\n```ts\\nimport { IncorrectAccountType } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Parameters\\n\\n### expected\\n\\n`string`\\nthe expected account type\\n\\n### actual\\n\\n`string`\\nthe actual account type that was received\\n\",\"document\":[{\"href\":\"/reference/aa-sdk/core/classes/IncorrectAccountType/constructor#incorrectaccounttype\",\"html\":\"\\nConstructs an error object indicating that the expected account type does not match the actual account type.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/IncorrectAccountType/constructor.mdx#incorrectaccounttype\",\"isPage\":true,\"text\":\"\\nConstructs an error object indicating that the expected account type does not match the actual account type.\\nIncorrectAccountType extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"IncorrectAccountType\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/IncorrectAccountType/constructor#import\",\"html\":\"\\nimport { IncorrectAccountType } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/IncorrectAccountType/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { IncorrectAccountType } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"IncorrectAccountType\"]},{\"href\":\"/reference/aa-sdk/core/classes/IncorrectAccountType/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/IncorrectAccountType/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"IncorrectAccountType\"]},{\"href\":\"/reference/aa-sdk/core/classes/IncorrectAccountType/constructor#expected\",\"html\":\"\\nstring
\\nthe expected account type
string
\\nthe actual account type that was received
Constructs a new error message indicating a failure to find the transaction for the specified user operation hash.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/FailedToFindTransactionError/constructor.mdx#failedtofindtransactionerror\",\"isPage\":true,\"text\":\"\\nConstructs a new error message indicating a failure to find the transaction for the specified user operation hash.\\nFailedToFindTransactionError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"FailedToFindTransactionError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/FailedToFindTransactionError/constructor#import\",\"html\":\"\\nimport { FailedToFindTransactionError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/FailedToFindTransactionError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { FailedToFindTransactionError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"FailedToFindTransactionError\"]},{\"href\":\"/reference/aa-sdk/core/classes/FailedToFindTransactionError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/FailedToFindTransactionError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"FailedToFindTransactionError\"]},{\"href\":\"/reference/aa-sdk/core/classes/FailedToFindTransactionError/constructor#hash\",\"html\":\"\\nHex
\\nThe hexadecimal value representing the user operation hash.
Logs a debug message to the console if the log level allows it.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/debug.mdx#debug\",\"isPage\":true,\"text\":\"\\nLogs a debug message to the console if the log level allows it.\\n\",\"title\":\"debug\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/debug#import\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/debug.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"debug\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/debug#usage\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.debug("Something is happening");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/debug.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.debug("Something is happening");\\n\",\"title\":\"Usage\",\"titles\":[\"debug\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/debug#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/debug.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"debug\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/debug#msg\",\"html\":\"\\nstring
\\nThe message to log
...any[]
\\nAdditional arguments to pass to the console.debug method
Sets the log filter pattern.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogFilter.mdx#setlogfilter\",\"isPage\":true,\"text\":\"\\nSets the log filter pattern.\\n\",\"title\":\"setLogFilter\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogFilter#import\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogFilter.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"setLogFilter\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogFilter#usage\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.setLogFilter("error");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogFilter.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.setLogFilter("error");\\n\",\"title\":\"Usage\",\"titles\":[\"setLogFilter\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogFilter#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogFilter.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setLogFilter\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogFilter#pattern\",\"html\":\"\\nstring
\\nThe pattern to set as the log filter
Initializes a new instance of the error class with a predefined error message indicating that a smart account requires a signer.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/SmartAccountWithSignerRequiredError/constructor.mdx#smartaccountwithsignerrequirederror\",\"isPage\":true,\"text\":\"\\nInitializes a new instance of the error class with a predefined error message indicating that a smart account requires a signer.\\nSmartAccountWithSignerRequiredError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"SmartAccountWithSignerRequiredError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/SmartAccountWithSignerRequiredError/constructor#import\",\"html\":\"\\nimport { SmartAccountWithSignerRequiredError } from "@aa-sdk/core";
\",\"id\":\"pages/reference/aa-sdk/core/classes/SmartAccountWithSignerRequiredError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { SmartAccountWithSignerRequiredError } from "@aa-sdk/core";\",\"title\":\"Import\",\"titles\":[\"SmartAccountWithSignerRequiredError\"]}]}],[\"index.61d5f0709220af4cca79f092759ac1805941a7cc8cf42d978b86e33d6f064e3c\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: warn\\ndescription: Overview of the warn method\\n---\\n\\n# warn\\n\\nLogs a warning message if the logging conditions are met.\\n\\n## Import\\n\\n```ts\\nimport { Logger } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Usage\\n\\n```ts\\nimport { Logger } from \\\"@aa-sdk/core\\\";\\n\\nLogger.warn(\\\"Careful...\\\");\\n```\\n\\n## Parameters\\n\\n### msg\\n\\n`string`\\nThe message to log as a warning\\n\\n### args\\n\\n`...any[]`\\nAdditional parameters to log along with the message\\n\",\"document\":[{\"href\":\"/reference/aa-sdk/core/classes/Logger/warn#warn\",\"html\":\"\\nLogs a warning message if the logging conditions are met.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/warn.mdx#warn\",\"isPage\":true,\"text\":\"\\nLogs a warning message if the logging conditions are met.\\n\",\"title\":\"warn\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/warn#import\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/warn.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"warn\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/warn#usage\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.warn("Careful...");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/warn.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.warn("Careful...");\\n\",\"title\":\"Usage\",\"titles\":[\"warn\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/warn#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/warn.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"warn\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/warn#msg\",\"html\":\"\\nstring
\\nThe message to log as a warning
...any[]
\\nAdditional parameters to log along with the message
A function to initialize an object with an inner parameter and derive a signerType from it.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/constructor.mdx#localaccountsigner\",\"isPage\":true,\"text\":\"\\nA function to initialize an object with an inner parameter and derive a signerType from it.\\n\",\"title\":\"LocalAccountSigner\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/constructor#import\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"LocalAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/constructor#usage\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { privateKeyToAccount, generatePrivateKey } from "viem";\\n \\nconst signer = new LocalAccountSigner(\\n privateKeyToAccount(generatePrivateKey())\\n);
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/constructor.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { privateKeyToAccount, generatePrivateKey } from "viem";\\n \\nconst signer = new LocalAccountSigner(\\n privateKeyToAccount(generatePrivateKey())\\n);\\n\",\"title\":\"Usage\",\"titles\":[\"LocalAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"LocalAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/constructor#inner\",\"html\":\"\\nT
\\nThe inner parameter containing the necessary data
Sets the log level for logging purposes.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogLevel.mdx#setloglevel\",\"isPage\":true,\"text\":\"\\nSets the log level for logging purposes.\\n\",\"title\":\"setLogLevel\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogLevel#import\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogLevel.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"setLogLevel\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogLevel#usage\",\"html\":\"\\nimport { Logger, LogLevel } from "@aa-sdk/core";\\nLogger.setLogLevel(LogLevel.DEBUG);
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogLevel.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Logger, LogLevel } from "@aa-sdk/core";\\nLogger.setLogLevel(LogLevel.DEBUG);\\n\",\"title\":\"Usage\",\"titles\":[\"setLogLevel\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogLevel#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/setLogLevel.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"setLogLevel\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/setLogLevel#loglevel\",\"html\":\"\\nLogLevel
\\nThe desired log level
Logs a message with additional arguments if the logging level permits it.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/verbose.mdx#verbose\",\"isPage\":true,\"text\":\"\\nLogs a message with additional arguments if the logging level permits it.\\n\",\"title\":\"verbose\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/verbose#import\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/verbose.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"verbose\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/verbose#usage\",\"html\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.verbose("Something is happening");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/verbose.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { Logger } from "@aa-sdk/core";\\n \\nLogger.verbose("Something is happening");\\n\",\"title\":\"Usage\",\"titles\":[\"verbose\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/verbose#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/Logger/verbose.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"verbose\"]},{\"href\":\"/reference/aa-sdk/core/classes/Logger/verbose#msg\",\"html\":\"\\nstring
\\nThe message to log
...any[]
\\nAdditional arguments to be logged
Creates a LocalAccountSigner
instance using the provided private key.
import { LocalAccountSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/privateKeyToAccountSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"privateKeyToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/privateKeyToAccountSigner#usage\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/privateKeyToAccountSigner.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());\\n\",\"title\":\"Usage\",\"titles\":[\"privateKeyToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/privateKeyToAccountSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/privateKeyToAccountSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"privateKeyToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/privateKeyToAccountSigner#key\",\"html\":\"\\nHex
\\nThe private key in hexadecimal format
LocalAccountSigner<PrivateKeyAccount>
\\nAn instance of LocalAccountSigner
initialized with the provided private key
Creates a LocalAccountSigner using the provided mnemonic key and optional HD options.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner.mdx#mnemonictoaccountsigner\",\"isPage\":true,\"text\":\"\\nCreates a LocalAccountSigner using the provided mnemonic key and optional HD options.\\n\",\"title\":\"mnemonicToAccountSigner\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner#import\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"mnemonicToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner#usage\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generateMnemonic } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generateMnemonic());
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generateMnemonic } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generateMnemonic());\\n\",\"title\":\"Usage\",\"titles\":[\"mnemonicToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"mnemonicToAccountSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/mnemonicToAccountSigner#key\",\"html\":\"\\nstring
\\nThe mnemonic key to derive the account from.
HDOptions
\\nOptional HD options for deriving the account.
LocalAccountSigner<HDAccount>
\\nA LocalAccountSigner object for the derived account.
Returns the address of the inner object in a specific hexadecimal format.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/getAddress.mdx#getaddress\",\"isPage\":true,\"text\":\"\\nReturns the address of the inner object in a specific hexadecimal format.\\n\",\"title\":\"getAddress\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/getAddress#import\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/getAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/getAddress#usage\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());\\nconst address = await signer.getAddress();
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/getAddress.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());\\nconst address = await signer.getAddress();\\n\",\"title\":\"Usage\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/getAddress#returns\",\"html\":\"\\nPromise<Hex>
\\nA promise that resolves to the address in the format 0x{string}
Signs the provided message using the inner signMessage function.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage.mdx#signmessage\",\"isPage\":true,\"text\":\"\\nSigns the provided message using the inner signMessage function.\\n\",\"title\":\"signMessage\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage#import\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage#usage\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());\\nconst signature = await signer.signMessage("Hello, world!");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());\\nconst signature = await signer.signMessage("Hello, world!");\\n\",\"title\":\"Usage\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signMessage#message\",\"html\":\"\\nstring
\\nThe message to be signed
Promise<any>
\\nA promise that resolves to the signed message
Signs typed data using the given parameters.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData.mdx#signtypeddata\",\"isPage\":true,\"text\":\"\\nSigns typed data using the given parameters.\\n\",\"title\":\"signTypedData\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData#import\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData#usage\",\"html\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());\\nconst signature = await signer.signTypedData({\\n domain: {},\\n types: {},\\n primaryType: "",\\n message: {},\\n});
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { LocalAccountSigner } from "@aa-sdk/core";\\nimport { generatePrivateKey } from "viem";\\n \\nconst signer = LocalAccountSigner.mnemonicToAccountSigner(generatePrivateKey());\\nconst signature = await signer.signTypedData({\\n domain: {},\\n types: {},\\n primaryType: "",\\n message: {},\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/aa-sdk/core/classes/LocalAccountSigner/signTypedData#params\",\"html\":\"\\nTypedDataDefinition<TTypedData, TPrimaryType>
\\nThe parameters defining the typed data and primary type
Promise<Hex>
\\nA promise that resolves to the signed data in hexadecimal format
Throws an error indicating that a transaction is missing the to
address in the request.
import { TransactionMissingToParamError } from "@aa-sdk/core";
\",\"id\":\"pages/reference/aa-sdk/core/classes/TransactionMissingToParamError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { TransactionMissingToParamError } from "@aa-sdk/core";\",\"title\":\"Import\",\"titles\":[\"TransactionMissingToParamError\"]}]}],[\"index.3263d1c94e35a15a4c4aec3137cbf5d5524b1462eefe94d607e38e956ac32f5f\",{\"mdx\":\"---\\n# This file is autogenerated\\ntitle: UpgradeToAndCallNotSupportedError\\ndescription: Overview of the UpgradeToAndCallNotSupportedError method\\n---\\n\\n# UpgradeToAndCallNotSupportedError\\n\\nConstructs an error message indicating that `UpgradeToAndCall` is not supported by the specified account type.\\n:::note\\n`UpgradeToAndCallNotSupportedError` extends `BaseError`, see the docs for BaseError for all supported methods.\\n:::\\n\\n## Import\\n\\n```ts\\nimport { UpgradeToAndCallNotSupportedError } from \\\"@aa-sdk/core\\\";\\n```\\n\\n## Parameters\\n\\n### accountType\\n\\n`string`\\nThe type of account that does not support `UpgradeToAndCall`\\n\",\"document\":[{\"href\":\"/reference/aa-sdk/core/classes/UpgradeToAndCallNotSupportedError/constructor#upgradetoandcallnotsupportederror\",\"html\":\"\\nConstructs an error message indicating that UpgradeToAndCall
is not supported by the specified account type.
import { UpgradeToAndCallNotSupportedError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/UpgradeToAndCallNotSupportedError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { UpgradeToAndCallNotSupportedError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"UpgradeToAndCallNotSupportedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/UpgradeToAndCallNotSupportedError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/UpgradeToAndCallNotSupportedError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"UpgradeToAndCallNotSupportedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/UpgradeToAndCallNotSupportedError/constructor#accounttype\",\"html\":\"\\nstring
\\nThe type of account that does not support UpgradeToAndCall
Error constructor for indicating that upgrades are not supported by the given account type.
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/UpgradesNotSupportedError/constructor.mdx#upgradesnotsupportederror\",\"isPage\":true,\"text\":\"\\nError constructor for indicating that upgrades are not supported by the given account type.\\nUpgradesNotSupportedError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"UpgradesNotSupportedError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/UpgradesNotSupportedError/constructor#import\",\"html\":\"\\nimport { UpgradesNotSupportedError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/UpgradesNotSupportedError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { UpgradesNotSupportedError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"UpgradesNotSupportedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/UpgradesNotSupportedError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/UpgradesNotSupportedError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"UpgradesNotSupportedError\"]},{\"href\":\"/reference/aa-sdk/core/classes/UpgradesNotSupportedError/constructor#accounttype\",\"html\":\"\\nstring
\\nThe type of account that does not support upgrades
Initializes a signer with a given wallet client and signer type.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/constructor.mdx#walletclientsigner\",\"isPage\":true,\"text\":\"\\nInitializes a signer with a given wallet client and signer type.\\n\",\"title\":\"WalletClientSigner\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/constructor#import\",\"html\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"WalletClientSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/constructor#usage\",\"html\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/constructor.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");\\n\",\"title\":\"Usage\",\"titles\":[\"WalletClientSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"WalletClientSigner\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/constructor#client\",\"html\":\"\\nWalletClient
\\nThe wallet client to interact with
string
\\nThe type of signer; must be a valid signer type, otherwise an error will be thrown
Signs a message using the account's signing method.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signMessage.mdx#signmessage\",\"isPage\":true,\"text\":\"\\nSigns a message using the account's signing method.\\n\",\"title\":\"signMessage\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signMessage#import\",\"html\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signMessage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signMessage#usage\",\"html\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");\\nconsole.log(await signer.signMessage("hello"));
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signMessage.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");\\nconsole.log(await signer.signMessage("hello"));\\n\",\"title\":\"Usage\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signMessage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signMessage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signMessage#message\",\"html\":\"\\nstring
\\nthe message string that needs to be signed
Promise<string>
\\na promise that resolves to the signed message
Asynchronously retrieves addresses from the inner object and returns the first address after applying the getAddress
function.
import { WalletClientSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/getAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/getAddress#usage\",\"html\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");\\nconsole.log(await signer.getAddress());
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/getAddress.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");\\nconsole.log(await signer.getAddress());\\n\",\"title\":\"Usage\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/getAddress#returns\",\"html\":\"\\nPromise<string>
\\nA promise that resolves to the first address after being processed by the getAddress
function.
undefined
\\n\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WaitForUserOperationError/constructor.mdx#waitforuseroperationerror\",\"isPage\":true,\"text\":\"\\nundefined\\nWaitForUserOperationError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"WaitForUserOperationError\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/WaitForUserOperationError/constructor#import\",\"html\":\"\\nimport { WaitForUserOperationError } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WaitForUserOperationError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { WaitForUserOperationError } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"WaitForUserOperationError\"]},{\"href\":\"/reference/aa-sdk/core/classes/WaitForUserOperationError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WaitForUserOperationError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"WaitForUserOperationError\"]},{\"href\":\"/reference/aa-sdk/core/classes/WaitForUserOperationError/constructor#request\",\"html\":\"\\nUserOperationRequest
\\nthe user operation request that failed
Error
\\nthe underlying error that caused the failure
Completes email auth for the user by injecting a credential bundle and retrieving the user information based on the provided organization ID. Emits events during the process.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth.mdx#completeemailauth\",\"isPage\":true,\"text\":\"\\nCompletes email auth for the user by injecting a credential bundle and retrieving the user information based on the provided organization ID. Emits events during the process.\\n\",\"title\":\"completeEmailAuth\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth#import\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"completeEmailAuth\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth#usage\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.completeEmailAuth({\\n orgId: "user-org-id",\\n bundle: "bundle-from-email",\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.completeEmailAuth({\\n orgId: "user-org-id",\\n bundle: "bundle-from-email",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"completeEmailAuth\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"completeEmailAuth\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/completeEmailAuth#config\",\"html\":\"\\n{ bundle: string; orgId: string }
\\nThe configuration object for the authentication function containing the credential bundle to inject and the organization id associated with the user
Promise<User>
\\nA promise that resolves to the authenticated user information
Begin authenticating a user with their email and an expiration time for the authentication request. Initializes the iframe stamper to get the target public key.\\nThis method sends an email to the user to complete their login
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth.mdx#initemailauth\",\"isPage\":true,\"text\":\"\\nBegin authenticating a user with their email and an expiration time for the authentication request. Initializes the iframe stamper to get the target public key.\\nThis method sends an email to the user to complete their login\\n\",\"title\":\"initEmailAuth\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth#import\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"initEmailAuth\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth#usage\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.initEmailAuth({ email: "you@mail.com" });
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.initEmailAuth({ email: "you@mail.com" });\\n\",\"title\":\"Usage\",\"titles\":[\"initEmailAuth\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"initEmailAuth\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/initEmailAuth#params\",\"html\":\"\\nOmit<EmailAuthParams, "targetPublicKey">
\\nThe parameters for email authentication, excluding the target public key
Promise<any>
\\nThe response from the authentication request
Asynchronously handles the authentication process using WebAuthn Stamper. If a user is provided, sets the user and returns it. Otherwise, retrieves the current user and initializes the WebAuthn stamper.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey.mdx#lookupuserwithpasskey\",\"isPage\":true,\"text\":\"\\nAsynchronously handles the authentication process using WebAuthn Stamper. If a user is provided, sets the user and returns it. Otherwise, retrieves the current user and initializes the WebAuthn stamper.\\n\",\"title\":\"lookupUserWithPasskey\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey#import\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"lookupUserWithPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey#usage\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.lookupUserWithPasskey();
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.lookupUserWithPasskey();\\n\",\"title\":\"Usage\",\"titles\":[\"lookupUserWithPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"lookupUserWithPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/lookupUserWithPasskey#user\",\"html\":\"\\nUser
\\nAn optional user object to authenticate
Promise<User>
\\nA promise that resolves to the authenticated user object
Used to export the wallet for a given user\\nIf the user is authenticated with an Email, this will return a seed phrase\\nIf the user is authenticated with a Passkey, this will return a private key
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet.mdx#exportwallet\",\"isPage\":true,\"text\":\"\\nUsed to export the wallet for a given user\\nIf the user is authenticated with an Email, this will return a seed phrase\\nIf the user is authenticated with a Passkey, this will return a private key\\n\",\"title\":\"exportWallet\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"exportWallet\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\n// the params passed to this are different based on the specific signer\\nconst result = signer.exportWallet();
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\n// the params passed to this are different based on the specific signer\\nconst result = signer.exportWallet();\\n\",\"title\":\"Usage\",\"titles\":[\"exportWallet\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"exportWallet\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/exportWallet#params\",\"html\":\"\\nunknown
\\nexport wallet parameters
boolean
\\ntrue if the wallet was exported successfully
Asynchronous function that clears the user and resets the iframe stamper.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/disconnect.mdx#disconnect\",\"isPage\":true,\"text\":\"\\nAsynchronous function that clears the user and resets the iframe stamper.\\n\",\"title\":\"disconnect\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/disconnect#import\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/disconnect.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"disconnect\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/disconnect#usage\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.disconnect();
\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/disconnect.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.disconnect();\",\"title\":\"Usage\",\"titles\":[\"disconnect\"]}]}],[\"index.2ebd6785085f5d7ce2d598cf16b6c38ceb2d348422117f575cfe157b07495a1d\",{\"mdx\":\"---\\n# This file is autogenerated\\n\\ntitle: AlchemyWebSigner\\ndescription: Overview of the AlchemyWebSigner method\\n---\\n\\n# AlchemyWebSigner\\n\\nInitializes an instance with the provided Alchemy signer parameters after parsing them with a schema.\\n:::note\\n`AlchemyWebSigner` extends `BaseAlchemySigner`, see the docs for BaseAlchemySigner for all supported methods.\\n:::\\n\\n## Import\\n\\n```ts\\nimport { AlchemyWebSigner } from \\\"@account-kit/signer\\\";\\n```\\n\\n## Usage\\n\\n```ts\\nimport { AlchemyWebSigner } from \\\"@account-kit/signer\\\";\\n\\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: \\\"/api/rpc\\\",\\n },\\n iframeConfig: {\\n iframeContainerId: \\\"alchemy-signer-iframe-container\\\",\\n },\\n },\\n});\\n```\\n\\n## Parameters\\n\\n### params\\n\\n`AlchemySignerParams`\\nThe parameters for the Alchemy signer, including the client and session configuration\\n\",\"document\":[{\"href\":\"/reference/account-kit/signer/classes/AlchemyWebSigner/constructor#alchemywebsigner\",\"html\":\"\\nInitializes an instance with the provided Alchemy signer parameters after parsing them with a schema.
\\n\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemyWebSigner/constructor.mdx#alchemywebsigner\",\"isPage\":true,\"text\":\"\\nInitializes an instance with the provided Alchemy signer parameters after parsing them with a schema.\\nAlchemyWebSigner extends BaseAlchemySigner, see the docs for BaseAlchemySigner for all supported methods.\\n\",\"title\":\"AlchemyWebSigner\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemyWebSigner/constructor#import\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemyWebSigner/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"AlchemyWebSigner\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemyWebSigner/constructor#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemyWebSigner/constructor.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"AlchemyWebSigner\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemyWebSigner/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemyWebSigner/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"AlchemyWebSigner\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemyWebSigner/constructor#params\",\"html\":\"\\nAlchemySignerParams
\\nThe parameters for the Alchemy signer, including the client and session configuration
Signs the provided typed data using the account's private key.
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData.mdx#signtypeddata\",\"isPage\":true,\"text\":\"\\nSigns the provided typed data using the account's private key.\\n\",\"title\":\"signTypedData\",\"titles\":[]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData#import\",\"html\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\n\",\"title\":\"Import\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData#usage\",\"html\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");\\nconsole.log(\\n await signer.signTypedData({\\n types: {\\n Message: [{ name: "content", type: "string" }],\\n },\\n primaryType: "Message",\\n message: { content: "Hello" },\\n })\\n);
\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { WalletClientSigner } from "@aa-sdk/core";\\nimport { createWalletClient, custom } from "viem";\\nimport { mainnet } from "viem/chains";\\n \\nconst client = createWalletClient({\\n chain: mainnet,\\n transport: custom(window.ethereum!),\\n});\\n \\nconst signer = new WalletClientSigner(client, "wallet");\\nconsole.log(\\n await signer.signTypedData({\\n types: {\\n Message: [{ name: "content", type: "string" }],\\n },\\n primaryType: "Message",\\n message: { content: "Hello" },\\n })\\n);\\n\",\"title\":\"Usage\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/aa-sdk/core/classes/WalletClientSigner/signTypedData#typeddata\",\"html\":\"\\nTypedDataDefinition<TTypedData, TPrimaryType>
\\nThe typed data to be signed
Promise<Hex>
\\nA promise that resolves to a hex string representing the signed data
Initializes a new instance with the given parameters, setting up the connection, iframe configuration, and WebAuthn stamper.
\\n\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor.mdx#alchemysignerwebclient\",\"isPage\":true,\"text\":\"\\nInitializes a new instance with the given parameters, setting up the connection, iframe configuration, and WebAuthn stamper.\\nAlchemySignerWebClient extends BaseSignerClient, see the docs for BaseSignerClient for all supported methods.\\n\",\"title\":\"AlchemySignerWebClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor#import\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"AlchemySignerWebClient\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor#usage\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"AlchemySignerWebClient\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"AlchemySignerWebClient\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/constructor#params\",\"html\":\"\\nAlchemySignerClientParams
\\nthe parameters required to initialize the client
ConnectionConfig
\\nThe connection details needed to connect to the service
{ iframeElementId?: string; iframeContainerId: string }
\\nThe configuration details for setting up the iframe stamper
string
\\nThe relying party ID, defaulting to the current hostname if not provided
string
\\nThe root organization ID
Adds a passkey to the user's account
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey.mdx#addpasskey\",\"isPage\":true,\"text\":\"\\nAdds a passkey to the user's account\\n\",\"title\":\"addPasskey\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"addPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst result = await signer.addPasskey();
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst result = await signer.addPasskey();\\n\",\"title\":\"Usage\",\"titles\":[\"addPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"addPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/addPasskey#params\",\"html\":\"\\nCredentialCreationOptions | undefined
\\noptional parameters for the passkey creation
Promise<string[]>
\\nan array of the authenticator ids added to the user
Authenticates the user by either email or passkey account creation flow. Emits events during the process.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount.mdx#createaccount\",\"isPage\":true,\"text\":\"\\nAuthenticates the user by either email or passkey account creation flow. Emits events during the process.\\n\",\"title\":\"createAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount#import\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"createAccount\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount#usage\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.createAccount({\\n type: "email",\\n email: "you@mail.com",\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.createAccount({\\n type: "email",\\n email: "you@mail.com",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"createAccount\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"createAccount\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/createAccount#params\",\"html\":\"\\nCreateAccountParams
\\nThe parameters for creating an account, including the type (email or passkey) and additional details.
Promise<SignupResponse>
\\nA promise that resolves with the response object containing the account creation result.
Initializes an instance with the provided client and session configuration.\\nThis function sets up the internal store, initializes the session manager,\\nregisters listeners and initializes the session manager to manage session state.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/constructor.mdx#basealchemysigner\",\"isPage\":true,\"text\":\"\\nInitializes an instance with the provided client and session configuration.\\nThis function sets up the internal store, initializes the session manager,\\nregisters listeners and initializes the session manager to manage session state.\\n\",\"title\":\"BaseAlchemySigner\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/constructor#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"BaseAlchemySigner\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"BaseAlchemySigner\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/constructor#param0\",\"html\":\"\\nBaseAlchemySignerParams<TClient>
\\nObject containing the client and session configuration
TClient
\\nThe client instance to be used internally
SessionConfig
\\nConfiguration for managing sessions
Clear a user session and log them out
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/disconnect.mdx#disconnect\",\"isPage\":true,\"text\":\"\\nClear a user session and log them out\\n\",\"title\":\"disconnect\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/disconnect#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/disconnect.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"disconnect\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/disconnect#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nawait signer.disconnect();
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/disconnect.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nawait signer.disconnect();\\n\",\"title\":\"Usage\",\"titles\":[\"disconnect\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/disconnect#returns\",\"html\":\"\\nPromise<void>
\\na promise that resolves when the user is logged out
Initiates the export of a wallet by creating an iframe stamper and calling the appropriate export function.\\nThe export can be based on a seed phrase or a private key.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet.mdx#exportwallet\",\"isPage\":true,\"text\":\"\\nInitiates the export of a wallet by creating an iframe stamper and calling the appropriate export function.\\nThe export can be based on a seed phrase or a private key.\\n\",\"title\":\"exportWallet\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet#import\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"exportWallet\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet#usage\",\"html\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.exportWallet({\\n iframeContainerId: "export-iframe-container",\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemySignerWebClient } from "@account-kit/signer";\\n \\nconst client = new AlchemySignerWebClient({\\n connection: {\\n apiKey: "your-api-key",\\n },\\n iframeConfig: {\\n iframeContainerId: "signer-iframe-container",\\n },\\n});\\n \\nconst account = await client.exportWallet({\\n iframeContainerId: "export-iframe-container",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"exportWallet\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"exportWallet\"]},{\"href\":\"/reference/account-kit/signer/classes/AlchemySignerWebClient/exportWallet#config\",\"html\":\"\\nExportWalletParams
\\nThe parameters for exporting the wallet
string
\\nThe ID of the container element that will hold the iframe stamper
string
\\nOptional ID for the iframe element
Promise<void>
\\nA promise that resolves when the export process is complete
Authenticate a user with either an email or a passkey and create a session for that user
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate.mdx#authenticate\",\"isPage\":true,\"text\":\"\\nAuthenticate a user with either an email or a passkey and create a session for that user\\n\",\"title\":\"authenticate\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"authenticate\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst result = await signer.authenticate({\\n type: "email",\\n email: "foo@mail.com",\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst result = await signer.authenticate({\\n type: "email",\\n email: "foo@mail.com",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"authenticate\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"authenticate\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate#params\",\"html\":\"\\nAuthParams
undefined if passkey login, otherwise an object with email and bundle to resolve
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate.mdx#params\",\"isPage\":false,\"text\":\"\\nAuthParams\\n\\n\\nundefined if passkey login, otherwise an object with email and bundle to resolve\\n\",\"title\":\"params\",\"titles\":[\"authenticate\",\"Parameters\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/authenticate#returns\",\"html\":\"\\nPromise<User>
\\nthe user that was authenticated
Gets the current logged in user\\nIf a user has an ongoing session, it will use that session and\\ntry to authenticate
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getAuthDetails.mdx#getauthdetails\",\"isPage\":true,\"text\":\"\\nGets the current logged in user\\nIf a user has an ongoing session, it will use that session and\\ntry to authenticate\\n\",\"title\":\"getAuthDetails\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getAuthDetails#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getAuthDetails.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"getAuthDetails\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getAuthDetails#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\n// throws if not logged in\\nconst user = await signer.getAuthDetails();
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getAuthDetails.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\n// throws if not logged in\\nconst user = await signer.getAuthDetails();\\n\",\"title\":\"Usage\",\"titles\":[\"getAuthDetails\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getAuthDetails#returns\",\"html\":\"\\nPromise<User>
\\nthe current user
Retrieves the address of the current user by calling the whoami
method on this.inner
.
import { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getAddress.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"getAddress\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getAddress#returns\",\"html\":\"\\nPromise<string>
\\nA promise that resolves to the address of the current user.
Allows you to subscribe to events emitted by the signer
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/on.mdx#on\",\"isPage\":true,\"text\":\"\\nAllows you to subscribe to events emitted by the signer\\n\",\"title\":\"on\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/on#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/on.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"on\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/on#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/on.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"on\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/on#event\",\"html\":\"\\nAlchemySignerEvent
\\nthe event to subscribe to
AlchemySignerEvents[AlchemySignerEvent]
\\nthe function to run when the event is emitted
() => void
\\na function to remove the listener
Serializes a transaction, signs it with a raw message, and then returns the serialized transaction with the signature.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction.mdx#signtransaction\",\"isPage\":true,\"text\":\"\\nSerializes a transaction, signs it with a raw message, and then returns the serialized transaction with the signature.\\n\",\"title\":\"signTransaction\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"signTransaction\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst tx = await signer.signTransaction({\\n to: "0x1234",\\n value: "0x1234",\\n data: "0x1234",\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst tx = await signer.signTransaction({\\n to: "0x1234",\\n value: "0x1234",\\n data: "0x1234",\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"signTransaction\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signTransaction\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signTransaction#tx\",\"html\":\"\\nTransaction
\\nthe transaction to be serialized and signed
{serializer?: SerializeTransactionFn}
\\noptions for serialization
() => Hex
\\nan optional serializer function. If not provided, the default serializeTransaction
function will be used
Promise<string>
\\na promise that resolves to the serialized transaction with the signature
Signs a raw message after hashing it.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage.mdx#signmessage\",\"isPage\":true,\"text\":\"\\nSigns a raw message after hashing it.\\n\",\"title\":\"signMessage\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst signature = await signer.signMessage("Hello, world!");
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst signature = await signer.signMessage("Hello, world!");\\n\",\"title\":\"Usage\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signMessage\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signMessage#msg\",\"html\":\"\\nstring
\\nthe message to be hashed and then signed
Promise<string>
\\na promise that resolves to the signed message
Unauthenticated call to look up a user's organizationId by email
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getUser.mdx#getuser\",\"isPage\":true,\"text\":\"\\nUnauthenticated call to look up a user's organizationId by email\\n\",\"title\":\"getUser\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getUser#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getUser.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"getUser\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getUser#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst result = await signer.getUser("foo@mail.com");
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getUser.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst result = await signer.getUser("foo@mail.com");\\n\",\"title\":\"Usage\",\"titles\":[\"getUser\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getUser#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/getUser.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"getUser\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/getUser#email\",\"html\":\"\\nstring
\\nthe email to lookup
Promise<{orgId: string}>
\\nthe organization id for the user if they exist
Signs a typed message by first hashing it and then signing the hashed message using the signRawMessage
method.
import { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signTypedData.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signTypedData#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst signature = await signer.signTypedData({\\n domain: {},\\n types: {},\\n primaryType: "",\\n message: {},\\n});
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signTypedData.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst signature = await signer.signTypedData({\\n domain: {},\\n types: {},\\n primaryType: "",\\n message: {},\\n});\\n\",\"title\":\"Usage\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signTypedData#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/signTypedData.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signTypedData\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/signTypedData#params\",\"html\":\"\\nTypedDataDefinition<TTypedData, TPrimaryType>
\\nThe parameters for the typed message to be hashed and signed
Promise<any>
\\nA promise that resolves to the signed message
This method lets you adapt your AlchemySigner to a viem LocalAccount, which\\nwill let you use the signer as an EOA directly.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/toViemAccount.mdx#toviemaccount\",\"isPage\":true,\"text\":\"\\nThis method lets you adapt your AlchemySigner to a viem LocalAccount, which\\nwill let you use the signer as an EOA directly.\\n\",\"title\":\"toViemAccount\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/toViemAccount#import\",\"html\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/toViemAccount.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseAlchemySigner } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"toViemAccount\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/toViemAccount#usage\",\"html\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst account = signer.toViemAccount();
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseAlchemySigner/toViemAccount.mdx#usage\",\"isPage\":false,\"text\":\"\\nimport { AlchemyWebSigner } from "@account-kit/signer";\\n \\nconst signer = new AlchemyWebSigner({\\n client: {\\n connection: {\\n rpcUrl: "/api/rpc",\\n },\\n iframeConfig: {\\n iframeContainerId: "alchemy-signer-iframe-container",\\n },\\n },\\n});\\n \\nconst account = signer.toViemAccount();\\n\",\"title\":\"Usage\",\"titles\":[\"toViemAccount\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseAlchemySigner/toViemAccount#returns\",\"html\":\"\\nLocalAccount
\\na LocalAccount object that can be used with viem's wallet client
Create a new instance of the Alchemy Signer client
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/constructor.mdx#basesignerclient\",\"isPage\":true,\"text\":\"\\nCreate a new instance of the Alchemy Signer client\\n\",\"title\":\"BaseSignerClient\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/constructor#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"BaseSignerClient\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"BaseSignerClient\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/constructor#params\",\"html\":\"\\nBaseSignerClientParams
\\nthe parameters required to create the client
Handles the creation of authenticators using WebAuthn attestation and the provided options. Requires the user to be authenticated.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/addPasskey.mdx#addpasskey\",\"isPage\":true,\"text\":\"\\nHandles the creation of authenticators using WebAuthn attestation and the provided options. Requires the user to be authenticated.\\n\",\"title\":\"addPasskey\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/addPasskey#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/addPasskey.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"addPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/addPasskey#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/addPasskey.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"addPasskey\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/addPasskey#options\",\"html\":\"\\nCredentialCreationOptions
\\nThe options used to create the WebAuthn attestation
Promise<string[]>
\\nA promise that resolves to an array of authenticator IDs
Looks up information based on an email address.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/lookupUserByEmail.mdx#lookupuserbyemail\",\"isPage\":true,\"text\":\"\\nLooks up information based on an email address.\\n\",\"title\":\"lookupUserByEmail\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/lookupUserByEmail#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/lookupUserByEmail.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"lookupUserByEmail\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/lookupUserByEmail#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/lookupUserByEmail.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"lookupUserByEmail\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/lookupUserByEmail#email\",\"html\":\"\\nstring
\\nthe email address to look up
Promise<any>
\\nthe result of the lookup request
Listen to events emitted by the client
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/on.mdx#on\",\"isPage\":true,\"text\":\"\\nListen to events emitted by the client\\n\",\"title\":\"on\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/on#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/on.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"on\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/on#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/on.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"on\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/on#event\",\"html\":\"\\nAlchemySignerClientEvent
\\nthe event you want to listen to
AlchemySignerClientEvents[AlchemySignerClientEvent]
\\nthe callback function to execute when an event is fired
() => void
\\na function that will remove the listener when called
This will sign a message with the user's private key, without doing any transformations on the message.\\nFor SignMessage or SignTypedData, the caller should hash the message before calling this method and pass\\nthat result here.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/signRawMessage.mdx#signrawmessage\",\"isPage\":true,\"text\":\"\\nThis will sign a message with the user's private key, without doing any transformations on the message.\\nFor SignMessage or SignTypedData, the caller should hash the message before calling this method and pass\\nthat result here.\\n\",\"title\":\"signRawMessage\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/signRawMessage#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/signRawMessage.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"signRawMessage\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/signRawMessage#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/signRawMessage.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"signRawMessage\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/signRawMessage#msg\",\"html\":\"\\nHex
\\nthe hex representation of the bytes to sign
Promise<Hex>
\\nthe signature over the raw hex
Constructs an error message indicating that a specific hook must be used within an AlchemyAccountProvider.
\\n\\n\",\"id\":\"pages/reference/account-kit/react/classes/NoAlchemyAccountContextError/constructor.mdx#noalchemyaccountcontexterror\",\"isPage\":true,\"text\":\"\\nConstructs an error message indicating that a specific hook must be used within an AlchemyAccountProvider.\\nNoAlchemyAccountContextError extends BaseError, see the docs for BaseError for all supported methods.\\n\",\"title\":\"NoAlchemyAccountContextError\",\"titles\":[]},{\"href\":\"/reference/account-kit/react/classes/NoAlchemyAccountContextError/constructor#import\",\"html\":\"\\nimport { NoAlchemyAccountContextError } from "@account-kit/react";
\\n\",\"id\":\"pages/reference/account-kit/react/classes/NoAlchemyAccountContextError/constructor.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { NoAlchemyAccountContextError } from "@account-kit/react";\\n\",\"title\":\"Import\",\"titles\":[\"NoAlchemyAccountContextError\"]},{\"href\":\"/reference/account-kit/react/classes/NoAlchemyAccountContextError/constructor#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/react/classes/NoAlchemyAccountContextError/constructor.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"NoAlchemyAccountContextError\"]},{\"href\":\"/reference/account-kit/react/classes/NoAlchemyAccountContextError/constructor#hookname\",\"html\":\"\\nstring
\\nThe name of the hook that must be used within the AlchemyAccountProvider
Retrieves the current user or fetches the user information if not already available.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/whoami.mdx#whoami\",\"isPage\":true,\"text\":\"\\nRetrieves the current user or fetches the user information if not already available.\\n\",\"title\":\"whoami\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/whoami#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/whoami.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"whoami\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/whoami#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/whoami.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"whoami\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/whoami#orgid\",\"html\":\"\\nstring
\\noptional organization ID, defaults to the user's organization ID
Promise<User>
\\nA promise that resolves to the user object
Sends a POST request to the given signer route with the specified body and returns the response.\\nNot intended to be used directly, use the specific methods instead on the client instead.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/request.mdx#request\",\"isPage\":true,\"text\":\"\\nSends a POST request to the given signer route with the specified body and returns the response.\\nNot intended to be used directly, use the specific methods instead on the client instead.\\n\",\"title\":\"request\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/request#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/request.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"request\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/request#parameters\",\"html\":\"\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/request.mdx#parameters\",\"isPage\":false,\"text\":\"\\n\",\"title\":\"Parameters\",\"titles\":[\"request\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/request#route\",\"html\":\"\\nSignerRoutes
\\nThe route to which the request should be sent
SignerBody<R>
\\nThe request body containing the data to be sent
Promise<SignerResponse<R>>
\\nA promise that resolves to the response from the signer
Returns the current user or null if no user is set.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/getUser.mdx#getuser\",\"isPage\":true,\"text\":\"\\nReturns the current user or null if no user is set.\\n\",\"title\":\"getUser\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/getUser#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/getUser.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"getUser\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/getUser#returns\",\"html\":\"\\nUser | null
\\nthe current user object or null if no user is available
Generates a stamped whoami request for the current user. This request can then be used to call /signer/v1/whoami to get the user information.\\nThis is useful if you want to get the user information in a different context like a server. You can pass the stamped request to the server\\nand then call our API to get the user information. Using this stamp is the most trusted way to get the user information since a stamp can only\\nbelong to the user who created it.
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/stampWhoami.mdx#stampwhoami\",\"isPage\":true,\"text\":\"\\nGenerates a stamped whoami request for the current user. This request can then be used to call /signer/v1/whoami to get the user information.\\nThis is useful if you want to get the user information in a different context like a server. You can pass the stamped request to the server\\nand then call our API to get the user information. Using this stamp is the most trusted way to get the user information since a stamp can only\\nbelong to the user who created it.\\n\",\"title\":\"stampWhoami\",\"titles\":[]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/stampWhoami#import\",\"html\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";
\\n\",\"id\":\"pages/reference/account-kit/signer/classes/BaseSignerClient/stampWhoami.mdx#import\",\"isPage\":false,\"text\":\"\\nimport { BaseSignerClient } from "@account-kit/signer";\\n\",\"title\":\"Import\",\"titles\":[\"stampWhoami\"]},{\"href\":\"/reference/account-kit/signer/classes/BaseSignerClient/stampWhoami#returns\",\"html\":\"\\nPromise<TSignedRequest>
\\na promise that resolves to the "whoami" information for the logged in user
= P & {\\n children?: ReactNode | undefined;\\n}\\nimport PropsWithChildren\",\"start\":229,\"length\":17,\"target\":\"PropsWithChildren\",\"line\":6,\"character\":9},{\"type\":\"hover\",\"text\":\"(alias) const Suspense: ExoticComponent = P & {\\n children?: ReactNode | undefined;\\n}\\nimport PropsWithChildren\",\"start\":358,\"length\":17,\"target\":\"PropsWithChildren\",\"line\":10,\"character\":9},{\"type\":\"hover\",\"text\":\"(property) initialState?: StoredState | undefined\",\"start\":378,\"length\":12,\"target\":\"initialState\",\"line\":10,\"character\":29},{\"type\":\"hover\",\"text\":\"(alias) type AlchemyClientState = {\\n alchemy: Omit