diff --git a/README.md b/README.md index b5579e4b9e..2657749636 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ There are currently 5 SDKs that are part of the `aa-sdk` suite: The core SDK also implements an EIP-1193 provider interface to easily plug into any popular dapp or wallet connect libraries such as RainbowKit, Wagmi, and Web3Modal. It also includes [`ethers.js`](https://docs.ethers.org/v5/) adapters to provide full support for `ethers.js`` apps. -The `aa-sdk` is modular at every layer of the stack and can be easily extended to fit your custom needs. You can plug in any [smart account](https://accountkit.alchemy.com/smart-accounts/accounts/using-your-own) implementation, [Signer](https://accountkit.alchemy.com/smart-accounts/signers/overview), [Gas Manager API](https://accountkit.alchemy.com/overview/introduction.html#gas-manager-api) and RPC Provider. +The `aa-sdk` is modular at every layer of the stack and can be easily extended to fit your custom needs. You can plug in any [smart account](https://accountkit.alchemy.com/smart-accounts/accounts/using-your-own) implementation, [Signer](https://accountkit.alchemy.com/signers/overview), [Gas Manager API](https://accountkit.alchemy.com/overview/introduction.html#gas-manager-api) and RPC Provider. ## Getting Started diff --git a/packages/alchemy/src/client/smartAccountClient.ts b/packages/alchemy/src/client/smartAccountClient.ts index 5c300f2bac..bd6828dca6 100644 --- a/packages/alchemy/src/client/smartAccountClient.ts +++ b/packages/alchemy/src/client/smartAccountClient.ts @@ -25,7 +25,6 @@ export type AlchemySmartAccountClientConfig< > = { account?: account; useSimulation?: boolean; - // TODO: this is missing the current gas manager fallback stuff gasManagerConfig?: AlchemyGasManagerConfig; } & AlchemyProviderConfig & Pick< diff --git a/packages/alchemy/src/middleware/gasManager.ts b/packages/alchemy/src/middleware/gasManager.ts index f3866c9aaa..bc2eb5060b 100644 --- a/packages/alchemy/src/middleware/gasManager.ts +++ b/packages/alchemy/src/middleware/gasManager.ts @@ -1,4 +1,7 @@ -import type { ClientMiddleware, ClientMiddlewareFn } from "@alchemy/aa-core"; +import type { + ClientMiddlewareConfig, + ClientMiddlewareFn, +} from "@alchemy/aa-core"; import { deepHexlify, defaultGasEstimator, @@ -34,12 +37,26 @@ export interface AlchemyGasEstimationOptions { fallbackFeeDataGetter?: ClientMiddlewareFn; } +const dummyPaymasterAndData = + (client: C) => + () => { + switch (client.chain.id) { + case 1: + case 10: + case 137: + case 42161: + return "0x4Fd9098af9ddcB41DA48A1d78F91F1398965addcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; + default: + return "0xc03aac639bb21233e0139381970328db8bceeb67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; + } + }; + export const alchemyGasManagerMiddleware = ( client: C, config: AlchemyGasManagerConfig ): Pick< - ClientMiddleware, - "dummyPaymasterAndData" | "paymasterAndData" | "feeEstimator" | "gasEstimator" + ClientMiddlewareConfig, + "paymasterAndData" | "feeEstimator" | "gasEstimator" > => { const gasEstimationOptions = config.gasEstimationOptions; const disableGasEstimation = @@ -103,25 +120,6 @@ export const alchemyGasManagerMiddleware = ( maxPriorityFeePerGas, }; }, - dummyPaymasterAndData: async (struct) => { - switch (client.chain.id) { - case 1: - case 10: - case 137: - case 42161: - return { - ...struct, - paymasterAndData: - "0x4Fd9098af9ddcB41DA48A1d78F91F1398965addcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c", - }; - default: - return { - ...struct, - paymasterAndData: - "0xc03aac639bb21233e0139381970328db8bceeb67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c", - }; - } - }, paymasterAndData: disableGasEstimation ? requestPaymasterAndData(client, config) : requestGasAndPaymasterData(client, config), @@ -131,9 +129,9 @@ export const alchemyGasManagerMiddleware = ( const requestGasAndPaymasterData: ( client: C, config: AlchemyGasManagerConfig -) => ClientMiddlewareFn = - (client, config) => - async (struct, { overrides, feeOptions, account }) => { +) => ClientMiddlewareConfig["paymasterAndData"] = (client, config) => ({ + dummyPaymasterAndData: dummyPaymasterAndData(client), + paymasterAndData: async (struct, { overrides, feeOptions, account }) => { const userOperation: UserOperationRequest = deepHexlify( await resolveProperties(struct) ); @@ -196,14 +194,15 @@ const requestGasAndPaymasterData: ( ...struct, ...result, }; - }; + }, +}); const requestPaymasterAndData: ( client: C, config: AlchemyGasManagerConfig -) => ClientMiddlewareFn = - (client, config) => - async (struct, { account }) => { +) => ClientMiddlewareConfig["paymasterAndData"] = (client, config) => ({ + dummyPaymasterAndData: dummyPaymasterAndData(client), + paymasterAndData: async (struct, { account }) => { const { paymasterAndData } = await client.request({ method: "alchemy_requestPaymasterAndData", params: [ @@ -219,4 +218,5 @@ const requestPaymasterAndData: ( ...struct, paymasterAndData, }; - }; + }, +}); diff --git a/packages/core/src/client/smartAccountClient.ts b/packages/core/src/client/smartAccountClient.ts index e4a94ff534..6ea0142ae6 100644 --- a/packages/core/src/client/smartAccountClient.ts +++ b/packages/core/src/client/smartAccountClient.ts @@ -24,6 +24,7 @@ import { type BaseSmartAccountClientActions, } from "./decorators/smartAccountClient.js"; import { SmartAccountClientOptsSchema } from "./schema.js"; +import type { ClientMiddlewareConfig } from "./types.js"; type SmartAccountClientOpts = z.output; @@ -40,7 +41,7 @@ export type SmartAccountClientConfig< > & { account?: account; opts?: z.input; - } & Partial + } & ClientMiddlewareConfig >; export type SmartAccountClientRpcSchema = [ diff --git a/packages/core/src/client/types.ts b/packages/core/src/client/types.ts index b573a473db..27482ca1fd 100644 --- a/packages/core/src/client/types.ts +++ b/packages/core/src/client/types.ts @@ -1,6 +1,10 @@ import type { Address } from "abitype"; import type { Hash, Hex } from "viem"; import type { z } from "zod"; +import type { + ClientMiddleware, + ClientMiddlewareFn, +} from "../middleware/types.js"; import type { UserOperationRequest } from "../types.js"; import type { ConnectionConfigSchema } from "./schema.js"; @@ -19,3 +23,13 @@ export type UpgradeToData = { implAddress: Address; initializationData: Hex; }; + +export type ClientMiddlewareConfig = Omit< + Partial, + "dummyPaymasterAndData" | "paymasterAndData" +> & { + paymasterAndData?: { + dummyPaymasterAndData: () => Hex; + paymasterAndData: ClientMiddlewareFn; + }; +}; diff --git a/packages/core/src/middleware/actions.ts b/packages/core/src/middleware/actions.ts index 1c9a9d9fb8..a78c9c9c03 100644 --- a/packages/core/src/middleware/actions.ts +++ b/packages/core/src/middleware/actions.ts @@ -10,6 +10,7 @@ import type { BundlerActions, BundlerRpcSchema, } from "../client/decorators/bundlerClient.js"; +import type { ClientMiddlewareConfig } from "../client/types.js"; import { defaultFeeEstimator } from "./defaults/feeEstimator.js"; import { defaultGasEstimator } from "./defaults/gasEstimator.js"; import { defaultPaymasterAndData } from "./defaults/paymasterAndData.js"; @@ -31,7 +32,7 @@ export type MiddlewareClient< >; export const middlewareActions = - (overrides: Partial) => + (overrides: ClientMiddlewareConfig) => < TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, @@ -43,11 +44,17 @@ export const middlewareActions = ): { middleware: ClientMiddleware } => ({ middleware: { customMiddleware: overrides.customMiddleware ?? noopMiddleware, - dummyPaymasterAndData: - overrides.dummyPaymasterAndData ?? defaultPaymasterAndData, + dummyPaymasterAndData: overrides.paymasterAndData?.dummyPaymasterAndData + ? async (struct) => ({ + ...struct, + paymasterAndData: + overrides.paymasterAndData!.dummyPaymasterAndData(), + }) + : defaultPaymasterAndData, feeEstimator: overrides.feeEstimator ?? defaultFeeEstimator(client), gasEstimator: overrides.gasEstimator ?? defaultGasEstimator(client), - paymasterAndData: overrides.paymasterAndData ?? defaultPaymasterAndData, + paymasterAndData: + overrides.paymasterAndData?.paymasterAndData ?? defaultPaymasterAndData, userOperationSimulator: overrides.userOperationSimulator ?? noopMiddleware, }, diff --git a/site/.vitepress/sidebar/new.ts b/site/.vitepress/sidebar/new.ts index ec9be91b7c..bf412abc92 100644 --- a/site/.vitepress/sidebar/new.ts +++ b/site/.vitepress/sidebar/new.ts @@ -58,12 +58,12 @@ export const newSidebar: DefaultTheme.Sidebar = [ }, { text: "Choosing a Signer", - base: "/smart-accounts/signers", + base: "/signers", items: [ { text: "Introduction", link: "/choosing-a-signer" }, { text: "Signer Guides", - base: "/smart-accounts/signers/guides", + base: "/signers/guides", collapsed: true, items: [ { text: "Magic", link: "/magic" }, @@ -146,9 +146,10 @@ export const newSidebar: DefaultTheme.Sidebar = [ }, { text: "Third Party Integrations", + base: "/third-party", items: [ - { text: "Bundlers", link: "/" }, - { text: "Paymasters", link: "/" }, + { text: "Bundlers", link: "/bundlers" }, + { text: "Paymasters", link: "/paymasters" }, ], }, packagesSidebar, diff --git a/site/.vitepress/sidebar/old.ts b/site/.vitepress/sidebar/old.ts deleted file mode 100644 index 467ba1c5c8..0000000000 --- a/site/.vitepress/sidebar/old.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { DefaultTheme } from "vitepress"; -import { packagesSidebar } from "./packages"; - -// TODO: remove this once we're done refactoring, keeping here for tracking -export const oldSidebar: DefaultTheme.Sidebar = [ - { - text: "Overview", - base: "/overview", - items: [ - { text: "Why Account Kit", link: "/why-account-kit" }, - { text: "Introduction", link: "/introduction" }, - { text: "Getting Started", link: "/getting-started" }, - { - text: "Packages Overview", - link: "/package-overview", - }, - { - text: "Demos", - link: "/demos", - }, - { - text: "FAQs", - link: "/faqs", - }, - { - text: "Contact Us", - link: "/contact-us", - }, - ], - }, - { - text: "Smart Accounts", - base: "/smart-accounts", - items: [ - { text: "Overview", link: "/overview" }, - { - text: "Choosing a Smart Account", - base: "/smart-accounts/accounts", - items: [ - { text: "Introduction", link: "/choosing-a-smart-account" }, - { - text: "Smart Account Guides", - base: "/smart-accounts/accounts/guides", - collapsed: true, - items: [ - { text: "Light Account", link: "/light-account" }, - { text: "Modular Account", link: "/modular-account" }, - { text: "Using Your Own", link: "/using-your-own" }, - ], - }, - { text: "Deployments", link: "/deployment-addresses" }, - { text: "Contributing Your Account", link: "/contributing" }, - ], - }, - { - text: "Choosing a Signer", - base: "/smart-accounts/signers", - items: [ - { text: "Introduction", link: "/choosing-a-signer" }, - { - text: "Signer Guides", - base: "/smart-accounts/signers/guides", - collapsed: true, - items: [ - { text: "Magic", link: "/magic" }, - { text: "Web3Auth", link: "/web3auth" }, - { text: "Turnkey", link: "/turnkey" }, - { text: "Privy", link: "/privy" }, - { text: "Dynamic", link: "/dynamic" }, - { text: "Fireblocks", link: "/fireblocks" }, - { text: "Portal", link: "/portal" }, - { text: "Capsule", link: "/capsule" }, - { text: "Lit Protocol", link: "/lit" }, - { text: "Particle Network", link: "/particle-network" }, - { text: "Arcana Auth", link: "/arcana-auth" }, - { text: "Dfns", link: "/dfns" }, - { text: "Externally Owned Account (EOA)", link: "/eoa" }, - { text: "Using Your Own", link: "/custom-signer" }, - ], - }, - { text: "Contributing Your Signer", link: "/contributing" }, - ], - }, - ], - }, - { - text: "Tutorials", - base: "/tutorials", - items: [ - { - text: "How to Send a User Operation", - link: "/send-user-operation", - }, - { - text: "Gas Sponsorship", - base: "/tutorials/sponsoring-gas", - items: [ - { - text: "How to Sponsor Gas for User Operations", - link: "/sponsoring-gas", - }, - { - text: "How to Handle User Operations that are Not Eligible for Gas Sponsorship", - link: "/gas-sponsorship-eligibility", - }, - ], - }, - { text: "How to Batch Transactions", link: "/batching-transactions" }, - { - text: "How to Transfer Ownership of a Smart Account", - link: "/transferring-ownership", - }, - { - text: "How to Simulate a User Operation", - link: "/sim-user-operation", - }, - { - text: "Smart Account Data", - base: "/tutorials/enhanced-apis", - items: [ - { - text: "How to Fetch a Smart Account's NFTs", - link: "/nft", - }, - { - text: "How to Fetch a Smart Account's ERC-20 Tokens", - link: "/token", - }, - ], - }, - ], - }, - packagesSidebar, - { - text: "Glossary", - base: "/glossary", - collapsed: true, - items: [ - { text: "Terms", link: "/terms" }, - { text: "Types", link: "/types" }, - ], - }, -]; diff --git a/site/getting-started/deploy-an-account.md b/site/getting-started/deploy-an-account.md index 72daca3ece..31903b6faa 100644 --- a/site/getting-started/deploy-an-account.md +++ b/site/getting-started/deploy-an-account.md @@ -40,7 +40,7 @@ The `LightAccount` implementation is not [ERC-6900](/smart-accounts/modular-acco ## 3. Choosing a Signer -A Signer is the entity that signs transactions (User Operations) on behalf of the smart account. It can be an EOA, a custodial service, or a multi-party computation (MPC) service. We explain the different types of signers in detail in the [overview](/smart-accounts/signers/choosing-a-signer) section on choosing a Signer and offer integration guides in these docs, many of which use our `aa-signers` SDK. +A Signer is the entity that signs transactions (User Operations) on behalf of the smart account. It can be an EOA, a custodial service, or a multi-party computation (MPC) service. We explain the different types of signers in detail in the [overview](/signers/choosing-a-signer) section on choosing a Signer and offer integration guides in these docs, many of which use our `aa-signers` SDK. At this point you should be able to integrate smart accounts in your application. However, there are a few advanced features that can help you improve the user experience and save on gas costs. Information about these can be found in the `Guides` section. diff --git a/site/getting-started/setup.md b/site/getting-started/setup.md index 1f3aaf1ac4..5f13f8bfe9 100644 --- a/site/getting-started/setup.md +++ b/site/getting-started/setup.md @@ -165,7 +165,7 @@ In this guide, we initialized an `AlchemyProvider` with the `aa-alchemy` package 2. To learn about the end-to-end process of integrating smart accounts in your applications, check out the section on [Smart Accounts](/smart-accounts/). -3. To learn about the `owner` field on your smart account, check out the section on [Choosing a Signer](/smart-accounts/signers/choosing-a-signer) to own the smart account. +3. To learn about the `owner` field on your smart account, check out the section on [Choosing a Signer](/signers/choosing-a-signer) to own the smart account. 4. To learn more about different User Operations you can send with different `target` and `data` fields in the `sendUserOperation` function above, look at our [How to Send a User Operation](/using-smart-accounts/send-user-operations) guide for an example using NFT mints. diff --git a/site/glossary/terms.md b/site/glossary/terms.md index 4e240c671d..3681b25e1c 100644 --- a/site/glossary/terms.md +++ b/site/glossary/terms.md @@ -22,7 +22,7 @@ head: ## Account Kit -Account Kit is a framework designed to embed smart accounts in web3 applications. It includes a set of tools such as [Signer integrations](https://accountkit.alchemy.com/smart-accounts/signers/choosing-a-signer.html), [Gas Manager](https://docs.alchemy.com/docs/gas-manager-services) and [Bundler](https://docs.alchemy.com/docs/bundler-services) utilities that unlock features such as [gas sponsorship](https://accountkit.alchemy.com/using-smart-accounts/sponsoring-gas/gas-manager.html), [batched transactions](https://accountkit.alchemy.com/using-smart-accounts/batch-user-operations.html) and email/social login. With its user-friendly suite of SDKs, known as [aa-sdk](https://github.com/alchemyplatform/aa-sdk), Account Kit makes it easy to deploy smart accounts, manage `UserOperation`s, and handle gas sponsorship, streamlining the entire process with minimal coding effort. +Account Kit is a framework designed to embed smart accounts in web3 applications. It includes a set of tools such as [Signer integrations](https://accountkit.alchemy.com/signers/choosing-a-signer.html), [Gas Manager](https://docs.alchemy.com/docs/gas-manager-services) and [Bundler](https://docs.alchemy.com/docs/bundler-services) utilities that unlock features such as [gas sponsorship](https://accountkit.alchemy.com/using-smart-accounts/sponsoring-gas/gas-manager.html), [batched transactions](https://accountkit.alchemy.com/using-smart-accounts/batch-user-operations.html) and email/social login. With its user-friendly suite of SDKs, known as [aa-sdk](https://github.com/alchemyplatform/aa-sdk), Account Kit makes it easy to deploy smart accounts, manage `UserOperation`s, and handle gas sponsorship, streamlining the entire process with minimal coding effort. ## Bundler diff --git a/site/overview/introduction.md b/site/overview/introduction.md index f43fc65bf5..8a860eb6c1 100644 --- a/site/overview/introduction.md +++ b/site/overview/introduction.md @@ -42,7 +42,7 @@ The `aa-sdk` is a type-safe and performant TypeScript library built on top of [v The SDK also implements an EIP-1193 provider interface to easily plug into any popular dapp or wallet connect libraries such as RainbowKit, Wagmi, and Web3Modal. It also includes ethers.js adapters to provide full support for ethers.js apps. -The `aa-sdk` is modular at every layer of the stack and can be easily extended to fit your custom needs. You can plug in any [smart account](/smart-accounts/custom/using-your-own) implementation, [Signer](/smart-accounts/signers/choosing-a-signer), Gas Manager API, RPC provider. +The `aa-sdk` is modular at every layer of the stack and can be easily extended to fit your custom needs. You can plug in any [smart account](/smart-accounts/custom/using-your-own) implementation, [Signer](/signers/choosing-a-signer), Gas Manager API, RPC provider. Get started with `aa-sdk` in our [Getting Started guide](/getting-started/setup) or checkout the [open source repo](https://github.com/alchemyplatform/aa-sdk). @@ -66,7 +66,7 @@ To learn how to deploy a `LightAccount`, see [Light Account](/smart-accounts/lig A Signer is responsible for securely managing the private key and signing transaction requests on the smart account. Account Kit supports many popular wallet signers. It also supports self-custodial wallets like MetaMask or Ledger. -To get started with a Signer, read the doc: [How to Choose a Signer](/smart-accounts/signers/choosing-a-signer). +To get started with a Signer, read the doc: [How to Choose a Signer](/signers/choosing-a-signer). ### Gas Manager API diff --git a/site/overview/why-account-kit.md b/site/overview/why-account-kit.md index 3a90ff5f40..d0ca685694 100644 --- a/site/overview/why-account-kit.md +++ b/site/overview/why-account-kit.md @@ -65,9 +65,9 @@ Streamline your sign up flow with simple web2 login options supported by Account - Self-custodial wallets like MetaMask or Ledger - and more -Account Kit integrates all the leading wallet Signers with integration guides that you can find [here](/smart-accounts/signers/choosing-a-signer). Account Kit even supports self-custodial wallets like MetaMask or Ledger. Users can even change their Signer later via Account Kit’s [ownership transfer](/using-smart-accounts/transfer-ownership/light-account) functionality. +Account Kit integrates all the leading wallet Signers with integration guides that you can find [here](/signers/choosing-a-signer). Account Kit even supports self-custodial wallets like MetaMask or Ledger. Users can even change their Signer later via Account Kit’s [ownership transfer](/using-smart-accounts/transfer-ownership/light-account) functionality. -Learn [how to choose and integrate the right Signer for your use case in this doc](/smart-accounts/signers/choosing-a-signer). +Learn [how to choose and integrate the right Signer for your use case in this doc](/signers/choosing-a-signer). ## Sponsor gas diff --git a/site/packages/aa-alchemy/smart-account-client/index.md b/site/packages/aa-alchemy/smart-account-client/index.md index 81e6de4c28..21b6b2fe89 100644 --- a/site/packages/aa-alchemy/smart-account-client/index.md +++ b/site/packages/aa-alchemy/smart-account-client/index.md @@ -77,6 +77,16 @@ A new instance of an `AlchemySmartAccountClient`. - `policyId: string` -- the policy id of the gas manager you want to use. +- `account?: SmartContractAccount` -- [optional] the smart account to use as context for all of your calls. If not provided, then the account can be provided to each individual call instead. + +- `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). + +- `feeEstimator?: ClientMiddlewareFn` -- [optional] an override for the fee estimator middleware. The `feeEstimator` middleware function calculates `maxFeePerGas` and `maxPriorityFeePerGas` for your User Operation. + +- `gasEstimator?: ClientMiddlewareFn` -- [optional] an override for the gas estimator middleware. The `gasEstimator` middleware function calculates the gas fields of your User Operation. + +- `customMiddleware?: ClientMiddlewareFn` -- [optional] if you would like to run a custom transformation on your User Operation after Gas and Fee estimation, but before your paymaster is called, you can provide a custom middleware function here. + - `opts: SmartAccountProviderOpts | undefined` -- [optional] overrides on provider config variables having to do with fetching transaction receipts and fee computation. - `txMaxRetries: string | undefined` -- [optional] the maximum number of times to try fetching a transaction receipt before giving up (default: 5). diff --git a/site/packages/aa-core/smart-account-client/index.md b/site/packages/aa-core/smart-account-client/index.md index f9ca8287c9..7c82869746 100644 --- a/site/packages/aa-core/smart-account-client/index.md +++ b/site/packages/aa-core/smart-account-client/index.md @@ -106,15 +106,16 @@ A new instance of a `SmartAccountClient`. - `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). -- `dummyPaymasterAndData?: ClientMiddlewareFn` -- [optional] an override for the dummy paymaster and data middleware. This is useful if you want to use a paymaster. The `dummyPaymasterAndData` middleware function is run before all other middlewares and is used during gas and fee estimation. It should be a value that does not cause your paymaster to revert. - - `feeEstimator?: ClientMiddlewareFn` -- [optional] an override for the fee estimator middleware. The `feeEstimator` middleware function calculates `maxFeePerGas` and `maxPriorityFeePerGas` for your User Operation. - `gasEstimator?: ClientMiddlewareFn` -- [optional] an override for the gas estimator middleware. The `gasEstimator` middleware function calculates the gas fields of your User Operation. - `customMiddleware?: ClientMiddlewareFn` -- [optional] if you would like to run a custom transformation on your User Operation after Gas and Fee estimation, but before your paymaster is called, you can provide a custom middleware function here. -- `paymasterAndData?: ClientMiddlewareFn` -- [optional] if you owuld like to use a paymaster, then this middleware must be supplied in conjunction with the above `dummyPaymasterAndData` middleware. This middleware runs after gas and fee estimation and should generate the `paymasterAndData` field that will be used to sponsor your user operation. +- `paymasterAndData?: ClientMiddlewareConfig["paymasterAndData"]` -- [optional] if you would like to use a paymaster, then this config must be supplied. + + - `paymasterAndData: ClientMiddlewareFn` -- this middleware function calculates the paymaster and data fields of your User Operation after estimating gas and fees + - `dummyPaymasterAndData: () => Hex` -- this just returns a Hex string to be used during gas and fee estimation. This will depend on your paymaster provider and must be a value that accurately resembles the gas cost of using your paymaster and does not revert during validation. - `opts: SmartAccountProviderOpts | undefined` -- [optional] overrides on provider config variables having to do with fetching transaction receipts and fee computation. diff --git a/site/smart-accounts/signers/choosing-a-signer.md b/site/signers/choosing-a-signer.md similarity index 98% rename from site/smart-accounts/signers/choosing-a-signer.md rename to site/signers/choosing-a-signer.md index 580e20d43f..032804ad33 100644 --- a/site/smart-accounts/signers/choosing-a-signer.md +++ b/site/signers/choosing-a-signer.md @@ -50,7 +50,7 @@ The Signer plays a crucial role in your app because it controls the user’s sma Account Kit is compatible with any EIP-1193 provider. Many of the most popular signers can be configured in minutes through our integration signer guides. -If you want to use another Signer, you can integrate any other Signer by wrapping it in an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) provider or using [`SmartAccountSigner`](/smart-accounts/signers/guides/custom-signer#implementing-smartaccountsigner) to adapt non-standard Signer. +If you want to use another Signer, you can integrate any other Signer by wrapping it in an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) provider or using [`SmartAccountSigner`](/signers/guides/custom-signer#implementing-smartaccountsigner) to adapt non-standard Signer. ## Criteria to consider diff --git a/site/smart-accounts/signers/contributing.md b/site/signers/contributing.md similarity index 97% rename from site/smart-accounts/signers/contributing.md rename to site/signers/contributing.md index 2ca2c2bda5..6c5cc571ff 100644 --- a/site/smart-accounts/signers/contributing.md +++ b/site/signers/contributing.md @@ -28,7 +28,7 @@ To ensure the best developer experience for anyone using Account Kit, we ask tha There, you'll be able to implement [`SmartAccountAuthenticator`](https://github.com/alchemyplatform/aa-sdk/blob/main/packages/core/src/signer/types.ts#L15) interface from `aa-core` which offers a wrapper for any SDKs, `inner`, that you may use to call upon for implementation details. You may also wish to build your Signer implementation from scratch. -In either case, if your `Signer` or library exports an `EIP-1193` compliant provider, you may find it helpful to use [`WalletClientSigner`](/packages/aa-core/signers/wallet-client) from `aa-core` to easily integrate your Signer in `aa-signers`. See the ["Using Your Own Signer"](/smart-accounts/signers/guides/custom-signer) guide for more details. +In either case, if your `Signer` or library exports an `EIP-1193` compliant provider, you may find it helpful to use [`WalletClientSigner`](/packages/aa-core/signers/wallet-client) from `aa-core` to easily integrate your Signer in `aa-signers`. See the ["Using Your Own Signer"](/signers/guides/custom-signer) guide for more details. Make sure to include unit tests along with your implementation! Take a look at these PRs from [Magic](https://github.com/alchemyplatform/aa-sdk/pull/229) and [Web3Auth](https://github.com/alchemyplatform/aa-sdk/pull/247) for reference. @@ -99,12 +99,12 @@ Find the `Choosing a Signer` item in the `sidebar` and add a new entry in `items // ... other entries { text: "Choosing a Signer", - base: "/smart-accounts/signers", + base: "/signers", items: [ { text: "Introduction", link: "/choosing-a-signer" }, { text: "Signer Guides", - base: "/smart-accounts/signers/guides", + base: "/signers/guides", collapsed: true, items: [ // ... other signers diff --git a/site/smart-accounts/signers/guides/arcana-auth.md b/site/signers/guides/arcana-auth.md similarity index 85% rename from site/smart-accounts/signers/guides/arcana-auth.md rename to site/signers/guides/arcana-auth.md index 753b9a496a..82127a6579 100644 --- a/site/smart-accounts/signers/guides/arcana-auth.md +++ b/site/signers/guides/arcana-auth.md @@ -57,11 +57,7 @@ Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `a ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { createArcanaAuthSigner } from "./arcana-auth"; @@ -69,18 +65,11 @@ const chain = sepolia; export async function getProvider() { const signer = await createArcanaAuthSigner(); - return new AlchemyProvider({ + return createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, - }).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: signer, - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) - ); + owner: signer, + }); } ``` diff --git a/site/smart-accounts/signers/guides/capsule.md b/site/signers/guides/capsule.md similarity index 87% rename from site/smart-accounts/signers/guides/capsule.md rename to site/signers/guides/capsule.md index b9b6d1fcce..fd05a75fbc 100644 --- a/site/smart-accounts/signers/guides/capsule.md +++ b/site/signers/guides/capsule.md @@ -77,28 +77,17 @@ Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `a ::: code-group ```ts [alchemy.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { createCapsuleSigner } from "./capsule"; const chain = sepolia; -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: await createCapsuleSigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createCapsuleSigner(), +}); ``` <<< @/snippets/signers/capsule.ts diff --git a/site/smart-accounts/signers/guides/custom-signer.md b/site/signers/guides/custom-signer.md similarity index 92% rename from site/smart-accounts/signers/guides/custom-signer.md rename to site/signers/guides/custom-signer.md index c10bf55fa8..53b9750ed1 100644 --- a/site/smart-accounts/signers/guides/custom-signer.md +++ b/site/signers/guides/custom-signer.md @@ -26,7 +26,7 @@ Account Kit is designed to be flexible and allow you to use any Signer you want. 2. If your Signer is an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compliant provider, you can leverage `viem`'s `WalletClient` and the [`WalletClientSigner`](/packages/aa-core/signers/wallet-client) (exported in `aa-core`). :::tip Note -If you want to add your Signer implementation to Account Kit's codebase, take a look at the [contibuting](/smart-accounts/signers/contributing) docs. We welcome Pull Requests onto the Github repo for [`aa-sdk`](https://github.com/alchemyplatform/aa-sdk)! +If you want to add your Signer implementation to Account Kit's codebase, take a look at the [contibuting](/signers/contributing) docs. We welcome Pull Requests onto the Github repo for [`aa-sdk`](https://github.com/alchemyplatform/aa-sdk)! ::: ## 1. Implementing `SmartAccountAuthenticator` or `SmartAccountSigner` diff --git a/site/smart-accounts/signers/guides/dfns.md b/site/signers/guides/dfns.md similarity index 78% rename from site/smart-accounts/signers/guides/dfns.md rename to site/signers/guides/dfns.md index e08fc157ea..de6b9b2dbf 100644 --- a/site/smart-accounts/signers/guides/dfns.md +++ b/site/signers/guides/dfns.md @@ -45,12 +45,7 @@ Setup the Dfns Web3 Provider and wrap it in an `AlchemyProvider`. ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; -import { encodeFunctionData, parseAbi } from "viem"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { createDfnsSigner } from "./dfns"; @@ -58,19 +53,12 @@ import { createDfnsSigner } from "./dfns"; const ALCHEMY_API_KEY = "API_KEY"; const chain = sepolia; -const createAlchemyProvider = async (): Promise => { - return new AlchemyProvider({ +const createAlchemyProvider = async () => { + return createModularAccountAlchemyClient({ apiKey: ALCHEMY_API_KEY, chain, - }).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: await createDfnsSigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) - ); + owner: await createDfnsSigner(), + }); }; ``` diff --git a/site/smart-accounts/signers/guides/dynamic.md b/site/signers/guides/dynamic.md similarity index 87% rename from site/smart-accounts/signers/guides/dynamic.md rename to site/signers/guides/dynamic.md index 6e5ec49371..77ca5746c8 100644 --- a/site/smart-accounts/signers/guides/dynamic.md +++ b/site/signers/guides/dynamic.md @@ -82,28 +82,17 @@ Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `a ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { dynamicSigner } from "./dynamic"; const chain = sepolia; -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: dynamicSigner, - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: dynamicSigner, +}); ``` <<< @/snippets/signers/dynamic.ts diff --git a/site/smart-accounts/signers/guides/eoa.md b/site/signers/guides/eoa.md similarity index 100% rename from site/smart-accounts/signers/guides/eoa.md rename to site/signers/guides/eoa.md diff --git a/site/smart-accounts/signers/guides/fireblocks.md b/site/signers/guides/fireblocks.md similarity index 89% rename from site/smart-accounts/signers/guides/fireblocks.md rename to site/signers/guides/fireblocks.md index 31bbcffa80..4d3eefc7a8 100644 --- a/site/smart-accounts/signers/guides/fireblocks.md +++ b/site/signers/guides/fireblocks.md @@ -58,27 +58,16 @@ Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `a ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { createFireblocksSigner } from "./fireblocks"; const chain = sepolia; -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain: rpcClient.chain, - owner: await createFireblocksSigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createFireblocksSigner(), +}); ``` <<< @/snippets/signers/fireblocks.ts diff --git a/site/smart-accounts/signers/guides/lit.md b/site/signers/guides/lit.md similarity index 85% rename from site/smart-accounts/signers/guides/lit.md rename to site/signers/guides/lit.md index 292a6c2b38..677fdeca5c 100644 --- a/site/smart-accounts/signers/guides/lit.md +++ b/site/signers/guides/lit.md @@ -79,26 +79,16 @@ We can link our `SmartAccountSigner` to a `LightSmartContractAccount` from `aa-a ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; +import { sepolia } from "@alchemy/aa-core"; import { createLitSigner } from "./lit"; const chain = sepolia; -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: await createLitSigner(AUTH_METHOD), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createLitSigner(AUTH_METHOD), +}); ``` ::: diff --git a/site/smart-accounts/signers/guides/magic.md b/site/signers/guides/magic.md similarity index 85% rename from site/smart-accounts/signers/guides/magic.md rename to site/signers/guides/magic.md index f24a5ef961..451ed3237f 100644 --- a/site/smart-accounts/signers/guides/magic.md +++ b/site/signers/guides/magic.md @@ -56,11 +56,7 @@ Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `a ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { createMagicSigner } from "./magic"; @@ -68,19 +64,11 @@ const chain = sepolia; // NOTE: the below is async because it depends on creating a magic Signer. You can choose to break that up how you want // e.g. use a useEffect + useState to create the Signer and then pass it down to the provider -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - entryPointAddress, - chain: rpcClient.chain, - owner: await createMagicSigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createMagicSigner(), +}); ``` <<< @/snippets/signers/magic.ts diff --git a/site/smart-accounts/signers/guides/particle-network.md b/site/signers/guides/particle-network.md similarity index 84% rename from site/smart-accounts/signers/guides/particle-network.md rename to site/signers/guides/particle-network.md index c30f74653d..e753310506 100644 --- a/site/smart-accounts/signers/guides/particle-network.md +++ b/site/signers/guides/particle-network.md @@ -57,29 +57,16 @@ Next, setup the Particle SDK and create an authenticated `ParticleSigner` using ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; -import { getDefaultEntryPointAddress } from "@alchemy/aa-core"; -import { polygonMumbai } from "@alchemy/aa-core"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; +import { sepolia } from "@alchemy/aa-core"; import { createParticleSigner } from "./particle"; const chain = polygonMumbai; -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: process.env.ALCHEMY_API_KEY, chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - entryPointAddress: getDefaultEntryPointAddress(chain), - chain: rpcClient.chain, - owner: await createParticleSigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createParticleSigner(), +}); ``` <<< @/snippets/signers/particle.ts diff --git a/site/smart-accounts/signers/guides/portal.md b/site/signers/guides/portal.md similarity index 81% rename from site/smart-accounts/signers/guides/portal.md rename to site/signers/guides/portal.md index 5bdcfcc562..8b8a841c12 100644 --- a/site/smart-accounts/signers/guides/portal.md +++ b/site/signers/guides/portal.md @@ -56,27 +56,17 @@ Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `a ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; -import { polygonMumbai } from "@alchemy/aa-core"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; +import { sepolia } from "@alchemy/aa-core"; import { createPortalSigner } from "./portal"; -const chain = polygonMumbai; -const provider = new AlchemyProvider({ - apiKey: process.env.ALCHEMY_API_KEY, +const chain = sepolia; + +const provider = await createModularAccountAlchemyClient({ + apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: await createPortalSigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createPortalSigner(), +}); ``` <<< @/snippets/signers/portal.ts diff --git a/site/smart-accounts/signers/guides/privy.md b/site/signers/guides/privy.md similarity index 100% rename from site/smart-accounts/signers/guides/privy.md rename to site/signers/guides/privy.md diff --git a/site/smart-accounts/signers/guides/turnkey.md b/site/signers/guides/turnkey.md similarity index 85% rename from site/smart-accounts/signers/guides/turnkey.md rename to site/signers/guides/turnkey.md index e8ce9e9c86..88375360cb 100644 --- a/site/smart-accounts/signers/guides/turnkey.md +++ b/site/signers/guides/turnkey.md @@ -58,33 +58,21 @@ Next, setup the Turnkey SDK and create an authenticated `TurnkeySigner` using th ### Use it with Light Account -Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `aa-accounts`: +Let's see it in action with `aa-alchemy` and `ModularAccount` from `aa-accounts`: ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { createTurnkeySigner } from "./turnkey"; const chain = sepolia; -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - entryPointAddress, - chain: rpcClient.chain, - owner: await createTurnkeySigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createTurnkeySigner(), +}); ``` <<< @/snippets/signers/turnkey.ts diff --git a/site/smart-accounts/signers/guides/web3auth.md b/site/signers/guides/web3auth.md similarity index 86% rename from site/smart-accounts/signers/guides/web3auth.md rename to site/signers/guides/web3auth.md index 34ae8e9b8f..6160250f40 100644 --- a/site/smart-accounts/signers/guides/web3auth.md +++ b/site/signers/guides/web3auth.md @@ -56,28 +56,17 @@ Let's see it in action with `aa-alchemy` and `LightSmartContractAccount` from `a ::: code-group ```ts [example.ts] -import { AlchemyProvider } from "@alchemy/aa-alchemy"; -import { - LightSmartContractAccount, - getDefaultLightAccountFactoryAddress, -} from "@alchemy/aa-accounts"; +import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy"; import { sepolia } from "@alchemy/aa-core"; import { createWeb3AuthSigner } from "./web3auth"; const chain = sepolia; -const provider = new AlchemyProvider({ +const provider = await createModularAccountAlchemyClient({ apiKey: "ALCHEMY_API_KEY", chain, -}).connect( - (rpcClient) => - new LightSmartContractAccount({ - chain, - owner: await createWeb3AuthSigner(), - factoryAddress: getDefaultLightAccountFactoryAddress(chain), - rpcClient, - }) -); + owner: await createWeb3AuthSigner(), +}); ``` <<< @/snippets/signers/web3auth.ts diff --git a/site/smart-accounts/index.md b/site/smart-accounts/index.md index 50002a7d75..4f4cb668b8 100644 --- a/site/smart-accounts/index.md +++ b/site/smart-accounts/index.md @@ -21,7 +21,7 @@ prev: link: /smart-accounts/overview next: text: Choosing a Signer - link: /smart-accounts/signers/choosing-a-signer + link: /signers/choosing-a-signer --- # Choosing a Smart Account diff --git a/site/third-party/bundlers.md b/site/third-party/bundlers.md new file mode 100644 index 0000000000..51e1e88e38 --- /dev/null +++ b/site/third-party/bundlers.md @@ -0,0 +1,73 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: 3rd Party Bundlers + - - meta + - name: description + content: Learn how to use a different RPC provider with Account Kit + - - meta + - property: og:description + content: Learn how to use a different RPC provider with Account Kit + - - meta + - name: twitter:title + content: 3rd Party Bundlers + - - meta + - name: twitter:description + content: Learn how to use a different RPC provider with Account Kit +--- + +# Using a different RPC Provider + +The `SmartAccountClient` within `@alchemy/aa-core` is unopinionated about which bundler you use, so you can connect to any RPC provider really simply. + +## Usage + +If we look at the example for creating a `SmartAccountClient`: + +<<< @/snippets/aa-core/smartAccountClient.ts + +You can see that we set the `transport` to `http("https://polygon-mumbai.g.alchemy.com/v2/demo")`. You can swap out that the url in the `http` function to +any other provider's URL. + +::: warning +Depending on your provider, you may have to pass in custom logic for the `gasEstimator` and `feeEstimator` properties when calling `createSmartAccountClient`. Consult +with your provider on what the correct logic is. +::: + +## Splitting Bundler traffic and Node RPC traffic + +It might be the case that you want to use a different RPC provider for your bundler traffic and your node traffic. This is a common use case, and you can do this by passing in a custom transport function to your `createSmartAccountClient` call. For example: + +```ts +import { createSmartAccountClient } from "@alchemy/aa-core"; +import { sepolia } from "viem"; + +const chain = sepolia; +const client = createSmartAccountClient({ + chain, + transport: (opts) => { + const bundlerRpc = http("BUNDLER_RPC_URL")(opts); + const publicRpc = http("OTHER_RPC_URL")(opts); + + return custom({ + request: async (args) => { + const bundlerMethods = new Set([ + "eth_sendUserOperation", + "eth_estimateUserOperationGas", + "eth_getUserOperationReceipt", + "eth_getUserOperationByHash", + "eth_supportedEntryPoints", + ]); + + if (bundlerMethods.has(args.method)) { + return bundlerRpc.request(args); + } else { + return publicRpc.request(args); + } + }, + })(opts); + }, +}); +``` diff --git a/site/third-party/paymasters.md b/site/third-party/paymasters.md new file mode 100644 index 0000000000..5f454ebc21 --- /dev/null +++ b/site/third-party/paymasters.md @@ -0,0 +1,48 @@ +--- +outline: deep +head: + - - meta + - property: og:title + content: 3rd Paymasters + - - meta + - name: description + content: Learn how to use a 3rd Party Paymaster with Account Kit + - - meta + - property: og:description + content: Learn how to use a 3rd Party Paymaster with Account Kit + - - meta + - name: twitter:title + content: 3rd Paymasters + - - meta + - name: twitter:description + content: Learn how to use a 3rd Party Paymaster with Account Kit +--- + +# Using a 3rd Party Paymaster + +The `SmartAccountClient` within `@alchemy/aa-core` is unopinionated about which paymaster you use, so you can connect to any paymaster really simply. Configuration is done using the the `paymasterAndData` config option when you call `createSmartAccountClient`. + +## Usage + +```ts +import { createSmartAccountClient } from "@alchemy/aa-core"; +import { sepolia } from "viem"; + +const chain = sepolia; +const client = createSmartAccountClient({ + chain, + transport: http("RPC_URL"), + paymasterAndData: { + paymasterAndData: async (userop, opts) => { + // call your paymaster here to sponsor the userop + // leverage the `opts` field to apply any overrides + return { + ...userop, + paymasterAndData: "0xresponsefromprovider" + } + }, + dummyPaymasterAndData: () => "0xnonrevertingpaymasterandata, + }, +}); + +``` diff --git a/site/using-smart-accounts/transfer-ownership/light-account.md b/site/using-smart-accounts/transfer-ownership/light-account.md index cc2442e219..4e9f003572 100644 --- a/site/using-smart-accounts/transfer-ownership/light-account.md +++ b/site/using-smart-accounts/transfer-ownership/light-account.md @@ -39,7 +39,6 @@ There a number of ways you can call this method using Account Kit. ::: code-group ```ts [example.ts] -import { transferLightAccountOwnership } from "@alchemy/aa-accounts"; import { smartAccountClient } from "./smartAccountClient"; // this will return the address of the smart account you want to transfer ownerhip of @@ -47,13 +46,13 @@ const accountAddress = await provider.getAddress(); const newOwner = "0x..."; // the address of the new owner // [!code focus:99] -const hash = transferLightAccountOwnership(smartAccountClient, { +const hash = smartAccountClient.transferOwnership({ newOwner, waitForTxn: true, }); ``` -<<< @/snippets/aa-core/smartAccountClient.ts +<<< @/snippets/aa-alchemy/light-account-client.ts [smartAccountClient.ts] :::