diff --git a/packages/alchemy/src/client/internal/smartAccountClientFromRpc.ts b/packages/alchemy/src/client/internal/smartAccountClientFromRpc.ts index 20d0d05371..ea86472570 100644 --- a/packages/alchemy/src/client/internal/smartAccountClientFromRpc.ts +++ b/packages/alchemy/src/client/internal/smartAccountClientFromRpc.ts @@ -43,8 +43,6 @@ export function createAlchemySmartAccountClientFromRpcClient({ gasManagerConfig, feeEstimator, gasEstimator, - paymasterAndData, - dummyPaymasterAndData, customMiddleware, client, }: CreateAlchemySmartAccountClientFromRpcClient): AlchemySmartAccountClient { @@ -63,8 +61,6 @@ export function createAlchemySmartAccountClientFromRpcClient({ userOperationSimulator: useSimulation ? alchemyUserOperationSimulator(client) : undefined, - paymasterAndData, - dummyPaymasterAndData, gasEstimator, ...(gasManagerConfig && alchemyGasManagerMiddleware(client, { diff --git a/packages/alchemy/src/client/smartAccountClient.ts b/packages/alchemy/src/client/smartAccountClient.ts index 17d959a78d..53b8ed6690 100644 --- a/packages/alchemy/src/client/smartAccountClient.ts +++ b/packages/alchemy/src/client/smartAccountClient.ts @@ -29,11 +29,7 @@ export type AlchemySmartAccountClientConfig< } & AlchemyProviderConfig & Pick< SmartAccountClientConfig, - | "customMiddleware" - | "dummyPaymasterAndData" - | "paymasterAndData" - | "feeEstimator" - | "gasEstimator" + "customMiddleware" | "feeEstimator" | "gasEstimator" >; export type AlchemySmartAccountClient_Base< @@ -74,11 +70,9 @@ export function createAlchemySmartAccountClient< account, gasManagerConfig, useSimulation, - dummyPaymasterAndData, feeEstimator, customMiddleware, gasEstimator, - paymasterAndData, ...config_ }: AlchemySmartAccountClientConfig< TTransport, @@ -90,11 +84,9 @@ export function createAlchemySmartAccountClient({ account, gasManagerConfig, useSimulation, - dummyPaymasterAndData, feeEstimator, customMiddleware, gasEstimator, - paymasterAndData, ...config_ }: AlchemySmartAccountClientConfig): AlchemySmartAccountClient { const config = AlchemyProviderConfigSchema.parse(config_); @@ -115,10 +107,9 @@ export function createAlchemySmartAccountClient({ ...opts, feeOptions, }, - dummyPaymasterAndData, feeEstimator, customMiddleware, gasEstimator, - paymasterAndData, + useSimulation, }); } diff --git a/packages/alchemy/src/index.ts b/packages/alchemy/src/index.ts index 233c089765..58308eceb4 100644 --- a/packages/alchemy/src/index.ts +++ b/packages/alchemy/src/index.ts @@ -1,7 +1,11 @@ export type * from "./actions/simulateUserOperationChanges.js"; export { simulateUserOperationChanges } from "./actions/simulateUserOperationChanges.js"; export type * from "./actions/types.js"; - +export { defineAlchemyChain } from "./chains.js"; +export type * from "./client/decorators/alchemyEnhancedApis.js"; +export { alchemyEnhancedApiActions } from "./client/decorators/alchemyEnhancedApis.js"; +export type * from "./client/decorators/smartAccount.js"; +export { alchemyActions } from "./client/decorators/smartAccount.js"; export { isAlchemySmartAccountClient } from "./client/isAlchemySmartAccountClient.js"; export type * from "./client/lightAccountClient.js"; export { createLightAccountAlchemyClient } from "./client/lightAccountClient.js"; @@ -10,18 +14,11 @@ export { createAlchemyPublicRpcClient } from "./client/rpcClient.js"; export type * from "./client/smartAccountClient.js"; export { createAlchemySmartAccountClient } from "./client/smartAccountClient.js"; export type * from "./client/types.js"; - -export type * from "./client/decorators/alchemyEnhancedApis.js"; -export { alchemyEnhancedApiActions } from "./client/decorators/alchemyEnhancedApis.js"; -export type * from "./client/decorators/smartAccount.js"; -export { alchemyActions } from "./client/decorators/smartAccount.js"; - +export { getDefaultUserOperationFeeOptions } from "./defaults.js"; export { alchemyFeeEstimator } from "./middleware/feeEstimator.js"; export type * from "./middleware/gasManager.js"; export { alchemyGasManagerMiddleware } from "./middleware/gasManager.js"; export { alchemyUserOperationSimulator } from "./middleware/userOperationSimulator.js"; - -export { getDefaultUserOperationFeeOptions } from "./defaults.js"; export type * from "./schema.js"; export { AlchemyProviderConfigSchema } from "./schema.js"; export type { AlchemyProviderConfig } from "./type.js"; diff --git a/packages/core/src/account/smartContractAccount.ts b/packages/core/src/account/smartContractAccount.ts index 36a005f095..387864bbd6 100644 --- a/packages/core/src/account/smartContractAccount.ts +++ b/packages/core/src/account/smartContractAccount.ts @@ -88,7 +88,7 @@ export type ToSmartContractAccountParams< getAccountInitCode: () => Promise; getDummySignature: () => Hex; encodeExecute: (tx: Tx) => Promise; - encodeBatchExecute: (txs: Tx[]) => Promise; + encodeBatchExecute?: (txs: Tx[]) => Promise; // if not provided, will default to just using signMessage over the Hex signUserOperationHash?: (uoHash: Hex) => Promise; encodeUpgradeToAndCall?: (params: UpgradeToAndCallParams) => Promise; @@ -308,7 +308,11 @@ export async function toSmartContractAccount< // and allow for generating the UO hash based on the EP version signUserOperationHash: signUserOperationHash_, getFactoryAddress, - encodeBatchExecute, + encodeBatchExecute: + encodeBatchExecute ?? + (() => { + throw new Error("Account does not support batch execution"); + }), encodeExecute, getDummySignature, getInitCode, diff --git a/packages/core/src/client/smartAccountClient.test.ts b/packages/core/src/client/smartAccountClient.test.ts index 1c6dba0971..39923a9fa6 100644 --- a/packages/core/src/client/smartAccountClient.test.ts +++ b/packages/core/src/client/smartAccountClient.test.ts @@ -47,6 +47,7 @@ describe("SmartAccountClient Tests", async () => { return; }, }), + chain, account, }); diff --git a/site/.vitepress/sidebar/packages/aa-accounts.ts b/site/.vitepress/sidebar/packages/aa-accounts.ts index 969daa85e7..3efbe42ed2 100644 --- a/site/.vitepress/sidebar/packages/aa-accounts.ts +++ b/site/.vitepress/sidebar/packages/aa-accounts.ts @@ -11,38 +11,23 @@ export const aaAccountsSidebar: DefaultTheme.SidebarItem = { }, { text: "Light Account", + link: "/light-account/", + }, + { + text: "Light Account Actions", collapsed: true, - base: "/packages/aa-accounts/light-account", + base: "/packages/aa-accounts/light-account/actions", items: [ { - text: "Introduction", - link: "/introduction", - }, - { - text: "constructor", - link: "/constructor", - }, - { - text: "provider", - link: "/provider", - }, - { - text: "signMessageWith6492", - link: "/signMessageWith6492", - }, - { text: "signTypedData", link: "/signTypedData" }, - { - text: "signTypedDataWith6492", - link: "/signTypedDataWith6492", + text: "transferOwnership", + link: "/transferOwnership", }, - { text: "getOwnerAddress", link: "/getOwnerAddress" }, - { - text: "encodeTransferOwnership", - link: "/encodeTransferOwnership", - }, - { text: "transferOwnership", link: "/transferOwnership" }, ], }, + { + text: "Light Account Client", + link: "/light-account/client", + }, { text: "Utils", collapsed: true, diff --git a/site/.vitepress/sidebar/packages/aa-alchemy.ts b/site/.vitepress/sidebar/packages/aa-alchemy.ts index fe7221d53b..2fc16438d2 100644 --- a/site/.vitepress/sidebar/packages/aa-alchemy.ts +++ b/site/.vitepress/sidebar/packages/aa-alchemy.ts @@ -10,61 +10,44 @@ export const aaAlchemySidebar: DefaultTheme.SidebarItem = { link: "/", }, { - text: "Provider", - base: "/packages/aa-alchemy/provider", + text: "Smart Account Client", + link: "/smart-account-client/", + }, + { + text: "Smart Account Actions", + base: "/packages/aa-alchemy/smart-account-client/actions", collapsed: true, items: [ { - text: "Introduction", - link: "/introduction", - }, - { - text: "constructor", - link: "/constructor", - }, - { - text: "factory", - link: "/light-account-factory", - }, - { text: "gasEstimator", link: "/gasEstimator" }, - { - text: "simulateUserOperationAssetChanges", - link: "/simulateUserOperationAssetChanges", - }, - { - text: "withAlchemyGasManager", - link: "/withAlchemyGasManager", + text: "simulateUserOperation", + link: "/simulateUserOperation", }, { - text: "withAlchemyUserOpSimulation", - link: "/withAlchemyUserOpSimulation", - }, - { - text: "withAlchemyEnhancedApis", - link: "/withAlchemyEnhancedApis", + text: "alchemyEnhancedApiActions", + link: "/alchemyEnhancedApiActions", }, ], }, + { + text: "Light Account Client", + link: "/light-account-client/", + }, { text: "Middleware", base: "/packages/aa-alchemy/middleware", collapsed: true, items: [ { - text: "Introduction", - link: "/introduction", - }, - { - text: "withAlchemyGasFeeEstimator", - link: "/withAlchemyGasFeeEstimator", + text: "alchemyFeeEstimator", + link: "/alchemyFeeEstimator", }, { - text: "withAlchemyGasManager", - link: "/withAlchemyGasManager", + text: "alchemyGasManagerMiddleware", + link: "/alchemyGasManagerMiddleware", }, { - text: "withAlchemyUserOpSimulation", - link: "/withAlchemyUserOpSimulation", + text: "alchemyUserOperationSimulator", + link: "/alchemyUserOperationSimulator", }, ], }, @@ -72,13 +55,7 @@ export const aaAlchemySidebar: DefaultTheme.SidebarItem = { text: "Utils", collapsed: true, base: "/packages/aa-alchemy/utils", - items: [ - { - text: "Introduction", - link: "/introduction", - }, - { text: "SupportedChains", link: "/supportedChains" }, - ], + items: [{ text: "Define Alchemy Chain", link: "/defineAlchemyChain" }], }, ], }; diff --git a/site/.vitepress/sidebar/packages/aa-core.ts b/site/.vitepress/sidebar/packages/aa-core.ts index 2a077e0703..ec9fc22e0c 100644 --- a/site/.vitepress/sidebar/packages/aa-core.ts +++ b/site/.vitepress/sidebar/packages/aa-core.ts @@ -106,8 +106,8 @@ export const aaCoreSidebar: DefaultTheme.SidebarItem = { }, { text: "Bundler Client", - base: "/packages/aa-core/bundler-client/index", - link: "/index", + base: "/packages/aa-core/bundler-client", + link: "/", }, { text: "Bundler Actions", @@ -143,102 +143,7 @@ export const aaCoreSidebar: DefaultTheme.SidebarItem = { { text: "Accounts", base: "/packages/aa-core/accounts", - collapsed: true, - items: [ - { - text: "Introduction", - link: "/introduction", - }, - { - text: "constructor", - link: "/constructor", - }, - { - text: "Required Methods", - collapsed: true, - base: "/packages/aa-core/accounts/required", - items: [ - { - text: "getDummySignature", - link: "/getDummySignature", - }, - { - text: "getAccountInitCode", - link: "/getAccountInitCode", - }, - { - text: "signMessage", - link: "/signMessage", - }, - { - text: "encodeExecute", - link: "/encodeExecute", - }, - ], - }, - { - text: "Optional Methods", - collapsed: true, - base: "/packages/aa-core/accounts/optional", - items: [ - { - text: "encodeBatchExecute", - link: "/encodeBatchExecute", - }, - { - text: "signTypedData", - link: "/signTypedData", - }, - { - text: "signMessageWith6492", - link: "/signMessageWith6492", - }, - { - text: "signTypedDataWith6492", - link: "/signTypedDataWith6492", - }, - { - text: "signUserOperationHash", - link: "/signUserOperationHash", - }, - ], - }, - { - text: "Other Methods", - collapsed: true, - base: "/packages/aa-core/accounts/other", - items: [ - { - text: "getAddress", - link: "/getAddress", - }, - { - text: "getNonce", - link: "/getNonce", - }, - { - text: "getOwner", - link: "/getOwner", - }, - { - text: "getDeploymentState", - link: "/getDeploymentState", - }, - { - text: "isAccountDeployed", - link: "/isAccountDeployed", - }, - { - text: "getFactoryAddress", - link: "/getFactoryAddress", - }, - { - text: "getEntryPointAddress", - link: "/getEntryPointAddress", - }, - ], - }, - ], + link: "/", }, { text: "Signers", diff --git a/site/glossary/types.md b/site/glossary/types.md index a8ebd0c19b..bcc7660257 100644 --- a/site/glossary/types.md +++ b/site/glossary/types.md @@ -94,7 +94,7 @@ Type representing the various transport protocols supported by the package. This ## `BundlerClient` -A client type that extends from the [`Viem` client](https://viem.sh/docs/clients/public.html). It integrates custom actions specific to [ERC-4337](https://accountkit.alchemy.com/glossary/terms.html#erc-4337). The `BundlerClient` is used within the [Alchemy Provider](https://github.com/alchemyplatform/aa-sdk/blob/b0f8dd538728f8a7dd4447da8c88a50179d61f95/packages/alchemy/src/provider/base.ts#L26) as a JSON-RPC transport, supporting standard EVM RPC methods as well as facilitating communication and operations specific to ERC-4337, such as sending `UserOperations` (UOs), estimating gas, and fetching operation receipts and responses. +A client type that extends from the [`Viem` client](https://viem.sh/docs/clients/public.html). It integrates custom actions specific to [ERC-4337](https://accountkit.alchemy.com/glossary/terms.html#erc-4337). The `BundlerClient` is used within the [Alchemy Smart Account Client](https://github.com/alchemyplatform/aa-sdk/blob/b0f8dd538728f8a7dd4447da8c88a50179d61f95/packages/alchemy/src/provider/base.ts#L26) as a JSON-RPC transport, supporting standard EVM RPC methods as well as facilitating communication and operations specific to ERC-4337, such as sending `UserOperations` (UOs), estimating gas, and fetching operation receipts and responses. [See Type ↗️](https://github.com/alchemyplatform/aa-sdk/blob/main/packages/core/src/client/types.ts#L98) diff --git a/site/overview/faqs.md b/site/overview/faqs.md index 791e8830c7..53bb0c06c0 100644 --- a/site/overview/faqs.md +++ b/site/overview/faqs.md @@ -36,7 +36,7 @@ There are two scenarios where you'd get a different contract address: ### How does a smart account get deployed? ::: details Answer -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`](/packages/aa-core/accounts/required/getAccountInitCode.html). +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`](/packages/aa-core/accounts/). ::: ### How would Alchemy initiate an upgrade of a Light Account? @@ -48,7 +48,7 @@ It is unlikely we will frequently update the Light Account contract itself, howe ### Can I have multiple accounts for the same owner address? / How do I set the value of the salt/index for Light Account? ::: details Answer -Yes! The optional index value (salt) on Light Account enables the ability to have multiple accounts for the same owner address. This value defaults to 0. You can set it in the [constructor](/packages/aa-accounts/light-account/constructor.html#params-simplesmartaccountparams). +Yes! The optional index value (salt) on Light Account enables the ability to have multiple accounts for the same owner address. This value defaults to 0. You can set it when you create [light account](/packages/aa-accounts/light-account/). ::: ## Submitting `UserOperation`s diff --git a/site/packages/aa-accounts/contributing.md b/site/packages/aa-accounts/contributing.md index 368bb2c17d..8758f64294 100644 --- a/site/packages/aa-accounts/contributing.md +++ b/site/packages/aa-accounts/contributing.md @@ -19,7 +19,7 @@ next: If you are looking to add a new account type, please follow the following structure. 1. Create a new folder in `src` with the name of your account type in `kebab-case` (we're following kebab casing for files throughout the project). -2. Create a new file in the folder you just created called `account.ts` and add your implementation for `BaseSmartContractAccount` +2. Create a new file in the folder you just created called `account.ts` and add a method that calls `toSmartContractAccount` to return an instance of your account 3. If needed, create a sub-folder in your account folder called `abis` and add your abis as `.ts` files. eg: ```ts @@ -28,11 +28,7 @@ export const MyContractAbi = [ ] as const; // the as const is important so we can get correct typing from viem ``` -4. If you need to extend the `SmartAccountProvider` class, add a file called `provider.ts` and add your implementation for `SmartAccountProvider`. - - - Ideally, your `Account` impl should _just_ work with the base provider provided by `aa-core`. - - If not, consider generalizing the use case and updating SmartAccountProvider - -5. Add some tests for your account and provider (if created) by creating a subfolder in your `account/my-account` called `__tests__` and make sure your files end with the `.test.ts` suffix +4. If you want, you can create a client creation method that return a `SmartAccountClient` instance with your account attached to it +5. Add some tests for your account and client (if created) by creating a subfolder in your `account/my-account` called `__tests__` and make sure your files end with the `.test.ts` suffix 6. Export the classes and types you've defined in `src/index.ts` 7. Open a PR and we'll review it as soon as possible! diff --git a/site/packages/aa-accounts/light-account/transferOwnership.md b/site/packages/aa-accounts/light-account/actions/transferOwnership.md similarity index 51% rename from site/packages/aa-accounts/light-account/transferOwnership.md rename to site/packages/aa-accounts/light-account/actions/transferOwnership.md index 414ae7693e..197463db9f 100644 --- a/site/packages/aa-accounts/light-account/transferOwnership.md +++ b/site/packages/aa-accounts/light-account/actions/transferOwnership.md @@ -14,24 +14,24 @@ next: text: Utils --- -# transferOwnership +# transferLightAccountOwnership -`transferOwnership` is a static class method on the `LightSmartContractAccount` which sends a UO that transfers ownership of the account to a new owner, and returns either the UO hash or transaction hash. +`transferLightAccountOwnership` is an action exported by `@alchemy/aa-accounts` which sends a UO that transfers ownership of the account to a new owner, and returns either the UO hash or transaction hash. ## Usage ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./provider"; +import { transferLightAccountOwnership } from "@alchemy/aa-accounts"; // [!code focus:99] // transfer ownership const newOwner = LocalAccountSigner.mnemonicToAccountSigner(NEW_OWNER_MNEMONIC); -const result = await LightSmartContractAccount.transferOwnership( - provider, - newOwner - true, // wait for txn with UO to be mined -); +const smartAccountClient = await transferLightAccountOwnership(provider, { + newOwner, + waitForTxn: true, // wait for txn with UO to be mined +}); ``` <<< @/snippets/smartAccountClient.ts @@ -45,6 +45,8 @@ A Promise containing the hash of either the UO or transaction containing the UO ## Parameters -- `provider: SmartAccountProvider & { account: LightSmartContractAccount }` -- the provider to use to send the transaction -- `newOwner: Address` -- the new owner of the account -- `waitForTxn?: boolean` -- optionally, wait for the transaction to be mined with the UO +- `client: SmartAccountClient` -- the provider to use to send the transaction +- `options: TransferLightAccountOwnershipParams` -- the options to use to transfer ownership + - `newOwner: Address` -- the new owner of the account + - `waitForTxn?: boolean` -- optionally, wait for the transaction to be mined with the UO + - `account?: LightAccount` -- optionally, pass the account if your client is not connected to it diff --git a/site/packages/aa-accounts/light-account/provider.md b/site/packages/aa-accounts/light-account/client.md similarity index 74% rename from site/packages/aa-accounts/light-account/provider.md rename to site/packages/aa-accounts/light-account/client.md index 3bf8414c8f..c40299da8f 100644 --- a/site/packages/aa-accounts/light-account/provider.md +++ b/site/packages/aa-accounts/light-account/client.md @@ -3,37 +3,37 @@ outline: deep head: - - meta - property: og:title - content: LightSmartContractAccount • createLightAccountProvider + content: LightSmartContractAccount • createLightAccountClient - - meta - name: description - content: Overview of the createLightAccountProvider factory in aa-accounts + content: Overview of the createLightAccountClient factory in aa-accounts - - meta - property: og:description - content: Overview of the createLightAccountProvider factory in aa-accounts + content: Overview of the createLightAccountClient factory in aa-accounts --- -# createLightAccountProvider +# createLightAccountClient -`createLightAccountProvider` is a factory that improves the developer experience of connecting a Light Account to a `SmartAccountProvider`. You can use this to directly instantiate a `SmartAccountProvider` already connected to a Light Account in one line of code. +`createLightAccountClient` is a factory that improves the developer experience of connecting a Light Account to a `SmartAccountClient`. You can use this to directly instantiate a `SmartAccountClient` already connected to a Light Account in one line of code. ## Usage ::: code-group -<<< @/snippets/light-account-provider.ts +<<< @/snippets/smartAccountClient.ts ::: ## Returns -### `Promise` +### `Promise` -A Promise containing a new `SmartAccountProvider` connected to a Light Account. +A Promise containing a new `SmartAccountClient` connected to a Light Account. ## Parameters -### `config: LightAccountProviderConfig` +### `config: CreateLightAccountClientParams` -- `rpcProvider: string | BundlerClient` -- a JSON-RPC URL, or a viem Client that supports ERC-4337 methods and Viem public actions. See [createBundlerClient](/packages/aa-core/bundler-client/index.md). +- `transport: Transport` -- a Viem transport for interacting with JSON RPC methods. - `chain: Chain` -- the chain on which to create the provider. @@ -63,3 +63,5 @@ A Promise containing a new `SmartAccountProvider` connected to a Light Account. - `initCode: Hex | undefined` -- [optional] the initCode for deploying the smart account with which the provider will connect. - `accountAddress: Address | undefined` -- [optional] a smart account address override that this object will manage instead of generating its own. + +- `...clientParams` -- [optional] additional parameters to pass to the [`SmartAccountClient`](/packages/aa-core/smart-account-client/) constructor. diff --git a/site/packages/aa-accounts/light-account/constructor.md b/site/packages/aa-accounts/light-account/constructor.md deleted file mode 100644 index 8da3b901ac..0000000000 --- a/site/packages/aa-accounts/light-account/constructor.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: LightSmartContractAccount • constructor - - - meta - - name: description - content: Overview of the constructor method on LightSmartContractAccount in aa-accounts - - - meta - - property: og:description - content: Overview of the constructor method on LightSmartContractAccount in aa-accounts ---- - -# constructor - -To initialize a `LightSmartContractAccount`, you must provide a set of parameters detailed below. - -Note that there is no difference in constructor arguments used for `LightSmartContractAccount` when compared to `SimpleSmartContractAccount`. - -## Usage - -::: code-group - -```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; -import { - LocalAccountSigner, - getDefaultEntryPointAddress, - type SmartAccountSigner, -} from "@alchemy/aa-core"; -import { sepolia } from "@alchemy/aa-core"; - -const PRIVATE_KEY = "0xYourEOAPrivateKey"; -const eoaSigner: SmartAccountSigner = - LocalAccountSigner.privateKeyToAccountSigner(`0x${PRIVATE_KEY}`); - -// instantiates using every possible parameter, as a reference -export const account = new LightSmartContractAccount({ - rpcClient: "ALCHEMY_RPC_URL", - chain: sepolia, - factoryAddress: getDefaultLightAccountFactoryAddress(sepolia), - owner: eoaSigner, - entryPointAddress: getDefaultEntryPointAddress(sepolia), - accountAddress: "0xYourSmartAccountAddress", - index: 0n, -}); -``` - -::: - -## Returns - -### `LightSmartContractAccount` - -A new instance of a `LightSmartContractAccount`. - -## Parameters - -### `params: SimpleSmartAccountParams` - -- `rpcClient: string | BundlerClient` -- a JSON-RPC URL, or a viem Client that supports ERC-4337 methods and Viem public actions. See [createBundlerClient](/packages/aa-core/bundler-client/index.md). - -- `chain: Chain` -- the chain on which to create the provider. - -- `factoryAddress: Address` -- the factory address for the smart account implementation, which is required for creating the account if not already deployed. - -- `owner: SmartAccountSigner` -- the owner EOA address responsible for signing user operations on behalf of the smart account. - -- `entryPointAddress: Address | undefined` -- [optional] entry point contract address. If not provided, the entry point contract address for the provider is the connected account's entry point contract, or if not connected, falls back to the default entry point contract for the chain. See [getDefaultEntryPointAddress](/packages/aa-core/utils/getDefaultEntryPointAddress.html#getdefaultentrypointaddress). - -- `accountAddress: Address | undefined` -- [optional] a smart account address override that this object will manage instead of generating its own. - -- `index: bigint | undefined` -- [optional] additional salt value used when creating the smart account. diff --git a/site/packages/aa-accounts/light-account/encodeTransferOwnership.md b/site/packages/aa-accounts/light-account/encodeTransferOwnership.md index 952ac457ff..4713c6febd 100644 --- a/site/packages/aa-accounts/light-account/encodeTransferOwnership.md +++ b/site/packages/aa-accounts/light-account/encodeTransferOwnership.md @@ -21,12 +21,12 @@ head: ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./smartAccountClient"; // [!code focus:99] // encode transfer pownership const newOwner = LocalAccountSigner.mnemonicToAccountSigner(NEW_OWNER_MNEMONIC); const encodedTransferOwnershipData = - LightSmartContractAccount.encodeTransferOwnership(newOwner); + smartAccountClient.account.encodeTransferOwnership({ newOwner }); ``` <<< @/snippets/smartAccountClient.ts diff --git a/site/packages/aa-accounts/light-account/getOwnerAddress.md b/site/packages/aa-accounts/light-account/getOwnerAddress.md index 1dfc2cfb1c..becb4eac31 100644 --- a/site/packages/aa-accounts/light-account/getOwnerAddress.md +++ b/site/packages/aa-accounts/light-account/getOwnerAddress.md @@ -21,10 +21,10 @@ head: ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./smartAccountClient"; // [!code focus:99] // get owner -const owner = await provider.account.getOwnerAddress(); +const owner = await smartAccountClient.account.getOwnerAddress(); ``` <<< @/snippets/smartAccountClient.ts diff --git a/site/packages/aa-accounts/light-account/introduction.md b/site/packages/aa-accounts/light-account/index.md similarity index 58% rename from site/packages/aa-accounts/light-account/introduction.md rename to site/packages/aa-accounts/light-account/index.md index 4e9dc0707d..7dc44dab87 100644 --- a/site/packages/aa-accounts/light-account/introduction.md +++ b/site/packages/aa-accounts/light-account/index.md @@ -3,43 +3,45 @@ outline: deep head: - - meta - property: og:title - content: LightSmartContractAccount + content: LightAccount - - meta - name: description - content: Overview of the LightSmartContractAccount class in aa-accounts + content: Overview of the LightAccount class in aa-accounts - - meta - property: og:description - content: Overview of the LightSmartContractAccount class in aa-accounts + content: Overview of the LightAccount class in aa-accounts --- # Light Account -`LightSmartContractAccount` is a simple, secure, and cost-effective smart account implementation which extends `SimpleSmartContractAccount` as an implementation of `BaseSmartContractAccount`. It supports features such as owner transfers, [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) message signing, and batched transactions. We recommend using Light Account for most use cases. +`LightAccount` is a simple, secure, and cost-effective smart account implementation which extends `SmartContractAccount`. It supports features such as owner transfers, [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) message signing, and batched transactions. We recommend using Light Account for most use cases. -Notable differences between `LightSmartContractAccount` and `SimpleSmartContractAccount` are implementations for: +The additional methods supported by `LightAccount` are: 1. [`signMessageWith6492`](/packages/aa-accounts/light-account/signMessageWith6492) -- supports message signatures for deployed smart accounts, as well as undeployed accounts (counterfactual addresses) using [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492). 2. [`signTypedData`](/packages/aa-accounts/light-account/signTypedData) -- supports typed data signatures from the smart account's owner address. 3. [`signTypedDataWith6492`](/packages/aa-accounts/light-account/signTypedDataWith6492) -- supports typed data signatures for deployed smart accounts, as well as undeployed accounts (counterfactual addresses) using ERC-6492. 4. [`getOwnerAddress`](/packages/aa-accounts/light-account/getOwnerAddress) -- returns the on-chain owner address of the account. 5. [`encodeTransferOwnership`](/packages/aa-accounts/light-account/encodeTransferOwnership) -- encodes the transferOwnership function call using Light Account ABI. -6. [`transferOwnership`](/packages/aa-accounts/light-account/transferOwnership) -- transfers ownership of the account to a new owner, and returns either the UO hash or transaction hash. +6. [`transferLightAccountOwnership`](/packages/aa-accounts/light-account/actions/transferOwnership) -- transfers ownership of the account to a new owner, and returns either the UO hash or transaction hash. ## Usage ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./smartAccountClient"; +import { transferLightAccountOwnership } from "@alchemy/aa-accounts"; + // [!code focus:99] // sign message (works for undeployed and deployed accounts) -const signedMessageWith6492 = provider.signMessageWith6492("test"); +const signedMessageWith6492 = smartAccountClient.signMessageWith6492("test"); // sign typed data -const signedTypedData = provider.signTypedData("test"); +const signedTypedData = smartAccountClient.signTypedData("test"); // sign typed data (works for undeployed and deployed accounts), using -const signedTypedDataWith6492 = provider.signTypedDataWith6492({ +const signedTypedDataWith6492 = smartAccountClient.signTypedDataWith6492({ types: { Request: [{ name: "hello", type: "string" }], }, @@ -50,19 +52,16 @@ const signedTypedDataWith6492 = provider.signTypedDataWith6492({ }); // get owner address -const owner = await provider.account.getOwnerAddress(); +const owner = await smartAccountClient.account.getOwnerAddress(); // encode transfer pownership const newOwner = LocalAccountSigner.mnemonicToAccountSigner(NEW_OWNER_MNEMONIC); -const encodedTransferOwnershipData = - LightSmartContractAccount.encodedTransferOwnership(newOwner); // transfer ownership -const result = await LightSmartContractAccount.transferOwnership( - provider, - newOwner - true, // wait for txn with UO to be mined -); +const result = await transferLightAccountOwnership(smartAccountClient, { + newOwner, + waitForTxn: true, // wait for txn with UO to be mined +}); ``` <<< @/snippets/smartAccountClient.ts diff --git a/site/packages/aa-accounts/light-account/signMessageWith6492.md b/site/packages/aa-accounts/light-account/signMessageWith6492.md index 063c4d5aab..2bad4ea66c 100644 --- a/site/packages/aa-accounts/light-account/signMessageWith6492.md +++ b/site/packages/aa-accounts/light-account/signMessageWith6492.md @@ -21,10 +21,12 @@ head: ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./smartAccountClient"; // [!code focus:99] // sign message (works for undeployed and deployed accounts) -const signedMessageWith6492 = provider.signMessageWith6492("test"); +const signedMessageWith6492 = smartAccountClient.signMessageWith6492({ + message: "test", +}); ``` <<< @/snippets/smartAccountClient.ts diff --git a/site/packages/aa-accounts/light-account/signTypedData.md b/site/packages/aa-accounts/light-account/signTypedData.md index a213cab605..36ce9a6b3b 100644 --- a/site/packages/aa-accounts/light-account/signTypedData.md +++ b/site/packages/aa-accounts/light-account/signTypedData.md @@ -21,10 +21,10 @@ head: ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./smartAccountClient"; // [!code focus:99] // sign typed data -const signedTypedData = provider.signTypedData({ +const signedTypedData = smartAccountClient.signTypedData({ domain: { name: "Ether Mail", version: "1", diff --git a/site/packages/aa-accounts/light-account/signTypedDataWith6492.md b/site/packages/aa-accounts/light-account/signTypedDataWith6492.md index 140a3b36b9..b2fa5cbec7 100644 --- a/site/packages/aa-accounts/light-account/signTypedDataWith6492.md +++ b/site/packages/aa-accounts/light-account/signTypedDataWith6492.md @@ -21,10 +21,10 @@ head: ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./smartAccountClient"; // [!code focus:99] // sign typed data (works for undeployed and deployed accounts) -const signedTypedDataWith6492 = provider.signTypedDataWith6492({ +const signedTypedDataWith6492 = smartAccountClient.signTypedDataWith6492({ domain: { name: "Ether Mail", version: "1", diff --git a/site/packages/aa-alchemy/index.md b/site/packages/aa-alchemy/index.md index 3fe06cc820..7d480b7faf 100644 --- a/site/packages/aa-alchemy/index.md +++ b/site/packages/aa-alchemy/index.md @@ -19,11 +19,11 @@ next: # `@alchemy/aa-alchemy` -This package contains `AlchemyProvider`, an implementation of `SmartAccountProvider` class defined in `aa-core`. It also contains middleware for accessing the Gas Manager (an [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) Paymaster) and for doing Fee Estimates according to the expectations of the [Rundler](https://github.com/alchemyplatform/rundler/tree/main) (an ERC-4337 Bundler). You may also find the util methods helpful. This repo is community maintained and we welcome contributions! +This package contains the `AlchemySmartAccountClient`, an extension of the `SmartAccountClient` defined in `aa-core`. It also contains middleware for accessing the Gas Manager (an [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) Paymaster) and for doing Fee Estimates according to the expectations of the [Rundler](https://github.com/alchemyplatform/rundler/tree/main) (an ERC-4337 Bundler). You may also find the util methods helpful. This repo is community maintained and we welcome contributions! ## Getting started -If you are already using the `@alchemy/aa-core` package, you can simply install this package and start using the `AlchemyProvider`. If you are not using `@alchemy/aa-core`, you can install it and follow the instructions in the ["Getting Started"](/overview/getting-started) docs to get started. +If you are already using the `@alchemy/aa-core` package, you can simply install this package and start using the `AlchemySmartAccountClient`. If you are not using `@alchemy/aa-core`, you can install it and follow the instructions in the ["Getting Started"](/overview/getting-started) docs to get started. ::: code-group @@ -41,9 +41,9 @@ pnpm i @alchemy/aa-alchemy ::: -Then, you can create a provider like so: +Then, you can create a client like so: ::: code-group -<<< @/snippets/smartAccountClient.ts +<<< @/snippets/alchemy-smartAccountClient.ts ::: diff --git a/site/packages/aa-alchemy/provider/light-account-factory.md b/site/packages/aa-alchemy/light-account-client/index.md similarity index 78% rename from site/packages/aa-alchemy/provider/light-account-factory.md rename to site/packages/aa-alchemy/light-account-client/index.md index c415070e74..b706609c86 100644 --- a/site/packages/aa-alchemy/provider/light-account-factory.md +++ b/site/packages/aa-alchemy/light-account-client/index.md @@ -3,31 +3,31 @@ outline: deep head: - - meta - property: og:title - content: AlchemyProvider • createLightAccountAlchemyProvider + content: createLightAccountAlchemyClient - - meta - name: description - content: Overview of the createLightAccountAlchemyProvider factory in aa-alchemy + content: Overview of the createLightAccountAlchemyClient factory in aa-alchemy - - meta - property: og:description - content: Overview of the createLightAccountAlchemyProvider factory in aa-alchemy + content: Overview of the createLightAccountAlchemyClient factory in aa-alchemy --- -# createLightAccountAlchemyProvider +# createLightAccountAlchemyClient -`createLightAccountAlchemyProvider` is a factory that improves the developer experience of connecting a Light Account to an `AlchemyProvider` via an optional dependency on the [`@alchemy/aa-accounts`](https://github.com/alchemyplatform/aa-sdk/tree/development/packages/accounts) package. You can use this to directly instantiate an `AlchemyProvider` already connected to a Light Account in one line of code. +`createLightAccountAlchemyClient` is a factory that improves the developer experience of connecting a Light Account to an `AlchemyProvider` via an optional dependency on the [`@alchemy/aa-accounts`](https://github.com/alchemyplatform/aa-sdk/tree/development/packages/accounts) package. You can use this to directly instantiate an `AlchemySmartAccountClient` already connected to a Light Account in one line of code. ## Usage ::: code-group -<<< @/snippets/light-account-alchemy-provider.ts +<<< @/snippets/light-account-alchemy-client.ts ::: ## Returns -### `Promise` +### `Promise` -A Promise containing a new `AlchemyProvider` connected to a Light Account. +A Promise containing a new `AlchemySmartAccountClient` connected to a Light Account. ## Parameters diff --git a/site/packages/aa-alchemy/middleware/alchemyFeeEstimator.md b/site/packages/aa-alchemy/middleware/alchemyFeeEstimator.md new file mode 100644 index 0000000000..e072005bd3 --- /dev/null +++ b/site/packages/aa-alchemy/middleware/alchemyFeeEstimator.md @@ -0,0 +1,54 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: Middleware • alchemyFeeEstimator + - - meta + - name: description + content: Overview of the alchemyFeeEstimator method in aa-alchemy + - - meta + - property: og:description + content: Overview of the alchemyFeeEstimator method in aa-alchemy +--- + +# alchemyFeeEstimator + +`alchemyFeeEstimator` is a middleware method you can use to easily leverage Rundler (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Bundler) for estimating gas fees for user operations. + +## Usage + +::: code-group + +```ts [example.ts] +import { + alchemyFeeEstimator, + createAlchemyRpcClient, +} from "@alchemy/aa-alchemy"; +import { createSmartAccountClient } from "@alchemy/aa-core"; +import { http } from "viem"; +import { sepolia } from "viem/chains"; + +const alchemyClient = createAlchemyRpcClient({ + transport: http("ALCHEMY_RPC_URL"), + chain: sepolia, +}); + +// use Alchemy Gas Fee Estimator to estimate gas fees according to the expectations of Rundler. +const clientWithGasFeeEstimator = createSmartAccountClient({ + ...config, + feeEstimator: alchemyFeeEstimator(alchemyClient), +}); +``` + +::: + +## Returns + +### `ClientMiddlewareFn` + +A `ClientMiddlewareFn` that will estimate fees using the Rundler. + +## Parameters + +### `client: ClientWithAlchemyMethods` -- an `PublicClient` that is connected to Alchemy's RPC diff --git a/site/packages/aa-alchemy/middleware/alchemyGasManagerMiddleware.md b/site/packages/aa-alchemy/middleware/alchemyGasManagerMiddleware.md new file mode 100644 index 0000000000..79daae805e --- /dev/null +++ b/site/packages/aa-alchemy/middleware/alchemyGasManagerMiddleware.md @@ -0,0 +1,63 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: Middleware • alchemyGasManagerMiddleware + - - meta + - name: description + content: Overview of the alchemyGasManagerMiddleware method in aa-alchemy + - - meta + - property: og:description + content: Overview of the alchemyGasManagerMiddleware method in aa-alchemy +--- + +# alchemyGasManagerMiddleware + +`alchemyGasManagerMiddleware` is a middleware method you can use to easily leverage our Gas Manager (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Paymaster) for sponsoring user operations. + +## Usage + +::: code-group + +```ts [example.ts] +import { + alchemyGasManagerMiddleware, + createAlchemyRpcClient, +} from "@alchemy/aa-alchemy"; +import { createSmartAccountClient } from "@alchemy/aa-core"; +import { http } from "viem"; +import { sepolia } from "viem/chains"; + +const alchemyClient = createAlchemyRpcClient({ + transport: http("ALCHEMY_RPC_URL"), + chain: sepolia, +}); + +// Use this middleware generator to set up your account to use Alchemy's Gas Manager Service +const clientAlchemyGasManager = createSmartAccountClient({ + ...config, + ...alchemyGasManagerMiddleware(alchemyClient, { + policyId: PAYMASTER_POLICY_ID, + }), +}); +``` + +::: + +## Returns + +### `{ feeEstimator: ClientMiddlewareFn, paymasterAndData: ClientMiddlewareFn, dummyPaymasterAndData: ClientMiddlewareFn, gasEstimator: ClientMiddlewareFn }` + +A set of `ClientMiddlewareFn` that will get the paymaster and data fields from Alchemy's Gas Manager, and optionally do gas / fee estimation. + +## Parameters + +### `client: ClientWithAlchemyMethods` -- an `PublicClient` that is connected to Alchemy's RPC + +### `AlchemyGasManagerConfig: AlchemyGasManagerConfig` + +- `policyId: string` -- the Gas Manager policy ID + +- `gasEstimationOptions?: AlchemyGasEstimationOptions` -- optional params for configuring gas estimation during paymaster resolution + - `disableGasEstimation?: boolean` -- if true, then gas estimation will be done locally instead of requesting it from the paymaster endpoint diff --git a/site/packages/aa-alchemy/middleware/alchemyUserOperationSimulator.md b/site/packages/aa-alchemy/middleware/alchemyUserOperationSimulator.md new file mode 100644 index 0000000000..bb21be09d1 --- /dev/null +++ b/site/packages/aa-alchemy/middleware/alchemyUserOperationSimulator.md @@ -0,0 +1,56 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: Middleware • alchemyUserOperationSimulator + - - meta + - name: description + content: Overview of the alchemyUserOperationSimulator method in aa-alchemy + - - meta + - property: og:description + content: Overview of the alchemyUserOperationSimulator method in aa-alchemy +next: + text: Utils +--- + +# alchemyUserOperationSimulator + +`alchemyUserOperationSimulator` is a middleware method you can use to easily leverage the [`alchemy_simulateUserOperationAssetChanges`](https://docs.alchemy.com/reference/alchemy-simulateuseroperationassetchanges/?a=ak-docs) API to simulate asset changes resulting from user operation. Having this as part of your middleware stack will ensure `UserOperations` that fail simulation do not get sent unnecessarily. + +## Usage + +::: code-group + +```ts [example.ts] +import { + alchemyUserOperationSimulator, + createAlchemyRpcClient, +} from "@alchemy/aa-alchemy"; +import { createSmartAccountClient } from "@alchemy/aa-core"; +import { http } from "viem"; +import { sepolia } from "viem/chains"; + +const alchemyClient = createAlchemyRpcClient({ + transport: http("ALCHEMY_RPC_URL"), + chain: sepolia, +}); + +// use Alchemy to simulate User Ops +const clientWithUserOpSimulator = createSmartAccountClient({ + ...config, + userOperationSimulator: alchemyUserOperationSimulator(alchemyClient), +}); +``` + +::: + +## Returns + +### `ClientMiddlewareFn` + +A `ClientMiddlewareFn` that will simulate a user operation using the Alchemy UserOperation Simulation API. + +## Parameters + +### `client: ClientWithAlchemyMethods` -- an `PublicClient` that is connected to Alchemy's RPC diff --git a/site/packages/aa-alchemy/middleware/introduction.md b/site/packages/aa-alchemy/middleware/introduction.md deleted file mode 100644 index 119ec78ace..0000000000 --- a/site/packages/aa-alchemy/middleware/introduction.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: Middleware - - - meta - - name: description - content: Overview of the Middleware methods in aa-alchemy - - - meta - - property: og:description - content: Overview of the Middleware methods in aa-alchemy ---- - -# Middleware - -The `aa-alchemy` package contains middleware you can use to easily leverage our Bundler(Rundler) (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Bundler) and our Gas Manager (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Paymaster). - -Currently, `aa-alchemy` has implementations for: - -1. [`withAlchemyGasFeeEstimator`](/packages/aa-alchemy/middleware/withAlchemyGasFeeEstimator) -- estimates gas fees according to the expectations of the Alchemy Rundler. -2. [`withAlchemyGasManager`](/packages/aa-alchemy/middleware/withAlchemyGasManager) -- adds the Alchemy Gas Manager middleware to the provider. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -import { - withAlchemyGasFeeEstimator, - withAlchemyGasManager, -} from "@alchemy/aa-alchemy"; - -// use Alchemy Gas Fee Estimator to estimate fees according to the expectations of the Alchemy Rundler. -// this is already set on AlchemyProvider, but you can always use the middleware directly to create a new instance. -const providerWithGasFeeEstimator = withAlchemyGasFeeEstimator( - provider, - 50n, - 50n -); - -// use Alchemy Gas Manager to sponsorship transactions -const providerWithGasManager = withAlchemyGasManager( - provider, - { - policyId: PAYMASTER_POLICY_ID, - }, - true // if true, uses `alchemy_requestGasAndPaymasterAndData`, otherwise uses `alchemy_requestPaymasterAndData` -); -``` - -<<< @/snippets/smartAccountClient.ts -::: diff --git a/site/packages/aa-alchemy/middleware/withAlchemyGasFeeEstimator.md b/site/packages/aa-alchemy/middleware/withAlchemyGasFeeEstimator.md deleted file mode 100644 index e07d7584c1..0000000000 --- a/site/packages/aa-alchemy/middleware/withAlchemyGasFeeEstimator.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: Middleware • withAlchemyGasFeeEstimator - - - meta - - name: description - content: Overview of the withAlchemyGasFeeEstimator method in aa-alchemy - - - meta - - property: og:description - content: Overview of the withAlchemyGasFeeEstimator method in aa-alchemy ---- - -# withAlchemyGasFeeEstimator - -`withAlchemyGasFeeEstimator` is a middleware method you can use to easily leverage Rundler (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Bundler) for estimating gas fees for user operations. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -import { withAlchemyGasFeeEstimator } from "@alchemy/aa-alchemy"; - -// use Alchemy Gas Fee Estimator to estimate gas fees according to the expectations of Rundler. -// this is already set on AlchemyProvider, but you can always use the middleware directly to create a new instance. -const providerWithGasFeeEstimator = withAlchemyGasFeeEstimator( - provider, - 50n, - 50n -); -``` - -<<< @/snippets/smartAccountClient.ts -::: - -## Returns - -### `AlchemyProvider` - -A new instance of an `AlchemyProvider` with the same attributes as the input, now with middleware for gas fee estimation. - -## Parameters - -### `provider: AlchemyProvider` -- an `AlchemyProvider` instance - -### `baseFeeBufferPercent: bigint` -- buffer percentage to adjust the `baseFee` of a UO request sent through the provider - -### `maxPriorityFeeBufferPercent: bigint` -- buffer percentage to adjust the `maxPriorityFee` of a UO request sent through the provider diff --git a/site/packages/aa-alchemy/middleware/withAlchemyGasManager.md b/site/packages/aa-alchemy/middleware/withAlchemyGasManager.md deleted file mode 100644 index 37f6594fbb..0000000000 --- a/site/packages/aa-alchemy/middleware/withAlchemyGasManager.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: Middleware • withAlchemyGasManager - - - meta - - name: description - content: Overview of the withAlchemyGasManager method in aa-alchemy - - - meta - - property: og:description - content: Overview of the withAlchemyGasManager method in aa-alchemy ---- - -# withAlchemyGasManager - -`withAlchemyGasManager` is a middleware method you can use to easily leverage our Gas Manager (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Paymaster) for sponsoring user operations. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -import { withAlchemyGasManager } from "@alchemy/aa-alchemy"; - -// use Gas Manager to sponsorship transactions -const providerWithGasManager = withAlchemyGasManager( - provider, - { - policyId: PAYMASTER_POLICY_ID, - }, - true // If true, uses `alchemy_requestGasAndPaymasterAndData`, otherwise uses `alchemy_requestPaymasterAndData` -); -``` - -<<< @/snippets/smartAccountClient.ts -::: - -## Returns - -### `AlchemyProvider` - -A new instance of an `AlchemyProvider` with the same attributes as the input, now with middleware for accessing the Gas Manager to sponsor UserOperations. - -## Parameters - -### `provider: AlchemyProvider` -- an `AlchemyProvider` instance - -### `AlchemyGasManagerConfig: AlchemyGasManagerConfig` - -- `policyId: string` -- the Gas Manager policy ID - -### `delegateGasEstimation: boolean` -- a flag to additionally estimate gas as part of requesting paymaster and data diff --git a/site/packages/aa-alchemy/middleware/withAlchemyUserOpSimulation.md b/site/packages/aa-alchemy/middleware/withAlchemyUserOpSimulation.md deleted file mode 100644 index c4400b95fc..0000000000 --- a/site/packages/aa-alchemy/middleware/withAlchemyUserOpSimulation.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: Middleware • withAlchemyUserOpSimulation - - - meta - - name: description - content: Overview of the withAlchemyUserOpSimulation method in aa-alchemy - - - meta - - property: og:description - content: Overview of the withAlchemyUserOpSimulation method in aa-alchemy -next: - text: Utils ---- - -# withAlchemyUserOpSimulation - -`withAlchemyUserOpSimulation` is a middleware method you can use to easily leverage the [`alchemy_simulateUserOperationAssetChanges`](https://docs.alchemy.com/reference/alchemy-simulateuseroperationassetchanges/?a=ak-docs) API to simulate asset changes resulting from user operation. Having this as part of your middleware stack will ensure `UserOperations` that fail simulation do not get sent unnecessarily. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -import { withAlchemyUserOpSimulation } from "@alchemy/aa-alchemy"; - -// use Alchemy UserOperation Simulation API to simulate asset changes resulting from user operation -const providerWithUserOpSimulation = withAlchemyUserOpSimulation(provider); -``` - -<<< @/snippets/smartAccountClient.ts -::: - -## Returns - -### `AlchemyProvider` - -A new instance of an `AlchemyProvider` with the same attributes as the input, now with middleware for accessing the Alchemy `UserOperation` Simulation API to simulate asset changes resulting from UserOperations. - -## Parameters - -### `provider: AlchemyProvider` -- an `AlchemyProvider` instance diff --git a/site/packages/aa-alchemy/provider/gasEstimator.md b/site/packages/aa-alchemy/provider/gasEstimator.md deleted file mode 100644 index 52e6135c29..0000000000 --- a/site/packages/aa-alchemy/provider/gasEstimator.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: AlchemyProvider • gasEstimator - - - meta - - name: description - content: Overview of the gasEstimator method on Alchemy Provider in aa-alchemy - - - meta - - property: og:description - content: Overview of the gasEstimator method on Alchemy Provider in aa-alchemy ---- - -# gasEstimator - -`gasEstimator` is an override of the same middleware on `SmartAccountProvider`. As part of the middleware stack that the `AlchemyProvider` would run on each UO built and sent, this middleware estimates gas using the Rundler (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Bundler), and updates `callGasLimit`, `verificationGasLimit`, and `preVerificationGas` in a UO request with appropriate buffers. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -// [!code focus:99] -// building a UO struct will use the overrided `gasEstimator` middleware on AlchemyProvider -const uoStruct = await provider.buildUserOperation({ - target: TO_ADDRESS, - data: ENCODED_DATA, - value: VALUE, // optional -}); -const uoHash = await provider.sendUserOperation(uoStruct); -``` - -<<< @/snippets/smartAccountClient.ts -::: - -## Returns - -### `Promise>` - -the resulting user operation struct after gas estimation, run as part of a middleware chain when building and sending UserOperations. - -## Parameters - -### `struct: Deferrable` -- the struct containing UserOperation fields, where each field may be asychronously returned from the middleware used to generate its final value. - -Note: You typically will call this method as part of a middleware chain when building and sending UserOperations, so the parameters of `UserOperationStruct` should be generated for you, as long as you pass in the initial parameters needed for [sendUserOperation](/packages/aa-core/smart-account-client/actions/sendUserOperation). diff --git a/site/packages/aa-alchemy/provider/introduction.md b/site/packages/aa-alchemy/provider/introduction.md deleted file mode 100644 index 1ac248bd75..0000000000 --- a/site/packages/aa-alchemy/provider/introduction.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: AlchemyProvider - - - meta - - name: description - content: Overview of the AlchemyProvider class in aa-alchemy - - - meta - - property: og:description - content: Overview of the AlchemyProvider class in aa-alchemy ---- - -# AlchemyProvider - -`AlchemyProvider` is an extension of the [`SmartAccountProvider`](/packages/aa-core/smart-account-client/index) implementation. It's a simpler interface you can use to leverage the Alchemy stack - JSON-RPC requests via API Key or JSON Web Token (JWT), Rundler (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Bundler), and Gas Manager (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Paymaster). - -Notable differences between `AlchemyProvider` and `SmartAccountProvider` are implementations for: - -2. [`withAlchemyGasManager`](/packages/aa-alchemy/provider/withAlchemyGasManager.md) -- adds the Alchemy Gas Manager middleware to the provider. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -// [!code focus:99] -// building a UO struct will use the overrided `gasEstimator` middleware on AlchemyProvider -const uoStruct = await provider.buildUserOperation({ - target: TO_ADDRESS, - data: ENCODED_DATA, - value: VALUE, // optional -}); -const uoHash = await provider.sendUserOperation(uoStruct); - -// use Gas Manager to sponsorship transactions -const providerWithGasManager = provider.withAlchemyGasManager({ - policyId: PAYMASTER_POLICY_ID, -}); -``` - -<<< @/snippets/smartAccountClient.ts -::: diff --git a/site/packages/aa-alchemy/provider/withAlchemyEnhancedApis.md b/site/packages/aa-alchemy/provider/withAlchemyEnhancedApis.md deleted file mode 100644 index b1f0903b24..0000000000 --- a/site/packages/aa-alchemy/provider/withAlchemyEnhancedApis.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: AlchemyProvider • withAlchemyEnhancedApis - - - meta - - name: description - content: Overview of the withAlchemyEnhancedApis method on Alchemy Provider in aa-alchemy - - - meta - - property: og:description - content: Overview of the withAlchemyEnhancedApis method on Alchemy Provider in aa-alchemy -next: - text: Middleware ---- - -# withAlchemyEnhancedApis - -`withAlchemyEnhancedApis` is a method on `AlchemyProvider` that you can optionally call to create a new provider instance with added methods that access the Alchemy [Enhanced APIs](https://www.alchemy.com/enhanced-apis/?a=ak-docs) via the [Alchemy SDK](https://github.com/alchemyplatform/alchemy-sdk-js). - -:::tip Note -This method requires an optional dependency on the [`alchemy-sdk`](https://github.com/alchemyplatform/alchemy-sdk-js) package, as the input to this method is an Alchemy SDK client. - -The Alchemy SDK client must be configured with the same API key and network as the `AlchemyProvider`. This method validates such at runtime. - -Additionally, since the Alchemy SDK client does not yet support JWT authentication, an `AlchemyProvider` initialized with JWTs cannot use this method. They must be initialized with an API key or RPC URL. -::: - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -// [!code focus:99] - -const alchemy = new Alchemy(); - -// use Alchemy Enhanced APIs -const providerWithEnhancedApis = provider.withAlchemyEnhancedApis(alchemy); -``` - -<<< @/snippets/smartAccountClient.ts -::: - -## Returns - -### `AlchemyProvider` - -A new instance of an `AlchemyProvider` with the same attributes as the input, now with methods for accessing the Alchemy Enhanced APIs to more efficiently query blockchain data. - -## Parameters - -### `alchemy: Alchemy` -- an initialized Alchemy SDK client diff --git a/site/packages/aa-alchemy/provider/withAlchemyGasManager.md b/site/packages/aa-alchemy/provider/withAlchemyGasManager.md deleted file mode 100644 index b323cd922b..0000000000 --- a/site/packages/aa-alchemy/provider/withAlchemyGasManager.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: AlchemyProvider • withAlchemyGasManager - - - meta - - name: description - content: Overview of the withAlchemyGasManager method on Alchemy Provider in aa-alchemy - - - meta - - property: og:description - content: Overview of the withAlchemyGasManager method on Alchemy Provider in aa-alchemy ---- - -# withAlchemyGasManager - -`withAlchemyGasManager` is a method on `AlchemyProvider` that you can optionally call to create a new provider instance with added middleware leveraging the Alchemy Gas Manager (an [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) Paymaster). Under the hood, this will call the [`withAlchemyGasManager`](/packages/aa-alchemy/middleware/withAlchemyGasManager) middleware. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -// [!code focus:99] - -// use Gas Manager to sponsorship transactions -const providerWithGasManager = provider.withAlchemyGasManager({ - policyId: PAYMASTER_POLICY_ID, -}); -``` - -<<< @/snippets/smartAccountClient.ts -::: - -## Returns - -### `AlchemyProvider` - -A new instance of an `AlchemyProvider` with the same attributes as the input, now with middleware for accessing the Alchemy Gas Manager to sponsor UserOperations. - -## Parameters - -### `config: AlchemyGasManagerConfig` - -- `policyId: string` -- the Gas Manager policy ID diff --git a/site/packages/aa-alchemy/provider/withAlchemyUserOpSimulation.md b/site/packages/aa-alchemy/provider/withAlchemyUserOpSimulation.md deleted file mode 100644 index b138da92c1..0000000000 --- a/site/packages/aa-alchemy/provider/withAlchemyUserOpSimulation.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: AlchemyProvider • withAlchemyUserOpSimulation - - - meta - - name: description - content: Overview of the withAlchemyUserOpSimulation method on Alchemy Provider in aa-alchemy - - - meta - - property: og:description - content: Overview of the withAlchemyUserOpSimulation method on Alchemy Provider in aa-alchemy ---- - -# withAlchemyUserOpSimulation - -`withAlchemyUserOpSimulation` is a method on `AlchemyProvider` that you can optionally call to create a new provider instance with added middleware leveraging the Alchemy `UserOperation` (UO) Simulation API. Under the hood, this will call the [`withAlchemyUserOpSimulation`](/packages/aa-alchemy/middleware/withAlchemyUserOpSimulation) middleware to simulate asset changes resulting from user operation. - -## Usage - -::: code-group - -```ts [example.ts] -import { provider } from "./provider"; -// [!code focus:99] - -// use Alchemy UserOperation Simulation API to simulate simulate asset changes resulting from user operation before sending -const providerWithGasManager = provider.withAlchemyUserOpSimulation(); -``` - -<<< @/snippets/smartAccountClient.ts -::: - -## Returns - -### `AlchemyProvider` - -A new instance of an `AlchemyProvider` with the same attributes as the input, now with middleware for accessing the Alchemy UO Simulation API to simulate asset changes resulting from user operation. diff --git a/site/packages/aa-alchemy/smart-account-client/actions/alchemyEnhancedApiActions.md b/site/packages/aa-alchemy/smart-account-client/actions/alchemyEnhancedApiActions.md new file mode 100644 index 0000000000..7b21a0a59e --- /dev/null +++ b/site/packages/aa-alchemy/smart-account-client/actions/alchemyEnhancedApiActions.md @@ -0,0 +1,57 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: alchemyEnhancedApiActions + - - meta + - name: description + content: Overview of the alchemyEnhancedApiActions method on Alchemy Smart Account Client in aa-alchemy + - - meta + - property: og:description + content: Overview of the alchemyEnhancedApiActions method on Alchemy Smart Account Client in aa-alchemy +next: + text: Middleware +--- + +# alchemyEnhancedApiActions + +`alchemyEnhancedApiActions` is a decorator that can be used with a `AlchemySmartAccountClient` that will extend the client with methods that access the Alchemy [Enhanced APIs](https://www.alchemy.com/enhanced-apis/?a=ak-docs) via the [Alchemy SDK](https://github.com/alchemyplatform/alchemy-sdk-js). + +:::tip Note +This method requires an optional dependency on the [`alchemy-sdk`](https://github.com/alchemyplatform/alchemy-sdk-js) package, as the input to this method is an Alchemy SDK client. + +The Alchemy SDK client must be configured with the same API key and network as the `AlchemySmartAccountClient`. This method validates such at runtime. + +Additionally, since the Alchemy SDK client does not yet support JWT authentication, an `AlchemySmartAccountClient` initialized with JWTs cannot use this method. They must be initialized with an API key or RPC URL. +::: + +## Usage + +::: code-group + +```ts [example.ts] +import { smartAccountClient } from "./alchemy-smartAccountClient"; +import { alchemyEnhancedApiActions } from "@alchemy/aa-alchemy"; +// [!code focus:99] + +const alchemy = new Alchemy(); + +// use Alchemy Enhanced APIs +const providerWithEnhancedApis = smartAccountClient.extend( + alchemyEnhancedApiActions +); +``` + +<<< @/snippets/alchemy-smartAccountClient.ts +::: + +## Returns + +### `AlchemySmartAccountClient` + +A new instance of an `AlchemySmartAccountClient` with the same attributes as the input, now with methods for accessing the Alchemy Enhanced APIs to more efficiently query blockchain data. + +## Parameters + +### `alchemy: Alchemy` -- an initialized Alchemy SDK client diff --git a/site/packages/aa-alchemy/provider/simulateUserOperationAssetChanges.md b/site/packages/aa-alchemy/smart-account-client/actions/simulateUserOperation.md similarity index 64% rename from site/packages/aa-alchemy/provider/simulateUserOperationAssetChanges.md rename to site/packages/aa-alchemy/smart-account-client/actions/simulateUserOperation.md index 40c752315a..26876dfe2e 100644 --- a/site/packages/aa-alchemy/provider/simulateUserOperationAssetChanges.md +++ b/site/packages/aa-alchemy/smart-account-client/actions/simulateUserOperation.md @@ -3,25 +3,25 @@ outline: deep head: - - meta - property: og:title - content: AlchemyProvider • simulateUserOperationAssetChanges + content: AlchemyProvider • simulateUserOperation - - meta - name: description - content: Overview of the simulateUserOperationAssetChanges method on Alchemy Provider in aa-alchemy + content: Overview of the simulateUserOperation method on Alchemy Smart Account Client in aa-alchemy - - meta - property: og:description - content: Overview of the simulateUserOperationAssetChanges method on Alchemy Provider in aa-alchemy + content: Overview of the simulateUserOperation method on Alchemy Smart Account Client in aa-alchemy --- -# simulateUserOperationAssetChanges +# simulateUserOperation -`simulateUserOperationAssetChanges` is a method you can use to easily leverage the [`alchemy_simulateUserOperationAssetChanges`](https://docs.alchemy.com/reference/alchemy-simulateuseroperationassetchanges/?a=ak-docs) API to simulate asset changes resulting from user operation. +`simulateUserOperation` is a method you can use to easily leverage the [`alchemy_simulateUserOperationAssetChanges`](https://docs.alchemy.com/reference/alchemy-simulateuseroperationassetchanges/?a=ak-docs) API to simulate asset changes resulting from user operation. ## Usage ::: code-group ```ts [example.ts] -import { provider } from "./provider"; +import { smartAccountClient } from "./alchemy-smartAccountClient"; // [!code focus:99] const uoStruct: UserOperationCallData = { @@ -30,16 +30,18 @@ const uoStruct: UserOperationCallData = { value: 1n, }; -const uoSimResult = await provider.simulateUserOperationAssetChanges(uoStruct); +const uoSimResult = await smartAccountClient.simulateUserOperationAssetChanges({ + uo: uoStruct, +}); if (uoSimResult.error) { console.error(uoSimResult.error.message); } -const uo = await provider.sendUserOperation(uoStruct); +const uo = await smartAccountClient.sendUserOperation({ uo: uoStruct }); ``` -<<< @/snippets/smartAccountClient.ts +<<< @/snippets/light-account-alchemy-client.ts ::: ## Returns diff --git a/site/packages/aa-alchemy/provider/constructor.md b/site/packages/aa-alchemy/smart-account-client/index.md similarity index 70% rename from site/packages/aa-alchemy/provider/constructor.md rename to site/packages/aa-alchemy/smart-account-client/index.md index abcedea015..49852f88ba 100644 --- a/site/packages/aa-alchemy/provider/constructor.md +++ b/site/packages/aa-alchemy/smart-account-client/index.md @@ -3,18 +3,18 @@ outline: deep head: - - meta - property: og:title - content: AlchemyProvider • constructor + content: Alchemy Smart Account Client - - meta - name: description - content: Overview of the constructor method on AlchemyProvider in aa-alchemy + content: Overview of the Alchemy Smart Account Client in aa-alchemy - - meta - property: og:description - content: Overview of the constructor method on AlchemyProvider in aa-alchemy + content: Overview of the Alchemy Smart Account Client in aa-alchemy --- -# constructor +# Alchemy Smart Account Client -To initialize an `AlchemyProvider`, you must provide a set of parameters detailed below. +To create an `AlchemySmartAccountClient`, you must provide a set of parameters detailed below. ## Usage @@ -26,20 +26,27 @@ import { getDefaultEntryPointAddress } from "@alchemy/aa-core"; import { sepolia } from "@alchemy/aa-core"; // instantiates using every possible parameter, as a reference -export const provider = new AlchemyProvider({ +export const provider = createAlchemySmartAccountClient({ + /// REQUIRED /// apiKey: "ALCHEMY_API_KEY", // replace with your Alchemy API Key chain: sepolia, - entryPointAddress: getDefaultEntryPointAddress(sepolia), + /// OPTIONAL /// opts: { txMaxRetries: 10, txRetryIntervalMs: 2_000, txRetryMulitplier: 1.5, minPriorityFeePerBid: 100_000_000n, + feeOpts: { + baseFeeBufferPercent: 50n, + maxPriorityFeeBufferPercent: 5n, + preVerificationGasBufferPercent: 5n, + }, }, - feeOpts: { - baseFeeBufferPercent: 50n, - maxPriorityFeeBufferPercent: 5n, - preVerificationGasBufferPercent: 5n, + // will simulate user operations before sending them to ensure they don't revert + useSimulation: true, + // if you want to use alchemy's gas manager + gasManagerConfig: { + policyId: "policy-id", }, }); ``` @@ -48,9 +55,9 @@ export const provider = new AlchemyProvider({ ## Returns -### `AlchemyProvider` +### `AlchemySmartAccountClient` -A new instance of an `AlchemyProvider`. +A new instance of an `AlchemySmartAccountClient`. ## Parameters @@ -64,7 +71,11 @@ A new instance of an `AlchemyProvider`. - `chain: Chain` -- the chain on which to create the provider. -- `entryPointAddress: Address | undefined` -- [optional] the entry point contract address. If not provided, the entry point contract address for the provider is the connected account's entry point contract, or if not connected, falls back to the default entry point contract for the chain. See [getDefaultEntryPointAddress](/packages/aa-core/utils/getDefaultEntryPointAddress.html#getdefaultentrypointaddress). +- `useSimulation?: boolean` -- whether or not to simulate user operations before sending them to ensure they don't revert. + +- `gasManagerConfig?: GasManagerConfig` -- if you want to use alchemy's gas manager. + + - `policyId: string` -- the policy id of the gas manager you want to use. - `opts: SmartAccountProviderOpts | undefined` -- [optional] overrides on provider config variables having to do with fetching transaction receipts and fee computation. diff --git a/site/packages/aa-alchemy/utils/defineAlchemyChain.md b/site/packages/aa-alchemy/utils/defineAlchemyChain.md new file mode 100644 index 0000000000..d1762e4626 --- /dev/null +++ b/site/packages/aa-alchemy/utils/defineAlchemyChain.md @@ -0,0 +1,49 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: Utils • SupportedChains + - - meta + - name: description + content: Overview of the SupportedChains util method in aa-alchemy + - - meta + - property: og:description + content: Overview of the SupportedChains util method in aa-alchemy +next: + text: aa-accounts +--- + +# defineAlchemyChain + +`defineAlchemyChain` allows you to extend a `viem` chain if it is not configured with Alchemy's RPC Url. This is useful `@alchemy/aa-core` does not export a chain you can use with the Alchemy Clieny. + +## Usage + +::: code-group + +```ts [example.ts] +import { defineAlchemyChain } from "@alchemy/aa-alchemy"; +import { mainnet } from "viem"; + +// eth mainnet +const mainnetWithAlch = defineAlchemyChain({ + chain: mainnet, + rpcBaseUrl: "https://eth-mainnet.g.alchemy.com/v2/", +}); +``` + +::: + +## Returns + +### `Chain` + +the associated viem `Chain` object. + +## Parameters + +### `config: AlchemyChainConfig` + +- `chain: Chain` -- the chain you want to extend +- `rpcBaseUrl: string` -- the Alchemy RPC Url for the chain (without the API Key appended) diff --git a/site/packages/aa-alchemy/utils/introduction.md b/site/packages/aa-alchemy/utils/introduction.md deleted file mode 100644 index 340ce52edc..0000000000 --- a/site/packages/aa-alchemy/utils/introduction.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: Utils - - - meta - - name: description - content: Overview of the Utils methods in aa-alchemy - - - meta - - property: og:description - content: Overview of the Utils methods in aa-alchemy ---- - -# Utils - -`aa-alchemy` offers util methods to speed up your development with `AlchemyProvider`. - -Notable util methods include: - -1. [`SupportedChains`](/packages/aa-alchemy/utils/supportedChains) -- calls `eth_estimateUserOperationGas` and returns the result. - -## Usage - -::: code-group - -```ts [example.ts] -import { SupportedChains } from "@alchemy/aa-alchemy"; - -// eth mainnet -const mainnet = SupportedChains.get(1); - -// bsc is unsupported, so the variable will be undefined -const bsc = SupportedChains.get(56); -``` - -::: diff --git a/site/packages/aa-alchemy/utils/supportedChains.md b/site/packages/aa-alchemy/utils/supportedChains.md deleted file mode 100644 index 1615154f75..0000000000 --- a/site/packages/aa-alchemy/utils/supportedChains.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: Utils • SupportedChains - - - meta - - name: description - content: Overview of the SupportedChains util method in aa-alchemy - - - meta - - property: og:description - content: Overview of the SupportedChains util method in aa-alchemy -next: - text: aa-accounts ---- - -# SupportedChains - -`SupportedChains` provides a mapping from chain ID to a viem `Chain` object for all chains supported by the Alchemy RPC. This util includes mappings for both supported mainnets and supported testnets. - -## Usage - -::: code-group - -```ts [example.ts] -import { SupportedChains } from "@alchemy/aa-alchemy"; - -// eth mainnet -const mainnet = SupportedChains.get(1); - -// bsc mainnet is unsupported, so the variable will be undefined -const bsc = SupportedChains.get(56); -``` - -::: - -## Returns - -### `Chain` - -the associated viem `Chain` object. - -## Parameters - -### `chainId: number` -- the struct containig UserOperation fields, where each field may be asychronously returned from the middleware used to generate its final value. diff --git a/site/packages/aa-core/accounts/constructor.md b/site/packages/aa-core/accounts/constructor.md deleted file mode 100644 index 6eba1dff64..0000000000 --- a/site/packages/aa-core/accounts/constructor.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: SimpleSmartContractAccount • constructor - - - meta - - name: description - content: Overview of the constructor method on SimpleSmartContractAccount in aa-core - - - meta - - property: og:description - content: Overview of the constructor method on SimpleSmartContractAccount in aa-core -next: - text: Required Methods ---- - -# constructor - -To initialize a `SimpleSmartContractAccount`, you must provide a set of parameters detailed below. - -Note that `BaseSmartContractAccount` is an abstract class, and so cannot be initialized even though it has a constructor. - -## Usage - -::: code-group - -```ts [example.ts] -import { - LocalAccountSigner, - SimpleSmartContractAccount, - getDefaultEntryPointAddress, - getDefaultSimpleAccountFactoryAddress, - type SmartAccountSigner, -} from "@alchemy/aa-core"; -import { sepolia } from "@alchemy/aa-core"; - -const PRIVATE_KEY = "0xYourEOAPrivateKey"; -const eoaSigner: SmartAccountSigner = - LocalAccountSigner.privateKeyToAccountSigner(`0x${PRIVATE_KEY}`); - -// instantiates using every possible parameter, as a reference -export const account = new SimpleSmartContractAccount({ - rpcClient: "ALCHEMY_RPC_URL", - chain: sepolia, - factoryAddress: getDefaultSimpleAccountFactoryAddress(sepolia), - owner: eoaSigner, - entryPointAddress: getDefaultEntryPointAddress(sepolia), - accountAddress: "0xYourSmartAccountAddress", - index: 0n, -}); -``` - -::: - -## Returns - -### `SimpleSmartContractAccount` - -A new instance of a `SimpleSmartContractAccount`. - -## Parameters - -### `params: SimpleSmartAccountParams` - -- `rpcClient: string | BundlerClient` -- a JSON-RPC URL, or a viem Client that supports ERC-4337 methods and Viem public actions. See [createBundlerClient](/packages/aa-core/bundler-client/index.md). - -- `chain: Chain` -- the chain on which to create the provider. - -- `factoryAddress: Address` -- the factory address for the smart account implementation, which is required for creating the account if not already deployed. - -- `owner: SmartAccountSigner` -- the owner EOA address responsible for signing user operations on behalf of the smart account. - -- `entryPointAddress: Address | undefined` -- [optional] entry point contract address. If not provided, the entry point contract address for the provider is the connected account's entry point contract, or if not connected, falls back to the default entry point contract for the chain. See [getDefaultEntryPointAddress](/packages/aa-core/utils/getDefaultEntryPointAddress.html#getdefaultentrypointaddress). - -- `accountAddress: Address | undefined` -- [optional] a smart account address override that this object will manage instead of generating its own. - -- `index: bigint | undefined` -- [optional] additional salt value used when creating the smart account. Allows for a one-to-many creation from one owner address to many smart account addresses. See [stringToIndex](/packages/aa-core/utils/stringToIndex.html) for an easy way to convert a string, such as an email in your database, to salt. diff --git a/site/packages/aa-core/accounts/index.md b/site/packages/aa-core/accounts/index.md new file mode 100644 index 0000000000..7309534261 --- /dev/null +++ b/site/packages/aa-core/accounts/index.md @@ -0,0 +1,86 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: SmartContractAccount + - - meta + - name: description + content: Overview of SmartContractAccount interface exported by aa-core accounts + - - meta + - property: og:description + content: Overview of SmartContractAccount interface exported by aa-core accounts +prev: + text: SmartAccountProvider +--- + +# SmartContractAccount + +The `SmartContractAccount` interface is an extension of viem's [`CustomAccount`](https://viem.sh/docs/accounts/custom) with additional methods used for Account Abstraction. It is meant to be used in conjunction with a [`SmartAccountClient`](/packages/aa-core/smart-account-client/). + +## Custom Smart Contract Accounts + +If you have your own smart contract that you'd like to interact with, then you can use the `toSmartContractAccount` method to create a `SmartContractAccount` instance. + +### Usage + +```ts +import { toSmartContractAccount } from "@alchemy/aa-core"; +import { sepolia } from "viem/chains"; + +const myAccount = await toSmartContractAccount({ + /// REQUIRED PARAMS /// + source: "MyAccount", + transport: http("RPC_URL"), + chain: sepolia, + // The entrypoint contract that your account is compatible with + entrypointAddress: "0x1234...", + // This should return a concatenation of your `factoryAddress` and the `callData` for your factory's create account method + getAccountInitCode: () => "0x{factoryAddress}{callData}", + // an invalid signature that doesn't cause your account to revert during validation + getDummySignature: () => "0x1234...", + // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method + encodeExecute: (uo)=> "...." + signMessage: ({message}: SignableMessage) => "0x...", + signTypedData: (typedData) => "0x000", + + /// OPTIONAL PARAMS /// + // if you already know your account's address, pass that in here to avoid generating a new counterfactual + accountAddress?: Address, + // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method + encodeBatchExecute: (uos) => "0x...", + // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here + signUserOperationHash: (hash) => "0x...", + // allows you to define the calldata for upgrading your account + encodeUpgradeToAndCall: (params) => "0x...", +}); +``` + +### Returns + +#### `SmartContractAccount` + +```ts +export type SmartContractAccount = + LocalAccount & { + source: Name; + getDummySignature: () => Hex; + encodeExecute: (tx: Tx) => Promise; + encodeBatchExecute: (txs: Tx[]) => Promise; + signUserOperationHash: (uoHash: Hex) => Promise; + signMessageWith6492: (params: { message: SignableMessage }) => Promise; + signTypedDataWith6492: < + const typedData extends TypedData | Record, + primaryType extends keyof typedData | "EIP712Domain" = keyof typedData + >( + typedDataDefinition: TypedDataDefinition + ) => Promise; + encodeUpgradeToAndCall: (params: UpgradeToAndCallParams) => Promise; + getNonce(): Promise; + getInitCode: () => Promise; + isAccountDeployed: () => Promise; + getFactoryAddress: () => Address; + getEntrypoint: () => Address; + getImplementationAddress: () => Promise<"0x0" | Address>; + }; +``` diff --git a/site/packages/aa-core/accounts/introduction.md b/site/packages/aa-core/accounts/introduction.md deleted file mode 100644 index 2424b62f08..0000000000 --- a/site/packages/aa-core/accounts/introduction.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: ISmartContractAccount - - - meta - - name: description - content: Overview of ISmartContractAccount class exported by aa-core accounts - - - meta - - property: og:description - content: Overview of ISmartContractAccount class exported by aa-core accounts -prev: - text: SmartAccountProvider ---- - -# ISmartContractAccount - -`ISmartContractAccount` defines how you would interact with your Smart Contract Account. - -::: details ISmartContractAccount -<<< @/../packages/core/src/account/types.ts -::: - -## BaseSmartContractAccount - -The `BaseSmartContractAccount` is an abstract class that provides the base implementation the `ISmartContractAccount` interface to provide the ease of creating your own Smart Contract Account. Any class that extends and implements `BaseSmartContractAccount` may also expose additional methods that support its connecting [SmartAccountProvider](/packages/aa-core/smart-account-client/index). - -`BaseSmartContractAccount` contains abstract methods that requires implementation from any class that extends the class. - -::: details BaseSmartContractAccount -<<< @/../packages/core/src/account/base.ts -::: - -### Required Methods To Implement - -- [`getDummySignature`](/packages/aa-core/accounts/required/getDummySignature) -- this method returns a signature that will not `revert` during validation. It does not have to pass validation, just not cause the contract to revert. This is required for gas estimation so that the gas estimate are accurate. -- [`encodeExecute`](/packages/aa-core/accounts/required/encodeExecute) -- this method returns the abi encoded function data for a call to your contract's `execute` method -- [`signMessage`](/packages/aa-core/accounts/required/signMessage) -- this method returns an [EIP-191](https://eips.ethereum.org/EIPS/eip-191) compliant message and is used to sign UO Hashes -- [`getAccountInitCode`](/packages/aa-core/accounts/required/getAccountInitCode) -- this method returns the account init code that will be used to create an account if one does not exist. Usually this is the concatenation of the account's factory address and the abi encoded function data of the account factory's `createAccount` method. - -### Optional Methods To Implement - -In addition, it provides other optional methods that need to be implemented by the subclass in order to support functionalities such as: - -- [`signTypedData`](/packages/aa-core/accounts/optional/signTypedData) -- Signs typed data per [ERC-712](https://eips.ethereum.org/EIPS/eip-712) -- [`signMessageWith6492`](/packages/aa-core/accounts/optional/signMessageWith6492) -- Wraps the result of `signMessage` as per [EIP-6492](https://eips.ethereum.org/EIPS/eip-6492) for signing the message for deployed smart accounts, as well as undeployed accounts -- [`signTypedDataWith6492`](/packages/aa-core/accounts/optional/signTypedDataWith6492) -- Similar to the signMessageWith6492 method above, this method wraps the result of `signTypedData` as per [EIP-6492](https://eips.ethereum.org/EIPS/eip-6492) -- [`encodeBatchExecute`](/packages/aa-core/accounts/optional/encodeBatchExecute) -- If your contract does support batching, encodes a list of transactions into the call data that will be passed to your contract's `batchExecute` method. - -**Note**: `signMessageWith6492` and `signTypedDataWith6492` methods are already implemented on `BaseSmartContractAccount`, so any class that extends and implements `BaseSmartContractAccount` may call this method. - -## SimpleSmartContractAccount - -[SimpleSmartContractAccount](packages/core/src/account/simple.ts) a minimal implementation version of `BaseSmartContractAccount`. It implements the required abstraction methods in `BaseSmartContractAccount`, and additionally implements the optional methods indicated above. - -**Note:** While `SimpleSmartContractAccount` fully implements the `ISmartContractAccount` interface for use as your basic smart account, we recommend using our [Light Account](/smart-accounts/accounts/guides/light-account) as it is a simple, yet more secure, and cost-effective smart account implementation. - -## Usage - -::: code-group - -<<< @/snippets/account-core.ts - -<<< @/snippets/account-alchemy.ts - -<<< @/snippets/account-ethers.ts - -::: diff --git a/site/packages/aa-core/accounts/optional/encodeBatchExecute.md b/site/packages/aa-core/accounts/optional/encodeBatchExecute.md deleted file mode 100644 index 4da7bd9766..0000000000 --- a/site/packages/aa-core/accounts/optional/encodeBatchExecute.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: encodeBatchExecute - - - meta - - name: description - content: Overview of the encodeBatchExecute method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the encodeBatchExecute method on BaseSmartContractAccount ---- - -# encodeBatchExecute - -**NOTE**: Not all accounts support batching. - -If your contract does, this method should encode a list of transactions into the call data that will be passed to your contract's `batchExecute` method. - -## Example Implementation - -::: code-group - -```ts [example.ts] -import { SimpleAccountAbi } from "./simple-account-abi"; -// [!code focus:99] -async encodeBatchExecute( - txs: BatchUserOperationCallData -): Promise<`0x${string}`> { - const [targets, datas] = txs.reduce( - (accum, curr) => { - accum[0].push(curr.target); - accum[1].push(curr.data); - - return accum; - }, - [[], []] as [Address[], Hex[]] - ); - - return encodeFunctionData({ - abi: SimpleAccountAbi, - functionName: "executeBatch", - args: [targets, datas], - }); -} -``` - -<<< @/snippets/simple-account-abi.ts -::: - -## Returns - -### `Promise` - -The promise containing the abi encoded function data for a call to your contract's `batchExecute` method - -## Parameters - -### `txs`: `BatchUserOperationCallData = UserOperationCallData[]` - -An array of objects containing the target, value, and data for each transaction as `UserOperationCallData` with following fields: - -- `target`: `string` - The address receiving the call data. Equivalent to `to` in a normal transaction. -- `value`: `bigint` - Optionally, the amount of native token to send. Equivalent to `value` in a normal transaction. -- `data`: `string` - The call data or "0x" if empty. Equivalent to `data` in a normal transaction. diff --git a/site/packages/aa-core/accounts/optional/signMessageWith6492.md b/site/packages/aa-core/accounts/optional/signMessageWith6492.md deleted file mode 100644 index 17e8111819..0000000000 --- a/site/packages/aa-core/accounts/optional/signMessageWith6492.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: signMessageWith6492 - - - meta - - name: description - content: Overview of the signMessageWith6492 method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the signMessageWith6492 method on BaseSmartContractAccount ---- - -# signMessageWith6492 - -This method wraps the result of `signMessage` as per [EIP-6492](https://eips.ethereum.org/EIPS/eip-6492) for signing the message for deployed smart accounts, as well as undeployed accounts (counterfactual addresses). - -**Note**: This method is already implemented on `BaseSmartContractAccount`, so any class that extends and implements `BaseSmartContractAccount` may call this method. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const signedMsgWrappedWith6492 = await provider.signMessageWith6492("msg"); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -A promise containing the signature of the message, additionally wrapped in EIP-6492 format if the account is undeployed - -## Parameters - -### `msg: string | Uint8Array | Hex` - -The message to sign diff --git a/site/packages/aa-core/accounts/optional/signTypedData.md b/site/packages/aa-core/accounts/optional/signTypedData.md deleted file mode 100644 index adff6f16f1..0000000000 --- a/site/packages/aa-core/accounts/optional/signTypedData.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: signTypedData - - - meta - - name: description - content: Overview of the signTypedData method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the signTypedData method on BaseSmartContractAccount ---- - -# signTypedData - -If your contract supports signing and verifying typed data, you should implement this method that returns the signed typed data object as per [ERC-712](https://eips.ethereum.org/EIPS/eip-712). - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -// sign typed data -const signedTypedData = provider.signTypedData({ - domain: { - name: "Ether Mail", - version: "1", - chainId: 1, - verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", - }, - types: { - Person: [ - { name: "name", type: "string" }, - { name: "wallet", type: "address" }, - ], - Mail: [ - { name: "from", type: "Person" }, - { name: "to", type: "Person" }, - { name: "contents", type: "string" }, - ], - }, - primaryType: "Mail", - message: { - from: { - name: "Cow", - wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", - }, - to: { - name: "Bob", - wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", - }, - contents: "Hello, Bob!", - }, -}); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -### Returns - -### `Promise` - -A promise containing the signature of the typed data. - -## Parameters - -### `SignTypedDataParams` - -The typed data to sign - -- `domain: TypedDataDomain` - The typed data domain -- `types: Object` -- The type definitions for the typed data -- `primaryType: inferred String` -- The primary type to extract from types and use in value -- `message: inferred from types & primaryType` -- The typed message object diff --git a/site/packages/aa-core/accounts/optional/signTypedDataWith6492.md b/site/packages/aa-core/accounts/optional/signTypedDataWith6492.md deleted file mode 100644 index 702372bf54..0000000000 --- a/site/packages/aa-core/accounts/optional/signTypedDataWith6492.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: signTypedDataWith6492 - - - meta - - name: description - content: Overview of the signTypedDataWith6492 method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the signTypedDataWith6492 method on BaseSmartContractAccount ---- - -# signTypedDataWith6492 - -Similar to the signMessageWith6492 method above, this method wraps the result of `signTypedData` as per [EIP-6492](https://eips.ethereum.org/EIPS/eip-6492) to support signing the typed data for deployed smart accounts, as well as undeployed accounts (counterfactual addresses). - -**Note**: This method is already implemented on `BaseSmartContractAccount`, so any class that extends and implements `BaseSmartContractAccount` may call this method. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const signedTypedDataWrappedWith6492 = provider.signTypedDataWith6492({ - domain: { - name: "Ether Mail", - version: "1", - chainId: 1, - verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", - }, - types: { - Person: [ - { name: "name", type: "string" }, - { name: "wallet", type: "address" }, - ], - Mail: [ - { name: "from", type: "Person" }, - { name: "to", type: "Person" }, - { name: "contents", type: "string" }, - ], - }, - primaryType: "Mail", - message: { - from: { - name: "Cow", - wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", - }, - to: { - name: "Bob", - wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", - }, - contents: "Hello, Bob!", - }, -}); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -A promise containing the signature of the message, additionally wrapped in EIP-6492 format if the account is undeployed - -## Parameters - -### `params: SignTypedDataParams` - -The typed data to sign - -- `domain: TypedDataDomain` -- The typed data domain -- `types: Object` -- The type definitions for the typed data -- `primaryType: inferred String` -- The primary type to extract from types and use in value -- `message: inferred from types & primaryType` -- The typed message object diff --git a/site/packages/aa-core/accounts/optional/signUserOperationHash.md b/site/packages/aa-core/accounts/optional/signUserOperationHash.md deleted file mode 100644 index 422d63b272..0000000000 --- a/site/packages/aa-core/accounts/optional/signUserOperationHash.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: signUserOperationHash - - - meta - - name: description - content: Overview of the signUserOperationHash method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the signUserOperationHash method on BaseSmartContractAccount -next: - text: Other Methods ---- - -# signUserOperationHash - -If your account handles [ERC-1271 signatures](https://eips.ethereum.org/EIPS/eip-1271) of `personal_sign` differently than it does user operations, you can implement your additional way to sign the user operation. - -**Note**: This method is already implemented on `BaseSmartContractAccount` defaulting to using the [`signMessage`](/packages/aa-core/accounts/required/signMessage.md) method. So any class that extends and implements `BaseSmartContractAccount` may call this method. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const signature = await provider.account.signUserOperationHash( - `` -); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -The signature of the UserOperation - -## Parameters - -### `uoHash: Hash` - -The hash of the UserOperation to sign diff --git a/site/packages/aa-core/accounts/other/getAddress.md b/site/packages/aa-core/accounts/other/getAddress.md deleted file mode 100644 index f1285e0f87..0000000000 --- a/site/packages/aa-core/accounts/other/getAddress.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getAddress - - - meta - - name: description - content: Overview of the getAddress method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getAddress method on BaseSmartContractAccount ---- - -# getAddress - -Returns the address of the account. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const address = await provider.account.getAddress(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -A promise that resolves to the address of the account diff --git a/site/packages/aa-core/accounts/other/getDeploymentState.md b/site/packages/aa-core/accounts/other/getDeploymentState.md deleted file mode 100644 index 4678a5d7de..0000000000 --- a/site/packages/aa-core/accounts/other/getDeploymentState.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getDeploymentState - - - meta - - name: description - content: Overview of the getDeploymentState method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getDeploymentState method on BaseSmartContractAccount ---- - -# getDeploymentState - -Returns the current deployment state as an enum `DeploymentState` (`UNDEFINED`, `NOT_DEPLOYED`, or `DEPLOYED`) for the account - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const deploymentState = await provider.account.getDeploymentState(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -A promise that resolves to the current deployment state as an enum `DeploymentState` (`UNDEFINED`, `NOT_DEPLOYED`, or `DEPLOYED`) for the account diff --git a/site/packages/aa-core/accounts/other/getEntryPointAddress.md b/site/packages/aa-core/accounts/other/getEntryPointAddress.md deleted file mode 100644 index f0122fd5cf..0000000000 --- a/site/packages/aa-core/accounts/other/getEntryPointAddress.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getEntryPointAddress - - - meta - - name: description - content: Overview of the getEntryPointAddress method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getEntryPointAddress method on BaseSmartContractAccount -next: - text: SmartAccountSigner ---- - -# getEntryPointAddress - -Returns the EntryPoint contract address for the account. - -Refer to [the reference docs](https://docs.alchemy.com/reference/eth-supportedentrypoints/?a=ak-docs) for all the supported entrypoints when using Alchemy as your RPC provider. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const entryPointAddress = await provider.account.getEntryPointAddress(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Address` - -The address of the EntryPoint contract diff --git a/site/packages/aa-core/accounts/other/getFactoryAddress.md b/site/packages/aa-core/accounts/other/getFactoryAddress.md deleted file mode 100644 index 08804beb22..0000000000 --- a/site/packages/aa-core/accounts/other/getFactoryAddress.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getFactoryAddress - - - meta - - name: description - content: Overview of the getFactoryAddress method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getFactoryAddress method on BaseSmartContractAccount ---- - -# getFactoryAddress - -Returns the account factory address for the account. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const factoryAddress = await provider.account.getFactoryAddress(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Address` - -The address of the account factory contract diff --git a/site/packages/aa-core/accounts/other/getNonce.md b/site/packages/aa-core/accounts/other/getNonce.md deleted file mode 100644 index dc3e7cb2b0..0000000000 --- a/site/packages/aa-core/accounts/other/getNonce.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getNonce - - - meta - - name: description - content: Overview of the getNonce method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getNonce method on BaseSmartContractAccount ---- - -# getNonce - -Returns the nonce of the account. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const address = await provider.account.getNonce(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -A promise that resolves to the current nonce of the account diff --git a/site/packages/aa-core/accounts/other/getOwner.md b/site/packages/aa-core/accounts/other/getOwner.md deleted file mode 100644 index 45a4e4f890..0000000000 --- a/site/packages/aa-core/accounts/other/getOwner.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getOwner - - - meta - - name: description - content: Overview of the getOwner method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getOwner method on BaseSmartContractAccount ---- - -# getOwner - -Returns the `SmartAccountSigner` that represents the current owner for the account. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const ownerSigner = await provider.account.getOwner(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `SmartAccountSigner | undefined` - -The `SmartAccountSigner` object that represents the current owner for the account diff --git a/site/packages/aa-core/accounts/other/isAccountDeployed.md b/site/packages/aa-core/accounts/other/isAccountDeployed.md deleted file mode 100644 index 92f8c17bc5..0000000000 --- a/site/packages/aa-core/accounts/other/isAccountDeployed.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: isAccountDeployed - - - meta - - name: description - content: Overview of the isAccountDeployed method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the isAccountDeployed method on BaseSmartContractAccount ---- - -# isAccountDeployed - -Returns a boolean flag indicating whether the account has been deployed or not. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const isAccountDeployed = await provider.account.isAccountDeployed(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -A promise that resolves the boolean flag indicating whether the account has been deployed or not diff --git a/site/packages/aa-core/accounts/required/encodeExecute.md b/site/packages/aa-core/accounts/required/encodeExecute.md deleted file mode 100644 index 5982bfdaec..0000000000 --- a/site/packages/aa-core/accounts/required/encodeExecute.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: encodeExecute - - - meta - - name: description - content: Overview of the encodeExecute abstract method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the encodeExecute abstract method on BaseSmartContractAccount -next: - text: Optional Methods ---- - -# encodeExecute - -Returns the abi encoded function data for a call to your contract's `execute` method. - -## Example Implementation - -::: code-group - -```ts [example.ts] -import { SimpleAccountAbi } from "./simple-account-abi"; -// [!code focus:99] -async encodeExecute( - target: Hex, - value: bigint, - data: Hex -): Promise<`0x${string}`> { - return encodeFunctionData({ - abi: SimpleAccountAbi, - functionName: "execute", - args: [target, value, data], - }); -} -``` - -<<< @/snippets/simple-account-abi.ts -::: - -## Returns - -### `Promise` - -The promise containing the abi encoded function data for a call to your contract's `execute` method - -## Parameters - -`UserOperationCallData` fields: - -- `target`: `string` - The address receiving the call data. Equivalent to `to` in a normal transaction. -- `value`: `bigint` - Optionally, the amount of native token to send. Equivalent to `value` in a normal transaction. -- `data`: `string` - The call data or "0x" if empty. Equivalent to `data` in a normal transaction. diff --git a/site/packages/aa-core/accounts/required/getAccountInitCode.md b/site/packages/aa-core/accounts/required/getAccountInitCode.md deleted file mode 100644 index ee01aacb50..0000000000 --- a/site/packages/aa-core/accounts/required/getAccountInitCode.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getAccountInitCode - - - meta - - name: description - content: Overview of the getAccountInitCode abstract method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getAccountInitCode abstract method on BaseSmartContractAccount ---- - -# getAccountInitCode - -This method should return the init code that will be used to create an account if one does not exist. - -This is [expected](https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/core/SenderCreator.sol#L15) to be the concatenation of the account's factory address and the abi encoded function data of the account factory's `createAccount` method. - -**Reference:** - -- [EIP-4337: First-time account creation](https://eips.ethereum.org/EIPS/eip-4337#first-time-account-creation) -- [EntryPoint spec](https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/core/SenderCreator.sol#L15) - -## Example Implementation - -::: code-group - -```ts [example.ts] -// [!code focus:99] -async getAccountInitCode(): Promise<`0x${string}`> { - return concatHex([ - this.factoryAddress, - encodeFunctionData({ - abi: SimpleAccountFactoryAbi, - functionName: "createAccount", - args: [await this.owner.getAddress(), this.index], - }), - ]); -} -``` - -::: - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const initCode = await provider.getAccountInitCode(); -const factoryAddress = `0x${initCode.substring(2, 42)}` as Address; -const factoryCalldata = `0x${initCode.substring(42)}` as Hex; -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Promise` - -The promise containing the init code for the account diff --git a/site/packages/aa-core/accounts/required/getDummySignature.md b/site/packages/aa-core/accounts/required/getDummySignature.md deleted file mode 100644 index fed4a33bde..0000000000 --- a/site/packages/aa-core/accounts/required/getDummySignature.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: getDummySignature - - - meta - - name: description - content: Overview of the getDummySignature abstract method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the getDummySignature abstract method on BaseSmartContractAccount ---- - -# getDummySignature - -This method should return a signature that will not `revert` during validation. It does not have to pass validation, just not cause the contract to revert. This is required for gas estimation so that the gas estimate are accurate. - -Please note that the dummy signature is specific to the account implementation and the example dummy signature below does not generalize to all account types. This is an example dummy signature for SimpleAccount account implementation. For other account implementations, you may need to provide a different dummy signature. - -**Reference:** - -- [Our Bundler API docs](https://docs.alchemy.com/reference/eth-estimateuseroperationgas#dummy-signature-for-simpleaccount/?a=ak-docs) -- [EIP-4337: `eth_estimateUserOperationGas`](https://eips.ethereum.org/EIPS/eip-4337#-eth_estimateuseroperationgas) - -## Example Implementation - -::: code-group - -```ts [example.ts] -// [!code focus:99] -getDummySignature(): `0x${string}` { - return "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; -} -``` - -::: - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const dummySignature = await provider.getDummySignature(); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -## Returns - -### `Hash` - -A dummy signature that doesn't cause the account to revert during estimation diff --git a/site/packages/aa-core/accounts/required/signMessage.md b/site/packages/aa-core/accounts/required/signMessage.md deleted file mode 100644 index a1a073eead..0000000000 --- a/site/packages/aa-core/accounts/required/signMessage.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -outline: deep -head: - - - meta - - property: og:title - content: signMessage - - - meta - - name: description - content: Overview of the signMessage abstract method on BaseSmartContractAccount - - - meta - - property: og:description - content: Overview of the signMessage abstract method on BaseSmartContractAccount ---- - -# signMessage - -This method should return an [ERC-191](https://eips.ethereum.org/EIPS/eip-191) compliant message and is used to sign `UserOperation` hashes. - -## Usage - -::: code-group - -```ts [example.ts] -import { smartAccountClient } from "./smartAccountClient"; -// [!code focus:99] -const signedMessage = await provider.signMessage("msg"); -``` - -<<< @/snippets/smartAccountClient.ts - -::: - -### Returns - -### `Promise` - -A promise containing the signature of the message - -## Parameters - -### `msg`: `string | Uint8Array | Hex` - -The message to sign diff --git a/site/packages/aa-core/bundler-client/index.md b/site/packages/aa-core/bundler-client/index.md index c9fb95b235..8f87384fd3 100644 --- a/site/packages/aa-core/bundler-client/index.md +++ b/site/packages/aa-core/bundler-client/index.md @@ -19,7 +19,9 @@ The `BundlerClient` is an extension of viem's [`PublicClient`](https://viem.sh/d ## Import ```ts -import { createSmartAccountClient } from "@alchemy/aa-core"; +import { createBundlerClient } from "@alchemy/aa-core"; +// OR +import { createBundlerClientFromExisting } from "@alchemy/aa-core"; ``` ## Usage diff --git a/site/packages/aa-core/index.md b/site/packages/aa-core/index.md index 06841407d6..91facf9ad2 100644 --- a/site/packages/aa-core/index.md +++ b/site/packages/aa-core/index.md @@ -16,11 +16,11 @@ next: # `@alchemy/aa-core` -This package contains the core interfaces and components for interacting with 4337 infrastructure. The primary interfaces that it exports are the `SmartAccountProvider` and `BaseSmartContractAccount`. +This package contains the core interfaces and components for interacting with 4337 infrastructure. The primary interfaces that it exports are the `SmartAccountClient` and `SmartContractAccount`. -The `SmartAccountProvider` is an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compliant Provider that wraps JSON RPC methods and some Wallet Methods (signing, sendTransaction, etc). With this Provider, you can submit User Operations to RPC providers, estimate gas, configure a Paymaster, send standard JSON RPC requests, and more. It is not opinionated about which RPC provider you are using and is configurable to work with any RPC provider. Because it implements EIP-1193, it can be used with any web3 library. +The `SmartAccountClient` is an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compliant Provider that wraps JSON RPC methods. With this Client, you can submit User Operations to RPC providers, estimate gas, configure a Paymaster, send standard JSON RPC requests, and more. It is not opinionated about which RPC provider you are using and is configurable to work with any RPC provider. Because it implements EIP-1193, it can be used with any web3 library. -The `BaseSmartContractAccount` interface defines how you would interact with your Smart Contract Account. Any class that extends `BaseSmartContractAccount` may also expose additional methods that allow its connecting `SmartAccountProvider` to provide ergonic utilities for building and submitting `User Operation`s. +The `SmartContractAccount` interface defines how you would interact with your Smart Contract Account. Any object that extends `SmartContractAccount` may also expose additional methods that allow its use with a `SmartAccountClient` to provide ergonic utilities for building and submitting `User Operation`s. ## Getting Started @@ -42,7 +42,7 @@ pnpm i @alchemy/aa-core ::: -Then, you can create a provider like so: +Then, you can create a client like so: ::: code-group <<< @/snippets/core-provider.ts ::: diff --git a/site/packages/aa-core/smart-account-client/index.md b/site/packages/aa-core/smart-account-client/index.md index c15547e1e4..f9ca8287c9 100644 --- a/site/packages/aa-core/smart-account-client/index.md +++ b/site/packages/aa-core/smart-account-client/index.md @@ -22,6 +22,8 @@ The `SmartAccountClient` is also an extension of the `viem` [`Client`](https://v ```ts import { createSmartAccountClient } from "@alchemy/aa-core"; +// OR +import { createSmartAccountClientFromExisting } from "@alchemy/aa-core"; ``` ## Usage diff --git a/site/packages/aa-ethers/account-signer/getPublicErc4337Client.md b/site/packages/aa-ethers/account-signer/getBundlerClient.md similarity index 100% rename from site/packages/aa-ethers/account-signer/getPublicErc4337Client.md rename to site/packages/aa-ethers/account-signer/getBundlerClient.md diff --git a/site/packages/aa-ethers/provider-adapter/connectToAccount.md b/site/packages/aa-ethers/provider-adapter/connectToAccount.md index 48ad072f89..415d78b61a 100644 --- a/site/packages/aa-ethers/provider-adapter/connectToAccount.md +++ b/site/packages/aa-ethers/provider-adapter/connectToAccount.md @@ -26,12 +26,12 @@ head: ## Returns -### `AccountSigner` +### `AccountSigner` -A new instance of a connected `AccountSigner`for any implementation class of `ISmartContractAccount` +A new instance of a connected `AccountSigner`for any implementation class of `SmartContractAccount` ## Parameters -### `fn: (rpcClient: BundlerClient) => TAccount extends ISmartContractAccount` +### `account: TAccount extends SmartContractAccount` A function that takes in the provider's rpcClient and returns an AccountSigner diff --git a/site/packages/aa-ethers/provider-adapter/getPublicErc4337Client.md b/site/packages/aa-ethers/provider-adapter/getBundlerClient.md similarity index 100% rename from site/packages/aa-ethers/provider-adapter/getPublicErc4337Client.md rename to site/packages/aa-ethers/provider-adapter/getBundlerClient.md diff --git a/site/packages/aa-ethers/provider-adapter/introduction.md b/site/packages/aa-ethers/provider-adapter/introduction.md index e1f2f894b4..86e87f32c9 100644 --- a/site/packages/aa-ethers/provider-adapter/introduction.md +++ b/site/packages/aa-ethers/provider-adapter/introduction.md @@ -35,6 +35,8 @@ import { } from "@alchemy/aa-accounts"; import { LocalAccountSigner, type SmartAccountSigner } from "@alchemy/aa-core"; import { polygonMumbai } from "@alchemy/aa-core"; +import { http } from "viem"; + // [!code focus:99] // EIP-1193 compliant requests const chainId = await provider.send("eth_chainId", []); @@ -47,13 +49,11 @@ const owner: SmartAccountSigner = LocalAccountSigner.mnemonicToAccountSigner( process.env.YOUR_OWNER_MNEMONIC! ); const signer = provider.connectToAccount( - (rpcClient) => - new LightSmartContractAccount({ - chain: polygonMumbai, - factoryAddress: getDefaultLightAccountFactoryAddress(polygonMumbai), - rpcClient, - owner, - }) + await createLightAccount({ + chain, + transport: http("RPC_URL"), + owner, + }) ); ``` diff --git a/site/snippets/alchemy-smartAccountClient.ts b/site/snippets/alchemy-smartAccountClient.ts new file mode 100644 index 0000000000..25846a1a97 --- /dev/null +++ b/site/snippets/alchemy-smartAccountClient.ts @@ -0,0 +1,9 @@ +import { createAlchemySmartAccountClient } from "@alchemy/aa-alchemy"; +import { polygonMumbai } from "@alchemy/aa-core"; + +const chain = polygonMumbai; + +export const provider = createAlchemySmartAccountClient({ + apiKey: "demo", + chain, +}); diff --git a/site/snippets/enhanced-apis-example/nft.ts b/site/snippets/enhanced-apis-example/nft.ts index 171c05ff28..2f4820d046 100644 --- a/site/snippets/enhanced-apis-example/nft.ts +++ b/site/snippets/enhanced-apis-example/nft.ts @@ -1,5 +1,8 @@ -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { sepolia } from "@alchemy/aa-core"; +import { + alchemyEnhancedApiActions, + createLightAccountAlchemyClient, +} from "@alchemy/aa-alchemy"; +import { LocalAccountSigner, sepolia } from "@alchemy/aa-core"; import { Alchemy, Network } from "alchemy-sdk"; const alchemy = new Alchemy({ @@ -7,12 +10,15 @@ const alchemy = new Alchemy({ apiKey: "YOUR_API_KEY", }); -const provider = new AlchemyProvider({ - chain: sepolia, - apiKey: "YOUR_API_KEY", -}).withAlchemyEnhancedApis(alchemy); +const provider = ( + await createLightAccountAlchemyClient({ + chain: sepolia, + apiKey: "YOUR_API_KEY", + owner: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"), + }) +).extend(alchemyEnhancedApiActions(alchemy)); -const address = await provider.getAddress(); +const address = provider.getAddress(); // get all NFTs owned by the smart account export const nfts = provider.nft.getNftsForOwner(address); diff --git a/site/snippets/enhanced-apis-example/token.ts b/site/snippets/enhanced-apis-example/token.ts index bff9b3bb1c..0443bbfd32 100644 --- a/site/snippets/enhanced-apis-example/token.ts +++ b/site/snippets/enhanced-apis-example/token.ts @@ -1,5 +1,8 @@ -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { sepolia } from "@alchemy/aa-core"; +import { + alchemyEnhancedApiActions, + createLightAccountAlchemyClient, +} from "@alchemy/aa-alchemy"; +import { LocalAccountSigner, sepolia } from "@alchemy/aa-core"; import { Alchemy, Network } from "alchemy-sdk"; const alchemy = new Alchemy({ @@ -7,12 +10,15 @@ const alchemy = new Alchemy({ apiKey: "YOUR_API_KEY", }); -const provider = new AlchemyProvider({ - chain: sepolia, - apiKey: "YOUR_API_KEY", -}).withAlchemyEnhancedApis(alchemy); +const provider = ( + await createLightAccountAlchemyClient({ + chain: sepolia, + apiKey: "YOUR_API_KEY", + owner: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"), + }) +).extend(alchemyEnhancedApiActions(alchemy)); -const address = await provider.getAddress(); +const address = provider.getAddress(); // get all tokens owned by the smart account export const tokenBalances = provider.core.getTokenBalances(address); diff --git a/site/snippets/ethers-signer.ts b/site/snippets/ethers-signer.ts index bcd07733af..2ce20ffddc 100644 --- a/site/snippets/ethers-signer.ts +++ b/site/snippets/ethers-signer.ts @@ -1,12 +1,10 @@ -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createLightAccount } from "@alchemy/aa-accounts"; import { LocalAccountSigner, SmartAccountSigner, polygonMumbai, } from "@alchemy/aa-core"; +import { http } from "viem"; import { provider } from "./ethers-provider.js"; const owner: SmartAccountSigner = LocalAccountSigner.mnemonicToAccountSigner( @@ -17,11 +15,9 @@ const chain = polygonMumbai; // 2. Connect the provider to the smart account signer export const signer = provider.connectToAccount( - (rpcClient) => - new LightSmartContractAccount({ - chain, - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - owner, - }) + await createLightAccount({ + chain, + transport: http("RPC_URL"), + owner, + }) ); diff --git a/site/snippets/light-account-alchemy-provider.ts b/site/snippets/light-account-alchemy-client.ts similarity index 55% rename from site/snippets/light-account-alchemy-provider.ts rename to site/snippets/light-account-alchemy-client.ts index 2c2690ccec..f077d4cd29 100644 --- a/site/snippets/light-account-alchemy-provider.ts +++ b/site/snippets/light-account-alchemy-client.ts @@ -1,7 +1,7 @@ -import { createLightAccountAlchemyProvider } from "@alchemy/aa-alchemy"; +import { createLightAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { LocalAccountSigner, sepolia } from "@alchemy/aa-core"; -export const provider = createLightAccountAlchemyProvider({ +export const smartAccountClient = await createLightAccountAlchemyClient({ apiKey: "YOUR_API_KEY", chain: sepolia, owner: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"), diff --git a/site/snippets/light-account-client.ts b/site/snippets/light-account-client.ts new file mode 100644 index 0000000000..635f774040 --- /dev/null +++ b/site/snippets/light-account-client.ts @@ -0,0 +1,9 @@ +import { createLightAccountClient } from "@alchemy/aa-accounts"; +import { LocalAccountSigner, sepolia } from "@alchemy/aa-core"; +import { http } from "viem"; + +export const provider = createLightAccountClient({ + transport: http(`${sepolia.rpcUrls.alchemy.http[0]}/${"YOUR_API_KEY"}`), + chain: sepolia, + owner: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"), +}); diff --git a/site/snippets/light-account-provider.ts b/site/snippets/light-account-provider.ts deleted file mode 100644 index 5502427377..0000000000 --- a/site/snippets/light-account-provider.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createLightAccountProvider } from "@alchemy/aa-accounts"; -import { LocalAccountSigner, sepolia } from "@alchemy/aa-core"; - -export const provider = createLightAccountProvider({ - rpcProvider: `${sepolia.rpcUrls.alchemy.http[0]}/${"YOUR_API_KEY"}`, - chain: sepolia, - owner: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"), -}); diff --git a/site/snippets/privy.ts b/site/snippets/privy.ts index 5f1c04a3b5..0c85abc962 100644 --- a/site/snippets/privy.ts +++ b/site/snippets/privy.ts @@ -43,7 +43,7 @@ const privySigner: SmartAccountSigner = new WalletClientSigner( "privy" // signerType ); -// Create an Alchemy Provider with the smart account signer +// Create an Alchemy Smart Account Client with the smart account signer export const provider = new AlchemyProvider({ apiKey: "ALCHEMY_API_KEY", chain: sepolia, diff --git a/site/snippets/send-uo-example/calldata.ts b/site/snippets/send-uo-example/calldata.ts index 7e6602db78..1430ec8706 100644 --- a/site/snippets/send-uo-example/calldata.ts +++ b/site/snippets/send-uo-example/calldata.ts @@ -1,5 +1,5 @@ +import { smartAccountClient } from "snippets/light-account-alchemy-client"; import { encodeFunctionData } from "viem"; -import { connectedProvider } from "./connect-account.js"; // this is an example ABI for a contract with a "mint" function const AlchemyTokenAbi = [ @@ -15,5 +15,5 @@ const AlchemyTokenAbi = [ export const uoCallData = encodeFunctionData({ abi: AlchemyTokenAbi, functionName: "mint", - args: [await connectedProvider.getAddress()], + args: [smartAccountClient.getAddress()], }); diff --git a/site/snippets/send-uo-example/connect-account.ts b/site/snippets/send-uo-example/connect-account.ts deleted file mode 100644 index 6486ff4c9e..0000000000 --- a/site/snippets/send-uo-example/connect-account.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; -import { - LocalAccountSigner, - sepolia, - type SmartAccountSigner, -} from "@alchemy/aa-core"; -import { provider } from "./create-provider.js"; - -const chain = sepolia; -const PRIVATE_KEY = "0xYourEOAPrivateKey"; -const eoaSigner: SmartAccountSigner = - LocalAccountSigner.privateKeyToAccountSigner(`0x${PRIVATE_KEY}`); - -export const connectedProvider = provider.connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: eoaSigner, - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); diff --git a/site/snippets/send-uo-example/create-provider.ts b/site/snippets/send-uo-example/create-provider.ts deleted file mode 100644 index 9c36fac54c..0000000000 --- a/site/snippets/send-uo-example/create-provider.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { sepolia } from "@alchemy/aa-core"; - -export const provider = new AlchemyProvider({ - apiKey: "ALCHEMY_API_KEY", // replace with your Alchemy API Key - chain: sepolia, -}); diff --git a/site/snippets/send-uo-example/full-example.ts b/site/snippets/send-uo-example/full-example.ts index cbdddadcb8..ebb0c6dce0 100644 --- a/site/snippets/send-uo-example/full-example.ts +++ b/site/snippets/send-uo-example/full-example.ts @@ -1,8 +1,4 @@ -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; -import { AlchemyProvider } from "@alchemy/aa-alchemy"; +import { createLightAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { LocalAccountSigner, sepolia, @@ -10,25 +6,18 @@ import { } from "@alchemy/aa-core"; import { encodeFunctionData } from "viem"; -const provider = new AlchemyProvider({ - apiKey: "ALCHEMY_API_KEY", // replace with your Alchemy API Key - chain: sepolia, -}); - -const chain = sepolia; const PRIVATE_KEY = "0xYourEOAPrivateKey"; const eoaSigner: SmartAccountSigner = LocalAccountSigner.privateKeyToAccountSigner(`0x${PRIVATE_KEY}`); -const connectedProvider = provider.connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: eoaSigner, - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); +const client = await createLightAccountAlchemyClient({ + apiKey: "ALCHEMY_API_KEY", // replace with your Alchemy API Key + chain: sepolia, + owner: eoaSigner, + gasManagerConfig: { + policyId: "POLICY_ID", // replace with your policy id, get yours at https://dashboard.alchemy.com/ + }, +}); // this is an example ABI for a contract with a "mint" function const AlchemyTokenAbi = [ @@ -44,18 +33,16 @@ const AlchemyTokenAbi = [ export const uoCallData = encodeFunctionData({ abi: AlchemyTokenAbi, functionName: "mint", - args: [await connectedProvider.getAddress()], + args: [client.getAddress()], }); -connectedProvider.withAlchemyGasManager({ - policyId: "POLICY_ID", // replace with your policy id, get yours at https://dashboard.alchemy.com/ -}); - -const uo = await connectedProvider.sendUserOperation({ - target: "0xTargetAddress", - data: uoCallData, +const uo = await client.sendUserOperation({ + uo: { + target: "0xTargetAddress", + data: uoCallData, + }, }); -const txHash = await connectedProvider.waitForUserOperationTransaction(uo.hash); +const txHash = await client.waitForUserOperationTransaction(uo); console.log(txHash); diff --git a/site/snippets/send-uo-example/send-uo.ts b/site/snippets/send-uo-example/send-uo.ts index 1a9cd90849..92e1245e20 100644 --- a/site/snippets/send-uo-example/send-uo.ts +++ b/site/snippets/send-uo-example/send-uo.ts @@ -1,15 +1,13 @@ +import { smartAccountClient } from "../light-account-alchemy-client.js"; import { uoCallData } from "./calldata.js"; -import { connectedProvider } from "./connect-account.js"; -connectedProvider.withAlchemyGasManager({ - policyId: "POLICY_ID", // replace with your policy id, get yours at https://dashboard.alchemy.com/ +const uo = await smartAccountClient.sendUserOperation({ + uo: { + target: "0xTARGET_ADDRESS", + data: uoCallData, + }, }); -const uo = await connectedProvider.sendUserOperation({ - target: "0xTARGET_ADDRESS", - data: uoCallData, -}); - -const txHash = await connectedProvider.waitForUserOperationTransaction(uo.hash); +const txHash = await smartAccountClient.waitForUserOperationTransaction(uo); console.log(txHash); diff --git a/site/snippets/sim-uo-example/sim-method.ts b/site/snippets/sim-uo-example/sim-method.ts index 61d5b7144f..cf07f9cefc 100644 --- a/site/snippets/sim-uo-example/sim-method.ts +++ b/site/snippets/sim-uo-example/sim-method.ts @@ -1,5 +1,15 @@ -import { UserOperationCallData } from "@alchemy/aa-core"; -import { provider } from "../smartAccountClient.js"; +import { createLightAccountAlchemyClient } from "@alchemy/aa-alchemy"; +import { + LocalAccountSigner, + UserOperationCallData, + sepolia, +} from "@alchemy/aa-core"; + +export const smartAccountClient = await createLightAccountAlchemyClient({ + apiKey: "YOUR_API_KEY", + chain: sepolia, + owner: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"), +}); const uoStruct: UserOperationCallData = { target: "0xTARGET_ADDRESS", @@ -7,14 +17,16 @@ const uoStruct: UserOperationCallData = { value: 1n, }; -const uoSimResult = await provider.simulateUserOperationAssetChanges(uoStruct); +const uoSimResult = await smartAccountClient.simulateUserOperation({ + uo: uoStruct, +}); if (uoSimResult.error) { console.error(uoSimResult.error.message); } -const uo = await provider.sendUserOperation(uoStruct); +const uo = await smartAccountClient.sendUserOperation({ uo: uoStruct }); -const txHash = await provider.waitForUserOperationTransaction(uo.hash); +const txHash = await smartAccountClient.waitForUserOperationTransaction(uo); console.log(txHash); diff --git a/site/snippets/sim-uo-example/sim-middleware.ts b/site/snippets/sim-uo-example/sim-middleware.ts index fac715c367..1543005127 100644 --- a/site/snippets/sim-uo-example/sim-middleware.ts +++ b/site/snippets/sim-uo-example/sim-middleware.ts @@ -1,15 +1,21 @@ -import { provider } from "../smartAccountClient.js"; +import { createLightAccountAlchemyClient } from "@alchemy/aa-alchemy"; +import { LocalAccountSigner, sepolia } from "@alchemy/aa-core"; -const providerWithSimulation = provider.withAlchemyUserOpSimulation(); +export const smartAccountClient = await createLightAccountAlchemyClient({ + apiKey: "YOUR_API_KEY", + chain: sepolia, + owner: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"), + useSimulation: true, +}); -const uo = await providerWithSimulation.sendUserOperation({ - target: "0xTARGET_ADDRESS", - data: "0xDATA", - value: 1n, +const uo = await smartAccountClient.sendUserOperation({ + uo: { + target: "0xTARGET_ADDRESS", + data: "0xDATA", + value: 1n, + }, }); -const txHash = await providerWithSimulation.waitForUserOperationTransaction( - uo.hash -); +const txHash = await smartAccountClient.waitForUserOperationTransaction(uo); console.log(txHash); diff --git a/site/tutorials/batching-transactions.md b/site/tutorials/batching-transactions.md index b36321473f..80bd8217f2 100644 --- a/site/tutorials/batching-transactions.md +++ b/site/tutorials/batching-transactions.md @@ -20,7 +20,7 @@ head: # How to Submit Batch Transactions -One benefit of Smart Contract Accounts is that it's possible to batch transactions in one `UserOperation` (UO). Not all Smart Contract Accounts support batching. But, if the `ISmartContractAccount` implementation you're using has the [`encodeBatchExecute`](/packages/aa-core/accounts/optional/encodeBatchExecute.md) method, then implementations of `SmartAccountProvider` will allow you to make those calls. +One benefit of Smart Contract Accounts is that it's possible to batch transactions in one `UserOperation` (UO). Not all Smart Contract Accounts support batching. But, if the `ISmartContractAccount` implementation you're using has the [`encodeBatchExecute`](/packages/aa-core/accounts/) method, then implementations of `SmartAccountProvider` will allow you to make those calls. There are two ways you can batch transactions using `SmartAccountProvider`: diff --git a/site/tutorials/enhanced-apis/nft.md b/site/tutorials/enhanced-apis/nft.md index f13ed79685..0e046b7419 100644 --- a/site/tutorials/enhanced-apis/nft.md +++ b/site/tutorials/enhanced-apis/nft.md @@ -22,13 +22,13 @@ head: We provide several [Enhanced APIs](https://www.alchemy.com/enhanced-apis/?a=ak-docs), which are especially useful for querying information about the smart accounts you create using Account Kit, such as the account's owned NFTs using the [NFT API](https://www.alchemy.com/nft-api/?a=ak-docs). -For the purposes of our example, we'll use the NFT API to query our smart account's data by extending the Alchemy Provider [with Enhanced APIs](/packages/aa-alchemy/provider/withAlchemyEnhancedApis.md). +For the purposes of our example, we'll use the NFT API to query our smart account's data by extending the Alchemy Smart Account Client [with Enhanced APIs](/packages/aa-alchemy/smart-account-client/actions/alchemyEnhancedApiActions.md). ## 1. Install the [`alchemy-sdk`](https://github.com/alchemyplatform/alchemy-sdk-js) We have developed a Typescript SDK to make development with the Enhanced APIs simple. The SDK includes ways to leverage Alchemy's Simulation API, Token API, Transact API, NFT API, Webhooks and Websockets, and more across our supported chains. Take a look at the code [here](https://github.com/alchemyplatform/alchemy-sdk-js). -We will use the Alchemy SDK Client to extend our Alchemy Provider using the provider's [`withAlchemyEnhancedApis`](/packages/aa-alchemy/provider/withAlchemyEnhancedApis.md) method. That way, our provider will have direct access to the Enhanced APIs. +We will use the Alchemy SDK Client to extend our Alchemy Smart Account Client using the provider's [`alchemyEnhancedApiActions`](/packages/aa-alchemy/smart-account-client/actions/alchemyEnhancedApiActions.md) method. That way, our provider will have direct access to the Enhanced APIs. To use the Alchemy SDK in our project directory, we'll need to install the required package: @@ -44,16 +44,16 @@ yarn add alchemy-sdk ::: -## 2. Extend the Alchemy Provider with Enhanced APIs +## 2. Extend the Alchemy Smart Account Client with Enhanced APIs -Then, all we need to do is create an `alchemy` client from the Alchemy SDK, create an `AlchemyProvider` from Account Kit, and then extend the provider with functionality from the SDK client using `withAlchemyEnhancedApis`. We can get the smart account's address from the `AlchemyProvider` in order to fetch the smart account's NFT in just 1 line of code! +Then, all we need to do is create an `alchemy` client from the Alchemy SDK, create an `AlchemySmartAccountClient` from Account Kit, and then extend the provider with functionality from the SDK client using `alchemyEnhancedApiActions`. We can get the smart account's address from the `AlchemySmartAccountClient` in order to fetch the smart account's NFT in just 1 line of code! <<< @/snippets/enhanced-apis-example/nft.ts :::tip Note -Note that we must configure the Alchemy SDK client to have the same API Key and blockchain network as Alchemy Provider it is extending via `withAlchemyEnhancedApis`. This method explicitly checks this requirement and will throw an error at runtime if not satisfied. +Note that we must configure the Alchemy SDK client to have the same API Key and blockchain network as Alchemy Smart Account Client it is extending via `alchemyEnhancedApiActions`. This method explicitly checks this requirement and will throw an error at runtime if not satisfied. -Additionally, since the Alchemy SDK client does not yet support JWT authentication, an `AlchemyProvider` initialized with JWTs cannot use this method. We must be initialize the provider with an API key or RPC URL. +Additionally, since the Alchemy SDK client does not yet support JWT authentication, an `AlchemySmartAccountClient` initialized with JWTs cannot use this method. We must be initialize the provider with an API key or RPC URL. ::: That's it! There are so many more Enhanced APIs the the Alchemy SDK exposes, and can be useful for development with Account Abstraction. Try it out [here](https://github.com/alchemyplatform/alchemy-sdk-js), and check out [How to fetch a Smart Account's ERC-20 Tokens](/tutorials/enhanced-apis/token) for another example. diff --git a/site/tutorials/enhanced-apis/token.md b/site/tutorials/enhanced-apis/token.md index 98cf5c0b6f..7188827a1e 100644 --- a/site/tutorials/enhanced-apis/token.md +++ b/site/tutorials/enhanced-apis/token.md @@ -22,13 +22,13 @@ head: Alchemy provides several [Enhanced APIs](https://www.alchemy.com/enhanced-apis/?a=ak-docs), which are especially useful for querying information about the smart accounts you create using Account Kit, such as the account's ERC-20 Token balances using the [Token API](https://www.alchemy.com/token-api/?a=ak-docs). -For the purposes of our example, we'll use the Token API to query our smart account's data by extending the Alchemy Provider [with Enhanced APIs](/packages/aa-alchemy/provider/withAlchemyEnhancedApis.md). +For the purposes of our example, we'll use the Token API to query our smart account's data by extending the Alchemy Smart Account Client [with Enhanced APIs](/packages/aa-alchemy/smart-account-client/actions/alchemyEnhancedApiActions.md). ## 1. Install the [`alchemy-sdk`](https://github.com/alchemyplatform/alchemy-sdk-js) Alchemy has developed a Typescript SDK to make development with the Enhanced APIs simple. The SDK includes ways to leverage Alchemy's Simulation API, Token API, Transact API, NFT API, Webhooks and Websockets, and more across Alchemy's supported chains. Take a look at the code [here](https://github.com/alchemyplatform/alchemy-sdk-js). -We will use the Alchemy SDK Client to extend our Alchemy Provider using the provider's [`withAlchemyEnhancedApis`](/packages/aa-alchemy/provider/withAlchemyEnhancedApis.md) method. That way, our provider will have direct access to the Enhanced APIs. +We will use the Alchemy SDK Client to extend our Alchemy Smart Account Client using the provider's [`alchemyEnhancedApiActions`](/packages/aa-alchemy/smart-account-client/actions/alchemyEnhancedApiActions.md) method. That way, our provider will have direct access to the Enhanced APIs. To use the Alchemy SDK in our project directory, we'll need to install the required package: @@ -44,16 +44,16 @@ yarn add alchemy-sdk ::: -## 2. Extend the Alchemy Provider with Enhanced APIs +## 2. Extend the Alchemy Smart Account Client with Enhanced APIs -Then, all we need to do is create an `alchemy` client from the Alchemy SDK, create an `AlchemyProvider` from Account Kit, and then extend the provider with functionality from the SDK client using `withAlchemyEnhancedApis`. We can get the smart account's address from the `AlchemyProvider` in order to fetch the smart account's ERC-20 Tokens in just 1 line of code! +Then, all we need to do is create an `alchemy` client from the Alchemy SDK, create an `AlchemySmartAccountClient` from Account Kit, and then extend the provider with functionality from the SDK client using `withAlchemyEnhancedApis`. We can get the smart account's address from the `AlchemySmartAccountClient` in order to fetch the smart account's ERC-20 Tokens in just 1 line of code! <<< @/snippets/enhanced-apis-example/token.ts :::tip Note -Note that we must configure the Alchemy SDK client to have the same API Key and blockchain network as Alchemy Provider it is extending via `withAlchemyEnhancedApis`. This method explicitly checks this requirement and will throw an error at runtime if not satisfied. +Note that we must configure the Alchemy SDK client to have the same API Key and blockchain network as Alchemy Smart Account Client it is extending via `alchemyEnhancedApiActions`. This method explicitly checks this requirement and will throw an error at runtime if not satisfied. -Additionally, since the Alchemy SDK client does not yet support JWT authentication, an `AlchemyProvider` initialized with JWTs cannot use this method. We must be initialize the provider with an API key or RPC URL. +Additionally, since the Alchemy SDK client does not yet support JWT authentication, an `AlchemySmartAccountClient` initialized with JWTs cannot use this method. We must be initialize the provider with an API key or RPC URL. ::: That's it! There are so many more Enhanced APIs the the Alchemy SDK exposes, and can be useful for development with Account Abstraction. Try it out [here](https://github.com/alchemyplatform/alchemy-sdk-js), and check out [How to fetch a Smart Account's NFTs](/tutorials/enhanced-apis/nft) for another example. diff --git a/site/tutorials/send-user-operation.md b/site/tutorials/send-user-operation.md index 5265c8a410..f838e4cbb9 100644 --- a/site/tutorials/send-user-operation.md +++ b/site/tutorials/send-user-operation.md @@ -23,25 +23,17 @@ prev: # How to Send a User Operation -This guide will show you how to send a User Operation with Account Kit by creating an Alchemy Provider, connecting it to a Light Account (a type of smart account implementation), and sending a User Operation from that provider. By the end of this guide, you'll have a basic understanding of how to use the SDK. +This guide will show you how to send a User Operation with Account Kit by creating an Alchemy Smart Account Client, connecting it to a Light Account (a type of smart account implementation), and sending a User Operation from that provider. By the end of this guide, you'll have a basic understanding of how to use the SDK. ## 1. Create Your Provider -Using the SDK, we'll create an Alchemy Provider. As it is, the providers gives you methods to query information related to user operations and smart accounts. To create a provider, you'll need an Alchemy API Key or RPC URL, which you can access from the [Alchemy Dashboard](https://dashboard.alchemy.com/signup/?a=aa-docs). +Using the SDK, we'll create an Alchemy Smart Account Client. As it is, the providers gives you methods to query information related to user operations and smart accounts. To create a provider, you'll need an Alchemy API Key or RPC URL, which you can access from the [Alchemy Dashboard](https://dashboard.alchemy.com/signup/?a=aa-docs). -See [Alchemy Provider](/packages/aa-alchemy/provider/introduction.md) for more details. +See [Alchemy Smart Account Client](/packages/aa-alchemy/smart-account-client/) for more details. -<<< @/snippets/send-uo-example/create-provider.ts +<<< @/snippets/light-account-alchemy-client.ts -## 2. Connect Your Smart Account - -To send User Operations, we must connect the `provider` with a smart account. The Light Account is our gas-optimized smart account implementation, which we'll use in this example. - -See [Light Account](/packages/aa-accounts/light-account/introduction.md) for more details. - -<<< @/snippets/send-uo-example/connect-account.ts - -## 3. Construct The CallData +## 2. Construct The CallData The best part of Account Kit is that it abstracts the differences between User Operation calldata and standard Transaction calldata, such that you can pass in typical calldata to [sendUserOperation](/packages/aa-core/smart-account-client/actions/waitForUserOperationTransaction.md) as if it was a transaction sent from your smart account, and we'll wrap it as necessary to generate calldata as it would be as a User Operation. @@ -51,11 +43,11 @@ The second best part of Account Kit is it's build atop [viem](https://viem.sh/). Some other helpful viem methods include: [encodeFunctionData](https://viem.sh/docs/contract/encodeFunctionData.html), [decodeFunctionData](https://viem.sh/docs/contract/decodeFunctionData.html), and [decodeFunctionResult](https://viem.sh/docs/contract/decodeFunctionResult.html). -## 4. Send The User Operation +## 3. Send The User Operation Now we'll use the connected provider to send a user operation. We'll use the [sendUserOperation](/packages/aa-core/smart-account-client/actions/sendUserOperation.md) method on the provider. -You can either send ETH to the smart account to pay for User Operation's gas, or you can connect your provider to our Gas Manager using the [withAlchemyGasManager](/packages/aa-alchemy/provider/withAlchemyGasManager.md) method to sponsor the UO's gas. We'll use the latter approach below. You can go to the [Alchemy Dashboard](https://dashboard.alchemy.com/gas-manager/?a=ak-docs) to get a Gas Manager policy ID. +You can either send ETH to the smart account to pay for User Operation's gas, or you can connect your provider to our Gas Manager using the [withAlchemyGasManager](/packages/aa-alchemy/middleware/alchemyGasManagerMiddleware.md) method to sponsor the UO's gas. We'll use the latter approach below. You can go to the [Alchemy Dashboard](https://dashboard.alchemy.com/gas-manager/?a=ak-docs) to get a Gas Manager policy ID. We'll also want to wait for the transaction which contains the User Operation, so that we know the User Operation executed on-chain. We can use the [waitForUserOperationTransaction](/packages/aa-core/smart-account-client/actions/waitForUserOperationTransaction.md) method on provider to do so, as seen below. diff --git a/site/tutorials/sim-user-operation.md b/site/tutorials/sim-user-operation.md index 8000849de3..5559fa99bd 100644 --- a/site/tutorials/sim-user-operation.md +++ b/site/tutorials/sim-user-operation.md @@ -31,33 +31,25 @@ Please note that the UO simulation results are based on the blockchain's state a This could lead to different outcomes than predicted. For instance, if a UO's effect is conditional on the current state of a contract, and this state is altered before the UO is executed, the final result may not match the simulation. Please be aware of this potential variance and consider it while using UO simulations. -::: - -There are two ways that Account Kit supports UO simulation on an `AlchemyProvider`: - -1. using the [`withAlchemyUserOpSimulation`](/packages/aa-alchemy/provider/withAlchemyUserOpSimulation) middleware -2. using the [`simulateUserOperationAssetChanges`](/packages/aa-alchemy/provider/simulateUserOperationAssetChanges) method -## 1. Using [`withAlchemyUserOpSimulation`](/packages/aa-alchemy/provider/withAlchemyUserOpSimulation) +## 1. Using [`alchemyUserOperationSimulator` middleware](/packages/aa-alchemy/middleware/alchemyUserOperationSimulator) -To simulate User Operations, we must connect the `provider` with the middleware to simulate `UserOperations` before sending them. This can be done in a single line code, as show below! +To simulate User Operations, we must create an Alchemy Client and pass in the `useSimulation` flag to true. Then, whenever you call a method on the provider which generates the UO to send (e.g. [`sendUserOperation`](/packages/aa-core/smart-account-client/actions/sendUserOperation), [`sendTransaction`](/packages/aa-core/smart-account-client/actions/sendTransaction), [`sendTransactions`](/packages/aa-core/smart-account-client/actions/sendTransactions), [`buildUserOperation`](/packages/aa-core/smart-account-client/actions/buildUserOperation), or [`buildUserOperationFromTx`](/packages/aa-core/smart-account-client/actions/buildUserOperationFromTx)), the provider will also simulate which assets change as a result of the UO, and if simulation fails, the provider will not send the UO unnecessarily! ::: code-group <<< @/snippets/sim-uo-example/sim-middleware.ts -<<< @/snippets/smartAccountClient.ts ::: -## 2. Using [`simulateUserOperationAssetChanges`](/packages/aa-alchemy/provider/simulateUserOperationAssetChanges) +## 2. Using [`simulateUserOperation`](/packages/aa-alchemy/smart-account-client/actions/simulateUserOperation) -You can also selectively simulate UOs by calling the [`simulateUserOperationAssetChanges`](/packages/aa-alchemy/provider/simulateUserOperationAssetChanges) method before sending a UO. You'd be responsible for catching any errors like how it's done below, but this is a nice alternative to always running simulation. +You can also selectively simulate UOs by calling the [`simulateUserOperation`](/packages/aa-alchemy/smart-account-client/actions/simulateUserOperation)) method before sending a UO. You'd be responsible for catching any errors like how it's done below, but this is a nice alternative to always running simulation. ::: code-group <<< @/snippets/sim-uo-example/sim-method.ts -<<< @/snippets/smartAccountClient.ts ::: diff --git a/site/tutorials/transferring-ownership.md b/site/tutorials/transferring-ownership.md index e4a5b7e7b2..6c978881bd 100644 --- a/site/tutorials/transferring-ownership.md +++ b/site/tutorials/transferring-ownership.md @@ -98,4 +98,4 @@ const { hash: userOperationHash } = provider.sendUserOperation({ ::: -See the [`LightSmartContractAccount`](/packages/aa-accounts/light-account/introduction) docs for more details about our Light Account implementation. +See the [`LightAccount`](/packages/aa-accounts/light-account/) docs for more details about our Light Account implementation.