diff --git a/docs/pages/global-address/index.mdx b/docs/pages/global-address/index.mdx index 6675d61..9e0d2b2 100644 --- a/docs/pages/global-address/index.mdx +++ b/docs/pages/global-address/index.mdx @@ -1,19 +1,19 @@ -# Smart Routing Address +# Smart routing address -**Smart Routing Address** enables users to easily deposit funds to a L2/L3 from any CEXs, fiat onramps, and chains, by simply sending funds to a unique deposit address on any chain. +**Smart Routing Address** enables users to easily deposit funds to an L2/L3 from any CEXs, fiat on-ramps, and chains, by simply sending funds to a unique deposit address on any chain. -Technically, **Smart Routing Address** is an address that encodes a _cross-chain intent_. **When anyone sends funds to a smart routing address on _any chain_, they are funding the intent and thereby triggering the intent on a _specific destination chain_.** In other words, smart routing address is _source-chain agnostic_, but _target-chain specific_. +Technically, **Smart Routing Address** is an address that encodes a _cross-chain intent_. **When anyone sends funds to a smart routing address on _any chain_, they are funding the intent and thereby triggering the intent on a _specific destination chain_.** In other words, a smart routing address is _source-chain-agnostic_, but _target-chain-specific_. -## Common Use Cases +## Common use cases - Sending funds from CEXs directly to an L2/L3. -- Using a fiat onramp with a L2/L3, even if the onramp doesn't directly support the L2/L3. +- Using a fiat on-ramp with an L2/L3, even if the on-ramp doesn't directly support the L2/L3. - Depositing into a token vault with funds from another chain. - Cross-chain transfers. -## Try Smart Routing Address +## Try smart routing address -You can try using smart routing address at [the official portal](https://smart-routing-address.zerodev.app/). +You can use the smart routing address at [the official portal](https://smart-routing-address.zerodev.app/). Should your users send the wrong tokens to their smart routing address, they can also use the portal to retrieve their funds. @@ -41,15 +41,15 @@ bun add @zerodev/smart-routing-address ## Usage -Smart routing address has a beautifully simple API: just `createSmartRoutingAddress` and then send funds to it. That's really it. +The Smart Routing Address has a beautifully simple API: create a Smart Routing Address and then send funds to it. That’s really it. -### Code Example +### Code example We recommend that you take a look at [our code example](https://github.com/zerodevapp/smart-routing-address-example) (even better if you try running it) as you follow along the docs. ### Creating a smart routing address -In the following example, we are going to create a smart routing address that, when receiving funds on any chain, will transfer the funds to a specific address on Base. This is helpful when, for instance, you want to create a deposit address for your user, so that they can send funds to the address on any chain (possibly from a CEX), and then they will receive funds in their wallet on the chain that your app runs on. +In the following example, we will create a smart routing address that, when receiving funds on any chain, transfers them to a specific address on Base. This is helpful when, for instance, you want to create a deposit address for your user so they can send funds to the address on any chain (possibly from a CEX), and then receive them in their wallet on the chain your app runs on. First import some types and functions: @@ -113,25 +113,25 @@ const { smartRoutingAddress } = await createSmartRoutingAddress({ The options are: -- `owner` is an address that is authorized to recover funds from the smart routing address, in case the smart routing address fails to execute the target action for whatever reason. Typically you would set this to your user's EOA wallet, but you could also set it to your own address if you want to recover funds for users. +- `owner`: is an address authorized to recover funds from the smart routing address if the smart routing address fails to execute the target action for any reason. Typically, you would set this to your user’s EOA wallet, but you could also set it to your own address if you want to recover funds for users. -- `destChain` is the chain on which the `actions` are supposed to happen. This is presumably the chain that your app runs on. +- `destChain`: is the chain on which the `actions` are supposed to happen. This is presumably the chain that your app runs on. -- `srcTokens` is a list of tokens that the smart routing address should be able to receive. Only tokens listed in `srcTokens` will trigger actions on the destination. The other tokens sent to the address will have to be manually recovered by the `owner`. +- `srcTokens`: is a list of tokens that the smart routing address can receive. Only tokens listed in `srcTokens` will trigger actions on the destination. The other tokens sent to the address will need to be recovered manually by the `owner`. -- `actions` is a map that records which action will be triggered by which token. In the example above, we specified an action that will be triggered when the smart routing address receives `USDC`. +- `actions`: is a map that records which action will be triggered by which token. In the example above, we specified an action that will be triggered when the smart routing address receives `USDC`. -- `slippage` is the _maximum_ slippage that the user can expect. `slippage` is an integer, where 1 is equal to 0.01% (so 100 would mean 1% slippage). You can skip this param if you are unsure what to set, and the SDK will estimate a reasonable slippage based on your other settings. +- `slippage`: is the _maximum_ slippage that the user can expect. `slippage` is an integer, where 1 is equal to 0.01% (so 100 would mean 1% slippage). You can skip this parameter if you are unsure what to set, and the SDK will estimate a reasonable slippage based on your other settings. Once you have created a smart routing address, you can send tokens to it on any of the chains specified in `srcTokens`, and the `actions` will happen on the `destChain`. It's really that simple. -## Fee Sponsorship +## Fee sponsorship By default, Smart Routing Address deducts usage fees from the user's transferred tokens. However, as a developer, you can sponsor these fees so your users receive the full amount they deposit. -**Example**: When a user deposits 10 USDC to their smart routing address, they will receive exactly 10 USDC on the destination chain, while your dapp pays the usage fees separately. +**Example**: When a user deposits 10 `USDC` to their smart routing address, they will receive exactly 10 `USDC` on the destination chain, while your dapp pays the usage fees separately. -### Sponsored Fee Configuration +### Sponsored fee configuration To set up fee sponsorship, you must perform two steps: @@ -182,7 +182,7 @@ Only tokens that are **both** configured with the project ID in the code **and** ### Notes - Smart Routing Address integrates with bridges under the hood, so the usage pricing is on top of the underlying bridge fees. -- Pricing can be negotiated. Feel free to reach out. +- Pricing is negotiable. Feel free to [reach out](https://zerodev.app/contact). ## Supported chains diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 91c5cb0..6bc6d8e 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -1,29 +1,29 @@ -# ZeroDev Introduction +# ZeroDev introduction -**ZeroDev is the most powerful smart account solution**, with support for both ERC-4337 and [EIP-7702](/sdk/getting-started/quickstart-7702). +**ZeroDev is the most powerful smart account solution**, supporting both [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) and [EIP-7702](/sdk/getting-started/quickstart-7702). ZeroDev improves Web3 UX by enabling: - Key abstraction - - Login with [passkeys](/sdk/advanced/passkeys) or [social accounts](/sdk/signers/intro). + - Log in with [passkeys](/sdk/advanced/passkeys) or [social accounts](/sdk/signers/intro). - [Recover user accounts](/sdk/advanced/recovery) if they lose their login. - Gas abstraction - [Sponsor gas](/sdk/core-api/sponsor-gas) for users. - - Let users [pay gas with ERC20 tokens](/sdk/core-api/pay-gas-with-erc20s). + - Let users [pay for gas with `ERC-20` tokens](/sdk/core-api/pay-gas-with-erc20s). - Transaction abstraction - - [Batch multiple transactions](/sdk/core-api/batch-transactions) into one. No more tedious approvals. - - [Automate transactions](/sdk/permissions/intro) with session keys. Great for AI agents. + - [Batch multiple transactions](/sdk/core-api/batch-transactions) into one—no more tedious approvals. + - [Automate transactions](/sdk/permissions/intro) with session keys. Great for AI agents. - Chain abstraction - [Spend tokens on any chain](/sdk/advanced/chain-abstraction), without bridging. - - [On/offramp with any exchanges](/smart-routing-address), even on L2s. + - [On/off-ramp with any exchanges](/smart-routing-address), even on L2s. -ZeroDev can be used as a standalone embedded smart account, or used alongside WaaS solutions such as Privy and Dynamic. +ZeroDev can be used as a standalone embedded smart account or used alongside WaaS solutions such as Privy and Dynamic. -ZeroDev is the most trusted solution in AA, powering more than 6 million smart accounts on 50+ networks for 200+ teams. +ZeroDev is the most trusted solution for AA (account abstraction), powering more than 6 million smart accounts across 50+ networks for 200+ teams. -## Getting Started +## Getting started To start coding with ZeroDev, check out [the quickstart](/sdk/getting-started/quickstart) or [the tutorial](/sdk/getting-started/tutorial). diff --git a/docs/pages/meta-infra/api.mdx b/docs/pages/meta-infra/api.mdx index feb1483..d494dcc 100644 --- a/docs/pages/meta-infra/api.mdx +++ b/docs/pages/meta-infra/api.mdx @@ -1,3 +1,3 @@ # Admin API -ZeroDev infra can be configured through APIs. [Check out all our APIs here.](https://zerodev-api.readme.io/reference/getaddresbyeoav2) \ No newline at end of file +ZeroDev infrastructure is configurable through APIs. [Check out all our APIs here.](https://zerodev-api.readme.io/reference/getaddresbyeoav2) \ No newline at end of file diff --git a/docs/pages/meta-infra/custom-gas-policies.mdx b/docs/pages/meta-infra/custom-gas-policies.mdx index 57b6105..c4e5571 100644 --- a/docs/pages/meta-infra/custom-gas-policies.mdx +++ b/docs/pages/meta-infra/custom-gas-policies.mdx @@ -1,12 +1,12 @@ -# Custom Gas Policies +# Custom gas policies Custom gas policies enable you to tailor your sponsorship criteria using a webhook. This feature allows you to set up a custom policy that calls a URL you provide to determine whether to sponsor a transaction. -## Getting Started +## Getting started To utilize custom gas policies, you'll need to configure a webhook endpoint on your server. This endpoint will receive data from ZeroDev and must return a JSON response indicating whether to proceed with the transaction sponsorship. -### Setting up Your Webhook Endpoint +### Setting up your webhook endpoint **Endpoint Requirements:** @@ -14,7 +14,7 @@ To utilize custom gas policies, you'll need to configure a webhook endpoint on y - The `POST` request will include the `userOp`, `projectId`, and `chainId` in the body (see example below). - The request must return a `200` status with a JSON body indicating whether to proceed (see example below). -## Configuring Your Custom Policy +## Configuring your custom policy Sign in to your ZeroDev dashboard and navigate to the Gas Policies page. At the bottom of the page, you will find the Custom Policy form as shown below. @@ -25,11 +25,11 @@ Sign in to your ZeroDev dashboard and navigate to the Gas Policies page. At the Enter the following options: - **Webhook URL**: The full URL that the ZeroDev policy engine will make a POST request to. -- **Timeout Settings**: The amount of time the policy engine will wait for a response from your webhook URL. It's important to keep response times low to decrease latency for your end-users. -- **Policy Pass on Error**: Select this option to always pass the policy when an error occurs or the webhook times out. +- **Timeout Settings**: The amount of time the policy engine will wait for a response from your webhook URL. It’s important to keep response times low to reduce latency for your end users. +- **Policy Pass on Error**: Select this option always to pass the policy when an error occurs or the webhook times out. - **Enabling the Policy**: Toggle this option when you are ready to enable the policy for your project. -## Webhook Payload +## Webhook payload The `POST` request sent to your webhook URL will include the following: @@ -58,11 +58,11 @@ Here is an example request body: } ``` -## Expected Webhook Response +## Expected webhook response Your webhook should respond with a `200` status code and a JSON body indicating whether to proceed with the transaction. Additionally, you can specify how the webhook's decision interacts with ZeroDev's internal policy checks using an optional `logicalOperator` field. -### Response Fields: +### Response fields: - **`proceed`** (boolean, required): Indicates whether to sponsor the `userOp` (`true`) or not (`false`). - **`logicalOperator`** (string, optional): Defines how to combine the webhook's `proceed` value with ZeroDev's policy checks. @@ -72,9 +72,9 @@ Your webhook should respond with a `200` status code and a JSON body indicating - `'or'`: Proceed if either ZeroDev's policy checks or `proceed` is `true`. - Default: `'and'` (if the field is omitted). -### Example Webhook Responses: +### Example webhook responses: -#### Proceed using logical AND (default): +#### Proceed using logical `AND` (default): ```json { @@ -84,7 +84,7 @@ Your webhook should respond with a `200` status code and a JSON body indicating In this case, the transaction will proceed only if both ZeroDev's internal policy checks and the webhook return `true`. -#### Proceed using logical OR: +#### Proceed using logical `OR`: ```json { @@ -93,11 +93,11 @@ In this case, the transaction will proceed only if both ZeroDev's internal polic } ``` -With the `logicalOperator` set to `'or'`, the transaction will proceed if either ZeroDev's policy checks or the webhook approve it. +With the `logicalOperator` set to `'or'`, the transaction will proceed if either ZeroDev’s policy checks or the webhook approves it. -## Behavior of Transaction Approval +## Behavior of transaction approval -When a transaction is submitted, ZeroDev performs internal policy checks to determine if the transaction meets the predefined criteria (e.g., gas policies, rate limits). The result of these checks is combined with the webhook's `proceed` value based on the `logicalOperator`. +When a transaction is submitted, ZeroDev performs internal policy checks to determine whether it meets predefined criteria (e.g., gas policies, rate limits). The result of these checks is combined with the webhook's `proceed` value based on the `logicalOperator`. - **Logical AND (`'and'`):** @@ -105,15 +105,19 @@ When a transaction is submitted, ZeroDev performs internal policy checks to dete - **Logical OR (`'or'`):** - The transaction proceeds if either ZeroDev's policy checks or the webhook approve (`true`). + The transaction proceeds if either ZeroDev's policy checks or the webhook approves (`true`). -**Note:** If the `logicalOperator` field is omitted or contains an invalid value, it defaults to `'and'`. +:::note -## Example Webhook Server +If the `logicalOperator` field is omitted or contains an invalid value, it defaults to `'and'`. + +::: + +## Example webhook server To help you get started with implementing your custom gas policies, we've provided an example webhook server. This server demonstrates how you might receive and handle incoming webhook requests from ZeroDev. -The repository includes a basic server setup using Express.js, which listens for POST requests on a specified route. It logs the incoming data to the console and responds with a JSON object indicating whether to sponsor the transaction. +The repository includes a basic server setup with Express.js that listens for POST requests on a specified route. It logs incoming data to the console and returns a JSON object indicating whether to sponsor the transaction. You can find the example server [here](https://github.com/zerodevapp/example-webhook-server/tree/main). diff --git a/docs/pages/meta-infra/gas-policies.mdx b/docs/pages/meta-infra/gas-policies.mdx index 7004c7e..da13e6b 100644 --- a/docs/pages/meta-infra/gas-policies.mdx +++ b/docs/pages/meta-infra/gas-policies.mdx @@ -1,10 +1,10 @@ -# Gas Policies +# Gas policies -You can configure **gas policies** for ZeroDev paymaster to have fine-grained control over what you sponsor, and how much. +You can configure **gas policies** for the ZeroDev paymaster to have fine-grained control over what you sponsor and how much you sponsor. -Paymaster policies can be configured through either [the dashboard](https://dashboard.zerodev.app/paymasters) or [the API](/meta-infra/api). +Paymaster policies configurations are possible through either [the dashboard](https://dashboard.zerodev.app/paymasters) or [the API](/meta-infra/api). -## Policy Types +## Policy types There are four types of gas policies on ZeroDev: @@ -13,20 +13,20 @@ There are four types of gas policies on ZeroDev: - Wallet policies: policies that apply to specific wallet addresses. - [Custom policies](/meta-infra/custom-gas-policies): if none of the policies above meet your needs, you can program totally custom policies via a webhook. -## Rate Limit Types +## Rate limit types When you create a new policy, you set up one or more *rate limits*. There are four types of rate limits: -- Amount: limit by the amount of gas -- Request: limit by the number of requests -- Gas Price: limit by the current gas price -- Amount per txn: limit by the amount of gas per transaction +- **Amount**: limited by the amount of gas +- **Request**: limit by the number of requests +- **Gas Price**: limited by the current gas price +- **Amount per txn**: limit by the amount of gas per transaction ## Policy examples -The policies and rate limits are hopefully intuitive, but here are some common examples in case they are helpful. We will be using Polygon (MATIC) in these examples. +The policies and rate limits are hopefully intuitive, but here are some common examples in case they are helpful. We will be using Polygon (MATIC) in these examples. ### Sponsor up to 1 MATIC every hour for the entire project @@ -44,7 +44,7 @@ Here we create a contract policy:

-### Sponsor transactions for a specific function when gas price is below 50 GWEI +### Sponsor transactions for a specific function when the gas price is below 50 GWEI Here we create a contract policy: diff --git a/docs/pages/meta-infra/intro.mdx b/docs/pages/meta-infra/intro.mdx index e7d946c..fd1fad2 100644 --- a/docs/pages/meta-infra/intro.mdx +++ b/docs/pages/meta-infra/intro.mdx @@ -1,27 +1,27 @@ -# Meta AA Infrastructure +# Meta AA infrastructure -ZeroDev works with major AA infra providers to provide a "meta intrastructure." Our meta infra proxies traffic to the underlying bundlers and paymasters, ensuring that our users have the highest possible uptime, since traffic can be routed to a different bundler when one goes down. +ZeroDev works with major AA infra providers to provide a “meta infrastructure.” Our meta infra proxies traffic to the underlying bundlers and paymasters, ensuring that our users have the highest possible uptime, since traffic can be routed to a different bundler when one goes down. -ZeroDev integrates with the following infra provider: +ZeroDev integrates with the following infra providers: -- [UltraRelay](/sdk/core-api/sponsor-gas#ultrarelay), ZeroDev's own bundler optimized for sponsored transactions +- [UltraRelay](/sdk/core-api/sponsor-gas#ultrarelay) (ZeroDev’s own bundler is optimized for sponsored transactions) - Alchemy - Gelato - Pimlico -To get started using bundlers & paymasters through ZeroDev: +To get started using bundlers and paymasters through ZeroDev: ## Getting a ZeroDev RPC -You will need an RPC to start using bundlers & paymasters through ZeroDev. +You will need an RPC to start using bundlers and paymasters through ZeroDev. - Sign up at the ZeroDev dashboard - Create a project -- Copy the RPC from the project page (each network has an RPC). +- Copy the RPC from the project page (each network has an RPC) -The same RPC can be used as both bundler and paymaster RPCs. +The same RPC can serve as both a bundler and a paymaster RPC. -[Learn more about bundler & paymaster RPCs here](/meta-infra/rpcs). +[Learn more about bundler and paymaster RPCs here](/meta-infra/rpcs). ## Setting up sponsoring policies diff --git a/docs/pages/meta-infra/rpcs.mdx b/docs/pages/meta-infra/rpcs.mdx index 1faefe0..01899ce 100644 --- a/docs/pages/meta-infra/rpcs.mdx +++ b/docs/pages/meta-infra/rpcs.mdx @@ -2,26 +2,28 @@ To ensure utmost reliability for our customers, our RPCs use multiple bundlers under the hood, including: -- [UltraRelay](/sdk/core-api/sponsor-gas#ultrarelay), ZeroDev's own bundler optimized for sponsored transactions +- [UltraRelay](/sdk/core-api/sponsor-gas#ultrarelay) (ZeroDev's own bundler is optimized for sponsored transactions) - Alchemy - Gelato - Pimlico Our RPCs support all standard methods defined in the [ERC-4337 spec](https://eips.ethereum.org/EIPS/eip-4337). -By default, ZeroDev sends traffic to a provider that's known to work well on the given network. However, you can configure which specific provider to proxy traffic to, as described below. +By default, ZeroDev sends traffic to a provider that's known to work well on the given network. However, you can configure which specific provider to proxy traffic to, as described below. -You can find the bundler & paymaster RPCs for a specific ZeroDev project on the [ZeroDev dashboard](https://dashboard.zerodev.app/). +You can find the bundler and paymaster RPCs for a specific ZeroDev project on the [ZeroDev dashboard](https://dashboard.zerodev.app/). :::info -While you can in principle use a paymaster from one provider with a bundler from another provider, in practice different providers are sometimes incompatible, so we recommend that if you want to use a specific provider, you use it for both the bundler and the paymaster. + +While you can, in principle, use a paymaster from one provider with a bundler from another, in practice, different providers are sometimes incompatible, so we recommend that if you want to use a specific provider, you use it for both the bundler and the paymaster. + ::: ## Configuring the RPC for a specific infra provider -You can append the following query params (i.e. `?param=value`) to the RPC: +You can append the following query params (e.g., `?param=value`) to the RPC: -- `provider`, which specifies the underlying bundler to use. Possible values include: +- `provider`, which specifies the underlying bundler to use. Possible values include: - `ULTRA_RELAY` - `ALCHEMY` - `GELATO` diff --git a/docs/pages/react/getting-started.mdx b/docs/pages/react/getting-started.mdx index e76c1b5..10f438d 100644 --- a/docs/pages/react/getting-started.mdx +++ b/docs/pages/react/getting-started.mdx @@ -1,8 +1,8 @@ -# Getting Started +# Getting started -ZeroDev's React SDK is called `@zerodev/waas`, which stands for Wallet-as-a-Service. This is to signal that the React SDK provides higher-level abstractions over the [low-level SDK](/). +ZeroDev's React SDK is called `@zerodev/waas`, which stands for Wallet-as-a-Service. This signals that the React SDK provides higher-level abstractions over the [low-level SDK](/). -The relationship between `@zerodev/waas` and `@zerodev/sdk` is similar to the relationship between Wagmi and Viem. We recommend using `@zerodev/waas` in all React projects, and you can always ["drop down" to the SDK](/react/use-kernelclient) if you want lower-level control. +The relationship between `@zerodev/waas` and `@zerodev/sdk` is similar to the relationship between Wagmi and Viem. We recommend using `@zerodev/waas` in all React projects, and you can always ["drop down" to the SDK](/react/use-kernelclient) if you want lower-level control. ## Installation @@ -28,7 +28,7 @@ bun add @zerodev/waas wagmi viem@2.x @tanstack/react-query ## Setup -In typical React pattern, `@zerodev/waas` is set up via a provider. A typical setup may look like this: +In the typical React pattern, `@zerodev/waas` is set up via a provider. A typical setup may look like this: ```tsx import { ZeroDevProvider, createConfig as createZdConfig } from "@zerodev/waas" @@ -69,6 +69,6 @@ export default function Providers({ children }: { children: React.ReactNode }) { } ``` -## Next Steps +## Next steps -The best way to learn how to use `@zerodev/waas` is by looking at [the examples](https://github.com/zerodevapp/waas-examples) and browsing the hooks on the sidebar. \ No newline at end of file +The best way to learn how to use `@zerodev/waas` is to look at [the examples](https://github.com/zerodevapp/waas-examples) and browse the hooks in the sidebar. diff --git a/docs/pages/react/use-balance.mdx b/docs/pages/react/use-balance.mdx index 1884813..68aa533 100644 --- a/docs/pages/react/use-balance.mdx +++ b/docs/pages/react/use-balance.mdx @@ -1,6 +1,6 @@ import QueryResult from "../shared/query-result.mdx" -# useBalance [Hook for getting balance of kernel account] +# `useBalance` [Hook for getting the balance of the kernel account] ## Import ```tsx @@ -25,15 +25,15 @@ import { type UseBalanceParameters } from '@zerodev/waas'; `Address | undefined` -The address of owner, kernel account if not specified. +The owner's address (of the kernel account) is not specified. ### tokenAddress `Address | undefined` -The address of token contract, native token if not specified. +The address of the token contract, native token if not specified. -## Return Types +## Return types ```tsx import { type UseBalanceReturnType } from '@zerodev/waas' @@ -48,12 +48,12 @@ import { type UseBalanceReturnType } from '@zerodev/waas' ### data `GetBalanceReturnType | undefined` - ##### value - `BigInt` The amount of token owned. + `BigInt`: The amount of the token owned. - ##### decimals - `number` The decimals of the token. + `number`: The decimals of the token. - ##### symbol - `string` The symbol of the token. + `string`: The symbol of the token. - ##### formatted - `string` The formatted string. + `string`: The formatted string. \ No newline at end of file diff --git a/docs/pages/react/use-chainid.mdx b/docs/pages/react/use-chainid.mdx index 6a2b208..2ecf7b6 100644 --- a/docs/pages/react/use-chainid.mdx +++ b/docs/pages/react/use-chainid.mdx @@ -1,4 +1,4 @@ -# useChainId [Hook for getting current connected chain id] +# `useChainId` [Hook for getting current connected chain id] ## Import ```tsx @@ -18,7 +18,7 @@ function App() { No parameter needed. -## Return Types +## Return types ```tsx import { type UseChainIdReturnType } from '@zerodev/waas' diff --git a/docs/pages/react/use-chains.mdx b/docs/pages/react/use-chains.mdx index 3557404..d986a5e 100644 --- a/docs/pages/react/use-chains.mdx +++ b/docs/pages/react/use-chains.mdx @@ -1,4 +1,4 @@ -# useChains [Hook for getting configured chains] +# `useChains` [Hook for getting configured chains] ## Import ```tsx @@ -18,7 +18,7 @@ function App() { No parameter needed. -## Return Types +## Return types ```tsx import { type UseChainsReturnType } from '@zerodev/waas' diff --git a/docs/pages/react/use-create-basic-session.mdx b/docs/pages/react/use-create-basic-session.mdx index 82478f1..b995347 100644 --- a/docs/pages/react/use-create-basic-session.mdx +++ b/docs/pages/react/use-create-basic-session.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useCreateBasicSession [Hook for creating session for kernel v2 account] +# `useCreateBasicSession` [Hook for creating session for kernel v2 account] ## Import ```tsx @@ -48,7 +48,7 @@ function App() { No parameter needed. -## Return Types +## Return types ```tsx import { type UseCreateBasicSessionReturnType } from '@zerodev/waas' @@ -63,7 +63,7 @@ import { type UseCreateBasicSessionReturnType } from '@zerodev/waas' ### write `(variables: CreateBasicSessionVariables) => void` -The mutation function to create session for v2 kernel account. +The mutation function creates a session for the v2 kernel account. - #### variables - ##### permissions @@ -83,14 +83,14 @@ Similar to [write](#write) but returns a promise. ### data `CreateBasicSessionData | undefined` - ##### sessionKey - `0x${string}` The private key of the session. + `0x${string}`: The private key of the session. - ##### sessionId - `0x${string}` The id of the session. + `0x${string}`: The id of the session. - ##### smartAccount - `0x${string}` The address of smart account. + `0x${string}`: The address of the smart account. - ##### enableSignature - `0x${string}` The signature to enable session. + `0x${string}`: The signature to enable the session. - ##### permissions - `Permission[]` The permissions of the session. + `Permission[]`: The permissions of the session. \ No newline at end of file diff --git a/docs/pages/react/use-create-kernelclient-eoa.mdx b/docs/pages/react/use-create-kernelclient-eoa.mdx index e150fb9..57db912 100644 --- a/docs/pages/react/use-create-kernelclient-eoa.mdx +++ b/docs/pages/react/use-create-kernelclient-eoa.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useCreateKernelClientEOA [Hook for creating kernel client with EOA] +# `useCreateKernelClientEOA` [Hook for creating kernel client with EOA] ## Import ```tsx @@ -32,7 +32,7 @@ import { type UseCreateKernelClientEOAParameters } from '@zerodev/waas'; `v2 | v3` -The version of kernel account. +The version of the kernel account. ```tsx import { useCreateKernelClientEOA } from '@zerodev/waas'; @@ -41,7 +41,7 @@ function App() { } ``` -## Return Types +## Return types ```tsx import { type UseCreateKernelClientEOAReturnType } from '@zerodev/waas' @@ -56,7 +56,7 @@ import { type UseCreateKernelClientEOAReturnType } from '@zerodev/waas' ### connect `(variables: CreateKernelClientEOAVariables) => void` -The mutation function to connect eoa and create the kernel smart account. +The mutation function connects the EOA and creates the kernel smart account. - #### variables - ##### connector @@ -76,10 +76,10 @@ Similar to [connect](#connect) but returns a promise. ### data `CreateKernelClientEOAData | undefined` - ##### validator - `KernelValidator` The object of kernel validator. + `KernelValidator`: The object of the kernel validator. - ##### kernelAccount - `KernelSmartAccount` The object of kernel account. + `KernelSmartAccount`: The object of the kernel account. - ##### entryPoint - `EntryPoint` The entrypoint address of kernel account. + `EntryPoint`: The entrypoint address of the kernel account. \ No newline at end of file diff --git a/docs/pages/react/use-create-kernelclient-passkey.mdx b/docs/pages/react/use-create-kernelclient-passkey.mdx index e4b3e0f..9298ffe 100644 --- a/docs/pages/react/use-create-kernelclient-passkey.mdx +++ b/docs/pages/react/use-create-kernelclient-passkey.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useCreateKernelClientPasskey [Hook for creating kernel client with Passkey] +# `useCreateKernelClientPasskey` [Hook for creating kernel client with Passkey] ## Import ```tsx @@ -41,7 +41,7 @@ import { type UseCreateKernelClientPasskeyParameters } from '@zerodev/waas'; `v2 | v3` -The version of kernel account. +The version of the kernel account. ```tsx import { useCreateKernelClientPasskey } from '@zerodev/waas'; @@ -51,7 +51,7 @@ function App() { } ``` -## Return Types +## Return types ```tsx import { type UseCreateKernelClientPasskeyReturnType } from '@zerodev/waas' @@ -66,7 +66,7 @@ import { type UseCreateKernelClientPasskeyReturnType } from '@zerodev/waas' ### connectRegister `(variables: CreateKernelClientPasskeyVariables) => void` -The mutation function to register passkey and create the kernel smart account. +The mutation function registers the passkey and creates the kernel smart account. - #### variables - ##### username @@ -86,7 +86,7 @@ Similar to [connectRegister](#connectregister) but returns a promise. ### connectLogin `() => void` -The mutation function to login created passkey and create the kernel smart account. +The mutation function for login creates a passkey and creates the kernel smart account. ### connectLoginAsync `() => Promise` @@ -96,10 +96,10 @@ Similar to [connectLogin](#connectlogin) but returns a promise. ### data `CreateKernelClientPasskeyData | undefined` - ##### validator - `KernelValidator` The object of kernel validator. + `KernelValidator`: The object of the kernel validator. - ##### kernelAccount - `KernelSmartAccount` The object of kernel account. + `KernelSmartAccount`: The object of the kernel account. - ##### entryPoint - `EntryPoint` The entrypoint address of kernel account. + `EntryPoint`: The entrypoint address of the kernel account. \ No newline at end of file diff --git a/docs/pages/react/use-create-kernelclient-social.mdx b/docs/pages/react/use-create-kernelclient-social.mdx index fb45862..0713064 100644 --- a/docs/pages/react/use-create-kernelclient-social.mdx +++ b/docs/pages/react/use-create-kernelclient-social.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useCreateKernelClientSocial [Hook for creating a kernel client with social login integration] +# `useCreateKernelClientSocial` [Hook for creating a kernel client with social login integration] ## Import ```tsx @@ -39,7 +39,7 @@ import { type UseCreateKernelClientSocialParameters } from '@zerodev/waas'; `v2 | v3` -The version of kernel account. +The version of the kernel account. ```tsx import { useCreateKernelClientSocial } from '@zerodev/waas'; @@ -52,9 +52,9 @@ function App() { ### oauthCallbackUrl (optional) `string` -The callback URL for social login. After a successful login, the user will be redirected to this URL. Defaults to the current URI of your application if not specified. +The callback URL for social login. After a successful login, the user will get redirected to this URL. Defaults to the current URI of your application if not specified. -## Return Types +## Return types ```tsx import { type UseCreateKernelClientSocialReturnType } from '@zerodev/waas' @@ -78,10 +78,10 @@ The function to trigger the redirect to your social provider for login. ### data `CreateKernelClientSocialReturnType | undefined` - ##### validator - `KernelValidator` The object of kernel validator. + `KernelValidator`: The object of the kernel validator. - ##### kernelAccount - `KernelSmartAccount` The object of kernel account. + `KernelSmartAccount`: The object of the kernel account. - ##### entryPoint - `EntryPoint` The entrypoint address of kernel account. + `EntryPoint`: The entrypoint address of the kernel account. \ No newline at end of file diff --git a/docs/pages/react/use-create-session.mdx b/docs/pages/react/use-create-session.mdx index f55770a..6d362c3 100644 --- a/docs/pages/react/use-create-session.mdx +++ b/docs/pages/react/use-create-session.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useCreateSession [Hook for creating session for kernel v3 account] +# `useCreateSession` [Hook for creating session for kernel v3 account] ## Import ```tsx @@ -32,7 +32,7 @@ function App() { No parameter needed. -## Return Types +## Return types ```tsx import { type UseCreateSessionReturnType } from '@zerodev/waas' @@ -47,7 +47,7 @@ import { type UseCreateSessionReturnType } from '@zerodev/waas' ### write `(variables: CreateSessionVariables) => void` -The mutation function to create session for v3 kernel account. +The mutation function creates a session for the v3 kernel account. - #### variables - ##### policies @@ -75,12 +75,12 @@ Similar to [write](#write) but returns a promise. The id of the session. - ##### smartAccount `0x${string}` - The address of smart account. + The address of the smart account. - ##### enableSignature `0x${string}` - The signature to enable session. + The signature to enable the session. - ##### policies `Policy[]` - The policies of session. + The policies of the session. \ No newline at end of file diff --git a/docs/pages/react/use-disconnect-kernelclient.mdx b/docs/pages/react/use-disconnect-kernelclient.mdx index 377b0da..aad256a 100644 --- a/docs/pages/react/use-disconnect-kernelclient.mdx +++ b/docs/pages/react/use-disconnect-kernelclient.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useDisconnectKernelClient [Hook for disconnecting kernel account client] +# `useDisconnectKernelClient` [Hook for disconnecting kernel account client] ## Import ```tsx @@ -26,7 +26,7 @@ function App() { No parameter needed. -## Return Types +## Return types ```tsx import { type UseDisconnectKernelClientReturnType } from '@zerodev/waas' @@ -41,7 +41,7 @@ import { type UseDisconnectKernelClientReturnType } from '@zerodev/waas' ### disconnect `() => void` -The mutation function to disconnect kernel client. +The mutation function disconnects the kernel client. ### disconnectAsync `() => Promise` @@ -52,6 +52,6 @@ Similar to [disconnect](#disconnect) but returns a promise. `boolean | undefined` - Defaults to `undefined` -- The last successfully resolved data for the mutation. +- The last successfully resolved data for the mutation \ No newline at end of file diff --git a/docs/pages/react/use-kernelclient.mdx b/docs/pages/react/use-kernelclient.mdx index 7757e6e..0ec85b8 100644 --- a/docs/pages/react/use-kernelclient.mdx +++ b/docs/pages/react/use-kernelclient.mdx @@ -1,6 +1,6 @@ import QueryResult from "../shared/query-result.mdx" -# useKernelClient [Hook for getting kernel account client] +# `useKernelClient` [Hook for getting kernel account client] ## Import ```tsx @@ -31,9 +31,9 @@ The paymaster type and gas token address. The type of paymaster. #### gasToken `string | undefined` - The symbol of erc20 token used for erc20 paymaster. + The symbol of the `ERC-20` token used for the `ERC-20` paymaster. -## Return Types +## Return types ```tsx import { type UseKernelClientReturnType } from '@zerodev/waas' @@ -42,7 +42,7 @@ import { type UseKernelClientReturnType } from '@zerodev/waas' ### address `Address | undefined` -The address of connected kernel account. +The address of the connected kernel account. ### kernelAccount `KernelSmartAccount | undefined` diff --git a/docs/pages/react/use-send-transaction-with-session.mdx b/docs/pages/react/use-send-transaction-with-session.mdx index 1027f82..900d2a7 100644 --- a/docs/pages/react/use-send-transaction-with-session.mdx +++ b/docs/pages/react/use-send-transaction-with-session.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useSendTransactionWithSession [Hooks for sending transactions with session keys] +# `useSendTransactionWithSession` [Hooks for sending transactions with session keys] ## Import ```tsx @@ -41,7 +41,7 @@ import { type UseSendTransactionWithSessionParameters } from '@zerodev/waas'; `0x${tring}` -The sessionId of session used to send user operation +The sessionId of the session used to send the user operation. ### paymaster `{type: "SPONSOR"} | {type: "ERC20", gasToken: string} | undefined` @@ -52,20 +52,20 @@ The paymaster type and gas token address. The type of paymaster. - #### gasToken `string | undefined` - The symbol of erc20 token used for erc20 paymaster. + The symbol of the `ERC-20` token used for the `ERC-20` paymaster. ### isParallel `boolean | undefined` - Default to `True` -- The flag determine whether the user operation allows parallel execution. +- The flag determines whether the user operation allows parallel execution. ### nonceKey `string | undefined` -The key to generate nonce for userop. +The key to generating a nonce for userop. -## Return Types +## Return types ```tsx import { type UseSendTransactionWithSessionReturnType } from '@zerodev/waas' @@ -80,7 +80,7 @@ import { type UseSendTransactionWithSessionReturnType } from '@zerodev/waas' ### write `(variables: SendTransactionWithSessionVariables) => void` -The mutation function to send transactions with session. +The mutation function sends transactions with a session. - #### variables - ##### to diff --git a/docs/pages/react/use-send-transaction.mdx b/docs/pages/react/use-send-transaction.mdx index 922410f..54d302c 100644 --- a/docs/pages/react/use-send-transaction.mdx +++ b/docs/pages/react/use-send-transaction.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useSendTransaction [Hook for sending transaction] +# `useSendTransaction` [Hook for sending transaction] ## Import ```tsx @@ -47,20 +47,20 @@ The paymaster type and gas token address. The type of paymaster. #### gasToken `string | undefined` - The symbol of erc20 token used for erc20 paymaster. + The symbol of the `ERC-20` token used for the `ERC-20` paymaster. ### isParallel `boolean | undefined` - Default to `True` -- The flag determine whether the user operation allows parallel execution. +- The flag determines whether the user operation allows parallel execution. ### nonceKey `string | undefined` -The key to generate nonce for userop. +The key to generating a nonce for userop. -## Return Types +## Return types ```tsx import { type UseSendTransactionReturnType } from '@zerodev/waas' @@ -75,7 +75,7 @@ import { type UseSendTransactionReturnType } from '@zerodev/waas' ### write `(variables: SendTransactionVariables) => void` -The mutation function to send transactions. +The mutation function sends transactions. - #### variables - ##### to diff --git a/docs/pages/react/use-send-useroperation-with-session.mdx b/docs/pages/react/use-send-useroperation-with-session.mdx index f902bde..40e8335 100644 --- a/docs/pages/react/use-send-useroperation-with-session.mdx +++ b/docs/pages/react/use-send-useroperation-with-session.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useSendUserOperationWithSession [Hooks for sending user operation with session keys] +# `useSendUserOperationWithSession` [Hooks for sending user operation with session keys] ## Import ```tsx @@ -46,8 +46,7 @@ import { type UseSendUserOperationWithSessionParameters } from '@zerodev/waas'; `0x${tring}` -The sessionId of session used to send user operation - +The sessionId of the session used to send the user operation. ### paymaster `{type: "SPONSOR"} | {type: "ERC20", gasToken: string} | undefined` @@ -58,20 +57,20 @@ The paymaster type and gas token address. The type of paymaster. - #### gasToken `string | undefined` - The symbol of erc20 token used for erc20 paymaster. + The symbol of the `ERC-20` token used for the `ERC-20` paymaster. ### isParallel `boolean | undefined` - Default to `True` -- The flag determine whether the user operation allows parallel execution. +- The flag determines whether the user operation allows parallel execution. ### nonceKey `string | undefined` -The key to generate nonce for userop. +The key to generating a nonce for userop. -## Return Types +## Return types ```tsx import { type UseSendUserOperationWithSessionReturnType } from '@zerodev/waas' @@ -86,7 +85,7 @@ import { type UseSendUserOperationWithSessionReturnType } from '@zerodev/waas' ### write `(variables: SendUserOperationWithSessionVariables) => void` -The mutation function to send useroperation with session. +The mutation function sends the user's operation along with the session. - #### variables - ##### address diff --git a/docs/pages/react/use-send-useroperation.mdx b/docs/pages/react/use-send-useroperation.mdx index 0bb9fa0..2f0799e 100644 --- a/docs/pages/react/use-send-useroperation.mdx +++ b/docs/pages/react/use-send-useroperation.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useSendUserOperation [Hook for sending user operation] +# `useSendUserOperation` [Hook for sending user operation] ## Import ```tsx @@ -52,20 +52,20 @@ The paymaster type and gas token address. The type of paymaster. #### gasToken `string | undefined` - The symbol of erc20 token used for erc20 paymaster. + The symbol of the `ERC-20` token used for the `ERC-20` paymaster. ### isParallel `boolean | undefined` - Default to `True` -- The flag determine whether the user operation allows parallel execution. +* The flag determines whether the user's operation allows parallel execution. ### nonceKey `string | undefined` -The key to generate nonce for userop. +The key to generating a nonce for userop. -## Return Types +## Return types ```tsx import { type UseSendUserOperationReturnType } from '@zerodev/waas' @@ -80,7 +80,7 @@ import { type UseSendUserOperationReturnType } from '@zerodev/waas' ### write `(variables: SendUserOperationVariables) => void` -The mutation function to send useroperation. +The mutation function sends the user's operation. - #### variables - ##### address diff --git a/docs/pages/react/use-session-kernelclient.mdx b/docs/pages/react/use-session-kernelclient.mdx index 9f4bbf1..e6f7842 100644 --- a/docs/pages/react/use-session-kernelclient.mdx +++ b/docs/pages/react/use-session-kernelclient.mdx @@ -1,6 +1,6 @@ import QueryResult from "../shared/query-result.mdx" -# useSessionKernelClient [Hook for getting kernel account client with session plugin] +# `useSessionKernelClient` [Hook for getting kernel account client with session plugin] ## Import ```ts @@ -26,7 +26,7 @@ import { type UseSessionKernelClientParameters } from '@zerodev/waas'; `0x${string}` -The sessionId of session used to send user operation. +The sessionId of the session used to send user operations. ### paymaster `{type: "SPONSOR"} | {type: "ERC20", gasToken: string} | undefined` @@ -37,9 +37,9 @@ The paymaster type and gas token address. The type of paymaster. - #### gasToken `string | undefined` - The symbol of erc20 token used for erc20 paymaster. + The `ERC-20` token symbol is used for the `ERC-20` paymaster. -## Return Types +## Return types ```tsx import { type UseKernelClientReturnType } from '@zerodev/waas' @@ -54,11 +54,11 @@ import { type UseSessionKernelClientReturnType } from '@zerodev/waas' ### kernelAccount `KernelSmartAccount | null` -The current kernel account with session plugin. +The current kernel account has a session plugin. ### kernelClient `KernelAccountClient` -The current kernel account client with session plugin. +The current kernel account client with the session plugin. \ No newline at end of file diff --git a/docs/pages/react/use-sessions.mdx b/docs/pages/react/use-sessions.mdx index 8204d11..b7cff1d 100644 --- a/docs/pages/react/use-sessions.mdx +++ b/docs/pages/react/use-sessions.mdx @@ -1,4 +1,4 @@ -# useSessions [Hook for getting sessions] +# `useSessions` [Hook for getting sessions] ## Import ```tsx @@ -18,7 +18,7 @@ function App() { No parameter needed. -## Return Types +## Return types ```tsx import { type UseSessionsReturnType } from '@zerodev/waas' @@ -27,7 +27,7 @@ import { type UseSessionsReturnType } from '@zerodev/waas' ### sessions `[sessionId: string]: SessionInfoType | null` -The session used in the smart account. +The session that is being used in the smart account. - SessionInfoType - ##### sessionKey @@ -38,13 +38,13 @@ The session used in the smart account. The id of the session. - ##### smartAccount `0x${string}` - The address of smart account. + The address of the smart account. - ##### enableSignature `0x${string}` - The signature to enable session. + The signature to enable the session. - ##### policies `Policy[]` - The policies of session. + The policies of the session. - ##### permissions `Permission[]` The permissions of the session. \ No newline at end of file diff --git a/docs/pages/react/use-set-kernelclient.mdx b/docs/pages/react/use-set-kernelclient.mdx index 143d49c..62a5b89 100644 --- a/docs/pages/react/use-set-kernelclient.mdx +++ b/docs/pages/react/use-set-kernelclient.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useSetKernelClient [Hook for setting kernel account client] +# `useSetKernelClient` [Hook for setting kernel account client] ## Import ```tsx @@ -32,7 +32,7 @@ function App() { No parameter needed. -## Return Types +## Return types ```tsx import { type UseSetKernelClientReturnType } from '@zerodev/waas' @@ -47,7 +47,7 @@ import { type UseSetKernelClientReturnType } from '@zerodev/waas' ### setKernelClient `(kernelClient: KernelAccountClient) => void` -The mutation function to set kernel client. +The mutation function sets the kernel client. ### setKernelClientAsync `(kernelClient: KernelAccountClient) => Promise` diff --git a/docs/pages/react/use-switch-chain.mdx b/docs/pages/react/use-switch-chain.mdx index bcb8e10..8ec3a66 100644 --- a/docs/pages/react/use-switch-chain.mdx +++ b/docs/pages/react/use-switch-chain.mdx @@ -1,6 +1,6 @@ import MutationResult from '../shared/mutation-result.mdx' -# useSwitchChain [Hook for switching chain] +# `useSwitchChain` [Hook for switching chain] ## Import ```tsx @@ -29,7 +29,7 @@ function App() { import { type UseSwitchChainParameters } from '@zerodev/waas'; ``` -## Return Types +## Return types ```tsx import { type UseSwitchChainReturnType } from '@zerodev/waas' @@ -44,12 +44,12 @@ import { type UseSwitchChainReturnType } from '@zerodev/waas' ### switchChain `(variables: SwitchChainVariables) => void` -The mutation function to swich chain. +The mutation function that switches chains. - #### variables - ##### chainId `number` - ID of chain to switch to. + ID of the chain to switch to. ### switchChainAsync `(variables: SwitchChainVariables) => Promise` @@ -59,10 +59,9 @@ Similar to [switchChain](#switchchain) but returns a promise. - #### variables - ##### chainId `number` - ID of chain to switch to. + ID of the chain to switch to. ### data `SwitchChainData | undefined` - \ No newline at end of file diff --git a/docs/pages/react/use-wallet-connect.mdx b/docs/pages/react/use-wallet-connect.mdx index 4dcfbcc..52e740f 100644 --- a/docs/pages/react/use-wallet-connect.mdx +++ b/docs/pages/react/use-wallet-connect.mdx @@ -1,8 +1,8 @@ -# useWalletConnect +# `useWalletConnect` Do you want your users to be able to use their smart accounts with other DApps? If so, you can integrate ZeroDev with WalletConnect. -The useWalletConnect hook from the `@zerodev/waas` package integrates WalletConnect functionality with a React application, providing an interface for connecting to WalletConnect, handling session proposals, requests, and managing connections. +The `useWalletConnect` hook from the `@zerodev/waas` package integrates WalletConnect functionality into a React application, providing an interface for connecting to WalletConnect, handling session proposals and requests, and managing connections. ## Import @@ -45,7 +45,7 @@ const App = () => { export default App; ``` -For a practical demonstration of how `useWalletConnect` can be implemented in a project, check out our [live demo](https://wallet-connect-demo.onrender.com). You can also explore the [source code of the demo](https://github.com/zerodevapp/waas-wallet-connect-demo) for a deeper understanding and more detailed examples. +For a practical demonstration of how to implement `useWalletConnect` in a project, check out our [live demo](https://wallet-connect-demo.onrender.com). You can also explore the [demo's source code](https://github.com/zerodevapp/waas-wallet-connect-demo) for a deeper understanding and more detailed examples. ## Parameters @@ -75,7 +75,7 @@ interface Metadata { Please refer to the WalletConnect documentation for more information on the metadata and projectId. -## Return Types +## Return types ```tsx import { type UseWalletConnectReturnType } from '@zerodev/waas' @@ -88,7 +88,7 @@ import { type UseWalletConnectReturnType } from '@zerodev/waas' ### `approveSessionProposal(proposalData?: Web3WalletTypes.SessionProposal)` - Function to approve a session proposal. -- Parameter `proposalData` is optional and should conform to the `Web3WalletTypes.SessionProposal` from `@walletconnect/web3wallet`. +- The parameter `proposalData` is optional and should conform to `Web3WalletTypes.SessionProposal` from `@walletconnect/web3wallet`. ### `rejectSessionProposal()` @@ -117,11 +117,11 @@ import { type UseWalletConnectReturnType } from '@zerodev/waas' ### `isLoading` -- Enum for loading states including 'Approve', 'Reject', 'Connect', 'Disconnect'. +- Enum for loading states including 'Approve', 'Reject', 'Connect', and 'Disconnect'. ### `sessions` -- Array of active sessions. +- An array of active sessions. ### `error` diff --git a/docs/pages/recovery-flow/intro.md b/docs/pages/recovery-flow/intro.md index 985642b..3391a9a 100644 --- a/docs/pages/recovery-flow/intro.md +++ b/docs/pages/recovery-flow/intro.md @@ -1,13 +1,13 @@ -# Recovery Flow +# Recovery flow -ZeroDev provides a set of pre-built UIs to quickly integrate account recovery into your project. These are collectively referred to as "recovery flow." +ZeroDev provides a set of pre-built UIs to integrate account recovery into your project quickly. These are collectively referred to as “recovery flow.” -The recovery flow works with Kernel accounts that have set up recovery using the official recovery plugin. There are two ways to set up recovery: +The recovery flow works with Kernel accounts that have set up recovery using the official recovery plugin. There are two ways to set up recovery: -- [Using our pre-built recovery setup UI.](/recovery-flow/setup) +- [Using our pre-built recovery setup UI](/recovery-flow/setup): - This is super easy to integrate with. -- [Using ZeroDev.](/sdk/advanced/recovery) +- [Using ZeroDev](/sdk/advanced/recovery): - This is harder to integrate with but allows you to customize your user experience. In either case, once an account has been set up for recovery, the guardian (which may be the user themselves) can recover the user's account through [the recovery portal](/recovery-flow/portal). diff --git a/docs/pages/recovery-flow/portal.md b/docs/pages/recovery-flow/portal.md index 3a771ba..185e3f4 100644 --- a/docs/pages/recovery-flow/portal.md +++ b/docs/pages/recovery-flow/portal.md @@ -1,7 +1,7 @@ -# Recovery Portal +# Recovery portal -The recovery portal is a hosted UI where Kernel account owners can recover their accounts, if they have set up recovery. +The recovery portal is a hosted UI that Kernel account owners can use to recover their accounts if they have set up recovery. -Note that the recovery portal is just a convenience UI -- it's not essential for executing recovery. That is, even if the portal goes down or ceases to exist, a guardian can always interact with the smart account directly to complete recovery. +Note that the recovery portal is just a convenience UI—it's not essential for executing recovery. That is, even if the portal goes down or ceases to exist, a guardian can always interact with the smart account directly to complete recovery. [Click here to go to the recovery portal](https://recovery.zerodev.app) \ No newline at end of file diff --git a/docs/pages/recovery-flow/setup.md b/docs/pages/recovery-flow/setup.md index c24051b..f61082a 100644 --- a/docs/pages/recovery-flow/setup.md +++ b/docs/pages/recovery-flow/setup.md @@ -1,3 +1,3 @@ -# Recovery Setup +# Recovery setup -[Follow instructions here to set up the recovery flow.](https://github.com/zerodevapp/recovery-flow) \ No newline at end of file +Follow the instructions in the [`recovery-flow` repo](https://github.com/zerodevapp/recovery-flow) to set up the recovery flow. \ No newline at end of file diff --git a/docs/pages/sdk/advanced/chain-abstraction.mdx b/docs/pages/sdk/advanced/chain-abstraction.mdx index 117031f..f868620 100644 --- a/docs/pages/sdk/advanced/chain-abstraction.mdx +++ b/docs/pages/sdk/advanced/chain-abstraction.mdx @@ -4,15 +4,15 @@ ZeroDev is the first smart account solution to support *cross-chain transactions More specifically, a ZeroDev smart account can use its tokens from one chain on another chain, without bridging. Some examples are: -- Stake ETH on Ethereum mainnet using ETH on Polygon. -- Spend USDC on Base to purchase an NFT sold in USDT on Arbitrum. -- Execute a transaction on Blast by paying gas in DAI from Optimism. +- Stake `ETH` on the Ethereum mainnet using `ETH` on Polygon. +- Spend `USDC` on Base to purchase an NFT sold in `USDT` on Arbitrum. +- Execute a transaction on Blast by paying gas in `DAI` from Optimism. ## Features ### Compatible with EIP-7702 -Unlike other chain abstraction solutions, ZeroDev Chain Abstraction supports not just regular smart accounts (ERC-4337), but also smart EOAs (EIP-7702). +Unlike other chain abstraction solutions, ZeroDev Chain Abstraction supports not only regular smart accounts (ERC-4337) but also smart EOA (EIP-7702). ### Cross-chain without bridging @@ -24,7 +24,7 @@ Cross-chain transactions with ZeroDev are very fast, thanks to *intents* -- solv ### Deep liquidity -Most "chain abstraction" solutions on the market are toys that fail under any real amount of traffic. ZeroDev's cross-chain transactions network is built on top of protocols with the deepest liquidity, such as Relay and Across. +Most “chain abstraction” solutions on the market are toys that fail under even moderate traffic. ZeroDev’s cross-chain transactions network is built on top of protocols with the deepest liquidity, such as Relay and Across. ## Code example @@ -33,7 +33,9 @@ Here is a [complete code example](https://github.com/zerodevapp/zerodev-examples ## Setting up chain abstraction :::info -We highly recommend that you use the code example above as a reference as you follow this guide. + +We highly recommend using the code example above as a reference as you follow this guide. + ::: ### Installation @@ -62,7 +64,7 @@ bun add @zerodev/intent @zerodev/sdk ### Choosing a validator -While chain abstraction works with any validator, we highly recommend using a multi-chain validator like `@zerodev/multi-chain-ecdsa-validator` for new projects. Multi-chain validators are optimized for cross-chain transactions because they can sign for multiple input chains with a single signature, making the process more efficient. +While chain abstraction works with any validator, we highly recommend using a multi-chain validator, such as `@zerodev/multi-chain-ecdsa-validator`, for new projects. Multi-chain validators are optimized for cross-chain transactions because they can sign for multiple input chains with a single signature, making the process more efficient. If you're starting a new project, you can install the multi-chain ECDSA validator: @@ -126,7 +128,7 @@ const intentClient = createIntentClient({ ## Using chain abstraction -At the core of chain abstraction is the idea of a "chain-abstracted balance" (CAB), which is a unified balance across all the chains. For example, if you have 100 USDC on Base and 200 on Arbitrum, then you have 300 "chain-abstracted USDC" which you can spend on any chain. +At the core of chain abstraction is the idea of a “chain-abstracted balance” (CAB), a unified balance across all chains. For example, if you have 100 `USDC` on Base and 200 on Arbitrum, then you have 300 “chain-abstracted USDC” which you can spend on any chain. ### Getting Chain-abstracted Balances @@ -180,10 +182,10 @@ console.log(`Intent executed on chain: ${receipt?.executionChainId}`); Here: - `calls` is a [batch](/sdk/core-api/batch-transactions) of calls to execute atomically. -- `outputTokens` is the chain-abstracted token that your calls require. For example, if your calls are looking to spend 500 USDC to buy an NFT, then you'd specify 500 USDC with the `outputTokens`. - - If you want to use ETH as the output token, set the address to `zeroAddress`. +- `outputTokens` is the chain-abstracted token that your calls require. For example, if your calls are looking to spend 500 `USDC` to buy an NFT, then you'd specify 500 `USDC` with the `outputTokens`. + - If you want to use `ETH` as the output token, set the address to `zeroAddress`. -Note that in this example, it doesn't matter whether you actually have USDC on Base. So long as you have enough USDC across all the chains, the transaction will execute. +Note that in this example, it doesn't matter whether you actually have `USDC` on Base. So long as you have enough `USDC` across all the chains, the transaction will execute. ### Specifying input tokens @@ -203,7 +205,7 @@ const result = await intentClient.sendUserIntent({ }) ``` -Here's a real example for using USDC on Arbitrum to execute a transaction on Base: +Here's a real example for using `USDC` on Arbitrum to execute a transaction on Base: ```ts const result = await intentClient.sendUserIntent({ @@ -238,17 +240,19 @@ Note that you do NOT need to specify an amount for your `inputTokens`. Your inp When using intents, you may use the `gasToken` flag to configure how to pay gas. - By default (with no `gasToken` specified), gas is paid in CAB (input tokens) itself. -- If you specify `gasToken: 'NATIVE'`, the account will pay gas with the native token (e.g. ETH). +- If you specify `gasToken: 'NATIVE'`, the account will pay gas with the native token (e.g., `ETH`). - If you specify `gasToken: 'SPONSORED'`, you will be [sponsoring gas](/sdk/core-api/sponsor-gas) for the account. - If you specify `gasToken: 'USDC'` or `gasToken: 'USDT'`, you will pay gas with the specified stablecoin. ### Parallel intent execution :::info + Parallel intent execution requires `INTENT_V0_4` or above. + ::: -ZeroDev supports executing multiple intents simultaneously, enabling you to batch multiple cross-chain transactions in parallel. This is particularly useful when you need to execute several independent transactions at the same time. +ZeroDev supports executing multiple intents simultaneously, enabling you to batch cross-chain transactions. This is particularly useful when you need to execute multiple independent transactions simultaneously. To execute intents in parallel, you'll need to use different nonce keys for each intent: @@ -311,15 +315,15 @@ console.log( ); ``` -This tracking system ensures you have complete visibility into your cross-chain transaction's progress, from initiation through to final execution. If you simply want to wait until the intent fully resolves, just waiting for the execution receipt is enough. +This tracking system ensures you have complete visibility into the progress of your cross-chain transaction, from initiation through to final execution. If you simply want to wait until the intent fully resolves, just waiting for the execution receipt is enough. ## Supported tokens and networks -Feel free to reach out to us with the link on top of this page if you want to see more tokens or networks supported. +Feel free to reach out to us using the link at the top of this page if you want to see more tokens or networks supported. ### Mainnet -We support **USDC, USDT, WETH, and ETH** for cross-chain transactions, on the following networks: +We support **`USDC`, `USDT`, `WETH`, and `ETH`** for cross-chain transactions on the following networks: - Ethereum mainnet - Arbitrum @@ -329,25 +333,25 @@ We support **USDC, USDT, WETH, and ETH** for cross-chain transactions, on the fo - Binance Smart Chain (BSC) - Avalanche (USDC only) -By default, ZeroDev spends USDC and USDT interchangeably, which means that if you have say 100 USDC on Arbitrum, you can spend 100 USDC or USDT (or any mix thereof) on any other chain. +By default, ZeroDev spends `USDC` and `USDT` interchangeably, which means that if you have, say, 100 `USDC` on Arbitrum, you can spend 100 `USDC` or `USDT` (or any mix thereof) on any other chain. ### Testnet -We support **USDC and ETH** on the following testnets: +We support **`USDC` and `ETH`** on the following testnets: - Ethereum Sepolia - Base Sepolia -Note that we highly recommend testing on mainnets instead of testnets, due to the unreliability of bridges on testnets. +Note that we highly recommend testing on mainnets rather than testnets due to the unreliability of bridges on testnets. ## Pricing - Developer pricing (charged to the developer) - - Chain Abstraction is rate limited for projects on the free or Growth plans. + - Chain Abstraction is rate-limited for projects on the free or Growth plans. - To use Chain Abstraction in production, please subscribe to the Scale or Enterprise plan. - User pricing (charged to the user by the input token) - For projects on the Scale plan, we charge: - 20 basis points (0.2%) for cross-chain transactions below $500. - 10 basis points (0.1%) for cross-chain transactions worth $500 or above. - - For projects on the enterprise plan, the rates are negotiable. + - For enterprise plan projects, the rates are negotiable. diff --git a/docs/pages/sdk/advanced/defi.mdx b/docs/pages/sdk/advanced/defi.mdx index ab31122..f3d4f3c 100644 --- a/docs/pages/sdk/advanced/defi.mdx +++ b/docs/pages/sdk/advanced/defi.mdx @@ -1,11 +1,11 @@ -# DeFi Integrations +# DeFi integrations ZeroDev partners with [Enso](https://www.enso.finance/) to support seamless token swaps and DeFi integrations, even across chains. The API deals with two types of tokens: -- **Base tokens** are normal tokens that do not represent a DeFi position. Examples are ETH, USDC, etc. -- **DeFi tokens** are ERC20 tokens that represent a DeFi position, such as in a [ERC-4626 vault](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/). For example, depositing ETH into Lido gets you `stETH` that represents staked ETH. +- **Base tokens** are normal tokens that do not represent a DeFi position. Examples are `ETH`, USDC, etc. +- **DeFi tokens** are `ERC-20` tokens that represent a DeFi position, such as in a [ERC-4626 vault](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/). For example, depositing `ETH` into Lido gets you `stETH` that represents staked `ETH`. By allowing you to swap between base tokens and DeFi tokens, you can easily: @@ -14,7 +14,7 @@ By allowing you to swap between base tokens and DeFi tokens, you can easily: ZeroDev leverages [batching](/sdk/core-api/batch-transactions) and [delegatecall](/sdk/core-api/delegatecall) internally to ensure that even complex routes are executed in one atomic UserOp, providing the user with low latency, low gas cost, and high safety. -## Supported Tokens +## Supported tokens See the full lists of supported base tokens and DeFi tokens: @@ -64,9 +64,9 @@ Where: - `kernelClient` is the [account client](/sdk/core-api/create-account#create-an-account-client) object. - `projectId` is your ZeroDev project ID, obtained from the dashboard. -### Swapping Tokens +### Swapping tokens -Suppose you want to swap 100 USDC to USDT: +Suppose you want to swap 100 `USDC` to `USDT`: ```ts import { baseTokenAddresses } from "@zerodev/defi" @@ -89,16 +89,16 @@ const userOpHash = await defiClient.sendSwapUserOp({ Where: - `fromToken` is the input token. -- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g. Wei for Ether. +- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g., Wei for `ETH`. - `toToken` is the output token. - `toAddress`: defaults to the account's own address. If specified, it will send the output token to that address instead. - `gasToken`: [see below.](#gas-tokens) -### Entering / Exiting DeFi positions +### Entering and exiting DeFi positions Entering a DeFi position simply means swapping a token into a DeFi token. -You can get a DeFi token address through the `defiTokenAddresses` constant, which is a map with three keys: `chainId => tokenName => protocolName`. For example, the DeFi token representing the USDC vault on AAVE v3 on Arbitrum would be `defiTokenAddresses[arbitrum.id]['USDC']['aave-v3']`. So, to enter the vault: +You can get a DeFi token address through the `defiTokenAddresses` constant, which is a map with three keys: `chainId => tokenName => protocolName`. For example, the DeFi token representing the USDC vault on AAVE v3 on Arbitrum would be `defiTokenAddresses[arbitrum.id]['USDC']['aave-v3']`. So, to enter the vault: ```ts import { defiTokenAddresses } from "@zerodev/defi" @@ -118,9 +118,9 @@ const userOpHash = await defiClient.sendSwapUserOp({ Similarly, exiting a DeFi position is just swapping a DeFi token into another token. -### Cross-chain Swaps +### Cross-chain swaps -To swap tokens across chains, use `sendSwapUserOpCrossChain`. For example, to swap USDC on Arbitrum to DAI on Polygon: +To swap tokens across chains, use `sendSwapUserOpCrossChain`. For example, to swap `USDC` on Arbitrum to `DAI` on Polygon: ```ts // Convert mainnet DAI to USDC, and lend it through AAVE on Arbitrum @@ -139,15 +139,15 @@ const userOpHash = await defiClient.sendSwapUserOpCrossChain({ Where: - `fromToken` is the input token. -- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g. Wei for Ether. +- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g., Wei for `ETH`. - `toToken` is the output token. - `toChainId`: the chain for `toToken`, - `toAddress`: defaults to the account's own address. If specified, it will send the output token to that address instead. - `gasToken`: [see below.](#gas-tokens) -### Listing Tokens +### Listing tokens -You can list all ERC20 tokens an account owns with the `listTokenBalances` function: +You can list all `ERC-20` tokens an account owns with the `listTokenBalances` function: ```ts const accountBalances = await defiClient.listTokenBalances({ @@ -156,15 +156,15 @@ const accountBalances = await defiClient.listTokenBalances({ }) ``` -### Gas Tokens +### Gas tokens -The `gasToken` flag specifies how gas is paid for the UserOp. It can be one of the following values: +The `gasToken` flag specifies how gas is paid for the UserOp. It can be one of the following values: - `sponsored`: sponsor the UserOp. -- `fromToken`: pays gas in the input token, using a [ERC20 paymaster](/sdk/core-api/pay-gas-with-erc20s). -- `toToken`: pays gas in the output token, using a [ERC20 paymaster](/sdk/core-api/pay-gas-with-erc20s). +- `fromToken`: pays gas in the input token, using a [`ERC-20` paymaster](/sdk/core-api/pay-gas-with-erc20s). +- `toToken`: pays gas in the output token, using a [`ERC-20` paymaster](/sdk/core-api/pay-gas-with-erc20s). - `native`: pays gas in the native token, using the account's balance. -- You can also specify an `Address` for a ERC20 token, to pay gas with that token using a [ERC20 paymaster](/sdk/core-api/pay-gas-with-erc20s). +- You can also specify an `Address` for a `ERC-20` token, to pay gas with that token using a [`ERC-20` paymaster](/sdk/core-api/pay-gas-with-erc20s). ### Getting the UserOp without sending diff --git a/docs/pages/sdk/advanced/fallback-providers.mdx b/docs/pages/sdk/advanced/fallback-providers.mdx index 2928901..852d75b 100644 --- a/docs/pages/sdk/advanced/fallback-providers.mdx +++ b/docs/pages/sdk/advanced/fallback-providers.mdx @@ -1,10 +1,12 @@ -# Fallback Providers +# Fallback providers :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/fallback-clients/main.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/fallback-clients/main.ts). + ::: -ZeroDev aggregates multiple bundler and paymaster services to provide the highest possible reliability to our users. You can set up "fallbacks" so that when one of the services fails, another takes over. +ZeroDev aggregates multiple bundler and paymaster services to provide the highest possible reliability to our users. You can set up “fallbacks” so that when one service fails, another takes over. ## API @@ -61,7 +63,7 @@ const kernelClient2 = createKernelAccountClient({ }) ``` -Then combine the Kernel clients with the `createFallbackKernelAccountClient` function: +Then, combine the Kernel clients with the `createFallbackKernelAccountClient` function: ```ts const kernelClient = createFallbackKernelAccountClient([ @@ -70,11 +72,11 @@ const kernelClient = createFallbackKernelAccountClient([ ]) ``` -Now you can use `kernelClient` as usual. Your `kernelClient` will use `kernelClient1` by default, and if it runs into any issues with it, it will fallback to `kernelClient2`. +Now you can use `kernelClient` as usual. Your `kernelClient` will use `kernelClient1` by default, and if it runs into any issues with it, it will fallback to `kernelClient2`. ## Using non-ZeroDev infra as fallbacks -In the previous example, we used different providers as fallbacks through ZeroDev. If you are worried that ZeroDev itself might go down, you can also sign up directly with providers like Pimlico and set them up as fallback providers. +In the previous example, we used different providers as fallbacks through ZeroDev. If you are worried that ZeroDev itself might go down, you can also sign up directly with providers like Pimlico and set them up as fallback providers. To do that, simply: diff --git a/docs/pages/sdk/advanced/go-sdk.mdx b/docs/pages/sdk/advanced/go-sdk.mdx index 0702709..0881a6b 100644 --- a/docs/pages/sdk/advanced/go-sdk.mdx +++ b/docs/pages/sdk/advanced/go-sdk.mdx @@ -1,9 +1,11 @@ -# ZeroDev Go SDK Documentation +# ZeroDev Go SDK documentation ## Overview :::info -The Go SDK and UserOp Builder API is only available for users on the Enterprise plan. + +The Go SDK and UserOp Builder API are only available for users on the Enterprise plan. + ::: The [ZeroDev Go SDK](https://github.com/zerodevapp/go-sdk) works with the user operation builder API to help developers build and send User Operations (UserOps) on Ethereum and compatible networks using Go. @@ -31,7 +33,7 @@ go get github.com/zerodevapp/sdk-go - An active ZeroDev Project ID from the ZeroDev Dashboard. - A gas sponsorship policy configured for your ZeroDev project. -## Quick Start +## Quick start Refer to the complete example code on GitHub: diff --git a/docs/pages/sdk/advanced/key-storage.mdx b/docs/pages/sdk/advanced/key-storage.mdx index 2141691..7b47cf4 100644 --- a/docs/pages/sdk/advanced/key-storage.mdx +++ b/docs/pages/sdk/advanced/key-storage.mdx @@ -1,14 +1,16 @@ -# Key Storage +# Key storage :::warning -The remote signer feature is a paid add-on. Please [contact us](https://t.me/derek_chiang) before you use this feature in production, in order to avoid service disruptions. + +The remote signer feature is a paid add-on. Please [get in touch](https://t.me/derek_chiang) with us before using this feature in production to avoid service disruptions. + ::: -Sometimes you might want to manage session keys or even actual private keys for your users, but you may not want to store the keys on your database. +Sometimes you can manage session keys or even actual private keys for your users, but you may not want to store them in your database. -ZeroDev offers a key management API you can use to generate private keys and sign with them. The private key is never transmitted to you or stored on your server -- the API executes the signing remotely. +ZeroDev provides a key management API that lets you generate private keys and sign with them. The private key is never transmitted to you or stored on your server—the API executes the signing remotely. -## Code Example +## Code example Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/remote-signer/main.ts). @@ -36,7 +38,7 @@ bun add @zerodev/remote-signer ## API -First, obtain the ZeroDev API key from [your dashboard](https://dashboard.zerodev.app/account). Remember: you must secure this API key. Whoever has access to this API key effectively controls all the private keys you manage with the key management API. +First, obtain the ZeroDev API key from [your dashboard](https://dashboard.zerodev.app/account). Remember: you must secure this API key. Whoever has access to this API key effectively controls all the private keys you manage with the key management API. ### Generating a private key @@ -49,13 +51,13 @@ const remoteSigner = await toRemoteSigner({ }) ``` -`remoteSigner` is a [Viem account](https://viem.sh/docs/accounts/privateKey) which you can use for signing. +`remoteSigner` is a [Viem account](https://viem.sh/docs/accounts/privateKey) you can use to sign. -Note that if you want to get this key later, you must store its "address" which is basically its public key: `remoteSigner.address`. +Note that if you want to get this key later, you must store its "address," which is basically its public key: `remoteSigner.address`. ### Getting an existing private key -When getting an existing key, specify the "address" of the key. +When getting an existing key, specify the key's “address”. ```ts import { toRemoteSigner, RemoteSignerMode } from "@zerodev/remote-signer" diff --git a/docs/pages/sdk/advanced/multi-chain-signing.mdx b/docs/pages/sdk/advanced/multi-chain-signing.mdx index 95b9ff5..33296c7 100644 --- a/docs/pages/sdk/advanced/multi-chain-signing.mdx +++ b/docs/pages/sdk/advanced/multi-chain-signing.mdx @@ -1,24 +1,23 @@ -# Multi-chain Signing +# Multi-chain signing -You can use Kernel with a "multi-chain validator" which can sign multiple UserOps in one signature, even if the UserOps are on different chains. For example, if you want to bridge some assets from chain A, and then execute a transaction on chain B with the bridged assets, you can sign both the bridging transaction and the target transaction in a single signature. +You can use Kernel with a “multi-chain validator,” which can sign multiple UserOps in a single signature, even if the UserOps are on different chains. For example, if you want to bridge some assets from chain A and then execute a transaction on chain B with the bridged assets, you can sign both the bridging transaction and the target transaction in a single signature. ## Examples ### Sending multi-chain transactions -If you want to send transactions across multiple chains with a single ecdsa signature, [refer to this code example.](https://github.com/zerodevapp/zerodev-examples/blob/main/multi-chain/main.ts) +If you want to send transactions across multiple chains with a single ECDSA signature, [refer to this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/multi-chain/main.ts). -If you want to use passkey instead of ecdsa, [refer to this code example.](https://github.com/zerodevapp/multi-chain-passkey-example) +If you want to use a passkey instead of ECDSA, [refer to this code example](https://github.com/zerodevapp/multi-chain-passkey-example). ### Creating multi-chain session keys If you want to create multiple session keys across different chains, with a single signature, [refer to this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/multi-chain/useSessionKeyWithApproval.ts). -If you want to use passkey instead of ecdsa, [refer to this code example.](https://github.com/zerodevapp/multi-chain-passkey-example/tree/session-key-with-serialization) - +If you want to use a passkey instead of ECDSA, [refer to this code example](https://github.com/zerodevapp/multi-chain-passkey-example/tree/session-key-with-serialization). ### Enabling plugins across chains -If you want to enable validators across chains (e.g. to enable recovery), with a single signature, [refer to this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/multi-chain/sendUserOpsWithEnable.ts). +If you want to enable validators across chains (e.g., enabling recovery) with a single signature, [refer to this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/multi-chain/sendUserOpsWithEnable.ts). -If you want to use passkey instead of ecdsa, [refer to this code example.](https://github.com/zerodevapp/multi-chain-passkey-example/tree/enable-regular) +If you want to use a passkey instead of ECDSA, [refer to this code example](https://github.com/zerodevapp/multi-chain-passkey-example/tree/enable-regular). \ No newline at end of file diff --git a/docs/pages/sdk/advanced/multisig.mdx b/docs/pages/sdk/advanced/multisig.mdx index fc3f6f7..522a388 100644 --- a/docs/pages/sdk/advanced/multisig.mdx +++ b/docs/pages/sdk/advanced/multisig.mdx @@ -10,7 +10,7 @@ With Kernel, it's possible to configure multiple signers for your smart account. ## How it works -Each signer is set up with a **weight**, and for any given signature, there must be enough combined weight to reach or surpass the **threshold** for the signature to be considered valid. +Each signer is assigned a **weight**, and for any given signature, the combined weight must meet or exceed the **threshold** for the signature to be considered valid. For example, let's say we have: @@ -46,7 +46,7 @@ bun i @zerodev/weighted-validator To set up a new multisig account, start by creating a validator. Here are examples for both ECDSA and passkey signers: -### With ECDSA Signers +### With ECDSA signers ```ts import { createWeightedValidator } from "@zerodev/weighted-validator" @@ -72,7 +72,7 @@ const multiSigValidator = await createWeightedValidator(publicClient, { }) ``` -### With Passkey Signers +### With passkey signers ```ts import { createWeightedValidator } from "@zerodev/weighted-validator" @@ -142,8 +142,8 @@ const client = createWeightedKernelAccountClient({ When using a multisig account, sending transactions requires gathering enough signatures to meet the threshold. This is a two-step process: -1. First, get approvals from the required signers -2. Then, send the UserOperation with the collected signatures +1. First, get approvals from the required signers. +2. Then, send the UserOperation with the collected signatures. Here's how to implement this flow: @@ -191,17 +191,19 @@ const receipt = await client.waitForUserOperationReceipt({ hash: userOpHash }) ``` +:::note Important note -Note that: -- The signatures can be collected asynchronously from different signers -- You need to collect enough signatures to meet the threshold weight -- The same UserOperation object must be used for all signatures -- Each signer must use their own client instance configured with their signer -- You can mix signatures from both ECDSA and passkey signers as long as their combined weight meets the threshold +- Collecting signatures is completed asynchronously from various signers. +- You need to collect enough signatures to meet the threshold weight. +- All signatures must use the same UserOperation object. +- Each signer must use their own client instance configured with their signer. +- You can mix signatures from both ECDSA and passkey signers as long as their combined weight meets the threshold. + +::: ## Updating multisig config -To update the multisig configuration (like adding or removing signers), you can use the update config functionality. This works the same way for both ECDSA and passkey signers: +To update the multisig configuration (e.g., adding or removing signers), use the update config functionality. This works the same way for both ECDSA and passkey signers: ```ts import { getUpdateConfigCall } from "@zerodev/weighted-validator" @@ -231,4 +233,4 @@ await kernelClient.sendTransaction( ) ``` -Note that `kernelClient` here must itself be a correctly set-up instance of a multisig account client with sufficient signing authority to make the change. +Note that the `kernelClient` (in the above) must be a correctly set up instance of a multisig account client with sufficient signing authority to make the change. \ No newline at end of file diff --git a/docs/pages/sdk/advanced/parallel-orders.mdx b/docs/pages/sdk/advanced/parallel-orders.mdx index 2c4ab88..1a94119 100644 --- a/docs/pages/sdk/advanced/parallel-orders.mdx +++ b/docs/pages/sdk/advanced/parallel-orders.mdx @@ -1,18 +1,20 @@ # Parallel UserOps :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/send-transactions/with-2d-nonce.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/send-transactions/with-2d-nonce.ts). + ::: -With a EOA, the nonce is sequential: 1, 2, 3, ... This means that transactions must be ordered sequentially, and a transaction cannot be processed unless a previous transaction was completed. +With a EOA, the nonce is sequential: 1, 2, 3,... meaning transaction ordering occurs sequentially, and a transaction cannot be processed unless the previous transaction has completed. -With smart accounts, the nonce can be two-dimensional, which allows for *parallel UserOps*. Imagine that your user wants to place three trades: +With smart accounts, the nonce can be two-dimensional, enabling *parallel UserOps*. Imagine that your user wants to place three trades: -1. Swap 100 USDC to DAI -2. Swap 100 DAI to USDT -3. Swap 1WETH to USDT +1. Swap 100 `USDC` to `DAI` +2. Swap 100 `DAI` to `USDT` +3. Swap 1 `WETH` to `USDT` -In this example, assuming the user did not have DAI to start with, the first two trades have dependencies, since the user needs to wait for the first trade to complete before they can do the second trade. However, the third trade doesn't depend on either of the first two trades, so it ought to be able to be placed in parallel. +In this example, assuming the user did not have `DAI` to start with, the first two trades are dependent, since the user needs to wait for the first trade to complete before they can do the second. However, the third trade doesn’t depend on either of the first two trades, so it ought to be able to be placed in parallel. ## API @@ -51,6 +53,6 @@ await kernelClient.sendUserOperation({ }) ``` -All UserOps using the same nonce key will be ordered sequentially. UserOps using different nonce keys will be parallel to each other. +All UserOps using the same nonce key will be ordered sequentially. UserOps using different nonce keys will run in parallel. -For example, if you want to order all UserOps that interact with Uniswap, and order all UserOps that interact with AAVE, but you want the Uniswap UserOps and the AAVE UserOps to be parallel to each other, you can use the string "Uniswap" and "AAVE" as the nonce keys for their UserOps respectively. \ No newline at end of file +For example, if you want to order all UserOps that interact with Uniswap, and order all UserOps that interact with AAVE, but you want the Uniswap UserOps and the AAVE UserOps to be parallel to each other, you can use the string "Uniswap" and "AAVE" as the nonce keys for their UserOps, respectively. \ No newline at end of file diff --git a/docs/pages/sdk/advanced/passkeys.mdx b/docs/pages/sdk/advanced/passkeys.mdx index bc1901b..45a20d7 100644 --- a/docs/pages/sdk/advanced/passkeys.mdx +++ b/docs/pages/sdk/advanced/passkeys.mdx @@ -2,13 +2,13 @@ Passkeys are cryptographic key pairs created on end-user devices. [Apple](https://developer.apple.com/passkeys) and [Google](https://developers.google.com/identity/passkeys) are two major industry players pushing for the passkeys standard, which means that passkeys are widely available on consumer devices such as: -- iPhones / iPads / Macbooks -- Android phones / tablets -- Chrome (on Windows / Mac / Android) +- iPhones/iPads/MacBooks +- Android phones/tablets +- Chrome (on Windows/Mac/Android) [See here for a full list of systems that support passkeys.](https://passkeys.dev/device-support/#matrix) -The biggest value-add of passkeys, in the context of Web3, is **saving users from manually managing and securing their private keys.** Instead of writing down 12-word seed phrases, your user can simply use a passkey-enabled device to manage their wallet, and trust that the hardware will safely store the passkey, and the hardware vendor (e.g. Apple/Google) will [securely backup the keys](#how-are-passkeys-sync-ed-and-recovered). +The biggest value-add of passkeys in the context of Web3 is **freeing users from manually managing and securing their private keys**. Instead of writing down 12-word seed phrases, your user can use a passkey-enabled device to manage their wallet, trusting that the hardware will safely store the passkey and that the hardware vendor (e.g., Apple/Google) will [securely back up the keys](#how-are-passkeys-sync-ed-and-recovered). ## Demo @@ -25,15 +25,15 @@ The biggest value-add of passkeys, in the context of Web3, is **saving users fro ZeroDev/Kernel supports using passkeys as signers. The support comes in two flavors: -- **Native passkeys** using precompiles via [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) on rollups and [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951) on Ethereum. Native passkeys are the best option when available, since it uses the least amount of gas (only 3450 gas for verifying a P256 signature). [See here](#chains-with-native-passkey-precompiles) for a list of chains that support native passkey precompiles. +- **Native passkeys** using precompiles via [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) on rollups and [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951) on Ethereum. Native passkeys are the best option when available, since they use the least gas (only 3450 for verifying a P-256 signature). [See here](#chains-with-native-passkey-precompiles) for a list of chains that support native passkey precompiles. - **Smart contract passkeys** using either the [Daimo](https://github.com/daimo-eth/p256-verifier) or [FCL](https://github.com/rdubois-crypto/FreshCryptoLib) implementation. Smart contract passkeys can work on all EVM networks, but they are expensive (300-400k gas for verifying a P256 signature). -ZeroDev implements passkey supports through a **progressive passkey validator**, which uses native passkeys if ERC-7212 is available, and falls back to smart contract passkeys otherwise. Notably, this means that if you use passkeys on a network where ERC-7212 isn't available, and the network later adds support for ERC-7212, you don't need to upgrade your validator -- it will automatically start taking advantage of the ERC-7212 precompile. +ZeroDev implements passkey support via a **progressive passkey validator**, which uses native passkeys if ERC-7212 is available, and falls back to smart contract passkeys otherwise. Notably, this means that if you use passkeys on a network where ERC-7212 isn't available, and the network later adds support for ERC-7212, you don't need to upgrade your validator -- it will automatically start taking advantage of the ERC-7212 precompile. ## Quickstart -[Follow this tutorial](/sdk/getting-started/tutorial-passkeys) to get started with passkey smart accounts. +[Follow this tutorial](/sdk/getting-started/tutorial-passkeys) to get started with Passkey Smart Accounts. ## Installation @@ -59,7 +59,7 @@ bun add @zerodev/passkey-validator ## API -### Setting up passkey server +### Setting up the passkey server In this tutorial, we will be using ZeroDev's passkey server. If you want to use your own passkey server, [read this](#how-do-i-use-my-own-passkeys-server). If you wonder why a passkey server is needed at all, [read this](#why-do-we-need-a-passkeys-server). @@ -69,7 +69,7 @@ Head to the [ZeroDev dashboard](https://dashboard.zerodev.app), select a project

-If you are testing on `localhost`, just leave the domain empty. If you are deploying to a domain, enter and save the domain. +If you are testing on `localhost`, leave the domain empty. If you are deploying to a domain, enter the domain and save it. ### Creating a new passkey @@ -133,16 +133,16 @@ Using passkeys with ECDSA session keys has multiple benefits: - Your users don't have to deal with passkey signing prompts for every UserOp. -### Why do we need a passkeys server? +### Why do we need a passkey server? -A passkey is generated from a client-server handshake. In theory, we could simulate the handshake on the frontend, then store the public key on-chain. However, storing the public key on-chain involves sending a transaction, so you would want to do that as a part of deploying the account. However, if you must deploy a passkey account before you can use it, that breaks one of the core optimizations of AA which is counterfactual deployment -- the ability to use the address of a smart account without first deploying it. +A passkey is generated from a client-server handshake. In theory, we could simulate the handshake on the frontend, then store the public key onchain. However, storing the public key onchain involves sending a transaction, so you would want to do that as a part of deploying the account. However, if you must deploy a passkey account before you can use it, that breaks one of the core optimizations of AA, which is counterfactual deployment—the ability to use the address of a smart account without first deploying it. -We are working on ways to remove the dependency on a passkey server. In the mean time, keep in mind that the centralization concern is mitigated by the following: +We are working on ways to remove the dependency on a passkey server. In the meantime, keep in mind that the centralization concern is mitigated by the following: - You can [use your own passkeys server](#how-do-i-use-my-own-passkeys-server). -- The passkeys server only stores the public authentication data. Even if it's compromised, your users's keys are stored on their devices only. +- The passkey server stores only public authentication data. Even if it’s compromised, your users' keys are stored only on their devices. -If the passkey server is lost, only users who have not yet deployed their accounts (i.e. users who have been using accounts counterfactually) will be unable to recover their accounts. Users who have deployed their accounts will have their authentication data stored on-chain, so their accounts will be safe even if the passkey server is lost. +If the passkey server is lost, only users who have not yet deployed their accounts (i.e., users who have been using accounts counterfactually) will be unable to recover their accounts. Users who have deployed their accounts will have their authentication data stored onchain, ensuring their accounts remain safe even if the passkey server is lost. ### How do I use my own passkeys server? @@ -200,7 +200,7 @@ if (verification.verified) { // return 401 error if the verification is failed ``` -- `/login/options`: Generate login options, including a challenge for verification, and return them to the client. The `generateAuthenticationOptions` function will assist you in creating these options. +- `/login/options`: Generate login options, including a verification challenge, and return them to the client. The `generateAuthenticationOptions` function will help you create these options. ```ts import { generateAuthenticationOptions } from "@simplewebauthn/server" @@ -213,7 +213,7 @@ const options = await generateAuthenticationOptions({ return options ``` -- `/login/verify`: Verify the login response (cred) and report the outcome to the client. Use the `verifyAuthenticationResponse` for the verification process. In the event of successful verification, retrieve the new counter from authenticationInfo and update the user's credentials in your database. It's crucial to send both the verification result and the user's public key back to the client, as the public key is not known to the client during the login process. +- `/login/verify`: Verify the login response (cred) and report the outcome to the client. Use the `verifyAuthenticationResponse` Upon successful verification, retrieve the new counter from `authenticationInfo` and update the user’s credentials in your database. It’s crucial to return both the verification result and the user’s public key to the client, since the public key is not known to the client during the login process. ```ts import { verifyAuthenticationResponse } from "@simplewebauthn/server" @@ -280,9 +280,9 @@ const passkeyValidator = await toPasskeyValidator(publicClient, { }) ``` -If you want to refer to the ZeroDev passkey server implementation, you can find it [here](https://github.com/zerodevapp/passkey-server) +If you want to refer to the ZeroDev passkey server implementation, you can find it [here](https://github.com/zerodevapp/passkey-server). -### How are passkeys sync-ed and recovered? +### How are passkeys synced and recovered? Synchronization and recovery are both supported natively by Apple and Google: @@ -290,9 +290,9 @@ Synchronization and recovery are both supported natively by Apple and Google: - With Google, [Google Password Manager](https://passwords.google/) syncs passkeys across devices seamlessly. Google has plans to support syncing more broadly across different operating systems, see [this support summary](https://developers.google.com/identity/passkeys/supported-environments#chrome-passkey-support-summary). Recovery is covered in [this FAQ ("What happens if a user loses their device?")](https://developers.google.com/identity/passkeys/faq#what_happens_if_a_user_loses_their_device): it relies on Google's overall [account recovery process](https://support.google.com/accounts/answer/7682439?hl=en) because passkeys are attached to Google accounts. -## Chains with Native Passkey Precompiles +## Chains with native passkey precompiles -This is an incomplete list of chains that support native passkey precompiles via RIP-7212 or EIP-7951: +This is an incomplete list of chains that support native passkey precompiles via [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) or [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951): ### Mainnet - Ethereum diff --git a/docs/pages/sdk/advanced/recovery.mdx b/docs/pages/sdk/advanced/recovery.mdx index e55bf59..8b587ea 100644 --- a/docs/pages/sdk/advanced/recovery.mdx +++ b/docs/pages/sdk/advanced/recovery.mdx @@ -1,26 +1,28 @@ # Recovery -With Kernel's [permissions system](/sdk/permissions/intro), it's possible to set up a guardian (or multiple guardians) for a smart account, so that if the owner loses their key, the guardian(s) can recover the key for the owner. +With Kernel's [permissions system](/sdk/permissions/intro), it's possible to set up a guardian (or multiple guardians) for a smart account, so that if the owner loses their key, the guardian(s) can recover it. There are two typical types of recovery: -- **Self-recovery**: your user can set up recovery for their account with another auth factor they own, such as a passkey or another wallet they own. +- **Self-recovery**: your user can set up recovery for their account using another authentication factor they own, such as a passkey or another wallet. -- **DApp-assisted recovery**: your user might set you (the DApp) as their guardian. When they lose their account, they would contact you and you would recover the account for them. +- **DApp-assisted recovery**: your user might set you (the DApp) as their guardian. When they lose their account, they would contact you, and you would recover the account for them. -There are two ways to use recovery: through a pre-built recovery flow or build a totally custom flow using the Kernel recovery plugin. +There are two ways to use recovery: through a pre-built recovery flow, or by building a fully custom flow using the Kernel recovery plugin. -## Recovery Plugin +## Recovery plugin :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/guardians/recovery.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/guardians/recovery.ts). + ::: Here we go through the process of using the recovery plugin: ### Setting up the guardian validator -Start by creating a permissions validator. Let's say you want a single key to be your guardian: +Start by creating a permissions validator. Let's say you want a single key to be your guardian: ```ts const guardianSigner = privateKeyToAccount(GUARDIAN_KEY) @@ -34,9 +36,9 @@ const guardianValidator = await signerToEcdsaValidator(publicClient, { If you want multiple guardians, set up a [multisig validator](/sdk/advanced/multisig) instead. -### Setting up account with the recovery action +### Setting up an account with the recovery action -We have deployed a simple recovery executor that can recover any accounts using [the ECDSA validator](/sdk/permissions/signers/ecdsa). You can set it up with the following values: +We have deployed a simple recovery executor that can recover any accounts using [the ECDSA validator](/sdk/permissions/signers/ecdsa). You can set it up with the following values: ```ts import { toFunctionSelector } from "viem" @@ -63,11 +65,11 @@ const account = await createKernelAccount(publicClient, { }) ``` -you only need to set the sudo validator if you are enabling the guardian validator, i.e. that it's the first time you are using the guardian. +You only need to set the sudo validator if you are enabling the guardian validator, i.e., if it's the first time you are using the guardian. ### Executing recovery -After you [construct the account client from the account](/sdk/core-api/create-account#create-an-account-client), you can execute recovery as such: +After you [construct the account client from the account](/sdk/core-api/create-account#create-an-account-client), you can execute recovery as follows: ```ts import { encodeFunctionData } from "viem" @@ -82,9 +84,9 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -### Using account with the new owner +### Using an account with the new owner -After you update the account owner, the account address can no longer by computed from the new owner. Therefore, you should use the `address` option to manually set the account address when you [create the account object](/sdk/core-api/create-account#create-a-kernel-account). For example: +After you update the account owner, the account address can not be computed from the new owner. Therefore, you should use the `address` option to manually set the account address when you [create the account object](/sdk/core-api/create-account#create-a-kernel-account). For example: ```ts const account = await createKernelAccount(publicClient, { diff --git a/docs/pages/sdk/advanced/run-solidity-code-on-init.mdx b/docs/pages/sdk/advanced/run-solidity-code-on-init.mdx index 8e18af3..1940d8f 100644 --- a/docs/pages/sdk/advanced/run-solidity-code-on-init.mdx +++ b/docs/pages/sdk/advanced/run-solidity-code-on-init.mdx @@ -1,21 +1,23 @@ # Run code when creating an account :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/emit-event-when-creating-account/main.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/emit-event-when-creating-account/main.ts). + ::: -Sometimes, you might want to execute some custom code when you create an account. One common use case is when you want to emit an event whenever a user creates an account. +Sometimes, you may want to execute some custom code when you create an account. One common use case is emitting an event whenever a user creates an account. -Running custom code during initialization can be done via plugins. Specifically you can follow this process: +Running custom code during initialization can be done via plugins. Specifically, you can follow this process: - Write a custom validator that executes your custom code during initialization. -- Install the validator to your account during account initialization. +- Install the validator on your account during initialization. ## Developing a custom validator -Kernel implements the [ERC-7579 interface](https://eips.ethereum.org/EIPS/eip-7579), so you can write a 7579 validator. +The kernel implements the [ERC-7579 interface](https://eips.ethereum.org/EIPS/eip-7579) so that you can write a 7579 validator. -[Here's an example of a validator that simply emits an event](https://github.com/zerodevapp/kernel/blob/ab30532763de3cdbe05dab7821652f11cc0a01c7/src/validator/EmitIdentifierValidator.sol). Note that [the `onInstall` function](https://github.com/zerodevapp/kernel/blob/ab30532763de3cdbe05dab7821652f11cc0a01c7/src/validator/EmitIdentifierValidator.sol#L12) accepts an initialization data, which you can use to run customized code per account. +Here’s an [example]((https://github.com/zerodevapp/kernel/blob/ab30532763de3cdbe05dab7821652f11cc0a01c7/src/validator/EmitIdentifierValidator.sol)) of a validator that emits an event. Note that the [`onInstall` function](https://github.com/zerodevapp/kernel/blob/ab30532763de3cdbe05dab7821652f11cc0a01c7/src/validator/EmitIdentifierValidator.sol#L12) accepts initialization data, which you can use to run customized code per account. Once you have developed the custom validator, deploy it using `CREATE2` so that it has the same address across all chains. diff --git a/docs/pages/sdk/advanced/session-keys.mdx b/docs/pages/sdk/advanced/session-keys.mdx index ec18e10..fa19ee3 100644 --- a/docs/pages/sdk/advanced/session-keys.mdx +++ b/docs/pages/sdk/advanced/session-keys.mdx @@ -1,36 +1,36 @@ -# Session Keys +# Session keys ## EntryPoint v0.7 (Kernel v3) :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys). +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys). ::: -In EntryPoint 0.7 (Kernel v3), session keys have been upgraded into a more powerful "permissions system." [Please refer to these docs.](/sdk/permissions/intro) +In EntryPoint 0.7 (Kernel v3), session keys have been upgraded into a more powerful "permissions system." [Please refer to these docs.](/sdk/permissions/intro) ## EntryPoint v0.6 (Kernel v2) :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/session-keys/v2-old). +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/session-keys/v2-old). ::: -The following document is for session keys for EntryPoint 0.6 (Kernel v2). If you are using EntryPoint 0.7 (Kernel v3), [please refer to permissions instead.](/sdk/permissions/intro) +The following document is for session keys for EntryPoint 0.6 (Kernel v2). If you are using EntryPoint 0.7 (Kernel v3), [please refer to permissions instead.](/sdk/permissions/intro) -Session keys are keys assigned with specific permissions. Some examples are: +Session keys are keys assigned with specific permissions. Some examples are: - A key that can only interact with Uniswap -- A key that can only use up to 1000 USDC +- A key that can only use up to 1000 `USDC` - A key that expires in 3 days -Of course, the permissions can be composed, so you can create a key that can only interact with Uniswap, while only using up to 1000 USDC, while expiring in 3 days, for instance. +Of course, the permissions can be composed, so you can create a key that can only interact with Uniswap, while only using up to 1000 `USDC`, while expiring in 3 days, for instance. Session keys have two primary use cases: -- **Skipping confirmations**: if you don't want your users to have to confirm every single transaction, you can create a session key that's only allowed to send specific transactions, and store the key in local storage. Now, your user can interact with your app with the session key without dealing with signing prompts. This experience is sometimes known as "one-click trading." +- **Skipping confirmations**: if you don't want your users to have to confirm every single transaction, you can create a session key that's only allowed to send specific transactions, and store the key in local storage. Now, your user can interact with your app with the session key without dealing with signing prompts. This experience is sometimes known as "one-click trading." -- **Automating transactions**: if you want to execute transactions for your users automatically, they can create a session key and give it to you. You can then store the session keys on your server and execute transactions for your users. Your users don't have to fully trust you since the session keys are bounded by permissions. +- **Automating transactions**: if you want to execute transactions for your users automatically, they can create a session key and give it to you. You can then store the session keys on your server and execute transactions for your users. Your users don't have to fully trust you since the session keys are bounded by permissions. -The possibility with transaction automation is endless. Some examples are: +The possibility with transaction automation is endless. Some examples are: - Subscriptions - Stop orders @@ -63,24 +63,26 @@ bun i @zerodev/session-key When using session keys, it's helpful to distinguish between the **owner** and the **agent**. -- The **owner** is whoever controls the master key of the account. The owner is the person that is able to create session keys. +- The **owner** is whoever controls the master key of the account. The owner is the person that is able to create session keys. - The **agent** is whoever using the session key. There are two typical flows for how the owner and the agent interact: - **Owner-created**: The owner creates the session key and shares it with the agent. -- **Agent-created**: The agent creates a key pair and shares the public key with the owner. The owner creates a partial session key based on the public key, then shares the partial session key with the agent. Finally, the agent combines the private key wih the partial session key to form a full session key. +- **Agent-created**: The agent creates a key pair and shares the public key with the owner. The owner creates a partial session key based on the public key, then shares the partial session key with the agent. Finally, the agent combines the private key wih the partial session key to form a full session key. Let's walk through how each flow works. ### Owner-created :::info + Check out [the code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/owner-created.ts) for the owner-created pattern. + ::: -We assume that you have [created a Kernel account](/sdk/core-api/create-account#create-a-kernel-account). If you only have a `kernelClient`, the Kernel account can be accessed as `kernelClient.account`. +We assume that you have [created a Kernel account](/sdk/core-api/create-account#create-a-kernel-account). If you only have a `kernelClient`, the Kernel account can be accessed as `kernelClient.account`. First, create a signer for the session key: @@ -105,7 +107,9 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { ``` :::info + Refer to [the session key params section](#session-key-parameters) to learn about session key params. + ::: Now, construct a Kernel account using your sudo validator and the session key validator: @@ -121,7 +125,7 @@ const sessionKeyAccount = await createKernelAccount(publicClient, { In this example, the sudo validator is `ecdsaValidator`. -If you want to use the session key on the same node, you can already [construct a Kernel client from this Kernel account](/sdk/core-api/create-account#create-an-account-client) and start using it. If you want to share the session key with an agent or store it for use later, you can serialize the session key: +If you want to use the session key on the same node, you can already [construct a Kernel client from this Kernel account](/sdk/core-api/create-account#create-an-account-client) and start using it. If you want to share the session key with an agent or store it for use later, you can serialize the session key: ```typescript import { serializeSessionKeyAccount } from "@zerodev/session-key" @@ -140,10 +144,12 @@ Now you can [create a Kernel client](/sdk/core-api/create-account#create-an-acco ### Agent-created :::info + Check out [the code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/agent-created.ts) for the agent-created pattern. + ::: -In the agent-created pattern, the agent creates a public-private key pair and shares the public key with the owner. The owner authorizes the public key (by signing it), and shares the signed data with the agent. Finally, the agent creates the full session key by combining the signed data with the private key. This pattern is powerful because **the agent never had to share the private part of the session key with anyone**. +In the agent-created pattern, the agent creates a public-private key pair and shares the public key with the owner. The owner authorizes the public key (by signing it), and shares the signed data with the agent. Finally, the agent creates the full session key by combining the signed data with the private key. This pattern is powerful because **the agent never had to share the private part of the session key with anyone**. First, the agent creates a key pair: @@ -157,7 +163,7 @@ const sessionKeyAddress = sessionKeySigner.address Note that while we are using a local private key in this example, the session key signer can be any [Viem account object](https://viem.sh/docs/accounts/local). -Then, the agent shares the public key (address) of this signer with the owner. In this case, it would be `sessionKeySigner.address`. +Then, the agent shares the public key (address) of this signer with the owner. In this case, it would be `sessionKeySigner.address`. With this address, the owner can authorize the session key as such: @@ -174,7 +180,9 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { ``` :::info + Refer to [the session key params section](#session-key-parameters) to learn about session key params. + ::: Now, the owner can construct a Kernel account using the sudo validator and the session key validator: @@ -202,11 +210,11 @@ Now, when the agent needs to use the session key, they deserialize it: const sessionKeyAccount = await deserializeSessionKeyAccount(publicClient, serializedSessionKey, sessionKeySigner) ``` -Note how we pass `sessionKeySigner` to `deserializeSessionKeyAccount`. This is the private part of the session key that only the agent knows about. +Note how we pass `sessionKeySigner` to `deserializeSessionKeyAccount`. This is the private part of the session key that only the agent knows about. Now you can [create a Kernel client](/sdk/core-api/create-account#create-an-account-client) using the `sessionKeyAccount` as you normally would. -### Revoking Session Keys +### Revoking session keys ```typescript import { revokeSessionKey } from "@zerodev/session-key" @@ -218,7 +226,7 @@ const userOpHash = await revokeSessionKey(kernelClient) const userOpHash = await revokeSessionKey(kernelClient, sessionKeySigner.address) ``` -Note that `kernelClient` in this case must be using the master signer (instead of the session key signer). If you want to revoke session keys using the session key signer itself, you must explicitly set up the session key permissions so that it's allowed to revoke itself. You can do so by including this permission: +Note that `kernelClient` in this case must be using the master signer (instead of the session key signer). If you want to revoke session keys using the session key signer itself, you must explicitly set up the session key permissions so that it's allowed to revoke itself. You can do so by including this permission: ```ts import { SESSION_KEY_VALIDATOR_ADDRESS } from "@zerodev/session-key" @@ -252,7 +260,7 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { }) ``` -## Session Key Parameters +## Session key parameters When creating a session key validator, you specify parameters under the `validatorData` flag: @@ -284,7 +292,7 @@ If not set or set to `0`, then the session key will be valid immediately. ### `paymaster` -`paymaster` specifies whether the session key must be used with a paymaster. **It's highly recommended that you set this flag unless 1) you fully trust the agent holding the session key, or 2) you don't expect your users to hold any ETH (or whatever native token for the network).** Otherwise, a malicious agent can set arbitrarily high gas price for UserOps sent with the session key, and then submit the UserOps themselves in order to profit from the gas, completely draining the user of ETH in the process. +`paymaster` specifies whether the session key must be used with a paymaster. **It's highly recommended that you set this flag unless 1) you fully trust the agent holding the session key, or 2) you don't expect your users to hold any `ETH` (or whatever native token for the network).** Otherwise, a malicious agent can set arbitrarily high gas price for `UserOps` sent with the session key, and then submit the `UserOps` themselves in order to profit from the gas, completely draining the user of `ETH` in the process. By setting the `paymaster` flag to a non-zero value, you ensure that the session key can only be used with a paymaster, and the paymaster (if properly set up) should have defense against arbitrarily high gas prices. @@ -296,7 +304,7 @@ If set to a specific paymaster address, then the session key can only be used wi ### `permissions` -Permissions are at the core of session keys. By specifying permissions, you limit the types of transactions that the session key can send. +Permissions are at the core of session keys. By specifying permissions, you limit the types of transactions that the session key can send. Permissions look like this: @@ -344,16 +352,16 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { Here's what each flag means: -- `target`: the target contract to call or address to send ETH to. If this is `zeroAddress`, then the target can be any contract as long as the ABI matches (or it can be any address if no ABI is specified). +- `target`: the target contract to call or address to send ETH to. If this is `zeroAddress`, then the target can be any contract as long as the ABI matches (or it can be any address if no ABI is specified). - `valueLimit`: the maximum [value](https://coinmarketcap.com/alexandria/glossary/ethereum-transaction#:~:text=The%20value%20is%20the%20amount%20of%20Ether%20to%20transfer%20from%20the%20sender%20to%20the%20recipient%2C%20and%20this%20can%20even%20be%20zero.) that can be transmitted. - `abi`: the contract ABI - `functionName`: the function name -- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. use `null` to skip an argument. +- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. use `null` to skip an argument. - `operator`: this can be `EQUAL`, `GREATER_THAN`, `LESS_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`, `NOT_EQUAL`. - - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the value must be equal to 2". -- `operation`: (optional) whether this is a call or a delegatecall. Defaults to call. + - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the value must be equal to 2". +- `operation`: (optional) whether this is a call or a delegatecall. Defaults to call. -### Batching and Delegatecall +### Batching and `Delegatecall` To use session keys with [batching](/sdk/core-api/batch-transactions), specify the following `action` when constructing the account: @@ -373,7 +381,7 @@ const sessionKeyAccount = await createKernelAccount(publicClient, { }) ``` -Then you can send batched UserOps with `sendUserOperation([userops])` as usual. +Then you can send batched `UserOps` with `sendUserOperation([userops])` as usual. To use session keys with `delegatecall`: @@ -392,9 +400,9 @@ const sessionKeyAccount = await createKernelAccount(publicClient, { }) ``` -### Transferring ETH +### Transferring `ETH` -If you want to transfer ETH with a session key, specify the `data` field as such: +If you want to transfer `ETH` with a session key, specify the `data` field as such: ```ts import { pad } from 'viem' @@ -410,8 +418,8 @@ await sessionKeyAccountClient.sendTransaction({ ### Does creating session keys cost gas? -No. Creating a session key entails simply signing a message, which is done off-chain and doesn't involve any gas cost. +No. Creating a session key entails simply signing a message, which is done offchain and doesn't involve any gas cost. ### Is it possible to use session keys with a not-yet-deployed account? -Yes. If you do so, the first UserOp sent with the session key will deploy the account. +Yes. If you do so, the first UserOp sent with the session key will deploy the account. diff --git a/docs/pages/sdk/advanced/social-login.mdx b/docs/pages/sdk/advanced/social-login.mdx index e910e57..b00cffc 100644 --- a/docs/pages/sdk/advanced/social-login.mdx +++ b/docs/pages/sdk/advanced/social-login.mdx @@ -1,8 +1,8 @@ import SocialLoginSetup from '../../shared/social-login-setup.mdx' -# Social Login +# Social login -Social login allows users to authenticate using their existing social media accounts such as Google or Facebook. +Social login allows users to authenticate using their existing social media accounts, such as Google or Facebook. ZeroDev supports social logins natively, but you can also use ZeroDev with [third-party auth providers](/sdk/signers/intro) such as Privy, Dynamic, and Magic if you prefer their UI. @@ -72,9 +72,9 @@ initiateLogin({ ``` #### Parameters -- socialProvider ("google" | "facebook"): The social provider to use for login. -- oauthCallbackUrl (string, optional): The URL to redirect to after login. Defaults to the current window location if not provided. -- projectId (string): Your ZeroDev project ID. +- `socialProvider` ("google" | "facebook"): The social provider to use for login. +- `oauthCallbackUrl` (string, optional): The URL to redirect to after login. Defaults to the current window location if not provided. +- `projectId` (string): Your ZeroDev project ID. #### Example @@ -109,9 +109,9 @@ export async function getSocialValidator< ``` #### Parameters -- client (Client): The client instance. -- entryPoint (entryPoint): The entry point object. -- projectId (string): Your ZeroDev project ID. +- `client` (Client): The client instance. +- `entryPoint` (entryPoint): The entry point object. +- `projectId` (string): Your ZeroDev project ID. #### Returns - `Promise>`: Resolves to a social validator object. @@ -130,7 +130,9 @@ const socialValidator = await getSocialValidator( ); ``` :::info + Now you can proceed to [create Kernel accounts](https://docs.zerodev.app/sdk/core-api/create-account#create-a-kernel-account) using the social validator as the sudo validator. + ::: ### `logout` @@ -142,7 +144,7 @@ logout({ projectId: string }) ``` #### Parameters -- projectId (string): Your ZeroDev project ID. +- `projectId` (string): Your ZeroDev project ID. #### Example diff --git a/docs/pages/sdk/advanced/supported-base-tokens.mdx b/docs/pages/sdk/advanced/supported-base-tokens.mdx index bd84f15..15cc109 100644 --- a/docs/pages/sdk/advanced/supported-base-tokens.mdx +++ b/docs/pages/sdk/advanced/supported-base-tokens.mdx @@ -1,4 +1,4 @@ -# Supported Base Tokens +# Supported Base tokens This is the full list of base tokens supported by ZeroDev's [DeFi integrations](/sdk/advanced/defi). @@ -10,7 +10,7 @@ To use these tokens, import the `baseTokenAddresses` constant: import { baseTokenAddresses } from "@zerodev/defi" ``` -Then get the base token address with `baseTokenAddresses[chainId][baseToken]`. For example, to swap USDC into USDT: +Then get the base token address with `baseTokenAddresses[chainId][baseToken]`. For example, to swap `USDC` into `USDT`: ```ts const userOpHash = await defiClient.sendSwapUserOp({ @@ -21,7 +21,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ }) ``` -## Ethereum Mainnet +## Ethereum mainnet | Symbol | Address | |--------|----------| @@ -194,7 +194,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | YFI | 0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e | | YFII | 0xa1d0E215a23d7030842FC67cE582a6aFa3CCaB83 | -## Optimism Mainnet +## Optimism mainnet | Symbol | Address | |--------|----------| @@ -216,7 +216,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBTC | 0x68f180fcCe6836688e9084f035309E29Bf0A2095 | | WETH | 0x4200000000000000000000000000000000000006 | -## BSC Mainnet +## BSC mainnet | Symbol | Address | |--------|----------| @@ -249,7 +249,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBNB | 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c | | XRP | 0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe | -## Polygon Mainnet PoS +## Polygon mainnet PoS | Symbol | Address | |--------|----------| @@ -287,7 +287,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBTC | 0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6 | | WETH | 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619 | -## Base Mainnet +## Base mainnet | Symbol | Address | |--------|----------| @@ -332,7 +332,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBTC | 0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f | | WETH | 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1 | -## Avalanche-C Mainnet +## Avalanche-C mainnet | Symbol | Address | |--------|----------| diff --git a/docs/pages/sdk/advanced/supported-defi-tokens.mdx b/docs/pages/sdk/advanced/supported-defi-tokens.mdx index 2b3cda8..ea4d674 100644 --- a/docs/pages/sdk/advanced/supported-defi-tokens.mdx +++ b/docs/pages/sdk/advanced/supported-defi-tokens.mdx @@ -1,4 +1,4 @@ -# Supported Defi Tokens +# Supported DeFi tokens This is the full list of DeFi tokens (aka "vaults") supported by ZeroDev's [DeFi integrations](/sdk/advanced/defi). @@ -21,7 +21,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ }) ``` -## Ethereum Mainnet +## Ethereum mainnet | Tokens | Protocol | Address | |--------|----------|---------| diff --git a/docs/pages/sdk/advanced/upgrade-kernel.mdx b/docs/pages/sdk/advanced/upgrade-kernel.mdx index ee1cc3d..d17f2df 100644 --- a/docs/pages/sdk/advanced/upgrade-kernel.mdx +++ b/docs/pages/sdk/advanced/upgrade-kernel.mdx @@ -1,16 +1,18 @@ # Upgrading Kernel :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-ecdsa-migration-account/main.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-ecdsa-migration-account/main.ts). + ::: -[Kernel](https://github.com/zerodevapp/kernel), our smart account implementation, receives updates from time to time to keep up with the latest standards and best practices. We do NOT recommend upgrading Kernel accounts unless you NEED TO, since there are many ways to accidentally screw up. But if you do need to upgrade, you can follow the steps here. +[Kernel](https://github.com/zerodevapp/kernel), our smart account implementation, receives periodic updates to keep up with the latest standards and best practices. We do NOT recommend upgrading Kernel accounts unless you NEED TO, since there are many ways to screw up accidentally. But if you do need to upgrade, you can follow the steps here. -The tricky thing about upgrading a smart account is that it affects the *deterministic address computation* (i.e. `CREATE2`), since a Kernel address is partially derived from the smart account implementation. Thankfully, the ZeroDev SDK offers a convenience function for upgrading Kernel accounts without messing up the deterministic address. +The tricky thing about upgrading a smart account is that it affects the *deterministic address computation* (e.g., `CREATE2`), since a Kernel address is partially derived from the smart account implementation. Thankfully, the ZeroDev SDK provides a convenience function for upgrading Kernel accounts without disrupting the deterministic address. ## API -We currently offer an API for upgrading a ECDSA Kernel account. For other account types, reach out for assistance. +We currently offer an API for upgrading an ECDSA Kernel account. For other account types, reach out for assistance. To migrate, replace the code that you used to set up the Kernel validator and account with a single `createEcdsaKernelMigrationAccount` function: diff --git a/docs/pages/sdk/advanced/userop-builder-api.mdx b/docs/pages/sdk/advanced/userop-builder-api.mdx index d21c9f0..ca20125 100644 --- a/docs/pages/sdk/advanced/userop-builder-api.mdx +++ b/docs/pages/sdk/advanced/userop-builder-api.mdx @@ -1,20 +1,22 @@ -# UserOp Builder API +# UserOp builder API The UserOp Builder API provides a server-side solution for building and sending ERC-7702 User Operations with [Kernel smart accounts](https://docs.zerodev.app/sdk/core-api/create-account). It handles gas estimation, paymaster integration, and bundler submission—perfect for backend services that need to construct user operations without client-side SDKs. :::info -The UserOp Builder API is only available for users on the Enterprise plan. + +The UserOp Builder API is available only to users on the Enterprise plan. + ::: ## Overview The UserOp Builder API supports: -- **EIP-7702** — EOA to smart account delegation +- **[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)** — EOA to smart account delegation - **Gas sponsorship** — Automatic paymaster integration - **Kernel versions** — `0.3.1`, `0.3.2`, `0.3.3` -## Quick Start +## Quick start ```typescript // 1. Build the user operation @@ -61,10 +63,12 @@ const { userOpHash } = await sendResponse.json(); ## Authentication :::info + Get your API key from the [ZeroDev Dashboard](https://dashboard.zerodev.app). + ::: -All endpoints require authentication via API key headers. Either one of the following headers must be included: +All endpoints require authentication via API key headers. One of the following headers must be included: | Header | Format | Description | | ---------------- | ------ | -------------------- | @@ -86,7 +90,7 @@ POST /:projectId/:chainId/ ## API Reference -### Build User Operation +### Build user operation Builds an unsigned ERC-7702 user operation with gas estimation and paymaster data. @@ -140,11 +144,13 @@ interface BuildUserOpResponse { } ``` -> **Important:** The `userOpHash` in the response is what you need to sign with your account's private key. +:::info + +The `userOpHash` in the response is what you need to sign with your account's private key. ---- +::: -### Send User Operation +### Send user operation Submits a signed user operation to the bundler. @@ -194,9 +200,8 @@ interface SendUserOpRequest { Use the returned `userOpHash` to poll for the receipt. ::: ---- -### Get User Operation Receipt +### Get user operation receipt Retrieves the receipt for a submitted user operation. @@ -230,13 +235,16 @@ interface UserOpReceipt { } ``` -> **Tip:** Poll this endpoint until you get a successful response. The user operation may take a few seconds to be included in a block. +:::note + +Poll this endpoint until you get a successful response. The user operation may take a few seconds to be included in a block. + +::: ---- -### Initialize Kernel Client +### Initialize kernel client -Pre-warms the kernel client cache for a project/chain. Optional but recommended for reducing latency on first request. +Pre-warms the kernel client cache for a project/chain. Optional, but recommended to reduce latency on the first request. ``` POST /:projectId/:chainId/init-kernel-client @@ -271,7 +279,7 @@ interface SignedAuthorization { ## Using with EIP-7702 -[EIP-7702](https://docs.zerodev.app/sdk/advanced/eip7702) allows EOAs to temporarily delegate to a smart contract. To use an EOA as a Kernel smart account: +[EIP-7702](https://docs.zerodev.app/sdk/advanced/eip7702) allows EOAs to delegate to a smart contract temporarily. To use an EOA as a Kernel smart account: ```typescript const response = await fetch( @@ -301,13 +309,13 @@ const response = await fetch( ); ``` -## Supported Chains +## Supported chains The API supports any chain configured in your ZeroDev project: See [ZeroDev's supported networks](https://docs.zerodev.app/sdk/faqs/chains) for the full list. -## Related Resources +## Related resources - [Kernel Smart Accounts](https://docs.zerodev.app/sdk/core-api/create-account) - [EIP-7702 Guide](https://docs.zerodev.app/sdk/advanced/eip7702) diff --git a/docs/pages/sdk/advanced/wallet-connect.mdx b/docs/pages/sdk/advanced/wallet-connect.mdx index 229b837..c4cd1a1 100644 --- a/docs/pages/sdk/advanced/wallet-connect.mdx +++ b/docs/pages/sdk/advanced/wallet-connect.mdx @@ -2,7 +2,7 @@ ## Overview -The `@zerodev/walletconnect` Core SDK facilitates the connection between a WalletConnect-compatible wallet and a blockchain application, handling session proposals, requests, and responses. It leverages a kernel EIP1193 provider to sign transactions or messages. +The `@zerodev/walletconnect` Core SDK facilitates the connection between a WalletConnect-compatible wallet and a blockchain application, handling session proposals, requests, and responses. It leverages a kernel [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) provider to sign transactions or messages. ## Installation @@ -52,7 +52,7 @@ await walletConnectKernelService.init({ - `kernelClient`: An optional kernel client for creating a kernel provider. - For detailed information on kernel clients, see [the kernel clients documentation.](/sdk/core-api/create-account#create-an-account-client) - `kernelProvider`: An optional pre-initialized kernel provider. - - If you are using wagmi with the capabilities pattern (for more information, see [the capabilities quickstart](/smart-wallet/quickstart-capabilities)), you can get the `kernelProvider` from wagmi. + - If you are using wagmi with the capabilities pattern (see [the capabilities quickstart](/smart-wallet/quickstart-capabilities) for more information), you can retrieve the kernelProvider from wagmi. ```typescript import { useAccount } from "wagmi"; @@ -67,7 +67,7 @@ const kernelEIP1193Provider = (await connector.getProvider()) as unknown as Kern You must either pass a `kernelProvider` or a `kernelClient` to the `init` method. ::: -## Connecting to a Wallet +## Connecting to a wallet To start a session, use the `connect` method with a WalletConnect URI: @@ -75,7 +75,7 @@ To start a session, use the `connect` method with a WalletConnect URI: await walletConnectKernelService.connect("wc:example_uri"); ``` -## Event Handling +## Event handling Subscribe to various session-related events: @@ -103,9 +103,9 @@ walletConnectKernelService.onSessionDelete(() => { }); ``` -## Session Management +## Session management -### Approving or Rejecting Proposals +### Approving or rejecting proposals Handle incoming session proposals by approving or rejecting them: @@ -114,7 +114,7 @@ await walletConnectKernelService.approveSessionProposal(proposal, chainId, addre await walletConnectKernelService.rejectSessionProposal(proposal); ``` -### Handling Session Requests +### Handling session requests Approve or reject session requests based on business logic: @@ -132,6 +132,6 @@ const sessions = walletConnectKernelService.getActiveSessions(); await walletConnectKernelService.disconnect(sessions[0]); ``` -## Example: WalletConnect ZeroDev Example +## WalletConnect ZeroDev example -For an example of integrating the `@zerodev/walletconnect` Core SDK with a React app, check out [this example repo.](https://github.com/zerodevapp/walletconnect-example). \ No newline at end of file +For an example of integrating the `@zerodev/walletconnect` Core SDK with a React app, check out [this example repo](https://github.com/zerodevapp/walletconnect-example). \ No newline at end of file diff --git a/docs/pages/sdk/core-api/batch-transactions.mdx b/docs/pages/sdk/core-api/batch-transactions.mdx index ea090b2..20317f8 100644 --- a/docs/pages/sdk/core-api/batch-transactions.mdx +++ b/docs/pages/sdk/core-api/batch-transactions.mdx @@ -1,21 +1,21 @@ -# Batching Transactions +# Batching transactions :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/batch-transactions). +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/batch-transactions). ::: -Smart accounts like Kernel support *batching* transactions -- rolling multiple transactions into one. This is very useful for simplifying Web3 interactions for your users. For instance, instead of doing `approve()` followed by `transfer()`, your user can do both in one transaction. +Smart accounts like Kernel support transaction batching—rolling multiple transactions into a single transaction. This is very useful for simplifying Web3 interactions for your users. For instance, instead of calling `approve()` followed by `transfer()`, your user can do both in a single transaction. -Batching transactions has a number of important benefits: +Batching transactions has several important benefits: -- Your user waits for only 1 transaction instead of multiple. -- Your user pays less gas. +- Your user waits for only one transaction instead of multiple. +- Your user pays less for gas. - If any transaction in the batch reverts, the entire batch reverts. This ensures that your user won't be stuck in an inconsistent state. - This is known as "atomicity." ## API -There are two ways to send batched transactions. `sendTransaction` is a simple API that's good enough for most use cases. If you need fine-grained control over your UserOp, you can use `sendUserOperation`. +There are two ways to send batched transactions. `sendTransaction` is a simple API that's good enough for most use cases. If you need fine-grained control over your UserOp, you can use `sendUserOperation`. ### `sendTransaction` @@ -40,7 +40,7 @@ const txHash = await kernelClient.sendTransaction({ You can learn more about the `sendUserOperation` API [here](/sdk/core-api/send-transactions#sending-raw-userops). -To send a UserOp with batching, simply pass an array of calls into `encodeCalls`. +To send a UserOp with batching, pass an array of calls into `encodeCalls`. ```typescript const userOpHash = await kernelClient.sendUserOperation({ @@ -62,7 +62,7 @@ const userOpHash = await kernelClient.sendUserOperation({ ### Execute a batch without reverting if some of the calls fail -By default, batching is atomic -- if any of the calls fails, the whole batch will fail. +By default, batching is atomic—if any of the calls fail, the entire batch fails. If you want to execute the batch such that even if some of the calls fail, the other calls will still execute, you can execute it with the `TRY` mode: diff --git a/docs/pages/sdk/core-api/create-account.mdx b/docs/pages/sdk/core-api/create-account.mdx index e303367..16c5278 100644 --- a/docs/pages/sdk/core-api/create-account.mdx +++ b/docs/pages/sdk/core-api/create-account.mdx @@ -1,14 +1,16 @@ # Creating a Smart Account :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + ::: -At the core of account abstraction is the *smart account* -- an account powered by a smart contract. ZeroDev is built on [Kernel](https://github.com/zerodevapp/kernel), a *modular smart account* that can be customized with plugins. +At the core of account abstraction is the _smart account_—an account powered by a smart contract. ZeroDev is built on [Kernel](https://github.com/zerodevapp/kernel), a _modular smart account_, which allows for customization with plugins. -When you create a Kernel account, you set it up with a *validator*, which is a type of plugin that handles how the account validates UserOps. In this tutorial, we will be using the ECDSA validator, which works like a normal EOA by validating signatures from a ECDSA private key. ZeroDev supports other validators such as [passkeys](/sdk/advanced/passkeys) and [multisig](/sdk/advanced/multisig). +When you create a Kernel account, you set it up with a validator, which is a type of plugin that handles how the account validates UserOps. In this tutorial, we will use the ECDSA validator, which works like a normal EOA by validating ECDSA signatures from a private key. ZeroDev supports other validators such as [passkeys](/sdk/advanced/passkeys) and [multisig](/sdk/advanced/multisig). -We will be using a local private key, but the ECDSA validator also works with [third-party auth providers](/sdk/signers/intro). +We will be using a local private key, but the ECDSA validator also supports [third-party authentication providers](/sdk/signers/intro). ## Installation @@ -36,11 +38,11 @@ bun add @zerodev/sdk @zerodev/ecdsa-validator ### Picking an EntryPoint -Currently there are two versions of ERC-4337 that are used in production. They are referred to as "EntryPoint 0.6" and "EntryPoint 0.7", where "EntryPoint" refers to the singleton ERC-4337 contract. +Currently, there are two versions of ERC-4337 in production. They are referred to as “EntryPoint 0.6” and “EntryPoint 0.7”, where “EntryPoint” refers to the singleton ERC-4337 contract. -If you are building a new application, we recommend using EntryPoint 0.7 (Kernel v3), which gives you the latest and greatest features and optimizations. If you already have an application using EntryPoint 0.6 (Kernel v2), just stick with it -- it will be supported indefinitely. +If you are building a new application, we recommend using EntryPoint 0.7 (Kernel v3), which gives you the latest and greatest features and optimizations. If you already have an application using EntryPoint 0.6 (Kernel v2), stick with it—support will continue indefinitely. -In this tutorial, we will use EntryPoint 0.7. Start by selecting an EntryPoint: +In this tutorial, we will use EntryPoint 0.7. Start by selecting an EntryPoint: ```ts const entryPoint = getEntryPoint("0.7") @@ -48,7 +50,7 @@ const entryPoint = getEntryPoint("0.7") ### Picking a Kernel version -[Kernel](https://github.com/zerodevapp/kernel) is the smart account that ZeroDev builds on. ZeroDev SDK used to implicitly use the latest version of Kernel, which has caused some compatibility issues when people upgrade the SDK. Therefore, starting from ZeroDev SDK v5.3, we require that you explicitly specify the Kernel version. This is how you generally should choose: +[Kernel](https://github.com/zerodevapp/kernel) is the smart account that ZeroDev builds on. The ZeroDev SDK implicitly uses the latest Kernel version, which has caused compatibility issues when people upgrade the SDK. Therefore, starting from ZeroDev SDK v5.3, we require that you explicitly specify the Kernel version. This is how you generally should choose: - If you had already been in production with ZeroDev SDK v4 or lower, use Kernel version 2.4 with EntryPoint 0.6. - If you had already been in production with ZeroDev SDK v5, use Kernel version 3.0 with EntryPoint 0.7. @@ -77,9 +79,10 @@ const publicClient = createPublicClient({ ### Creating a signer -As aforementioned, a Kernel account using a ECDSA validator is "owned" by a signer, which is anything that can sign messages with a private key. +As mentioned above, a Kernel account using an ECDSA validator is “owned” by a signer, which is anything that can sign messages with a private key. + +Since Kernel is built on top of Viem, we can use any [Viem account](https://viem.sh/docs/accounts/local/toAccount) as the signer. In this example, we create a signer from a private key: -Since Kernel is built on top of Viem, we can use any [Viem account](https://viem.sh/docs/accounts/local/toAccount) as the signer. In this example, we create a signer from a private key: ```typescript import { Hex } from "viem" @@ -88,7 +91,7 @@ import { privateKeyToAccount } from "viem/accounts" const signer = privateKeyToAccount("PRIVATE_KEY" as Hex) ``` -Replace `PRIVATE_KEY` with an actual private key. You can [generate a random one here](https://privatekeys.pw/keys/ethereum/random). +Replace `PRIVATE_KEY` with an actual private key. You can [generate a random one here](https://privatekeys.pw/keys/ethereum/random). ### Creating a ECDSA validator @@ -122,7 +125,7 @@ const account = await createKernelAccount(publicClient, { ### Create an account client -Now that we have an account, we can finally construct an "account client," which is the equivalent of a [wallet client in Viem](https://viem.sh/docs/clients/wallet.html) that allows you to send UserOps to bundlers. +Now that we have an account, we can finally construct an “account client,” which is the equivalent of a [wallet client in Viem](https://viem.sh/docs/clients/wallet.html) that allows you to send UserOps to bundlers. ```typescript import { createKernelAccountClient } from "@zerodev/sdk" @@ -154,17 +157,17 @@ Note that: - You need to replace the `ZERODEV_RPC` with the RPC found on your ZeroDev dashboard. - You need to make sure to set the right `chain`. -- `paymaster` only needs to be specified if you want to [use a paymaster](/sdk/core-api/sponsor-gas). +- `paymaster` only needs to be specified if you want to [use one](/sdk/core-api/sponsor-gas). Now you are ready to do things with your smart account, like [sending UserOps](/sdk/core-api/send-transactions)! ## FAQs -### When I create an account, is it deployed on-chain? +### When I create an account, is it deployed onchain? -No. If your account hasn't been deployed yet, we simply use [`CREATE2`](https://eips.ethereum.org/EIPS/eip-1014) to compute the address that the account *would* be deployed to. Your account is deployed automatically with the first UserOp it sends. +No. If your account hasn’t been deployed yet, we use [`CREATE2`](https://eips.ethereum.org/EIPS/eip-1014) to compute the address to which it will be deployed. Your account is deployed automatically with the first UserOp it sends. -In other words, "creating" accounts with the SDK is free -- you can create an infinite number of such account objects without paying any gas. It's only when you send the first UserOp that the account is deployed automatically. +In other words, “creating” accounts with the SDK is free—you can create an infinite number of such account objects without paying any gas. It’s only when you send the first UserOp that the account is deployed automatically. ### Can I create multiple accounts from the same EOA signer? @@ -183,7 +186,7 @@ const account = createKernelAccount(publicClient, { ### How do I get the smart account address from the EOA signer address? -Sometimes you only know the address of the EOA signer but you don't have the signer itself. In that case, you can still compute the address of the smart account with this helper function: +Sometimes you only know the address of the EOA signer, but you don’t have the signer itself. In that case, you can still compute the address of the smart account with this helper function: ```ts import { getKernelAddressFromECDSA } from "@zerodev/ecdsa-validator" @@ -194,7 +197,7 @@ const smartAccountAddress = await getKernelAddressFromECDSA(publicClient, eoaAdd ### How do I get the EOA signer address from the smart account address? -You can query it on-chain like this: +You can query it onchain like this: ```ts import { getValidatorAddress } from "@zerodev/ecdsa-validator" @@ -220,7 +223,7 @@ const owner = await ecdsaValidatorContract.read.ecdsaValidatorStorage([ ### How do I create a Kernel account object with a specific address? -Normally, you don't need to manually specify an address because the smart account address is computed from your signer data. However, if you have changed the signer, then you may need to manually specify the smart account address. +Normally, you don’t need to manually specify an address because the smart account address is computed from your signer data. However, if you have changed the signer, then you may need to specify the smart account address manually. You can do it like this: diff --git a/docs/pages/sdk/core-api/delegatecall.mdx b/docs/pages/sdk/core-api/delegatecall.mdx index d2d254b..0f7399f 100644 --- a/docs/pages/sdk/core-api/delegatecall.mdx +++ b/docs/pages/sdk/core-api/delegatecall.mdx @@ -1,19 +1,23 @@ # Delegatecall :::warning -`delegatecall` is very dangerous. Unless you know exactly what you are doing, don't do it, or you might risk losing all your funds. + +`delegatecall` is very dangerous. Unless you know exactly what you are doing, don't do it, or you might risk losing all your funds. + ::: :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/delegatecall/main.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/delegatecall/main.ts). + ::: -`delegatecall` is a powerful EVM opcode that allows the calling contract to execute code in another contract, while keeping the storage context. [You can read more about `delegatecall` here](https://solidity-by-example.org/delegatecall/). +`delegatecall` is a powerful EVM opcode that allows the calling contract to execute code in another contract, while keeping the storage context. [You can read more about `delegatecall` here](https://solidity-by-example.org/delegatecall/). ## API -To send a UserOp that uses `delegatecall`, simply specify the `callType` of the UserOp: +To send a UserOp that uses `delegatecall`, specify the `callType` of the UserOp: ```typescript diff --git a/docs/pages/sdk/core-api/deploy-contract.mdx b/docs/pages/sdk/core-api/deploy-contract.mdx index 7b7b2f4..eacb619 100644 --- a/docs/pages/sdk/core-api/deploy-contract.mdx +++ b/docs/pages/sdk/core-api/deploy-contract.mdx @@ -1,7 +1,9 @@ -# Deploying Contracts +# Deploying contracts :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/deploy-contract/main.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/deploy-contract/main.ts). + ::: To deploy smart contracts from your smart account, use the `deployContract` function: diff --git a/docs/pages/sdk/core-api/pay-gas-with-erc20s.mdx b/docs/pages/sdk/core-api/pay-gas-with-erc20s.mdx index 79b9e48..e89aa1f 100644 --- a/docs/pages/sdk/core-api/pay-gas-with-erc20s.mdx +++ b/docs/pages/sdk/core-api/pay-gas-with-erc20s.mdx @@ -1,20 +1,24 @@ -# Paying Gas with ERC20s +# Paying gas with `ERC-20`s :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/pay-gas-with-erc20). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/pay-gas-with-erc20). + ::: :::warning -**Important:** Our ERC20 Paymaster currently supports USDC on Ethereum Mainnet, Polygon, Base, Optimism, and Arbitrum networks, including both their mainnet and testnet environments. + +**Important:** Our `ERC-20` Paymaster currently supports USDC on Ethereum Mainnet, Polygon, Base, Optimism, and Arbitrum networks, including both their mainnet and testnet environments. + ::: -A smart account can pay gas with ERC20 tokens. As a result, your users don't have to own any native gas tokens (e.g. ETH) in order to use Web3. Instead, they can just use stablecoins or even your project's own tokens. When your users pay gas with ERC20 tokens, we add 5% to the exchange rate to make a profit. +A smart account can pay for gas with `ERC-20` tokens. As a result, your users don’t need to own any native gas tokens (e.g., `ETH`) to use Web3. Instead, they can use stablecoins or even your project’s own tokens. When your users pay for gas with `ERC-20` tokens, we add a 5% markup to the exchange rate to make a profit. -ZeroDev supports two USDC paymasters: the Circle paymaster and the ZeroDev paymaster. Generally, the Circle paymaster gives you better exchange rates, while the ZeroDev paymaster is available on more networks. +ZeroDev supports two `USDC` paymasters: Circle and ZeroDev. Generally, the Circle paymaster gives you better exchange rates, while the ZeroDev paymaster is available on more networks. -## Circle Paymaster +## Circle paymaster -Start by signing a USDC permit for the paymaster. The permit specifies the maximum amount of USDC that the signing account wants to spent on gas. +Start by signing a `USDC` permit for the paymaster. The permit specifies the maximum amount of `USDC` the signing account is willing to spend on gas. ```ts import { @@ -30,7 +34,7 @@ const { signature: permit } = await account.signTypedData( ) ``` -Next, you can create a Circle paymaster client: +Next, you can create a Circle Paymaster client: ```ts import { @@ -49,19 +53,19 @@ const kernelClient = createKernelAccountClient({ }) ``` -Now you can use the Kernel client as usual, and you will be paying gas with USDC! +Now you can use the Kernel client as usual, and you'll pay gas in `USDC`! ## ZeroDev Paymaster -On a high level, you need to do two things to enable a smart account to pay gas in a particular ERC20 token: +On a high level, you need to do two things to enable a smart account to pay gas in a particular `ERC-20` token: -- Set up the Kernel client with the ERC20 paymaster. -- Ensure that enough ERC20 tokens have been approved for the ERC20 paymaster. - - This step is necessary because the ERC20 paymaster needs to withdraw ERC20 tokens from the smart account. +- Set up the Kernel client with the `ERC-20` paymaster. +- Ensure that enough `ERC-20` tokens have been approved for the `ERC-20` paymaster. + - This step is necessary because the `ERC-20` paymaster needs to withdraw `ERC-20` tokens from the smart account. Let's go through these two steps next. -### Set up Kernel Client +### Set up Kernel client When you [set up an account](/sdk/core-api/create-account#create-an-account-client), do this: @@ -94,9 +98,9 @@ const kernelClient = createKernelAccountClient({ }) ``` -### Approve ERC20 tokens for paymaster +### Approve `ERC-20` tokens for paymaster -Use the `getERC20PaymasterApproveCall` function to construct a call that approves the paymaster with the ERC20 tokens: +Use the `getERC20PaymasterApproveCall` function to construct a call that approves the paymaster with the `ERC-20` tokens: ```typescript import { getERC20PaymasterApproveCall } from "@zerodev/sdk" @@ -133,11 +137,11 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -Note that you only have to approve once, as long as the approval amount is sufficient for many UserOps. The [paymaster contract by Pimlico](https://github.com/pimlicolabs/erc20-paymaster/blob/main/src/ERC20PaymasterV07.sol) has been audited, it's widely used and generally considered safe. +Note that you only have to approve once, as long as the approval amount is sufficient for many UserOps. The [Pimlico paymaster contract](https://github.com/pimlicolabs/erc20-paymaster/blob/main/src/ERC20PaymasterV07.sol) has been audited, is widely used, and is generally considered safe. -### Estimate Gas in ERC20s +### Estimate gas in `ERC-20` -If you need to estimate gas in terms of a ERC20 token, do this: +If you need to estimate gas in terms of an `ERC-20` token, do this: ```ts const userOperation = await kernelClient.prepareUserOperation({ @@ -159,9 +163,9 @@ const erc20Amount = await paymasterClient.estimateGasInERC20({ You can also see [a code example for estimating gas here](https://github.com/zerodevapp/zerodev-examples/blob/main/pay-gas-with-erc20/estimate-gas.ts). -### Supported Tokens +### Supported tokens -Currently, our ERC20 Paymaster supports USDC on the following networks: +Currently, our `ERC-20` Paymaster supports `USDC` on the following networks: - **Ethereum Mainnet** - **Polygon** @@ -169,15 +173,15 @@ Currently, our ERC20 Paymaster supports USDC on the following networks: - **Optimism** - **Arbitrum** -If you want to use a different token or support a new network, you can either reach out to us or deploy your own Self-Funded ERC20 Paymaster. +If you want to use a different token or support a new network, you can either reach out to us or deploy your own self-funded `ERC-20` paymaster. ### Deploy Your Own ERC20 Paymaster -If you want to support a custom ERC20 token, you can deploy and manage your own ERC20 paymaster contract. To do this: +If you want to support a custom `ERC-20` token, you can deploy and manage your own `ERC-20` paymaster contract. To do this: -1. Visit the ZeroDev dashboard to deploy a self-funded ERC20 paymaster contract -2. Fund the contract with the native currency (e.g., ETH) -3. Set a conversion rate for the ERC20 token you would like to enable for the paymaster +1. Visit the ZeroDev dashboard to deploy a self-funded `ERC-20` paymaster contract. +2. Fund the contract with the native currency (e.g., `ETH`). +3. Set a conversion rate for the `ERC-20` token you would like to enable for the paymaster. Once deployed, you can use your custom paymaster by copying the paymaster URL from the dashboard and using it as the `transport` parameter when creating the paymaster client: diff --git a/docs/pages/sdk/core-api/send-transactions.mdx b/docs/pages/sdk/core-api/send-transactions.mdx index 32857ec..8ea728a 100644 --- a/docs/pages/sdk/core-api/send-transactions.mdx +++ b/docs/pages/sdk/core-api/send-transactions.mdx @@ -1,25 +1,27 @@ -# Sending Transactions +# Sending transactions :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/send-transactions). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/send-transactions). + ::: -In ERC-4337, a transaction is known as a "UserOp." A UserOp looks mostly like a regular transaction, but it contains some extra information specific to AA, such as whether the UserOp should be sponsored. +In ERC-4337, a transaction is known as a "UserOp." A UserOp looks mostly like a regular transaction, but it contains some extra information specific to AA, such as whether the UserOp should be sponsored. There are two ways to send UserOps: - Sending raw UserOps - Sending regular transactions through the Viem API, which ZeroDev then "translates" into UserOps -The former enables the highest degree of flexibility, whereas the latter is more interoperable with existing libraries like Viem that deal only with transactions and not UserOps. +The former offers the highest degree of flexibility, whereas the latter is more interoperable with existing libraries like Viem, which deal only with transactions and not UserOps. -We will now describe both approaches. We assume that you have already [created a Kernel account](/sdk/core-api/create-account). +We will now describe both approaches. We assume that you have already [created a Kernel account](/sdk/core-api/create-account). ## Using the Viem API Since the Kernel account client implements [Viem's wallet client interface](https://viem.sh/docs/clients/wallet.html), you can send UserOps with standard Viem methods. -### Sending Transactions +### Sending transactions ```typescript const txnHash = await kernelClient.sendTransaction({ @@ -29,11 +31,11 @@ const txnHash = await kernelClient.sendTransaction({ }) ``` -This function returns the transaction hash of the ERC-4337 bundle that contains the UserOp. Due to the way that ERC-4337 works, by the time we get the transaction hash, the ERC-4337 bundle (and therefore the UserOps includeded within) will have already been mined, meaning that you don't have to [wait with the hash](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html). +This function returns the transaction hash of the ERC-4337 bundle that contains the UserOp. Because ERC-4337 works the way it does, by the time we get the transaction hash, the ERC-4337 bundle (and therefore the UserOps included within) will have already been mined, so you don’t have to [wait with the hash](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html). -If you need to separate the sending from the waiting of the UserOp, try [sending raw UserOps](#sending-raw-userops). +If you need to separate the sending from the waiting for the UserOp, try [sending raw UserOps](#sending-raw-userops). -### Interacting with Contracts +### Interacting with contracts First, construct a [Viem contract instance](https://viem.sh/docs/contract/getContract.html) by passing the Kernel account client as the `walletClient`: @@ -71,7 +73,7 @@ const unwatch = contract.watchEvent.Transfer( ### UserOp API -Sending raw UserOps affords you with the highest degree of control. To send a raw UserOp, use `sendUserOperation`: +Sending raw UserOps affords you the highest degree of control. To send a raw UserOp, use `sendUserOperation`: ```typescript const userOpHash = await kernelClient.sendUserOperation({ @@ -103,11 +105,11 @@ Other than `callData`, every field has a sensible default: - `nonce` defaults to the next available nonce - `initCode` defaults to `0x` if the account has been deployed, or the correct `initCode` if not. - `callGasLimit`, `verificationGasLimit`, and `preVerificationGas` default to estimations provided by the underlying bundler and paymaster. -- `maxFeePerGas` and `maxPriorityFeePerGas` default to estimations provided by the public client. +- `maxFeePerGas` and `maxPriorityFeePerGas` default to the public client's estimates. - `paymasterAndData` defaults to `0x` if no paymaster was specified when you created the Kernel account object, or it will use the value provided by the paymaster. -- `signature` defaults to the signature provided by the signer. +- `signature` defaults to the signer's signature. -### Encoding callData +### Encoding `callData` To encode the calldata, use the `encodeCalls` function from the account object: @@ -121,7 +123,7 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -You can use Viem's helper functions such as `encodeFunctionData` to encode function calls. For example: +You can use Viem's helper functions, such as `encodeFunctionData`, to encode function calls. For example: ```ts const userOpHash = await kernelClient.sendUserOperation({ @@ -149,7 +151,7 @@ const receipt = await kernelClient.waitForUserOperationReceipt({ ### Constructing a UserOp for sending later -In some applications, you might want to construct a UserOp but not immediately send it. There are two possible flows: +In some applications, you might want to construct a UserOp but not send it immediately. There are two possible flows: - If you want to separate signing and sending: - Create and sign a UserOp with `kernelClient.signUserOperation()` diff --git a/docs/pages/sdk/core-api/sign-and-verify.mdx b/docs/pages/sdk/core-api/sign-and-verify.mdx index 18e0b50..cc79a5a 100644 --- a/docs/pages/sdk/core-api/sign-and-verify.mdx +++ b/docs/pages/sdk/core-api/sign-and-verify.mdx @@ -1,24 +1,27 @@ -# Signing and Verifying Messages +# Signing and verifying messages -Signing and verifying messages for smart accounts is different than with EOAs. There are a few reasons why: +Signing and verifying messages for smart accounts differs from that for EOAs. There are a few reasons why: -- With an EOA, the address is effectively the public key of the private key used for signing. Therefore, verifying a EOA signature is as simple as [recovering](https://soliditydeveloper.com/ecrecover) the signature and compare the recovered public key with the address. - - With a smart account, the address is the address of a smart contract that has no cryptographic link to the signing private key. Therefore, you must use [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) to validate the message. +- In an EOA, the address is effectively the public key corresponding to the private key used for signing. Therefore, verifying an EOA signature is as simple as [recovering](https://soliditydeveloper.com/ecrecover) the signature and comparing the recovered public key with the address. + - With a smart account, the address is that of a smart contract with no cryptographic link to the signing private key. Therefore, you must use [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) to validate the message. -- With an EOA, you don't have to deploy the account. It just exists. - - Since smart accounts need to be deployed, it may not be clear how you can validate messages against a smart account not yet deployed. However, that's actually possible thanks to [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492). +- With an EOA, you don't have to deploy the account. It just exists. + - Since smart accounts need to be deployed, it may not be clear how to validate messages against a smart account that hasn't been deployed yet. However, that's actually possible thanks to [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492). -If you are impatient, head straight to [the API](#api). Otherwise, read on to learn more about ERC-1271 and ERC-6492. +If you are impatient, head straight to [the API](#api). Otherwise, read on to learn more about ERC-1271 and ERC-6492. + + ## API ### Signing messages -Both [the account and account client objects](/sdk/core-api/create-account#create-a-kernel-account) are able to sign messages: +Both [the account and account client objects](/sdk/core-api/create-account#create-a-kernel-account) can sign messages: ```ts const signature = await account.signMessage({ @@ -30,11 +33,11 @@ const signature = await kernelClient.signMessage({ }) ``` -If the account hasn't been deployed, a ERC-6492 signature will be generated. +If the account hasn't been deployed, an ERC-6492 signature will be generated. ### Validating signatures -While you can validate signatures with ERC-1271, it's recommended that you use ERC-6492 since it works just like ERC-1271 if the account has been deployed, but it can also validate signatures for undeployed accounts. +While you can validate signatures with ERC-1271, it’s recommended that you use ERC-6492 since it works just like ERC-1271 if the account has been deployed. Still, it can also validate signatures for undeployed accounts. To validate signatures with ERC-6492: diff --git a/docs/pages/sdk/core-api/sponsor-gas.mdx b/docs/pages/sdk/core-api/sponsor-gas.mdx index 1a02e83..69fd821 100644 --- a/docs/pages/sdk/core-api/sponsor-gas.mdx +++ b/docs/pages/sdk/core-api/sponsor-gas.mdx @@ -1,28 +1,30 @@ -# Sponsoring Gas +# Sponsoring gas -With account abstraction, you can pay gas for users so they don't have to acquire native tokens in order to interact with your DApp. +With account abstraction, you can pay for gas for users so they don’t have to acquire native tokens to interact with your DApp. When you sponsor gas through ZeroDev, there are two ways to pay for the gas: -- Put down your credit card. We front the gas for your users, and then at the end of the billing cycle (once a month) we charge your credit card. +- Put down your credit card. We front the gas for your users, and then at the end of the billing cycle (once a month), we charge your credit card. - Buy gas credits from us. ## Setting up gas sponsoring policies -To avoid over-spending gas on sponsoring, you must set up gas-sponsoring policies. Sign up on the ZeroDev dashboard if you haven't already, then [set up gas policies](/meta-infra/gas-policies). +To avoid overspending on gas for sponsorship, you must set up gas-sponsoring policies. Sign up on the ZeroDev dashboard if you haven’t already, then [set up gas policies](/meta-infra/gas-policies). -Note that you MUST set up a gas policy to begin sponsoring. Without setting up a gas policy, there won't be any gas sponsored. +Note that you MUST set up a gas policy before you can begin sponsoring. Without setting up a gas policy, there won’t be any gas sponsorship. ## API :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + ::: When [setting up an account](/sdk/core-api/create-account), you can specify a `getPaymasterData` function in `paymaster` when you [create the account client](/sdk/core-api/create-account#create-an-account-client). -The `getPaymasterData` function essentially takes a UserOp and then returns a UserOp with the `paymasterAndData` field set. For example, if you are using the ZeroDev paymaster, use the `createZeroDevPaymasterClient` helper function: +The `getPaymasterData` function takes a UserOp and then returns a UserOp with the `paymasterAndData` field set. For example, if you are using the ZeroDev paymaster, use the `createZeroDevPaymasterClient` helper function: ```typescript import { http } from "viem" @@ -54,7 +56,7 @@ const kernelClient = createKernelAccountClient({ If you have reached the sponsorship limit, either because of the [policies](/meta-infra/gas-policies) you set up or because you have reached an account-level limit, sending UserOp will fail. -If, instead of failing, you want the UserOp to proceed but use the user's own native tokens (e.g. ETH), then you can set up your `paymaster` middleware like this: +If, instead of failing, you want the UserOp to proceed but use the user's own native tokens (e.g., `ETH`), then you can set up your `paymaster` middleware like this: ```ts import { GetPaymasterDataReturnType } from "viem/account-abstraction" @@ -76,7 +78,7 @@ const kernelClient = createKernelAccountClient({ ## UltraRelay -UltraRelay is a new relay solution that functions as a combination of ERC-4337 bundlers and paymasters, as a single entity. UltraRelay is significantly more efficient than regular ERC-4337 bundlers and paymasters. In our benchmarks, UltraRelay achieves: +UltraRelay is a new relay solution that combines [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) bundlers and paymasters into a single entity. UltraRelay is significantly more efficient than regular ERC-4337 bundlers and paymasters. In our benchmarks, UltraRelay achieves: - 30% less gas than ERC-4337 bundlers - 20% lower latency than ERC-4337 bundlers @@ -85,13 +87,13 @@ This makes UltraRelay the best solution for gas sponsorship. ### API -To use UltraRelay, simply update your `createKernelAccountClient` config as follows: +To use UltraRelay, update your `createKernelAccountClient` config as follows: - Append `?provider=ULTRA_RELAY` to your ZeroDev RPC. - (optional) Do NOT set the [paymaster middleware](#api), which will save you some latency. -- (optional) Set a no-op gas estimation middleware, which will save you even more latency. +- (optional) Set up a no-op gas estimation middleware to save you even more latency. -Here's how it looks like in code: +Here's what it looks like in code: ```ts const kernelClient = createKernelAccountClient({ @@ -111,7 +113,7 @@ const kernelClient = createKernelAccountClient({ ### Supported networks -UltraRelay is being gradually rolled out to all networks. It currently supports: +UltraRelay is being gradually rolled out to all networks. It currently supports: - Base - Arbitrum diff --git a/docs/pages/sdk/core-api/status.mdx b/docs/pages/sdk/core-api/status.mdx index 3b93610..baa138a 100644 --- a/docs/pages/sdk/core-api/status.mdx +++ b/docs/pages/sdk/core-api/status.mdx @@ -4,16 +4,16 @@ ZeroDev provides a status API for monitoring uptime and performance metrics of R You can also find the status page here: https://status.zerodev.app/ -## API Documentation +## API documentation You can find the base URL at: https://status-api.zerodev.app/ -### 1. Get Uptime & Chain List +### 1. Get uptime & chain list **Endpoint**: `GET /uptime` -Returns the service's overall uptime status and a list of supported chains. This is the primary endpoint for checking general service health. -This returns uptime as a list of boolean values indicating health status for last 24 hours per minute. -Additionally this returns a list of chains supported by our bundler service. +- Returns the service’s overall uptime status and a list of supported chains. - This is the primary endpoint for checking general service health. +- This returns uptime as a list of boolean values indicating the health status for the last 24 hours, per minute. +- Additionally, this returns a list of chains supported by our bundler service. **Response Format**: ```json @@ -39,13 +39,10 @@ Additionally this returns a list of chains supported by our bundler service. } ``` ---- - -### 2. Get Chain Performance +### 2. Get chain performance **Endpoint**: `GET /performance/:chainId` -Returns detailed performance metrics for a specific chain. (for last 6 hours) -This endpoint gives the error rate, and latency performance data for the specific chain for every minute, and also for major RPC methods +Returns detailed performance metrics for a specific chain (for the last six hours). This endpoint provides error rate and latency performance data for the specific chain every minute, as well as for major RPC methods. **Parameters**: - `chainId` (path parameter): The numeric ID of the network (e.g., `42161`). diff --git a/docs/pages/sdk/core-api/using-plugins.mdx b/docs/pages/sdk/core-api/using-plugins.mdx index f1a5569..3e9e6ca 100644 --- a/docs/pages/sdk/core-api/using-plugins.mdx +++ b/docs/pages/sdk/core-api/using-plugins.mdx @@ -1,72 +1,72 @@ -# Using Plugins + # Using plugins -ZeroDev is built on [Kernel](https://github.com/zerodevapp/kernel), a *modular smart account* that can be extended with *plugins* (sometimes also called *modules*). + ZeroDev is built on [Kernel](https://github.com/zerodevapp/kernel), a *modular smart account* that is extensible with *plugins* (also called *modules*). -While there are many types of plugins, we will focus on *validators*, which modify the logic for validating UserOps. Validators are used for most of the major use cases of AA, including: + While there are many types of plugins, we will focus on *validators*, which modify the logic for validating UserOps. Validators are used for most of the major use cases of AA, including: -- Alternative signature schemes, such as passkeys and multisig. -- Dynamic access control, such as guardians and session keys. + - Alternative signature schemes, such as passkeys and multisig. + - Dynamic access control, such as guardians and session keys. -## Sudo vs regular validators + ## Sudo vs regular validators -For any given Kernel account, it will have one **sudo validator** and any number of **regular validators**. + For any given Kernel account, it will have one **sudo validator** and any number of **regular validators**. -- The **sudo validator** is the "owner" of the account. It's the only validator that can enable other validators. -- A **regular validator** represents an alternative form of access to the smart account. For example, a session key or a guardian would be a regular validator. Regular validators cannot enable other validators. + - The **sudo validator** is the "owner" of the account. It's the only validator that can enable other validators. + - A **regular validator** represents an alternative form of access to the smart account. For example, a session key or a guardian would be a regular validator. Regular validators cannot enable other validators. -When you set up a [Kernel account object](/sdk/core-api/create-account#create-a-kernel-account) with the SDK, you must specify a sudo validator, a regular validator, or both. Let's walk through the three cases: + When you set up a [Kernel account object](/sdk/core-api/create-account#create-a-kernel-account) with the SDK, you must specify a sudo validator, a regular validator, or both. Let's walk through the three cases: -### Using only a sudo validator + ### Using only a sudo validator -In the most common case, you set up a Kernel account that is powered by a single sudo validator. For example, to set up an account owned by a ECDSA key: + In the most common case, you set up a Kernel account that is powered by a single sudo validator. For example, to set up an account owned by an ECDSA key: -```ts -const account = await createKernelAccount(publicClient, { - plugins: { - sudo: ecdsaValidator, - }, - entryPoint, - kernelVersion -}) -``` + ```ts + const account = await createKernelAccount(publicClient, { + plugins: { + sudo: ecdsaValidator, + }, + entryPoint, + kernelVersion + }) + ``` -Here, when you send a UserOp, the ECDSA key will be used for signing the UserOp, and the ECDSA key has sudo access to the smart account (meaning it can do anything). + Here, when you send a UserOp, the ECDSA key is used to sign it, and the ECDSA key has sudo access to the smart account (meaning it can do anything). -### Enabling a regular validator + ### Enabling a regular validator -If you have access to the sudo validator, you can enable a regular validator. For example, to enable a [session key](/sdk/advanced/session-keys): + If you have access to the sudo validator, you can enable a regular validator. For example, to enable a [session key](/sdk/advanced/session-keys): -```ts -const account = await createKernelAccount(publicClient, { - plugins: { - sudo: ecdsaValidator, - regular: sessionKeyValidator, - }, - entryPoint, - kernelVersion -}) -``` + ```ts + const account = await createKernelAccount(publicClient, { + plugins: { + sudo: ecdsaValidator, + regular: sessionKeyValidator, + }, + entryPoint, + kernelVersion + }) + ``` -Now, when you send a UserOp with this `account`, the regular validator will be enabled, and the regular validator (in this case the session key) will be used for signing the UserOp. + Now, when you send a UserOp with this `account`, the regular validator activates, and the regular validator (in this case, the session key) signs the UserOp. -Note that Kernel plugins are enabled "lazily" -- you don't have to explicitly enable them. That is, whenever you send the first UserOp with an `account` object with a `regular` plugin, the plugin will be enabled as a part of that UserOp. The UserOp itself can do whatever it needs to do. + Note that Kernel plugins are enabled “lazily”—you don’t need to enable them explicitly. Whenever you send the first UserOp with an account object (with a `regular` plugin), the UserOp itself activates the plugin and can perform any required actions. -### Using only a regular validator + ### Using only a regular validator -If a regular validator has already been enabled, you can use it without access to the sudo validator. + If a regular validator has already been enabled, you can use it without access to the sudo validator. -For example, continuing the session key example above, if the session key has already been enabled, you can simply do: + For example, continuing the session key example above, if the session key has already been enabled, you can do: -```ts -const account = await createKernelAccount(publicClient, { - plugins: { - regular: sessionKeyValidator, - }, - entryPoint, - kernelVersion -}) -``` + ```ts + const account = await createKernelAccount(publicClient, { + plugins: { + regular: sessionKeyValidator, + }, + entryPoint, + kernelVersion + }) + ``` -## Next Steps + ## Next steps -Learn more about plugins such as [passkeys](/sdk/advanced/passkeys) and [permissions](/sdk/permissions/intro). + Learn more about plugins such as [passkeys](/sdk/advanced/passkeys) and [permissions](/sdk/permissions/intro). diff --git a/docs/pages/sdk/faqs/audits.md b/docs/pages/sdk/faqs/audits.md index e587507..97cc546 100644 --- a/docs/pages/sdk/faqs/audits.md +++ b/docs/pages/sdk/faqs/audits.md @@ -1,4 +1,4 @@ -# ZeroDev Audits +# ZeroDev audits All ZeroDev contracts and plugins are audited unless otherwise noted. diff --git a/docs/pages/sdk/faqs/chains.mdx b/docs/pages/sdk/faqs/chains.mdx index 40f7121..ae78899 100644 --- a/docs/pages/sdk/faqs/chains.mdx +++ b/docs/pages/sdk/faqs/chains.mdx @@ -1,8 +1,8 @@ -# Supported Networks +# Supported networks -Since we need to update this list manually, it may be missing some networks that we support. To see a complete list, check out [our dashboard](https://dashboard.zerodev.app/). +Since we need to update this list manually, it may miss some networks we support. To see a complete list, check out [our dashboard](https://dashboard.zerodev.app/). -## Regular EVM Networks +## Regular EVM networks | Network | ID | | -------------------------- | ---------- | @@ -66,7 +66,7 @@ Since we need to update this list manually, it may be missing some networks that | Unichain | 130 | | Unichain Sepolia | 1301 | -## Rollup Provider Networks +## Rollup provider networks We also support chains deployed on rollup providers like Conduit and Gelato. The comprehensive list is available on the [dashboard](https://dashboard.zerodev.app/). @@ -79,4 +79,4 @@ Top rollup networks: ## Are we missing a network? -If you don't see a EVM network that you'd like support for, feel free to reach out to us on [Discord](https://discord.gg/KS9MRaTSjx). +If you don't see an EVM network that you'd like support for, feel free to reach out to us on [Discord](https://discord.gg/KS9MRaTSjx). diff --git a/docs/pages/sdk/faqs/debug-userop.mdx b/docs/pages/sdk/faqs/debug-userop.mdx index 0a6af3d..371ee54 100644 --- a/docs/pages/sdk/faqs/debug-userop.mdx +++ b/docs/pages/sdk/faqs/debug-userop.mdx @@ -1,10 +1,10 @@ # Debugging UserOps with Tenderly -In account abstraction (ERC-4337), the transactions sent by smart accounts are known as "UserOps." UserOps are similar to but not the same as regular transactions, so it may not be clear how to debug them. +In account abstraction ([ERC-4337](https://eips.ethereum.org/EIPS/eip-4337)), transactions sent by smart accounts are called “UserOps.” UserOps are similar to but not the same as regular transactions, so it may not be clear how to debug them. -In this guide, we will be using [Tenderly](https://dashboard.tenderly.co/) to debug UserOps. Make sure you have signed up and created a Tenderly account. +In this guide, we will be using [Tenderly](https://dashboard.tenderly.co/) to debug UserOps. Make sure you have signed up and created a Tenderly account. -## The UserOp Structure +## The UserOp structure Let's begin by examining a typical UserOp example: @@ -25,11 +25,11 @@ Let's begin by examining a typical UserOp example: ``` -This UserOp structure will be our reference point as we navigate through the process of simulating and debugging UserOps. Understanding the components of this example is key to effectively using Tenderly's tools for our debugging needs. +This UserOp structure will serve as our reference point as we navigate the process of simulating and debugging UserOps. Understanding the components of this example is key to effectively using Tenderly’s tools for our debugging needs. -## UserOp Lifecycle +## UserOp lifecycle -Before delving into the nuances of debugging UserOps, it's helpful to learn the lifecycle of a UserOp. Here it is: +Before delving into the nuances of debugging UserOps, it’s helpful to understand its lifecycle. Here it is:

@@ -40,9 +40,9 @@ If this looks daunting, let's focus on only the high level: - A UserOp, with no gas estimates nor signature, is sent to a paymaster server, who simulates the UserOp and returns the gas estimates. - If the UserOp has any errors in the validation or execution phase, the paymaster server will return an error since it can't properly simulate it. - Now, the UserOp, with gas estimates and a proper signature, is sent to the bundler. - - At this point, the UserOp is not expected to revert during the validation phase, but it may nevertheless revert during the execution phase due to the on-chain state having changed between when the UserOp was sent to the paymaster and when it's submitted by the bundler. + - At this point, the UserOp is not expected to revert during the validation phase. Still, it may revert during execution if the onchain state changes between when the UserOp was sent to the paymaster and when the bundler submits it. -## Understanding UserOp Failures +## Understanding UserOp failures A UserOp can fail at various stages, including during the paymaster call (if sponsored), the gas estimation call, or the final execution call. Identifying the failure point is straightforward by examining the method indicated in the error log of the failed UserOp. For instance: @@ -53,11 +53,11 @@ A UserOp can fail at various stages, including during the paymaster call (if spo Failures are generally classified into two categories: - **Validation Errors**: These occur during the validation phase when transactions are deemed invalid due to issues like incorrect signatures or nonce values. They typically present as EntryPoint error codes (e.g., AA23: XXXX). -- **Execution Errors**: These occur during the execution phase when transactions are valid, but the contract interaction is reverted, often noted as **`execution reverted`**. +- **Execution Errors**: These occur during execution when transactions are valid, but the contract interaction is reverted, often indicated by **`execution reverted`**. -## Using Tenderly for Simulation and Debugging +## Using Tenderly for simulation and debugging -### Adjusting Gas Limits for Simulation +### Adjusting gas limits for simulation For failures during paymaster or gas estimation calls, the UserOp gas limits (**`preVerificationGas`**, **`callGasLimit`**, **`verificationGasLimit`**) may default to **`0x`**. Before simulating the UserOp, adjust these gas limits as shown below. Increase these values based on error feedback if the simulation fails: @@ -72,7 +72,7 @@ For failures during paymaster or gas estimation calls, the UserOp gas limits (** If the failure occurs during **`eth_sendUserOperation`**, the UserOp should already contain all necessary values for accurate simulation. -### Debugging Execution Errors +### Debugging execution errors To simulate a UserOp in Tenderly, follow these steps: @@ -88,13 +88,13 @@ To simulate a UserOp in Tenderly, follow these steps:

-3. Enter the EntryPoint contract address in `Insert any address` input and select the appropriate chain. +3. Enter the EntryPoint contract address in the `Insert any address` input and select the appropriate chain. - The EntryPoint address is `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` for v0.6 (default for ZeroDev SDK v5.1.x or below) and `0x0000000071727De22E5E9d8BAf0edAc6f37da032` for v0.7 (default for ZeroDev SDK v5.2.x or above) 4. Choose **`simulateHandleOp`**, input the UserOp into the tuple field, and commence the simulation. If the simulation fails, it typically indicates a problem with the end contract. Verify the initial calldata thoroughly. -### Simulating End Contract Calls +### Simulating end contract calls

@@ -102,11 +102,11 @@ If the simulation fails, it typically indicates a problem with the end contract. To simulate an end contract call: -1. Insert the Smart Contract Wallet address in `Insert any address` input (**`sender`** field from UserOp). +1. Insert the Smart Contract Wallet address in the `Insert any address` input (**`sender`** field from UserOp). 2. Select the chain and enter the EntryPoint contract address in the **`From`** field. 3. Enter the **`calldata`** field from UserOp into the **`Raw input data`** field and simulate the transaction. -### Debugging Validation Errors +### Debugging validation errors For validation errors, simulate the validation process by: @@ -131,7 +131,7 @@ On Tenderly, it might look like this: This result indicates various aspects of the validation process, with a particular focus on the failure due to signature validation (**`"sigFailed": true`**). Such output suggests that the UserOp failed validation because the signature did not match the expected parameters or was otherwise invalid. -## Decoding Error Messages +## Decoding error messages When a UserOp reverts with encoded error data, you can decode the error message to understand what went wrong. Here's how to decode error messages like: @@ -141,13 +141,13 @@ UserOperation reverted during simulation with reason: 0000000000000000000000000001d5472616e73616374696f6e20616c726561647920636f6e6669726d6564000000 ``` -### Step 1: Identify the Error Signature +### Step 1: Identify the error signature 1. Go to [https://openchain.xyz/signatures](https://openchain.xyz/signatures) 2. Search for the error signature (first 4 bytes): `0x08c379a0` -3. This will show you the error type - in this case, it's the standard Solidity `Error(string)` function +3. This will show you the error type—in this case, it's the standard Solidity `Error(string)` function, -### Step 2: Decode the Error Message +### Step 2: Decode the error message Use Viem's `decodeErrorResult` function to decode the full error data: @@ -176,9 +176,9 @@ console.log(error) In this example, the decoded error message is "Transaction already confirmed", which indicates that the transaction you're trying to execute has already been processed. -### Common Error Signatures +### Common error signatures -- `0x08c379a0` - Standard Solidity `Error(string)` revert +- `0x08c379a0`: Standard Solidity `Error(string)` revert - Custom errors will have different signatures that you can look up on openchain.xyz Understanding these decoded error messages helps you quickly identify and fix issues with your UserOps. diff --git a/docs/pages/sdk/faqs/use-with-ethers.mdx b/docs/pages/sdk/faqs/use-with-ethers.mdx index ce5f027..3ff101e 100644 --- a/docs/pages/sdk/faqs/use-with-ethers.mdx +++ b/docs/pages/sdk/faqs/use-with-ethers.mdx @@ -1,8 +1,8 @@ -# Can I Use a KernelClient with Ethers? +# Can I Use a KernelClient with Ethers.js? -Our KernelClient implements the Viem WalletClient interface. Although it is not directly compatible with Ethers.js, we have developed an EIP1193Provider that accepts a KernelClient as a constructor parameter. This provider enables the use of KernelClient with Ethers.js in a similar manner to how window.ethereum is utilized with Ethers.js. +Our `KernelClient` implements the Viem WalletClient interface. Although it is not directly compatible with Ethers.js, we have developed an `EIP1193Provider` that accepts a `KernelClient` as a constructor parameter. This provider enables using `KernelClient` with Ethers.js, as `window.ethereum` is used with Ethers.js. -Below is an example demonstrating how to use a KernelClient with the EIP1193Provider. This example assumes you are familiar with the creating of a KernelClient. For detailed instructions on creating a KernelClient, please refer to our [API docs](https://docs.zerodev.app/sdk/core-api/create-account). +Below is an example demonstrating how to use a `KernelClient` with the `EIP1193Provider`. This example assumes you are familiar with creating a `KernelClient`. For detailed instructions on creating a `KernelClient`, please refer to our [API docs](https://docs.zerodev.app/sdk/core-api/create-account). ```typescript import { KernelEIP1193Provider } from '@zerodev/sdk/providers'; diff --git a/docs/pages/sdk/faqs/use-with-gelato.mdx b/docs/pages/sdk/faqs/use-with-gelato.mdx index d7b3faf..4fab5d7 100644 --- a/docs/pages/sdk/faqs/use-with-gelato.mdx +++ b/docs/pages/sdk/faqs/use-with-gelato.mdx @@ -1,14 +1,14 @@ # Using ZeroDev with Gelato -Gelato's has a unique approach to handling transaction fees without the need for an EntryPoint deposit or an on-chain paymaster. Instead, transaction fees are settled post-execution via [1Balance](https://docs.gelato.network/web3-services/relay/subscriptions-and-payments/1balance-and-relay) across all supported networks, ensuring accurate charging of gas consumed without necessitating per-chain user deposits. +Gelato’s has a unique approach to handling transaction fees without requiring an EntryPoint deposit or an onchain paymaster. Instead, transaction fees are settled post-execution via [1Balance](https://docs.gelato.network/web3-services/relay/subscriptions-and-payments/1balance-and-relay) across all supported networks, ensuring accurate charging of gas consumed without necessitating per-chain user deposits. For a deeper understanding of Gelato's capabilities, refer to [their comprehensive documentation](https://docs.gelato.network/web3-services/account-abstraction/advantages-and-highlights). ## ZeroDev SDK with Gelato -Integrating Gelato with our SDK necessitates specific configurations, diverging from conventional bundler setups due to Gelato's distinct fee management mechanism. +Integrating Gelato with our SDK requires specific configurations that differ from conventional bundler setups, given Gelato’s distinct fee management mechanism. -### Essential Configurations +### Essential configurations - **Omit Paymaster**: Unlike other services, Gelato's transactions are sponsored without specifying a paymaster. Thus, your account will directly bear the gas fees incurred through Gelato's operations. diff --git a/docs/pages/sdk/faqs/use-with-react-native.mdx b/docs/pages/sdk/faqs/use-with-react-native.mdx index c3d76a6..83bc581 100644 --- a/docs/pages/sdk/faqs/use-with-react-native.mdx +++ b/docs/pages/sdk/faqs/use-with-react-native.mdx @@ -1,6 +1,6 @@ # Using ZeroDev with React Native -ZeroDev works great in React Native. Our user Stephen Gordon has helpfully made starter templates for: +ZeroDev works great in React Native. Our user Stephen Gordon has helpfully made starter templates for: - [ZeroDev with React Native.](https://github.com/stephen-gordon/zerodev-expo-starter) - [ZeroDev + Privy with Expo.](https://github.com/Stephen-Gordon/zerodev-privy-expo) diff --git a/docs/pages/sdk/getting-started/migration.mdx b/docs/pages/sdk/getting-started/migration.mdx index 54ed9e9..c027894 100644 --- a/docs/pages/sdk/getting-started/migration.mdx +++ b/docs/pages/sdk/getting-started/migration.mdx @@ -1,11 +1,11 @@ -# Migration Guide +# Migration guide ## API v2 => API v3 With API v3, the notable changes are: - A ZeroDev project can now support multiple networks. -- The same RPC can be used for both bundler and paymaster. +- * The same RPC is usable for both bundler and paymaster. Here's what a v3 RPC looks like: @@ -13,7 +13,7 @@ Here's what a v3 RPC looks like: https://rpc.zerodev.app/api/v3/xxxxxf2d-xxxx-xxxx-90cc-xxxxxxxxx007/chain/42161 ``` -Note that the last part `42161` is the chain ID. Therefore, if you'd like to programmatically use the RPC for different chains, you can do something like: +Note that the last part `42161` is the chain ID. Therefore, if you'd like to use the RPC for different chains programmatically, you can do something like: ```ts // replace the prefix with your own RPC prefix @@ -21,13 +21,13 @@ const rpcPrefix = `https://rpc.zerodev.app/api/v3/xxxxxf2d-xxxx-xxxx-90cc-xxxxxx const rpc = rpcPrefix + chain.id ``` -Of course, you can also simply copy the RPC for different chains from the dashboard. +Of course, you can also copy the RPC for different chains from the dashboard.

-The same RPC can then be used as both the bundler RPC and the paymaster RPC. See [the tutorial](/sdk/getting-started/tutorial#creating-a-kernel-client) for an example. +The same RPC can then be used as both the bundler RPC and the paymaster RPC. See [the tutorial](/sdk/getting-started/tutorial#creating-a-kernel-client) for an example. ## SDK 5.3.x => 5.4.x @@ -43,7 +43,7 @@ This guide will help you migrate your codebase to be compatible with the new ver npm uninstall permissionless ``` -2. **Ensure you have `viem@^2.21.40` version** +2. **Ensure you have the `viem@^2.21.40` version** ### Update `permissionless` Account Abstractions @@ -51,14 +51,14 @@ Replace any imports from `permissionless` with the equivalent from `viem/account ### Update Type Definitions -Replace `EntryPoint` Types +Replace the `EntryPoint` Types ```typescript import type { EntryPoint } from 'permissionless/types'; // [!code --] import type { EntryPointVersion } from 'viem/account-abstraction'; // [!code ++] ``` -Replace `UserOperation` Types +Replace the `UserOperation` Types ```typescript @@ -126,7 +126,7 @@ signerToEcdsaValidator(publicClient, { ### Added `estimateFeesPerGas` to `userOperation` in `createKernelAccountClient` `estimateFeesPerGas` is now required in `userOperation` in `createKernelAccountClient` to estimate the gas price for the user operation. -The default gas prices might be too high, so it's recommended to use this function to estimate the gas price. +The default gas prices might be too high, so it's recommended to use this function to estimate them. ```typescript const kernelClient = createKernelAccountClient({ diff --git a/docs/pages/sdk/getting-started/quickstart-7702.mdx b/docs/pages/sdk/getting-started/quickstart-7702.mdx index f29fe38..5cc1b74 100644 --- a/docs/pages/sdk/getting-started/quickstart-7702.mdx +++ b/docs/pages/sdk/getting-started/quickstart-7702.mdx @@ -1,10 +1,10 @@ -# Quickstart -- EIP-7702 +# Quickstart: EIP-7702 -[EIP-7702](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7702.md) is an Ethereum upgrade that allows for attaching a piece of EVM code to a EOA, effectively turning it into a "dual account" that can function simultaneously as a EOA and a smart account. You can learn more about EIP-7702 from our blog series [here](/blog/7702-adoption) and [here](/blog/7702-for-dapps). +[EIP-7702](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7702.md) is an Ethereum upgrade that allows attaching a piece of EVM code to an EOA, effectively turning it into a “dual account” that can function simultaneously as an EOA and a smart account. You can learn more about EIP-7702 from our blog series [here](/blog/7702-adoption) and [here](/blog/7702-for-dapps).. -In practical terms, this means that EOA users can now enjoy most of the benefits of AA, such as gas sponsorship, transaction batching, session keys, chain abstraction, and more. +In practical terms, this means EOA users can now enjoy most of the benefits of AA, including gas sponsorship, transaction batching, session keys, chain abstraction, and more. -In this example, we will upgrade a EOA into a ZeroDev smart account ([Kernel](https://github.com/zerodevapp/kernel)) and send a gasless batched transaction from it. +In this example, we will upgrade an EOA into a ZeroDev smart account ([Kernel](https://github.com/zerodevapp/kernel)) and send a gasless batched transaction from it. ## Complete example @@ -22,7 +22,7 @@ npm i @zerodev/sdk viem ## Create a project for a 7702-compatible network -In this example, we will use the Sepolia testnet, but you can use any 7702-compatible network such as Arbitrum and Base. +In this example, we will use the Sepolia testnet, but you can use any 7702-compatible network, such as Arbitrum and Base. - Go to [the ZeroDev dashboard](https://dashboard.zerodev.app) and create a project for `Sepolia`. - Enable gas sponsorship for Sepolia under `Gas Policies`. @@ -34,9 +34,9 @@ ZERODEV_RPC= Use the ZeroDev RPC on your project page from the dashboard. -## Upgrade EOA to smart account +## Upgrade EOA to a smart account -To upgrade a EOA to a smart account, you need to sign an "authorization." You can create this authorization manually and pass it to the ZeroDev SDK, or you can let ZeroDev create this authorization automatically. +To upgrade an EOA to a smart account, you need to sign an “authorization.” You can create this authorization manually and pass it to the ZeroDev SDK, or let ZeroDev create it automatically. ### Automatically create the authorization @@ -81,13 +81,13 @@ const kernelClient = createKernelAccountClient({ }) ``` -Note that in this example, `eip7702Account` is the EOA you want to upgrade. We are using a random EOA in this example but you should replace this with the actual EOA. +Note that in this example, `eip7702Account` is the EOA you want to upgrade. We are using a random EOA in this example, but you should replace this with the actual EOA. ### Manually create the authorization You can create the authorization manually with [Viem's `signAuthorization` function](https://viem.sh/docs/eip7702/signAuthorization), then pass the authorization to the ZeroDev SDK. -When you create the authorization, make sure you are specifying [Kernel](https://github.com/zerodevapp/kernel) as the smart account. +When creating the authorization, make sure you specify [Kernel](https://github.com/zerodevapp/kernel) as the smart account. ```ts import { KERNEL_V3_3 } from "@zerodev/sdk/constants"; @@ -107,7 +107,7 @@ const account = await createKernelAccount(publicClient, { ## Sending UserOps from the smart account -Once you have upgraded the EOA to a smart account, you can use the ZeroDev SDK as usual. For example, to send a gasless batched UserOp: +Once you have upgraded the EOA to a smart account, you can use the ZeroDev SDK as usual. For example, to send a gasless batched UserOp: ```ts const userOpHash = await kernelClient.sendUserOperation({ @@ -132,6 +132,6 @@ await kernelClient.waitForUserOperationReceipt({ console.log("UserOp completed") ``` -Congratulations! You just sent your first gasless, batched transaction using a EOA. You can see it by looking up your account on [the Sepolia explorer](https://sepolia.etherscan.io/). Note that you may need to look under "Internal Transactions" because UserOps do not appear as regular transactions. +Congratulations! You just sent your first gasless, batched transaction using an EOA. You can see it by looking up your account on [the Sepolia explorer](https://sepolia.etherscan.io/). Note that you may need to look under "Internal Transactions" because UserOps do not appear as regular transactions. -Easy, right? Now try some of the more advanced [examples](https://7702.zerodev.app/) for building with 7702, or explore the rest of the ZeroDev docs! +Easy, right? Now try some of the more advanced [examples](https://7702.zerodev.app/) for building with 7702, or explore the rest of the ZeroDev docs! diff --git a/docs/pages/sdk/getting-started/quickstart-agentkit.mdx b/docs/pages/sdk/getting-started/quickstart-agentkit.mdx index 710391a..f9e6594 100644 --- a/docs/pages/sdk/getting-started/quickstart-agentkit.mdx +++ b/docs/pages/sdk/getting-started/quickstart-agentkit.mdx @@ -1,16 +1,19 @@ -# Quickstart — ZeroDev × AgentKit (LangChain chatbot) +# Quickstart: ZeroDev × AgentKit (LangChain chatbot) -> **Goal**: build a minimal LangChain chatbot whose on-chain wallet is a ZeroDev smart account, all in 50 lines of code. +:::info Goal -The tutorial is a trimmed-down version of the full example that ships with AgentKit — `typescript/examples/langchain-zerodev-chatbot`. Here we swap the CDP MPC wallet for a local private key (via **Viem**) to keep things lightweight and dependency-free. +Build a minimal LangChain chatbot whose onchain wallet is a ZeroDev smart account, all in 50 lines of code. + +::: + +The tutorial is a trimmed-down version of the full example that ships with AgentKit—`typescript/examples/langchain-zerodev-chatbot`. Here we swap the CDP MPC wallet for a local private key (via **Viem**) to keep things lightweight and dependency-free. ---- ## 1. Prerequisites & install -• Node 18+ -• An **OpenAI** key (for the LLM) -• A **ZeroDev Project ID** (grab one from the dashboard — Base Sepolia is perfect for testing) +• Node 18+ +• An **OpenAI** key (for the LLM) +• A **ZeroDev Project ID** (grab one from the dashboard—Base Sepolia is perfect for testing) ```bash mkdir zerodev-agentkit-bot && cd zerodev-agentkit-bot @@ -23,8 +26,6 @@ npm i @coinbase/agentkit @coinbase/agentkit-langchain viem @langchain/core @lang npm i -D ts-node typescript @types/node ``` ---- - ## 2. Environment variables Create a `.env` file (or export vars however you prefer): @@ -38,8 +39,6 @@ PRIVATE_KEY= NETWORK_ID=base-sepolia ``` ---- - ## 3. The code (index.ts) ```ts title="index.ts" @@ -135,10 +134,10 @@ npx ts-node --env-file=.env index.ts ```txt Smart-account address: 0xAAc5…eF32 -Ask me to do something on-chain (type ‘exit’ to quit)… +Ask me to do something onchain (type ‘exit’ to quit)… Prompt: transfer 0.001 eth to 0x000000000000000000000000000000000000dEaD -✅ Sent a gas-sponsored transaction – hash 0x9eab…1d3a +✅ Sent a gas-sponsored transaction – hash 0x9eab…1d3a --- Prompt: what’s my eth balance? @@ -146,12 +145,10 @@ Your smart-account holds ~0.42 ETH on Base Sepolia. --- ``` ---- - ## 4. Next steps -• Swap the local key for a **CDP** or **Privy** wallet for MPC security. -• Add more `actionProviders` (ERC-20, ERC-721, DeFi, …) so the agent can do *real* work. +• Swap the local key for a **CDP** or **Privy** wallet for MPC security. +• Add more `actionProviders` (`ERC-20`, `ERC-721`, DeFi,...) so the agent can do *real* work. • Explore the [full chatbot example](https://github.com/coinbase/agentkit/tree/main/typescript/examples/langchain-zerodev-chatbot) for persistence, autonomous mode, and more advanced prompts. Happy hacking 🚀 diff --git a/docs/pages/sdk/getting-started/quickstart.mdx b/docs/pages/sdk/getting-started/quickstart.mdx index aa70d77..6b4c9a2 100644 --- a/docs/pages/sdk/getting-started/quickstart.mdx +++ b/docs/pages/sdk/getting-started/quickstart.mdx @@ -142,6 +142,6 @@ Waiting for UserOp to complete... View completed UserOp here: https://jiffyscan.xyz/userOpHash/0x7a8e0ba961cc0a34f745b81d64766f033269fee831104fee0269fa5bcc397dcb ``` -Congrats -- you just sent your first gasless transaction with ZeroDev! +Congrats—you just sent your first gasless transaction with ZeroDev! -In this example, you used a public ZeroDev API key. Now read [the tutorial](/sdk/getting-started/tutorial) to see how to set up your own ZeroDev project. +In this example, you used a public ZeroDev API key. Now read [the tutorial](/sdk/getting-started/tutorial) to see how to set up your own ZeroDev project. diff --git a/docs/pages/sdk/getting-started/tutorial-passkeys.mdx b/docs/pages/sdk/getting-started/tutorial-passkeys.mdx index 947aa74..854c1e0 100644 --- a/docs/pages/sdk/getting-started/tutorial-passkeys.mdx +++ b/docs/pages/sdk/getting-started/tutorial-passkeys.mdx @@ -1,6 +1,6 @@ -# ZeroDev Tutorial -- Passkeys +# ZeroDev tutorial: Passkeys -In this tutorial, we will be building a Next.js app where your users can create smart accounts and send UserOps with [passkeys](/sdk/advanced/passkeys). +In this tutorial, we will build a Next.js app where users can create smart accounts and send UserOps with [passkeys](/sdk/advanced/passkeys). ## Clone the template @@ -10,7 +10,7 @@ We have prepared a [Next.js template](https://github.com/zerodevapp/passkey-tuto git clone git@github.com:zerodevapp/passkey-tutorial.git ``` -If you ever want to check out the completed code, you can checkout [the `completed` branch](https://github.com/zerodevapp/passkey-tutorial/tree/completed). You can also see a deployed demo [here](https://passkey-demo.zerodev.app/). +If you ever want to see the completed code, check out [the `completed` branch](https://github.com/zerodevapp/passkey-tutorial/tree/completed). You can also see a deployed demo [here](https://passkey-demo.zerodev.app/). Run the app in development mode: @@ -19,7 +19,7 @@ npm i npm run dev ``` -Open `app/page.tsx`. We will be working on this file for the rest of the tutorial. +Open `app/page.tsx`. We will be working on this file for the rest of the tutorial. ## Create a ZeroDev project @@ -92,7 +92,7 @@ const handleLogin = async () => { } ``` -In this tutorial, we are using a public passkey server URL. In practice, you'd create your own passkey server URL from [the dashboard](https://dashboard.zerodev.app/). +In this tutorial, we are using a public passkey server URL. In practice, you'd create your own passkey server URL from [the dashboard](https://dashboard.zerodev.app/). Now modify `createAccountAndClient` to actually create the account using the `passkeyValidator`: @@ -133,7 +133,7 @@ At this point, you should be able to create passkey accounts with either `Regist ## Sending UserOps -Sending UserOps from a passkey account is the same as sending them from any account. Modify `handleSendUserOp` as such: +Sending UserOps from a passkey account is the same as sending them from any account. Modify `handleSendUserOp` as such: ```ts const handleSendUserOp = async () => { @@ -168,14 +168,14 @@ const handleSendUserOp = async () => { Now try sending some UserOps! -Also, the UserOps are sponsored thanks to paymasters -- that's why you are able to send UserOps from an account with no ETH. +Also, the UserOps are sponsored thanks to paymasters—that’s why you can send UserOps from an account with no `ETH`. -## Next Steps +## Next steps -In this tutorial, you were able to create smart accounts and send UserOps with passkeys. +In this tutorial, you created smart accounts and sent UserOps with passkeys. For next steps: -- Check out [the core API](/sdk/core-api/create-account) to learn more about the SDK -- Learn more about [passkeys](/sdk/advanced/passkeys) -- Read some [code examples](https://github.com/zerodevapp/zerodev-examples) of using ZeroDev +- Check out [the core API](/sdk/core-api/create-account) to learn more about the SDK. +- Learn more about [passkeys](/sdk/advanced/passkeys). +- Read some [code examples](https://github.com/zerodevapp/zerodev-examples) of using ZeroDev. diff --git a/docs/pages/sdk/getting-started/tutorial.mdx b/docs/pages/sdk/getting-started/tutorial.mdx index 7c9bdcf..06f50ee 100644 --- a/docs/pages/sdk/getting-started/tutorial.mdx +++ b/docs/pages/sdk/getting-started/tutorial.mdx @@ -1,12 +1,14 @@ -# ZeroDev Tutorial +# ZeroDev tutorial :::info -Impatient? Check out [the complete example here](https://github.com/zerodevapp/zerodev-examples/tree/main/tutorial/completed.ts). + +Impatient? Check out [the complete example here](https://github.com/zerodevapp/zerodev-examples/tree/main/tutorial/completed.ts). + ::: In this tutorial, we will mint an NFT without paying gas. -## Create a ZeroDev Project +## Create a ZeroDev project For this tutorial, we will use [ZeroDev's AA infra](/meta-infra/intro), but you can use ZeroDev with any AA infra provider. @@ -28,7 +30,7 @@ Go to the `Gas Policies` section of your dashboard, select `Sepolia`, and toggle ## Write the code -Clone the [ZeroDev examples repo](https://github.com/zerodevapp/zerodev-examples). Then, inside the directory, install all dependencies: +Clone the [ZeroDev examples repo](https://github.com/zerodevapp/zerodev-examples). Then, inside the directory, install all dependencies: ```bash npm install @@ -40,7 +42,7 @@ Create a `.env` file with the following line: ZERODEV_RPC= ``` -Replace `` with the RPC you copy from the dashboard: +Replace `` with the RPC you copied from the dashboard:

@@ -52,13 +54,13 @@ If all goes well, you should be able to run: npx ts-node tutorial/completed.ts ``` -Now open the [`tutorial/template.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/template.ts) file in your editor. This will be the template where you will write your code. You can always refer to [`tutorial/completed.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/completed.ts) to see the completed tutorial code. +Now open the [`tutorial/template.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/template.ts) file in your editor. This will be the template where you will write your code. You can always refer to [`tutorial/completed.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/completed.ts) to see the completed tutorial code. ### Create a signer -Kernel accounts support many different signing methods, including ECDSA keys and passkeys. In this tutorial, we will use ECDSA keys which are the same type of keys that MetaMask and other Ethereum wallets use. +Kernel accounts support many different signing methods, including ECDSA keys and passkeys. In this tutorial, we will use ECDSA keys, the same type used by MetaMask and other Ethereum wallets. -Let's start by generating a random key. Add the following code to the `main` function: +Let's start by generating a random key. Add the following code to the `main` function: ```typescript import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" @@ -71,7 +73,7 @@ const main = async () => { ### Create a validator -Each Kernel account handles validation through a smart contract known as a "validator." In this case, we will be using the ECDSA validator. +Each Kernel account handles validation through a smart contract known as a "validator." In this case, we will be using the ECDSA validator. Add the following code to create the ECDSA validator: @@ -90,7 +92,7 @@ const main = async () => { ### Create an account -We are now ready to create an account. Add the following code: +We are now ready to create an account. Add the following code: ```typescript import { createKernelAccount } from "@zerodev/sdk" @@ -109,7 +111,7 @@ const main = async () => { ### Creating a Kernel client -Finally, we are going to create an "account client" which serves as the connection between your account and some AA infra (i.e. bundlers and paymasters). The connection is necessary for you to actually send UserOps. +Finally, we are going to create an “account client” that serves as the connection between your account and AA infrastructure (i.e., bundlers and paymasters). The connection is necessary for you to send UserOps. Add the following code: @@ -143,7 +145,7 @@ Run this script with `npx ts-node tutorial/template.ts` and confirm that it prin ### Send a UserOp -Now that you have an account client, it's time to send your first UserOp! For this tutorial, we will mint an NFT from a contract deployed on Sepolia. +Now that you have an account client, it's time to send your first UserOp! For this tutorial, we will mint an NFT from a contract deployed on Sepolia. Add the following import and code: @@ -168,18 +170,18 @@ const main = async () => { } ``` -There's quite a bit of code going on, so let's go through it. +There's quite a bit of code, so let's go through it. - We start by calling `kernelClient.sendUserOperation`, which takes a `userOperation` argument. -- Inside `userOperation`, we specify a `callData` field. This is the equivalent of the calldata field for a normal Ethereum transaction. +- Inside `userOperation`, we specify a `callData` field. This is equivalent to the calldata field in a typical Ethereum transaction. - Since we want to call the `mint(address)` function on the NFT contract, we use Viem's helper function `encodeFunctionData` and give it the ABI, function name, and function argument. -- `kernelClient.sendUserOperation` returns a "UserOperation hash." This is the equivalent of a transaction hash but for a UserOp. +- `kernelClient.sendUserOperation` returns a "UserOperation hash." This is the equivalent of a transaction hash but for a UserOp. -Run the script again with `npx ts-node tutorial/template.ts` and confirm that it prints the UserOp hash. At this point, you can go to a UserOp explorer such as [JiffyScan](https://jiffyscan.xyz/) and find your UserOp with the hash! +Run the script again with `npx ts-node tutorial/template.ts` and confirm that it prints the UserOp hash. At this point, you can use a UserOp explorer such as [JiffyScan](https://jiffyscan.xyz/) to find your UserOp by its hash! ### Waiting for the UserOp -When you call `sendUserOperation`, the call returns as soon as the UserOp has been submitted to the bundler, but it doesn't wait for the UserOp to be "confirmed" on-chain. To wait for the UserOp to be confirmed, add the following import and code: +When you call `sendUserOperation`, the call returns as soon as the UserOp has been submitted to the bundler, but it doesn't wait for the UserOp to be "confirmed" onchain. To wait for the UserOp to be confirmed, add the following import and code: ```typescript @@ -195,12 +197,12 @@ const main = async () => { Let's break down the code: -- `waitForUserOperationReceipt` is a bundler action. If you are unfamiliar with the concept of "actions," you can read more about it on [Viem's documentation](https://viem.sh/docs/actions/public/introduction). -- This function returns a "receipt" object. If you are curious, you can print the full object and see what it contains. +- `waitForUserOperationReceipt` is a bundler action. If you are unfamiliar with the concept of "actions," you can read more about it on [Viem's documentation](https://viem.sh/docs/actions/public/introduction). +- This function returns a "receipt" object. If you are curious, you can print the full object and see what it contains. ### Read contract state -Now let's confirm that we actually minted an NFT. Add the following import and code: +Now let's confirm that we actually minted an NFT. Add the following import and code: ```typescript import { publicActions } from "viem" @@ -218,7 +220,7 @@ const main = async () => { } ``` -Run the script again. You should see that it prints `NFT balance: 1`, confirming that you have minted an NFT! +Run the script again. You should see it print "`NFT balance: 1`," confirming that you have minted an NFT! ## Next steps @@ -226,5 +228,5 @@ In this tutorial, we were able to mint an NFT without paying gas, thanks to gas For next steps: -- Check out [the core API](/sdk/core-api/create-account) to learn more about the SDK -- Read some [code examples](https://github.com/zerodevapp/zerodev-examples) of using ZeroDev \ No newline at end of file +- Check out [the core API](/sdk/core-api/create-account) to learn more about the SDK. +- Read some [code examples](https://github.com/zerodevapp/zerodev-examples) of using ZeroDev. \ No newline at end of file diff --git a/docs/pages/sdk/infra/coinbase.md b/docs/pages/sdk/infra/coinbase.md index 740bd77..117fc9d 100644 --- a/docs/pages/sdk/infra/coinbase.md +++ b/docs/pages/sdk/infra/coinbase.md @@ -2,6 +2,6 @@ [Coinbase Developer Platform](https://docs.cdp.coinbase.com/) (CDP) offers bundler and paymaster services that you can use with ZeroDev. -Generally speaking, Coinbase bundlers & paymasters speak the same interface as Pimlico, so you can follow [this guide](/sdk/infra/pimlico) and simply replace the Pimlico bundler/paymaster URLs with the CDP bundler/paymaster URLs. +Generally speaking, Coinbase bundlers & paymasters speak the same interface as Pimlico, so you can follow [this guide](/sdk/infra/pimlico) and replace the Pimlico bundler/paymaster URLs with the CDP bundler/paymaster URLs. You can also refer to [CDP's official examples for ZeroDev](https://github.com/coinbase/paymaster-bundler-examples/tree/master/examples/zerodev). diff --git a/docs/pages/sdk/infra/intro.md b/docs/pages/sdk/infra/intro.md index 86e7571..78423da 100644 --- a/docs/pages/sdk/infra/intro.md +++ b/docs/pages/sdk/infra/intro.md @@ -1,4 +1,4 @@ -# Choosing an infra provider +# Choosing an infrastructure provider ZeroDev is compatible with any account abstraction infra provider. Check out these guides for integrating with a specific provider: @@ -9,7 +9,7 @@ Read on to learn how to integrate with a custom provider. ## Interop with Bundlers -For the most part, bundlers are perfectly interoperable between different providers. You simply specify the bundler RPC when you construct a Kernel client: +For the most part, bundlers are perfectly interoperable between different providers. You specify the bundler RPC when you construct a Kernel client: ```typescript import { createKernelAccountClient } from "@zerodev/sdk"; @@ -24,7 +24,7 @@ const kernelClient = createKernelAccountClient({ ## Interop with Paymasters -If the Paymaster supports [ERC-7677](https://www.erc7677.xyz/) paymaster methods, you can simply pass the Paymaster RPC URL to `createZeroDevPaymasterClient`: +If the Paymaster supports [ERC-7677](https://www.erc7677.xyz/) paymaster methods, you can pass the Paymaster RPC URL to `createZeroDevPaymasterClient`: ```typescript import { createKernelAccountClient, createZeroDevPaymasterClient } from "@zerodev/sdk" @@ -41,7 +41,7 @@ const kernelClient = createKernelAccountClient({ }) ``` -To integrate with a paymaster which doesn't support [ERC-7677](https://www.erc7677.xyz/), you need to implement the `getPaymasterData` function: +To integrate with a paymaster that doesn't support [ERC-7677](https://www.erc7677.xyz/), you need to implement the `getPaymasterData` function: ```typescript const kernelClient = createKernelAccountClient({ diff --git a/docs/pages/sdk/infra/pimlico.md b/docs/pages/sdk/infra/pimlico.md index 6b7edd1..bfb2d63 100644 --- a/docs/pages/sdk/infra/pimlico.md +++ b/docs/pages/sdk/infra/pimlico.md @@ -4,7 +4,7 @@ You can use the ZeroDev SDK with Pimlico bundlers. ## Using Pimlico bundler -Simply specify Pimlico's bundler RPC when [constructing a Kernel client](/sdk/core-api/create-account#standard-api): +Specify Pimlico's bundler RPC when [constructing a Kernel client](/sdk/core-api/create-account#standard-api): ```typescript import { createKernelAccountClient } from "@zerodev/sdk" diff --git a/docs/pages/sdk/infra/zerodev.md b/docs/pages/sdk/infra/zerodev.md index 6a27ce6..8497bd0 100644 --- a/docs/pages/sdk/infra/zerodev.md +++ b/docs/pages/sdk/infra/zerodev.md @@ -1,3 +1,3 @@ # ZeroDev -ZeroDev provides a meta infrastructure that proxies traffic to multiple infra providers including Alchemy, Gelato and Pimlico. [Read more here](/meta-infra/intro). \ No newline at end of file +ZeroDev provides a meta infrastructure that proxies traffic to multiple infrastructure providers, including Alchemy, Gelato, and Pimlico. [Read more here](/meta-infra/intro). \ No newline at end of file diff --git a/docs/pages/sdk/permissions/1-click-trading.mdx b/docs/pages/sdk/permissions/1-click-trading.mdx index 3c3f9f3..a2f63fd 100644 --- a/docs/pages/sdk/permissions/1-click-trading.mdx +++ b/docs/pages/sdk/permissions/1-click-trading.mdx @@ -1,8 +1,8 @@ -# Tutorial -- Transaction Automation +# Tutorial: Transaction automation In this tutorial, you will learn how to enable 1-click trading for your app using session keys. -Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/1-click-trading.ts) while you follow along the tutorial. You can run the example by following instructions of [the examples repo](https://github.com/zerodevapp/zerodev-examples). +Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/1-click-trading.ts) while you follow along with the tutorial. You can run the example by following the instructions in [the examples repo](https://github.com/zerodevapp/zerodev-examples). ## Installation @@ -28,16 +28,20 @@ bun add @zerodev/permissions ::: -## Owner-Agent Architecture +## Owner-Agent architecture -There are multiple ways to use session keys. In this tutorial, we will use the popular "owner-agent" pattern: +There are multiple ways to use session keys. In this tutorial, we will use the popular "owner-agent" pattern: - The "owner" is the owner of the master key. - The "agent" is the entity that wants to use the session key. -In a typical setup, you might be wishing to automate transactions for your users from your server. +In a typical setup, you can automate transactions for your users on your server. -your user's master key might be connected to your DApp frontend, in which case your frontend is the "owner." You might be wishing + ## API @@ -53,7 +57,7 @@ With a permissions validator, you are putting together: ### Creating a signer -Start by creating a [ECDSA signer](/sdk/permissions/signers/ecdsa): +Start by creating an [ECDSA signer](/sdk/permissions/signers/ecdsa): ```ts const sessionPrivateKey = generatePrivateKey() @@ -95,7 +99,7 @@ const rateLimitPolicy = toRateLimitPolicy({ ### Composing signer and policies -Here comes the fun part -- we "compose" the signer and policies together into a single validator: +Here comes the fun part—we "compose" the signer and policies together into a single validator: ```ts const sessionKeyValidator = await toPermissionValidator(publicClient, { @@ -109,11 +113,11 @@ const sessionKeyValidator = await toPermissionValidator(publicClient, { }), ``` -Now, we have created a ECDSA session key that's subject to a call policy and a rate limit policy. Just like that! +Now, we have created an ECDSA session key that's subject to a call policy and a rate limit policy. Just like that! ### Using the session key -Finally, we can set up the account with this session key as the signer. Note that if this is the first time that the session key is used, we need to [enable the plugin](/sdk/core-api/using-plugins#enabling-a-regular-validator). +Finally, we can set up the account with this session key as the signer. Note that if this is the first time that the session key is used, we need to [enable the plugin](/sdk/core-api/using-plugins#enabling-a-regular-validator). ```ts const account = await createKernelAccount(publicClient, { @@ -126,21 +130,21 @@ const account = await createKernelAccount(publicClient, { }) ``` -Now you can [set up a Kernel client](/sdk/core-api/create-account#create-an-account-client) using this account, and start minting NFTs with this session key -- but only up to once a month! +Now you can [set up a Kernel client](/sdk/core-api/create-account#create-an-account-client) using this account, and start minting NFTs with this session key—but only up to once a month! Try running [this script](https://github.com/zerodevapp/zerodev-examples/blob/main/permissions/main.ts) and see for yourself. ## Storing Session Keys -Session keys (and permission validators in general) can be stored, by serializing them and then deserializing them later. +Session keys (and permission validators in general) can be stored by serializing them and then deserializing them later. ### Code examples -There are two general patterns with storing session keys. +There are two general patterns for storing session keys. -- The owner creates a session key for another agent to store & use. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/owner-created.ts). -- The agent creates a session key and asks the owner to "approve" it as a session key. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/agent-created.ts). - - In this flow, the owner never sees the private part of the session key, so it may be better for security. +- The owner creates a session key for another agent to store & use. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/owner-created.ts). +- The agent generates a session key and asks the owner to “approve” it. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/agent-created.ts). + - In this flow, the owner never sees the private part of the session key, which may be better for security. ### Serializing a session key @@ -148,7 +152,7 @@ There are two general patterns with storing session keys. const serializedSessionKey = await serializePermissionAccount(sessionKeyAccount, sessionPrivateKey) ``` -Note that `sessionPrivateKey` is optional. If the private key is not included, then you must provide the private key when you deserialize the session key. +Note that `sessionPrivateKey` is optional. If the private key is not included, you must provide it when deserializing the session key. ### De-serializing a session key diff --git a/docs/pages/sdk/permissions/actions/build-your-own.mdx b/docs/pages/sdk/permissions/actions/build-your-own.mdx index c3ebd31..f71166e 100644 --- a/docs/pages/sdk/permissions/actions/build-your-own.mdx +++ b/docs/pages/sdk/permissions/actions/build-your-own.mdx @@ -1,3 +1,3 @@ -# Build Your Own Action +# Build your own action Guide coming soon. \ No newline at end of file diff --git a/docs/pages/sdk/permissions/install-with-init-config.mdx b/docs/pages/sdk/permissions/install-with-init-config.mdx index 6562f87..01e6ca6 100644 --- a/docs/pages/sdk/permissions/install-with-init-config.mdx +++ b/docs/pages/sdk/permissions/install-with-init-config.mdx @@ -1,9 +1,11 @@ -# Installing Permissions During Account Creation +# Installing permission during account creation -You can install permission plugins during account creation using `initConfig`. This approach allows you to set up permissions right when the account is deployed. +You can install permission plugins during account creation using `initConfig`. This approach lets you set up permissions when the account is deployed. :::note + The counterfactual account address is tied to the permission plugin configuration. If you modify the permission plugin's configuration after account creation and reinstall it, you'll need to explicitly specify the account address using the `address` parameter when calling `createKernelAccount`. + ::: ## Example @@ -35,6 +37,6 @@ const account = await createKernelAccount(publicClient, { }) ``` -## Starter Template +## Starter template An example of a starter template for installing permissions during account creation is available [here](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/install-permissions-with-init-config.ts). \ No newline at end of file diff --git a/docs/pages/sdk/permissions/intro.mdx b/docs/pages/sdk/permissions/intro.mdx index e4bf7ab..49530f0 100644 --- a/docs/pages/sdk/permissions/intro.mdx +++ b/docs/pages/sdk/permissions/intro.mdx @@ -1,25 +1,25 @@ -# Permissions (Session Keys) +# Permissions (session keys) -With Kernel, you can assign different permissions to different keys. Some of these keys might be owned by the owner(s) of the smart account, and some might be short-lived keys that you share with others to delegate transactions. The latter are also commonly known as "session keys." +With Kernel, you can assign different permissions to different keys. Some of these keys might be owned by the owner(s) of the smart account, and some might be short-lived keys that you share with others to delegate transactions. The latter are also commonly known as "session keys." To set up permissions for a key, you must answer three questions: who, when, and what. -- **Who** (what key) can perform the action? +- **Who** (what key) can take the action? - **When** (under what condition) can the action be performed? -- **What** is the action anyways? +- **What** is the action anyway? These three questions correspond to three types of "permissions plugins": - **Signers** (who) specify the key and the algorithm (ECDSA, WebAuthn) it uses. -- **Policies** (when) specify the *conditions* under which the keys can be used. Some example conditions are: +- **Policies** (when) specify the *conditions* under which the keys are usable. Some example conditions are: - Only if interacting with Uniswap - Only if spending USDC - Only once a month - **Actions** (what) specify the execution function the key uses. -## Composing Permissions +## Composing permissions -Kernel is the first smart account to support *composable permissions*. That is, you can build up fine-grained permissions from putting together signers, policies, and actions. Here's the formula: +Kernel is the first smart account to support *composable permissions*. That is, you can build fine-grained permissions by combining signers, policies, and actions. Here’s the formula: ``` Permission = 1 signer + N policies + 1 action @@ -39,17 +39,17 @@ const account = createKernelAccount({ }) ``` -Here, the `signer` will be able to perform `action` if all `policies` are met. +Here, the `signer` will be able to call `action` if all `policies` are met. Now let's dive into these plugin types. -## Permission Plugins +## Permission plugins Because permissions are plugins, **you can write your own permissions** if the default ones provided by ZeroDev don't meet your needs. ### Signers -Signers specify the keys and the algorithms the keys use. ZeroDev provides signers for: +Signers specify the keys and the algorithms the keys use. ZeroDev provides signers for: - ECDSA - WebAuthn (passkeys) @@ -57,7 +57,7 @@ Signers specify the keys and the algorithms the keys use. ZeroDev provides sign ### Policies -Policies are the conditions under which the keys can be used. ZeroDev provides the following policies: +Policies are the conditions under which the keys are usable. ZeroDev provides the following policies: - [Sudo policy](/sdk/permissions/policies/sudo): you can do anything - [Call policy](/sdk/permissions/policies/call): you can only call certain contracts or functions (and only with certain params) @@ -68,12 +68,12 @@ Policies are the conditions under which the keys can be used. ZeroDev provides ### Actions -Actions are arbitrary functions that the smart account will `delegatecall` to. They give you perfect flexibility over the execution logic. +Actions are arbitrary functions that the smart account will `delegatecall` to. They give you perfect flexibility over the execution logic. -Note that actions are NOT to be confused with the calls you actually want to execute. For example, if you want to interact with Uniswap, that's just the call you want to execute. "Action" here specifically refers to the execution function by which Uniswap is called. +Note that actions are NOT to be confused with the calls you actually want to execute. For example, if you want to interact with Uniswap, that's just the call you want to execute. "Action" here specifically refers to the execution function by which Uniswap is called. -If that's confusing, just forget about actions. Mostly commonly you will only be setting up signers and policies, and the `action` will default to Kernel's default `execute()` function, which is enough for most needs. +If that's confusing, just forget about actions. Most commonly, you will only set up signers and policies, and the `action` will default to Kernel's `execute()` function, which is enough for most needs. -## Next Steps +## Next steps - [Learn to automate transactions for users with permissions.](/sdk/permissions/transaction-automation) \ No newline at end of file diff --git a/docs/pages/sdk/permissions/policies/build-your-own.mdx b/docs/pages/sdk/permissions/policies/build-your-own.mdx index 28d0b4c..81e6f72 100644 --- a/docs/pages/sdk/permissions/policies/build-your-own.mdx +++ b/docs/pages/sdk/permissions/policies/build-your-own.mdx @@ -1,3 +1,3 @@ -# Build Your Own Policy +# Build your own policy Guide coming soon. \ No newline at end of file diff --git a/docs/pages/sdk/permissions/policies/call.mdx b/docs/pages/sdk/permissions/policies/call.mdx index fcab65f..ab8a9a7 100644 --- a/docs/pages/sdk/permissions/policies/call.mdx +++ b/docs/pages/sdk/permissions/policies/call.mdx @@ -1,6 +1,6 @@ -# Call Policy +# Call policy -The call policy limits the target (either contract or EOA) that the UserOp can interact with. If the target is a contract, then you can further specify the functions the UserOp can interact with, as well as putting constraints on the values of the function arguments. +The call policy limits the target (either contract or EOA) that the UserOp can interact with. If the target is a contract, then you can further specify the functions the UserOp can interact with, as well as put constraints on the values of the function arguments. ## API @@ -43,12 +43,12 @@ const validator = toPermissionValidator(publicClient, { }) ``` -- `target`: the target contract to call or address to send ETH to. If this is `zeroAddress`, then the target can be any contract as long as the ABI matches (or it can be any address if no ABI is specified). +- `target`: the target contract to call or address to send `ETH` to. If this is `zeroAddress`, the target can be any contract as long as the ABI matches (or any address if no ABI is specified). - `valueLimit`: the maximum value. that can be transmitted. - `abi`: the contract ABI - `functionName`: the function name -- `selector`: if you have multiple functions with the same name, you can distinguish them with `selector`. For example: `selector: toFunctionSelector("transfer(uint256, uint256)")`. -- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. use `null` to skip an argument. +- `selector`: if you have multiple functions with the same name, you can distinguish them with `selector`. For example: `selector: toFunctionSelector("transfer(uint256, uint256)")`. +- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. Use `null` to skip an argument. - `operator`: this can be `EQUAL`, `GREATER_THAN`, `LESS_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`, `NOT_EQUAL`. - - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the argument must be equal to 2". -- `operation`: whether this is a call or a delegatecall. Defaults to call. + - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the argument must be equal to 2". +- `operation`: whether this is a call or a delegatecall. Defaults to call. diff --git a/docs/pages/sdk/permissions/policies/gas.mdx b/docs/pages/sdk/permissions/policies/gas.mdx index 1d29f3a..5506476 100644 --- a/docs/pages/sdk/permissions/policies/gas.mdx +++ b/docs/pages/sdk/permissions/policies/gas.mdx @@ -1,6 +1,6 @@ -# Gas Policy +# Gas policy -The gas policy specifies how much gas the signer can use in total, across all UserOps it sends. It can also enforce that the UserOps must use paymasters, or use a specific paymaster. +The gas policy specifies the total amount of gas the signer can use across all UserOps it sends. It can also enforce that the UserOps must use paymasters, or use a specific paymaster. ## API @@ -35,6 +35,6 @@ const validator = toPermissionValidator(publicClient, { `toGasPolicy` takes one or more of the following arguments: -- `allowed`: an amount, in wei, of the ETH (or whatever native token) that the signer can spend on gas, in total across all UserOps it sends. -- `enforcePaymaster`: a boolean value. If set to true, enforce that a paymaster must be used. -- `allowedPaymaster`: a paymaster address. If set, enforce that the specific paymaster is used. \ No newline at end of file +- `allowed`: an amount, in wei, of the `ETH` (or whatever native token) that the signer can spend on gas, in total across all UserOps it sends. +- `enforcePaymaster`: a boolean value. If set to true, a paymaster must be utilized. +- `allowedPaymaster`: a paymaster address. If set, enforce the use of the specific paymaster. \ No newline at end of file diff --git a/docs/pages/sdk/permissions/policies/rate-limit.mdx b/docs/pages/sdk/permissions/policies/rate-limit.mdx index 02f4b2d..021a0fd 100644 --- a/docs/pages/sdk/permissions/policies/rate-limit.mdx +++ b/docs/pages/sdk/permissions/policies/rate-limit.mdx @@ -1,6 +1,6 @@ -# Rate Limit Policy +# Rate limit policy -The rate limit policy specifies the frequency at which the signer is allowed to send UserOps. +The rate limit policy specifies the frequency at which the signer can send UserOps. We have two types of rate limit policies: @@ -9,7 +9,7 @@ We have two types of rate limit policies: ## Rate limit with no reset -Send one UserOp per `interval`, for up to `count` times. Each UserOp call must have at least an `interval` of time between it and the next call. +Send one UserOp per `interval`, for up to `count` times. Each UserOp call must have at least an `interval` of time between it and the next call. ### API @@ -37,17 +37,17 @@ Arguments to `toRateLimitPolicy`: - `count`: the number of intervals. - (optional) `interval`: the length of an interval. -- (optional) `startAt`: the starting UNIX timestamp for when the rate limit should take effect. Before that, the signer cannot send any UserOps. +- (optional) `startAt`: the starting UNIX timestamp for when the rate limit should take effect. Before that, the signer cannot send any UserOps. ## Rate limit with reset -Send `count` UserOps within an `interval`, for an indefinite number of intervals. +Send `count` UserOps within an `interval` for an indefinite number of intervals. -The Rate Limit Policy with reset allows you to define a recurring allowance of UserOps that refreshes after each interval period. This is useful for creating recurring permissions that automatically renew, such as monthly subscription payments or regular administrative actions. +The Rate Limit Policy with reset allows you to define a recurring allowance for UserOps that refreshes after each interval. This is useful for creating recurring permissions that automatically renew, such as monthly subscription payments or regular administrative actions. ### API -Unlike the standard Rate Limit Policy which counts down a total number of allowed operations, the reset version gives the signer a fresh allocation of operations after each interval passes. +Unlike the standard Rate Limit Policy, which counts down a total number of allowed operations, the reset version gives the signer a fresh allocation of operations after each interval passes. ```ts import { toRateLimitPolicy, RATE_LIMIT_POLICY_WITH_RESET_CONTRACT } from "@zerodev/permissions/policies" @@ -92,5 +92,5 @@ If you want to do a monthly payment indefinitely, the parameters will be: ## Notes -- We are aware that the semantics of `count` and `interval` changes completely between the `no reset` version and the `reset` version and it's very confusing; this is technical debt we intend to clean up. -- The `reset` version technically violates ERC-4337 storage rules since it needs to access `block.timestamp`, so it won't work with all bundler, but it's known to work with [UltraRelay](https://docs.zerodev.app/sdk/core-api/sponsor-gas#ultrarelay) and Pimlico. +- We are aware that the semantics of `count` and `interval` change completely between the `no reset` version and the `reset` version and it's very confusing; this is technical debt we intend to clean up. +- The `reset` version technically violates ERC-4337 storage rules since it needs to access `block.timestamp`, so it won't work with all bundlers, but it's known to work with [UltraRelay](https://docs.zerodev.app/sdk/core-api/sponsor-gas#ultrarelay) and Pimlico. diff --git a/docs/pages/sdk/permissions/policies/signature.mdx b/docs/pages/sdk/permissions/policies/signature.mdx index d57a766..dcc8c44 100644 --- a/docs/pages/sdk/permissions/policies/signature.mdx +++ b/docs/pages/sdk/permissions/policies/signature.mdx @@ -1,8 +1,8 @@ -# Signature Caller Policy +# Signature caller policy The signature caller policy specifies a list of addresses that are allowed to validate messages signed by the signer. -This is useful when you want the signer to sign messages for a set of particular protocols only. For example, if you want to create a signer that can only sign USDC [permits](https://eips.ethereum.org/EIPS/eip-2612), then you can use this policy to ensure that only the USDC contract can validate its messages. +This is useful when you want the signer to sign messages only for a specific set of protocols. For example, if you want to create a signer that can only sign `USDC` [permits](https://eips.ethereum.org/EIPS/eip-2612), then you can use this policy to ensure that only the `USDC` contract can validate its messages. ## API diff --git a/docs/pages/sdk/permissions/policies/sudo.mdx b/docs/pages/sdk/permissions/policies/sudo.mdx index 1a0f83d..1984670 100644 --- a/docs/pages/sdk/permissions/policies/sudo.mdx +++ b/docs/pages/sdk/permissions/policies/sudo.mdx @@ -1,6 +1,6 @@ -# Sudo Policy +# Sudo policy -The sudo policy gives full permission to the signer. The signer will be able to send any UserOps and sign any messages. +The sudo policy gives full permission to the signer. The signer will be able to send any UserOps and sign any messages. ## API diff --git a/docs/pages/sdk/permissions/policies/timestamp.mdx b/docs/pages/sdk/permissions/policies/timestamp.mdx index dbb3336..a17dbd0 100644 --- a/docs/pages/sdk/permissions/policies/timestamp.mdx +++ b/docs/pages/sdk/permissions/policies/timestamp.mdx @@ -1,6 +1,6 @@ -# Timestamp Policy +# Timestamp policy -The timestamp policy specifies the start and end time for when the signer is valid. +The timestamp policy specifies the start and end times for when the signer is valid. ## API @@ -26,5 +26,5 @@ const validator = toPermissionValidator(publicClient, { Arguments to `toTimestampPolicy`: -- `validAfter`: the time after which the signer becomes valid. If not specified, the signer is immediately valid. -- `validUntil`: the time before which the signer is valid. If not specified, the signer never expires. +- `validAfter`: the time after which the signer becomes valid. If not specified, the signer is considered valid immediately. +- `validUntil`: the time before which the signer is valid. If not specified, the signer never expires. diff --git a/docs/pages/sdk/permissions/signers/build-your-own.mdx b/docs/pages/sdk/permissions/signers/build-your-own.mdx index 1d97718..9d8f7ff 100644 --- a/docs/pages/sdk/permissions/signers/build-your-own.mdx +++ b/docs/pages/sdk/permissions/signers/build-your-own.mdx @@ -1,3 +1,3 @@ -# Build Your Own Signer +# Build your own signer Guide coming soon. \ No newline at end of file diff --git a/docs/pages/sdk/permissions/signers/ecdsa.mdx b/docs/pages/sdk/permissions/signers/ecdsa.mdx index 939be06..5ddb6db 100644 --- a/docs/pages/sdk/permissions/signers/ecdsa.mdx +++ b/docs/pages/sdk/permissions/signers/ecdsa.mdx @@ -1,4 +1,4 @@ -# ECDSA Signer +# ECDSA signer The ECDSA signer signs with a single ECDSA key, specifically with the `secp256k1` curve, which is the same algorithm that EOAs use. diff --git a/docs/pages/sdk/permissions/signers/multisig.mdx b/docs/pages/sdk/permissions/signers/multisig.mdx index cf8ae05..209b2ee 100644 --- a/docs/pages/sdk/permissions/signers/multisig.mdx +++ b/docs/pages/sdk/permissions/signers/multisig.mdx @@ -1,6 +1,6 @@ -# Multisig Signer +# Multisig signer -The weighted ECDSA (multisig) signer signs with a collection of ECDSA keys. Each key is weighted, so that the signature will pass as long as enough signers with enough weight have signed. +The weighted ECDSA (multisig) signer signs with a collection of ECDSA keys. Each key is weighted, so that the signature will pass as long as enough signers with enough weight have signed. Read [the multisig doc](/sdk/advanced/multisig) for more details. diff --git a/docs/pages/sdk/permissions/signers/passkeys.mdx b/docs/pages/sdk/permissions/signers/passkeys.mdx index 6465671..3bcb9c3 100644 --- a/docs/pages/sdk/permissions/signers/passkeys.mdx +++ b/docs/pages/sdk/permissions/signers/passkeys.mdx @@ -1,6 +1,6 @@ -# WebAuthn Signer +# WebAuthn signer -The WebAuthn (passkeys) signer signs with a single passkey. Read [the passkeys doc](/sdk/advanced/passkeys) for a more detailed intro to passkeys. +The WebAuthn (passkeys) signer signs with a single passkey. Read [the passkeys doc](/sdk/advanced/passkeys) for a more detailed intro to passkeys. ## API @@ -36,5 +36,5 @@ const validator = toPermissionValidator(publicClient, { For the params: - `passkeyName` can be any name -- `passkeyServerUrl` is a [passkey server URL](/sdk/advanced/passkeys#setting-up-passkey-server). You can get it from the ZeroDev dashboard. +- `passkeyServerUrl` is a [passkey server URL](/sdk/advanced/passkeys#setting-up-passkey-server). You can get it from the ZeroDev dashboard. - `mode` is either `register` or `login`, depending on whether you are creating a new key or using an existing key. \ No newline at end of file diff --git a/docs/pages/sdk/permissions/transaction-automation.mdx b/docs/pages/sdk/permissions/transaction-automation.mdx index c81ec68..f7f0139 100644 --- a/docs/pages/sdk/permissions/transaction-automation.mdx +++ b/docs/pages/sdk/permissions/transaction-automation.mdx @@ -1,12 +1,12 @@ -# Tutorial -- Transaction Automation +# Tutorial: Transaction automation -In this tutorial, you will learn how to automate transactions for your users using [session keys](/sdk/permissions/intro). This is useful when you want to send transactions for your users from your server, for instance. +In this tutorial, you will learn how to automate transactions for your users using [session keys](/sdk/permissions/intro). This is useful when you want to send transactions for your users from your server, for instance. -Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/transaction-automation.ts) while you follow along the tutorial. You can run the example by following instructions of [the examples repo](https://github.com/zerodevapp/zerodev-examples). +Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/transaction-automation.ts) while you follow along with the tutorial. You can run the example by following the instructions in [the examples repo](https://github.com/zerodevapp/zerodev-examples). ## Installation -Session keys are enabled through the `@zerodev/permissions` package. The examples repo already installed this, but normally you would install permissions with: +Session keys are enabled through the `@zerodev/permissions` package. The examples repo already installed this, but normally you would install permissions with: :::code-group @@ -28,28 +28,28 @@ bun add @zerodev/permissions ::: -## The Architecture of Transaction Automation +## The architecture of transaction automation In the typical architecture for transaction automation, there's an "owner" and an "agent": - The "owner" is the entity that controls the user's master key. - The "agent" is the entity that automates transactions for the owner. -For instance, your user might be using an embedded wallet (master key) with your frontend, and you might want to automate transactions for your users from your server. In this case, the frontend would be the "owner" and your server would be the "agent." +For instance, your user might be using an embedded wallet (master key) with your frontend, and you might want to automate transactions for your users from your server. In this case, the frontend would be the "owner," and your server would be the "agent." From a high level, this is how transaction automation works: - The agent creates a session key. - At this point, the session key has not been approved by the owner. -- The agent sends the "address" of the session key to the owner for approval. +- The agent sends the session key's “address” to the owner for approval. - The owner signs the address and returns the approval (signature) to the agent. - The agent can now send transactions for users using the approval and the session key. -## Code Flow +## Code flow ### Agent: creating a session key -From the agent's side, create a [ECDSA signer](/sdk/permissions/signers/ecdsa) as the session key: +From the agent's side, create an [ECDSA signer](/sdk/permissions/signers/ecdsa) as the session key: ```ts const sessionPrivateKey = generatePrivateKey() @@ -74,7 +74,7 @@ const sessionKeySigner = await toECDSASigner({ ### Agent: send session key "address" to the owner -For the owner to approve the session key, the agent must send the "address" of the session key to the owner. Note that the private key is never sent -- it's only the address which is the public key of the session key that's sent. +For the owner to approve the session key, the agent must send the session key's “address” to the owner. Note that the private key is never sent—it’s only the address, which is the public key of the session key that’s sent. To obtain the session key address: @@ -125,7 +125,7 @@ Now, send the serialized approval back to the agent. ### Agent: using the session key -When the agent wants to use the session key, first recreate the signer. Presumably, you would've stored the session key somewhere: +When the agent wants to use the session key, first recreate the signer. Presumably, you would've stored the session key somewhere: ```ts // Using a stored private key @@ -174,7 +174,7 @@ Now you can send transactions with the Kernel client. ### Revoking a Session Key -After a session key has been used, or if it's no longer needed, it's a good security practice to revoke it to ensure it cannot be used for any further transactions. Here's how you can revoke a session key: +After a session key has been used or is no longer needed, it’s a good security practice to revoke it to prevent it from being used for any further transactions. Here’s how you can revoke a session key: First, prepare your environment for the revocation process. This involves creating a "sudo" account capable of performing privileged operations, such as uninstalling plugins. @@ -192,7 +192,7 @@ const sudoKernelClient = createKernelAccountClient({ }) ``` -Now to revoke the session key by uninstalling its associated permission plugin, call `uninstallPlugin` on `sudoKernelClient`. +Now, to revoke the session key by uninstalling its associated permission plugin, call `uninstallPlugin` on `sudoKernelClient`. ```ts const txHash = await sudoKernelClient.uninstallPlugin({ @@ -238,4 +238,4 @@ const sessionKeyAccount = await createKernelAccount(publicClient, { }) ``` -That is, instead of creating a ECDSA validator, simply pass the EOA (the 7702 account) as `eip7702Account` into `createKernelAccount`, and don't set a `sudo` validator. +That is, instead of creating an ECDSA validator, pass the EOA (the 7702 account) as `eip7702Account` into `createKernelAccount`, and don't set a `sudo` validator. diff --git a/docs/pages/sdk/presets/intro.mdx b/docs/pages/sdk/presets/intro.mdx index eb6da90..1949be7 100644 --- a/docs/pages/sdk/presets/intro.mdx +++ b/docs/pages/sdk/presets/intro.mdx @@ -1,8 +1,8 @@ # Presets -ZeroDev is highly modular and composable thanks to building on top of Viem, but sometimes it can feel like you are writing a lot of boilerplate code before you can set up a functional Kernel account. **Presets** are helper functions that help you set up Kernel accounts with common configurations, including connections to bundlers and paymasters. +ZeroDev is highly modular and composable thanks to its build on Viem, but sometimes it can feel like you are writing a lot of boilerplate code before you can set up a functional Kernel account. **Presets** are helper functions that help you set up Kernel accounts with common configurations, including connections to bundlers and paymasters. -Generally speaking, there will be a preset for each `` pair. For example, the `` preset will create a ECDSA Kernel account using ZeroDev's infrastructure. +Generally speaking, there will be a preset for each `` pair. For example, the `` preset will create an ECDSA Kernel account using ZeroDev's infrastructure. Click the links below to see presets for different infra providers: diff --git a/docs/pages/sdk/presets/zerodev.mdx b/docs/pages/sdk/presets/zerodev.mdx index b203ab8..993e599 100644 --- a/docs/pages/sdk/presets/zerodev.mdx +++ b/docs/pages/sdk/presets/zerodev.mdx @@ -1,6 +1,6 @@ -# ZeroDev Presets +# ZeroDev presets -## ECDSA Validator +## ECDSA validator To set up a Kernel account using ECDSA for validation (mimicking EOAs): @@ -25,10 +25,10 @@ const kernelClient = await createEcdsaKernelAccountClient({ - `projectId` is a ZeroDev project ID from the [ZeroDev dashboard](https://dashboard.zerodev.app/). - `signer` is a [Viem account](https://viem.sh/docs/accounts/local.html). - (optional) `provider` can be [any provider that ZeroDev supports](/meta-infra/intro). -- (optional) `index` can be any positive integer. Different indexes will yield different accounts. +- (optional) `index` can be any positive integer. Different indices will yield different accounts. - (optional) `paymaster` can be: - `'NONE'`: not using any paymaster (the user pays their own gas). - `'SPONSOR'` (default): sponsor gas for users according to [gas policies](/meta-infra/gas-policies). - - A ERC20 token address: use the specified ERC20 token as gas tokens. See the [ERC20 gas token docs](/sdk/core-api/pay-gas-with-erc20s) for details. + - An `ERC-20` token address: use the specified `ERC-20` token as gas tokens. See the [`ERC-20` gas token docs](/sdk/core-api/pay-gas-with-erc20s) for details. is a boolean flag that determines whether ZeroDev will use [the sponsoring paymaster](/meta-infra/intro). diff --git a/docs/pages/sdk/signers/arcana.mdx b/docs/pages/sdk/signers/arcana.mdx index cd2ad2f..bd1e8bd 100644 --- a/docs/pages/sdk/signers/arcana.mdx +++ b/docs/pages/sdk/signers/arcana.mdx @@ -1,6 +1,6 @@ # Use Arcana Auth with ZeroDev -[Arcana Auth](https://www.arcana.network/) offers a self-custodial Web3 wallet embedded within applications, utilizing asynchronous distributed key generation algorithms for enhanced security and privacy. This wallet, accessible without the need for a browser extension, allows authenticated users to instantly access and sign blockchain transactions within the app environment. +[Arcana Auth](https://www.arcana.network/) offers a self-custodial Web3 wallet embedded in applications, leveraging asynchronous distributed key-generation algorithms for enhanced security and privacy. This wallet, accessible without a browser extension, allows authenticated users to sign blockchain transactions within the app instantly. ## Set up @@ -10,10 +10,12 @@ To use Arcana Auth with ZeroDev, first create an application that integrates wit - For a quick start, Arcana Auth provides a web app guide, available [here](https://docs.arcana.network/quick-start/web/). ## Integration -Integrating ZeroDev with Arcana Auth is straightforward after setting up the project. Arcana Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Arcana Auth is straightforward once the project is set up. Arcana Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the authProvider object -After following the Arcana Auth documentation, you will have access to a `authProvider` object as shown below: + +After following the Arcana Auth documentation, you will have access to an `authProvider` object as shown below: ```typescript import { @@ -28,7 +30,7 @@ const authProvider = new AuthProvider(clientId, params); ### Use with ZeroDev -Use the provider from Arcana to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). +Use the Arcana provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/signers/capsule.mdx b/docs/pages/sdk/signers/capsule.mdx index d4cea22..f58f94f 100644 --- a/docs/pages/sdk/signers/capsule.mdx +++ b/docs/pages/sdk/signers/capsule.mdx @@ -15,9 +15,10 @@ To use Para with ZeroDev, first create an application that integrates with Para. Check out [this example](https://github.com/zerodevapp/zerodev-signer-examples/tree/main/capsule) for custom integration with Para. ::: -Integrating ZeroDev with Para is straightforward after setting up the project. Para provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. +Integrating ZeroDev with Para is straightforward once the project is set up. Para provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Para object + After following the Para documentation, you will have access to a `ParaWeb3Provider` object as shown below: ```typescript diff --git a/docs/pages/sdk/signers/custom-signer.mdx b/docs/pages/sdk/signers/custom-signer.mdx index 041c686..fe5ca3f 100644 --- a/docs/pages/sdk/signers/custom-signer.mdx +++ b/docs/pages/sdk/signers/custom-signer.mdx @@ -1,13 +1,15 @@ -# Custom Signer Integration +# Custom signer integration + ZeroDev offers the flexibility to integrate various types of signers, catering to diverse application requirements. ## Using Externally Owned Accounts (EOAs) -Most commonly used signers are Externally Owned Accounts (EOAs). If you're using a signer that falls under this category and isn't explicitly covered in our documentation, we recommend visiting our dedicated [EOA integration section](/sdk/signers/eoa). This section provides detailed guidance on integrating EOAs with ZeroDev. -## Implementing Custom Signers +Most commonly used signers are Externally Owned Accounts (EOAs). If you’re using a signer in this category and it isn’t explicitly covered in our documentation, we recommend visiting our dedicated [EOA integration section](/sdk/signers/eoa). This section provides detailed guidance on integrating EOAs with ZeroDev. + +## Implementing custom signers -If your requirements extend beyond standard EOAs, ZeroDev supports the integration of custom signers. Our signers conform to the `SmartAccountSigner` interface defined in permissionless.js. For developers looking to implement a custom solution, you can reference the `SmartAccountSigner` interface on their [GitHub repository](https://github.com/pimlicolabs/permissionless.js/blob/0b1cf0086b3fa131415a6a9bf398852c159fc181/packages/permissionless/accounts/types.ts#L60). This interface provides the necessary structure and guidelines to ensure compatibility with ZeroDev. +If your requirements extend beyond standard EOAs, ZeroDev supports integrating custom signers. Our signers conform to the `SmartAccountSigner` interface defined in permissionless.js. For developers looking to implement a custom solution, you can reference the `SmartAccountSigner` interface on their [GitHub repository](https://github.com/pimlicolabs/permissionless.js/blob/0b1cf0086b3fa131415a6a9bf398852c159fc181/packages/permissionless/accounts/types.ts#L60). This interface provides the necessary structure and guidelines to ensure compatibility with ZeroDev. -One easy way to implement a `SmartAccountSigner` is to implement Viem's account type, [by following this guide](https://viem.sh/docs/accounts/local/toAccount). +One easy way to implement a `SmartAccountSigner` is to use Viem’s account type, [following this guide](https://viem.sh/docs/accounts/local/toAccount). Once you've implemented the signer, you should be able to [use it with a validator](/sdk/core-api/create-account#creating-a-ecdsa-validator). diff --git a/docs/pages/sdk/signers/dfns.mdx b/docs/pages/sdk/signers/dfns.mdx index 7a77b2e..1e310dd 100644 --- a/docs/pages/sdk/signers/dfns.mdx +++ b/docs/pages/sdk/signers/dfns.mdx @@ -1,6 +1,6 @@ # Use Dfns with ZeroDev -[Dfns](https://www.dfns.co/) is an MPC/TSS Wallet-as-a-Service API/SDK provider. Dfns aims to optimize the balance of security and UX by deploying key shares into a decentralized network on the backend while enabling wallet access via biometric open standards on the frontend like Webauthn. Reach out [here](https://www.dfns.co/learn-more) to set up a sandbox environment to get started. +[Dfns](https://www.dfns.co/) is an MPC/TSS Wallet-as-a-Service API/SDK provider. Dfns aims to optimize the balance between security and UX by deploying key shares to a decentralized network on the backend while enabling wallet access via biometric open standards on the frontend, such as WebAuthn. Reach out [here](https://www.dfns.co/learn-more) to set up a sandbox environment to get started. ## Set up @@ -9,9 +9,11 @@ To use Dfns with ZeroDev, first create an application that integrates with Dfns. - Refer to the [Dfns documentation site](https://docs.dfns.co/d/) for instructions on setting up an application with the Dfns. ## Integration -Integrating ZeroDev with Dfns is straightforward after setting up the project. Dfns provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Dfns is straightforward once the project is set up. Dfns provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Set up Dfns + After following the Dfns documentation, you will have access to a `dfnsWallet` object as shown below: ```typescript diff --git a/docs/pages/sdk/signers/dynamic.mdx b/docs/pages/sdk/signers/dynamic.mdx index 3252572..c1c02a8 100644 --- a/docs/pages/sdk/signers/dynamic.mdx +++ b/docs/pages/sdk/signers/dynamic.mdx @@ -6,23 +6,27 @@ To use Dynamic with ZeroDev, you have two options: Dynamic's native integration that utilizes ZeroDev, or a custom integration using Dynamic's Externally Owned Account (EOA) as a signer. Choose the approach that best fits your needs. -### Native Integration +### Native integration -Dynamic natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, utilize session keys. -- For more information and how to get started, visit the [Dynamic Account Abstraction documentation](https://docs.dynamic.xyz/smart-wallets/smart-wallet-providers/zerodev). +Dynamic natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, and utilize session keys. +- For more information on how to get started, visit the [Dynamic Account Abstraction documentation](https://docs.dynamic.xyz/smart-wallets/smart-wallet-providers/zerodev). -### Custom Integration -If you would like to use ZeroDev directly with a Dynamic project, you can set up a custom integration using Dynamics's EOA as a signer. +### Custom integration + +If you would like to use ZeroDev directly with a Dynamics project, you can set up a custom integration using Dynamic's EOA as a signer. - Begin by setting up your application with Dynamic, as detailed in the [Dynamic documentation](https://docs.dynamic.xyz/introduction/welcome). - Dynamic also offers a quick start guide and sample apps, available [here](https://docs.dynamic.xyz/quickstart). -## Implementing Custom Integration +## Implementing custom integration + Integrating ZeroDev with Dynamic is straightforward once your application is set up. Dynamic provides an EOA wallet to use as a signer with Kernel. -### Get the Dynamic wallet's Provider +### Get the dynamic wallet's provider + To begin, ensure your application is integrated with Dynamic. Detailed guidance is available in the [Dynamic documentation](https://docs.dynamic.xyz/). The following example demonstrates the use of Dynamic's React Core SDK. Ensure your React app is already configured with Dynamic; for setup instructions, refer to the [tutorial](https://docs.dynamic.xyz/react-sdk/tutorial). + ```typescript import { useDynamicContext } from "@dynamic-labs/sdk-react-core"; @@ -59,6 +63,6 @@ const ecdsaValidator = await signerToEcdsaValidator(publicClient, { // You can now use this ECDSA Validator to create a Kernel account ``` -## Starter Template +## Starter template A user has helpfully created a [starter template for Dynamic + ZeroDev](https://github.com/tantodefi/se2-dynamic-zerodev). diff --git a/docs/pages/sdk/signers/eoa.mdx b/docs/pages/sdk/signers/eoa.mdx index 12f2698..2b96275 100644 --- a/docs/pages/sdk/signers/eoa.mdx +++ b/docs/pages/sdk/signers/eoa.mdx @@ -1,11 +1,13 @@ # Use an EOA with ZeroDev -An Externally Owned Account (EOA) is a standard Ethereum account operated via a private key. It's commonly used in wallets like MetaMask. ZeroDev is compatible with EOAs as signers, and the method of integrating an EOA varies based on your dApp's connection approach. +An Externally Owned Account (EOA) is a standard Ethereum account operated via a private key. It’s commonly used in wallets like MetaMask. ZeroDev supports EOAs as signers, and the integration method varies depending on your dApp’s connection approach. -## Integration Methods -We'll explore three methods to integrate a signer with ZeroDev: using an EIP-1193 provider, using a viem WalletClient, and employing a Local Account. +## Integration methods + +We'll explore three methods to integrate a signer with ZeroDev: using an EIP-1193 provider, using a Viem WalletClient, and employing a Local Account. ### EIP-1193 Provider Integration + EIP-1193 is a standard interface for Ethereum providers, such as MetaMask or hardware wallets, where the key material is hosted externally rather than on the local client. ZeroDev supports creating a signer from any provider that implements this interface. ```typescript @@ -30,10 +32,12 @@ const ecdsaValidator = await signerToEcdsaValidator(publicClient, { // You can now use this ECDSA Validator to create a Kernel account ``` -### Viem Wallet Client Integration -A [Wallet Client](https://viem.sh/docs/clients/wallet.html) is an interface to interact with Ethereum Account(s) and provides the ability to retrieve accounts, execute transactions, sign messages, etc through Wallet Actions. +### Viem Wallet Client integration + +A [Wallet Client](https://viem.sh/docs/clients/wallet.html) is an interface for interacting with Ethereum Account(s) and provides the ability to retrieve accounts, execute transactions, sign messages, etc., through Wallet Actions. In this example, we assume that you have access to a WalletClient object. + ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" import { KERNEL_V3_1, getEntryPoint } from "@zerodev/sdk/constants" @@ -54,8 +58,9 @@ const ecdsaValidator = await signerToEcdsaValidator(publicClient, { // You can now use this ECDSA Validator to create a Kernel account ``` -### Local Account -A Local Account refers to an EOA where the private key is directly accessible on the client. In this example we assume you have access to the private key locally. +### Local account + +A Local Account is an EOA whose private key is directly accessible on the client. In this example we assume you have access to the private key locally. ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/signers/fireblocks.mdx b/docs/pages/sdk/signers/fireblocks.mdx index bf8113e..0a9c228 100644 --- a/docs/pages/sdk/signers/fireblocks.mdx +++ b/docs/pages/sdk/signers/fireblocks.mdx @@ -6,13 +6,15 @@ To use Fireblocks with ZeroDev, first create an application that integrates with Fireblocks. -- Refer to the [Fireblocks documentation site](https://developers.fireblocks.com/) for instructions on setting up an application with the Fireblocks. +- Refer to the [Fireblocks documentation site](https://developers.fireblocks.com/) for instructions on setting up an application with Fireblocks. - For a quick start, Fireblocks provides a guide, available [here](https://developers.fireblocks.com/docs/quickstart). ## Integration -Integrating ZeroDev with Fireblocks is straightforward after setting up the project. Fireblocks provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Fireblocks is straightforward once the project is set up. Fireblocks provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Fireblocks object + After following the Fireblocks documentation, you will have access to a `FireblocksWeb3Provider` object as shown below: ```typescript @@ -25,7 +27,7 @@ const fireblocksWeb3Provider = new FireblocksWeb3Provider(fireblocksProviderConf ### Use with ZeroDev -Use the provider from Fireblocks to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). +Use the Fireblocks provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/signers/intro.mdx b/docs/pages/sdk/signers/intro.mdx index 2142b94..5321306 100644 --- a/docs/pages/sdk/signers/intro.mdx +++ b/docs/pages/sdk/signers/intro.mdx @@ -1,9 +1,9 @@ -# Auth Providers +# Auth providers -Smart accounts, like EOAs, rely on signatures to validate transactions and messages. The difference with smart accounts is that it can use arbitrary signatures schemes, such as multisig, passkeys, etc. +Smart accounts, like EOAs, rely on signatures to validate transactions and messages. The difference with smart accounts is that they can use arbitrary signature schemes, such as multisig and passkeys. -It's possible to use third-party "wallet services" as signers for smart accounts. The end result is that your users will be interacting with the wallet UIs provided by these services, while using a smart account powered by ZeroDev. +It’s possible to use third-party “wallet services” as signers for smart accounts. The result is that your users will interact with the wallet UIs provided by these services while using a smart account powered by ZeroDev. -ZeroDev has been integrated natively with many leading wallet services such as [Privy](https://docs.privy.io/guide/frontend/account-abstraction/zerodev), [Dynamic](https://docs.dynamic.xyz/account-abstraction/aa-providers/zerodev), [Portal](https://docs.portalhq.io/resources/account-abstraction-alpha), [JoyID](https://docs.joyid.dev/guide/evm/evm-aa), etc. However, even when a native integration doesn't exist, it's generally very easy to integrate ZeroDev with a wallet service as long as it's able to sign messages. +ZeroDev has been integrated natively with many leading wallet services including [Privy](https://docs.privy.io/guide/frontend/account-abstraction/zerodev), [Dynamic](https://docs.dynamic.xyz/account-abstraction/aa-providers/zerodev), [Portal](https://docs.portalhq.io/resources/account-abstraction-alpha), [JoyID](https://docs.joyid.dev/guide/evm/evm-aa), etc. However, even when a native integration doesn’t exist, it’s generally very easy to integrate ZeroDev with a wallet service as long as it’s able to sign messages. -Check out the wallet services that are known to work with ZeroDev using the left sidebar. If the wallet service you want to use is not listed, check out the general guide for [integrating with EOA signers](/sdk/signers/eoa), or try [building your own integration](/sdk/signers/custom-signer). +Check out the wallet services known to work with ZeroDev in the left sidebar. If the wallet service you want to use is not listed, check out the general guide for [integrating with EOA signers](/sdk/signers/eoa), or try [building your own integration](/sdk/signers/custom-signer). diff --git a/docs/pages/sdk/signers/lit-protocol.mdx b/docs/pages/sdk/signers/lit-protocol.mdx index c8b3f53..25425e3 100644 --- a/docs/pages/sdk/signers/lit-protocol.mdx +++ b/docs/pages/sdk/signers/lit-protocol.mdx @@ -1,18 +1,20 @@ # Use Lit Protocol with ZeroDev -[Lit Protocol](https://www.litprotocol.com/) is distributed cryptography for signing, encryption, and compute. A generalizable key management network, Lit provides you with a set of tools for managing sovereign identities on the open Web. +[Lit Protocol](https://www.litprotocol.com/) is a distributed cryptographic protocol for signing, encryption, and computation. A generalizable key management network, Lit provides you with a set of tools for managing sovereign identities on the open Web. ## Set up To use Lit with ZeroDev, first create an application that integrates with Lit. -- Refer to the [Lit documentation site](https://developer.litprotocol.com/v3/) for instructions on setting up an application with the Lit. -- For a quick start, Lit provides examples, available [here](https://docs.Lit.com/getting-started/examples). +- Refer to the [Lit documentation site](https://developer.litprotocol.com/v3/) for instructions on setting up an application with Lit. +- For a quick start, Lit provides examples available [here](https://docs.Lit.com/getting-started/examples). ## Integration -Integrating ZeroDev with Lit is straightforward after setting up the project. Lit provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. -### Create the pkpWallet +Integrating ZeroDev with Lit is straightforward once the project is set up. Lit provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +### Create the pkpWallet + After following the Lit documentation, you will have access to a `pkpWallet`. An example is shown below: ```typescript @@ -75,7 +77,7 @@ const pkpWallet = new PKPEthersWallet({ ### Use with ZeroDev -Use the provider from Lit Protocol to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). +Use the Lit Protocol provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/signers/magic.mdx b/docs/pages/sdk/signers/magic.mdx index 7b650d2..b8058ea 100644 --- a/docs/pages/sdk/signers/magic.mdx +++ b/docs/pages/sdk/signers/magic.mdx @@ -1,6 +1,6 @@ # Use Magic with ZeroDev -[Magic](https://magic.link/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp in order to pay for gas, which introduces significant friction. +[Magic](https://magic.link/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp to pay for gas, which introduces significant friction. By combining ZeroDev with Magic, you can use Magic to enable a smooth social login experience, while using ZeroDev as the smart wallet to sponsor gas for users, batch transactions, and more. @@ -19,7 +19,7 @@ To use Magic with ZeroDev, first create an application that integrates with Magi Check out [this example](https://github.com/zerodevapp/zerodev-signer-examples/tree/main/magic) for custom integration with Magic. ::: -Integrating ZeroDev with Magic is straightforward after setting up the Magic SDK. Magic provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. +Integrating ZeroDev with Magic is straightforward once the Magic SDK is set up. Magic provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Magic object @@ -39,7 +39,7 @@ const magic = new MagicBase(process.env.MAGIC_API_KEY as string, { ### Use with ZeroDev -Use the provider from Magic to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). +Use the Magic provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/signers/particle.mdx b/docs/pages/sdk/signers/particle.mdx index c892328..c7806a8 100644 --- a/docs/pages/sdk/signers/particle.mdx +++ b/docs/pages/sdk/signers/particle.mdx @@ -1,6 +1,6 @@ # Use Particle Network with ZeroDev -[Particle Network](https://particle.network/) is an intent-centric, modular wallet-as-a-service (WaaS). By utilizing MPC-TSS for key management, Particle can streamline onboarding via familiar Web2 methods such as Google, emails, and phone numbers. +[Particle Network](https://particle.network/) is an intent-centric, modular wallet-as-a-service (WaaS). By using MPC-TSS for key management, Particle can streamline onboarding using familiar Web2 methods such as Google, email, and phone numbers. By combining ZeroDev with Particle, you can use Particle to enable a smooth social login experience, while using ZeroDev as the smart wallet to sponsor gas for users, batch transactions, and more. @@ -12,9 +12,11 @@ To use Particle Network with ZeroDev, first create an application that integrate - For a quick start, Particle Network provides a guide, available [here](https://docs.particle.network/getting-started/get-started). ## Integration -Integrating ZeroDev with Particle Network is straightforward after setting up the project. Particle Network provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Particle Network is straightforward once the project is set up. Particle Network provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Particle Network object + After following the Particle Network documentation, you will have access to a `ParticleProvider` object as shown below: ```typescript @@ -34,7 +36,7 @@ const particleProvider = new ParticleProvider(particle.auth) ### Use with ZeroDev -Use the provider from Particle Network to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). +Use the Particle Network provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/signers/portal.mdx b/docs/pages/sdk/signers/portal.mdx index bd89ba4..0f3c81e 100644 --- a/docs/pages/sdk/signers/portal.mdx +++ b/docs/pages/sdk/signers/portal.mdx @@ -1,24 +1,28 @@ # Use Portal with ZeroDev -[Portal](https://www.portalhq.io/) is an embedded blockchain infrastructure company that powers companies with an end to end platform for key management for self-custodial wallets (MPC and AA), security firewall, and web3 protocol connect kit. +[Portal](https://www.portalhq.io/) is an embedded blockchain infrastructure company that powers companies with an end-to-end platform for key management for self-custodial wallets (MPC and AA), a security firewall, and a Web3 protocol connect kit. ## Set up To use Portal with ZeroDev, you have two options: Portal's native integration using ZeroDev, or a custom integration using Portal's Externally Owned Account (EOA) as a signer for ZeroDev. Choose the approach that best fits your needs. -### Native Integration +### Native integration + Portal natively supports account abstraction using ZeroDev. This integration allows your organization to sponsor gas fees for your clients using specific policies and chains, with additional features coming soon. - For more information, visit the [Portal Account Abstraction documentation](https://docs.portalhq.io/resources/account-abstraction-alpha) -### Custom Integration +### Custom integration + If you require ZeroDev functionality not yet supported natively by Portal, a custom integration using Portal's EOA as a signer might be preferable. - Begin by setting up your application with Portal, as detailed in the [Portal documentation](https://docs.portalhq.io/). -- Portal also offers a quick start guide for their web SDK, available [here](https://docs.portalhq.io/sdk/web). +- Portal also offers a quick-start guide for its web SDK, available [here](https://docs.portalhq.io/sdk/web). + +## Implementing custom integration -## Implementing Custom Integration Integrating ZeroDev with Portal is straightforward once your application is set up. Portal provides an EOA wallet to use as a signer with Kernel. ### Create the Portal object + After following the Portal documentation, you will have access to a `Portal` object as shown below: ```typescript @@ -31,7 +35,7 @@ const portal = new Portal(portalOptions); ### Use with ZeroDev -Use the provider from Portal to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). +Use the provider from the Portal to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/signers/privy.mdx b/docs/pages/sdk/signers/privy.mdx index 3011d96..a3ecde2 100644 --- a/docs/pages/sdk/signers/privy.mdx +++ b/docs/pages/sdk/signers/privy.mdx @@ -1,33 +1,37 @@ # Use Privy with ZeroDev -[Privy](https://privy.io/) offers a seamless user onboarding experience for both mobile and desktop platforms, accommodating users with or without existing wallets. It simplifies the process of setting up self-custodial wallets for users logging in via email, SMS, or social media accounts. Additionally, it provides flexibility for web3-savvy users to continue using their existing wallets with your application, offering them a choice based on their preference. +[Privy](https://privy.io/) offers a seamless user onboarding experience for both mobile and desktop platforms, accommodating users with or without existing wallets. It simplifies the process of setting up self-custodial wallets for users logging in via email, SMS, or social media accounts. Additionally, it provides web3-savvy users with the flexibility to continue using their existing wallets with your application, offering them a choice based on their preferences. ## Set up To use Privy with ZeroDev, you have two options: Privy's native integration that utilizes ZeroDev, or a custom integration using Privy's Externally Owned Account (EOA) as a signer. Choose the approach that best fits your needs. -### Native Integration +### Native integration -Privy natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, utilize session keys. -- For more information and how to get started, visit the Privy's [Account Abstraction documentation](https://docs.privy.io/wallets/using-wallets/evm-smart-wallets/overview). +Privy natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, and utilize session keys. +- For more information on how to get started, visit the Privy's [Account Abstraction documentation](https://docs.privy.io/wallets/using-wallets/evm-smart-wallets/overview). -### Custom Integration +### Custom integration :::info + Check out [this example](https://github.com/zerodevapp/zerodev-signer-examples/tree/main/privy) for custom integration with Privy. + ::: -If you would like to use ZeroDev directly with a Privy project, you can set up a custom integration using Privys's EOA as a signer. +If you would like to use ZeroDev directly with a Privy project, you can set up a custom integration using Privy’s EOA as a signer. - Begin by setting up your application with Privy, as detailed in the [Privy documentation](https://docs.privy.io/). -- Privy also offers a quick start guide, available [here](https://docs.privy.io/guide/quickstart). +- Privy also offers a quick-start guide available [here](https://docs.privy.io/guide/quickstart). + +## Implementing custom integration -## Implementing Custom Integration Integrating ZeroDev with Privy is straightforward once your application is set up. Privy provides an EOA wallet to use as a signer with Kernel. -### Get the Privy wallet's Provider -To begin, ensure your application is integrated with Privy. Detailed guidance is available in the [Privy documentation](https://docs.privy.io/guide/quickstart). You should also configure your PrivyProvider to create embedded wallets for your users when they login. +### Get the privy wallet's provider + +To begin, ensure your application is integrated with Privy. Detailed guidance is available in the [Privy documentation](https://docs.privy.io/guide/quickstart). You should also configure your PrivyProvider to create embedded wallets for your users when they log in. -The following example demonstrates the use of Privy's react auth SDK to get the embedded wallet and use it as a signer for ZeroDev. +The following example demonstrates using Privy’s React Auth SDK to retrieve the embedded wallet and use it as a signer for ZeroDev. ```typescript import { useWallets } from "@privy-io/react-auth"; @@ -46,7 +50,7 @@ const privyProvider = await embeddedWallet.getEthereumProvider(); ### Use with ZeroDev -Use the provider from Privy to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). +Use the Privy provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" @@ -72,4 +76,4 @@ const ecdsaValidator = await signerToEcdsaValidator(publicClient, { ## Templates -A user has helpfully created a ZeroDev + Privy template for React Native (Expo). [Check it out here.](https://github.com/Stephen-Gordon/zerodev-privy-expo) +A user has helpfully created a ZeroDev + Privy template for React Native (Expo). [Check it out here.](https://github.com/Stephen-Gordon/zerodev-privy-expo) diff --git a/docs/pages/sdk/signers/smart-wallet.mdx b/docs/pages/sdk/signers/smart-wallet.mdx index a1eac27..41e5fc1 100644 --- a/docs/pages/sdk/signers/smart-wallet.mdx +++ b/docs/pages/sdk/signers/smart-wallet.mdx @@ -1,8 +1,8 @@ -# Use a Smart Wallet as a Signer +# Use a smart wallet as a signer ZeroDev supports using one smart wallet (kernel account) as a signer for another kernel account. -## Integration Example +## Integration example Here's how to use one kernel account as a validator for another kernel account: @@ -31,6 +31,6 @@ const validator = await signerToSmartAccountValidator(publicClient, { // You can now use this Validator to create a Kernel account ``` -## Starter Template +## Starter template An example of a starter template for using a Safe smart wallet as a signer is available [here](https://github.com/zerodevapp/safe-as-owner-example). \ No newline at end of file diff --git a/docs/pages/sdk/signers/turnkey.mdx b/docs/pages/sdk/signers/turnkey.mdx index a423074..8f0abf9 100644 --- a/docs/pages/sdk/signers/turnkey.mdx +++ b/docs/pages/sdk/signers/turnkey.mdx @@ -2,17 +2,17 @@ [Turnkey](https://turnkey.com/) is a key infrastructure provider with a great developer API and a powerful security policy engine. -By combining ZeroDev with Turnkey, you can create **custodial AA wallets** whose security is provided by Turnkey, with powerful functionalities such as sponsoring gas, batching transactions, etc. +By combining ZeroDev with Turnkey, you can create **custodial AA wallets** whose security is provided by Turnkey, with powerful features such as sponsoring gas and batching transactions. ## Set up To use Turnkey with ZeroDev, first create an application that integrates with Turnkey. - Refer to the [Turnkey documentation site](https://docs.turnkey.com/) for instructions on setting up an application with the Turnkey. -- For a quick start, Turnkey provides examples, available [here](https://docs.turnkey.com/getting-started/examples). +- For a quick start, Turnkey provides examples available [here](https://docs.turnkey.com/getting-started/examples). ## Integration -Integrating ZeroDev with Turnkey is straightforward after setting up the project. Turnkey provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. +Integrating ZeroDev with Turnkey is straightforward once the project is set up. Turnkey provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the TurnkeyClient and a Turnkey viem account After following the Turnkey documentation, you will have access to a `TurnkeyClient`. An example is shown below: diff --git a/docs/pages/sdk/signers/web3auth.mdx b/docs/pages/sdk/signers/web3auth.mdx index bc8f7b1..12aed3d 100644 --- a/docs/pages/sdk/signers/web3auth.mdx +++ b/docs/pages/sdk/signers/web3auth.mdx @@ -1,6 +1,6 @@ # Use Web3Auth with ZeroDev -[Web3Auth](https://web3auth.io/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp in order to pay for gas, which introduces significant friction. +[Web3Auth](https://web3auth.io/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp to pay for gas, which introduces significant friction. By combining ZeroDev with Web3Auth, you can use Web3Auth to enable a smooth social login experience, while using ZeroDev as the smart wallet to sponsor gas for users, batch transactions, and more. @@ -8,11 +8,11 @@ By combining ZeroDev with Web3Auth, you can use Web3Auth to enable a smooth soci To use Web3Auth with ZeroDev, first create an application that integrates with Web3Auth. -- Refer to the [Web3Auth documentation site](https://web3auth.io/docs/index.html) for instructions on setting up an application with the Web3Auth. +- Refer to the [Web3Auth documentation site](https://web3auth.io/docs/index.html) for instructions on setting up an application with Web3Auth. - For a quick start, Web3Auth provides example starter projects, available [here](https://web3auth.io/docs/examples?product=Plug+and+Play&sdk=Plug+and+Play+Web+Modal+SDK). ## Integration -Integrating ZeroDev with Web3Auth is straightforward after setting up the project. Web3Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. +Integrating ZeroDev with Web3Auth is straightforward once the project is set up. Web3Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Web3Auth object After following the Web3Auth documentation, you will have access to a `web3auth` object as shown below: diff --git a/docs/pages/sdk/v5_3_x/advanced/chain-abstraction.mdx b/docs/pages/sdk/v5_3_x/advanced/chain-abstraction.mdx index ff70524..73a1a0f 100644 --- a/docs/pages/sdk/v5_3_x/advanced/chain-abstraction.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/chain-abstraction.mdx @@ -2,15 +2,17 @@ import VersionWarning from "../VersionWarning" -# Chain Abstraction +# Chain abstraction :::info -Chain Abstraction is in public alpha and undergoing audit. Please [contact us](https://t.me/derek_chiang) if you plan on going live with it. + +Chain Abstraction is in public alpha and undergoing audit. Please [contact us](https://t.me/derek_chiang) if you plan on going live with it. + ::: ZeroDev is the first smart account solution to support *chain abstraction*. -With ZeroDev, you can turn a token balance into a "**chain-abstracted balance**" (CAB). Instead of thinking about "USDC on Ethereum" vs "USDC on Arbitrum," your user can just look at their "USDC balance" as a single balance that can be spent on any chain. +With ZeroDev, you can turn a token balance into a "**chain-abstracted balance**" (CAB). Instead of thinking about "`USDC` on Ethereum" vs "`USDC` on Arbitrum," your user can look at their `“USDC` balance” as a single balance that is usable on any chain. ## Demo @@ -20,23 +22,23 @@ With ZeroDev, you can turn a token balance into a "**chain-abstracted balance**" ### One unified balance -As aforementioned, CAB (chain-abstracted balance) is a single balance that can be spent on any chain. +As mentioned, CAB (chain-abstracted balance) is a single balance usable across any chain. -For example, if you deposit 100 USDC to a ZeroDev account on Base, then deposit 200 USDC to the account on Polygon, the account will now hold 300 "chain-abstracted USDC" that can be spent on any chain. +For example, if you deposit 100 `USDC` to a ZeroDev account on Base, then deposit 200 `USDC` to the account on Polygon, the account will now hold 300 "chain-abstracted `USDC`" that can be spent on any chain. ### No bridging latency -Amazingly, CAB can be spent at the speed of the destination chain -- just like a regular transaction. This is unlike a traditional bridge where the user has to wait for confirmations on both the source chain and the destination chain. +Amazingly, CAB can be spent at the speed of the destination chain—just like a regular transaction. This is unlike a traditional bridge, where the user has to wait for confirmations on both the source and destination chains. ### Spending as any tokens -CAB can be spent as any supported tokens; ZeroDev automatically handles the swapping. For example, if you have 500 USDC in CAB but you need to spend 500 USDT, you can do that. +CAB can be spent as any supported tokens; ZeroDev automatically handles the swapping. For example, if you have 500 `USDC` in CAB but you need to spend 500 `USDT`, you can do that. -Currently, we support swapping USDC to USDT/DAI/WETH/WBTC. Contact us if you are looking to support any specific tokens. +Currently, we support swapping `USDC` to USDT/`DAI`/`WETH`/`WBTC`. Contact us if you are looking to support any specific tokens. ## Code example -Here are [complete code examples](https://github.com/zerodevapp/zerodev-examples/blob/main/chain-abstraction) for using CAB. To run the example you need to set the environment variable `CAB_PAYMASTER_URL` which you can find [here](#setting-up-the-cab-client). +Here are [complete code examples](https://github.com/zerodevapp/zerodev-examples/blob/main/chain-abstraction) for using CAB. To run the example, you need to set the environment variable `CAB_PAYMASTER_URL`, which you can find [here](#setting-up-the-cab-client). ## Usage @@ -64,9 +66,9 @@ bun add @zerodev/cab ### Setting up the Kernel account -Skip to the next section if your ZeroDev app is already live. This section is for developers who can still change how they set up their Kernel accounts. +Skip to the next section if your ZeroDev app is already live. This section is for developers who can still change how they set up their Kernel accounts. -For the best experience with CAB, we recommend setting up your Kernel account with a *multi-chain validator*, which is a [validator](https://docs.zerodev.app/sdk/core-api/using-plugins) that can sign messages for multiple chains in one signature. This is useful for CAB because CAB needs to be enabled for each chain, so with a multi-chain validator you can enable CAB with just one signature, whereas with a regular validator you'd need to sign once per chain. +For the best experience with CAB, we recommend setting up your Kernel account with a *multi-chain [validator](https://docs.zerodev.app/sdk/core-api/using-plugins)*, which can sign messages for multiple chains in a single signature. This is useful for CAB because CAB needs to be enabled for each chain, so with a multi-chain validator, you can enable CAB with just one signature, whereas with a regular validator, you’d need to sign once per chain. To set up a multi-chain ECDSA validator ([code example](https://github.com/zerodevapp/zerodev-examples/blob/main/chain-abstraction/multichain-validator.ts)): @@ -96,11 +98,11 @@ const cabClient = createKernelCABClient(kernelClient, { }) ``` -For testing, you can use `https://cab-paymaster-service.onrender.com/paymaster/api` as the `CAB_PAYMASTER_URL`. You need to [contact us](https://t.me/derek_chiang) to obtain a CAB paymaster URL for production. +For testing, you can use `https://cab-paymaster-service.onrender.com/paymaster/api` as the `CAB_PAYMASTER_URL`. You need to [contact us](https://t.me/derek_chiang) to obtain a CAB paymaster URL for production. ### Enabling chain-abstracted balance -Before using CAB, you need to enable CAB for the smart account, by specifying a list of tokens you wish to support. Currently, CAB supports USDC only. Please let us know if there are specific tokens you wish us to support. +Before using CAB, you need to enable CAB for the smart account by specifying a list of tokens you wish to support. Currently, CAB supports `USDC` only. Please let us know if there are any specific tokens you would like us to support. ```tsx await cabClient.enableCAB({ @@ -111,7 +113,7 @@ await cabClient.enableCAB({ }) ``` -You can optionally specify the list of networks to enable CAB for. If you don't specify it, CAB is enabled for all supported networks. +You can optionally specify the list of networks to enable CAB for. If you don't specify it, CAB is enabled for all supported networks. If you are not using a multi-chain validator, you need to enableCAB for each network, one at a time: @@ -132,7 +134,7 @@ There are three steps to spending CAB: - Prepare the CAB UserOp and token info - Send the UserOp -First, start by constructing the calls. You can include multiple calls if you'd like to send a batch. +First, construct the calls. You can include multiple calls if you'd like to send a batch. ```tsx // In this example, we are performing a USDC transfer @@ -149,7 +151,8 @@ const calls = [ ] ``` -Then, prepare the CAB UserOp by specifying the calls and repay tokens. Note that the call can spend a different token than the repay token. Currently the repay token can only be USDC, but the call can spend USDC/USDT/DAI/WETH/WBTC. If the repay token and the spent token are different, the ZeroDev SDK automatically performs the swapping. +Then, prepare the CAB UserOp by specifying the calls and repay tokens. Note that the call can spend a different token than the repay token. Currently, the repay token can only be `USDC`, but the call can spend `USDC`/`USDT`/`DAI`/`WETH`/`WBTC`. If the repay token and the spent token differ, the ZeroDev SDK automatically swaps them. + ```tsx const { userOperation, repayTokensInfo, sponsorTokensInfo } = diff --git a/docs/pages/sdk/v5_3_x/advanced/defi.mdx b/docs/pages/sdk/v5_3_x/advanced/defi.mdx index 7043889..659391b 100644 --- a/docs/pages/sdk/v5_3_x/advanced/defi.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/defi.mdx @@ -2,23 +2,23 @@ import VersionWarning from "../VersionWarning" -# DeFi Integrations +# DeFi integrations ZeroDev partners with [Enso](https://www.enso.finance/) to support seamless token swaps and DeFi integrations, even across chains. The API deals with two types of tokens: -- **Base tokens** are normal tokens that do not represent a DeFi position. Examples are ETH, USDC, etc. -- **DeFi tokens** are ERC20 tokens that represent a DeFi position, such as in a [ERC-4626 vault](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/). For example, depositing ETH into Lido gets you `stETH` that represents staked ETH. +- **Base tokens** are normal tokens that do not represent a DeFi position. Examples are `ETH`, `USDC`, etc. +- **DeFi tokens** are `ERC-20` tokens that represent a DeFi position, such as in an [ERC-4626 vault](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/)—for example, depositing `ETH` into Lido yields `stETH`, which represents staked `ETH`. By allowing you to swap between base tokens and DeFi tokens, you can easily: - Swap between any token pairs. - Entering and exiting DeFi positions (staking, lending, etc.) -ZeroDev leverages [batching](/sdk/v5_3_x/core-api/batch-transactions) and [delegatecall](/sdk/v5_3_x/core-api/delegatecall) internally to ensure that even complex routes are executed in one atomic UserOp, providing the user with low latency, low gas cost, and high safety. +ZeroDev leverages [batching](/sdk/v5_3_x/core-api/batch-transactions) and [delegatecall](/sdk/v5_3_x/core-api/delegatecall) internally to ensure that even complex routes are executed in a single atomic UserOp, providing the user with low latency, low gas costs, and high safety. -## Supported Tokens +## Supported tokens See the full lists of supported base tokens and DeFi tokens: @@ -50,7 +50,9 @@ bun add @zerodev/defi ## API :::info + Check out [these code examples](https://github.com/zerodevapp/zerodev-examples/tree/main/defi). + ::: ### Creating a DeFi client @@ -65,12 +67,12 @@ const defiClient = createKernelDefiClient(kernelClient, projectId) Where: -- `kernelClient` is the [account client](/sdk/v5_3_x/core-api/create-account#create-an-account-client) object. -- `projectId` is your ZeroDev project ID, obtained from the dashboard. +- `kernelClient`: is the [account client](/sdk/v5_3_x/core-api/create-account#create-an-account-client) object. +- `projectId`: is your ZeroDev project ID, obtained from the dashboard. -### Swapping Tokens +### Swapping tokens -Suppose you want to swap 100 USDC to USDT: +Suppose you want to swap 100 `USDC` to `USDT`: ```ts import { baseTokenAddresses } from "@zerodev/defi" @@ -93,16 +95,16 @@ const userOpHash = await defiClient.sendSwapUserOp({ Where: - `fromToken` is the input token. -- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g. Wei for Ether. +- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g., Wei for `ETH`. - `toToken` is the output token. - `toAddress`: defaults to the account's own address. If specified, it will send the output token to that address instead. - `gasToken`: [see below.](#gas-tokens) -### Entering / Exiting DeFi positions +### Entering/exiting DeFi positions -Entering a DeFi position simply means swapping a token into a DeFi token. +Entering a DeFi position means swapping a token for a DeFi token. -You can get a DeFi token address through the `defiTokenAddresses` constant, which is a map with three keys: `chainId => tokenName => protocolName`. For example, the DeFi token representing the USDC vault on AAVE v3 on Arbitrum would be `defiTokenAddresses[arbitrum.id]['USDC']['aave-v3']`. So, to enter the vault: +You can get a DeFi token address through the `defiTokenAddresses` constant, which is a map with three keys: `chainId => tokenName => protocolName`. For example, the DeFi token representing the USDC vault on AAVE v3 on Arbitrum would be `defiTokenAddresses[arbitrum.id]['USDC']['aave-v3']`. So, to enter the vault: ```ts import { defiTokenAddresses } from "@zerodev/defi" @@ -120,11 +122,11 @@ const userOpHash = await defiClient.sendSwapUserOp({ }) ``` -Similarly, exiting a DeFi position is just swapping a DeFi token into another token. +Similarly, exiting a DeFi position is simply swapping a DeFi token for another token. -### Cross-chain Swaps +### Cross-chain swaps -To swap tokens across chains, use `sendSwapUserOpCrossChain`. For example, to swap USDC on Arbitrum to DAI on Polygon: +To swap tokens across chains, use `sendSwapUserOpCrossChain`. For example, to swap `USDC` on Arbitrum to `DAI` on Polygon: ```ts // Convert mainnet DAI to USDC, and lend it through AAVE on Arbitrum @@ -143,15 +145,15 @@ const userOpHash = await defiClient.sendSwapUserOpCrossChain({ Where: - `fromToken` is the input token. -- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g. Wei for Ether. +- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g., Wei for `ETH`. - `toToken` is the output token. - `toChainId`: the chain for `toToken`, - `toAddress`: defaults to the account's own address. If specified, it will send the output token to that address instead. - `gasToken`: [see below.](#gas-tokens) -### Listing Tokens +### Listing tokens -You can list all ERC20 tokens an account owns with the `listTokenBalances` function: +You can list all `ERC-20` tokens an account owns with the `listTokenBalances` function: ```ts const accountBalances = await defiClient.listTokenBalances({ @@ -160,21 +162,21 @@ const accountBalances = await defiClient.listTokenBalances({ }) ``` -### Gas Tokens +### Gas tokens -The `gasToken` flag specifies how gas is paid for the UserOp. It can be one of the following values: +The `gasToken` flag specifies how gas is paid for the UserOp. It can be one of the following values: - `sponsored`: sponsor the UserOp. -- `fromToken`: pays gas in the input token, using a [ERC20 paymaster](/sdk/v5_3_x/core-api/pay-gas-with-erc20s). -- `toToken`: pays gas in the output token, using a [ERC20 paymaster](/sdk/v5_3_x/core-api/pay-gas-with-erc20s). +- `fromToken`: pays gas on the input token using an [`ERC-20` paymaster](/sdk/v5_3_x/core-api/pay-gas-with-erc20s). +- `toToken`: pays gas in the output token, using an [`ERC-20` paymaster](/sdk/v5_3_x/core-api/pay-gas-with-erc20s). - `native`: pays gas in the native token, using the account's balance. -- You can also specify an `Address` for a ERC20 token, to pay gas with that token using a [ERC20 paymaster](/sdk/v5_3_x/core-api/pay-gas-with-erc20s). +- You can also specify an `Address` for an `ERC-20` token to pay gas with that token using an [`ERC-20` paymaster](/sdk/v5_3_x/core-api/pay-gas-with-erc20s). ### Getting the UserOp without sending -If you want to just construct a UserOp but not send it immediately, use: +If you want just to construct a UserOp but not send it immediately, use: - `getSwapUserOp` instead of `sendSwapUserOp` - `getSwapUserOpCrossChain` instead of `sendSwapUserOpCrossChain` -If you want to get regular transaction data instead of UserOps (presumably because you want to send the transaction through a EOA), use `getSwapUserOpCrossChain`. +If you want to get regular transaction data instead of UserOps (presumably because you want to send the transaction through an EOA), use `getSwapUserOpCrossChain`. diff --git a/docs/pages/sdk/v5_3_x/advanced/fallback-providers.mdx b/docs/pages/sdk/v5_3_x/advanced/fallback-providers.mdx index 79e2c6f..316fc18 100644 --- a/docs/pages/sdk/v5_3_x/advanced/fallback-providers.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/fallback-providers.mdx @@ -2,15 +2,17 @@ import VersionWarning from "../VersionWarning" -# Fallback Providers +# Fallback providers :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/fallback-clients/main.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/fallback-clients/main.ts). + ::: -When you use ZeroDev, you can pick [a specific infrastructure provider](/meta-infra/rpcs#bundler-rpc). If you don't pick one, we pick one for you. +When you use ZeroDev, you can pick [a specific infrastructure provider](/meta-infra/rpcs#bundler-rpc). If you don't pick one, we pick one for you. -However, sometimes an infra provider may experience downtime. We have developed a "fallbacks" feature that allows you to set up multiple providers, so that when one fails, another takes over. +However, sometimes an infra provider may experience downtime. We have developed a "fallbacks" feature that allows you to set up multiple providers, so that when one fails, another takes over. ## API @@ -79,11 +81,11 @@ const kernelClient = createFallbackKernelAccountClient([ ]) ``` -Now you can use `kernelClient` as usual. Your `kernelClient` will use `kernelClient1` by default, and if it runs into any issues with it, it will fallback to `kernelClient2`. +Now you can use `kernelClient` as usual. Your `kernelClient` will use `kernelClient1` by default, and if it runs into any issues with it, it will fallback to `kernelClient2`. ## Using non-ZeroDev infra as fallbacks -In the previous example, we used different providers as fallbacks through ZeroDev. If you are worried that ZeroDev itself might go down, you can also sign up directly with providers like Pimlico and set them up as fallback providers. +In the previous example, we used different providers as fallbacks through ZeroDev. If you are worried that ZeroDev itself might go down, you can also sign up directly with providers like Pimlico and set them up as fallback providers. To do that, simply: @@ -96,4 +98,4 @@ const kernelClient = createFallbackKernelAccountClient([ zerodevKernelClient, pimlicoKernelClient, ]) -``` \ No newline at end of file +``` diff --git a/docs/pages/sdk/v5_3_x/advanced/key-storage.mdx b/docs/pages/sdk/v5_3_x/advanced/key-storage.mdx index bbb5bb0..d74899f 100644 --- a/docs/pages/sdk/v5_3_x/advanced/key-storage.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/key-storage.mdx @@ -2,15 +2,17 @@ import VersionWarning from "../VersionWarning" -# Key Storage +# Key storage :::warning -The remote signer feature is a paid add-on. Please [contact us](https://t.me/derek_chiang) before you use this feature in production, in order to avoid service disruptions. + +The remote signer feature is a paid add-on. Please [contact us](https://t.me/derek_chiang) before using this feature in production to avoid service disruptions. + ::: -Sometimes you might want to manage session keys or even actual private keys for your users, but you may not want to store the keys on your database. +Sometimes you can manage session keys or even actual private keys for your users, but you may not want to store the keys in your database. -ZeroDev offers a key management API you can use to generate private keys and sign with them. The private key is never transmitted to you or stored on your server -- the API executes the signing remotely. +ZeroDev provides a key management API that lets you generate private keys and sign with them. The private key is never transmitted to you or stored on your server—the API executes the signing remotely. ## Code Example @@ -40,7 +42,7 @@ bun add @zerodev/remote-signer ## API -First, obtain the ZeroDev API key from [your dashboard](https://dashboard.zerodev.app/account). Remember: you must secure this API key. Whoever has access to this API key effectively controls all the private keys you manage with the key management API. +First, obtain the ZeroDev API key from [your dashboard](https://dashboard.zerodev.app/account). Remember: you must secure this API key. Whoever has access to this API key effectively controls all the private keys you manage with the key management API. ### Generating a private key @@ -53,13 +55,13 @@ const remoteSigner = await toRemoteSigner({ }) ``` -`remoteSigner` is a [Viem account](https://viem.sh/docs/accounts/privateKey) which you can use for signing. +`remoteSigner` is a [Viem account](https://viem.sh/docs/accounts/privateKey) that you can use for signing. -Note that if you want to get this key later, you must store its "address" which is basically its public key: `remoteSigner.address`. +Note that if you want to get this key later, you must store its "address," which is basically its public key: `remoteSigner.address`. ### Getting an existing private key -When getting an existing key, specify the "address" of the key. +When getting an existing key, specify the key's “address”. ```ts import { toRemoteSigner, RemoteSignerMode } from "@zerodev/remote-signer" diff --git a/docs/pages/sdk/v5_3_x/advanced/multi-chain-signing.mdx b/docs/pages/sdk/v5_3_x/advanced/multi-chain-signing.mdx index 410790c..4afe08a 100644 --- a/docs/pages/sdk/v5_3_x/advanced/multi-chain-signing.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/multi-chain-signing.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../VersionWarning" -# Multi-chain Signing +# Multi-chain signing -You can use Kernel with a "multi-chain validator" which can sign multiple UserOps in one signature, even if the UserOps are on different chains. For example, if you want to bridge some assets from chain A, and then execute a transaction on chain B with the bridged assets, you can sign both the bridging transaction and the target transaction in a single signature. +You can use Kernel with a “multi-chain validator,” which can sign multiple UserOps in a single signature, even if the UserOps are on different chains. For example, if you want to bridge some assets from chain A and then execute a transaction on chain B with the bridged assets, you can sign both the bridging transaction and the target transaction in a single signature. ## Examples @@ -19,4 +19,4 @@ If you want to create multiple session keys across different chains, with a sing ### Enabling plugins across chains -If you want to enable validators across chains (e.g. to enable recovery), with a single signature, [refer to this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/multi-chain/sendUserOpsWithEnable.ts). +If you want to enable validators across chains (e.g., for recovery), with a single signature, [refer to this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/multi-chain/sendUserOpsWithEnable.ts). diff --git a/docs/pages/sdk/v5_3_x/advanced/multisig.mdx b/docs/pages/sdk/v5_3_x/advanced/multisig.mdx index 194576c..ba0f45c 100644 --- a/docs/pages/sdk/v5_3_x/advanced/multisig.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/multisig.mdx @@ -5,15 +5,16 @@ import VersionWarning from "../VersionWarning" # Multisig :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/multisig). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/multisig). + ::: -With Kernel, it's possible to configure multiple signers for your smart account. The plugin that supports this functionality is named `WeightedECDSAValidator`, for the fact that it supports multiple ECDSA signers, each having a specific "weight." +With Kernel, it’s possible to configure multiple signers for your smart account. The plugin that supports this functionality is named `WeightedECDSAValidator` because it supports multiple ECDSA signers, each with a specific “weight.” ## How it works -Each signer is set up with a **weight**, and for any given signature, there must be enough combined weight to reach or surpass the **threshold** for the signature to be considered valid. - +Each signer is assigned a **weight**, and for any given signature, the combined weight must meet or exceed the **threshold** for the signature to be considered valid. For example, let's say we have: - Threshold: 100 @@ -67,9 +68,9 @@ const multisigValidator = await createWeightedECDSAValidator(publicClient, { }) ``` -In `config`, you specify the `threshold` and an list of signer addresses, as well as their weights. +In `config`, you specify the `threshold`, a list of signer addresses, and their weights. -In `signers`, you specify the list of signers ([Viem accounts](https://viem.sh/docs/accounts/local)) that will be signing for this account. The combined weight of these signers must reach the threshold. +In `signers`, specify the list of signers ([Viem accounts](https://viem.sh/docs/accounts/local)) who will sign for this account. The combined weight of these signers must reach the threshold. After creating the validator, you can [set up a Kernel account using the validator](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account) as usual. @@ -96,7 +97,7 @@ const account = await createKernelAccount(publicClient, { ## Updating multisig config -In many use cases, you may need to add and remove signers over time. To do so, send a UserOp that updates the config: +In many use cases, you may need to add and remove signers over time. To do so, send a UserOp that updates the config: ```ts import { getUpdateConfigCall } from "@zerodev/weighted-ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/advanced/parallel-orders.mdx b/docs/pages/sdk/v5_3_x/advanced/parallel-orders.mdx index 7f9a0ab..051a680 100644 --- a/docs/pages/sdk/v5_3_x/advanced/parallel-orders.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/parallel-orders.mdx @@ -5,18 +5,20 @@ import VersionWarning from "../VersionWarning" # Parallel UserOps :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/send-transactions/with-2d-nonce.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/send-transactions/with-2d-nonce.ts). + ::: -With a EOA, the nonce is sequential: 1, 2, 3, ... This means that transactions must be ordered sequentially, and a transaction cannot be processed unless a previous transaction was completed. +With an EOA, the nonce is sequential: 1, 2, 3,… This means that transactions get processed sequentially, and a transaction cannot be processed unless the previous transaction has completed. -With smart accounts, the nonce can be two-dimensional, which allows for *parallel UserOps*. Imagine that your user wants to place three trades: +With smart accounts, the nonce can be two-dimensional, enabling *parallel UserOps*. Imagine that your user wants to place three trades: -1. Swap 100 USDC to DAI -2. Swap 100 DAI to USDT -3. Swap 1WETH to USDT +1. Swap 100 `USDC` to `DAI` +2. Swap 100 `DAI` to `USDT` +3. Swap 1WETH to `USDT` -In this example, assuming the user did not have DAI to start with, the first two trades have dependencies, since the user needs to wait for the first trade to complete before they can do the second trade. However, the third trade doesn't depend on either of the first two trades, so it ought to be able to be placed in parallel. +In this example, assuming the user did not have DAI to start with, the first two trades are dependent, since the user needs to wait for the first trade to complete before they can do the second. However, the third trade doesn’t depend on either of the first two trades, so it ought to be able to be placed in parallel. ## API @@ -55,6 +57,6 @@ await kernelClient.sendUserOperation({ }) ``` -All UserOps using the same nonce key will be ordered sequentially. UserOps using different nonce keys will be parallel to each other. +All UserOps using the same nonce key will be ordered sequentially. UserOps using different nonce keys will run in parallel. -For example, if you want to order all UserOps that interact with Uniswap, and order all UserOps that interact with AAVE, but you want the Uniswap UserOps and the AAVE UserOps to be parallel to each other, you can use the string "Uniswap" and "AAVE" as the nonce keys for their UserOps respectively. \ No newline at end of file +For example, if you want to order all UserOps that interact with Uniswap, and order all UserOps that interact with AAVE, but you want the Uniswap UserOps and the AAVE UserOps to be parallel to each other, you can use the string "Uniswap" and "AAVE" as the nonce keys for their UserOps, respectively. diff --git a/docs/pages/sdk/v5_3_x/advanced/passkeys.mdx b/docs/pages/sdk/v5_3_x/advanced/passkeys.mdx index c6bf245..6175751 100644 --- a/docs/pages/sdk/v5_3_x/advanced/passkeys.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/passkeys.mdx @@ -6,13 +6,13 @@ import VersionWarning from "../VersionWarning" Passkeys are cryptographic key pairs created on end-user devices. [Apple](https://developer.apple.com/passkeys) and [Google](https://developers.google.com/identity/passkeys) are two major industry players pushing for the passkeys standard, which means that passkeys are widely available on consumer devices such as: -- iPhones / iPads / Macbooks -- Android phones / tablets -- Chrome (on Windows / Mac / Android) +- iPhones/iPads/MacBooks +- Android phones/tablets +- Chrome (on Windows/Mac/Android) [See here for a full list of systems that support passkeys.](https://passkeys.dev/device-support/#matrix) -The biggest value-add of passkeys, in the context of Web3, is **saving users from manually managing and securing their private keys.** Instead of writing down 12-word seed phrases, your user can simply use a passkey-enabled device to manage their wallet, and trust that the hardware will safely store the passkey, and the hardware vendor (e.g. Apple/Google) will [securely backup the keys](#how-are-passkeys-sync-ed-and-recovered). +The biggest value-add of passkeys in the context of Web3 is **freeing users from manually managing and securing their private keys**. Instead of writing down 12-word seed phrases, your user can use a passkey-enabled device to manage their wallet, trusting that the hardware will safely store the passkey and that the hardware vendor (e.g., Apple/Google) will [securely back up the keys](#how-are-passkeys-sync-ed-and-recovered). ## Demo @@ -29,15 +29,15 @@ The biggest value-add of passkeys, in the context of Web3, is **saving users fro ZeroDev/Kernel supports using passkeys as signers. The support comes in two flavors: -- **Native passkeys** using the [ERC-7212 precompile](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md). Native passkeys are the best option when available, since it uses the least amount of gas (only 3450 gas for verifying a P256 signature). Currently only a small number of networks support ERC-7212, but it's expected that most networks will support it over time. +- **Native passkeys** using the [ERC-7212 precompile](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md). Native passkeys are the best option when available, since they use the least gas (only 3450 gas to verify a P-256 signature). Currently, only a small number of networks support ERC-7212, but it’s expected that most networks will support it over time. -- **Smart contract passkeys** using either the [Daimo](https://github.com/daimo-eth/p256-verifier) or [FCL](https://github.com/rdubois-crypto/FreshCryptoLib) implementation. Smart contract passkeys can work on all EVM networks, but they are expensive (300-400k gas for verifying a P256 signature). +- **Smart contract passkeys** using either the [Daimo](https://github.com/daimo-eth/p256-verifier) or [FCL](https://github.com/rdubois-crypto/FreshCryptoLib) implementation. Smart contract passkeys can work across all EVM networks, but they are expensive (300-400k gas to verify a P-256 signature). -ZeroDev implements passkey supports through a **progressive passkey validator**, which uses native passkeys if ERC-7212 is available, and falls back to smart contract passkeys otherwise. Notably, this means that if you use passkeys on a network where ERC-7212 isn't available, and the network later adds support for ERC-7212, you don't need to upgrade your validator -- it will automatically start taking advantage of the ERC-7212 precompile. +ZeroDev implements passkey support via a **progressive passkey validator** that uses native passkeys if ERC-7212 is available, and falls back to smart contract passkeys otherwise. Notably, this means that if you use passkeys on a network where ERC-7212 isn’t available, and the network later adds support for ERC-7212, you don’t need to upgrade your validator—it will automatically start taking advantage of the ERC-7212 precompile. ## Quickstart -[Follow this tutorial](/sdk/v5_3_x/getting-started/tutorial-passkeys) to get started with passkey smart accounts. +[Follow this tutorial](/sdk/v5_3_x/getting-started/tutorial-passkeys) to get started with Passkey Smart Accounts. ## Installation @@ -63,7 +63,7 @@ bun add @zerodev/passkey-validator ## API -### Setting up passkey server +### Setting up the passkey server In this tutorial, we will be using ZeroDev's passkey server. If you want to use your own passkey server, [read this](#how-do-i-use-my-own-passkeys-server). If you wonder why a passkey server is needed at all, [read this](#why-do-we-need-a-passkeys-server). @@ -73,7 +73,7 @@ Head to the [ZeroDev dashboard](https://dashboard.zerodev.app), select a project

-If you are testing on `localhost`, just leave the domain empty. If you are deploying to a domain, enter and save the domain. +If you are testing on `localhost`, leave the domain empty. If you are deploying to a domain, enter the domain and save it. ### Creating a new passkey @@ -139,22 +139,22 @@ Using passkeys with ECDSA session keys has multiple benefits: - Your users don't have to deal with passkey signing prompts for every UserOp. -### Why do we need a passkeys server? +### Why do we need a passkey server? -A passkey is generated from a client-server handshake. In theory, we could simulate the handshake on the frontend, then store the public key on-chain. However, storing the public key on-chain involves sending a transaction, so you would want to do that as a part of deploying the account. However, if you must deploy a passkey account before you can use it, that breaks one of the core optimizations of AA which is counterfactual deployment -- the ability to use the address of a smart account without first deploying it. +A passkey is generated from a client-server handshake. In theory, we could simulate the handshake on the frontend, then store the public key onchain. However, storing the public key onchain involves sending a transaction, so you would want to do that as a part of deploying the account. However, if you must deploy a passkey account before you can use it, that breaks one of the core optimizations of AA, which is counterfactual deployment—the ability to use the address of a smart account without first deploying it. -We are working on ways to remove the dependency on a passkey server. In the mean time, keep in mind that the centralization concern is mitigated by the following: +We are working on ways to remove the dependency on a passkey server. In the meantime, keep in mind that the centralization concern is mitigated by the following: - You can [use your own passkeys server](#how-do-i-use-my-own-passkeys-server). -- The passkeys server only stores the public authentication data. Even if it's compromised, your users's keys are stored on their devices only. +- * The passkey server stores only public authentication data. Even if it’s compromised, your users' keys are stored only on their devices. -If the passkey server is lost, only users who have not yet deployed their accounts (i.e. users who have been using accounts counterfactually) will be unable to recover their accounts. Users who have deployed their accounts will have their authentication data stored on-chain, so their accounts will be safe even if the passkey server is lost. +If the passkey server is lost, only users who have not yet deployed their accounts (i.e., users who have been using accounts in violation of the policy) will be unable to recover their accounts. Users who have deployed their accounts will have their authentication data stored onchain, ensuring their accounts remain safe even if the passkey server is lost. ### How do I use my own passkeys server? You can optionally implement your own passkey server. To do that, make sure that your server implements the following URLs: -- `/register/options`: Generate and return registration options to the client. The client will use these options to prompt the user to create a passkey. If you are utilizing the [@simplewebauthn/server](https://simplewebauthn.dev/) library, the `generateRegistrationOptions` function can be used for this purpose. During this process, consider generating and storing a unique userID for later database reference. +- `/register/options`: Generate and return registration options to the client. The client will use these options to prompt the user to create a passkey. If you are utilizing the [@simplewebauthn/server](https://simplewebauthn.dev/) library, the `generateRegistrationOptions` function is for this purpose. During this process, consider generating and storing a unique `userID` for later database reference. ```ts import { generateRegistrationOptions } from "@simplewebauthn/server" @@ -175,7 +175,7 @@ const options = await generateRegistrationOptions({ return options ``` -- `/register/verify`: Verify the registration response (cred) and return the results to the client. The `verifyRegistrationResponse` function is also available for this verification. Upon successful verification, store the user's credentials, such as pubKey and credentialId, in your database. +- `/register/verify`: Verify the registration response (cred) and return the results to the client. The `verifyRegistrationResponse` function is also available for this verification. Upon successful verification, store the user's credentials, such as `pubKey` and `credentialId`, in your database. ```ts import { verifyRegistrationResponse } from "@simplewebauthn/server" @@ -219,7 +219,7 @@ const options = await generateAuthenticationOptions({ return options ``` -- `/login/verify`: Verify the login response (cred) and report the outcome to the client. Use the `verifyAuthenticationResponse` for the verification process. In the event of successful verification, retrieve the new counter from authenticationInfo and update the user's credentials in your database. It's crucial to send both the verification result and the user's public key back to the client, as the public key is not known to the client during the login process. +- `/login/verify`: Verify the login response (cred) and report the outcome to the client. Use the `verifyAuthenticationResponse` for the verification process. Upon successful verification, retrieve the new counter from authenticationInfo and update the user's credentials in your database. It's crucial to return both the verification result and the user's public key to the client, since the public key is not known to the client during the login process. ```ts import { verifyAuthenticationResponse } from "@simplewebauthn/server" @@ -286,9 +286,9 @@ const passkeyValidator = await toPasskeyValidator(publicClient, { }) ``` -If you want to refer to the ZeroDev passkey server implementation, you can find it [here](https://github.com/zerodevapp/passkey-server) +If you want to refer to the ZeroDev passkey server implementation, you can find it [here](https://github.com/zerodevapp/passkey-server). -### How are passkeys sync-ed and recovered? +### How are passkeys synced and recovered? Synchronization and recovery are both supported natively by Apple and Google: diff --git a/docs/pages/sdk/v5_3_x/advanced/recovery.mdx b/docs/pages/sdk/v5_3_x/advanced/recovery.mdx index b903076..22965ce 100644 --- a/docs/pages/sdk/v5_3_x/advanced/recovery.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/recovery.mdx @@ -4,31 +4,33 @@ import VersionWarning from "../VersionWarning" # Recovery -With Kernel's [permissions system](/sdk/v5_3_x/permissions/intro), it's possible to set up a guardian (or multiple guardians) for a smart account, so that if the owner loses their key, the guardian(s) can recover the key for the owner. +With Kernel's [permissions system](/sdk/v5_3_x/permissions/intro), it's possible to set up a guardian (or multiple guardians) for a smart account, so that if the owner loses their key, the guardian(s) can recover it. There are two typical types of recovery: -- **Self-recovery**: your user can set up recovery for their account with another auth factor they own, such as a passkey or another wallet they own. +- **Self-recovery**: your user can set up recovery for their account using another authentication factor they own, such as a passkey or another wallet. -- **DApp-assisted recovery**: your user might set you (the DApp) as their guardian. When they lose their account, they would contact you and you would recover the account for them. +- **DApp-assisted recovery**: your user might set you (the DApp) as their guardian. When they lose their account, they would contact you, and you would recover the account for them. -There are two ways to use recovery: through a pre-built recovery flow or build a totally custom flow using the Kernel recovery plugin. +There are two ways to use recovery: through a pre-built recovery flow, or by building a fully custom flow using the Kernel recovery plugin. -## Pre-built Recovery Flow +## Pre-built recovery flow [Check out the recovery flow docs.](/recovery-flow/intro) -## Recovery Plugin +## Recovery plugin :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/guardians/recovery.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/guardians/recovery.ts). + ::: Here we go through the process of using the recovery plugin: ### Setting up the guardian validator -Start by creating a permissions validator. Let's say you want a single key to be your guardian: +Start by creating a permissions validator. Let's say you want a single key to be your guardian: ```ts const guardianSigner = privateKeyToAccount(GUARDIAN_KEY) @@ -40,11 +42,11 @@ const guardianValidator = await signerToEcdsaValidator(publicClient, { }) ``` -If you want multiple guardians, set up a [multisig validator](/sdk/v5_3_x/advanced/multisig) instead. + If you want multiple guardians, set up a [multisig validator](/sdk/v5_3_x/advanced/multisig) instead. -### Setting up account with the recovery action + ### Setting up an account with the recovery action -We have deployed a simple recovery executor that can recover any accounts using [the ECDSA validator](/sdk/v5_3_x/permissions/signers/ecdsa). You can set it up with the following values: + We have deployed a simple recovery executor that can recover any accounts using [the ECDSA validator](/sdk/v5_3_x/permissions/signers/ecdsa). You can set it up with the following values: ```ts import { toFunctionSelector } from "viem" @@ -71,11 +73,11 @@ const account = await createKernelAccount(publicClient, { }) ``` -you only need to set the sudo validator if you are enabling the guardian validator, i.e. that it's the first time you are using the guardian. +You only need to set the sudo validator if you are enabling the guardian validator, i.e., if it’s the first time you are using the guardian. ### Executing recovery -After you [construct the account client from the account](/sdk/v5_3_x/core-api/create-account#create-an-account-client), you can execute recovery as such: +After you [construct the account client from the account](/sdk/v5_3_x/core-api/create-account#create-an-account-client), you can execute recovery as follows: ```ts import { encodeFunctionData } from "viem" @@ -92,9 +94,9 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -### Using account with the new owner +### Using an account with the new owner -After you update the account owner, the account address can no longer by computed from the new owner. Therefore, you should use the `deployedAccountAddress` option to manually set the account address when you [create the account object](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account). For example: +After you update the account owner, the account address can no longer be computed from the new owner. Therefore, you should use the `deployedAccountAddress` option to manually set the account address when you [create the account object](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account). For example: ```ts const account = await createKernelAccount(publicClient, { diff --git a/docs/pages/sdk/v5_3_x/advanced/session-keys.mdx b/docs/pages/sdk/v5_3_x/advanced/session-keys.mdx index 6ec4b4f..b937d06 100644 --- a/docs/pages/sdk/v5_3_x/advanced/session-keys.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/session-keys.mdx @@ -2,39 +2,41 @@ import VersionWarning from "../VersionWarning" -# Session Keys +# Session keys ## EntryPoint v0.7 (Kernel v3) :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys). +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys). ::: -In EntryPoint 0.7 (Kernel v3), session keys have been upgraded into a more powerful "permissions system." [Please refer to these docs.](/sdk/v5_3_x/permissions/intro) +In EntryPoint 0.7 (Kernel v3), session keys have been upgraded into a more powerful "permissions system." [Please refer to these docs.](/sdk/v5_3_x/permissions/intro) ## EntryPoint v0.6 (Kernel v2) :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/session-keys/v2-old). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/session-keys/v2-old). + ::: -The following document is for session keys for EntryPoint 0.6 (Kernel v2). If you are using EntryPoint 0.7 (Kernel v3), [please refer to permissions instead.](/sdk/v5_3_x/permissions/intro) +The following document is for session keys for EntryPoint 0.6 (Kernel v2). If you are using EntryPoint 0.7 (Kernel v3), [please refer to permissions instead.](/sdk/v5_3_x/permissions/intro) -Session keys are keys assigned with specific permissions. Some examples are: +Session keys are keys assigned with specific permissions. Some examples are: - A key that can only interact with Uniswap -- A key that can only use up to 1000 USDC +- A key that can only use up to 1000 `USDC` - A key that expires in 3 days -Of course, the permissions can be composed, so you can create a key that can only interact with Uniswap, while only using up to 1000 USDC, while expiring in 3 days, for instance. +Of course, permissions can be composed, so you can create a key that can only interact with Uniswap, use up to 1000 `USDC`, and expire in three days, for instance. Session keys have two primary use cases: -- **Skipping confirmations**: if you don't want your users to have to confirm every single transaction, you can create a session key that's only allowed to send specific transactions, and store the key in local storage. Now, your user can interact with your app with the session key without dealing with signing prompts. This experience is sometimes known as "one-click trading." +- **Skipping confirmations**: if you don’t want your users to have to confirm every transaction, you can create a session key that’s allowed to send only specific transactions and store it in local storage. Now, your user can interact with your app using the session key without having to deal with sign-in prompts. This experience is sometimes known as “one-click trading.” -- **Automating transactions**: if you want to execute transactions for your users automatically, they can create a session key and give it to you. You can then store the session keys on your server and execute transactions for your users. Your users don't have to fully trust you since the session keys are bounded by permissions. +- **Automating transactions**: if you want to execute transactions for your users automatically, they can create a session key and give it to you. You can then store the session keys on your server and execute transactions for your users. Your users don’t have to fully trust you, since session keys are bound to permissions. -The possibility with transaction automation is endless. Some examples are: +The possibilities with transaction automation are endless. Some examples are: - Subscriptions - Stop orders @@ -67,24 +69,26 @@ bun i @zerodev/session-key When using session keys, it's helpful to distinguish between the **owner** and the **agent**. -- The **owner** is whoever controls the master key of the account. The owner is the person that is able to create session keys. -- The **agent** is whoever using the session key. +- The **owner** is whoever controls the account's master key. The owner is the person who can create session keys. +- The **agent** is whoever uses the session key. There are two typical flows for how the owner and the agent interact: - **Owner-created**: The owner creates the session key and shares it with the agent. -- **Agent-created**: The agent creates a key pair and shares the public key with the owner. The owner creates a partial session key based on the public key, then shares the partial session key with the agent. Finally, the agent combines the private key wih the partial session key to form a full session key. +- **Agent-created**: The agent creates a key pair and shares the public key with the owner. The owner generates a partial session key from the public key and shares it with the agent. Finally, the agent combines the private key with the partial session key to form a full session key. Let's walk through how each flow works. ### Owner-created :::info + Check out [the code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/owner-created.ts) for the owner-created pattern. + ::: -We assume that you have [created a Kernel account](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account). If you only have a `kernelClient`, the Kernel account can be accessed as `kernelClient.account`. +We assume that you have [created a Kernel account](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account). If you only have a `kernelClient`, the Kernel account can be accessed as `kernelClient.account`. First, create a signer for the session key: @@ -109,7 +113,9 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { ``` :::info + Refer to [the session key params section](#session-key-parameters) to learn about session key params. + ::: Now, construct a Kernel account using your sudo validator and the session key validator: @@ -125,7 +131,7 @@ const sessionKeyAccount = await createKernelAccount(publicClient, { In this example, the sudo validator is `ecdsaValidator`. -If you want to use the session key on the same node, you can already [construct a Kernel client from this Kernel account](/sdk/v5_3_x/core-api/create-account#create-an-account-client) and start using it. If you want to share the session key with an agent or store it for use later, you can serialize the session key: +If you want to use the session key on the same node, you can already [construct a Kernel client from this Kernel account](/sdk/v5_3_x/core-api/create-account#create-an-account-client) and start using it. If you want to share the session key with an agent or store it for use later, you can serialize the session key: ```typescript import { serializeSessionKeyAccount } from "@zerodev/session-key" @@ -144,10 +150,12 @@ Now you can [create a Kernel client](/sdk/v5_3_x/core-api/create-account#create- ### Agent-created :::info + Check out [the code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/agent-created.ts) for the agent-created pattern. + ::: -In the agent-created pattern, the agent creates a public-private key pair and shares the public key with the owner. The owner authorizes the public key (by signing it), and shares the signed data with the agent. Finally, the agent creates the full session key by combining the signed data with the private key. This pattern is powerful because **the agent never had to share the private part of the session key with anyone**. +In the agent-created pattern, the agent creates a public-private key pair and shares the public key with the owner. The owner authorizes the public key (by signing it) and shares the signed data with the agent. Finally, the agent creates the full session key by combining the signed data with the private key. This pattern is powerful because **the agent never had to share the private part of the session key with anyone**. First, the agent creates a key pair: @@ -161,7 +169,7 @@ const sessionKeyAddress = sessionKeySigner.address Note that while we are using a local private key in this example, the session key signer can be any [Viem account object](https://viem.sh/docs/accounts/local). -Then, the agent shares the public key (address) of this signer with the owner. In this case, it would be `sessionKeySigner.address`. +Then the agent shares the signer's public key (address) with the owner. In this case, it would be `sessionKeySigner.address`. With this address, the owner can authorize the session key as such: @@ -178,7 +186,9 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { ``` :::info + Refer to [the session key params section](#session-key-parameters) to learn about session key params. + ::: Now, the owner can construct a Kernel account using the sudo validator and the session key validator: @@ -206,11 +216,11 @@ Now, when the agent needs to use the session key, they deserialize it: const sessionKeyAccount = await deserializeSessionKeyAccount(publicClient, serializedSessionKey, sessionKeySigner) ``` -Note how we pass `sessionKeySigner` to `deserializeSessionKeyAccount`. This is the private part of the session key that only the agent knows about. +Note how we pass `sessionKeySigner` to `deserializeSessionKeyAccount`. This is the private part of the session key that only the agent knows about. Now you can [create a Kernel client](/sdk/v5_3_x/core-api/create-account#create-an-account-client) using the `sessionKeyAccount` as you normally would. -### Revoking Session Keys +### Revoking session keys ```typescript import { revokeSessionKey } from "@zerodev/session-key" @@ -222,7 +232,7 @@ const userOpHash = await revokeSessionKey(kernelClient) const userOpHash = await revokeSessionKey(kernelClient, sessionKeySigner.address) ``` -Note that `kernelClient` in this case must be using the master signer (instead of the session key signer). If you want to revoke session keys using the session key signer itself, you must explicitly set up the session key permissions so that it's allowed to revoke itself. You can do so by including this permission: +Note that `kernelClient` in this case must be using the master signer (instead of the session key signer). If you want to revoke session keys using the session key signer itself, you must explicitly set the session key permissions so it can revoke itself. You can do so by including this permission: ```ts import { SESSION_KEY_VALIDATOR_ADDRESS } from "@zerodev/session-key" @@ -256,7 +266,7 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { }) ``` -## Session Key Parameters +## Session key parameters When creating a session key validator, you specify parameters under the `validatorData` flag: @@ -276,23 +286,23 @@ Now we go over each parameter. ### `validUntil` -`validUntil` is a UNIX timestamp (in seconds) that specifies when the session key should expire. +`validUntil` is a UNIX timestamp (in seconds) indicating when the session key expires. If not set or set to `0`, then the session key will never expire. ### `validAfter` -`validAfter` is a UNIX timestamp (in seconds) that specifies when the session key should start taking effect. +`validAfter` is a UNIX timestamp (in seconds) indicating when the session key should take effect. If not set or set to `0`, then the session key will be valid immediately. ### `paymaster` -`paymaster` specifies whether the session key must be used with a paymaster. **It's highly recommended that you set this flag unless 1) you fully trust the agent holding the session key, or 2) you don't expect your users to hold any ETH (or whatever native token for the network).** Otherwise, a malicious agent can set arbitrarily high gas price for UserOps sent with the session key, and then submit the UserOps themselves in order to profit from the gas, completely draining the user of ETH in the process. +`paymaster` specifies whether the session key is required with a paymaster. **It's highly recommended that you set this flag unless 1) you fully trust the agent holding the session key, or 2) you don't expect your users to hold any `ETH` (or whatever native token for the network).** Otherwise, a malicious agent can set an arbitrarily high gas price for UserOps sent with the session key and then submit the UserOps themselves to profit from the gas, completely draining the user of `ETH` in the process. -By setting the `paymaster` flag to a non-zero value, you ensure that the session key can only be used with a paymaster, and the paymaster (if properly set up) should have defense against arbitrarily high gas prices. +By setting the `paymaster` flag to a non-zero value, you ensure that the session key can only be used with a paymaster, and that the paymaster (if properly set up) should be protected against arbitrarily high gas prices. -If not set or set to `address(0)` (you can use `zeroAddress` from `viem`), the session key will work with or without paymaster. +If not set or set to `address(0)` (you can use `zeroAddress` from `viem`), the session key is limited to use by that paymaster. If set to `address(1)` (you can use `oneAddress` from `@zerodev/session-key`), the session key will only work with a paymaster, but it can be any paymaster. @@ -300,7 +310,7 @@ If set to a specific paymaster address, then the session key can only be used wi ### `permissions` -Permissions are at the core of session keys. By specifying permissions, you limit the types of transactions that the session key can send. +Permissions are at the core of session keys. By specifying permissions, you limit the types of transactions that the session key can send. Permissions look like this: @@ -348,14 +358,14 @@ const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, { Here's what each flag means: -- `target`: the target contract to call or address to send ETH to. If this is `zeroAddress`, then the target can be any contract as long as the ABI matches (or it can be any address if no ABI is specified). +- `target`: the target contract to call or address to send `ETH` to. If this is `zeroAddress`, the target can be any contract as long as the ABI matches (or any address if no ABI is specified). - `valueLimit`: the maximum [value](https://coinmarketcap.com/alexandria/glossary/ethereum-transaction#:~:text=The%20value%20is%20the%20amount%20of%20Ether%20to%20transfer%20from%20the%20sender%20to%20the%20recipient%2C%20and%20this%20can%20even%20be%20zero.) that can be transmitted. - `abi`: the contract ABI - `functionName`: the function name -- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. use `null` to skip an argument. +- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. Use `null` to skip an argument. - `operator`: this can be `EQUAL`, `GREATER_THAN`, `LESS_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`, `NOT_EQUAL`. - - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the value must be equal to 2". -- `operation`: (optional) whether this is a call or a delegatecall. Defaults to call. + - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the value must be equal to 2". +- `operation`: (optional) whether this is a call or a delegatecall. Defaults to call. ### Batching and Delegatecall @@ -396,9 +406,9 @@ const sessionKeyAccount = await createKernelAccount(publicClient, { }) ``` -### Transferring ETH +### Transferring `ETH` -If you want to transfer ETH with a session key, specify the `data` field as such: +If you want to transfer `ETH` with a session key, specify the `data` field as such: ```ts import { pad } from 'viem' @@ -414,8 +424,8 @@ await sessionKeyAccountClient.sendTransaction({ ### Does creating session keys cost gas? -No. Creating a session key entails simply signing a message, which is done off-chain and doesn't involve any gas cost. +No. Creating a session key involves signing a message, which is done offchain and incurs no gas cost. ### Is it possible to use session keys with a not-yet-deployed account? -Yes. If you do so, the first UserOp sent with the session key will deploy the account. +Yes. If you do so, the first UserOp sent with the session key will deploy the account. diff --git a/docs/pages/sdk/v5_3_x/advanced/social-login.mdx b/docs/pages/sdk/v5_3_x/advanced/social-login.mdx index 9869047..c56a10b 100644 --- a/docs/pages/sdk/v5_3_x/advanced/social-login.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/social-login.mdx @@ -4,9 +4,9 @@ import VersionWarning from "../VersionWarning" -# Social Login +# Social login -Social login allows users to authenticate using their existing social media accounts such as Google or Facebook. +Social login allows users to authenticate using their existing social media accounts, such as Google or Facebook. ZeroDev supports social logins natively, but you can also use ZeroDev with [third-party auth providers](/sdk/v5_3_x/signers/intro) such as Dynamic, Privy, and Magic if you prefer their UI. @@ -47,10 +47,10 @@ isAuthorized({ projectId: string }): Promise ``` #### Parameters -- projectId (string): Your ZeroDev project ID. +- `projectId (string)`: Your ZeroDev project ID. #### Returns -- `Promise`: Resolves to true if the user is logged in, otherwise false. +- `Promise`: Resolves to true if the user is logged in, otherwise returns false. #### Example @@ -76,9 +76,9 @@ initiateLogin({ ``` #### Parameters -- socialProvider ("google" | "facebook"): The social provider to use for login. -- oauthCallbackUrl (string, optional): The URL to redirect to after login. Defaults to the current window location if not provided. -- projectId (string): Your ZeroDev project ID. +- `socialProvider ("google" | "facebook")`: The social provider to use for login. +- `oauthCallbackUrl (string, optional)`: The URL to redirect to after login. Defaults to the current window location if not provided. +- `projectId (string)`: Your ZeroDev project ID. #### Example @@ -106,9 +106,9 @@ getSocialValidator>`: Resolves to a social validator object. @@ -128,7 +128,9 @@ const socialValidator = await getSocialValidator( ); ``` :::info + Now you can proceed to [create Kernel accounts](https://docs.zerodev.app/sdk/core-api/create-account#create-a-kernel-account) using the social validator as the sudo validator. + ::: ### `logout` @@ -140,7 +142,7 @@ logout({ projectId: string }) ``` #### Parameters -- projectId (string): Your ZeroDev project ID. +- `projectId (string)`: Your ZeroDev project ID. #### Example diff --git a/docs/pages/sdk/v5_3_x/advanced/supported-base-tokens.mdx b/docs/pages/sdk/v5_3_x/advanced/supported-base-tokens.mdx index f1d4c8a..940f404 100644 --- a/docs/pages/sdk/v5_3_x/advanced/supported-base-tokens.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/supported-base-tokens.mdx @@ -2,7 +2,7 @@ import VersionWarning from "../VersionWarning" -# Supported Base Tokens +# Supported Base tokens This is the full list of base tokens supported by ZeroDev's [DeFi integrations](/sdk/v5_3_x/advanced/defi). @@ -14,7 +14,7 @@ To use these tokens, import the `baseTokenAddresses` constant: import { baseTokenAddresses } from "@zerodev/defi" ``` -Then get the base token address with `baseTokenAddresses[chainId][baseToken]`. For example, to swap USDC into USDT: +Then get the base token address with `baseTokenAddresses[chainId][baseToken]`. For example, to swap `USDC` into `USDT`: ```ts const userOpHash = await defiClient.sendSwapUserOp({ @@ -25,7 +25,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ }) ``` -## Ethereum Mainnet +## Ethereum mainnet | Symbol | Address | |--------|----------| @@ -220,7 +220,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBTC | 0x68f180fcCe6836688e9084f035309E29Bf0A2095 | | WETH | 0x4200000000000000000000000000000000000006 | -## BSC Mainnet +## BSC mainnet | Symbol | Address | |--------|----------| @@ -253,7 +253,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBNB | 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c | | XRP | 0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe | -## Polygon Mainnet PoS +## Polygon mainnet PoS | Symbol | Address | |--------|----------| @@ -291,7 +291,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBTC | 0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6 | | WETH | 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619 | -## Base Mainnet +## Base mainnet | Symbol | Address | |--------|----------| @@ -336,7 +336,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | WBTC | 0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f | | WETH | 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1 | -## Avalanche-C Mainnet +## Avalanche-C mainnet | Symbol | Address | |--------|----------| diff --git a/docs/pages/sdk/v5_3_x/advanced/supported-defi-tokens.mdx b/docs/pages/sdk/v5_3_x/advanced/supported-defi-tokens.mdx index f4b8cd9..41683c0 100644 --- a/docs/pages/sdk/v5_3_x/advanced/supported-defi-tokens.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/supported-defi-tokens.mdx @@ -2,7 +2,7 @@ import VersionWarning from "../VersionWarning" -# Supported Defi Tokens +# Supported DeFi tokens This is the full list of DeFi tokens (aka "vaults") supported by ZeroDev's [DeFi integrations](/sdk/v5_3_x/advanced/defi). @@ -14,7 +14,7 @@ To use these tokens, import the `defiTokenAddresses` constant: import { defiTokenAddresses } from "@zerodev/defi" ``` -Then get the DeFi token address with `defiTokenAddresses[chainId][baseToken][protocol]`. For example, to deposit USDC into the AAVE v3 USDC token vault: +Then get the DeFi token address with `defiTokenAddresses[chainId][baseToken][protocol]`. For example, to deposit `USDC` into the AAVE v3 `USDC` token vault: ```ts const userOpHash = await defiClient.sendSwapUserOp({ @@ -2515,7 +2515,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | Metis | stargate | 0xD4CEc732b3B135eC52a3c0bc8Ce4b8cFb9dacE46 | | WOO | stargate | 0x5a0F550bfCaDe1D898034D57A6f72E7Aef32CE79 | -## Polygon Mainnet PoS +## Polygon mainnet PoS | Tokens | Protocol | Address | |--------|----------|---------| @@ -3560,7 +3560,7 @@ const userOpHash = await defiClient.sendSwapUserOp({ | jitoSOL/wstETH | balancer-gauge | 0xfA7C98b893b26e99EFb53110B1B72FFAaC607b69 | -## Avalanche-C Mainnet +## Avalanche-C mainnet | Tokens | Protocol | Address | |--------|----------|---------| diff --git a/docs/pages/sdk/v5_3_x/advanced/wallet-connect.mdx b/docs/pages/sdk/v5_3_x/advanced/wallet-connect.mdx index 502b110..ac5f260 100644 --- a/docs/pages/sdk/v5_3_x/advanced/wallet-connect.mdx +++ b/docs/pages/sdk/v5_3_x/advanced/wallet-connect.mdx @@ -6,7 +6,7 @@ import VersionWarning from "../VersionWarning" ## Overview -The `@zerodev/walletconnect` Core SDK facilitates the connection between a WalletConnect-compatible wallet and a blockchain application, handling session proposals, requests, and responses. It leverages a kernel EIP1193 provider to sign transactions or messages. +The `@zerodev/walletconnect` Core SDK facilitates the connection between a WalletConnect-compatible wallet and a blockchain application, handling session proposals, requests, and responses. It leverages a kernel [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) provider to sign transactions or messages. ## Installation @@ -51,12 +51,12 @@ await walletConnectKernelService.init({ }); ``` -- `walletConnectProjectId`: Your WalletConnect project ID. You will get this from the [WalletConnect dashboard.](https://cloud.walletconnect.com/sign-in) -- `walletConnectMetadata`: Metadata related to the WalletConnect session. -- `kernelClient`: An optional kernel client for creating a kernel provider. - - For detailed information on kernel clients, see [the kernel clients documentation.](/sdk/v5_3_x/core-api/create-account#create-an-account-client) -- `kernelProvider`: An optional pre-initialized kernel provider. - - If you are using wagmi with the capabilities pattern (for more information, see [the capabilities quickstart](/smart-wallet/quickstart-capabilities)), you can get the `kernelProvider` from wagmi. + - `walletConnectProjectId`: Your WalletConnect project ID. You will get this from the [WalletConnect dashboard.](https://cloud.walletconnect.com/sign-in) + - `walletConnectMetadata`: Metadata related to the WalletConnect session. + - `kernelClient`: An optional kernel client for creating a kernel provider. + - For detailed information on kernel clients, see [the kernel clients documentation.](/sdk/v5_3_x/core-api/create-account#create-an-account-client) + - `kernelProvider`: An optional pre-initialized kernel provider. + - If you are using Wagmi with the capabilities pattern ([see the capabilities quickstart for more information](/smart-wallet/quickstart-capabilities)), you can retrieve the `kernelProvider` from Wagmi. ```typescript import { useAccount } from "wagmi"; @@ -68,10 +68,12 @@ const kernelEIP1193Provider = (await connector.getProvider()) as unknown as Kern ``` :::info + You must either pass a `kernelProvider` or a `kernelClient` to the `init` method. + ::: -## Connecting to a Wallet +## Connecting to a wallet To start a session, use the `connect` method with a WalletConnect URI: @@ -79,9 +81,9 @@ To start a session, use the `connect` method with a WalletConnect URI: await walletConnectKernelService.connect("wc:example_uri"); ``` -## Event Handling + ## Event handling -Subscribe to various session-related events: + Subscribe to various session-related events: ```typescript // Handle session request @@ -109,7 +111,7 @@ walletConnectKernelService.onSessionDelete(() => { ## Session Management -### Approving or Rejecting Proposals +### Approving or rejecting proposals Handle incoming session proposals by approving or rejecting them: @@ -118,7 +120,7 @@ await walletConnectKernelService.approveSessionProposal(proposal, chainId, addre await walletConnectKernelService.rejectSessionProposal(proposal); ``` -### Handling Session Requests +### Handling session requests Approve or reject session requests based on business logic: @@ -136,6 +138,6 @@ const sessions = walletConnectKernelService.getActiveSessions(); await walletConnectKernelService.disconnect(sessions[0]); ``` -## Example: WalletConnect ZeroDev Example +## Example: WalletConnect ZeroDev example -For an example of integrating the `@zerodev/walletconnect` Core SDK with a React app, check out [this example repo.](https://github.com/zerodevapp/walletconnect-example). \ No newline at end of file +For an example of integrating the `@zerodev/walletconnect` Core SDK with a React app, check out [this example repo](https://github.com/zerodevapp/walletconnect-example). \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/core-api/batch-transactions.mdx b/docs/pages/sdk/v5_3_x/core-api/batch-transactions.mdx index 6f9e03a..ab79711 100644 --- a/docs/pages/sdk/v5_3_x/core-api/batch-transactions.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/batch-transactions.mdx @@ -2,24 +2,26 @@ import VersionWarning from "../VersionWarning" -# Batching Transactions +# Batching transactions :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/batch-transactions). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/batch-transactions). + ::: -Smart accounts like Kernel support *batching* transactions -- rolling multiple transactions into one. This is very useful for simplifying Web3 interactions for your users. For instance, instead of doing `approve()` followed by `transfer()`, your user can do both in one transaction. +Smart accounts like Kernel support transaction *batching*—rolling multiple transactions into a single transaction. This is very useful for simplifying Web3 interactions for your users. For instance, instead of calling `approve()` followed by `transfer()`, your user can do both in a single transaction. -Batching transactions has a number of important benefits: +Batching transactions has several important benefits: -- Your user waits for only 1 transaction instead of multiple. -- Your user pays less gas. +- Your user waits for only one transaction instead of multiple. +- Your user pays less for gas. - If any transaction in the batch reverts, the entire batch reverts. This ensures that your user won't be stuck in an inconsistent state. - This is known as "atomicity." ## API -There are two ways to send batched transactions. `sendTransactions` is a simple API that's good enough for most use cases. If you need fine-grained control over your UserOp, you can use `sendUserOperation`. +There are two ways to send batched transactions. `sendTransactions` is a simple API that's good enough for most use cases. If you need fine-grained control over your UserOp, you can use `sendUserOperation`. ### `sendTransactions` @@ -44,7 +46,7 @@ const txHash = await kernelClient.sendTransactions({ You can learn more about the `sendUserOperation` API [here](/sdk/v5_3_x/core-api/send-transactions#sending-raw-userops). -To send a UserOp with batching, simply pass an array of calls into `encodeCallData`. +To send a UserOp with batching, pass an array of calls into `encodeCallData`. ```typescript const userOpHash = await kernelClient.sendUserOperation({ diff --git a/docs/pages/sdk/v5_3_x/core-api/create-account.mdx b/docs/pages/sdk/v5_3_x/core-api/create-account.mdx index 8199f21..62e8446 100644 --- a/docs/pages/sdk/v5_3_x/core-api/create-account.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/create-account.mdx @@ -5,14 +5,16 @@ import VersionWarning from "../VersionWarning" # Creating a Smart Account :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + ::: -At the core of account abstraction is the *smart account* -- an account powered by a smart contract. ZeroDev is built on [Kernel](https://github.com/zerodevapp/kernel), a *modular smart account* that can be customized with plugins. +At the core of account abstraction is the *smart account*—an account powered by a smart contract. ZeroDev is built on [Kernel](https://github.com/zerodevapp/kernel), a *modular smart account* that can be customized with plugins. -When you create a Kernel account, you set it up with a *validator*, which is a type of plugin that handles how the account validates UserOps. In this tutorial, we will be using the ECDSA validator, which works like a normal EOA by validating signatures from a ECDSA private key. ZeroDev supports other validators such as [passkeys](/sdk/v5_3_x/advanced/passkeys) and [multisig](/sdk/v5_3_x/advanced/multisig). +When you create a Kernel account, you set it up with a validator, which is a type of plugin that handles how the account validates UserOps. In this tutorial, we will use the ECDSA validator, which works like a normal EOA by validating ECDSA signatures from an ECDSA private key. ZeroDev supports other validators such as [passkeys](/sdk/v5_3_x/advanced/passkeys) and [multisig](/sdk/v5_3_x/advanced/multisig). -We will be using a local private key, but the ECDSA validator also works with [third-party auth providers](/sdk/v5_3_x/signers/intro). +We will be using a local private key, but the ECDSA validator also supports [third-party auth providers](/sdk/v5_3_x/signers/intro). ## Installation @@ -40,11 +42,11 @@ bun add @zerodev/sdk @zerodev/ecdsa-validator permissionless ### Picking an EntryPoint -Currently there are two versions of ERC-4337 that are used in production. They are referred to as "EntryPoint 0.6" and "EntryPoint 0.7", where "EntryPoint" refers to the singleton ERC-4337 contract. +Currently, there are two versions of ERC-4337 in production. They are referred to as "EntryPoint 0.6" and "EntryPoint 0.7", where "EntryPoint" refers to the singleton ERC-4337 contract. -If you are building a new application, we recommend using EntryPoint 0.7 (Kernel v3), which gives you the latest and greatest features and optimizations. If you already have an application using EntryPoint 0.6 (Kernel v2), just stick with it -- it will be supported indefinitely. +If you are building a new application, we recommend using EntryPoint 0.7 (Kernel v3), which gives you the latest and greatest features and optimizations. If you already have an application using EntryPoint 0.6 (Kernel v2), stick with it—support will continue indefinitely. -In this tutorial, we will use EntryPoint 0.7. Start by selecting an EntryPoint: +In this tutorial, we will use EntryPoint 0.7. Start by selecting an EntryPoint: ```ts import { ENTRYPOINT_ADDRESS_V07 } from "permissionless" @@ -54,7 +56,7 @@ const entryPoint = ENTRYPOINT_ADDRESS_V07 ### Picking a Kernel version -[Kernel](https://github.com/zerodevapp/kernel) is the smart account that ZeroDev builds on. ZeroDev SDK used to implicitly use the latest version of Kernel, which has caused some compatibility issues when people upgrade the SDK. Therefore, starting from ZeroDev SDK v5.3, we require that you explicitly specify the Kernel version. This is how you generally should choose: +[Kernel](https://github.com/zerodevapp/kernel) is the smart account that ZeroDev builds on. The ZeroDev SDK implicitly uses the latest Kernel version, which has caused compatibility issues when people upgrade the SDK. Therefore, starting from ZeroDev SDK v5.3, we require that you explicitly specify the Kernel version. This is how you generally should choose: - If you had already been in production with ZeroDev SDK v4 or lower, use Kernel version 2.4 with EntryPoint 0.6. - If you had already been in production with ZeroDev SDK v5, use Kernel version 3.0 with EntryPoint 0.7. @@ -83,9 +85,9 @@ const publicClient = createPublicClient({ ### Creating a signer -As aforementioned, a Kernel account using a ECDSA validator is "owned" by a signer, which is anything that can sign messages with a private key. +As mentioned above, a Kernel account using an ECDSA validator is “owned” by a signer, which is anything that can sign messages with a private key. -Since Kernel is built on top of Viem, we can use any [Viem account](https://viem.sh/docs/accounts/local/toAccount) as the signer. In this example, we create a signer from a private key: +Since Kernel is built on top of Viem, we can use any [Viem account](https://viem.sh/docs/accounts/local/toAccount) as the signer. In this example, we create a signer from a private key: ```typescript import { Hex } from "viem" @@ -94,7 +96,7 @@ import { privateKeyToAccount } from "viem/accounts" const signer = privateKeyToAccount("PRIVATE_KEY" as Hex) ``` -Replace `PRIVATE_KEY` with an actual private key. You can [generate a random one here](https://privatekeys.pw/keys/ethereum/random). +Replace `PRIVATE_KEY` with an actual private key. You can [generate a random one here](https://privatekeys.pw/keys/ethereum/random). ### Creating a ECDSA validator @@ -158,17 +160,17 @@ Note that: - You need to replace the `BUNDLER_RPC` with an actual bundler RPC. - For ZeroDev, you can find the RPC on your dashboard. - You need to make sure to set the right `chain`. -- `sponsorUserOperation` only needs to be specified if you want to [use a paymaster](/sdk/v5_3_x/core-api/sponsor-gas). +- `sponsorUserOperation` is required only if you want to [use a paymaster](/sdk/v5_3_x/core-api/sponsor-gas). Now you are ready to do things with your smart account, like [sending UserOps](/sdk/v5_3_x/core-api/send-transactions)! ## FAQs -### When I create an account, is it deployed on-chain? +### When I create an account, is it deployed onchain? -No. If your account hasn't been deployed yet, we simply use [`CREATE2`](https://eips.ethereum.org/EIPS/eip-1014) to compute the address that the account *would* be deployed to. Your account is deployed automatically with the first UserOp it sends. +No. If your account hasn’t been deployed yet, we use [`CREATE2`](https://eips.ethereum.org/EIPS/eip-1014) to compute the address to which it will be deployed. Your account is deployed automatically with the first UserOp it sends. -In other words, "creating" accounts with the SDK is free -- you can create an infinite number of such account objects without paying any gas. It's only when you send the first UserOp that the account is deployed automatically. +In other words, "creating" accounts with the SDK is free—you can create an infinite number of such account objects without paying any gas. It's only when you send the first UserOp that the account is deployed automatically. ### Can I create multiple accounts from the same EOA signer? @@ -187,7 +189,7 @@ const account = createKernelAccount(publicClient, { ### How do I compute the smart account address from the EOA signer address? -Sometimes you only know the address of the EOA signer but you don't have the signer itself. In that case, you can still compute the address of the smart account with this helper function: +Sometimes you only know the address of the EOA signer, but you don't have the signer itself. In that case, you can still compute the address of the smart account with this helper function: ```ts import { getKernelAddressFromECDSA } from "@zerodev/ecdsa-validator" @@ -198,7 +200,7 @@ const smartAccountAddress = await getKernelAddressFromECDSA(publicClient, eoaAdd ### How do I create a Kernel account object with a specific address? -Normally, you don't need to manually specify an address because the smart account address is computed from your signer data. However, if you have changed the signer, then you may need to manually specify the smart account address. +Normally, you don't need to manually specify an address because the smart account address is computed from your signer data. However, if you have changed the signer, then you may need to specify the smart account address manually. You can do it like this: diff --git a/docs/pages/sdk/v5_3_x/core-api/delegatecall.mdx b/docs/pages/sdk/v5_3_x/core-api/delegatecall.mdx index 8f69b35..8cda13c 100644 --- a/docs/pages/sdk/v5_3_x/core-api/delegatecall.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/delegatecall.mdx @@ -5,19 +5,23 @@ import VersionWarning from "../VersionWarning" # Delegatecall :::warning -`delegatecall` is very dangerous. Unless you know exactly what you are doing, don't do it, or you might risk losing all your funds. + +`delegatecall` is very dangerous. Unless you know exactly what you are doing, don't do it, or you might risk losing all your funds. + ::: :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/delegatecall/main.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/delegatecall/main.ts). + ::: -`delegatecall` is a powerful EVM opcode that allows the calling contract to execute code in another contract, while keeping the storage context. [You can read more about `delegatecall` here](https://solidity-by-example.org/delegatecall/). +`delegatecall` is a powerful EVM opcode that allows the calling contract to execute code in another contract, while keeping the storage context. [You can read more about `delegatecall` here](https://solidity-by-example.org/delegatecall/). ## API -To send a UserOp that uses `delegatecall`, simply specify the `callType` of the UserOp: +To send a UserOp that uses `delegatecall`, specify the `callType` of the UserOp: ```typescript diff --git a/docs/pages/sdk/v5_3_x/core-api/deploy-contract.mdx b/docs/pages/sdk/v5_3_x/core-api/deploy-contract.mdx index 724a0a4..000f427 100644 --- a/docs/pages/sdk/v5_3_x/core-api/deploy-contract.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/deploy-contract.mdx @@ -2,10 +2,12 @@ import VersionWarning from "../VersionWarning" -# Deploying Contracts +# Deploying contracts :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/deploy-contract/main.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/deploy-contract/main.ts). + ::: To deploy smart contracts from your smart account, use the `deployContract` function: diff --git a/docs/pages/sdk/v5_3_x/core-api/pay-gas-with-erc20s.mdx b/docs/pages/sdk/v5_3_x/core-api/pay-gas-with-erc20s.mdx index 3ab6b63..31b6f5b 100644 --- a/docs/pages/sdk/v5_3_x/core-api/pay-gas-with-erc20s.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/pay-gas-with-erc20s.mdx @@ -2,31 +2,37 @@ import VersionWarning from "../VersionWarning" -# Paying Gas with ERC20s +# Paying gas with `ERC-20`s :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/pay-gas-with-erc20). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/pay-gas-with-erc20). + ::: :::warning -**Important:** Our ERC20 Paymaster currently supports USDC on Ethereum Mainnet, Polygon, Base, Optimism, and Arbitrum networks, including both their mainnet and testnet environments. + +**Important:** Our `ERC-20` Paymaster currently supports `USDC` on Ethereum Mainnet, Polygon, Base, Optimism, and Arbitrum networks, including both their mainnet and testnet environments. + ::: -A smart account can pay gas with ERC20 tokens. As a result, your users don't have to own any native gas tokens (e.g. ETH) in order to use Web3. Instead, they can just use stablecoins or even your project's own tokens. When your users pay gas with ERC20 tokens, we add 5% to the exchange rate to make a profit. +A smart account can pay for gas with `ERC-20` tokens. As a result, your users don’t need to own any native gas tokens (e.g., `ETH`) to use Web3. Instead, they can use stablecoins or even your project’s own tokens. When your users pay gas with `ERC-20` tokens, we add 5% to the exchange rate to make a profit. :::warning -Using your project's own tokens to pay for gas is a beta feature. If you are interested, please reach out. + +Using your project's own tokens to pay for gas is a beta feature. If you are interested, please reach out. + ::: -On a high level, you need to do two things to enable a smart account to pay gas in a particular ERC20 token: +On a high level, you need to do two things to enable a smart account to pay gas in a particular `ERC-20` token: -- Set up the Kernel client with the ERC20 paymaster. -- Ensure that enough ERC20 tokens have been approved for the ERC20 paymaster. - - This step is necessary because the ERC20 paymaster needs to withdraw ERC20 tokens from the smart account. +- Set up the Kernel client with the `ERC-20` paymaster. +- Ensure that enough `ERC-20` tokens have been approved for the `ERC-20` paymaster. + - This step is necessary because the `ERC-20` paymaster needs to withdraw `ERC-20` tokens from the smart account. Let's go through these two steps next. -## Set up Kernel Client +## Set up Kernel client When you [set up an account](/sdk/v5_3_x/core-api/create-account#create-an-account-client), do this: @@ -66,9 +72,9 @@ const kernelClient = createKernelAccountClient({ }) ``` -## Approve ERC20 tokens for paymaster +## Approve `ERC-20` tokens for the paymaster -Use the `getERC20PaymasterApproveCall` function to construct a call that approves the paymaster with the ERC20 tokens: +Use the `getERC20PaymasterApproveCall` function to construct a call that approves the paymaster with the `ERC-20` tokens: ```typescript import { getERC20PaymasterApproveCall } from "@zerodev/sdk" @@ -109,11 +115,11 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -Note that you only have to approve once, as long as the approval amount is sufficient for many UserOps. The [paymaster contract by Pimlico](https://github.com/pimlicolabs/erc20-paymaster/blob/main/src/ERC20PaymasterV07.sol) has been audited, it's widely used and generally considered safe. +Note that you only have to approve once, as long as the approval amount is sufficient for many UserOps. The [Pimlico paymaster contract](https://github.com/pimlicolabs/erc20-paymaster/blob/main/src/ERC20PaymasterV07.sol) has been audited; it’s widely used and generally considered safe. -## Estimate Gas in ERC20s +## Estimate Gas in `ERC-20`s -If you need to estimate gas in terms of a ERC20 token, do this: +If you need to estimate gas in terms of an `ERC-20` token, do this: ```ts const userOperation = await kernelClient.prepareUserOperationRequest({ @@ -138,9 +144,9 @@ const erc20Amount = await paymasterClient.estimateGasInERC20({ You can also see [a code example for estimating gas here](https://github.com/zerodevapp/zerodev-examples/blob/main/pay-gas-with-erc20/estimate-gas.ts). -## Supported Tokens +## Supported tokens -Currently, our ERC20 Paymaster supports USDC on the following networks: +Currently, our `ERC-20` Paymaster supports `USDC` on the following networks: - **Ethereum Mainnet** - **Polygon** @@ -148,15 +154,15 @@ Currently, our ERC20 Paymaster supports USDC on the following networks: - **Optimism** - **Arbitrum** -If you want to use a different token, you can either reach out to us or deploy your own Self-Funded ERC20 Paymaster. +If you want to use a different token, you can either reach out to us or deploy your own Self-Funded `ERC-20` Paymaster. -## Deploy Your Own ERC20 Paymaster +## Deploy Your Own `ERC-20` Paymaster -If you want to support a custom ERC20 token, you can deploy and manage your own ERC20 paymaster contract. To do this: +If you want to support a custom `ERC-20` token, you can deploy and manage your own `ERC-20` paymaster contract. To do this: -1. Visit the ZeroDev dashboard to deploy a self-funded ERC20 paymaster contract -2. Fund the contract with the native currency (e.g., ETH) -3. Set a conversion rate for the ERC20 token you would like to enable for the paymaster +1. Visit the ZeroDev dashboard to deploy a self-funded `ERC-20` paymaster contract. +2. Fund the contract with the native currency (e.g., `ETH`). +3. Set a conversion rate for the `ERC-20` token you would like to enable for the paymaster. Once deployed, you can use your custom paymaster by copying the paymaster URL from the dashboard and using it as the `transport` parameter when creating the paymaster client: diff --git a/docs/pages/sdk/v5_3_x/core-api/send-transactions.mdx b/docs/pages/sdk/v5_3_x/core-api/send-transactions.mdx index 147b25f..299c84f 100644 --- a/docs/pages/sdk/v5_3_x/core-api/send-transactions.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/send-transactions.mdx @@ -2,28 +2,28 @@ import VersionWarning from "../VersionWarning" -# Sending Transactions +# Sending transactions :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/send-transactions). +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/send-transactions). ::: -In ERC-4337, a transaction is known as a "UserOp." A UserOp looks mostly like a regular transaction, but it contains some extra information specific to AA, such as whether the UserOp should be sponsored. +In ERC-4337, a transaction is known as a "UserOp." A UserOp looks mostly like a regular transaction, but it contains some extra information specific to AA, such as whether the UserOp should be sponsored. There are two ways to send UserOps: - Sending raw UserOps - Sending regular transactions through the Viem API, which ZeroDev then "translates" into UserOps -The former enables the highest degree of flexibility, whereas the latter is more interoperable with existing libraries like Viem that deal only with transactions and not UserOps. +The former offers the highest degree of flexibility, whereas the latter is more interoperable with existing libraries like Viem, which deal only with transactions and not UserOps. -We will now describe both approaches. We assume that you have already [created a Kernel account](/sdk/v5_3_x/core-api/create-account). +We will now describe both approaches. We assume that you have already [created a Kernel account](/sdk/v5_3_x/core-api/create-account). ## Using the Viem API Since the Kernel account client implements [Viem's wallet client interface](https://viem.sh/docs/clients/wallet.html), you can send UserOps with standard Viem methods. -### Sending Transactions +### Sending transactions ```typescript const txnHash = await kernelClient.sendTransaction({ @@ -33,11 +33,11 @@ const txnHash = await kernelClient.sendTransaction({ }) ``` -This function returns the transaction hash of the ERC-4337 bundle that contains the UserOp. Due to the way that ERC-4337 works, by the time we get the transaction hash, the ERC-4337 bundle (and therefore the UserOps includeded within) will have already been mined, meaning that you don't have to [wait with the hash](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html). +This function returns the transaction hash of the ERC-4337 bundle that contains the UserOp. Because ERC-4337 works the way it does, by the time we get the transaction hash, the ERC-4337 bundle (and therefore the UserOps included within) will have already been mined, so you don’t have to [wait with the hash](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html). -If you need to separate the sending from the waiting of the UserOp, try [sending raw UserOps](#sending-raw-userops). +If you need to separate the sending from the waiting for the UserOp, try [sending raw UserOps](#sending-raw-userops). -### Interacting with Contracts +### Interacting with contracts First, construct a [Viem contract instance](https://viem.sh/docs/contract/getContract.html) by passing the Kernel account client as the `walletClient`: @@ -75,7 +75,7 @@ const unwatch = contract.watchEvent.Transfer( ### UserOp API -Sending raw UserOps affords you with the highest degree of control. To send a raw UserOp, use `sendUserOperation`: +Sending raw UserOps affords you the highest degree of control. To send a raw UserOp, use `sendUserOperation`: ```typescript const userOpHash = await kernelClient.sendUserOperation({ @@ -107,17 +107,17 @@ const userOpHash = await kernelClient.sendUserOperation({ Other than `callData`, every field has a sensible default: -- `sender` defaults to the Kernel account address -- `nonce` defaults to the next available nonce -- `initCode` defaults to `0x` if the account has been deployed, or the correct `initCode` if not. -- `callGasLimit`, `verificationGasLimit`, and `preVerificationGas` default to estimations provided by the underlying bundler and paymaster. -- `maxFeePerGas` and `maxPriorityFeePerGas` default to estimations provided by the public client. -- `paymasterAndData` defaults to `0x` if no paymaster was specified when you created the Kernel account object, or it will use the value provided by the paymaster. -- `signature` defaults to the signature provided by the signer. +- `sender`: defaults to the Kernel account address +- `nonce`: defaults to the next available nonce +- `initCode`: defaults to `0x` if the account has been deployed, or the correct `initCode` if not. +- `callGasLimit`, `verificationGasLimit`, and `preVerificationGas`: default to estimations provided by the underlying bundler and paymaster. +- `maxFeePerGas` and `maxPriorityFeePerGas`: default to the public client's estimates. +- `paymasterAndData`: defaults to `0x` if no paymaster was specified when you created the Kernel account object, or it will use the value provided by the paymaster. +- `signature`: defaults to the signer's signature. -### Encoding callData +### Encoding `callData` -To encode the calldata, use the `encodeCallData` function from the account object: +To encode the call data, use the `encodeCallData` function from the account object: ```typescript const userOpHash = await kernelClient.sendUserOperation({ @@ -131,7 +131,7 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -You can use Viem's helper functions such as `encodeFunctionData` to encode function calls. For example: +You can use Viem's helper functions, such as `encodeFunctionData` to encode function calls. For example: ```ts const userOpHash = await kernelClient.sendUserOperation({ @@ -159,7 +159,7 @@ const receipt = await bundlerClient.waitForUserOperationReceipt({ }) ``` -Note that if you had constructed your `kernelClient` with a [preset](/sdk/v5_3_x/presets/intro), you may not have access to a bundler client. Instead, you can extend your `kernelClient` with bundler actions: +Note that if you had constructed your `kernelClient` with a [preset](/sdk/v5_3_x/presets/intro), you may not have access to a bundler client. Instead, you can extend your `kernelClient` with bundler actions: ```typescript import { ENTRYPOINT_ADDRESS_V07, bundlerActions } from "permissionless" @@ -172,7 +172,7 @@ const receipt = await bundlerClient.waitForUserOperationReceipt({ ### Constructing a UserOp for sending later -In some applications, you might want to construct a UserOp but not immediately send it. There are two possible flows: +In some applications, you should construct a UserOp but not send it immediately. There are two possible flows: - If you want to separate signing and sending: - Create and sign a UserOp with `kernelClient.signUserOperation()` diff --git a/docs/pages/sdk/v5_3_x/core-api/sign-and-verify.mdx b/docs/pages/sdk/v5_3_x/core-api/sign-and-verify.mdx index a6b839c..6e76a1a 100644 --- a/docs/pages/sdk/v5_3_x/core-api/sign-and-verify.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/sign-and-verify.mdx @@ -2,27 +2,28 @@ import VersionWarning from "../VersionWarning" -# Signing and Verifying Messages +# Signing and verifying messages -Signing and verifying messages for smart accounts is different than with EOAs. There are a few reasons why: +Signing and verifying messages for smart accounts differs from that for EOAs. There are a few reasons why: -- With an EOA, the address is effectively the public key of the private key used for signing. Therefore, verifying a EOA signature is as simple as [recovering](https://soliditydeveloper.com/ecrecover) the signature and compare the recovered public key with the address. - - With a smart account, the address is the address of a smart contract that has no cryptographic link to the signing private key. Therefore, you must use [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) to validate the message. +- In an EOA, the address is effectively the public key corresponding to the private key used for signing. Therefore, verifying an EOA signature is as simple as [recovering](https://soliditydeveloper.com/ecrecover) the signature and comparing the recovered public key with the address. + - With a smart account, the address is that of a smart contract with no cryptographic link to the signing private key. Therefore, you must use [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) to validate the message. -- With an EOA, you don't have to deploy the account. It just exists. - - Since smart accounts need to be deployed, it may not be clear how you can validate messages against a smart account not yet deployed. However, that's actually possible thanks to [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492). +- With an EOA, you don't have to deploy the account. It just exists. + - Since smart accounts need to be deployed, it may not be clear how to validate messages against a smart account that hasn't been deployed yet. However, that's actually possible thanks to [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492). -If you are impatient, head straight to [the API](#api). Otherwise, read on to learn more about ERC-1271 and ERC-6492. +If you are impatient, head straight to [the API](#api). Otherwise, read on to learn more about ERC-1271 and ERC-6492. + ## API ### Signing messages -Both [the account and account client objects](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account) are able to sign messages: +Both [the account and account client objects](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account) can sign messages: ```ts const signature = await account.signMessage({ diff --git a/docs/pages/sdk/v5_3_x/core-api/sponsor-gas.mdx b/docs/pages/sdk/v5_3_x/core-api/sponsor-gas.mdx index c13ce7d..f668e48 100644 --- a/docs/pages/sdk/v5_3_x/core-api/sponsor-gas.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/sponsor-gas.mdx @@ -2,29 +2,30 @@ import VersionWarning from "../VersionWarning" -# Sponsoring Gas +# Sponsoring gas -With account abstraction, you can pay gas for users so they don't have to acquire native tokens in order to interact with your DApp. +With account abstraction, you can pay for gas for users so they don’t have to acquire native tokens to interact with your DApp. When you sponsor gas through ZeroDev, there are two ways to pay for the gas: -- Put down your credit card. We front the gas for your users, and then at the end of the billing cycle (once a month) we charge your credit card. - +- Put down your credit card. We front the gas for your users, and then at the end of the billing cycle (once a month), we charge your credit card. - Buy gas credits from us. ## Setting up gas sponsoring policies -To avoid over-spending gas on sponsoring, you must set up gas-sponsoring policies. Sign up on the ZeroDev dashboard if you haven't already, then [set up gas policies](/meta-infra/gas-policies). +To avoid overspending on gas sponsorship, you must set up gas-sponsoring policies. Sign up on the ZeroDev dashboard if you haven't already, then [set up gas policies](/meta-infra/gas-policies). ## API :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + ::: When [setting up an account](/sdk/v5_3_x/core-api/create-account), you can specify a `sponsorUserOperation` function when you [create the account client](/sdk/v5_3_x/core-api/create-account#create-an-account-client). -The `sponsorUserOperation` function essentially takes a UserOp and then returns a UserOp with the `paymasterAndData` field set. For example, if you are using the ZeroDev paymaster, use the `createZeroDevPaymasterClient` helper function: +The `sponsorUserOperation` function takes a UserOp and then returns a UserOp with the `paymasterAndData` field set. For example, if you are using the ZeroDev paymaster, use the `createZeroDevPaymasterClient` helper function: ```typescript import { http } from "viem" @@ -61,4 +62,4 @@ If you want to use Pimlico paymasters, you can use these helper functions: import { createPimlicoPaymasterClient } from "permissionless/clients/pimlico" ``` -Then, simply replace `createZeroDevPaymasterClient` with one of these functions, and make sure to use the corresponding paymaster RPC for these infra providers. +Then, replace `createZeroDevPaymasterClient` with one of these functions, and make sure to use the corresponding paymaster RPC for these infra providers. diff --git a/docs/pages/sdk/v5_3_x/core-api/using-plugins.mdx b/docs/pages/sdk/v5_3_x/core-api/using-plugins.mdx index 0f70d6a..b526faa 100644 --- a/docs/pages/sdk/v5_3_x/core-api/using-plugins.mdx +++ b/docs/pages/sdk/v5_3_x/core-api/using-plugins.mdx @@ -2,11 +2,11 @@ import VersionWarning from "../VersionWarning" -# Using Plugins +# Using plugins ZeroDev is built on [Kernel](https://github.com/zerodevapp/kernel), a *modular smart account* that can be extended with *plugins* (sometimes also called *modules*). -While there are many types of plugins, we will focus on *validators*, which modify the logic for validating UserOps. Validators are used for most of the major use cases of AA, including: +While there are many types of plugins, we will focus on *validators*, which modify the logic for validating UserOps. Validators are used for most of the major use cases of AA, including: - Alternative signature schemes, such as passkeys and multisig. - Dynamic access control, such as guardians and session keys. @@ -15,14 +15,14 @@ While there are many types of plugins, we will focus on *validators*, which modi For any given Kernel account, it will have one **sudo validator** and any number of **regular validators**. -- The **sudo validator** is the "owner" of the account. It's the only validator that can enable other validators. -- A **regular validator** represents an alternative form of access to the smart account. For example, a session key or a guardian would be a regular validator. Regular validators cannot enable other validators. +- The **sudo validator** is the "owner" of the account. It's the only validator that can enable other validators. +- A **regular validator** represents an alternative form of access to the smart account. For example, a session key or a guardian would be a regular validator. Regular validators cannot enable other validators. -When you set up a [Kernel account object](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account) with the SDK, you must specify a sudo validator, a regular validator, or both. Let's walk through the three cases: +When you set up a [Kernel account object](/sdk/v5_3_x/core-api/create-account#create-a-kernel-account) with the SDK, you must specify a sudo validator, a regular validator, or both. Let's walk through the three cases: ### Using only a sudo validator -In the most common case, you set up a Kernel account that is powered by a single sudo validator. For example, to set up an account owned by a ECDSA key: +In the most common case, you set up a Kernel account that is powered by a single sudo validator. For example, to set up an account owned by an ECDSA key: ```ts const account = await createKernelAccount(publicClient, { @@ -34,11 +34,11 @@ const account = await createKernelAccount(publicClient, { }) ``` -Here, when you send a UserOp, the ECDSA key will be used for signing the UserOp, and the ECDSA key has sudo access to the smart account (meaning it can do anything). +Here, when you send a UserOp, the ECDSA key is used to sign it, and the ECDSA key has sudo access to the smart account (meaning it can do anything). ### Enabling a regular validator -If you have access to the sudo validator, you can enable a regular validator. For example, to enable a [session key](/sdk/v5_3_x/advanced/session-keys): +If you have access to the sudo validator, you can enable a regular validator. For example, to enable a [session key](/sdk/v5_3_x/advanced/session-keys): ```ts const account = await createKernelAccount(publicClient, { @@ -51,15 +51,15 @@ const account = await createKernelAccount(publicClient, { }) ``` -Now, when you send a UserOp with this `account`, the regular validator will be enabled, and the regular validator (in this case the session key) will be used for signing the UserOp. +Now, when you send a UserOp from this `account`, the regular validator (in this case, the session key) will sign it. -Note that Kernel plugins are enabled "lazily" -- you don't have to explicitly enable them. That is, whenever you send the first UserOp with an `account` object with a `regular` plugin, the plugin will be enabled as a part of that UserOp. The UserOp itself can do whatever it needs to do. +Note that Kernel plugins are enabled “lazily”—you don’t have to enable them explicitly. That is, whenever you send the first UserOp with an `account` object with a `regular` plugin, the plugin will be enabled as a part of that UserOp. The UserOp itself can do whatever it needs to do. ### Using only a regular validator If a regular validator has already been enabled, you can use it without access to the sudo validator. -For example, continuing the session key example above, if the session key has already been enabled, you can simply do: +For example, continuing the session key example above, if the session key has already been enabled, you can do: ```ts const account = await createKernelAccount(publicClient, { diff --git a/docs/pages/sdk/v5_3_x/faqs/audits.mdx b/docs/pages/sdk/v5_3_x/faqs/audits.mdx index 3010738..1d08400 100644 --- a/docs/pages/sdk/v5_3_x/faqs/audits.mdx +++ b/docs/pages/sdk/v5_3_x/faqs/audits.mdx @@ -2,7 +2,7 @@ import VersionWarning from "../VersionWarning" -# ZeroDev Audits +# ZeroDev audits All ZeroDev contracts and plugins are audited unless otherwise noted. diff --git a/docs/pages/sdk/v5_3_x/faqs/chains.mdx b/docs/pages/sdk/v5_3_x/faqs/chains.mdx index 61ba6e7..3844a8d 100644 --- a/docs/pages/sdk/v5_3_x/faqs/chains.mdx +++ b/docs/pages/sdk/v5_3_x/faqs/chains.mdx @@ -2,7 +2,7 @@ import VersionWarning from "../VersionWarning" -# Supported Networks +# Supported networks ZeroDev supports EVM networks including: diff --git a/docs/pages/sdk/v5_3_x/faqs/debug-userop.mdx b/docs/pages/sdk/v5_3_x/faqs/debug-userop.mdx index c016fdc..e3e0751 100644 --- a/docs/pages/sdk/v5_3_x/faqs/debug-userop.mdx +++ b/docs/pages/sdk/v5_3_x/faqs/debug-userop.mdx @@ -4,11 +4,11 @@ import VersionWarning from "../VersionWarning" # Debugging UserOps with Tenderly -In account abstraction (ERC-4337), the transactions sent by smart accounts are known as "UserOps." UserOps are similar to but not the same as regular transactions, so it may not be clear how to debug them. +In account abstraction (ERC-4337), the transactions sent by smart accounts are known as "UserOps." UserOps are similar to but not the same as regular transactions, so it may not be clear how to debug them. -In this guide, we will be using [Tenderly](https://dashboard.tenderly.co/) to debug UserOps. Make sure you have signed up and created a Tenderly account. +In this guide, we will be using [Tenderly](https://dashboard.tenderly.co/) to debug UserOps. Make sure you have signed up and created a Tenderly account. -## The UserOp Structure +## The UserOp structure Let's begin by examining a typical UserOp example: @@ -29,11 +29,11 @@ Let's begin by examining a typical UserOp example: ``` -This UserOp structure will be our reference point as we navigate through the process of simulating and debugging UserOps. Understanding the components of this example is key to effectively using Tenderly's tools for our debugging needs. +This UserOp structure will serve as our reference point as we navigate the process of simulating and debugging UserOps. Understanding the components of this example is key to effectively using Tenderly’s tools for our debugging needs. -## UserOp Lifecycle +## UserOp lifecycle -Before delving into the nuances of debugging UserOps, it's helpful to learn the lifecycle of a UserOp. Here it is: +Before delving into the nuances of debugging UserOps, it’s helpful to understand its lifecycle. Here it is:

@@ -41,12 +41,12 @@ Before delving into the nuances of debugging UserOps, it's helpful to learn the If this looks daunting, let's focus on only the high level: -- A UserOp, with no gas estimates nor signature, is sent to a paymaster server, who simulates the UserOp and returns the gas estimates. - - If the UserOp has any errors in the validation or execution phase, the paymaster server will return an error since it can't properly simulate it. +- A UserOp, with no gas estimates nor signature, is sent to a paymaster server, which simulates the UserOp and returns the gas estimates. + - If the UserOp encounters any errors during validation or execution, the paymaster server will return an error because it can’t properly simulate them. - Now, the UserOp, with gas estimates and a proper signature, is sent to the bundler. - - At this point, the UserOp is not expected to revert during the validation phase, but it may nevertheless revert during the execution phase due to the on-chain state having changed between when the UserOp was sent to the paymaster and when it's submitted by the bundler. + - At this point, the UserOp is not expected to revert during the validation phase. Still, it may revert during execution if the on-chain state changes between when the UserOp was sent to the paymaster and when the bundler submits it. -## Understanding UserOp Failures +## Understanding UserOp failures A UserOp can fail at various stages, including during the paymaster call (if sponsored), the gas estimation call, or the final execution call. Identifying the failure point is straightforward by examining the method indicated in the error log of the failed UserOp. For instance: @@ -57,11 +57,11 @@ A UserOp can fail at various stages, including during the paymaster call (if spo Failures are generally classified into two categories: - **Validation Errors**: These occur during the validation phase when transactions are deemed invalid due to issues like incorrect signatures or nonce values. They typically present as EntryPoint error codes (e.g., AA23: XXXX). -- **Execution Errors**: These occur during the execution phase when transactions are valid, but the contract interaction is reverted, often noted as **`execution reverted`**. +- **Execution Errors**: These occur during execution when transactions are valid, but the contract interaction is reverted, often indicated by **`execution reverted`**. -## Using Tenderly for Simulation and Debugging +## Using Tenderly for simulation and debugging -### Adjusting Gas Limits for Simulation +### Adjusting gas limits for simulation For failures during paymaster or gas estimation calls, the UserOp gas limits (**`preVerificationGas`**, **`callGasLimit`**, **`verificationGasLimit`**) may default to **`0x`**. Before simulating the UserOp, adjust these gas limits as shown below. Increase these values based on error feedback if the simulation fails: @@ -76,7 +76,7 @@ For failures during paymaster or gas estimation calls, the UserOp gas limits (** If the failure occurs during **`eth_sendUserOperation`**, the UserOp should already contain all necessary values for accurate simulation. -### Debugging Execution Errors +### Debugging execution errors To simulate a UserOp in Tenderly, follow these steps: @@ -92,13 +92,13 @@ To simulate a UserOp in Tenderly, follow these steps:

-3. Enter the EntryPoint contract address in `Insert any address` input and select the appropriate chain. +3. Enter the EntryPoint contract address in the `Insert any address` input and select the appropriate chain. - The EntryPoint address is `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` for v0.6 (default for ZeroDev SDK v5.1.x or below) and `0x0000000071727De22E5E9d8BAf0edAc6f37da032` for v0.7 (default for ZeroDev SDK v5.2.x or above) 4. Choose **`simulateHandleOp`**, input the UserOp into the tuple field, and commence the simulation. If the simulation fails, it typically indicates a problem with the end contract. Verify the initial calldata thoroughly. -### Simulating End Contract Calls +### Simulating end contract calls

@@ -106,11 +106,11 @@ If the simulation fails, it typically indicates a problem with the end contract. To simulate an end contract call: -1. Insert the Smart Contract Wallet address in `Insert any address` input (**`sender`** field from UserOp). +1. Insert the Smart Contract Wallet address in the `Insert any address` input (**`sender`** field from UserOp). 2. Select the chain and enter the EntryPoint contract address in the **`From`** field. 3. Enter the **`calldata`** field from UserOp into the **`Raw input data`** field and simulate the transaction. -### Debugging Validation Errors +### Debugging validation errors For validation errors, simulate the validation process by: diff --git a/docs/pages/sdk/v5_3_x/faqs/use-with-ethers.mdx b/docs/pages/sdk/v5_3_x/faqs/use-with-ethers.mdx index 34207bc..3bace87 100644 --- a/docs/pages/sdk/v5_3_x/faqs/use-with-ethers.mdx +++ b/docs/pages/sdk/v5_3_x/faqs/use-with-ethers.mdx @@ -2,11 +2,11 @@ import VersionWarning from "../VersionWarning" -# Can I Use a KernelClient with Ethers? +# Can I Use a KernelClient with Ethers.js? -Our KernelClient implements the Viem WalletClient interface. Although it is not directly compatible with Ethers.js, we have developed an EIP1193Provider that accepts a KernelClient as a constructor parameter. This provider enables the use of KernelClient with Ethers.js in a similar manner to how window.ethereum is utilized with Ethers.js. +Our KernelClient implements the Viem WalletClient interface. Although it is not directly compatible with Ethers.js, we have developed an EIP1193Provider that accepts a KernelClient as a constructor parameter. This provider enables using KernelClient with Ethers.js, like how window.ethereum is used with Ethers.js. -Below is an example demonstrating how to use a KernelClient with the EIP1193Provider. This example assumes you are familiar with the creating of a KernelClient. For detailed instructions on creating a KernelClient, please refer to our [API docs](https://docs.zerodev.app/sdk/core-api/create-account). +Below is an example demonstrating how to use a KernelClient with the EIP1193Provider. This example assumes you are familiar with creating a KernelClient. For detailed instructions on creating a KernelClient, please refer to our [API docs](https://docs.zerodev.app/sdk/core-api/create-account). ```typescript import { KernelEIP1193Provider } from '@zerodev/sdk/providers'; diff --git a/docs/pages/sdk/v5_3_x/faqs/use-with-gelato.mdx b/docs/pages/sdk/v5_3_x/faqs/use-with-gelato.mdx index 4a2ba31..b9bf670 100644 --- a/docs/pages/sdk/v5_3_x/faqs/use-with-gelato.mdx +++ b/docs/pages/sdk/v5_3_x/faqs/use-with-gelato.mdx @@ -4,18 +4,20 @@ import VersionWarning from "../VersionWarning" # Using ZeroDev with Gelato -Gelato's has a unique approach to handling transaction fees without the need for an EntryPoint deposit or an on-chain paymaster. Instead, transaction fees are settled post-execution via [1Balance](https://docs.gelato.network/web3-services/relay/subscriptions-and-payments/1balance-and-relay) across all supported networks, ensuring accurate charging of gas consumed without necessitating per-chain user deposits. This method relies on setting `maxFeePerGas=0`, thereby eliminating the need for upfront fee payments (`requiredPrefund=0`). +Gelato's has a unique approach to handling transaction fees without the need for an EntryPoint deposit or an onchain paymaster. Instead, transaction fees are settled post-execution via [1Balance](https://docs.gelato.network/web3-services/relay/subscriptions-and-payments/1balance-and-relay) across all supported networks, ensuring accurate charging of gas consumed without necessitating per-chain user deposits. This method relies on setting `maxFeePerGas=0`, thereby eliminating the need for upfront fee payments (`requiredPrefund=0`). For a deeper understanding of Gelato's capabilities, refer to [their comprehensive documentation](https://docs.gelato.network/web3-services/account-abstraction/advantages-and-highlights). ## ZeroDev SDK with Gelato -Integrating Gelato with our SDK necessitates specific configurations, diverging from conventional bundler setups due to Gelato's distinct fee management mechanism. +Integrating Gelato with our SDK requires specific configurations that differ from conventional bundler setups, given Gelato’s distinct fee management mechanism. + +### Essential configurations -### Essentail Configurations - **Omit Paymaster**: Unlike other services, Gelato's transactions are sponsored without specifying a paymaster. Thus, your account will directly bear the gas fees incurred through Gelato's operations. Initialization with Preset Options + ```typescript const kernelClient = await createEcdsaKernelAccountClient({ // Mandatory fields @@ -31,7 +33,8 @@ const kernelClient = await createEcdsaKernelAccountClient({ Manual Setup without Presets -If opting for a manual configuration, ensure the sponsorUserOperation middleware is not used, as illustrated below (commented out for clarity): +If opting for a manual configuration, ensure the `sponsorUserOperation` middleware is not used, as illustrated below (commented out for clarity): + ```typescript const kernelClient = createKernelAccountClient({ account, @@ -50,7 +53,7 @@ const kernelClient = createKernelAccountClient({ }) ``` -### Transaction Configuration +### Transaction configuration When dispatching transactions or user operations through Gelato, it's crucial to set both `maxFeePerGas` and `maxPriorityFeePerGas` to `0x0`. This ensures compatibility with Gelato's fee settlement approach. diff --git a/docs/pages/sdk/v5_3_x/faqs/use-with-react-native.mdx b/docs/pages/sdk/v5_3_x/faqs/use-with-react-native.mdx index 275eea2..49f6e7b 100644 --- a/docs/pages/sdk/v5_3_x/faqs/use-with-react-native.mdx +++ b/docs/pages/sdk/v5_3_x/faqs/use-with-react-native.mdx @@ -4,7 +4,7 @@ import VersionWarning from "../VersionWarning" # Using ZeroDev with React Native -ZeroDev works great in React Native. Our user Stephen Gordon has helpfully made starter templates for: +ZeroDev works great in React Native. Our user Stephen Gordon has helpfully made starter templates for: - [ZeroDev with React Native.](https://github.com/stephen-gordon/zerodev-expo-starter) - [ZeroDev + Privy with Expo.](https://github.com/Stephen-Gordon/zerodev-privy-expo) diff --git a/docs/pages/sdk/v5_3_x/getting-started/migration.mdx b/docs/pages/sdk/v5_3_x/getting-started/migration.mdx index d7edd56..fb9b648 100644 --- a/docs/pages/sdk/v5_3_x/getting-started/migration.mdx +++ b/docs/pages/sdk/v5_3_x/getting-started/migration.mdx @@ -2,7 +2,7 @@ import VersionWarning from "../VersionWarning" -# Migration Guide +# Migration guide ## SDK 5.1.x => 5.2.x diff --git a/docs/pages/sdk/v5_3_x/getting-started/quickstart.mdx b/docs/pages/sdk/v5_3_x/getting-started/quickstart.mdx index be4963f..2095ca9 100644 --- a/docs/pages/sdk/v5_3_x/getting-started/quickstart.mdx +++ b/docs/pages/sdk/v5_3_x/getting-started/quickstart.mdx @@ -152,6 +152,6 @@ Waiting for UserOp to complete... View completed UserOp here: https://jiffyscan.xyz/userOpHash/0x7a8e0ba961cc0a34f745b81d64766f033269fee831104fee0269fa5bcc397dcb ``` -Congrats -- you just sent your first gasless transaction with ZeroDev! +Congrats—you just sent your first gasless transaction with ZeroDev! -In this example, you used a public ZeroDev API key. Now read [the tutorial](/sdk/v5_3_x/getting-started/tutorial) to see how to set up your own ZeroDev project. +In this example, you used a public ZeroDev API key. Now read [the tutorial](/sdk/v5_3_x/getting-started/tutorial) to see how to set up your own ZeroDev project. diff --git a/docs/pages/sdk/v5_3_x/getting-started/tutorial-passkeys.mdx b/docs/pages/sdk/v5_3_x/getting-started/tutorial-passkeys.mdx index 8ea47dc..2891b7f 100644 --- a/docs/pages/sdk/v5_3_x/getting-started/tutorial-passkeys.mdx +++ b/docs/pages/sdk/v5_3_x/getting-started/tutorial-passkeys.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../VersionWarning" -# ZeroDev Tutorial -- Passkeys +# ZeroDev tutorial: Passkeys -In this tutorial, we will be building a Next.js app where your users can create smart accounts and send UserOps with [passkeys](/sdk/v5_3_x/advanced/passkeys). +In this tutorial, we will build a Next.js app where users can create smart accounts and send UserOps with [passkeys](/sdk/v5_3_x/advanced/passkeys). ## Clone the template @@ -14,7 +14,7 @@ We have prepared a [Next.js template](https://github.com/zerodevapp/passkey-tuto git clone git@github.com:zerodevapp/passkey-tutorial.git ``` -If you ever want to check out the completed code, you can checkout the `completed` branch. You can also see a deployed demo [here](https://passkey-demo.zerodev.app/). +If you ever want to check out the completed code, you can check out the `completed` branch. You can also see a deployed demo [here](https://passkey-demo.zerodev.app/). Run the app in development mode: @@ -23,7 +23,7 @@ npm i npm run dev ``` -Open `app/page.tsx`. We will be working on this file for the rest of the tutorial. +Open `app/page.tsx`. We will be working on this file for the rest of the tutorial. ## Create a ZeroDev project @@ -96,7 +96,7 @@ const handleLogin = async () => { } ``` -In this tutorial, we are using a public passkey server URL. In practice, you'd create your own passkey server URL from [the dashboard](https://dashboard.zerodev.app/). +In this tutorial, we are using a public passkey server URL. In practice, you'd create your own passkey server URL from [the dashboard](https://dashboard.zerodev.app/). Now modify `createAccountAndClient` to actually create the account using the `passkeyValidator`: @@ -139,7 +139,7 @@ At this point, you should be able to create passkey accounts with either `Regist ## Sending UserOps -Sending UserOps from a passkey account is the same as sending them from any account. Modify `handleSendUserOp` as such: +Sending UserOps from a passkey account is the same as sending them from any account. Modify `handleSendUserOp` as such: ```ts const handleSendUserOp = async () => { @@ -179,11 +179,11 @@ const handleSendUserOp = async () => { Now try sending some UserOps! -Also, the UserOps are sponsored thanks to paymasters -- that's why you are able to send UserOps from an account with no ETH. +Also, the UserOps are sponsored thanks to paymasters—that’s why you can send UserOps from an account with no `ETH`. -## Next Steps +## Next steps -In this tutorial, you were able to create smart accounts and send UserOps with passkeys. +In this tutorial, you created smart accounts and sent UserOps with passkeys. For next steps: diff --git a/docs/pages/sdk/v5_3_x/getting-started/tutorial.mdx b/docs/pages/sdk/v5_3_x/getting-started/tutorial.mdx index 8a8e40d..fb09026 100644 --- a/docs/pages/sdk/v5_3_x/getting-started/tutorial.mdx +++ b/docs/pages/sdk/v5_3_x/getting-started/tutorial.mdx @@ -2,15 +2,15 @@ import VersionWarning from "../VersionWarning" -# ZeroDev Tutorial +# ZeroDev tutorial :::info -Impatient? Check out [the complete example here](https://github.com/zerodevapp/zerodev-examples/tree/main/tutorial/completed.ts). +Impatient? Check out [the complete example here](https://github.com/zerodevapp/zerodev-examples/tree/main/tutorial/completed.ts). ::: In this tutorial, we will mint an NFT without paying gas. We assume that you have a high-level understanding of AA concepts such as bundlers, paymasters, and UserOp; if not, read [the introduction](/) first. -## Create a ZeroDev Project +## Create a ZeroDev project For this tutorial, we will use [ZeroDev's AA infra](/meta-infra/intro), but you can use ZeroDev with any AA infra provider. @@ -28,7 +28,7 @@ We will be using the "Project ID" in the next steps. ## Set up a gas policy -With ZeroDev, by default you are not sponsoring UserOps. To sponsor UserOps, you need to set up a gas policy. +By default, with ZeroDev, you are not sponsoring UserOps. To sponsor UserOps, you need to set up a gas policy. Go to the "Gas Policies" section of your dashboard and create a new "Project Policy": @@ -40,7 +40,7 @@ From now on, when you use the paymaster RPC from the previous step, the paymaste ## Write the code -Clone the [ZeroDev examples repo](https://github.com/zerodevapp/zerodev-examples). Then, inside the directory, install all dependencies: +Clone the [ZeroDev examples repo](https://github.com/zerodevapp/zerodev-examples). Then, inside the directory, install all dependencies: ```bash npm install @@ -52,7 +52,7 @@ Create a `.env` file with the following line: ZERODEV_PROJECT_ID= ``` -Replacing `` with your actual project ID from the dashboard, and make sure you are using a project ID for Sepolia. +Replace `` with your actual project ID from the dashboard, and ensure you are using a Sepolia project ID. If all goes well, you should be able to run: @@ -60,13 +60,13 @@ If all goes well, you should be able to run: npx ts-node tutorial/completed.ts ``` -Now open the [`tutorial/template.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/template.ts) file in your editor. This will be the template where you will write your code. You can always refer to [`tutorial/completed.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/completed.ts) to see the completed tutorial code. +Now open the [`tutorial/template.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/template.ts) file in your editor. This will be the template where you will write your code. You can always refer to [`tutorial/completed.ts`](https://github.com/zerodevapp/zerodev-examples/blob/main/tutorial/completed.ts) to see the completed tutorial code. ### Create a signer -Kernel accounts support many different signing methods, including ECDSA keys and passkeys. In this tutorial, we will use ECDSA keys which are the same type of keys that MetaMask and other Ethereum wallets use. +Kernel accounts support many different signing methods, including ECDSA keys and passkeys. In this tutorial, we will use ECDSA keys, the same type used by MetaMask and other Ethereum wallets. -Let's start by generating a random key. Add the following code to the `main` function: +Let's start by generating a random key. Add the following code to the `main` function: ```typescript import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" @@ -79,7 +79,7 @@ const main = async () => { ### Create a validator -Each Kernel account handles validation through a smart contract known as a "validator." In this case, we will be using the ECDSA validator. +Each Kernel account handles validation through a smart contract known as a "validator." In this case, we will be using the ECDSA validator. Add the following code to create the ECDSA validator: @@ -98,7 +98,7 @@ const main = async () => { ### Create an account -We are now ready to create an account. Add the following code: +We are now ready to create an account. Add the following code: ```typescript import { createKernelAccount } from "@zerodev/sdk" @@ -117,7 +117,7 @@ const main = async () => { ### Creating a Kernel client -Finally, we are going to create an "account client" which serves as the connection between your account and some AA infra (i.e. bundlers and paymasters). The connection is necessary for you to actually send UserOps. +Finally, we are going to create an “account client” that serves as the connection between your account and AA infrastructure (i.e., bundlers and paymasters). The connection is necessary for you to send UserOps. Add the following code: @@ -154,7 +154,7 @@ Run this script with `npx ts-node tutorial/template.ts` and confirm that it prin ### Send a UserOp -Now that you have an account client, it's time to send your first UserOp! For this tutorial, we will mint an NFT from a contract deployed on Sepolia. +Now that you have an account client, it's time to send your first UserOp! For this tutorial, we will mint an NFT from a contract deployed on Sepolia. Add the following import and code: @@ -184,15 +184,15 @@ const main = async () => { There's quite a bit of code going on, so let's go through it. - We start by calling `kernelClient.sendUserOperation`, which takes a `userOperation` argument. -- Inside `userOperation`, we specify a `callData` field. This is the equivalent of the calldata field for a normal Ethereum transaction. +- Inside `userOperation`, we specify a `callData` field. This is equivalent to the calldata field in a typical Ethereum transaction. - Since we want to call the `mint(address)` function on the NFT contract, we use Viem's helper function `encodeFunctionData` and give it the ABI, function name, and function argument. -- `kernelClient.sendUserOperation` returns a "UserOperation hash." This is the equivalent of a transaction hash but for a UserOp. +- `kernelClient.sendUserOperation` returns a "UserOperation hash." This is the equivalent of a transaction hash but for a UserOp. -Run the script again with `npx ts-node tutorial/template.ts` and confirm that it prints the UserOp hash. At this point, you can go to a UserOp explorer such as [JiffyScan](https://jiffyscan.xyz/) and find your UserOp with the hash! +Run the script again with `npx ts-node tutorial/template.ts` and confirm that it prints the UserOp hash. At this point, you can use a UserOp explorer such as [JiffyScan](https://jiffyscan.xyz/) to find your UserOp by its hash! ### Waiting for the UserOp -When you call `sendUserOperation`, the call returns as soon as the UserOp has been submitted to the bundler, but it doesn't wait for the UserOp to be "confirmed" on-chain. To wait for the UserOp to be confirmed, add the following import and code: +When you call `sendUserOperation`, the call returns as soon as the UserOp has been submitted to the bundler, but it doesn't wait for the UserOp to be "confirmed" onchain. To wait for the UserOp to be confirmed, add the following import and code: ```typescript import { bundlerActions } from "permissionless" @@ -211,12 +211,12 @@ const main = async () => { Let's break down the code: -- Since `waitForUserOperationReceipt` is a bundler action, we need to first `extend` the `kernelClient` with `bundlerActions`. If you are unfamiliar with the concept of "actions," you can read more about it on [Viem's documentation](https://viem.sh/docs/actions/public/introduction). -- Now, we can call `waitForUserOperationReceipt`. This function returns a "receipt" object. If you are curious, you can print the full object and see what it contains. +- Since `waitForUserOperationReceipt` is a bundler action, we need to `extend` the `kernelClient` with `bundlerActions`. If you are unfamiliar with the concept of "actions," you can read more about it on [Viem's documentation](https://viem.sh/docs/actions/public/introduction). +- Now, we can call `waitForUserOperationReceipt`. This function returns a "receipt" object. If you are curious, you can print the full object and see what it contains. ### Read contract state -Now let's confirm that we actually minted an NFT. Add the following import and code: +Now let's confirm that we actually minted an NFT. Add the following import and code: ```typescript import { publicActions } from "viem" @@ -234,7 +234,7 @@ const main = async () => { } ``` -Run the script again. You should see that it prints `NFT balance: 1`, confirming that you have minted an NFT! +Run the script again. You should see it print "`NFT balance: 1`," confirming that you have minted an NFT! ## Next steps diff --git a/docs/pages/sdk/v5_3_x/index.mdx b/docs/pages/sdk/v5_3_x/index.mdx index 735742b..15eb75d 100644 --- a/docs/pages/sdk/v5_3_x/index.mdx +++ b/docs/pages/sdk/v5_3_x/index.mdx @@ -2,18 +2,18 @@ import VersionWarning from "./VersionWarning" -# ZeroDev Introduction +# ZeroDev introduction ZeroDev is a **chain-abstracted smart account** for building user-friendly Web3 experiences. - **Chain-abstracted**: ZeroDev smart accounts can aggregate tokens across chains into a unified "[chain-abstracted balance](/sdk/v5_3_x/advanced/chain-abstraction)" which can be spent on any chain, without bridging. - - For example, if you deposit 100 USDC on Base and 200 USDC on Polygon to a ZeroDev account, it now holds 300 "chain-abstracted USDC" which can be spent on any chain, without bridging. + - For example, if you deposit 100 `USDC` on Base and 200 `USDC` on Polygon to a ZeroDev account, it now holds 300 "chain-abstracted `USDC`" which can be spent on any chain, without bridging. - **Smart**: ZeroDev is the most powerful smart account solution, supporting not just basic AA features such as gas sponsorship and batching, but also advanced features including transaction automation (session keys), recovery, and more. -ZeroDev can be used as a standalone embedded smart account, or used to enable smart accounts for WaaS solutions such as [Privy](/sdk/v5_3_x/signers/privy) and [Dynamic](/sdk/v5_3_x/signers/dynamic). +ZeroDev can be used as a standalone embedded smart account or used to enable smart accounts for WaaS solutions such as [Privy](/sdk/v5_3_x/signers/privy) and [Dynamic](/sdk/v5_3_x/signers/dynamic). ZeroDev is one of the most trusted solutions in AA, powering more than 50% of all AA wallets and a majority of DeFi volume that leverages AA. -## Getting Started +## Getting started To start coding with ZeroDev, check out [the quickstart](/sdk/v5_3_x/getting-started/quickstart) or [the tutorial](/sdk/v5_3_x/getting-started/tutorial). diff --git a/docs/pages/sdk/v5_3_x/infra/coinbase.mdx b/docs/pages/sdk/v5_3_x/infra/coinbase.mdx index f5da793..4fad2d4 100644 --- a/docs/pages/sdk/v5_3_x/infra/coinbase.mdx +++ b/docs/pages/sdk/v5_3_x/infra/coinbase.mdx @@ -6,6 +6,6 @@ import VersionWarning from "../VersionWarning" [Coinbase Developer Platform](https://docs.cdp.coinbase.com/) (CDP) offers bundler and paymaster services that you can use with ZeroDev. -Generally speaking, Coinbase bundlers & paymasters speak the same interface as Pimlico, so you can follow [this guide](/sdk/v5_3_x/infra/pimlico) and simply replace the Pimlico bundler/paymaster URLs with the CDP bundler/paymaster URLs. +Generally speaking, Coinbase bundlers & paymasters speak the same interface as Pimlico, so you can follow [this guide](/sdk/v5_3_x/infra/pimlico) and replace the Pimlico bundler/paymaster URLs with the CDP bundler/paymaster URLs. You can also refer to [CDP's official examples for ZeroDev](https://github.com/coinbase/paymaster-bundler-examples/tree/master/examples/zerodev). diff --git a/docs/pages/sdk/v5_3_x/infra/intro.mdx b/docs/pages/sdk/v5_3_x/infra/intro.mdx index 5c4e8e1..fe1dad7 100644 --- a/docs/pages/sdk/v5_3_x/infra/intro.mdx +++ b/docs/pages/sdk/v5_3_x/infra/intro.mdx @@ -4,16 +4,16 @@ import VersionWarning from "../VersionWarning" # Choosing an infra provider -ZeroDev is compatible with any account abstraction infra provider. Check out these guides for integrating with a specific provider: +ZeroDev is compatible with any account abstraction infra provider. Check out these guides for integrating with a specific provider: - [ZeroDev](/meta-infra/intro) - [Pimlico](/sdk/v5_3_x/infra/pimlico) Read on to learn how to integrate with a custom provider. -## Interop with Bundlers +## Interop with bundlers -For the most part, bundlers are perfectly interoperable between different providers. You simply specify the bundler RPC when you construct a Kernel client: +For the most part, bundlers are perfectly interoperable between different providers. You specify the bundler RPC when you construct a Kernel client: ```typescript import { createKernelAccountClient } from "@zerodev/sdk" @@ -28,7 +28,7 @@ const kernelClient = createKernelAccountClient({ ## Interop with Paymasters -Paymasters are not perfectly interoperable between providers. To integrate with a paymaster, you need to implement the `sponsorUserOperation` function: +Paymasters are not perfectly interoperable between providers. To integrate with a paymaster, you need to implement the `sponsorUserOperation` function: ```typescript import { createKernelAccountClient } from "@zerodev/sdk" diff --git a/docs/pages/sdk/v5_3_x/infra/pimlico.mdx b/docs/pages/sdk/v5_3_x/infra/pimlico.mdx index 7e89a5d..ef293f5 100644 --- a/docs/pages/sdk/v5_3_x/infra/pimlico.mdx +++ b/docs/pages/sdk/v5_3_x/infra/pimlico.mdx @@ -4,13 +4,13 @@ import VersionWarning from "../VersionWarning" # Pimlico -[Pimlico](https://www.pimlico.io/) is a leading AA infra provider with a wide coverage of networks. +[Pimlico](https://www.pimlico.io/) is a leading AA infrastructure provider with a wide network coverage. Note that ZeroDev is built on top of Pimlico's [Permissionless](https://docs.pimlico.io/permissionless/reference) SDK, so if you were already using Permissionless, it's easy to switch to ZeroDev to take full advantage of the power of [Kernel](https://github.com/zerodevapp/kernel). ## Using Pimlico bundler -Simply specify Pimlico's bundler RPC when [constructing a Kernel client](/sdk/v5_3_x/core-api/create-account#standard-api): +Specify Pimlico's bundler RPC when [constructing a Kernel client](/sdk/v5_3_x/core-api/create-account#standard-api): ```typescript import { createKernelAccountClient } from "@zerodev/sdk" @@ -23,7 +23,7 @@ const kernelClient = createKernelAccountClient({ }) ``` -## Using Pimlico paymaster +## Using the Pimlico paymaster Construct the Kernel client with Pimlico's paymaster client: diff --git a/docs/pages/sdk/v5_3_x/infra/zerodev.mdx b/docs/pages/sdk/v5_3_x/infra/zerodev.mdx index 01ca365..0e17179 100644 --- a/docs/pages/sdk/v5_3_x/infra/zerodev.mdx +++ b/docs/pages/sdk/v5_3_x/infra/zerodev.mdx @@ -4,4 +4,4 @@ import VersionWarning from "../VersionWarning" # ZeroDev -ZeroDev provides a meta infrastructure that proxies traffic to multiple infra providers including Alchemy, Gelato and Pimlico. [Read more here](/meta-infra/intro). \ No newline at end of file +ZeroDev provides a meta infrastructure that proxies traffic to multiple infrastructure providers, including Alchemy, Gelato, and Pimlico. [Read more here](/meta-infra/intro). \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/1-click-trading.mdx b/docs/pages/sdk/v5_3_x/permissions/1-click-trading.mdx index 0a1ebb6..51f8151 100644 --- a/docs/pages/sdk/v5_3_x/permissions/1-click-trading.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/1-click-trading.mdx @@ -2,11 +2,11 @@ import VersionWarning from "../VersionWarning" -# Tutorial -- Transaction Automation +# Tutorial: Transaction automation In this tutorial, you will learn how to enable 1-click trading for your app using session keys. -Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/1-click-trading.ts) while you follow along the tutorial. You can run the example by following instructions of [the examples repo](https://github.com/zerodevapp/zerodev-examples). +Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/1-click-trading.ts) while you follow along with the tutorial. You can run the example by following the instructions in [the examples repo](https://github.com/zerodevapp/zerodev-examples). ## Installation @@ -32,21 +32,26 @@ bun add @zerodev/permissions ::: -## Owner-Agent Architecture +## Owner-Agent architecture -There are multiple ways to use session keys. In this tutorial, we will use the popular "owner-agent" pattern: +There are multiple ways to use session keys. In this tutorial, we will use the popular "owner-agent" pattern: - The "owner" is the owner of the master key. - The "agent" is the entity that wants to use the session key. -In a typical setup, you might be wishing to automate transactions for your users from your server. +In a typical setup, you can automate transactions for your users on your server. -your user's master key might be connected to your DApp frontend, in which case your frontend is the "owner." You might be wishing + ## API :::info + You can reference this [complete code example](https://github.com/zerodevapp/zerodev-examples/blob/main/permissions/main.ts) as you go through the tutorial. + ::: With a permissions validator, you are putting together: @@ -57,7 +62,7 @@ With a permissions validator, you are putting together: ### Creating a signer -Start by creating a [ECDSA signer](/sdk/v5_3_x/permissions/signers/ecdsa): +Start by creating an [ECDSA signer](/sdk/v5_3_x/permissions/signers/ecdsa): ```ts const sessionPrivateKey = generatePrivateKey() @@ -68,7 +73,7 @@ const sessionKeySigner = await toECDSASigner({ }) ``` -### Creating a number of policies +### Creating several of policies Now, let's create two policies: @@ -99,7 +104,7 @@ const rateLimitPolicy = toRateLimitPolicy({ ### Composing signer and policies -Here comes the fun part -- we "compose" the signer and policies together into a single validator: +Here comes the fun part—we "compose" the signer and policies together into a single validator: ```ts const sessionKeyValidator = await toPermissionValidator(publicClient, { @@ -113,11 +118,11 @@ const sessionKeyValidator = await toPermissionValidator(publicClient, { }), ``` -Now, we have created a ECDSA session key that's subject to a call policy and a rate limit policy. Just like that! +Now, we have created an ECDSA session key that's subject to a call policy and a rate limit policy. Just like that! ### Using the session key -Finally, we can set up the account with this session key as the signer. Note that if this is the first time that the session key is used, we need to [enable the plugin](/sdk/v5_3_x/core-api/using-plugins#enabling-a-regular-validator). +Finally, we can set up the account with this session key as the signer. Note that if this is the first time that the session key is used, we need to [enable the plugin](/sdk/v5_3_x/core-api/using-plugins#enabling-a-regular-validator). ```ts const account = await createKernelAccount(publicClient, { @@ -130,21 +135,21 @@ const account = await createKernelAccount(publicClient, { }) ``` -Now you can [set up a Kernel client](/sdk/v5_3_x/core-api/create-account#create-an-account-client) using this account, and start minting NFTs with this session key -- but only up to once a month! +Now you can [set up a Kernel client](/sdk/v5_3_x/core-api/create-account#create-an-account-client) using this account, and start minting NFTs with this session key—but only up to once a month! Try running [this script](https://github.com/zerodevapp/zerodev-examples/blob/main/permissions/main.ts) and see for yourself. -## Storing Session Keys +## Storing session keys -Session keys (and permission validators in general) can be stored, by serializing them and then deserializing them later. +Session keys (and permission validators in general) can be stored by serializing them and then deserializing them later. ### Code examples -There are two general patterns with storing session keys. +There are two general patterns for storing session keys. -- The owner creates a session key for another agent to store & use. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/owner-created.ts). -- The agent creates a session key and asks the owner to "approve" it as a session key. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/agent-created.ts). - - In this flow, the owner never sees the private part of the session key, so it may be better for security. +- The owner creates a session key for another agent to store & use. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/owner-created.ts). +- The agent generates a session key and asks the owner to “approve” it. Check out [this example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/agent-created.ts). + - In this flow, the owner never sees the private part of the session key, which may be better for security. ### Serializing a session key @@ -152,7 +157,7 @@ There are two general patterns with storing session keys. const serializedSessionKey = await serializePermissionAccount(sessionKeyAccount, sessionPrivateKey) ``` -Note that `sessionPrivateKey` is optional. If the private key is not included, then you must provide the private key when you deserialize the session key. +Note that `sessionPrivateKey` is optional. If the private key is not included, you must provide it when deserializing the session key. ### De-serializing a session key diff --git a/docs/pages/sdk/v5_3_x/permissions/actions/build-your-own.mdx b/docs/pages/sdk/v5_3_x/permissions/actions/build-your-own.mdx index 5ee3d44..5fc2ccf 100644 --- a/docs/pages/sdk/v5_3_x/permissions/actions/build-your-own.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/actions/build-your-own.mdx @@ -2,6 +2,6 @@ import VersionWarning from "../../VersionWarning" -# Build Your Own Action +# Build your own action Guide coming soon. \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/intro.mdx b/docs/pages/sdk/v5_3_x/permissions/intro.mdx index 219e03e..aec4e76 100644 --- a/docs/pages/sdk/v5_3_x/permissions/intro.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/intro.mdx @@ -2,28 +2,28 @@ import VersionWarning from "../VersionWarning" -# Permissions (Session Keys) +# Permissions (session keys) -With Kernel, you can assign different permissions to different keys. Some of these keys might be owned by the owner(s) of the smart account, and some might be short-lived keys that you share with others to delegate transactions. The latter are also commonly known as "session keys." +With Kernel, you can assign different permissions to different keys. Some of these keys might be owned by the owner(s) of the smart account, and some might be short-lived keys that you share with others to delegate transactions. The latter are also commonly known as "session keys." To set up permissions for a key, you must answer three questions: who, when, and what. -- **Who** (what key) can perform the action? +- **Who** (what key) can take the action? - **When** (under what condition) can the action be performed? -- **What** is the action anyways? +- **What** is the action anyway? These three questions correspond to three types of "permissions plugins": - **Signers** (who) specify the key and the algorithm (ECDSA, WebAuthn) it uses. -- **Policies** (when) specify the *conditions* under which the keys can be used. Some example conditions are: +- **Policies** (when) specify the *conditions* under which the keys are usable. Some example conditions are: - Only if interacting with Uniswap - - Only if spending USDC + - Only if spending `USDC` - Only once a month - **Actions** (what) specify the execution function the key uses. -## Composing Permissions +## Composing permissions -Kernel is the first smart account to support *composable permissions*. That is, you can build up fine-grained permissions from putting together signers, policies, and actions. Here's the formula: +Kernel is the first smart account to support *composable permissions*. That is, you can build fine-grained permissions by combining signers, policies, and actions. Here’s the formula: ``` Permission = 1 signer + N policies + 1 action @@ -43,17 +43,17 @@ const account = createKernelAccount({ }) ``` -Here, the `signer` will be able to perform `action` if all `policies` are met. +Here, the `signer` can take action if all `action` if all `policies` are met. -Now let's dive into these plugin types. +Now, let's dive into these plugin types. -## Permission Plugins +## Permission plugins Because permissions are plugins, **you can write your own permissions** if the default ones provided by ZeroDev don't meet your needs. ### Signers -Signers specify the keys and the algorithms the keys use. ZeroDev provides signers for: +Signers specify the keys and the algorithms the keys use. ZeroDev provides signers for: - ECDSA - WebAuthn (passkeys) @@ -61,7 +61,7 @@ Signers specify the keys and the algorithms the keys use. ZeroDev provides sign ### Policies -Policies are the conditions under which the keys can be used. ZeroDev provides the following policies: +Policies are the conditions under which the keys become usable. ZeroDev provides the following policies: - [Sudo policy](/sdk/v5_3_x/permissions/policies/sudo): you can do anything - [Call policy](/sdk/v5_3_x/permissions/policies/call): you can only call certain contracts or functions (and only with certain params) @@ -72,12 +72,12 @@ Policies are the conditions under which the keys can be used. ZeroDev provides ### Actions -Actions are arbitrary functions that the smart account will `delegatecall` to. They give you perfect flexibility over the execution logic. +Actions are arbitrary functions that the smart account will `delegatecall` to. They give you perfect flexibility over the execution logic. -Note that actions are NOT to be confused with the calls you actually want to execute. For example, if you want to interact with Uniswap, that's just the call you want to execute. "Action" here specifically refers to the execution function by which Uniswap is called. +Note that actions are NOT to be confused with the calls you actually want to execute. For example, if you want to interact with Uniswap, that's just the call you want to execute. "Action" here specifically refers to the execution function by which Uniswap is called. -If that's confusing, just forget about actions. Mostly commonly you will only be setting up signers and policies, and the `action` will default to Kernel's default `execute()` function, which is enough for most needs. +If that’s confusing, forget about actions. Most commonly, you will only set up signers and policies, and the `action` will default to Kernel's default `execute()` function, which is enough for most needs. -## Next Steps +## Next steps - [Learn to automate transactions for users with permissions.](/sdk/v5_3_x/permissions/transaction-automation) \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/policies/build-your-own.mdx b/docs/pages/sdk/v5_3_x/permissions/policies/build-your-own.mdx index 5b7b0aa..1f7bf17 100644 --- a/docs/pages/sdk/v5_3_x/permissions/policies/build-your-own.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/policies/build-your-own.mdx @@ -2,6 +2,6 @@ import VersionWarning from "../../VersionWarning" -# Build Your Own Policy +# Build your own policy Guide coming soon. \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/policies/call.mdx b/docs/pages/sdk/v5_3_x/permissions/policies/call.mdx index 7fe8c6f..9eb8545 100644 --- a/docs/pages/sdk/v5_3_x/permissions/policies/call.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/policies/call.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../../VersionWarning" -# Call Policy +# Call policy -The call policy limits the target (either contract or EOA) that the UserOp can interact with. If the target is a contract, then you can further specify the functions the UserOp can interact with, as well as putting constraints on the values of the function arguments. +The call policy limits the target (either contract or EOA) that the UserOp can interact with. If the target is a contract, then you can further specify the functions the UserOp can interact with, as well as put constraints on the values of the function arguments. ## API @@ -47,12 +47,12 @@ const validator = toPermissionValidator(publicClient, { }) ``` -- `target`: the target contract to call or address to send ETH to. If this is `zeroAddress`, then the target can be any contract as long as the ABI matches (or it can be any address if no ABI is specified). +- `target`: the target contract to call or the address to send `ETH` to. If this is `zeroAddress`, the target can be any contract as long as the ABI matches (or any address if no ABI is specified). - `valueLimit`: the maximum value. that can be transmitted. - `abi`: the contract ABI - `functionName`: the function name -- `selector`: if you have multiple functions with the same name, you can distinguish them with `selector`. For example: `selector: toFunctionSelector("transfer(uint256, uint256)")`. -- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. use `null` to skip an argument. +- `selector`: if you have multiple functions with the same name, you can distinguish them with a `selector`. For example: `selector: toFunctionSelector("transfer(uint256, uint256)")`. +- `args`: an array of conditions, each corresponding to an argument, in the order that the arguments are laid out. Use `null` to skip an argument. - `operator`: this can be `EQUAL`, `GREATER_THAN`, `LESS_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`, `NOT_EQUAL`. - - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the argument must be equal to 2". -- `operation`: whether this is a call or a delegatecall. Defaults to call. + - `value`: the value of the argument to use with the operator. For instance, `operator = EQUAL` and `value = 2` would mean "the argument must be equal to 2". +- `operation`: whether this is a call or a `delegatecall`. Defaults to call. diff --git a/docs/pages/sdk/v5_3_x/permissions/policies/gas.mdx b/docs/pages/sdk/v5_3_x/permissions/policies/gas.mdx index ca160f8..d19c5cc 100644 --- a/docs/pages/sdk/v5_3_x/permissions/policies/gas.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/policies/gas.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../../VersionWarning" -# Gas Policy +# Gas policy -The gas policy specifies how much gas the signer can use in total, across all UserOps it sends. It can also enforce that the UserOps must use paymasters, or use a specific paymaster. +The gas policy specifies the total amount of gas the signer can use across all UserOps it sends. It can also enforce that the UserOps must use paymasters, or use a specific paymaster. ## API @@ -39,6 +39,6 @@ const validator = toPermissionValidator(publicClient, { `toGasPolicy` takes one or more of the following arguments: -- `allowed`: an amount, in wei, of the ETH (or whatever native token) that the signer can spend on gas, in total across all UserOps it sends. -- `enforcePaymaster`: a boolean value. If set to true, enforce that a paymaster must be used. -- `allowedPaymaster`: a paymaster address. If set, enforce that the specific paymaster is used. \ No newline at end of file +- `allowed`: an amount, in wei, of the `ETH` (or whatever native token) that the signer can spend on gas, in total across all UserOps it sends. +- `enforcePaymaster`: a boolean value. If set to true, a paymaster is required. +- `allowedPaymaster`: a paymaster address. If set, enforce the use of the specific paymaster. \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/policies/rate-limit.mdx b/docs/pages/sdk/v5_3_x/permissions/policies/rate-limit.mdx index 6688266..fddede3 100644 --- a/docs/pages/sdk/v5_3_x/permissions/policies/rate-limit.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/policies/rate-limit.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../../VersionWarning" -# Rate Limit Policy +# Rate limit policy -The rate limit policy specifies the frequency at which the signer is allowed to send UserOps. +The rate limit policy specifies the frequency at which the signer can send UserOps. ## API @@ -33,4 +33,4 @@ Arguments to `toRateLimitPolicy`: - `count`: the number of times the signer can send UserOps in the given internal. - (optional) `interval`: the length of the interval, in seconds. - If not specified, then the interval is infinite, which means that you can use `count` to specify the number of times the signer can send UserOps in total. -- (optional) `startAt`: the starting UNIX timestamp for when the rate limit should take effect. Before that, the signer cannot send any UserOps. \ No newline at end of file +- (optional) `startAt`: the starting UNIX timestamp for when the rate limit should take effect. Before that, the signer cannot send any UserOps. \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/policies/signature.mdx b/docs/pages/sdk/v5_3_x/permissions/policies/signature.mdx index 3c61206..f4cf617 100644 --- a/docs/pages/sdk/v5_3_x/permissions/policies/signature.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/policies/signature.mdx @@ -2,11 +2,11 @@ import VersionWarning from "../../VersionWarning" -# Signature Caller Policy +# Signature caller policy The signature caller policy specifies a list of addresses that are allowed to validate messages signed by the signer. -This is useful when you want the signer to sign messages for a set of particular protocols only. For example, if you want to create a signer that can only sign USDC [permits](https://eips.ethereum.org/EIPS/eip-2612), then you can use this policy to ensure that only the USDC contract can validate its messages. +This is useful when you want the signer to sign messages only for a specific set of protocols. For example, if you want to create a signer that can only sign `USDC` [permits](https://eips.ethereum.org/EIPS/eip-2612), then you can use this policy to ensure that only the `USDC` contract can validate its messages. ## API @@ -28,4 +28,4 @@ const validator = toPermissionValidator(publicClient, { }) ``` -- `allowedCallers` is a list of addresses that are allowed to validate messages signed by the signer. \ No newline at end of file +- `allowedCallers`: is a list of addresses that are allowed to validate messages signed by the signer. \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/policies/sudo.mdx b/docs/pages/sdk/v5_3_x/permissions/policies/sudo.mdx index f979e09..84c86a6 100644 --- a/docs/pages/sdk/v5_3_x/permissions/policies/sudo.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/policies/sudo.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../../VersionWarning" -# Sudo Policy +# Sudo policy -The sudo policy gives full permission to the signer. The signer will be able to send any UserOps and sign any messages. +The sudo policy gives full permission to the signer. The signer will be able to send any UserOps and sign any messages. ## API diff --git a/docs/pages/sdk/v5_3_x/permissions/policies/timestamp.mdx b/docs/pages/sdk/v5_3_x/permissions/policies/timestamp.mdx index f3c6ab0..a53c8c0 100644 --- a/docs/pages/sdk/v5_3_x/permissions/policies/timestamp.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/policies/timestamp.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../../VersionWarning" -# Timestamp Policy +# Timestamp policy -The timestamp policy specifies the start and end time for when the signer is valid. +The timestamp policy specifies the start and end times for when the signer is valid. ## API @@ -30,5 +30,5 @@ const validator = toPermissionValidator(publicClient, { Arguments to `toTimestampPolicy`: -- `validAfter`: the time after which the signer becomes valid. If not specified, the signer is immediately valid. -- `validUntil`: the time before which the signer is valid. If not specified, the signer never expires. +- `validAfter`: the time after which the signer becomes valid. If not specified, the signer is considered valid immediately. +- `validUntil`: the time before which the signer is valid. If not specified, the signer never expires. diff --git a/docs/pages/sdk/v5_3_x/permissions/signers/build-your-own.mdx b/docs/pages/sdk/v5_3_x/permissions/signers/build-your-own.mdx index b5fbe3f..f181515 100644 --- a/docs/pages/sdk/v5_3_x/permissions/signers/build-your-own.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/signers/build-your-own.mdx @@ -2,6 +2,6 @@ import VersionWarning from "../../VersionWarning" -# Build Your Own Signer +# Build your own signer Guide coming soon. \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/signers/ecdsa.mdx b/docs/pages/sdk/v5_3_x/permissions/signers/ecdsa.mdx index e595122..16e552c 100644 --- a/docs/pages/sdk/v5_3_x/permissions/signers/ecdsa.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/signers/ecdsa.mdx @@ -2,7 +2,7 @@ import VersionWarning from "../../VersionWarning" -# ECDSA Signer +# ECDSA signer The ECDSA signer signs with a single ECDSA key, specifically with the `secp256k1` curve, which is the same algorithm that EOAs use. diff --git a/docs/pages/sdk/v5_3_x/permissions/signers/multisig.mdx b/docs/pages/sdk/v5_3_x/permissions/signers/multisig.mdx index e8e87ab..4bc4b41 100644 --- a/docs/pages/sdk/v5_3_x/permissions/signers/multisig.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/signers/multisig.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../../VersionWarning" -# Multisig Signer +# Multisig signer -The weighted ECDSA (multisig) signer signs with a collection of ECDSA keys. Each key is weighted, so that the signature will pass as long as enough signers with enough weight have signed. +The weighted ECDSA (multisig) signer signs with a collection of ECDSA keys. Each key is weighted, so that the signature will pass as long as enough signers with enough weight have signed. Read [the multisig doc](/sdk/v5_3_x/advanced/multisig) for more details. diff --git a/docs/pages/sdk/v5_3_x/permissions/signers/passkeys.mdx b/docs/pages/sdk/v5_3_x/permissions/signers/passkeys.mdx index ea404d2..e123935 100644 --- a/docs/pages/sdk/v5_3_x/permissions/signers/passkeys.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/signers/passkeys.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../../VersionWarning" -# WebAuthn Signer +# WebAuthn signer -The WebAuthn (passkeys) signer signs with a single passkey. Read [the passkeys doc](/sdk/v5_3_x/advanced/passkeys) for a more detailed intro to passkeys. +The WebAuthn (passkeys) signer signs with a single passkey. Read [the passkeys doc](/sdk/v5_3_x/advanced/passkeys) for a more detailed intro to passkeys. ## API @@ -40,5 +40,5 @@ const validator = toPermissionValidator(publicClient, { For the params: - `passkeyName` can be any name -- `passkeyServerUrl` is a [passkey server URL](/sdk/v5_3_x/advanced/passkeys#setting-up-passkey-server). You can get it from the ZeroDev dashboard. +- `passkeyServerUrl` is a [passkey server URL](/sdk/v5_3_x/advanced/passkeys#setting-up-passkey-server). You can get it from the ZeroDev dashboard. - `mode` is either `register` or `login`, depending on whether you are creating a new key or using an existing key. \ No newline at end of file diff --git a/docs/pages/sdk/v5_3_x/permissions/transaction-automation.mdx b/docs/pages/sdk/v5_3_x/permissions/transaction-automation.mdx index b8dacae..ca5ce98 100644 --- a/docs/pages/sdk/v5_3_x/permissions/transaction-automation.mdx +++ b/docs/pages/sdk/v5_3_x/permissions/transaction-automation.mdx @@ -2,15 +2,15 @@ import VersionWarning from "../VersionWarning" -# Tutorial -- Transaction Automation +# Tutorial: Transaction automation -In this tutorial, you will learn how to automate transactions for your users using [session keys](/sdk/v5_3_x/permissions/intro). This is useful when you want to send transactions for your users from your server, for instance. +In this tutorial, you will learn how to automate transactions for your users using [session keys](/sdk/v5_3_x/permissions/intro). This is useful when you want to send transactions for your users from your server, for instance. -Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/transaction-automation.ts) while you follow along the tutorial. You can run the example by following instructions of [the examples repo](https://github.com/zerodevapp/zerodev-examples). +Refer to [this code example](https://github.com/zerodevapp/zerodev-examples/blob/main/session-keys/transaction-automation.ts) while you follow along with the tutorial. You can run the example by following the instructions in [the examples repo](https://github.com/zerodevapp/zerodev-examples). ## Installation -Session keys are enabled through the `@zerodev/permissions` package. The examples repo already installed this, but normally you would install permissions with: +Session keys are enabled through the `@zerodev/permissions` package. The examples repo already installed this, but normally you would install permissions with: :::code-group @@ -32,28 +32,28 @@ bun add @zerodev/permissions ::: -## The Architecture of Transaction Automation +## The Architecture of transaction automation -In the typical architecture for transaction automation, there's an "owner" and an "agent": +In the typical architecture for transaction automation, there's an "owner," and an "agent": - The "owner" is the entity that controls the user's master key. - The "agent" is the entity that automates transactions for the owner. -For instance, your user might be using an embedded wallet (master key) with your frontend, and you might want to automate transactions for your users from your server. In this case, the frontend would be the "owner" and your server would be the "agent." +For instance, your user might be using an embedded wallet (master key) with your frontend, and you might want to automate transactions for your users from your server. In this case, the frontend would be the "owner" and your server would be the "agent." From a high level, this is how transaction automation works: - The agent creates a session key. - At this point, the session key has not been approved by the owner. -- The agent sends the "address" of the session key to the owner for approval. +- * The agent sends the session key's “address” to the owner for approval. - The owner signs the address and returns the approval (signature) to the agent. - The agent can now send transactions for users using the approval and the session key. -## Code Flow +## Code flow ### Agent: creating a session key -From the agent's side, create a [ECDSA signer](/sdk/v5_3_x/permissions/signers/ecdsa) as the session key: +From the agent's side, create an [ECDSA signer](/sdk/v5_3_x/permissions/signers/ecdsa) as the session key: ```ts const sessionPrivateKey = generatePrivateKey() @@ -78,7 +78,7 @@ const sessionKeySigner = toECDSASigner({ ### Agent: send session key "address" to the owner -For the owner to approve the session key, the agent must send the "address" of the session key to the owner. Note that the private key is never sent -- it's only the address which is the public key of the session key that's sent. +For the owner to approve the session key, the agent must send the session key's “address” to the owner. Note that the private key is never sent—it’s only the address, which is the public key of the session key that’s sent. To obtain the session key address: @@ -127,9 +127,9 @@ const approval = await serializePermissionAccount(sessionKeyAccount) Now, send the serialized approval back to the agent. -### Agent: using the session key +### Agent: Using the session key -When the agent wants to use the session key, first recreate the signer. Presumably, you would've stored the session key somewhere: +When the agent wants to use the session key, first recreate the signer. Presumably, you would've stored the session key somewhere: ```ts // Using a stored private key @@ -176,9 +176,9 @@ const kernelClient = createKernelAccountClient({ Now you can send transactions with the Kernel client. -### Revoking a Session Key +### Revoking a session key -After a session key has been used, or if it's no longer needed, it's a good security practice to revoke it to ensure it cannot be used for any further transactions. Here's how you can revoke a session key: +After a session key has been used or is no longer needed, it’s a good security practice to revoke it to prevent it from being used for any further transactions. Here’s how you can revoke a session key: First, prepare your environment for the revocation process. This involves creating a "sudo" account capable of performing privileged operations, such as uninstalling plugins. @@ -196,7 +196,7 @@ const sudoKernelClient = createKernelAccountClient({ }) ``` -Now to revoke the session key by uninstalling its associated permission plugin, call `uninstallPlugin` on `sudoKernelClient`. +Now, to revoke the session key by uninstalling its associated permission plugin, call `uninstallPlugin` on `sudoKernelClient`. ```ts const txHash = await sudoKernelClient.uninstallPlugin({ diff --git a/docs/pages/sdk/v5_3_x/presets/intro.mdx b/docs/pages/sdk/v5_3_x/presets/intro.mdx index dd1e5ba..c2484b7 100644 --- a/docs/pages/sdk/v5_3_x/presets/intro.mdx +++ b/docs/pages/sdk/v5_3_x/presets/intro.mdx @@ -4,9 +4,9 @@ import VersionWarning from "../VersionWarning" # Presets -ZeroDev is highly modular and composable thanks to building on top of Viem and Permissionless, but sometimes it can feel like you are writing a lot of boilerplate code before you can set up a functional Kernel account. **Presets** are helper functions that help you set up Kernel accounts with common configurations, including connections to bundlers and paymasters. +ZeroDev is highly modular and composable because it builds on Viem and Permissionless. Still, sometimes it can feel like you are writing a lot of boilerplate code before you can set up a functional Kernel account. **Presets** are helper functions that help you set up Kernel accounts with common configurations, including connections to bundlers and paymasters. -Generally speaking, there will be a preset for each `` pair. For example, the `` preset will create a ECDSA Kernel account using ZeroDev's infrastructure. +Generally speaking, there will be a preset for each `` pair. For example, the `` preset creates an ECDSA Kernel account using ZeroDev’s infrastructure. Click the links below to see presets for different infra providers: diff --git a/docs/pages/sdk/v5_3_x/presets/zerodev.mdx b/docs/pages/sdk/v5_3_x/presets/zerodev.mdx index d3ccccb..5cf1e0d 100644 --- a/docs/pages/sdk/v5_3_x/presets/zerodev.mdx +++ b/docs/pages/sdk/v5_3_x/presets/zerodev.mdx @@ -2,9 +2,9 @@ import VersionWarning from "../VersionWarning" -# ZeroDev Presets +# ZeroDev presets -## ECDSA Validator +## ECDSA validator To set up a Kernel account using ECDSA for validation (mimicking EOAs): @@ -29,10 +29,10 @@ const kernelClient = await createEcdsaKernelAccountClient({ - `projectId` is a ZeroDev project ID from the [ZeroDev dashboard](https://dashboard.zerodev.app/). - `signer` is a [Viem account](https://viem.sh/docs/accounts/local.html). - (optional) `provider` can be [any provider that ZeroDev supports](/meta-infra/intro). -- (optional) `index` can be any positive integer. Different indexes will yield different accounts. +- (optional) `index` can be any positive integer. Different indices will yield different accounts. - (optional) `paymaster` can be: - `'NONE'`: not using any paymaster (the user pays their own gas). - `'SPONSOR'` (default): sponsor gas for users according to [gas policies](/meta-infra/gas-policies). - - A ERC20 token address: use the specified ERC20 token as gas tokens. See the [ERC20 gas token docs](/sdk/v5_3_x/core-api/pay-gas-with-erc20s) for details. + - An `ERC-20` token address: use the specified `ERC-20` token as gas tokens. See the [`ERC-20` gas token docs](/sdk/v5_3_x/core-api/pay-gas-with-erc20s) for details. -is a boolean flag that determines whether ZeroDev will use [the sponsoring paymaster](/meta-infra/intro). +It is a boolean flag that determines whether ZeroDev will use [the sponsoring paymaster](/meta-infra/intro). diff --git a/docs/pages/sdk/v5_3_x/signers/arcana.mdx b/docs/pages/sdk/v5_3_x/signers/arcana.mdx index a6ed743..f8a7012 100644 --- a/docs/pages/sdk/v5_3_x/signers/arcana.mdx +++ b/docs/pages/sdk/v5_3_x/signers/arcana.mdx @@ -4,7 +4,7 @@ import VersionWarning from "../VersionWarning" # Use Arcana Auth with ZeroDev -[Arcana Auth](https://www.arcana.network/) offers a self-custodial Web3 wallet embedded within applications, utilizing asynchronous distributed key generation algorithms for enhanced security and privacy. This wallet, accessible without the need for a browser extension, allows authenticated users to instantly access and sign blockchain transactions within the app environment. +[Arcana Auth](https://www.arcana.network/) offers a self-custodial Web3 wallet embedded in applications, leveraging asynchronous distributed key-generation algorithms for enhanced security and privacy. This wallet, accessible without a browser extension, allows authenticated users to sign blockchain transactions within the app instantly. ## Set up @@ -14,10 +14,12 @@ To use Arcana Auth with ZeroDev, first create an application that integrates wit - For a quick start, Arcana Auth provides a web app guide, available [here](https://docs.arcana.network/quick-start/web/). ## Integration -Integrating ZeroDev with Arcana Auth is straightforward after setting up the project. Arcana Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. -### Create the authProvider object -After following the Arcana Auth documentation, you will have access to a `authProvider` object as shown below: +Integrating ZeroDev with Arcana Auth is straightforward once the project is set up. Arcana Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +### Create the `authProvider` object + +After following the Arcana Auth documentation, you will have access to an `authProvider` object as shown below: ```typescript import { @@ -32,7 +34,7 @@ const authProvider = new AuthProvider(clientId, params); ### Use with ZeroDev -Use the provider from Arcana to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). +Use the Arcana provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/capsule.mdx b/docs/pages/sdk/v5_3_x/signers/capsule.mdx index 3f05cae..476bcd2 100644 --- a/docs/pages/sdk/v5_3_x/signers/capsule.mdx +++ b/docs/pages/sdk/v5_3_x/signers/capsule.mdx @@ -16,12 +16,15 @@ To use Capsule with ZeroDev, first create an application that integrates with Ca ## Integration :::info + Check out [this example](https://github.com/zerodevapp/zerodev-signer-examples/tree/main/capsule) for custom integration with Capsule. + ::: -Integrating ZeroDev with Capsule is straightforward after setting up the project. Capsule provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. +Integrating ZeroDev with Capsule is straightforward once the project is set up. Capsule provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Capsule object + After following the Capsule documentation, you will have access to a `CapsuleWeb3Provider` object as shown below: ```typescript diff --git a/docs/pages/sdk/v5_3_x/signers/custom-signer.mdx b/docs/pages/sdk/v5_3_x/signers/custom-signer.mdx index 975b376..f6aa7dd 100644 --- a/docs/pages/sdk/v5_3_x/signers/custom-signer.mdx +++ b/docs/pages/sdk/v5_3_x/signers/custom-signer.mdx @@ -2,16 +2,18 @@ import VersionWarning from "../VersionWarning" -# Custom Signer Integration +# Custom Signer integration + ZeroDev offers the flexibility to integrate various types of signers, catering to diverse application requirements. ## Using Externally Owned Accounts (EOAs) -Most commonly used signers are Externally Owned Accounts (EOAs). If you're using a signer that falls under this category and isn't explicitly covered in our documentation, we recommend visiting our dedicated [EOA integration section](/sdk/v5_3_x/signers/eoa). This section provides detailed guidance on integrating EOAs with ZeroDev. -## Implementing Custom Signers +Most commonly used signers are Externally Owned Accounts (EOAs). If you’re using a signer in this category and it isn’t explicitly covered in our documentation, we recommend visiting our dedicated [EOA integration section](/sdk/v5_3_x/signers/eoa). This section provides detailed guidance on integrating EOAs with ZeroDev. + +## Implementing custom signers -If your requirements extend beyond standard EOAs, ZeroDev supports the integration of custom signers. Our signers conform to the `SmartAccountSigner` interface defined in permissionless.js. For developers looking to implement a custom solution, you can reference the `SmartAccountSigner` interface on their [GitHub repository](https://github.com/pimlicolabs/permissionless.js/blob/0b1cf0086b3fa131415a6a9bf398852c159fc181/packages/permissionless/accounts/types.ts#L60). This interface provides the necessary structure and guidelines to ensure compatibility with ZeroDev. +If your requirements extend beyond standard EOAs, ZeroDev supports integrating custom signers. Our signers conform to the `SmartAccountSigner` interface defined in permissionless.js. For developers looking to implement a custom solution, you can reference the `SmartAccountSigner` interface on their [GitHub repository](https://github.com/pimlicolabs/permissionless.js/blob/0b1cf0086b3fa131415a6a9bf398852c159fc181/packages/permissionless/accounts/types.ts#L60). This interface provides the necessary structure and guidelines to ensure compatibility with ZeroDev. -One easy way to implement a `SmartAccountSigner` is to implement Viem's account type, [by following this guide](https://viem.sh/docs/accounts/custom). +One easy way to implement a `SmartAccountSigner` is to implement Viem's account type [by following this guide](https://viem.sh/docs/accounts/custom). Once you've implemented the signer, you should be able to [use it with a validator](/sdk/v5_3_x/core-api/create-account#creating-a-ecdsa-validator). diff --git a/docs/pages/sdk/v5_3_x/signers/dfns.mdx b/docs/pages/sdk/v5_3_x/signers/dfns.mdx index a3234fe..d7f69b7 100644 --- a/docs/pages/sdk/v5_3_x/signers/dfns.mdx +++ b/docs/pages/sdk/v5_3_x/signers/dfns.mdx @@ -4,7 +4,7 @@ import VersionWarning from "../VersionWarning" # Use Dfns with ZeroDev -[Dfns](https://www.dfns.co/) is an MPC/TSS Wallet-as-a-Service API/SDK provider. Dfns aims to optimize the balance of security and UX by deploying key shares into a decentralized network on the backend while enabling wallet access via biometric open standards on the frontend like Webauthn. Reach out [here](https://www.dfns.co/learn-more) to set up a sandbox environment to get started. +[Dfns](https://www.dfns.co/) is an MPC/TSS Wallet-as-a-Service API/SDK provider. Dfns aims to optimize the balance between security and UX by deploying key shares to a decentralized network on the backend while enabling wallet access via biometric open standards on the frontend, such as WebAuthn. Reach out [here](https://www.dfns.co/learn-more) to set up a sandbox environment to get started. ## Set up @@ -13,9 +13,11 @@ To use Dfns with ZeroDev, first create an application that integrates with Dfns. - Refer to the [Dfns documentation site](https://docs.dfns.co/d/) for instructions on setting up an application with the Dfns. ## Integration -Integrating ZeroDev with Dfns is straightforward after setting up the project. Dfns provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Dfns is straightforward once the project is set up. Dfns provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Set up Dfns + After following the Dfns documentation, you will have access to a `dfnsWallet` object as shown below: ```typescript diff --git a/docs/pages/sdk/v5_3_x/signers/dynamic.mdx b/docs/pages/sdk/v5_3_x/signers/dynamic.mdx index 620c61c..a3d0703 100644 --- a/docs/pages/sdk/v5_3_x/signers/dynamic.mdx +++ b/docs/pages/sdk/v5_3_x/signers/dynamic.mdx @@ -10,23 +10,28 @@ import VersionWarning from "../VersionWarning" To use Dynamic with ZeroDev, you have two options: Dynamic's native integration that utilizes ZeroDev, or a custom integration using Dynamic's Externally Owned Account (EOA) as a signer. Choose the approach that best fits your needs. -### Native Integration +### Native integration -Dynamic natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, utilize session keys. -- For more information and how to get started, visit the [Dynamic Account Abstraction documentation](https://docs.dynamic.xyz/smart-wallets/smart-wallet-providers/zerodev). +Dynamic natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, and utilize session keys. +- For more information on how to get started, visit the [Dynamic Account Abstraction documentation](https://docs.dynamic.xyz/smart-wallets/smart-wallet-providers/zerodev). + +### Custom integration + +If you would like to use ZeroDev directly with a Dynamics project, you can set up a custom integration using Dynamics' EOA as a signer. -### Custom Integration -If you would like to use ZeroDev directly with a Dynamic project, you can set up a custom integration using Dynamics's EOA as a signer. - Begin by setting up your application with Dynamic, as detailed in the [Dynamic documentation](https://docs.dynamic.xyz/introduction/welcome). - Dynamic also offers a quick start guide and sample apps, available [here](https://docs.dynamic.xyz/quickstart). -## Implementing Custom Integration +## Implementing custom integration + Integrating ZeroDev with Dynamic is straightforward once your application is set up. Dynamic provides an EOA wallet to use as a signer with Kernel. -### Get the Dynamic wallet's Provider +### Get the dynamic wallet's provider + To begin, ensure your application is integrated with Dynamic. Detailed guidance is available in the [Dynamic documentation](https://docs.dynamic.xyz/). The following example demonstrates the use of Dynamic's React Core SDK. Ensure your React app is already configured with Dynamic; for setup instructions, refer to the [tutorial](https://docs.dynamic.xyz/react-sdk/tutorial). + ```typescript import { useDynamicContext } from "@dynamic-labs/sdk-react-core"; @@ -67,6 +72,6 @@ const ecdsaValidator = await signerToEcdsaValidator(publicClient, { // You can now use this ECDSA Validator to create a Kernel account ``` -## Starter Template +## Starter template A user has helpfully created a [starter template for Dynamic + ZeroDev](https://github.com/tantodefi/se2-dynamic-zerodev). diff --git a/docs/pages/sdk/v5_3_x/signers/eoa.mdx b/docs/pages/sdk/v5_3_x/signers/eoa.mdx index ab74ec1..eb7ca97 100644 --- a/docs/pages/sdk/v5_3_x/signers/eoa.mdx +++ b/docs/pages/sdk/v5_3_x/signers/eoa.mdx @@ -4,12 +4,14 @@ import VersionWarning from "../VersionWarning" # Use an EOA with ZeroDev -An Externally Owned Account (EOA) is a standard Ethereum account operated via a private key. It's commonly used in wallets like MetaMask. ZeroDev is compatible with EOAs as signers, and the method of integrating an EOA varies based on your dApp's connection approach. +An Externally Owned Account (EOA) is a standard Ethereum account operated via a private key. It’s commonly used in wallets like MetaMask. ZeroDev supports EOAs as signers, and the integration method varies depending on your dApp’s connection approach. -## Integration Methods -We'll explore three methods to integrate a signer with ZeroDev: using an EIP-1193 provider, using a viem WalletClient, and employing a Local Account. +## Integration methods + +We'll explore three methods to integrate a signer with ZeroDev: using an EIP-1193 provider, using a Viem WalletClient, and employing a Local Account. ### EIP-1193 Provider Integration + EIP-1193 is a standard interface for Ethereum providers, such as MetaMask or hardware wallets, where the key material is hosted externally rather than on the local client. ZeroDev supports creating a signer from any provider that implements this interface. ```typescript @@ -38,10 +40,12 @@ const ecdsaValidator = await signerToEcdsaValidator(publicClient, { // You can now use this ECDSA Validator to create a Kernel account ``` -### Viem Wallet Client Integration -A [Wallet Client](https://viem.sh/docs/clients/wallet.html) is an interface to interact with Ethereum Account(s) and provides the ability to retrieve accounts, execute transactions, sign messages, etc through Wallet Actions. +### Viem wallet client intergration + +A [Wallet Client](https://viem.sh/docs/clients/wallet.html) is an interface for interacting with Ethereum Account(s) and provides the ability to retrieve accounts, execute transactions, sign messages, etc., through Wallet Actions. In this example, we assume that you have access to a WalletClient object. + ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" import { KERNEL_V3_1 } from "@zerodev/sdk/constants" @@ -65,8 +69,9 @@ const ecdsaValidator = await signerToEcdsaValidator(publicClient, { // You can now use this ECDSA Validator to create a Kernel account ``` -### Local Account -A Local Account refers to an EOA where the private key is directly accessible on the client. In this example we assume you have access to the private key locally. +### Local account + +A Local Account is an EOA whose private key is directly accessible on the client. In this example we assume you have access to the private key locally. ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/fireblocks.mdx b/docs/pages/sdk/v5_3_x/signers/fireblocks.mdx index 1435381..94f9b1f 100644 --- a/docs/pages/sdk/v5_3_x/signers/fireblocks.mdx +++ b/docs/pages/sdk/v5_3_x/signers/fireblocks.mdx @@ -10,13 +10,15 @@ import VersionWarning from "../VersionWarning" To use Fireblocks with ZeroDev, first create an application that integrates with Fireblocks. -- Refer to the [Fireblocks documentation site](https://developers.fireblocks.com/) for instructions on setting up an application with the Fireblocks. +- Refer to the [Fireblocks documentation site](https://developers.fireblocks.com/) for instructions on setting up an application with Fireblocks. - For a quick start, Fireblocks provides a guide, available [here](https://developers.fireblocks.com/docs/quickstart). ## Integration -Integrating ZeroDev with Fireblocks is straightforward after setting up the project. Fireblocks provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Fireblocks is straightforward once the project is set up. Fireblocks provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Fireblocks object + After following the Fireblocks documentation, you will have access to a `FireblocksWeb3Provider` object as shown below: ```typescript @@ -29,7 +31,7 @@ const fireblocksWeb3Provider = new FireblocksWeb3Provider(fireblocksProviderConf ### Use with ZeroDev -Use the provider from Fireblocks to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). +Use the Fireblocks provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/intro.mdx b/docs/pages/sdk/v5_3_x/signers/intro.mdx index be6cd6b..8170f9c 100644 --- a/docs/pages/sdk/v5_3_x/signers/intro.mdx +++ b/docs/pages/sdk/v5_3_x/signers/intro.mdx @@ -2,12 +2,12 @@ import VersionWarning from "../VersionWarning" -# Auth Providers +# Auth providers -Smart accounts, like EOAs, rely on signatures to validate transactions and messages. The difference with smart accounts is that it can use arbitrary signatures schemes, such as multisig, passkeys, etc. +Smart accounts, like EOAs, rely on signatures to validate transactions and messages. The difference with smart accounts is that they can use arbitrary signature schemes, such as multisig and passkeys. -It's possible to use third-party "wallet services" as signers for smart accounts. The end result is that your users will be interacting with the wallet UIs provided by these services, while using a smart account powered by ZeroDev. +It’s possible to use third-party “wallet services” as signers for smart accounts. As a result, your users will interact with the wallet UIs provided by these services while using a smart account powered by ZeroDev. -ZeroDev has been integrated natively with many leading wallet services such as [Privy](https://docs.privy.io/guide/frontend/account-abstraction/zerodev), [Dynamic](https://docs.dynamic.xyz/account-abstraction/aa-providers/zerodev), [Portal](https://docs.portalhq.io/resources/account-abstraction-alpha), [JoyID](https://docs.joyid.dev/guide/evm/evm-aa), etc. However, even when a native integration doesn't exist, it's generally very easy to integrate ZeroDev with a wallet service as long as it's able to sign messages. +ZeroDev has been integrated natively with many leading wallet services, including [Privy](https://docs.privy.io/guide/frontend/account-abstraction/zerodev), [Dynamic](https://docs.dynamic.xyz/account-abstraction/aa-providers/zerodev), [Portal](https://docs.portalhq.io/resources/account-abstraction-alpha), and [JoyID](https://docs.joyid.dev/guide/evm/evm-aa). However, even when a native integration doesn’t exist, it’s generally very easy to integrate ZeroDev with a wallet service as long as it’s able to sign messages. -Check out the wallet services that are known to work with ZeroDev using the left sidebar. If the wallet service you want to use is not listed, check out the general guide for [integrating with EOA signers](/sdk/v5_3_x/signers/eoa), or try [building your own integration](/sdk/v5_3_x/signers/custom-signer). +Check out the wallet services known to work with ZeroDev in the left sidebar. If the wallet service you want to use is not listed, check out the general guide for [integrating with EOA signers](/sdk/v5_3_x/signers/eoa), or try [building your own integration](/sdk/v5_3_x/signers/custom-signer). diff --git a/docs/pages/sdk/v5_3_x/signers/lit-protocol.mdx b/docs/pages/sdk/v5_3_x/signers/lit-protocol.mdx index ae330d4..7486712 100644 --- a/docs/pages/sdk/v5_3_x/signers/lit-protocol.mdx +++ b/docs/pages/sdk/v5_3_x/signers/lit-protocol.mdx @@ -4,19 +4,21 @@ import VersionWarning from "../VersionWarning" # Use Lit Protocol with ZeroDev -[Lit Protocol](https://www.litprotocol.com/) is distributed cryptography for signing, encryption, and compute. A generalizable key management network, Lit provides you with a set of tools for managing sovereign identities on the open Web. +[Lit Protocol](https://www.litprotocol.com/) is a distributed cryptographic protocol for signing, encryption, and computation. A generalizable key management network, Lit provides you with a set of tools for managing sovereign identities on the open Web. ## Set up To use Lit with ZeroDev, first create an application that integrates with Lit. -- Refer to the [Lit documentation site](https://developer.litprotocol.com/v3/) for instructions on setting up an application with the Lit. -- For a quick start, Lit provides examples, available [here](https://docs.Lit.com/getting-started/examples). +- Refer to the [Lit documentation site](https://developer.litprotocol.com/v3/) for instructions on setting up an application with Lit. +- For a quick start, Lit provides examples available [here](https://docs.Lit.com/getting-started/examples). ## Integration -Integrating ZeroDev with Lit is straightforward after setting up the project. Lit provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Lit is straightforward once the project is set up. Lit provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the pkpWallet + After following the Lit documentation, you will have access to a `pkpWallet`. An example is shown below: ```typescript @@ -79,7 +81,7 @@ const pkpWallet = new PKPEthersWallet({ ### Use with ZeroDev -Use the provider from Lit Protocol to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). +Use the Lit Protocol provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/magic.mdx b/docs/pages/sdk/v5_3_x/signers/magic.mdx index 27edf8a..4fdd82e 100644 --- a/docs/pages/sdk/v5_3_x/signers/magic.mdx +++ b/docs/pages/sdk/v5_3_x/signers/magic.mdx @@ -4,7 +4,7 @@ import VersionWarning from "../VersionWarning" # Use Magic with ZeroDev -[Magic](https://magic.link/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp in order to pay for gas, which introduces significant friction. +[Magic](https://magic.link/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp to pay for gas, which introduces significant friction. By combining ZeroDev with Magic, you can use Magic to enable a smooth social login experience, while using ZeroDev as the smart wallet to sponsor gas for users, batch transactions, and more. @@ -23,7 +23,7 @@ To use Magic with ZeroDev, first create an application that integrates with Magi Check out [this example](https://github.com/zerodevapp/zerodev-signer-examples/tree/main/magic) for custom integration with Magic. ::: -Integrating ZeroDev with Magic is straightforward after setting up the Magic SDK. Magic provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. +Integrating ZeroDev with Magic is straightforward once the Magic SDK is set up. Magic provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Magic object @@ -43,7 +43,7 @@ const magic = new MagicBase(process.env.MAGIC_API_KEY as string, { ### Use with ZeroDev -Use the provider from Magic to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). +Use the Magic provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/particle.mdx b/docs/pages/sdk/v5_3_x/signers/particle.mdx index a14e085..65942ac 100644 --- a/docs/pages/sdk/v5_3_x/signers/particle.mdx +++ b/docs/pages/sdk/v5_3_x/signers/particle.mdx @@ -4,7 +4,7 @@ import VersionWarning from "../VersionWarning" # Use Particle Network with ZeroDev -[Particle Network](https://particle.network/) is an intent-centric, modular wallet-as-a-service (WaaS). By utilizing MPC-TSS for key management, Particle can streamline onboarding via familiar Web2 methods such as Google, emails, and phone numbers. +[Particle Network](https://particle.network/) is an intent-centric, modular wallet-as-a-service (WaaS). By using MPC-TSS for key management, Particle can streamline onboarding using familiar Web2 methods such as Google, email, and phone numbers. By combining ZeroDev with Particle, you can use Particle to enable a smooth social login experience, while using ZeroDev as the smart wallet to sponsor gas for users, batch transactions, and more. @@ -16,9 +16,11 @@ To use Particle Network with ZeroDev, first create an application that integrate - For a quick start, Particle Network provides a guide, available [here](https://docs.particle.network/getting-started/get-started). ## Integration -Integrating ZeroDev with Particle Network is straightforward after setting up the project. Particle Network provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Particle Network is straightforward once the project is set up. Particle Network provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Particle Network object + After following the Particle Network documentation, you will have access to a `ParticleProvider` object as shown below: ```typescript @@ -38,7 +40,7 @@ const particleProvider = new ParticleProvider(particle.auth) ### Use with ZeroDev -Use the provider from Particle Network to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). +Use the Particle Network provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/portal.mdx b/docs/pages/sdk/v5_3_x/signers/portal.mdx index df6e382..37505bc 100644 --- a/docs/pages/sdk/v5_3_x/signers/portal.mdx +++ b/docs/pages/sdk/v5_3_x/signers/portal.mdx @@ -4,25 +4,31 @@ import VersionWarning from "../VersionWarning" # Use Portal with ZeroDev -[Portal](https://www.portalhq.io/) is an embedded blockchain infrastructure company that powers companies with an end to end platform for key management for self-custodial wallets (MPC and AA), security firewall, and web3 protocol connect kit. +[Portal](https://www.portalhq.io/) is an embedded blockchain infrastructure company that powers companies with an end-to-end platform for key management for self-custodial wallets (MPC and AA), a security firewall, and a Web3 protocol connect kit. ## Set up To use Portal with ZeroDev, you have two options: Portal's native integration using ZeroDev, or a custom integration using Portal's Externally Owned Account (EOA) as a signer for ZeroDev. Choose the approach that best fits your needs. -### Native Integration +### Native integration + Portal natively supports account abstraction using ZeroDev. This integration allows your organization to sponsor gas fees for your clients using specific policies and chains, with additional features coming soon. -- For more information, visit the [Portal Account Abstraction documentation](https://docs.portalhq.io/resources/account-abstraction-alpha) -### Custom Integration +- For more information, visit the [Portal Account Abstraction documentation](https://docs.portalhq.io/resources/account-abstraction-alpha). + +### Custom integration + If you require ZeroDev functionality not yet supported natively by Portal, a custom integration using Portal's EOA as a signer might be preferable. + - Begin by setting up your application with Portal, as detailed in the [Portal documentation](https://docs.portalhq.io/). -- Portal also offers a quick start guide for their web SDK, available [here](https://docs.portalhq.io/sdk/web). +- Portal also offers a quick-start guide for its web SDK, available [here](https://docs.portalhq.io/sdk/web). + +## Implementing custom integration -## Implementing Custom Integration Integrating ZeroDev with Portal is straightforward once your application is set up. Portal provides an EOA wallet to use as a signer with Kernel. ### Create the Portal object + After following the Portal documentation, you will have access to a `Portal` object as shown below: ```typescript @@ -35,7 +41,7 @@ const portal = new Portal(portalOptions); ### Use with ZeroDev -Use the provider from Portal to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). +Use the provider from the Portal to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/privy.mdx b/docs/pages/sdk/v5_3_x/signers/privy.mdx index ac16d66..3932ee3 100644 --- a/docs/pages/sdk/v5_3_x/signers/privy.mdx +++ b/docs/pages/sdk/v5_3_x/signers/privy.mdx @@ -4,33 +4,40 @@ import VersionWarning from "../VersionWarning" # Use Privy with ZeroDev -[Privy](https://privy.io/) offers a seamless user onboarding experience for both mobile and desktop platforms, accommodating users with or without existing wallets. It simplifies the process of setting up self-custodial wallets for users logging in via email, SMS, or social media accounts. Additionally, it provides flexibility for web3-savvy users to continue using their existing wallets with your application, offering them a choice based on their preference. +[Privy](https://privy.io/) offers a seamless user onboarding experience for both mobile and desktop platforms, accommodating users with or without existing wallets. It simplifies the process of setting up self-custodial wallets for users logging in via email, SMS, or social media accounts. Additionally, it provides web3-savvy users with the flexibility to continue using their existing wallets with your application, offering them a choice based on their preferences. ## Set up To use Privy with ZeroDev, you have two options: Privy's native integration that utilizes ZeroDev, or a custom integration using Privy's Externally Owned Account (EOA) as a signer. Choose the approach that best fits your needs. -### Native Integration -Privy natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, utilize session keys. -- For more information and how to get started, visit the Privy's [Account Abstraction with ZeroDev documentation](https://docs.privy.io/guide/frontend/account-abstraction/zerodev). +### Native integration -### Custom Integration +Privy natively supports account abstraction using ZeroDev. This integration allows you to sponsor gas fees, bundle transactions, recover and transfer accounts, and utilize session keys. + +- For more information on how to get started, visit the Privy's [Account Abstraction with ZeroDev documentation](https://docs.privy.io/guide/frontend/account-abstraction/zerodev). + +### Custom integration :::info + Check out [this example](https://github.com/zerodevapp/zerodev-signer-examples/tree/main/privy) for custom integration with Privy. + ::: -If you would like to use ZeroDev directly with a Privy project, you can set up a custom integration using Privys's EOA as a signer. +If you would like to use ZeroDev directly with a Privy project, you can set up a custom integration using Privy's EOA as a signer. + - Begin by setting up your application with Privy, as detailed in the [Privy documentation](https://docs.privy.io/). - Privy also offers a quick start guide, available [here](https://docs.privy.io/guide/quickstart). -## Implementing Custom Integration +## Implementing custom integration + Integrating ZeroDev with Privy is straightforward once your application is set up. Privy provides an EOA wallet to use as a signer with Kernel. -### Get the Privy wallet's Provider -To begin, ensure your application is integrated with Privy. Detailed guidance is available in the [Privy documentation](https://docs.privy.io/guide/quickstart). You should also configure your PrivyProvider to create embedded wallets for your users when they login. +### Get the Privy wallet's provider + +To begin, ensure your application is integrated with Privy. Detailed guidance is available in the [Privy documentation](https://docs.privy.io/guide/quickstart). You should also configure your PrivyProvider to create embedded wallets for your users when they log in. -The following example demonstrates the use of Privy's react auth SDK to get the embedded wallet and use it as a signer for ZeroDev. +The following example demonstrates using Privy’s React Auth SDK to retrieve the embedded wallet and use it as a signer for ZeroDev. ```typescript import { useWallets } from "@privy-io/react-auth"; @@ -49,7 +56,7 @@ const privyProvider = await embeddedWallet.getEthereumProvider(); ### Use with ZeroDev -Use the provider from Privy to create a smart account signer, which can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). +Use the Privy provider to create a smart account signer that can be passed to a validator. For detailed guidance on using a validator, refer to our documentation on [creating accounts](/sdk/v5_3_x/core-api/create-account#api). ```typescript import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator" diff --git a/docs/pages/sdk/v5_3_x/signers/turnkey.mdx b/docs/pages/sdk/v5_3_x/signers/turnkey.mdx index 50d1b33..053933c 100644 --- a/docs/pages/sdk/v5_3_x/signers/turnkey.mdx +++ b/docs/pages/sdk/v5_3_x/signers/turnkey.mdx @@ -6,19 +6,21 @@ import VersionWarning from "../VersionWarning" [Turnkey](https://turnkey.com/) is a key infrastructure provider with a great developer API and a powerful security policy engine. -By combining ZeroDev with Turnkey, you can create **custodial AA wallets** whose security is provided by Turnkey, with powerful functionalities such as sponsoring gas, batching transactions, etc. +By combining ZeroDev with Turnkey, you can create **custodial AA wallets** whose security is provided by Turnkey, with powerful features such as sponsoring gas and batching transactions. ## Set up To use Turnkey with ZeroDev, first create an application that integrates with Turnkey. - Refer to the [Turnkey documentation site](https://docs.turnkey.com/) for instructions on setting up an application with the Turnkey. -- For a quick start, Turnkey provides examples, available [here](https://docs.turnkey.com/getting-started/examples). +- For a quick start, Turnkey provides examples available [here](https://docs.turnkey.com/getting-started/examples). ## Integration -Integrating ZeroDev with Turnkey is straightforward after setting up the project. Turnkey provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. -### Create the TurnkeyClient and a Turnkey viem account +Integrating ZeroDev with Turnkey is straightforward once the project is set up. Turnkey provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +### Create the TurnkeyClient and a Turnkey Viem account + After following the Turnkey documentation, you will have access to a `TurnkeyClient`. An example is shown below: ```typescript diff --git a/docs/pages/sdk/v5_3_x/signers/web3auth.mdx b/docs/pages/sdk/v5_3_x/signers/web3auth.mdx index 09f6842..4e8e26d 100644 --- a/docs/pages/sdk/v5_3_x/signers/web3auth.mdx +++ b/docs/pages/sdk/v5_3_x/signers/web3auth.mdx @@ -4,7 +4,7 @@ import VersionWarning from "../VersionWarning" # Use Web3Auth with ZeroDev -[Web3Auth](https://web3auth.io/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp in order to pay for gas, which introduces significant friction. +[Web3Auth](https://web3auth.io/) is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp to pay for gas, which introduces significant friction. By combining ZeroDev with Web3Auth, you can use Web3Auth to enable a smooth social login experience, while using ZeroDev as the smart wallet to sponsor gas for users, batch transactions, and more. @@ -12,13 +12,15 @@ By combining ZeroDev with Web3Auth, you can use Web3Auth to enable a smooth soci To use Web3Auth with ZeroDev, first create an application that integrates with Web3Auth. -- Refer to the [Web3Auth documentation site](https://web3auth.io/docs/index.html) for instructions on setting up an application with the Web3Auth. +- Refer to the [Web3Auth documentation site](https://web3auth.io/docs/index.html) for instructions on setting up an application with Web3Auth. - For a quick start, Web3Auth provides example starter projects, available [here](https://web3auth.io/docs/examples?product=Plug+and+Play&sdk=Plug+and+Play+Web+Modal+SDK). ## Integration -Integrating ZeroDev with Web3Auth is straightforward after setting up the project. Web3Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. + +Integrating ZeroDev with Web3Auth is straightforward once the project is set up. Web3Auth provides an Externally Owned Account (EOA) wallet to use as a signer with Kernel. ### Create the Web3Auth object + After following the Web3Auth documentation, you will have access to a `web3auth` object as shown below: ```typescript diff --git a/docs/pages/shared/mutation-result.mdx b/docs/pages/shared/mutation-result.mdx index 31a08e1..dfd10d4 100644 --- a/docs/pages/shared/mutation-result.mdx +++ b/docs/pages/shared/mutation-result.mdx @@ -3,7 +3,7 @@ `Error | null` -The error object for the mutation, if an error was encountered. +The mutation's error object, if an error occurred. ### isError / isIdle / isPending / isSuccess @@ -16,7 +16,7 @@ Boolean variables derived from [`status`](#status). `boolean` - will be `true` if the mutation has been `paused`. -- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. +- Refer to [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. ### status @@ -31,4 +31,4 @@ Boolean variables derived from [`status`](#status). `() => void` -A function to clean the mutation internal state (e.g. it resets the mutation to its initial state). +A function to clean the mutation internal state (e.g., it resets the mutation to its initial state). diff --git a/docs/pages/shared/query-result.mdx b/docs/pages/shared/query-result.mdx index cb45157..cc19a19 100644 --- a/docs/pages/shared/query-result.mdx +++ b/docs/pages/shared/query-result.mdx @@ -2,7 +2,7 @@ `Error | null` -- The error object for the query, if an error was thrown. +- The error object for the query, if an error is thrown. - Defaults to `null` ### isError / isPending / isSuccess @@ -14,22 +14,22 @@ Boolean variables derived from [`status`](#status). `boolean` -Will be `true` if the query has been fetched. +It will be `true` if the query has been fetched. ### isLoading `boolean` -- Is `true` whenever the first fetch for a query is in-flight +- It is `true` whenever the first fetch for a query is in-flight - Is the same as `isFetching && isPending` ### status `'error' | 'pending' | 'success'` -- `pending` if there's no cached data and no query attempt was finished yet. -- `error` if the query attempt resulted in an error. The corresponding `error` property has the error received from the attempted fetch -- `success` if the query has received a response with no errors and is ready to display its data. The corresponding `data` property on the query is the data received from the successful fetch or if the query's `enabled` property is set to `false` and has not been fetched yet `data` is the first `initialData` supplied to the query on initialization. +- `pending` if there’s no cached data and no query attempt is finished yet. +- `error` if the query attempt resulted in an error. The corresponding `error` property has the error received from the attempted fetch. +- `success` if the query has received a response with no errors and is ready to display its data. The corresponding `data` property on the query is the data returned by the successful fetch, or, if the query's `enabled` property is set to `false` and has not been fetched yet, `data` is the `initialData` supplied to the query on initialization. ### refetch @@ -37,9 +37,9 @@ Will be `true` if the query has been fetched. - A function to manually refetch the query. - `throwOnError` - - When set to `true`, an error will be thrown if the query fails. + - When set to `true`, an error gets thrown if the query fails. - When set to `false`, an error will be logged if the query fails. - `cancelRefetch` - - When set to `true`, a currently running request will be cancelled before a new request is made. - - When set to `false`, no refetch will be made if there is already a request running. + - When set to `true`, if an active request is running, it will be canceled before a new request is made. + - When set to `false`, no refetch will be performed if a request is already running. - Defaults to `true` diff --git a/docs/pages/shared/social-login-setup.mdx b/docs/pages/shared/social-login-setup.mdx index b52c14c..35af184 100644 --- a/docs/pages/shared/social-login-setup.mdx +++ b/docs/pages/shared/social-login-setup.mdx @@ -2,7 +2,7 @@ ZeroDev offers two modes for setting up social login: Development and Production - **Development Mode**: - Available to all users by default. - - Functions only when your application is running locally on the `localhost` URI. + - Functions only when your application is running locally at `localhost` - Ideal for testing social sign-in features during development. - **Production Mode**: @@ -15,7 +15,7 @@ ZeroDev offers two modes for setting up social login: Development and Production **Production Mode Configuration Steps**: 1. Enter the client ID and client secret from your social provider into the designated fields in the ZeroDev dashboard. 2. Copy the redirect URI provided by ZeroDev into your social provider’s dashboard. -3. Ensure that the redirect URI and whitelist URI for your application are input correctly in the form. +3. Ensure that the redirect and whitelist URIs for your application are entered correctly in the form. 4. Submit the form for review. -For detailed information on how Magic handles the creation of public/private key pairs, integral to the security of the social login process, please refer to [Magic's product security documentation.](https://magic.link/docs/home/security/product-security) +For detailed information on how Magic creates public/private key pairs, which are integral to the security of the social login process, please refer to [Magic's product security documentation.](https://magic.link/docs/home/security/product-security) diff --git a/docs/pages/smart-routing-address/index.mdx b/docs/pages/smart-routing-address/index.mdx index 284e99d..9e99114 100644 --- a/docs/pages/smart-routing-address/index.mdx +++ b/docs/pages/smart-routing-address/index.mdx @@ -1,19 +1,19 @@ # Smart Routing Address -**Smart Routing Address** enables users to easily deposit funds from any source—CEX, fiat onramp, or any chain—to any destination chain, simply by sending funds to a unique deposit address. +**Smart Routing Address** enables users to easily deposit funds from any source—CEX, a fiat onramp, or any chain—to any destination chain by sending funds to a unique deposit address. -Technically, **Smart Routing Address** is an address that encodes a _cross-chain intent_. **When someone sends funds to a smart routing address on _any chain_, they are funding the intent and thereby triggering the intent on a _specific destination chain_.** In other words, Smart Routing Address is _source-chain agnostic_, but _destination-chain specific_. +Technically, a **Smart Routing Address** is an address that encodes a *cross-chain intent*. **When someone sends funds to a Smart Routing Address on *any chain*, they are funding the intent and thereby triggering the intent on a *specific destination chain***. In other words, Smart Routing Address is source-chain-agnostic but destination-chain-specific. -## Common Use Cases +## Common use cases - Sending funds from any CEX directly to any chain - Using a fiat onramp with any chain, even if the onramp doesn't directly support that chain - Depositing into a token vault on one chain using funds from another - Cross-chain transfers -## Try Smart Routing Address +## Try a Smart Routing Address -You can try using Smart Routing Address at [the official portal](https://smart-routing-address.zerodev.app/). +You can use a Smart Routing Address at [the official portal](https://smart-routing-address.zerodev.app/). Should your users send the wrong tokens to their smart routing address, they can also use the portal to retrieve their funds. @@ -43,13 +43,13 @@ bun add @zerodev/smart-routing-address Smart Routing Address has a beautifully simple API: just `createSmartRoutingAddress` and then send funds to it. That's really it. -### Code Example +### Code example We recommend that you take a look at [our code example](https://github.com/zerodevapp/smart-routing-address-example) (even better if you try running it) as you follow along the docs. -### Creating a smart routing address +### Creating a Smart Routing Address -In the following example, we are going to create a smart routing address that, when receiving funds on any chain, will transfer the funds to a specific address on Base. This is helpful when, for instance, you want to create a deposit address for your user, so that they can send funds to the address on any chain (possibly from a CEX), and then they will receive funds in their wallet on the chain that your app runs on. +In the following example, we will create a smart routing address that, when receiving funds on any chain, transfers them to a specific address on Base. This is helpful when, for instance, you want to create a deposit address for your user so they can send funds to the address on any chain (possibly from a CEX), and then receive them in their wallet on the chain your app runs on. First import some types and functions: @@ -113,25 +113,25 @@ const { smartRoutingAddress } = await createSmartRoutingAddress({ The options are: -- `owner` is an address that is authorized to recover funds from the smart routing address, in case the smart routing address fails to execute the target action for whatever reason. Typically you would set this to your user's EOA wallet, but you could also set it to your own address if you want to recover funds for users. +- `owner` is an address authorized to recover funds from the smart routing address if the smart routing address fails to execute the target action for any reason. Typically, you would set this to your user’s EOA wallet, but you could also set it to your own address if you want to recover funds for users. - `destChain` is the chain on which the `actions` are supposed to happen. This is presumably the chain that your app runs on. -- `srcTokens` is a list of tokens that the smart routing address should be able to receive. Only tokens listed in `srcTokens` will trigger actions on the destination. The other tokens sent to the address will have to be manually recovered by the `owner`. +- `srcTokens` is a list of tokens that the smart routing address can receive. Only tokens listed in srcTokens will trigger actions on the destination. The other tokens sent to the address will have to be manually recovered by the `owner`. - `actions` is a map that records which action will be triggered by which token. In the example above, we specified an action that will be triggered when the smart routing address receives `USDC`. -- `slippage` is the _maximum_ slippage that the user can expect. `slippage` is an integer, where 1 is equal to 0.01% (so 100 would mean 1% slippage). You can skip this param if you are unsure what to set, and the SDK will estimate a reasonable slippage based on your other settings. +- `slippage` is the *maximum* slippage that the user can expect. `slippage` is an integer, where 1 is equal to 0.01% (so 100 would mean 1% slippage). You can skip this parameter if you are unsure what to set, and the SDK will estimate a reasonable slippage based on your other settings. Once you have created a smart routing address, you can send tokens to it on any of the chains specified in `srcTokens`, and the `actions` will happen on the `destChain`. It's really that simple. -## Fee Sponsorship +## Fee sponsorship By default, Smart Routing Address deducts usage fees from the user's transferred tokens. However, as a developer, you can sponsor these fees so your users receive the full amount they deposit. **Example**: When a user deposits 10 USDC to their smart routing address, they will receive exactly 10 USDC on the destination chain, while your dapp pays the usage fees separately. -### Sponsored Fee Configuration +### Sponsored fee configuration To set up fee sponsorship, you must perform two steps: diff --git a/docs/pages/smart-wallet/account-recovery.mdx b/docs/pages/smart-wallet/account-recovery.mdx index 59ff017..64039e7 100644 --- a/docs/pages/smart-wallet/account-recovery.mdx +++ b/docs/pages/smart-wallet/account-recovery.mdx @@ -1,26 +1,28 @@ -# Account Recovery +# Account recovery -With ZeroDev's [permissions system](/smart-wallet/permissions/intro), it's possible to set up a guardian (or multiple guardians) for a smart account, so that if the owner loses their key, the guardian(s) can recover the key for the owner. +With ZeroDev's [permissions system](/smart-wallet/permissions/intro), it's possible to set up a guardian (or multiple guardians) for a smart account, so that if the owner loses their key, the guardian(s) can recover it. There are two typical types of recovery: -- **Self-recovery**: your user can set up recovery for their account with another auth factor they own, such as a passkey or another wallet they own. +- **Self-recovery**: your user can set up recovery for their account using another authentication factor they own, such as a passkey or another wallet. -- **DApp-assisted recovery**: your user might set you (the DApp) as their guardian. When they lose their account, they would contact you and you would recover the account for them. +- **DApp-assisted recovery**: your user might set you (the DApp) as their guardian. When they lose their account, they would contact you, and you would recover the account for them. -There are two ways to use recovery: through a pre-built recovery flow or build a totally custom flow using the Kernel recovery plugin. +There are two ways to use recovery: through a pre-built recovery flow or by building a fully custom flow using the Kernel recovery plugin. ## Core API :::info + Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/tree/main/guardians/recovery.ts). + ::: Here we go through the process of using the recovery plugin: ### Setting up the guardian validator -Start by creating a permissions validator. Let's say you want a single key to be your guardian: +Start by creating a permissions validator. Let's say you want a single key to be your guardian: ```ts const guardianSigner = privateKeyToAccount(GUARDIAN_KEY) @@ -34,9 +36,9 @@ const guardianValidator = await signerToEcdsaValidator(publicClient, { If you want multiple guardians, set up a [multisig validator](/sdk/advanced/multisig) instead. -### Setting up account with the recovery action +### Setting up an account with the recovery action -We have deployed a simple recovery executor that can recover any accounts using [the ECDSA validator](/sdk/permissions/signers/ecdsa). You can set it up with the following values: +We have deployed a simple recovery executor that can recover any accounts using [the ECDSA validator](/sdk/permissions/signers/ecdsa). You can set it up with the following values: ```ts import { toFunctionSelector } from "viem" @@ -63,11 +65,11 @@ const account = await createKernelAccount(publicClient, { }) ``` -you only need to set the sudo validator if you are enabling the guardian validator, i.e. that it's the first time you are using the guardian. +You only need to set the sudo validator if you are enabling the guardian validator, i.e., that it's the first time you are using the guardian. ### Executing recovery -After you [construct the account client from the account](/sdk/core-api/create-account#create-an-account-client), you can execute recovery as such: +After you [construct the account client from the account](/sdk/core-api/create-account#create-an-account-client), you can execute recovery as follows: ```ts import { encodeFunctionData } from "viem" @@ -84,9 +86,9 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -### Using account with the new owner +### Using the account with the new owner -After you update the account owner, the account address can no longer by computed from the new owner. Therefore, you should use the `address` option to manually set the account address when you [create the account object](/sdk/core-api/create-account#create-a-kernel-account). For example: +After you update the account owner, the account address can no longer be computed from the new owner. Therefore, you should use the `address` option to manually set the account address when you [create the account object](/sdk/core-api/create-account#create-a-kernel-account). For example: ```ts const account = await createKernelAccount(publicClient, { @@ -96,6 +98,8 @@ const account = await createKernelAccount(publicClient, { }) ``` + \ No newline at end of file diff --git a/docs/pages/smart-wallet/batching-transactions.mdx b/docs/pages/smart-wallet/batching-transactions.mdx index f5f0f59..b4a9953 100644 --- a/docs/pages/smart-wallet/batching-transactions.mdx +++ b/docs/pages/smart-wallet/batching-transactions.mdx @@ -1,23 +1,23 @@ # Batching -Smart accounts support *batching* transactions -- rolling multiple transactions into one. This is very useful for simplifying Web3 interactions for your users. For instance, instead of doing `approve()` followed by `transfer()`, your user can do both in one transaction. +Smart accounts support transaction **batching**—combining multiple transactions into a single transaction. This is very useful for simplifying Web3 interactions for your users. For instance, instead of calling `approve()` followed by `transfer()`, your user can do both in a single transaction Batching transactions has a number of important benefits: - Your user waits for only 1 transaction instead of multiple. -- Your user pays less gas. +- Your user pays for less gas. - If any transaction in the batch reverts, the entire batch reverts. This ensures that your user won't be stuck in an inconsistent state. - This is known as "atomicity." ## Capabilities API -Thanks to [the new capabilities standard](/smart-wallet/quickstart-capabilities), you can batch transactions in a standard way regardless of the smart wallet implementation. +Thanks to [the new capabilities standard](/smart-wallet/quickstart-capabilities), you can batch transactions consistently regardless of the smart wallet implementation. -To batch transactions, simply use the `wallet_sendCalls` API. We will be using [Wagmi](https://wagmi.sh/react/api/hooks/useSendCalls) here but you can find the same API in [Viem](https://viem.sh/experimental/eip5792/sendCalls): +To batch transactions, use the wallet_sendCalls API. We will be using [Wagmi](https://wagmi.sh/react/api/hooks/useSendCalls) here, but you can find the same API in [Viem](https://viem.sh/experimental/eip5792/sendCalls): ## React API -Simply pass an array of transactions (UserOps) when using the `useSendUserOperation` hook: +Pass an array of transactions (UserOps) when using the `useSendUserOperation` hook: ```tsx import { useSendUserOperation, useKernelClient } from '@zerodev/waas' @@ -50,10 +50,12 @@ function App() { ## Core API :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/batch-transactions). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/batch-transactions). + ::: -There are two ways to send batched transactions. `sendTransaction` is a simple API that's good enough for most use cases. If you need fine-grained control over your UserOp, you can use `sendUserOperation`. +There are two ways to send batched transactions. `sendTransaction` is a simple API that's good enough for most use cases. If you need fine-grained control over your UserOp, you can use `sendUserOperation`. ### `sendTransaction` @@ -78,7 +80,7 @@ const txHash = await kernelClient.sendTransaction({ You can learn more about the `sendUserOperation` API [here](/sdk/core-api/send-transactions#sending-raw-userops). -To send a UserOp with batching, simply pass an array of calls into `encodeCalls`. +To send a UserOp with batching, pass an array of calls into `encodeCalls`. ```typescript const userOpHash = await kernelClient.sendUserOperation({ diff --git a/docs/pages/smart-wallet/code-examples.mdx b/docs/pages/smart-wallet/code-examples.mdx index c87e6da..99bf98c 100644 --- a/docs/pages/smart-wallet/code-examples.mdx +++ b/docs/pages/smart-wallet/code-examples.mdx @@ -1,6 +1,6 @@ -# Code Examples +# Code examples -ZeroDev has extensive code examples that you can run. They are the best way to learn how to use ZeroDev. +ZeroDev has extensive code examples that you can run. They are the best way to learn how to use ZeroDev. Check out the examples here: diff --git a/docs/pages/smart-wallet/creating-wallets.mdx b/docs/pages/smart-wallet/creating-wallets.mdx index 73e7415..f4a9881 100644 --- a/docs/pages/smart-wallet/creating-wallets.mdx +++ b/docs/pages/smart-wallet/creating-wallets.mdx @@ -5,18 +5,20 @@ import SocialLoginSetup from '../shared/social-login-setup.mdx' ZeroDev supports three types of wallet creation: - Passkeys - - ZeroDev supports on-chain passkeys, where transactions are signed directly with passkeys on your user's device, and the signatures are validated on-chain with either [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) (if supported by the network) or smart contracts, without reliance on centralized infrastructure. [Learn more here](/sdk/advanced/passkeys). + - ZeroDev supports onchain passkeys, where transactions are signed directly with passkeys on your user's device, and the signatures are validated onchain with either [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) (if supported by the network) or smart contracts, without reliance on centralized infrastructure. [Learn more here](/sdk/advanced/passkeys). - Socials - - ZeroDev supports social logins natively, but you can also use ZeroDev with [third-party auth providers](/sdk/signers/intro) such as Dynamic, Privy, and Magic if your prefer their UI. + - ZeroDev supports social logins natively, but you can also use ZeroDev with [third-party auth providers](/sdk/signers/intro) such as Dynamic, Privy, and Magic if you prefer their UI. - EOA - - It's important to note that when a user signs in with an EOA (e.g. MetaMask) through ZeroDev, the EOA is not used as a wallet, but rather as the *signer* of the ZeroDev smart wallet. Therefore, the address of the smart wallet is different than the address of the user's EOA. + - It's important to note that when a user signs in with an EOA (e.g., MetaMask) via ZeroDev, the EOA is not used as a wallet but rather as the **signer** for the ZeroDev smart wallet. Therefore, the smart wallet's address differs from the user’s EOA address. ## Capabilities API -[Capabilities](/smart-wallet/quickstart-capabilities) (ERC-5792) are the new standard for DApps to communicate with smart wallets. If you are building a DApp and looking to use ZeroDev as an embedded smart wallet, we recommend that you do it through the capabilities API, in order to be compatible with other smart wallets. +[Capabilities](/smart-wallet/quickstart-capabilities) (ERC-5792) are the new standard for DApps to communicate with smart wallets. If you are building a DApp and want to use ZeroDev as an embedded smart wallet, we recommend using the capabilities API to ensure compatibility with other smart wallets. :::info + Check out this [code example](https://github.com/zerodevapp/capabilities-examples/tree/main/create-account). + ::: ### Passkeys @@ -59,21 +61,25 @@ function App() { } ``` + ## React API :::info + Check out this [code example](https://github.com/zerodevapp/waas-examples/tree/main/create-account). + ::: ### Passkeys -You can learn more about [how ZeroDev's on-chain passkeys work here](/sdk/advanced/passkeys). +You can learn more about [how ZeroDev's onchain passkeys work here](/sdk/advanced/passkeys). -Create the wallet using [`useCreateKernelClientPasskey`](/react/use-create-kernelclient-passkey). Use `connectRegister` to create a new passkey, or `connectLogin` to use an existing key. +Create the wallet using [`useCreateKernelClientPasskey`](/react/use-create-kernelclient-passkey). Use `connectRegister` to create a new passkey, or `connectLogin` to use an existing key. ```tsx import { useCreateKernelClientPasskey } from "@zerodev/waas" @@ -100,7 +106,7 @@ function App() { ### Socials -Use `useCreateKernelClientSocial`. Note that you can also use ZeroDev with a [third-party auth provider](/sdk/signers/intro) (e.g. Privy/Dynamic) to enable social logins. +Use `useCreateKernelClientSocial`. Note that you can also use ZeroDev with a [third-party auth provider](/sdk/signers/intro) (e.g., Privy/Dynamic) to enable social logins. ```tsx import { useCreateKernelClientSocial } from "@zerodev/waas" @@ -122,7 +128,7 @@ function App() { ### EOA -If you want to use an EOA wallet as signer to your ZeroDev smart wallet, wrap the `ZeroDevProvider` inside a Wagmi provider, then use [`useCreateKernelClientEOA`](/react/use-create-kernelclient-eoa). +If you want to use an EOA wallet as a signer to your ZeroDev smart wallet, wrap the `ZeroDevProvider` inside a Wagmi provider, then use [`useCreateKernelClientEOA`](/react/use-create-kernelclient-eoa). ```tsx import { useCreateKernelClientEOA } from "@zerodev/waas" diff --git a/docs/pages/smart-wallet/defi-integrations.md b/docs/pages/smart-wallet/defi-integrations.md index 0c774a2..79fdb45 100644 --- a/docs/pages/smart-wallet/defi-integrations.md +++ b/docs/pages/smart-wallet/defi-integrations.md @@ -1,20 +1,20 @@ -# DeFi Integrations +# DeFi integrations ZeroDev partners with [Enso](https://www.enso.finance/) to support seamless token swaps and DeFi integrations, even across chains. The API deals with two types of tokens: -- **Base tokens** are normal tokens that do not represent a DeFi position. Examples are ETH, USDC, etc. -- **DeFi tokens** are ERC20 tokens that represent a DeFi position, such as in a [ERC-4626 vault](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/). For example, depositing ETH into Lido gets you `stETH` that represents staked ETH. +- **Base tokens** are normal tokens that do not represent a DeFi position. Examples are `ETH`, `USDC`, etc. +- **DeFi tokens** are ERC20 tokens that represent a DeFi position, such as in an [ERC-4626 vault](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/)—for example, depositing `ETH` into Lido yields `stETH`, which represents staked `ETH`. By allowing you to swap between base tokens and DeFi tokens, you can easily: - Swap between any token pairs. - Entering and exiting DeFi positions (staking, lending, etc.) -ZeroDev leverages [batching](/sdk/core-api/batch-transactions) and [delegatecall](/sdk/core-api/delegatecall) internally to ensure that even complex routes are executed in one atomic UserOp, providing the user with low latency, low gas cost, and high safety. +ZeroDev leverages [batching](/sdk/core-api/batch-transactions) and [delegatecall](/sdk/core-api/delegatecall) internally to ensure that even complex routes are executed in a single atomic UserOp, providing the user with low latency, low gas costs, and high safety. -## Supported Tokens +## Supported tokens See the full lists of supported base tokens and DeFi tokens: @@ -46,7 +46,9 @@ bun add @zerodev/defi ## Core API :::info + Check out [these code examples](https://github.com/zerodevapp/zerodev-examples/tree/main/defi). + ::: ### Creating a DeFi client @@ -64,9 +66,9 @@ Where: - `kernelClient` is the [account client](/sdk/core-api/create-account#create-an-account-client) object. - `projectId` is your ZeroDev project ID, obtained from the dashboard. -### Swapping Tokens +### Swapping tokens -Suppose you want to swap 100 USDC to USDT: +Suppose you want to swap 100 `USDC` to `USDT`: ```ts import { baseTokenAddresses } from "@zerodev/defi" @@ -89,16 +91,16 @@ const userOpHash = await defiClient.sendSwapUserOp({ Where: - `fromToken` is the input token. -- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g. Wei for Ether. +- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g., Wei for `ETH`. - `toToken` is the output token. - `toAddress`: defaults to the account's own address. If specified, it will send the output token to that address instead. - `gasToken`: [see below.](#gas-tokens) ### Entering / Exiting DeFi positions -Entering a DeFi position simply means swapping a token into a DeFi token. +Entering a DeFi position means swapping a token for a DeFi token. -You can get a DeFi token address through the `defiTokenAddresses` constant, which is a map with three keys: `chainId => tokenName => protocolName`. For example, the DeFi token representing the USDC vault on AAVE v3 on Arbitrum would be `defiTokenAddresses[arbitrum.id]['USDC']['aave-v3']`. So, to enter the vault: +You can get a DeFi token address through the `defiTokenAddresses` constant, which is a map with three keys: `chainId => tokenName => protocolName`. For example, the DeFi token representing the `USDC` vault on AAVE v3 on Arbitrum would be `defiTokenAddresses[arbitrum.id]['USDC']['aave-v3']`. So, to enter the vault: ```ts import { defiTokenAddresses } from "@zerodev/defi" @@ -116,11 +118,11 @@ const userOpHash = await defiClient.sendSwapUserOp({ }) ``` -Similarly, exiting a DeFi position is just swapping a DeFi token into another token. +Similarly, exiting a DeFi position is just swapping a DeFi token for another token. -### Cross-chain Swaps +### Cross-chain swaps -To swap tokens across chains, use `sendSwapUserOpCrossChain`. For example, to swap USDC on Arbitrum to DAI on Polygon: +To swap tokens across chains, use `sendSwapUserOpCrossChain`. For example, to swap `USDC` on Arbitrum to DAI on Polygon: ```ts // Convert mainnet DAI to USDC, and lend it through AAVE on Arbitrum @@ -139,7 +141,7 @@ const userOpHash = await defiClient.sendSwapUserOpCrossChain({ Where: - `fromToken` is the input token. -- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g. Wei for Ether. +- `fromAmount` is a `bigint` representing the input token amount. Note that this uses the smallest unit for the token, e.g., Wei for `ETH`. - `toToken` is the output token. - `toChainId`: the chain for `toToken`, - `toAddress`: defaults to the account's own address. If specified, it will send the output token to that address instead. @@ -147,7 +149,7 @@ Where: ### Listing Tokens -You can list all ERC20 tokens an account owns with the `listTokenBalances` function: +You can list all `ERC-20` tokens an account owns with the `listTokenBalances` function: ```ts const accountBalances = await defiClient.listTokenBalances({ @@ -156,31 +158,33 @@ const accountBalances = await defiClient.listTokenBalances({ }) ``` -### Gas Tokens +### Gas tokens -The `gasToken` flag specifies how gas is paid for the UserOp. It can be one of the following values: +The `gasToken` flag specifies how gas is paid for the UserOp. It can be one of the following values: - `sponsored`: sponsor the UserOp. -- `fromToken`: pays gas in the input token, using a [ERC20 paymaster](/sdk/core-api/pay-gas-with-erc20s). -- `toToken`: pays gas in the output token, using a [ERC20 paymaster](/sdk/core-api/pay-gas-with-erc20s). +- `fromToken`: pays gas on the input token using an [`ERC-20` paymaster](/sdk/core-api/pay-gas-with-erc20s). +- `toToken`: pays gas in the output token, using an [`ERC-20` paymaster](/sdk/core-api/pay-gas-with-erc20s). - `native`: pays gas in the native token, using the account's balance. -- You can also specify an `Address` for a ERC20 token, to pay gas with that token using a [ERC20 paymaster](/sdk/core-api/pay-gas-with-erc20s). +- You can also specify an `Address` for an `ERC-20` token to pay gas with that token using an [`ERC-20` paymaster](/sdk/core-api/pay-gas-with-erc20s). ### Getting the UserOp without sending -If you want to just construct a UserOp but not send it immediately (perhaps because you want to show the user a gas estimate), use: +If you want to construct a UserOp but not send it immediately (perhaps because you want to show the user a gas estimate), use: - `getSwapUserOp` instead of `sendSwapUserOp` - `getSwapUserOpCrossChain` instead of `sendSwapUserOpCrossChain` -The functions above will get a signed UserOp but not sending it. If you want to get an unsigned UserOp, use: +The functions above will get a signed UserOp, but they will not send it. If you want to get an unsigned UserOp, use: - `getSwapData`, [like this](https://github.com/zerodevapp/zerodev-examples/blob/8cd83fd5e588a11414d1eb946622eda864e2b044/defi/get-swap-data.ts#L67-L84). -If you want to get regular transaction data instead of UserOps (presumably because you want to send the transaction through a EOA), use: +If you want to get regular transaction data instead of UserOps (presumably because you want to send the transaction through an EOA), use: - `getSwapUserOpCrossChain` + \ No newline at end of file diff --git a/docs/pages/smart-wallet/delegatecall.mdx b/docs/pages/smart-wallet/delegatecall.mdx index 7f81950..f040069 100644 --- a/docs/pages/smart-wallet/delegatecall.mdx +++ b/docs/pages/smart-wallet/delegatecall.mdx @@ -1,20 +1,22 @@ # Delegatecall :::warning -`delegatecall` is very dangerous. Unless you know exactly what you are doing, don't do it, or you might risk losing all your funds. + +`delegatecall` is very dangerous. Unless you know exactly what you are doing, don't do it, or you might risk losing all your funds. + ::: -`delegatecall` is a powerful EVM opcode that allows the calling contract to execute code in another contract, while keeping the storage context. [You can read more about `delegatecall` here](https://solidity-by-example.org/delegatecall/). +`delegatecall` is a powerful EVM opcode that allows the calling contract to execute code in another contract, while keeping the storage context. [You can read more about `delegatecall` here](https://solidity-by-example.org/delegatecall/). ## Core API :::info -Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/delegatecall/main.ts). -::: +Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/delegatecall/main.ts). -To send a UserOp that uses `delegatecall`, simply specify the `callType` of the UserOp: +::: +To send a UserOp that uses `delegatecall`, specify the `callType` of the UserOp: ```typescript const userOpHash = await kernelClient.sendUserOperation({ @@ -26,6 +28,7 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` + \ No newline at end of file diff --git a/docs/pages/smart-wallet/importing-assets.md b/docs/pages/smart-wallet/importing-assets.md index e084106..59b5e2f 100644 --- a/docs/pages/smart-wallet/importing-assets.md +++ b/docs/pages/smart-wallet/importing-assets.md @@ -1,13 +1,13 @@ -# Importing Assets +# Importing assets -Generally there are two ways to get assets into the smart wallet: +Generally, there are two ways to get assets into the smart wallet: - Fiat onramp - Importing assets from another wallet -ZeroDev works with any fiat onramp solution -- you simply specify the smart wallet address as the destination address. +ZeroDev works with any fiat onramp solution—you specify the smart wallet address as the destination address. -In this doc, we describe how to use ZeroDev's routing function to help users transfer their assets from another wallet (presumably an EOA) into the smart account. We support both same-chain and cross-chain transfers. +In this doc, we describe how to use ZeroDev's routing function to help users transfer their assets from another wallet (presumably an EOA) into the smart account. We support both same-chain and cross-chain transfers. ## Installation :::code-group @@ -108,9 +108,9 @@ function App() { ## Core API -### Same Chain +### Same chain -Refer to the [page](/smart-wallet/creating-wallets#creating-wallets) for instructions on how to construct a kernel client. +Refer to the [page](/smart-wallet/creating-wallets#creating-wallets) for instructions on building a kernel client. ```ts import { createWalletClient, http } from 'viem' @@ -145,7 +145,7 @@ await walletClient.sendTransaction({ ``` -### Cross Chain +### Cross chain Please see the [example](#same-chain-1) above for guidance on skipping imports and constructing wallets. diff --git a/docs/pages/smart-wallet/infra-fallbacks.mdx b/docs/pages/smart-wallet/infra-fallbacks.mdx index 5c05df2..3cda84b 100644 --- a/docs/pages/smart-wallet/infra-fallbacks.mdx +++ b/docs/pages/smart-wallet/infra-fallbacks.mdx @@ -1,12 +1,14 @@ -# Infra Fallbacks +# Infra fallbacks :::info -Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/fallback-clients/main.ts). + +Impatient? Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/fallback-clients/main.ts). + ::: -ZeroDev offers a "[meta infrastructure](/meta-infra/intro)" that integrates with all leading AA infra providers. When you use ZeroDev, you can pick [a specific infrastructure provider](/meta-infra/rpcs#bundler-rpc). If you don't pick one, we pick one for you. +ZeroDev offers a "[meta infrastructure](/meta-infra/intro)" that integrates with all leading AA infra providers. When you use ZeroDev, you can pick [a specific infrastructure provider](/meta-infra/rpcs#bundler-rpc). If you don't pick one, we pick one for you. -However, sometimes an infra provider may experience downtime. We have developed a "fallbacks" feature that allows you to set up multiple providers, so that when one fails, another takes over. +However, sometimes an infra provider may experience downtime. We have developed a "fallbacks" feature that allows you to set up multiple providers, so that when one fails, another takes over. ## Core API @@ -67,11 +69,11 @@ const kernelClient = createFallbackKernelAccountClient([ ]) ``` -Now you can use `kernelClient` as usual. Your `kernelClient` will use `kernelClient1` by default, and if it runs into any issues with it, it will fallback to `kernelClient2`. +Now you can use `kernelClient` as usual. Your `kernelClient` will use `kernelClient1` by default, and if it runs into any issues with it, it will fallback to `kernelClient2`. ### Using non-ZeroDev infra as fallbacks -In the previous example, we used different providers as fallbacks through ZeroDev. If you are worried that ZeroDev itself might go down, you can also sign up directly with providers like Pimlico and set them up as fallback providers. +In the previous example, we used different providers as fallbacks through ZeroDev. If you are worried that ZeroDev itself might go down, you can also sign up directly with providers like Pimlico and set them up as fallback providers. To do that, simply: @@ -86,6 +88,7 @@ const kernelClient = createFallbackKernelAccountClient([ ]) ``` + \ No newline at end of file diff --git a/docs/pages/smart-wallet/multisig.mdx b/docs/pages/smart-wallet/multisig.mdx index 8b03d54..862745a 100644 --- a/docs/pages/smart-wallet/multisig.mdx +++ b/docs/pages/smart-wallet/multisig.mdx @@ -1,10 +1,10 @@ # Multisig -With ZeroDev, it's possible to configure multiple signers for your smart account. The plugin that supports this functionality is named `WeightedECDSAValidator`, for the fact that it supports multiple ECDSA signers, each having a specific "weight." +With ZeroDev, it's possible to configure multiple signers for your smart account. The plugin that supports this functionality is named `WeightedECDSAValidator` because it supports multiple ECDSA signers, each with a specific “weight.” ## How it works -Each signer is set up with a **weight**, and for any given signature, there must be enough combined weight to reach or surpass the **threshold** for the signature to be considered valid. +Each signer is assigned a **weight**, and for any given signature, the combined weight must meet or exceed the **threshold** for the signature to be considered valid. For example, let's say we have: @@ -19,7 +19,9 @@ In this case, we are setting up a multisig where either signer A alone (100 = 10 ## Core API :::info + Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/multisig). + ::: ### Installation @@ -65,9 +67,9 @@ const multisigValidator = await createWeightedECDSAValidator(publicClient, { }) ``` -In `config`, you specify the `threshold` and an list of signer addresses, as well as their weights. +In `config`, you specify the `threshold`, a list of signer addresses, as well as their weights. -In `signers`, you specify the list of signers ([Viem accounts](https://viem.sh/docs/accounts/local)) that will be signing for this account. The combined weight of these signers must reach the threshold. +In `signers`, specify the list of signers ([Viem accounts](https://viem.sh/docs/accounts/local)) who will sign for this account. The combined weight of these signers must reach the threshold. After creating the validator, you can [set up a Kernel account using the validator](/sdk/core-api/create-account#create-a-kernel-account) as usual. @@ -94,7 +96,7 @@ const account = await createKernelAccount(publicClient, { ### Updating multisig config -In many use cases, you may need to add and remove signers over time. To do so, send a UserOp that updates the config: +In many use cases, you may need to add and remove signers over time. To do so, send a UserOp that updates the config: ```ts import { getUpdateConfigCall } from "@zerodev/weighted-ecdsa-validator" diff --git a/docs/pages/smart-wallet/one-click-trading.md b/docs/pages/smart-wallet/one-click-trading.md index b8f062f..7918f72 100644 --- a/docs/pages/smart-wallet/one-click-trading.md +++ b/docs/pages/smart-wallet/one-click-trading.md @@ -1,26 +1,28 @@ -# One-click Trading +# One-click trading -Signing every transaction gets annoying if you expect users to do frequent trades. The solution is "1-click trading" aka 1CT. +Signing every transaction can get annoying if you expect users to make frequent trades. The solution is “1-click trading” aka 1CT. -## How 1CT Works +## How 1CT works -The reason why transactions normally need to be confirmed is that each transaction has *unlimited permissions* -- any transaction can do anything. That's why the user needs to look at each transaction and confirm it. +The reason why transactions normally need to be confirmed is that each transaction has *unlimited permissions*—any transaction can do anything. That's why the user needs to look at each transaction and confirm it. -ZeroDev enables 1CT through *session keys*. Session keys are **temporary keys with limited permissions**. For example, you might create a session key that: +ZeroDev enables 1CT through *session keys*. Session keys are **temporary keys with limited permissions**. For example, you might create a session key that: - Lasts 24 hours. - Can only interact with Uniswap. -- Can only spend up to 100 USDC. +- Can only spend up to 100 `USDC`. -Since the session key cannot do *everything*, but rather only do specific things, there's no need for the user to confirm every transaction. The user would only confirm the *permissions* when the session key is created. +Since the session key cannot do everything, only specific things, there’s no need for the user to confirm every transaction. The user would only confirm the *permissions* when the session key is created. ## Capabilities API :::info + Check out [a complete code example here](https://github.com/zerodevapp/capabilities-examples/tree/main/session-keys). + ::: -With [the capabilities API](/smart-wallet/quickstart-capabilities), you can create a "session" with the wallet by requesting permissions. Then, transactions can be sent within those permissions, without asking the user for further confirmations. +With [the capabilities API](/smart-wallet/quickstart-capabilities), you can create a "session" with the wallet by requesting permissions. Then, transactions can be sent within those permissions, without asking the user for further confirmations. First, request permissions from the connected wallet using Viem: @@ -90,12 +92,14 @@ function App() { ## React API :::info + Check out [a complete code example here](https://github.com/zerodevapp/waas-examples/tree/main/session-keys). + ::: -### Creating Sessions +### Creating sessions -Use [the `useCreateSession` hook](/react/use-create-session) to create a session. When you create a session, ZeroDev generates a random session key and stores it in local storage. The key is then assigned with a list of policies. [Learn more about policies here.](/smart-wallet/permissions/intro) +Use [the `useCreateSession` hook](/react/use-create-session) to create a session. When you create a session, ZeroDev generates a random session key and stores it in local storage. The key is then assigned a list of policies. [Learn more about policies here.](/smart-wallet/permissions/intro) ```tsx import { useCreateSession } from '@zerodev/waas'; @@ -119,7 +123,7 @@ function App() { } ``` -### Using Sessions +### Using sessions Now, you can send transactions with [`useSendUserOperationWithSession`](/react/use-send-useroperation-with-session): @@ -145,7 +149,7 @@ function App() { } ``` -Sessions are automatically stored inside local storage, so they will persist even after your user closes their tab, until they expire due to policies. +Sessions are automatically stored in local storage, so they persist even after your user closes their tab until they expire due to policies. ## Core API diff --git a/docs/pages/smart-wallet/parallel-transactions.md b/docs/pages/smart-wallet/parallel-transactions.md index bc47fec..3da02e9 100644 --- a/docs/pages/smart-wallet/parallel-transactions.md +++ b/docs/pages/smart-wallet/parallel-transactions.md @@ -1,26 +1,26 @@ -# Parallel Transactions +# Parallel transactions -With a EOA, the nonce is sequential: 1, 2, 3, ... This means that transactions must be ordered sequentially, and a transaction cannot be processed unless a previous transaction was completed. +With an EOA, the nonce is sequential: 1, 2, 3,… This means that transactions get processed sequentially, and a transaction cannot be processed unless the previous transaction has completed. -With smart accounts, the nonce can be two-dimensional, which allows for *parallel UserOps*. Imagine that your user wants to place three trades: +With smart accounts, the nonce can be two-dimensional, enabling *parallel UserOps*. Imagine that your user wants to place three trades: -1. Swap 100 USDC to DAI -2. Swap 100 DAI to USDT -3. Swap 1WETH to USDT +1. Swap 100 `USDC` to `DAI` +2. Swap 100 `DAI` to `USDT` +3. Swap 1WETH to `USDT` -In this example, assuming the user did not have DAI to start with, the first two trades have dependencies, since the user needs to wait for the first trade to complete before they can do the second trade. However, the third trade doesn't depend on either of the first two trades, so it ought to be able to be placed in parallel. +In this example, assuming the user did not have DAI to start with, the first two trades are dependent, since the user needs to wait for the first trade to complete before they can do the second. However, the third trade doesn’t depend on either of the first two trades, so it ought to be able to be placed in parallel. -## How 2D Nonces Work +## How 2D nonces work -With a smart account, the nonce has two components: a "nonce key" and a "nonce value." +In a smart account, the nonce consists of two components: a “nonce key” and a “nonce value.” -UserOps with the same nonce key will be ordered sequentially. For example, by default all UserOps use the a nonce key of `0`, which is why by default all UserOps are ordered sequentially. +UserOps with the same nonce key will be ordered sequentially. For example, by default, all UserOps use a nonce key of `0`, which is why all UserOps are ordered sequentially. -To send UserOps in parallel, simply assign them with different nonce keys. +To send UserOps in parallel, assign each UserOps instance a different nonce key. ## React API -When sending UserOps with `useSendUserOperation` or `useSendUserOperationWithSession`, you can specify a `nonceKey` which is a string. +When sending UserOps with `useSendUserOperation` or `useSendUserOperationWithSession`, you can specify a `nonceKey`, which is a string. ```tsx import { useSendUserOperation, useKernelClient } from '@zerodev/waas' @@ -53,12 +53,14 @@ function App() { } ``` -UserOps with the same `nonceKey` will be ordered sequentially. UserOps with different `nonceKey`s will be ordered in parallel. All UserOps use a nonceKey of `0` by default. +UserOps with the same `nonceKey` will be ordered sequentially. UserOps with different `nonceKey`s will be ordered in parallel. All UserOps use a default nonceKey of `0`. ## Core API :::info + Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/send-transactions/with-2d-nonce.ts). + ::: To send parallel UserOps, use "nonce keys" to compute nonces: @@ -92,6 +94,6 @@ await kernelClient.sendUserOperation({ }) ``` -All UserOps using the same nonce key will be ordered sequentially. UserOps using different nonce keys will be parallel to each other. +All UserOps using the same nonce key will be ordered sequentially. UserOps using different nonce keys will run in parallel. -For example, if you want to order all UserOps that interact with Uniswap, and order all UserOps that interact with AAVE, but you want the Uniswap UserOps and the AAVE UserOps to be parallel to each other, you can use the string "Uniswap" and "AAVE" as the nonce keys for their UserOps respectively. \ No newline at end of file +For example, if you want to order all UserOps that interact with Uniswap, and order all UserOps that interact with AAVE, but you want the Uniswap UserOps and the AAVE UserOps to be parallel to each other, you can use the string "Uniswap" and "AAVE" as the nonce keys for their UserOps, respectively. \ No newline at end of file diff --git a/docs/pages/smart-wallet/pay-gas-in-erc20s.mdx b/docs/pages/smart-wallet/pay-gas-in-erc20s.mdx index ff6da7c..e8eb342 100644 --- a/docs/pages/smart-wallet/pay-gas-in-erc20s.mdx +++ b/docs/pages/smart-wallet/pay-gas-in-erc20s.mdx @@ -1,18 +1,20 @@ -# Paying Gas in ERC20s +# Paying gas in `ERC-20`s -A smart account can pay gas with ERC20 tokens. As a result, your users don't have to own any native gas tokens (e.g. ETH) in order to use Web3. Instead, they can just use stablecoins or even your project's own tokens. When your users pay gas with ERC20 tokens, we add 5% to the exchange rate to make a profit. +A smart account can pay for gas with `ERC-20` tokens. As a result, your users don’t need to own any native gas tokens (e.g., `ETH`) to use Web3. Instead, they can use stablecoins or even your project’s own tokens. When your users pay for gas with `ERC-20` tokens, we add a 5% markup to the exchange rate to make a profit. :::warning -Using your project's own tokens to pay for gas is a beta feature. If you are interested, please reach out. + +Using your project's own tokens to pay for gas is a beta feature. If you are interested, please reach out. + ::: -On a high level, you need to do two things to enable a smart account to pay gas in a particular ERC20 token: +On a high level, you need to do two things to enable a smart account to pay gas in a particular `ERC-20` token: -- Set up the Kernel client with the ERC20 paymaster. -- Ensure that enough ERC20 tokens have been approved for the ERC20 paymaster. - - This step is necessary because the ERC20 paymaster needs to withdraw ERC20 tokens from the smart account. +- Set up the Kernel client with the `ERC-20` paymaster. +- Ensure that enough `ERC-20` tokens have been approved for the `ERC-20` paymaster. + - This step is necessary because the `ERC-20` paymaster needs to withdraw `ERC-20` tokens from the smart account. -Let's go through these two steps next. We will be using mainnet USDC in the following examples, but you can use any of [these supported tokens](https://docs.pimlico.io/infra/paymaster/erc20-paymaster/supported-tokens) thanks to our integration with Pimlico. +Let’s go through these two steps next. We will use mainnet USDC in the following examples, but you can use any of the [supported tokens](https://docs.pimlico.io/infra/paymaster/erc20-paymaster/supported-tokens) thanks to our integration with Pimlico. ## React API @@ -70,10 +72,12 @@ function App() { ## Core API :::info + Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/tree/main/pay-gas-with-erc20). + ::: -### Setting up Kernel Client +### Setting up Kernel client When you [set up an account](/smart-wallet/creating-wallets#create-an-account-client), do this: @@ -104,9 +108,9 @@ const kernelClient = createKernelAccountClient({ }) ``` -### Approving ERC20 tokens for paymaster +### Approving `ERC-20` tokens for the paymaster -Use the `getERC20PaymasterApproveCall` function to construct a call that approves the paymaster with the ERC20 tokens: +Use the `getERC20PaymasterApproveCall` function to construct a call that approves the paymaster with the `ERC-20` tokens: ```typescript import { getERC20PaymasterApproveCall } from "@zerodev/sdk" @@ -141,11 +145,12 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -Note that you only have to approve once, as long as the approval amount is sufficient for many UserOps. The [paymaster contract by Pimlico](https://github.com/pimlicolabs/erc20-paymaster/blob/main/src/ERC20PaymasterV06.sol) has been audited, it's widely used and generally considered safe. -### Estimating Gas in ERC20s +Note that you only have to approve once, as long as the approval amount is sufficient for many UserOps. The [Pimlico paymaster contract](https://github.com/pimlicolabs/erc20-paymaster/blob/main/src/ERC20PaymasterV06.sol) has been audited; it’s widely used and generally considered safe. + +### Estimating Gas in `ERC-20`s' -If you need to estimate gas in terms of a ERC20 token, do this: +If you need to estimate gas in terms of a `ERC-20` token, do this: ```ts const userOperation = await kernelClient.prepareUserOperation({ @@ -167,6 +172,6 @@ const erc20Amount = await paymasterClient.estimateGasInERC20({ You can also see [a code example for estimating gas here](https://github.com/zerodevapp/zerodev-examples/blob/main/pay-gas-with-erc20/estimate-gas.ts). -## Supported Tokens +## Supported tokens We support [these tokens](https://docs.pimlico.io/infra/paymaster/erc20-paymaster/supported-tokens) thanks to our integration with Pimlico. diff --git a/docs/pages/smart-wallet/permissions/actions/build-your-own.mdx b/docs/pages/smart-wallet/permissions/actions/build-your-own.mdx index c3ebd31..f71166e 100644 --- a/docs/pages/smart-wallet/permissions/actions/build-your-own.mdx +++ b/docs/pages/smart-wallet/permissions/actions/build-your-own.mdx @@ -1,3 +1,3 @@ -# Build Your Own Action +# Build your own action Guide coming soon. \ No newline at end of file diff --git a/docs/pages/smart-wallet/permissions/policies/build-your-own.mdx b/docs/pages/smart-wallet/permissions/policies/build-your-own.mdx index 28d0b4c..81e6f72 100644 --- a/docs/pages/smart-wallet/permissions/policies/build-your-own.mdx +++ b/docs/pages/smart-wallet/permissions/policies/build-your-own.mdx @@ -1,3 +1,3 @@ -# Build Your Own Policy +# Build your own policy Guide coming soon. \ No newline at end of file diff --git a/docs/pages/smart-wallet/permissions/policies/call.mdx b/docs/pages/smart-wallet/permissions/policies/call.mdx index 6483449..10f3da8 100644 --- a/docs/pages/smart-wallet/permissions/policies/call.mdx +++ b/docs/pages/smart-wallet/permissions/policies/call.mdx @@ -1,4 +1,4 @@ -# Call Policy +# Call policy The call policy limits the target (either contract or EOA) that the UserOp can interact with. If the target is a contract, then you can further specify the functions the UserOp can interact with, as well as putting constraints on the values of the function arguments. diff --git a/docs/pages/smart-wallet/permissions/policies/gas.mdx b/docs/pages/smart-wallet/permissions/policies/gas.mdx index 1d29f3a..a163e53 100644 --- a/docs/pages/smart-wallet/permissions/policies/gas.mdx +++ b/docs/pages/smart-wallet/permissions/policies/gas.mdx @@ -1,4 +1,4 @@ -# Gas Policy +# Gas policy The gas policy specifies how much gas the signer can use in total, across all UserOps it sends. It can also enforce that the UserOps must use paymasters, or use a specific paymaster. diff --git a/docs/pages/smart-wallet/permissions/policies/rate-limit.mdx b/docs/pages/smart-wallet/permissions/policies/rate-limit.mdx index 3db9fb3..22e03ca 100644 --- a/docs/pages/smart-wallet/permissions/policies/rate-limit.mdx +++ b/docs/pages/smart-wallet/permissions/policies/rate-limit.mdx @@ -1,4 +1,4 @@ -# Rate Limit Policy +# Rate limit policy The rate limit policy specifies the frequency at which the signer is allowed to send UserOps. diff --git a/docs/pages/smart-wallet/permissions/policies/signature.mdx b/docs/pages/smart-wallet/permissions/policies/signature.mdx index d57a766..d19e9bd 100644 --- a/docs/pages/smart-wallet/permissions/policies/signature.mdx +++ b/docs/pages/smart-wallet/permissions/policies/signature.mdx @@ -1,4 +1,4 @@ -# Signature Caller Policy +# Signature caller policy The signature caller policy specifies a list of addresses that are allowed to validate messages signed by the signer. diff --git a/docs/pages/smart-wallet/permissions/policies/sudo.mdx b/docs/pages/smart-wallet/permissions/policies/sudo.mdx index 1a0f83d..3ed3f68 100644 --- a/docs/pages/smart-wallet/permissions/policies/sudo.mdx +++ b/docs/pages/smart-wallet/permissions/policies/sudo.mdx @@ -1,4 +1,4 @@ -# Sudo Policy +# Sudo policy The sudo policy gives full permission to the signer. The signer will be able to send any UserOps and sign any messages. diff --git a/docs/pages/smart-wallet/permissions/policies/timestamp.mdx b/docs/pages/smart-wallet/permissions/policies/timestamp.mdx index dbb3336..dc18f6d 100644 --- a/docs/pages/smart-wallet/permissions/policies/timestamp.mdx +++ b/docs/pages/smart-wallet/permissions/policies/timestamp.mdx @@ -1,4 +1,4 @@ -# Timestamp Policy +# Timestamp policy The timestamp policy specifies the start and end time for when the signer is valid. diff --git a/docs/pages/smart-wallet/permissions/signers/build-your-own.mdx b/docs/pages/smart-wallet/permissions/signers/build-your-own.mdx index 1d97718..9d8f7ff 100644 --- a/docs/pages/smart-wallet/permissions/signers/build-your-own.mdx +++ b/docs/pages/smart-wallet/permissions/signers/build-your-own.mdx @@ -1,3 +1,3 @@ -# Build Your Own Signer +# Build your own signer Guide coming soon. \ No newline at end of file diff --git a/docs/pages/smart-wallet/permissions/signers/ecdsa.mdx b/docs/pages/smart-wallet/permissions/signers/ecdsa.mdx index 939be06..5ddb6db 100644 --- a/docs/pages/smart-wallet/permissions/signers/ecdsa.mdx +++ b/docs/pages/smart-wallet/permissions/signers/ecdsa.mdx @@ -1,4 +1,4 @@ -# ECDSA Signer +# ECDSA signer The ECDSA signer signs with a single ECDSA key, specifically with the `secp256k1` curve, which is the same algorithm that EOAs use. diff --git a/docs/pages/smart-wallet/permissions/signers/multisig.mdx b/docs/pages/smart-wallet/permissions/signers/multisig.mdx index cf8ae05..10431cb 100644 --- a/docs/pages/smart-wallet/permissions/signers/multisig.mdx +++ b/docs/pages/smart-wallet/permissions/signers/multisig.mdx @@ -1,4 +1,4 @@ -# Multisig Signer +# Multisig signer The weighted ECDSA (multisig) signer signs with a collection of ECDSA keys. Each key is weighted, so that the signature will pass as long as enough signers with enough weight have signed. diff --git a/docs/pages/smart-wallet/permissions/signers/passkeys.mdx b/docs/pages/smart-wallet/permissions/signers/passkeys.mdx index d7647c1..7473a10 100644 --- a/docs/pages/smart-wallet/permissions/signers/passkeys.mdx +++ b/docs/pages/smart-wallet/permissions/signers/passkeys.mdx @@ -1,4 +1,4 @@ -# WebAuthn Signer +# WebAuthn signer The WebAuthn (passkeys) signer signs with a single passkey. Read [the passkeys doc](/sdk/advanced/passkeys) for a more detailed intro to passkeys. diff --git a/docs/pages/smart-wallet/quickstart-capabilities.mdx b/docs/pages/smart-wallet/quickstart-capabilities.mdx index ddb3ea3..be68056 100644 --- a/docs/pages/smart-wallet/quickstart-capabilities.mdx +++ b/docs/pages/smart-wallet/quickstart-capabilities.mdx @@ -1,31 +1,31 @@ -# Quickstart -- Capabilities +# Quickstart: Capabilities -Capabilities ([ERC-5792](https://eips.ethereum.org/EIPS/eip-5792)) is the [new standard way for DApps to interact with smart wallets](/blog/hello-capabilities). On a high level, it comes down to two steps: +Capabilities ([ERC-5792](https://eips.ethereum.org/EIPS/eip-5792)) is the [new standard way for DApps to interact with smart wallets](/blog/hello-capabilities). On a high level, it comes down to two steps: - The DApp *discovers* capabilities of the connected wallet through the `wallet_getCapabilities` RPC. - The DApp *uses* capabilities through the `wallet_sendCalls` RPC. -By standardizing smart wallet features such as gas sponsorship, transaction batching, and permissions (session keys), capabilities enable DApps to interact with any smart wallets through standard APIs. This means that: +By standardizing smart wallet features such as gas sponsorship, transaction batching, and permissions (session keys), capabilities enable DApps to interact with any smart wallets through standard APIs. This means that: -- If you are building a DApp, you can write your code once and it will work with any AA wallets, whether it's embedded wallets like ZeroDev or standalone wallets like Coinbase Smart Wallet. +- If you are building a DApp, you can write your code once, and it will work with any AA wallets, whether it's embedded wallets like ZeroDev or standalone wallets like Coinbase Smart Wallet. -- If you are building a wallet, you can write your code once and it will work with any AA accounts, whether it's ZeroDev (Kernel) or another smart account. +- If you are building a wallet, you can write your code once, and it will work with any AA accounts, whether it's ZeroDev (Kernel) or another smart account. **TLDR: capabilities standardize smart wallet features and thereby improve interoperability between smart wallets, reducing vendor lock-in for developers.** -In this tutorial, we will guide you through setting up a ZeroDev embedded wallet in your DApp, and communicate with it through the standard capability API using Viem/Wagmi. +In this tutorial, we will guide you through setting up a ZeroDev embedded wallet in your DApp and communicating with it via the standard capability API using Viem/Wagmi. -## Code Example +## Code example Use [this example repo](https://github.com/zerodevapp/capabilities-examples/tree/main/quick-start) as a reference as you go through this tutorial. ## Create an embedded Passkey Wallet -ZeroDev has created a number of Wagmi connectors that speak the capabilities API. In this tutorial, we will use the [passkey](/sdk/advanced/passkeys) connector. You can find [other connectors here](/smart-wallet/creating-wallets). +ZeroDev has created several of Wagmi connectors that speak the capabilities API. In this tutorial, we will use the [passkey](/sdk/advanced/passkeys) connector. You can find [other connectors here](/smart-wallet/creating-wallets). ## 1. Create a Wagmi project with Next.js: -In this tutorial, we will be using [Next.js](https://nextjs.org/docs/getting-started/installation). Start by creating a Next.js project: +In this tutorial, we will be using [Next.js](https://nextjs.org/docs/getting-started/installation). Start by creating a Next.js project: ```bash npx create-next-app@latest @@ -55,11 +55,11 @@ bun add @zerodev/wallet viem@latest wagmi @tanstack/react-query ::: -## 3. Setup a ZeroDev connector +## 3. Set up a ZeroDev connector For this tutorial, we will let the user create smart wallets with [passkeys](https://docs.zerodev.app/smart-wallet/creating-wallets). -Create a Wagmi provider and set it up with ZeroDev's passkey connector. You will need to [create a project ID from the dashboard](/smart-wallet/setting-up-zerodev-projects), and make sure you are using the right `chain` object corresponding to your ZeroDev project. +Create a Wagmi provider and set it up with ZeroDev's passkey connector. You will need to [create a project ID](/smart-wallet/setting-up-zerodev-projects) in the dashboard and make sure you are using the correct chain object for your ZeroDev project. :::code-group @@ -122,9 +122,9 @@ function App() { } ``` -## 4. Send sponsored & batched transactions +## 4. Send sponsored and batched transactions -Now let's try using two capabilities together: gas sponsorship and batching. We will send a batch of two transactions, and sponsor gas for them: +Now let's try using two capabilities together: gas sponsorship and batching. We will send a batch of two transactions, and sponsor gas for them: ```tsx filename=page.tsx // [page.tsx] import { parseAbi } from 'viem' @@ -179,8 +179,8 @@ function App() { } ``` -## Next Steps +## Next steps -Congrats -- you just sent your first gasless transaction with ZeroDev, through the standard capability API! +Congrats—you just sent your first gasless transaction with ZeroDev, through the standard capability API! -In this example, you used a public ZeroDev API key. Now learn how to [set up your own ZeroDev project](/smart-wallet/setting-up-zerodev-projects). Then browse the ZeroDev features using the sidebar and see what you'd like to use! +In this example, you used a public ZeroDev API key. Now learn how to [set up your own ZeroDev project](/smart-wallet/setting-up-zerodev-projects). Then browse the ZeroDev features using the sidebar and see what you'd like to use! diff --git a/docs/pages/smart-wallet/quickstart-core.mdx b/docs/pages/smart-wallet/quickstart-core.mdx index 2fa3c3a..586cb5b 100644 --- a/docs/pages/smart-wallet/quickstart-core.mdx +++ b/docs/pages/smart-wallet/quickstart-core.mdx @@ -1,10 +1,10 @@ -# Quickstart -- Core SDK +# Quickstart: Core SDK -ZeroDev has two main packages: `@zerodev/waas` which is designed for React projects, and `@zerodev/sdk` which is our core SDK that can be used in any JavaScript environment. +ZeroDev has two main packages: `@zerodev/waas` designed for React projects, and `@zerodev/sdk` which is our core SDK that integrates in any JavaScript environment. -In this tutorial, we will walk you through using the core SDK. If you are building a React project, we recommend [getting started with the React SDK](/smart-wallet/quickstart-react). +In this tutorial, we will walk you through using the core SDK. If you are building a React project, we recommend [getting started with the React SDK](/smart-wallet/quickstart-react). -## Getting Started +## Getting started Create a new project with `npm` (or whatever package manager you use): @@ -20,7 +20,7 @@ Install the ZeroDev SDK and presets: npm i @zerodev/sdk @zerodev/ecdsa-validator ``` -Install dev packages for TypeScript: +Install the `dev` packages for TypeScript: ```bash npm i --save-dev @types/node tslib @@ -146,6 +146,6 @@ Waiting for UserOp to complete... View completed UserOp here: https://jiffyscan.xyz/userOpHash/0x7a8e0ba961cc0a34f745b81d64766f033269fee831104fee0269fa5bcc397dcb ``` -Congrats -- you just sent your first gasless transaction with ZeroDev! +Congrats—you just sent your first gasless transaction with ZeroDev! In this example, you used a public ZeroDev API key. Now learn [how to set up your own ZeroDev project](/smart-wallet/setting-up-zerodev-projects). \ No newline at end of file diff --git a/docs/pages/smart-wallet/quickstart-react.mdx b/docs/pages/smart-wallet/quickstart-react.mdx index a095570..e1b73aa 100644 --- a/docs/pages/smart-wallet/quickstart-react.mdx +++ b/docs/pages/smart-wallet/quickstart-react.mdx @@ -1,20 +1,20 @@ -# Quickstart -- React +# Quickstart: React :::info Check out the [complete quickstart code here](https://github.com/zerodevapp/waas-examples/tree/main/quick-start). ::: -ZeroDev has two main packages: `@zerodev/waas` which is designed for React projects, and `@zerodev/sdk` which is our core SDK that can be used in any JavaScript environment. +ZeroDev has two main packages: `@zerodev/waas` designed for React projects, and `@zerodev/sdk` our core SDK that integrates with any JavaScript environment. -If you are building a React project, we recommend starting with `@zerodev/waas`, which is what we will walk you through in this tutorial. You can always ["dropping down" to the core SDK](#interop-with-the-core-sdk) when necessary. +If you are building a React project, we recommend starting with `@zerodev/waas`, which is what we will walk you through in this tutorial. You can always ["dropping down" to the core SDK](#interop-with-the-core-sdk) when necessary. ## 0. Clone the code -Since React has a lot of boilerplate, we will only focus on the ZeroDev-specific code. We recommend cloning the [complete quickstart code](https://github.com/zerodevapp/waas-examples/tree/main/quick-start) and refer to it if you get lost as you follow along this tutorial. +Since React has a lot of boilerplate, we will only focus on the ZeroDev-specific code. We recommend cloning the entire [quickstart code](https://github.com/zerodevapp/waas-examples/tree/main/quick-start) and referring to it if you get lost while following this tutorial. ## 1. Create a Next.js project -In this tutorial, we will be using [Next.js](https://nextjs.org/docs/getting-started/installation). Start by creating a Next.js project: +In this tutorial, we will be using [Next.js](https://nextjs.org/docs/getting-started/installation). Start by creating a Next.js project: ```bash npx create-next-app@latest @@ -44,9 +44,9 @@ bun add @zerodev/waas viem@2.x @tanstack/react-query ::: -## 3. Setup context provider +## 3. Set up context provider -Create a provider in typical React style. You will need to [create a project ID from the dashboard](/smart-wallet/setting-up-zerodev-projects), and make sure you are using the right `chain` object corresponding to your ZeroDev project. +Create a provider in typical React style. You will need to [create a project ID in the dashboard](/smart-wallet/setting-up-zerodev-projects), and make sure you are using the correct `chain` object corresponding to your ZeroDev project. ```ts filename=Providers.tsx // [Providers.tsx] import { http } from "viem" @@ -74,9 +74,9 @@ function Providers({ children }: { children: React.ReactNode}) { } ``` -## 4. Use ZeroDev waas +## 4. Use ZeroDev WaaS -### Create a Smart Account +### Create a smart account Let's start by creating an account: @@ -161,12 +161,12 @@ function App() { ### Interop with the Core SDK -If you ever want to use the Core SDK (perhaps because a feature is only supported in the core SDK but not through the React API), you can "drop down" to the SDK with [the `useKernelClient` hook](/react/use-kernelclient#usekernelclient). +If you ever want to use the Core SDK (perhaps because a feature is only supported in the Core SDK but not through the React API), you can "drop down" to the SDK with [the `useKernelClient` hook](/react/use-kernelclient#usekernelclient). Similarly, if you have created a Kernel client object with the core SDK, you can "embed" it inside the React SDK using [the `useSetKernelClient` hook](https://docs.zerodev.app/react/use-set-kernelclient). ## Next Steps -Congrats -- you just sent your first gasless transaction with ZeroDev! +Congrats—you just sent your first gasless transaction with ZeroDev! -In this example, you used a public ZeroDev API key. Now learn [how to set up your own ZeroDev project](/smart-wallet/setting-up-zerodev-projects). +In this example, you used a public ZeroDev API key. Now learn [how to set up your own ZeroDev project](/smart-wallet/setting-up-zerodev-projects). diff --git a/docs/pages/smart-wallet/sending-transactions.mdx b/docs/pages/smart-wallet/sending-transactions.mdx index 5056aab..0d7b891 100644 --- a/docs/pages/smart-wallet/sending-transactions.mdx +++ b/docs/pages/smart-wallet/sending-transactions.mdx @@ -1,15 +1,15 @@ -# Sending Transactions +# Sending transactions -In ERC-4337, a transaction is known as a "UserOp." A UserOp looks mostly like a regular transaction, but it contains some extra information specific to AA, such as whether the UserOp should be sponsored. +In ERC-4337, a transaction is known as a "UserOp." A UserOp looks mostly like a regular transaction, but it contains some extra information specific to AA, such as whether the UserOp should be sponsored. There are two ways to send UserOps: - Sending raw UserOps - Sending regular transactions through the Viem API, which ZeroDev then "translates" into UserOps -The former enables the highest degree of flexibility, whereas the latter is more interoperable with existing libraries like Viem that deal only with transactions and not UserOps. +The former offers the highest degree of flexibility, whereas the latter is more interoperable with existing libraries like Viem, which deal only with transactions and not UserOps. -We will now describe both approaches. We assume that you have already [created a Kernel account](/sdk/core-api/create-account). +We will now describe both approaches. We assume that you have already [created a Kernel account](/sdk/core-api/create-account). ## React API @@ -44,19 +44,21 @@ function App() { } ``` -The argument to `write` is an array of UserOps. The format of each UserOp is the same as the argument to Wagmi's [`writeContract`](https://wagmi.sh/core/api/actions/writeContract#writecontract). +The argument to `write` is an array of UserOps. The format of each UserOp is the same as the argument to Wagmi's [`writeContract`](https://wagmi.sh/core/api/actions/writeContract#writecontract). -If you pass more than one UserOps, you'd be sending them all in a [batch](/smart-wallet/batching-transactions). +If you pass more than one UserOps, you’d send them all in a single [batch](/smart-wallet/batching-transactions). ## Core API :::info -Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/send-transactions). + +Impatient? Check out [complete examples here](https://github.com/zerodevapp/zerodev-examples/tree/main/send-transactions). + ::: ### UserOp API -Sending raw UserOps affords you with the highest degree of control. To send a raw UserOp, use `sendUserOperation`: +Sending raw UserOps affords you the highest degree of control. To send a raw UserOp, use `sendUserOperation`: ```typescript const userOpHash = await kernelClient.sendUserOperation({ @@ -88,11 +90,11 @@ Other than `callData`, every field has a sensible default: - `nonce` defaults to the next available nonce - `initCode` defaults to `0x` if the account has been deployed, or the correct `initCode` if not. - `callGasLimit`, `verificationGasLimit`, and `preVerificationGas` default to estimations provided by the underlying bundler and paymaster. -- `maxFeePerGas` and `maxPriorityFeePerGas` default to estimations provided by the public client. +- `maxFeePerGas` and `maxPriorityFeePerGas` default to the public client's estimates. - `paymasterAndData` defaults to `0x` if no paymaster was specified when you created the Kernel account object, or it will use the value provided by the paymaster. -- `signature` defaults to the signature provided by the signer. +- `signature` defaults to the signer's signature. -### Encoding callData +### Encoding `callData` To encode the calldata, use the `encodeCalls` function from the account object: @@ -106,7 +108,7 @@ const userOpHash = await kernelClient.sendUserOperation({ }) ``` -You can use Viem's helper functions such as `encodeFunctionData` to encode function calls. For example: +You can use Viem's helper functions, such as `encodeFunctionData`, to encode function calls. For example: ```ts const userOpHash = await kernelClient.sendUserOperation({ @@ -134,7 +136,7 @@ const receipt = await kernelClient.waitForUserOperationReceipt({ ### Constructing a UserOp for sending later -In some applications, you might want to construct a UserOp but not immediately send it. There are two possible flows: +In some applications, you should construct a UserOp but not send it immediately. There are two possible flows: - If you want to separate signing and sending: - Create and sign a UserOp with `kernelClient.signUserOperation()` @@ -149,7 +151,7 @@ In some applications, you might want to construct a UserOp but not immediately s Since the Kernel account client implements [Viem's wallet client interface](https://viem.sh/docs/clients/wallet.html), you can send UserOps with standard Viem methods. -### Sending Transactions +### Sending transactions ```typescript const txnHash = await kernelClient.sendTransaction({ @@ -159,11 +161,11 @@ const txnHash = await kernelClient.sendTransaction({ }) ``` -This function returns the transaction hash of the ERC-4337 bundle that contains the UserOp. Due to the way that ERC-4337 works, by the time we get the transaction hash, the ERC-4337 bundle (and therefore the UserOps includeded within) will have already been mined, meaning that you don't have to [wait with the hash](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html). +This function returns the transaction hash of the ERC-4337 bundle that contains the UserOp. Because ERC-4337 works the way it does, by the time we get the transaction hash, the ERC-4337 bundle (and therefore the UserOps included within) will have already been mined, so you don’t have to [wait with the hash](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html). -If you need to separate the sending from the waiting of the UserOp, try [sending raw UserOps](#sending-raw-userops). +If you need to separate the sending from the waiting for the UserOp, try [sending raw UserOps](#sending-raw-userops). -### Interacting with Contracts +### Interacting with contracts First, construct a [Viem contract instance](https://viem.sh/docs/contract/getContract.html) by passing the Kernel account client as the `walletClient`: diff --git a/docs/pages/smart-wallet/setting-up-zerodev-projects.mdx b/docs/pages/smart-wallet/setting-up-zerodev-projects.mdx index e624991..2500855 100644 --- a/docs/pages/smart-wallet/setting-up-zerodev-projects.mdx +++ b/docs/pages/smart-wallet/setting-up-zerodev-projects.mdx @@ -1,8 +1,8 @@ -# Setting up a ZeroDev Project +# Setting up a ZeroDev project -ZeroDev provides the necessary [infrastructure](/meta-infra/intro) to power your smart accounts. To start using ZeroDev, you need to create a *project*. +ZeroDev provides the necessary [infrastructure](/meta-infra/intro) to power your smart accounts. To start using ZeroDev, you need to create a *project*. -## Creating a Project +## Creating a project Sign up at the [ZeroDev dashboard](https://dashboard.zerodev.app/), then create a project for your target network. @@ -10,25 +10,25 @@ Sign up at the [ZeroDev dashboard](https://dashboard.zerodev.app/), then create

-You will then see your "Project Home" with a number of configs. +You will then see your "Project Home" with several configs.

-These configs give you access to ZeroDev infra. When you [create wallets](/smart-wallet/creating-wallets), you will be using these values with the SDK. +These configs give you access to ZeroDev infra. When you [create wallets](/smart-wallet/creating-wallets), you will be using these values with the SDK. -## Setting up Billing +## Setting up billing You can use ZeroDev for free on testnets. -If you want to use ZeroDev on a mainnet, you must sign up for a billing plan. You can [see the billing plans here](https://dashboard.zerodev.app/billing). +If you want to use ZeroDev on a mainnet, you must sign up for a billing plan. You can [see the billing plans here](https://dashboard.zerodev.app/billing). -## Next Steps +## Next steps If you haven't already, check out these tutorials according to your needs: - [React SDK](/smart-wallet/quickstart-react) - [Core SDK](/smart-wallet/quickstart-core) -Otherwise, start looking into specific features you need, such as [creating wallets](/smart-wallet/creating-wallets). \ No newline at end of file +Otherwise, start looking into the specific features you need, such as [wallet creation](/smart-wallet/creating-wallets).. diff --git a/docs/pages/smart-wallet/sponsoring-gas.mdx b/docs/pages/smart-wallet/sponsoring-gas.mdx index 96aa309..2a979af 100644 --- a/docs/pages/smart-wallet/sponsoring-gas.mdx +++ b/docs/pages/smart-wallet/sponsoring-gas.mdx @@ -1,24 +1,24 @@ -# Sponsoring Gas +# Sponsoring gas -You can sponsor gas for your users so they don't have to acquire gas tokens (e.g. ETH) before using your app. +You can sponsor gas for your users so they don't have to acquire gas tokens (e.g., `ETH`) before using your app. ## How to pay for gas -When you sponsor gas through ZeroDev, we "front" the gas for you, and then charge your credit card at the end of your billing cycle. If you prefer to pay upfront, you can also purchase gas credits from us. +When you sponsor gas through ZeroDev, we "front" the gas for you, and then charge your credit card at the end of your billing cycle. If you prefer to pay upfront, you can also purchase gas credits from us. ## Set up gas policies -To start sponsoring gas, you need to set up "gas policies." Gas policies are security measures to ensure that you don't overspend on gas. +To start sponsoring gas, you need to set up “gas policies.” Gas policies are security measures to help you avoid overspending on gas. -You can set up gas policies on the ZeroDev dashboard or through the admin API. [Read this document to learn how to set up gas policies.](/meta-infra/gas-policies) +You can set up gas policies on the ZeroDev dashboard or through the admin API. [Read this document to learn how to set up gas policies.](/meta-infra/gas-policies) ## Capabilities API Thanks to [the new capabilities standard](/smart-wallet/quickstart-capabilities), you can use ZeroDev paymasters to sponsor gas for any smart wallets, and use any paymaster to sponsor gas for ZeroDev smart wallets. -In this tutorial, we will be using the ZeroDev paymaster. Make sure you have [set up gas policies](#set-up-gas-policies). Then copy the paymaster URL from [your dashboard](https://dashboard.zerodev.app/). +In this tutorial, we will be using the ZeroDev paymaster. Make sure you have [set up gas policies](#set-up-gas-policies). Then copy the paymaster URL from [your dashboard](https://dashboard.zerodev.app/). -Now, you can send sponsored transactions using the `wallet_sendCalls` API with the `paymasterService` capability. We will be using [Wagmi](https://wagmi.sh/react/api/hooks/useSendCalls) here but you can find the same API in [Viem](https://viem.sh/experimental/eip5792/sendCalls): +Now, you can send sponsored transactions using the `wallet_sendCalls` API with the `paymasterService` capability. We will be using [Wagmi](https://wagmi.sh/react/api/hooks/useSendCalls) here, but you can find the same API in [Viem](https://viem.sh/experimental/eip5792/sendCalls): ## React API @@ -39,12 +39,14 @@ function App() { ## Core API :::info + Check out [a complete example here](https://github.com/zerodevapp/zerodev-examples/blob/main/create-account/main.ts). + ::: When [creating an account](/smart-wallet/creating-wallets), you can specify a `sponsorUserOperation` function when you create the account client. -The `sponsorUserOperation` function essentially takes a UserOp and then returns a UserOp with the `paymasterAndData` field set. You can use the `createZeroDevPaymasterClient` helper function: +The `sponsorUserOperation` function takes a UserOp and then returns a UserOp with the `paymasterAndData` field set. You can use the `createZeroDevPaymasterClient` helper function: ```typescript import { http } from "viem" diff --git a/docs/pages/smart-wallet/transaction-automation.md b/docs/pages/smart-wallet/transaction-automation.md index 2a87f65..16c8bcc 100644 --- a/docs/pages/smart-wallet/transaction-automation.md +++ b/docs/pages/smart-wallet/transaction-automation.md @@ -1,17 +1,17 @@ -# Transaction Automation +# Transaction automation -With smart accounts, you can automate transactions for your users. Some example use cases are: +With smart accounts, you can automate transactions for your users. Some example use cases are: -- Subscriptions. -- Trading bots. -- Automatic order execution, e.g. limit orders & trailing orders. +- Subscriptions +- Trading bots +- Automatic order execution, e.g., limit orders and trailing orders In general, any time you wish to execute a transaction for your user, you can use transaction automation. -## How Transaction Automation Works +## How transaction automation works -Thanks to smart accounts, transaction automation is *safe* with ZeroDev. Your users delegate to you a specific set of [*permissions*](https://docs.zerodev.app/smart-wallet/permissions/intro) through [session keys](https://docs.zerodev.app/blog/session-keys-are-the-jwts-of-web3), so even if your server is hacked, your users's assets will be safe. +Thanks to smart accounts, transaction automation is *safe* with ZeroDev. Your users delegate to you a specific set of [*permissions*](https://docs.zerodev.app/smart-wallet/permissions/intro) through [session keys](https://docs.zerodev.app/blog/session-keys-are-the-jwts-of-web3), so even if your server is hacked, your users's assets will be safe. -## Getting Started +## Getting started [Follow this tutorial to get started with transaction automation.](/smart-wallet/permissions/transaction-automation) diff --git a/docs/pages/smart-wallet/wallet-connect.md b/docs/pages/smart-wallet/wallet-connect.md index 42abd0c..685f2bc 100644 --- a/docs/pages/smart-wallet/wallet-connect.md +++ b/docs/pages/smart-wallet/wallet-connect.md @@ -1,6 +1,6 @@ -# Connecting Wallet with Other DApps +# Connecting wallet with other dApps -If you want your users to be able to use your embedded wallet on other DApps, you can use our WalletConnect integration. +If you want your users to use your embedded wallet across other DApps, you can use our WalletConnect integration. ## React SDK `@zerodev/waas` diff --git a/docs/pages/smart-wallet/which-sdk.mdx b/docs/pages/smart-wallet/which-sdk.mdx index 25af723..ae1972a 100644 --- a/docs/pages/smart-wallet/which-sdk.mdx +++ b/docs/pages/smart-wallet/which-sdk.mdx @@ -2,30 +2,30 @@ ZeroDev currently offers three SDKs for different use cases: -- `@zerodev/wallet` packages the ZeroDev smart wallet into [Wagmi connectors](https://wagmi.sh/react/api/connectors) and [EIP-1193 providers](https://eips.ethereum.org/EIPS/eip-1193), so you can easily plug ZeroDev into any application as an embedded wallet. +- `@zerodev/wallet` packages the ZeroDev smart wallet as [Wagmi connectors](https://wagmi.sh/react/api/connectors) and [EIP-1193 providers](https://eips.ethereum.org/EIPS/eip-1193), so you can easily embed ZeroDev in any application as an embedded wallet. -- `@zerodev/core` implements the core logic of the ZeroDev smart embedded wallet (powered by [Kernel](https://github.com/zerodevapp/kernel)). This library has the most complete functionality and offers the most low-level and fine-grained control. +- `@zerodev/core` implements the core logic of the ZeroDev smart embedded wallet (powered by [Kernel](https://github.com/zerodevapp/kernel)). This library offers the most complete functionality and the most low-level, fine-grained control. -- `@zerodev/waas` is a React SDK built on top of `@zerodev/core`. It can be viewed as the equivalent of Wagmi but for smart wallets. +- `@zerodev/waas` is a React SDK built on top of `@zerodev/core`. It can be viewed as the equivalent of Wagmi, but for smart wallets. To decide which SDK to use, first decide what you are building: ## Are you building a wallet or a DApp? -The line between a wallet and a DApp can be a bit blurry in Web3. For the purpose of this discussion, we define wallets and DApps as follows: +The line between a wallet and a DApp can be blurry in Web3. For this discussion, we define wallets and DApps as follows: -- Wallets: you want your users to use your app as their primary wallet, as opposed to bringing wallets to your app. +- Wallets: You want your users to use your app as their primary wallet rather than bringing their own wallets to your app. -- DApps: you want your users to bring wallets to your app, or spin up a wallet for them if they don't have one. +- DApps: You want your users to bring wallets to your app, or spin up a wallet for them if they don't have one. ## If you are building a DApp -If you are building a DApp, we recommend that you use `@zerodev/wallet` to spin up a smart embedded wallet for users who don't bring their own smart wallet (which are most users today). +If you are building a DApp, we recommend using `@zerodev/wallet` to spin up a smart embedded wallet for users who don’t bring their own smart wallet (which most users do today). -Then, you can program your DApp with Viem/Wagmi as usual, while using smart wallet features (e.g. gas sponsoring) through [the capabilities API](/smart-wallet/quickstart-capabilities). +Then, you can program your DApp with Viem/Wagmi as usual, while using smart wallet features (e.g., gas sponsoring) via [the capabilities API](/smart-wallet/quickstart-capabilities). ## If you are building a wallet -[Use `@zerodev/core`](/smart-wallet/quickstart-core) if you want all the ZeroDev features and the most fine-grained control. +[Use `@zerodev/core`](/smart-wallet/quickstart-core) for all ZeroDev features and the most fine-grained control. [Use `@zerodev/waas`](/smart-wallet/quickstart-react) if you are building the wallet using React. \ No newline at end of file