diff --git a/docs/pages/infra/bundler/usage.mdx b/docs/pages/infra/bundler/usage.mdx index 5a73a3db..d51db8c6 100644 --- a/docs/pages/infra/bundler/usage.mdx +++ b/docs/pages/infra/bundler/usage.mdx @@ -1,10 +1,10 @@ # How to use the bundler :::tip[Tip] -We recommend using [permissionless.js](/permissionless/reference/bundler-actions/sendUserOperation) as the SDK to interact with the bundler as it provides type-safe wrappers for all bundler methods. +We recommend using [permissionless.js](/permissionless/reference/bundler-actions/sendUserOperation) as the SDK to interact with the bundler as it provides type-safe wrappers for all bundler methods. ::: -ERC-4337 bundlers are relayers that bundle user operations into transactions and submit them to the blockchain. You can interact with bundlers using stndard JSON-RPC requests. +ERC-4337 bundlers are relayers that bundle user operations into transactions and submit them to the blockchain. You can interact with bundlers using standard JSON-RPC requests. To get access to the bundler, you need to use your [Pimlico API key](https://dashboard.pimlico.io/apikeys). Using the API key, you can make the following JSON-RPC requests to the bundler: @@ -17,4 +17,4 @@ To get access to the bundler, you need to use your [Pimlico API key](https://das - [pimlico_getUserOperationGasPrice](/infra/bundler/endpoints/pimlico_getUserOperationGasPrice) - [pimlico_getUserOperationStatus](/infra/bundler/endpoints/pimlico_getUserOperationStatus) -If you would like an end-to-end example of how to use the bundler, please refer to [tutorial 1](/permissionless/tutorial/tutorial-1) of the permissionless.js documentation. \ No newline at end of file +If you would like an end-to-end example of how to use the bundler, please refer to [tutorial 1](/permissionless/tutorial/tutorial-1) of the permissionless.js documentation. diff --git a/docs/pages/infra/paymaster/erc20-paymaster/contract-addresses.mdx b/docs/pages/infra/paymaster/erc20-paymaster/contract-addresses.mdx index dee5829a..c13b4cca 100644 --- a/docs/pages/infra/paymaster/erc20-paymaster/contract-addresses.mdx +++ b/docs/pages/infra/paymaster/erc20-paymaster/contract-addresses.mdx @@ -10,6 +10,8 @@ Below are the contract addresses for the ERC-20 Paymaster contracts that are cur | sepolia | [0x000000000041F3aFe8892B48D88b6862efe0ec8d](https://sepolia.etherscan.io/address/0x000000000041F3aFe8892B48D88b6862efe0ec8d) | [USDC: 0x1c7D...7238](https://sepolia.etherscan.io/address/0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238) | | base-sepolia | [0x00000000002E3A39aFEf1132214fEee5a55ce127](https://sepolia.basescan.org/address/0x00000000002E3A39aFEf1132214fEee5a55ce127) | [USDC: 0x036C...CF7e](https://sepolia.basescan.org/address/0x036CbD53842c5426634e7929541eC2318f3dCF7e) | | base | [0x0000000000164F4b0508aCf9c7443C9B682E4091](https://basescan.org/address/0x0000000000164F4b0508aCf9c7443C9B682E4091) | [USDC: 0x8335...2913](https://basescan.org/address/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) | +| bob | [0x000000003CE83Ad13E6A53658Eb03179a37411AE](https://explorer.gobob.xyz/address/0x000000003CE83Ad13E6A53658Eb03179a37411AE) | [WBTC: 0x03c7...cfa3](https://explorer.gobob.xyz/address/0x03c7054bcb39f7b2e5b2c7acb37583e32d70cfa3) | +| bob | [0x00000000D1925888A08895393501545Ea885fbA8](https://explorer.gobob.xyz/address/0x00000000D1925888A08895393501545Ea885fbA8) | [TBTC: 0xBBa2...c2e2](https://explorer.gobob.xyz/address/0xBBa2eF945D523C4e2608C9E1214C2Cc64D4fc2e2) | | polygon | [0x00000000007672027B2DFbFc9FB2dd2842092EC3](https://polygonscan.com/address/0x00000000007672027B2DFbFc9FB2dd2842092EC3) | [USDC: 0x3c49...3359](https://polygonscan.com/address/0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359) | | optimism | [0x000000000055a2B69645b4B69B65De6fF00B7468](https://optimistic.etherscan.io/address/0x000000000055a2B69645b4B69B65De6fF00B7468) | [USDC: 0x0b2C...Ff85](https://optimistic.etherscan.io/address/0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85) | | bsc | [0x0000000000bB595b6Af77D0818a48464e144Fa35](https://bscscan.com/address/0x0000000000bB595b6Af77D0818a48464e144Fa35) | [USDC: 0x8AC7...580d](https://bscscan.com/address/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d) | diff --git a/docs/pages/infra/paymaster/erc20-paymaster/guides.mdx b/docs/pages/infra/paymaster/erc20-paymaster/guides.mdx new file mode 100644 index 00000000..e0af1368 --- /dev/null +++ b/docs/pages/infra/paymaster/erc20-paymaster/guides.mdx @@ -0,0 +1,152 @@ +# ERC-20 Paymaster Guides + +## Estimating Approval Amounts + +When using Pimlico's ERC20-paymaster, the paymaster needs approval to spend funds on the payer's behalf. The amount to approve must be atleast equal to the userOperation's prefund value. + +You can use the helper function below to get the required approval amount. + +```ts +// Calculates amount of tokens that need to be approved for ERC20 paymaster to sponsor userOperation +const getApprovalAmount = async ({ + publicClient, + paymasterAddress, + userOperation, +}: EstimateParams) => { + const erc20Paymaster = getContract({ + client: publicClient, + address: paymasterAddress, + abi: parseAbi([ + "function getPrice() view returns (uint192)", + "function priceMarkup() view returns (uint32)", + "function refundPostOpCost() view returns (uint)", + ]), + }); + + const requiredGas = + userOperation.verificationGasLimit + + userOperation.callGasLimit + + (userOperation.paymasterVerificationGasLimit || 0n) + + (userOperation.paymasterPostOpGasLimit || 0n) + + userOperation.preVerificationGas; + + const requiredPreFund = requiredGas * userOperation.maxFeePerGas; + + // fetch onchain info + const markup = BigInt(await erc20Paymaster.read.priceMarkup()); + const refundPostOpCost = BigInt(await erc20Paymaster.read.refundPostOpCost()); + const tokenPrice = BigInt(await erc20Paymaster.read.getPrice()); + + const maxFeePerGas = userOperation.maxFeePerGas; + + return ( + ((requiredPreFund + refundPostOpCost * maxFeePerGas) * + markup * + tokenPrice) / + (BigInt(1e18) * BigInt(1e6)) + ); +}; +``` + +## Estimating Gas Cost + +The helper function below shows an example on how to accurately estimate the gas cost of a UserOperation when using Pimlico's paymasters. The function expects a valid and signed UserOperation. + +```ts +// Returns the cost of the UserOperation (denominated in token) +export const estimateCost = async ({ + userOperation, + publicClient, + paymasterAddress, +}: EstimateParams) => { + const beneficiary = privateKeyToAddress(generatePrivateKey()); + + const erc20Paymaster = getContract({ + address: paymasterAddress, + abi: parseAbi(["function token() view returns (address)"]), + client: publicClient, + }); + const erc20Token = await erc20Paymaster.read.token(); + + const multicall3Abi = parseAbi([ + "struct Result { bool success; bytes returnData; }", + "struct Call3 { address target; bool allowFailure; bytes callData; }", + "function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData)", + ]); + + const entrypointAbi = parseAbi([ + "struct PackedUserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; bytes32 accountGasLimits; uint256 preVerificationGas; bytes32 gasFees; bytes paymasterAndData; bytes signature; }", + "function handleOps(PackedUserOperation[] calldata ops, address beneficiary)", + "error FailedOp(uint256 opIndex, string reason)", + "error FailedOpWithRevert(uint256 opIndex, string reason, bytes inner)", + "error PostOpReverted(bytes returnData)", + "error SignatureValidationFailed(address aggregator)", + ]); + const handleOpsData = encodeFunctionData({ + abi: entrypointAbi, + functionName: "handleOps", + args: [[getPackedUserOperation(userOperation)], beneficiary], + }); + + const getTokenBalanceData = encodeFunctionData({ + abi: parseAbi(["function balanceOf(address) returns (uint)"]), + args: [userOperation.sender], + }); + + const multicallPayload = encodeFunctionData({ + abi: multicall3Abi, + functionName: "aggregate3", + args: [ + [ + { + target: erc20Token, + callData: getTokenBalanceData, + allowFailure: true, + }, + { + target: ENTRYPOINT_ADDRESS_V07, + callData: handleOpsData, + allowFailure: true, + }, + { + target: erc20Token, + callData: getTokenBalanceData, + allowFailure: true, + }, + ], + ], + }); + + const response = await publicClient.call({ + to: "0xca11bde05977b3631167028862be2a173976ca11", + data: multicallPayload, + gasPrice: await publicClient.getGasPrice(), + }); + + if (!response.data) { + throw new Error("Failed to estimate erc20Paymaster's gas cost"); + } + + const [balBefore, handleOps, balAfter] = decodeAbiParameters( + multicall3Abi[0].outputs, + response.data, + )[0]; + + if (!balBefore.success || !balAfter.success) { + throw new Error("Failed to estimate erc20Paymaster's gas cost"); + } + + if (!handleOps.success) { + const parsedError = decodeErrorResult({ + abi: entrypointAbi, + data: handleOps.returnData, + }); + + throw new Error( + `Failed to estimate erc20Paymaster's gas cost due to ${parsedError.args}`, + ); + } + + return hexToBigInt(balBefore.returnData) - hexToBigInt(balAfter.returnData); +}; +``` diff --git a/docs/pages/infra/platform/debugging/dropped-user-operations.mdx b/docs/pages/infra/platform/debugging/dropped-user-operations.mdx new file mode 100644 index 00000000..76977735 --- /dev/null +++ b/docs/pages/infra/platform/debugging/dropped-user-operations.mdx @@ -0,0 +1,7 @@ +# How to debug dropped user operations + +If a user operation is dropped in the mempool of the bundler after initially being accepted by it, the error can not be propagated by the bundler to the user. To debug what happened to these user operations, we recommend using the [User Operation Tracking](https://dashboard.pimlico.io/debugging/tracking) page on our dashboard, which will show you the exact flow of the user operation stage-by-stage through Pimlico's bundler with timestamps, including any errors it encounters. + +An example screenshot of the User Operation Tracking page is shown below: + +![User Operation Tracking page, showing a dropped user operation](/tracking.png) \ No newline at end of file diff --git a/docs/pages/infra/platform/sponsorship-policies/webhook.mdx b/docs/pages/infra/platform/sponsorship-policies/webhook.mdx new file mode 100644 index 00000000..16ee9158 --- /dev/null +++ b/docs/pages/infra/platform/sponsorship-policies/webhook.mdx @@ -0,0 +1,27 @@ +# How to use Sponsorship Policy webhook + +Webhook allows you to receive real-time notifications when a sponsorship policy is triggered. You can use webhooks to approve or reject sponsoring userops. Start by going to the [sponsorship policies page](https://dashboard.pimlico.io/sponsorship-policies) on the Pimlico dashboard, clicking on the existing policy and clicking on the "Edit button". + +Request is sent with POST, where body is a JSON object with the following structure: + +```typescript +const body = { + type: 'sponsorshipPolicy.webhook', + data: { + object: { + userOperation, + entryPoint, + chainId, + sponsorshipPolicyId: sponsorshipPolicy.id + } + } +}; +``` + +The returned value should be a JSON with the following structure: + +```json +{ + "sponsor": true // Boolean +} +``` \ No newline at end of file diff --git a/docs/pages/infra/platform/why-pimlico.mdx b/docs/pages/infra/platform/why-pimlico.mdx new file mode 100644 index 00000000..27ca339e --- /dev/null +++ b/docs/pages/infra/platform/why-pimlico.mdx @@ -0,0 +1,25 @@ +# Why Pimlico + +Are you looking to improve your app's user experience and wondering why you should use Pimlico as your account abstraction infrastructure provider? + +Below are some reasons some of the best teams in crypto have chosen to build on Pimlico + +## Developer-first experience + +Pimlico is a platform built by developers for developers. We understand the importance of a great developer experience and have built our platform with that in mind. + +This means you can expect clean, modern, well-typed SDKs, comprehensive documentation, and a support team that's comprised of devleopers who can help you with any issues you might encounter. + +## Powerful features + +When you build on Pimlico, you're not just getting a simple account abstraction platform. You're getting a powerful set of tools that can help you build the best user experience with the most powerful infrastructure in the space. + +This means a comprehensive set of tools, charts, logs, configurations to give you all the scale, observability, security, and debugging capabilities you need to build with smart accounts, as well as accesss to 70+ chains with one API key and one, centrally-managed balance. + +## Expert, veteran team + +Our team has been working in the account abstraction space for years, and we have a deep understanding of the space. We are co-authors of some of the most important smart account standards, are constantly innovating at the frontier and can make sure you're always ahead of the curve. Our developer-focused team also means you can expect fast, helpful support whenever you need it, and new features being constantly added daily rather than quarterly. + +## What's next? + +If you're ready to get started, you can sign up to the [Pimlico dashboard](https://dashboard.pimlico.io) or [contact us](https://cal.com/team/pimlico/20min) to start building with Pimlico today, and join the ranks of some of the best teams in crypto such as Zora, WalletConnect, Daimo, Safe, and more. diff --git a/docs/pages/permissionless/how-to/accounts/user-erc7579-actions.mdx b/docs/pages/permissionless/how-to/accounts/use-erc7579-account.mdx similarity index 76% rename from docs/pages/permissionless/how-to/accounts/user-erc7579-actions.mdx rename to docs/pages/permissionless/how-to/accounts/use-erc7579-account.mdx index 25dc0860..7f323dd8 100644 --- a/docs/pages/permissionless/how-to/accounts/user-erc7579-actions.mdx +++ b/docs/pages/permissionless/how-to/accounts/use-erc7579-account.mdx @@ -1,12 +1,12 @@ -# How to use ERC 7579 compatible smart accounts with permissionless.js +# How to use an ERC-7579 compatible smart account with permissionless.js -[ERC7579](https://eips.ethereum.org/EIPS/eip-7579) defines a standard for modular smart account interfaces. It also defines behavior for interoperability with minimal restrictions for accounts and modules. +[ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) defines a standard for modular smart account interfaces. It also defines behavior for interoperability with minimal restrictions for accounts and modules. -Currently Safe and Kernel are the only smart accounts that implements ERC7579. +Currently Safe and Kernel are the only smart accounts that implements ERC-7579. -For this guide, we will use the `Safe smart account` as an example. +For this guide, we will use the Safe smart accounts as an example. If you would like to find out more about the Safe smart account, you can check out the [Safe-specific guide](/permissionless/how-to/accounts/use-safe-account). -This guide will show you how to create and use a ERC7579 compatible smart account with permissionless.js. +This guide will show you how to create and use a ERC-7579 compatible smart account with permissionless.js. ## Steps diff --git a/docs/pages/permissionless/how-to/signers/dynamic.mdx b/docs/pages/permissionless/how-to/signers/dynamic.mdx index 3549c3a7..03d187ce 100644 --- a/docs/pages/permissionless/how-to/signers/dynamic.mdx +++ b/docs/pages/permissionless/how-to/signers/dynamic.mdx @@ -45,30 +45,39 @@ export const App = () => { Create the smart account client using the Dynamic signer. Note: DynamicWagmiConnector internally sets up the WagmiConfig, so there is no need to do it separately. This is where you would configure what smart account implementation (e.g. [Safe](/permissionless/how-to/accounts/use-safe-account), [Kernel](/permissionless/how-to/accounts/use-kernel-account), Biconomy, [TrustWallet](/permissionless/how-to/accounts/use-trustwallet-account) [SimpleAccount](/permissionless/how-to/accounts/use-simple-account)) and what paymaster logic you want to use. ```ts -import { createSmartAccountClient, walletClientToSmartAccountSigner } from "permissionless"; +import { createSmartAccountClient, walletClientToSmartAccountSigner, ENTRYPOINT_ADDRESS_V06 } from "permissionless"; import { signerToSimpleSmartAccount } from "permissionless/accounts"; import { useWalletClient } from "wagmi"; +import { createPublicClient, http, zeroAddress } from "viem"; +import { sepolia } from "viem/chains"; const { - data: walletClient + data: walletClient } = useWalletClient() +const publicClient = createPublicClient({ + chain: sepolia, // or whatever chain you are using + transport: http() +}) + const signer = walletClientToSmartAccountSigner(walletClient) const simpleSmartAccountClient = await signerToSimpleSmartAccount(publicClient, { - entryPoint: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", - signer: signer, - factoryAddress: "0x9406Cc6185a346906296840746125a0E44976454" + entryPoint: ENTRYPOINT_ADDRESS_V06, + signer, }) const smartAccountClient = createSmartAccountClient({ - account: simpleSmartAccountClient, - chain: sepolia, // or whatever chain you are using - bundlerTransport: http(""), - entryPoint: ENTRYPOINT_ADDRESS_V06, - middleware: { - sponsorUserOperation: paymasterClient.sponsorUserOperation, // optional, if using a paymaster - }, + account: simpleSmartAccountClient, + entryPoint: ENTRYPOINT_ADDRESS_V06, + chain: sepolia, // or whatever chain you are using + bundlerTransport: http("", { + timeout: 30_000 // optional + }), + middleware: { + gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast, + sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation, + }, }) ``` diff --git a/docs/pages/permissionless/how-to/signers/privy.mdx b/docs/pages/permissionless/how-to/signers/privy.mdx index 9927977d..9a243cff 100644 --- a/docs/pages/permissionless/how-to/signers/privy.mdx +++ b/docs/pages/permissionless/how-to/signers/privy.mdx @@ -2,6 +2,8 @@ permissionless.js allows you to plug in custom signers to control the accounts that you create. Privy is an embedded wallet provider that allows you to easily onboard users to your dapp. It is possible to use Privy as a signer with permissionless.js, allowing you to use Privy to create and control smart accounts and sign transactions. +Additionally you may want to look at Privy's guide on working with permissionless.js [here](https://docs.privy.io/guide/react/recipes/account-abstraction/pimlico). + ::::steps ### Install the dependencies @@ -56,31 +58,39 @@ useEffect(() => setActiveWallet(embeddedWallet), [embeddedWallet]) Create the smart account client using the Privy signer. This is where you would configure what smart account implementation (e.g. [Safe](/permissionless/how-to/accounts/use-safe-account), [Kernel](/permissionless/how-to/accounts/use-kernel-account), Biconomy, [TrustWallet](/permissionless/how-to/accounts/use-trustwallet-account), [SimpleAccount](/permissionless/how-to/accounts/use-simple-account)) and what paymaster logic you want to use. ```ts -import { createSmartAccountClient, walletClientToSmartAccountSigner } from "permissionless"; +import { createSmartAccountClient, walletClientToSmartAccountSigner, ENTRYPOINT_ADDRESS_V06 } from "permissionless"; import { signerToSimpleSmartAccount } from "permissionless/accounts"; import { useWalletClient } from "wagmi"; +import { createPublicClient, http, zeroAddress } from "viem"; +import { sepolia } from "viem/chains"; const { data: walletClient } = useWalletClient() +const publicClient = createPublicClient({ + chain: sepolia, // or whatever chain you are using + transport: http() +}) + const signer = walletClientToSmartAccountSigner(walletClient) const simpleSmartAccountClient = await signerToSimpleSmartAccount(publicClient, { - entryPoint: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", - signer: signer, - factoryAddress: "0x9406Cc6185a346906296840746125a0E44976454" + entryPoint: ENTRYPOINT_ADDRESS_V06, + signer, }) const smartAccountClient = createSmartAccountClient({ - account: safeAccount, - entryPoint: ENTRYPOINT_ADDRESS_V06, - chain: sepolia, - bundlerTransport: http("https://api.pimlico.io/v2/sepolia/rpc?apikey=API_KEY"), - middleware: { - gasPrice: async () => (await pimlicoBundlerClient.getUserOperationGasPrice()).fast, // use pimlico bundler to get gas prices, if using pimlico - sponsorUserOperation: paymasterClient.sponsorUserOperation, // optional - }, + account: simpleSmartAccountClient, + entryPoint: ENTRYPOINT_ADDRESS_V06, + chain: sepolia, // or whatever chain you are using + bundlerTransport: http("", { + timeout: 30_000 // optional + }), + middleware: { + gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast, + sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation, + }, }) ``` diff --git a/docs/pages/permissionless/how-to/signers/web3auth.mdx b/docs/pages/permissionless/how-to/signers/web3auth.mdx index d2029487..40be5419 100644 --- a/docs/pages/permissionless/how-to/signers/web3auth.mdx +++ b/docs/pages/permissionless/how-to/signers/web3auth.mdx @@ -25,4 +25,6 @@ After following the Web3Auth documentation, you will have access to a `web3auth` ### Use with permissionless.js - \ No newline at end of file + + +For a full example, see the [example permissionless + Web3Auth app](https://github.com/pimlicolabs/web3auth-demo/blob/main/src/components/web3auth/web3auth.tsx). diff --git a/docs/pages/permissionless/reference/erc7579-actions/accountId.mdx b/docs/pages/permissionless/reference/erc7579-actions/accountId.mdx index 10749cf5..13d250be 100644 --- a/docs/pages/permissionless/reference/erc7579-actions/accountId.mdx +++ b/docs/pages/permissionless/reference/erc7579-actions/accountId.mdx @@ -1,6 +1,6 @@ # accountId -Gets the accountId of the smart account as defined in [ERC7579](https://eips.ethereum.org/EIPS/eip-7579). Check out [this guide](/permissionless/how-to/accounts/user-erc7579-actions) for a complete tutorial. +Gets the accountId of the smart account as defined in [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579). Check out [this guide](/permissionless/how-to/accounts/use-erc7579-account) for a complete tutorial. ## Usage @@ -32,4 +32,4 @@ The account id of the smart account. - **Type:** `SmartAccount` -If your SmartAccountClient doesn't have an account, you should provide one here. +If your `SmartAccountClient` doesn't have an account, you should provide one here. diff --git a/docs/pages/permissionless/reference/erc7579-actions/installModule.mdx b/docs/pages/permissionless/reference/erc7579-actions/installModule.mdx index 6addba2d..fbb2522a 100644 --- a/docs/pages/permissionless/reference/erc7579-actions/installModule.mdx +++ b/docs/pages/permissionless/reference/erc7579-actions/installModule.mdx @@ -1,6 +1,6 @@ # installModule -Installs a [ERC7579](https://eips.ethereum.org/EIPS/eip-7579) module to the smart account. Check out [this guide](/permissionless/how-to/accounts/user-erc7579-actions) for a complete tutorial. +Installs a [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) module to the smart account. Check out [this guide](/permissionless/how-to/accounts/use-erc7579-account) for a complete tutorial. ## Usage @@ -27,7 +27,7 @@ Installs a [ERC7579](https://eips.ethereum.org/EIPS/eip-7579) module to the smar The user operation hash. :::warning -This is user operation hash, not transaction hash, you must use `waitForUserOperationReceipt` to wait for the user operation to be included on-chain. +This is a user operation hash, not a transaction hash, you must use `waitForUserOperationReceipt` to wait for the user operation to be included onchain. ::: ## Parameters @@ -48,22 +48,22 @@ Type of the module to install. Accepted values are `"validator" | "executor" | " - **Type:** `Hex` -Context bytes that will be passed to the module as part of initData. +Context bytes that will be passed to the module as part of `initData`. ### maxFeePerGas (optional) - **Type:** `bigint` -The maximum fee per gas that the user is willing to pay for this transaction. If not provided, the bundler will use its own recommendation. +The maximum fee per gas that the user is willing to pay for this user operation. If not provided, the bundler will use its own recommendation. ### maxPriorityFeePerGas (optional) - **Type:** `bigint` -The maximum priority fee per gas that the user is willing to pay for this transaction. If not provided, the bundler will use its own recommendation. +The maximum priority fee per gas that the user is willing to pay for this user operation. If not provided, the bundler will use its own recommendation. ### nonce (optional) - **Type:** `bigint` -The nonce of the smart account that will be used to send this transaction. If not provided, current nonce will be used. +The nonce of the smart account that will be used to send this user operatino. If not provided, current nonce will be used. diff --git a/docs/pages/permissionless/reference/erc7579-actions/isModuleInstalled.mdx b/docs/pages/permissionless/reference/erc7579-actions/isModuleInstalled.mdx index 689f2268..2a47f26e 100644 --- a/docs/pages/permissionless/reference/erc7579-actions/isModuleInstalled.mdx +++ b/docs/pages/permissionless/reference/erc7579-actions/isModuleInstalled.mdx @@ -1,6 +1,6 @@ # isModuleInstalled -Checks if a [ERC7579](https://eips.ethereum.org/EIPS/eip-7579) module is installed on the smart account. Check out [this guide](/permissionless/how-to/accounts/user-erc7579-actions) for a complete tutorial. +Checks if an [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) module is installed on the smart account. Check out [this guide](/permissionless/how-to/accounts/use-erc7579-account) for a complete tutorial. ## Usage @@ -44,4 +44,4 @@ Type of the module to install. Accepted values are `"validator" | "executor" | " - **Type:** `Hex` -Context bytes that will be passed to the module as part of additionalContext. +Context bytes that will be passed to the module as part of `additionalContext`. diff --git a/docs/pages/permissionless/reference/erc7579-actions/supportsExecutionMode.mdx b/docs/pages/permissionless/reference/erc7579-actions/supportsExecutionMode.mdx index c4264bc9..09d2e14d 100644 --- a/docs/pages/permissionless/reference/erc7579-actions/supportsExecutionMode.mdx +++ b/docs/pages/permissionless/reference/erc7579-actions/supportsExecutionMode.mdx @@ -1,8 +1,10 @@ # supportsExecutionMode -Checks if a [ERC7579](https://eips.ethereum.org/EIPS/eip-7579) execution mode is supported on the smart account. Check out [this guide](/permissionless/how-to/accounts/user-erc7579-actions) for a complete tutorial. +Checks if a [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) execution mode is supported on the smart account. Check out [this guide](/permissionless/how-to/accounts/use-erc7579-account) for a complete tutorial. -NOTE: According to spec, not all execution modes must be supported. So use this function to check if the execution mode is supported before using it. +:::info +According to the specification, not all execution modes must be supported. So it is recommended to use this function to check if the execution mode is supported before using it. +::: ## Usage @@ -46,10 +48,10 @@ If true, the execution will revert if the call fails. Defaults to false. - **Type:** `Hex` -The selector of the function to call. If not provided, "0x" will be used. +The selector of the function to call. If not provided, `0x` will be used. ### context (optional) - **Type:** `Hex` -Context bytes that will be passed to the module as part of modeContext. +Context bytes that will be passed to the module as part of `modeContext`. diff --git a/docs/pages/permissionless/reference/erc7579-actions/supportsModule.mdx b/docs/pages/permissionless/reference/erc7579-actions/supportsModule.mdx index f706397a..d4c13268 100644 --- a/docs/pages/permissionless/reference/erc7579-actions/supportsModule.mdx +++ b/docs/pages/permissionless/reference/erc7579-actions/supportsModule.mdx @@ -1,6 +1,6 @@ # supportsModule -Checks if a [ERC7579](https://eips.ethereum.org/EIPS/eip-7579) module type is supported by the smart account. Check out [this guide](/permissionless/how-to/accounts/user-erc7579-actions) for a complete tutorial. +Checks if a [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) module type is supported by the smart account. Check out [this guide](/permissionless/how-to/accounts/use-erc7579-account) for a complete tutorial. ## Usage diff --git a/docs/pages/permissionless/reference/erc7579-actions/uninstallModule.mdx b/docs/pages/permissionless/reference/erc7579-actions/uninstallModule.mdx index 76e7d938..46db3b49 100644 --- a/docs/pages/permissionless/reference/erc7579-actions/uninstallModule.mdx +++ b/docs/pages/permissionless/reference/erc7579-actions/uninstallModule.mdx @@ -1,6 +1,6 @@ # uninstallModule -Uninstalls a [ERC7579](https://eips.ethereum.org/EIPS/eip-7579) module from the smart account. Check out [this guide](/permissionless/how-to/accounts/user-erc7579-actions) for a complete tutorial. +Uninstalls a [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) module from the smart account. Check out [this guide](/permissionless/how-to/accounts/use-erc7579-account) for a complete tutorial. ## Usage @@ -27,7 +27,7 @@ Uninstalls a [ERC7579](https://eips.ethereum.org/EIPS/eip-7579) module from the The user operation hash. :::warning -This is user operation hash, not transaction hash, you must use `waitForUserOperationReceipt` to wait for the user operation to be included on-chain. +This is a user operation hash, not a transaction hash, you must use `waitForUserOperationReceipt` to wait for the user operation to be included onchain. ::: ## Parameters @@ -48,22 +48,22 @@ Type of the module to uninstall. Accepted values are `"validator" | "executor" | - **Type:** `Hex` -Context bytes that will be passed to the module as part of deInitData. +Context bytes that will be passed to the module as part of `deInitData`. ### maxFeePerGas (optional) - **Type:** `bigint` -The maximum fee per gas that the user is willing to pay for this transaction. If not provided, the bundler will use its own recommendation. +The maximum fee per gas that the user is willing to pay for this user operation. If not provided, the bundler will use its own recommendation. ### maxPriorityFeePerGas (optional) - **Type:** `bigint` -The maximum priority fee per gas that the user is willing to pay for this transaction. If not provided, the bundler will use its own recommendation. +The maximum priority fee per gas that the user is willing to pay for this user operation. If not provided, the bundler will use its own recommendation. ### nonce (optional) - **Type:** `bigint` -The nonce of the smart account that will be used to send this transaction. If not provided, current nonce will be used. +The nonce of the smart account that will be used to send this user operation. If not provided, current nonce will be used. diff --git a/docs/pages/permissionless/tutorial/tutorial-3.mdx b/docs/pages/permissionless/tutorial/tutorial-3.mdx index c8d3b04c..8ad681e5 100644 --- a/docs/pages/permissionless/tutorial/tutorial-3.mdx +++ b/docs/pages/permissionless/tutorial/tutorial-3.mdx @@ -78,18 +78,14 @@ Since we will be looking to fund our account with USDC (which is what we will us Let's run this code with `npm start`. You should see something like this: ```txt -Smart account address: https://sepolia.etherscan.io/address/0xbAd38BdCf884ED92ab370f69C0CD0B7b8a1459A1 +Smart account address: https://sepolia.basescan.org/address/0xbAd38BdCf884ED92ab370f69C0CD0B7b8a1459A1 ``` ### Get Testnet USDC on Sepolia Let's get some USDC on the Sepolia testnet to the counterfactual address of the wallet we will be deploying. This will be used to pay for the gas fees of the user operation we will be submitting. -The recommended way to do this is to use the [USDC faucet](https://usdcfaucet.com/), select 'Ethereum Sepolia' and enter the counterfactual sender address you generated in the previous step. - -:::tip -Alternatively, if the faucet does not work, you can get some Sepolia ETH. Then, if you're using Metamask, [switch your chain to Sepolia](https://chainlist.org/chain/11155111) and then [visit this page to swap some of the Sepolia ETH to testnet USDC on Uniswap](https://app.uniswap.org/#/swap?inputCurrency=ETH&outputCurrency=0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238&exactAmount=1&exactField=input&chain=sepolia) and then send that USDC to the counterfactual sender address. -::: +The recommended way to do this is to use the [USDC faucet](https://usdcfaucet.com/), select 'Base Sepolia' and enter the counterfactual sender address you generated in the previous step. ### Verify you have USDC on the counterfactual sender address @@ -136,10 +132,10 @@ Add the following to the bottom of `index.ts`: Let's run this code again with `npm start`. You should see the transaction hash bundling the user operation on-chain printed to the console. ```txt -User operation included: https://sepolia.etherscan.io/tx/0xf8e4fc41a134fc9530a0c019167f9dc0981874b90187717605355bdcce8b2fb7 +User operation included: https://sepolia.basescan.org/tx/0xf8e4fc41a134fc9530a0c019167f9dc0981874b90187717605355bdcce8b2fb7 ``` -You can now view the transaction on the Sepolia testnet explorer. By sending this user operation, you have: +You can now view the transaction on the Base Sepolia testnet explorer. By sending this user operation, you have: - Deployed the counterfactual smart account contract - Had your smart account approve the ERC-20 Paymaster to spend USDC during deployment - Had this newly-deployed smart account verify the private key's signature @@ -147,7 +143,7 @@ You can now view the transaction on the Sepolia testnet explorer. By sending thi - Executed a simple transaction to `vitalik.eth`'s address -If you visit the address of the `sender` account on the [Sepolia explorer](https://sepolia.etherscan.io), you should also see that some of your USDC balance has been deducted! +If you visit the address of the `sender` account on the [Base Sepolia explorer](https://sepolia.basescan.org), you should also see that some of your USDC balance has been deducted! That's it! Congratulations! diff --git a/docs/public/tracking.png b/docs/public/tracking.png new file mode 100644 index 00000000..44d99d6b Binary files /dev/null and b/docs/public/tracking.png differ diff --git a/docs/snippets/signers/accounts/biconomySmartAccount.ts b/docs/snippets/signers/accounts/biconomySmartAccount.ts index 7a297f62..071daaa9 100644 --- a/docs/snippets/signers/accounts/biconomySmartAccount.ts +++ b/docs/snippets/signers/accounts/biconomySmartAccount.ts @@ -1,13 +1,26 @@ const smartAccountSigner = privateKeyToAccount(generatePrivateKey()) -import { ENTRYPOINT_ADDRESS_V06 } from "permissionless" +import { ENTRYPOINT_ADDRESS_V06, createSmartAccountClient } from "permissionless" // [!region main] import { signerToBiconomySmartAccount } from "permissionless/accounts" +import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" import { createPublicClient, http } from "viem" import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" import { sepolia } from "viem/chains" -export const publicClient = createPublicClient({ +const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=` + +const pimlicoPaymaster = createPimlicoPaymasterClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06 +}) + +const bundlerClient = createPimlicoBundlerClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06, +}) + +const publicClient = createPublicClient({ transport: http("https://rpc.ankr.com/eth_sepolia"), chain: sepolia, }) @@ -16,4 +29,17 @@ const smartAccount = await signerToBiconomySmartAccount(publicClient, { signer: smartAccountSigner, entryPoint: ENTRYPOINT_ADDRESS_V06, }) + +const smartAccountClient = createSmartAccountClient({ + account: smartAccount, + entryPoint: ENTRYPOINT_ADDRESS_V06, + chain: sepolia, // or whatever chain you are using + bundlerTransport: http(pimlicoRpcUrl, { + timeout: 30_000 // optional + }), + middleware: { + gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast, + sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation, + }, +}) // [!endregion main] diff --git a/docs/snippets/signers/accounts/ecdsaKernelSmartAccount.ts b/docs/snippets/signers/accounts/ecdsaKernelSmartAccount.ts index 2bb0b3d4..5f939435 100644 --- a/docs/snippets/signers/accounts/ecdsaKernelSmartAccount.ts +++ b/docs/snippets/signers/accounts/ecdsaKernelSmartAccount.ts @@ -1,13 +1,26 @@ const smartAccountSigner = privateKeyToAccount(generatePrivateKey()) -import { ENTRYPOINT_ADDRESS_V06 } from "permissionless" +import { ENTRYPOINT_ADDRESS_V06, createSmartAccountClient } from "permissionless" // [!region main] import { signerToEcdsaKernelSmartAccount } from "permissionless/accounts" +import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" import { createPublicClient, http } from "viem" import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" import { sepolia } from "viem/chains" -export const publicClient = createPublicClient({ +const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=` + +const pimlicoPaymaster = createPimlicoPaymasterClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06 +}) + +const bundlerClient = createPimlicoBundlerClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06, +}) + +const publicClient = createPublicClient({ transport: http("https://rpc.ankr.com/eth_sepolia"), chain: sepolia, }) @@ -16,4 +29,17 @@ const smartAccount = await signerToEcdsaKernelSmartAccount(publicClient, { signer: smartAccountSigner, entryPoint: ENTRYPOINT_ADDRESS_V06, }) + +const smartAccountClient = createSmartAccountClient({ + account: smartAccount, + entryPoint: ENTRYPOINT_ADDRESS_V06, + chain: sepolia, // or whatever chain you are using + bundlerTransport: http(pimlicoRpcUrl, { + timeout: 30_000 // optional + }), + middleware: { + gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast, + sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation, + }, +}) // [!endregion main] diff --git a/docs/snippets/signers/accounts/safeSmartAccount.ts b/docs/snippets/signers/accounts/safeSmartAccount.ts index 7dd373e1..eacb3e07 100644 --- a/docs/snippets/signers/accounts/safeSmartAccount.ts +++ b/docs/snippets/signers/accounts/safeSmartAccount.ts @@ -1,13 +1,26 @@ const smartAccountSigner = privateKeyToAccount(generatePrivateKey()) -import { ENTRYPOINT_ADDRESS_V06 } from "permissionless" +import { ENTRYPOINT_ADDRESS_V06, createSmartAccountClient } from "permissionless" // [!region main] import { signerToSafeSmartAccount } from "permissionless/accounts" +import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" import { createPublicClient, http } from "viem" import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" import { sepolia } from "viem/chains" -export const publicClient = createPublicClient({ +const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=` + +const pimlicoPaymaster = createPimlicoPaymasterClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06 +}) + +const bundlerClient = createPimlicoBundlerClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06, +}) + +const publicClient = createPublicClient({ transport: http("https://rpc.ankr.com/eth_sepolia"), chain: sepolia, }) @@ -17,4 +30,17 @@ const smartAccount = await signerToSafeSmartAccount(publicClient, { safeVersion: "1.4.1", entryPoint: ENTRYPOINT_ADDRESS_V06, }) + +const smartAccountClient = createSmartAccountClient({ + account: smartAccount, + entryPoint: ENTRYPOINT_ADDRESS_V06, + chain: sepolia, // or whatever chain you are using + bundlerTransport: http(pimlicoRpcUrl, { + timeout: 30_000 // optional + }), + middleware: { + gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast, + sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation, + }, +}) // [!endregion main] diff --git a/docs/snippets/signers/accounts/simpleSmartAccount.ts b/docs/snippets/signers/accounts/simpleSmartAccount.ts index f07bc659..b55baf93 100644 --- a/docs/snippets/signers/accounts/simpleSmartAccount.ts +++ b/docs/snippets/signers/accounts/simpleSmartAccount.ts @@ -1,20 +1,46 @@ const smartAccountSigner = privateKeyToAccount(generatePrivateKey()) -import { ENTRYPOINT_ADDRESS_V06 } from "permissionless" +import { ENTRYPOINT_ADDRESS_V06, createSmartAccountClient } from "permissionless" // [!region main] import { signerToSimpleSmartAccount } from "permissionless/accounts" +import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" import { createPublicClient, http } from "viem" import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" import { sepolia } from "viem/chains" -export const publicClient = createPublicClient({ +const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=` + +const pimlicoPaymaster = createPimlicoPaymasterClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06 +}) + +const bundlerClient = createPimlicoBundlerClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06, +}) + +const publicClient = createPublicClient({ transport: http("https://rpc.ankr.com/eth_sepolia"), chain: sepolia, }) const smartAccount = await signerToSimpleSmartAccount(publicClient, { signer: smartAccountSigner, - factoryAddress: "0x9406Cc6185a346906296840746125a0E44976454", entryPoint: ENTRYPOINT_ADDRESS_V06, }) + +const smartAccountClient = createSmartAccountClient({ + account: smartAccount, + entryPoint: ENTRYPOINT_ADDRESS_V06, + chain: sepolia, // or whatever chain you are using + bundlerTransport: http(pimlicoRpcUrl, { + timeout: 30_000 // optional + }), + middleware: { + gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast, + sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation, + }, +}) + // [!endregion main] diff --git a/docs/snippets/signers/accounts/trustSmartAccount.ts b/docs/snippets/signers/accounts/trustSmartAccount.ts index ab991bda..6277ece1 100644 --- a/docs/snippets/signers/accounts/trustSmartAccount.ts +++ b/docs/snippets/signers/accounts/trustSmartAccount.ts @@ -1,13 +1,26 @@ const smartAccountSigner = privateKeyToAccount(generatePrivateKey()) -import { ENTRYPOINT_ADDRESS_V06 } from "permissionless" +import { ENTRYPOINT_ADDRESS_V06, createSmartAccountClient } from "permissionless" // [!region main] import { signerToTrustSmartAccount } from "permissionless/accounts" +import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" import { createPublicClient, http } from "viem" import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" import { sepolia } from "viem/chains" -export const publicClient = createPublicClient({ +const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=` + +const pimlicoPaymaster = createPimlicoPaymasterClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06 +}) + +const bundlerClient = createPimlicoBundlerClient({ + transport: http(pimlicoRpcUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06, +}) + +const publicClient = createPublicClient({ transport: http("https://rpc.ankr.com/eth_sepolia"), chain: sepolia, }) @@ -16,4 +29,17 @@ const smartAccount = await signerToTrustSmartAccount(publicClient, { signer: smartAccountSigner, entryPoint: ENTRYPOINT_ADDRESS_V06, }) + +const smartAccountClient = createSmartAccountClient({ + account: smartAccount, + entryPoint: ENTRYPOINT_ADDRESS_V06, + chain: sepolia, // or whatever chain you are using + bundlerTransport: http(pimlicoRpcUrl, { + timeout: 30_000 // optional + }), + middleware: { + gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast, + sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation, + }, +}) // [!endregion main] diff --git a/docs/snippets/signers/passport/passportKeySigner.ts b/docs/snippets/signers/passport/passportKeySigner.ts index a2bee174..5cb2579b 100644 --- a/docs/snippets/signers/passport/passportKeySigner.ts +++ b/docs/snippets/signers/passport/passportKeySigner.ts @@ -26,5 +26,5 @@ const client = await createPassportClient( "https://tiramisu.0xpass.io" ); -const signer = walletClientToSmartAccountSigner(client); +const smartAccountSigner = walletClientToSmartAccountSigner(client); // [!endregion main] diff --git a/docs/snippets/signers/passport/passportWebauthnSigner.ts b/docs/snippets/signers/passport/passportWebauthnSigner.ts index 533f9458..b2566a80 100644 --- a/docs/snippets/signers/passport/passportWebauthnSigner.ts +++ b/docs/snippets/signers/passport/passportWebauthnSigner.ts @@ -35,5 +35,5 @@ const client = await createPassportClient( "https://tiramisu.0xpass.io" ); -const signer = walletClientToSmartAccountSigner(client); +const smartAccountSigner = walletClientToSmartAccountSigner(client); // [!endregion main] diff --git a/docs/snippets/tutorial-1.ts b/docs/snippets/tutorial-1.ts index 26511203..e5489435 100644 --- a/docs/snippets/tutorial-1.ts +++ b/docs/snippets/tutorial-1.ts @@ -54,7 +54,9 @@ const smartAccountClient = createSmartAccountClient({ account, entryPoint: ENTRYPOINT_ADDRESS_V07, chain: sepolia, - bundlerTransport: http(bundlerUrl), + bundlerTransport: http(bundlerUrl, { + timeout: 30_000 // Wait 30 seconds for user operation to be included + }), middleware: { gasPrice: async () => { return (await bundlerClient.getUserOperationGasPrice()).fast diff --git a/docs/snippets/tutorial-2.ts b/docs/snippets/tutorial-2.ts index 1b825598..068e8725 100644 --- a/docs/snippets/tutorial-2.ts +++ b/docs/snippets/tutorial-2.ts @@ -28,7 +28,9 @@ const apiKey = "YOUR_PIMLICO_API_KEY" // REPLACE THIS const endpointUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=${apiKey}` const bundlerClient = createClient({ - transport: http(endpointUrl), + transport: http(endpointUrl, { + timeout: 30_000 + }), chain: sepolia, }) .extend(bundlerActions(ENTRYPOINT_ADDRESS_V07)) diff --git a/docs/snippets/tutorial-3.ts b/docs/snippets/tutorial-3.ts index 30333c3d..fbbd0e54 100644 --- a/docs/snippets/tutorial-3.ts +++ b/docs/snippets/tutorial-3.ts @@ -6,11 +6,11 @@ import { pimlicoPaymasterActions } from "permissionless/actions/pimlico" import { createPimlicoBundlerClient } from "permissionless/clients/pimlico" import { type Hex, createPublicClient, encodeFunctionData, http, parseAbiItem } from "viem" import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" -import { sepolia } from "viem/chains" +import { baseSepolia } from "viem/chains" // [!region clients] -const erc20PaymasterAddress = "0x000000000041F3aFe8892B48D88b6862efe0ec8d" -const usdcAddress = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238" +const erc20PaymasterAddress = "0x00000000002E3A39aFEf1132214fEee5a55ce127" +const usdcAddress = "0x036CbD53842c5426634e7929541eC2318f3dCF7e" const privateKey = (process.env.PRIVATE_KEY as Hex) ?? @@ -21,11 +21,11 @@ const privateKey = })() const publicClient = createPublicClient({ - transport: http("https://rpc.ankr.com/eth_sepolia"), + transport: http("https://sepolia.base.org"), }) const apiKey = "YOUR_PIMLICO_API_KEY" -const bundlerUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=${apiKey}` +const bundlerUrl = `https://api.pimlico.io/v2/84532/rpc?apikey=${apiKey}` const bundlerClient = createPimlicoBundlerClient({ transport: http(bundlerUrl), @@ -53,7 +53,7 @@ const account = await signerToSafeSmartAccount(publicClient, { ], }) -console.log(`Smart account address: https://sepolia.etherscan.io/address/${account.address}`) +console.log(`Smart account address: https://sepolia.basescan.org/address/${account.address}`) // [!endregion smartAccount] // [!region checkBalance] @@ -68,7 +68,7 @@ if (senderUsdcBalance < 1_000_000n) { throw new Error( `insufficient USDC balance for counterfactual wallet address ${account.address}: ${ Number(senderUsdcBalance) / 1000000 - } USDC, required at least 1 USDC. Load up balance at https://faucet.circle.com/`, + } USDC, required at least 1 USDC. Load up balance at https://faucet.circle.com/ (Base Sepolia)`, ) } @@ -79,7 +79,7 @@ console.log(`Smart account USDC balance: ${Number(senderUsdcBalance) / 1000000} const smartAccountClient = createSmartAccountClient({ account, entryPoint: ENTRYPOINT_ADDRESS_V07, - chain: sepolia, + chain: baseSepolia, bundlerTransport: http(bundlerUrl), middleware: { gasPrice: async () => { @@ -109,5 +109,5 @@ const txHash = await smartAccountClient.sendTransaction({ data: "0x1234", }) -console.log(`User operation included: https://sepolia.etherscan.io/tx/${txHash}`) +console.log(`User operation included: https://sepolia.basescan.org/tx/${txHash}`) // [!endregion submit] diff --git a/vercel.json b/vercel.json index dbcdd39c..20379b09 100644 --- a/vercel.json +++ b/vercel.json @@ -22,6 +22,11 @@ "destination": "/infra/bundler/entrypoint-errors/:match", "permanent": false }, + { + "source": "/pricing", + "destination": "/infra/platform/pricing", + "permanent": false + }, { "source": "/docs/:match*", "destination": "/", diff --git a/vocs.config.tsx b/vocs.config.tsx index 7c3d02ac..20ac259f 100644 --- a/vocs.config.tsx +++ b/vocs.config.tsx @@ -1,277 +1,295 @@ -import { defineConfig } from "vocs"; -import viteConfig from "./utils"; +import { defineConfig } from "vocs" +import viteConfig from "./utils" export const platformSidebar = [ - { - text: "Overview", - link: "/infra/platform", - }, - { - text: "Pricing", - link: "/infra/platform/pricing", - }, - { - text: "Supported Chains", - link: "/infra/platform/supported-chains", - }, - { - text: "Sponsorship Policies", - items: [ - { - text: "How to use sponsorship policies", - link: "/infra/platform/sponsorship-policies", - }, - ], - }, -]; + { + text: "Overview", + link: "/infra/platform", + }, + { + text: "Pricing", + link: "/infra/platform/pricing", + }, + { + text: "Why Pimlico", + link: "/infra/platform/why-pimlico", + }, + { + text: "Supported Chains", + link: "/infra/platform/supported-chains", + }, + { + text: "Sponsorship Policies", + items: [ + { + text: "How to use sponsorship policies", + link: "/infra/platform/sponsorship-policies", + }, + { + text: "How to use a webhook", + link: "/infra/platform/sponsorship-policies/webhook", + }, + ], + }, + { + text: "Debugging", + items: [ + { + text: "How to debug dropped user operations", + link: "/infra/platform/debugging/dropped-user-operations", + }, + ], + }, +] export const bundlerSidebar = [ - { - text: "Overview", - link: "/infra/bundler", - }, - { - text: "How to use the bundler", - link: "/infra/bundler/usage", - }, - { text: "FAQs", link: "/infra/bundler/faqs" }, - { - text: "Compression", - items: [ - { - text: "How to create your own inflator contract and submit compressed user operations", - link: "/infra/bundler/compression", - }, - { - text: "Contracts Reference", - link: "/infra/bundler/compression/reference", - }, - ], - }, - { - text: "Endpoints", - collapsed: false, - items: [ - { - text: "eth_sendUserOperation", - link: "/infra/bundler/endpoints/eth_sendUserOperation", - }, - { - text: "eth_estimateUserOperationGas", - link: "/infra/bundler/endpoints/eth_estimateUserOperationGas", - }, - { - text: "eth_getUserOperationReceipt", - link: "/infra/bundler/endpoints/eth_getUserOperationReceipt", - }, - { - text: "eth_getUserOperationByHash", - link: "/infra/bundler/endpoints/eth_getUserOperationByHash", - }, - { - text: "eth_supportedEntryPoints", - link: "/infra/bundler/endpoints/eth_supportedEntryPoints", - }, - { - text: "pimlico_sendCompressedUserOperation", - link: "/infra/bundler/endpoints/pimlico_sendCompressedUserOperation", - }, - { - text: "pimlico_getUserOperationGasPrice", - link: "/infra/bundler/endpoints/pimlico_getUserOperationGasPrice", - }, - { - text: "pimlico_getUserOperationStatus", - link: "/infra/bundler/endpoints/pimlico_getUserOperationStatus", - }, - ], - }, - { - text: "Bundler Errors", - collapsed: true, - items: [ - { - text: "Invalid 'apikey' query parameter", - link: "/infra/bundler/bundler-errors/invalid-api-key", - }, - { - text: "Chain is not supported", - link: "/infra/bundler/bundler-errors/chain-not-supported", - }, - { - text: "Validation Error: Invalid Discriminator Value", - link: "/infra/bundler/bundler-errors/invalid-discriminator-value", - }, - { - text: "Unknown error from alto bundler", - link: "/infra/bundler/bundler-errors/unknown-error", - }, - ], - }, - { - text: "EntryPoint Errors", - collapsed: true, - items: [ - { - text: "AA10 sender already constructed", - link: "/infra/bundler/entrypoint-errors/aa10", - }, - { - text: "AA13 initCode failed or OOG", - link: "/infra/bundler/entrypoint-errors/aa13", - }, - { - text: "AA14 initCode must return sender", - link: "/infra/bundler/entrypoint-errors/aa14", - }, - { - text: "AA15 initCode must create sender", - link: "/infra/bundler/entrypoint-errors/aa15", - }, - { - text: "AA20 account not deployed", - link: "/infra/bundler/entrypoint-errors/aa20", - }, - { - text: "AA21 didn't pay prefund", - link: "/infra/bundler/entrypoint-errors/aa21", - }, - { - text: "AA22 expired or not due", - link: "/infra/bundler/entrypoint-errors/aa22", - }, - { text: "AA23 reverted", link: "/infra/bundler/entrypoint-errors/aa23" }, - { - text: "AA24 signature error", - link: "/infra/bundler/entrypoint-errors/aa24", - }, - { - text: "AA25 invalid account nonce", - link: "/infra/bundler/entrypoint-errors/aa25", - }, - { - text: "AA30 paymaster not deployed", - link: "/infra/bundler/entrypoint-errors/aa30", - }, - { - text: "AA31 paymaster deposit too low", - link: "/infra/bundler/entrypoint-errors/aa31", - }, - { - text: "AA32 paymaster expired or not due", - link: "/infra/bundler/entrypoint-errors/aa32", - }, - { text: "AA33 reverted", link: "/infra/bundler/entrypoint-errors/aa33" }, - { - text: "AA34 signature error", - link: "/infra/bundler/entrypoint-errors/aa34", - }, - { - text: "AA40 over verificationGasLimit", - link: "/infra/bundler/entrypoint-errors/aa40", - }, - { - text: "AA41 too little verificationGas", - link: "/infra/bundler/entrypoint-errors/aa41", - }, - { - text: "AA50 postOp reverted", - link: "/infra/bundler/entrypoint-errors/aa50", - }, - { - text: "AA51 prefund below actualGasCost", - link: "/infra/bundler/entrypoint-errors/aa51", - }, - { - text: "AA90 invalid beneficiary", - link: "/infra/bundler/entrypoint-errors/aa90", - }, - { - text: "AA91 failed send to beneficiary", - link: "/infra/bundler/entrypoint-errors/aa91", - }, - { - text: "AA92 internal call only", - link: "/infra/bundler/entrypoint-errors/aa92", - }, - { - text: "AA93 invalid paymasterAndData", - link: "/infra/bundler/entrypoint-errors/aa93", - }, - { - text: "AA94 gas values overflow", - link: "/infra/bundler/entrypoint-errors/aa94", - }, - { - text: "AA95 out of gas", - link: "/infra/bundler/entrypoint-errors/aa95", - }, - { - text: "AA96 invalid aggregator", - link: "/infra/bundler/entrypoint-errors/aa96", - }, - ], - }, -]; + { + text: "Overview", + link: "/infra/bundler", + }, + { + text: "How to use the bundler", + link: "/infra/bundler/usage", + }, + { text: "FAQs", link: "/infra/bundler/faqs" }, + { + text: "Compression", + items: [ + { + text: "How to create your own inflator contract and submit compressed user operations", + link: "/infra/bundler/compression", + }, + { + text: "Contracts Reference", + link: "/infra/bundler/compression/reference", + }, + ], + }, + { + text: "Endpoints", + collapsed: false, + items: [ + { + text: "eth_sendUserOperation", + link: "/infra/bundler/endpoints/eth_sendUserOperation", + }, + { + text: "eth_estimateUserOperationGas", + link: "/infra/bundler/endpoints/eth_estimateUserOperationGas", + }, + { + text: "eth_getUserOperationReceipt", + link: "/infra/bundler/endpoints/eth_getUserOperationReceipt", + }, + { + text: "eth_getUserOperationByHash", + link: "/infra/bundler/endpoints/eth_getUserOperationByHash", + }, + { + text: "eth_supportedEntryPoints", + link: "/infra/bundler/endpoints/eth_supportedEntryPoints", + }, + { + text: "pimlico_sendCompressedUserOperation", + link: "/infra/bundler/endpoints/pimlico_sendCompressedUserOperation", + }, + { + text: "pimlico_getUserOperationGasPrice", + link: "/infra/bundler/endpoints/pimlico_getUserOperationGasPrice", + }, + { + text: "pimlico_getUserOperationStatus", + link: "/infra/bundler/endpoints/pimlico_getUserOperationStatus", + }, + ], + }, + { + text: "Bundler Errors", + collapsed: true, + items: [ + { + text: "Invalid 'apikey' query parameter", + link: "/infra/bundler/bundler-errors/invalid-api-key", + }, + { + text: "Chain is not supported", + link: "/infra/bundler/bundler-errors/chain-not-supported", + }, + { + text: "Validation Error: Invalid Discriminator Value", + link: "/infra/bundler/bundler-errors/invalid-discriminator-value", + }, + { + text: "Unknown error from alto bundler", + link: "/infra/bundler/bundler-errors/unknown-error", + }, + ], + }, + { + text: "EntryPoint Errors", + collapsed: true, + items: [ + { + text: "AA10 sender already constructed", + link: "/infra/bundler/entrypoint-errors/aa10", + }, + { + text: "AA13 initCode failed or OOG", + link: "/infra/bundler/entrypoint-errors/aa13", + }, + { + text: "AA14 initCode must return sender", + link: "/infra/bundler/entrypoint-errors/aa14", + }, + { + text: "AA15 initCode must create sender", + link: "/infra/bundler/entrypoint-errors/aa15", + }, + { + text: "AA20 account not deployed", + link: "/infra/bundler/entrypoint-errors/aa20", + }, + { + text: "AA21 didn't pay prefund", + link: "/infra/bundler/entrypoint-errors/aa21", + }, + { + text: "AA22 expired or not due", + link: "/infra/bundler/entrypoint-errors/aa22", + }, + { text: "AA23 reverted", link: "/infra/bundler/entrypoint-errors/aa23" }, + { + text: "AA24 signature error", + link: "/infra/bundler/entrypoint-errors/aa24", + }, + { + text: "AA25 invalid account nonce", + link: "/infra/bundler/entrypoint-errors/aa25", + }, + { + text: "AA30 paymaster not deployed", + link: "/infra/bundler/entrypoint-errors/aa30", + }, + { + text: "AA31 paymaster deposit too low", + link: "/infra/bundler/entrypoint-errors/aa31", + }, + { + text: "AA32 paymaster expired or not due", + link: "/infra/bundler/entrypoint-errors/aa32", + }, + { text: "AA33 reverted", link: "/infra/bundler/entrypoint-errors/aa33" }, + { + text: "AA34 signature error", + link: "/infra/bundler/entrypoint-errors/aa34", + }, + { + text: "AA40 over verificationGasLimit", + link: "/infra/bundler/entrypoint-errors/aa40", + }, + { + text: "AA41 too little verificationGas", + link: "/infra/bundler/entrypoint-errors/aa41", + }, + { + text: "AA50 postOp reverted", + link: "/infra/bundler/entrypoint-errors/aa50", + }, + { + text: "AA51 prefund below actualGasCost", + link: "/infra/bundler/entrypoint-errors/aa51", + }, + { + text: "AA90 invalid beneficiary", + link: "/infra/bundler/entrypoint-errors/aa90", + }, + { + text: "AA91 failed send to beneficiary", + link: "/infra/bundler/entrypoint-errors/aa91", + }, + { + text: "AA92 internal call only", + link: "/infra/bundler/entrypoint-errors/aa92", + }, + { + text: "AA93 invalid paymasterAndData", + link: "/infra/bundler/entrypoint-errors/aa93", + }, + { + text: "AA94 gas values overflow", + link: "/infra/bundler/entrypoint-errors/aa94", + }, + { + text: "AA95 out of gas", + link: "/infra/bundler/entrypoint-errors/aa95", + }, + { + text: "AA96 invalid aggregator", + link: "/infra/bundler/entrypoint-errors/aa96", + }, + ], + }, +] export const paymasterSidebar = [ - { - text: "Overview", - link: "/infra/paymaster", - }, - { - text: "Verifying Paymaster", - link: "/infra/paymaster/verifying-paymaster", - items: [ - { - text: "How to use the Verifying Paymaster", - link: "/infra/paymaster/verifying-paymaster/usage", - }, - { - text: "Endpoints", - link: "/infra/paymaster/verifying-paymaster/endpoints", - }, - { text: "FAQs", link: "/infra/paymaster/verifying-paymaster/faqs" }, - { - text: "Common Errors", - link: "/infra/paymaster/verifying-paymaster/common-errors", - }, - ], - }, - { - text: "ERC-20 Paymaster", - link: "/infra/paymaster/erc20-paymaster", - items: [ - { text: "Overview", link: "/infra/paymaster/erc20-paymaster" }, - { - text: "Contract Addresses", - link: "/infra/paymaster/erc20-paymaster/contract-addresses", - }, - { - text: "Architecture", - link: "/infra/paymaster/erc20-paymaster/architecture", - }, - { text: "FAQs", link: "/infra/paymaster/erc20-paymaster/faqs" }, - ], - }, - { - text: "ERC-20 Paymaster (legacy)", - collapsed: true, - link: "/infra/paymaster/erc20-paymaster-legacy", - items: [ - { text: "Overview", link: "/infra/paymaster/erc20-paymaster-legacy" }, - { - text: "Contract Addresses", - link: "/infra/paymaster/erc20-paymaster-legacy/contract-addresses", - }, - { - text: "Architecture", - link: "/infra/paymaster/erc20-paymaster-legacy/architecture", - }, - { text: "FAQs", link: "/infra/paymaster/erc20-paymaster-legacy/faqs" }, - ], - }, -]; + { + text: "Overview", + link: "/infra/paymaster", + }, + { + text: "Verifying Paymaster", + link: "/infra/paymaster/verifying-paymaster", + items: [ + { + text: "How to use the Verifying Paymaster", + link: "/infra/paymaster/verifying-paymaster/usage", + }, + { + text: "Endpoints", + link: "/infra/paymaster/verifying-paymaster/endpoints", + }, + { text: "FAQs", link: "/infra/paymaster/verifying-paymaster/faqs" }, + { + text: "Common Errors", + link: "/infra/paymaster/verifying-paymaster/common-errors", + }, + ], + }, + { + text: "ERC-20 Paymaster", + link: "/infra/paymaster/erc20-paymaster", + items: [ + { text: "Overview", link: "/infra/paymaster/erc20-paymaster" }, + { + text: "Contract Addresses", + link: "/infra/paymaster/erc20-paymaster/contract-addresses", + }, + { + text: "Architecture", + link: "/infra/paymaster/erc20-paymaster/architecture", + }, + { text: "Guides", link: "/infra/paymaster/erc20-paymaster/guides" }, + { text: "FAQs", link: "/infra/paymaster/erc20-paymaster/faqs" }, + ], + }, + { + text: "ERC-20 Paymaster (legacy)", + collapsed: true, + link: "/infra/paymaster/erc20-paymaster-legacy", + items: [ + { text: "Overview", link: "/infra/paymaster/erc20-paymaster-legacy" }, + { + text: "Contract Addresses", + link: "/infra/paymaster/erc20-paymaster-legacy/contract-addresses", + }, + { + text: "Architecture", + link: "/infra/paymaster/erc20-paymaster-legacy/architecture", + }, + { text: "FAQs", link: "/infra/paymaster/erc20-paymaster-legacy/faqs" }, + ], + }, +] /* { text: "deployContract", link: "/permissionless/reference/smart-account-actions/deployContract" }, @@ -284,524 +302,521 @@ export const paymasterSidebar = [ */ export const conceptualSidebar = [ - { - text: "Overview", - link: "/conceptual", - }, - { - text: "Account Abstraction", - link: "/conceptual/account-abstraction", - }, - { - text: "ERC-4337", - link: "/conceptual/erc4337", - }, - { - text: "ERC-7579", - link: "/conceptual/erc7579", - }, -]; + { + text: "Overview", + link: "/conceptual", + }, + { + text: "Account Abstraction", + link: "/conceptual/account-abstraction", + }, + { + text: "ERC-4337", + link: "/conceptual/erc4337", + }, + { + text: "ERC-7579", + link: "/conceptual/erc7579", + }, +] export const permissionlessSidebar = [ - { - text: "Overview", - link: "/permissionless", - }, - { - text: "Why permissionless.js", - link: "/permissionless/why", - }, - { - text: "Tutorials", - link: "/permissionless/tutorial", - items: [ - { - text: "1. Send your first gasless transaction", - link: "/permissionless/tutorial/tutorial-1", - }, - { - text: "2. Submit a user operation with a Verifying Paymaster", - link: "/permissionless/tutorial/tutorial-2", - }, - { - text: "3. Submit a user operation with an ERC-20 Paymaster", - link: "/permissionless/tutorial/tutorial-3", - }, - ], - }, - { - text: "How-to Guides", - items: [ - { - text: "Update your existing app to sponsor gas fees for smart account users", - link: "/permissionless/how-to/dapp-gas-sponsorship", - }, - { - text: "Error Handling", - link: "/permissionless/how-to/error-handling", - }, - { - text: "Migration Guide", - link: "/permissionless/how-to/migration-guide", - }, - { - text: "Local Testing", - link: "/permissionless/how-to/local-testing", - }, - { - text: "Accounts", - items: [ - { - text: "EntryPoint support", - link: "/permissionless/how-to/accounts/support", - }, - { - text: "How to use a Safe account", - link: "/permissionless/how-to/accounts/use-safe-account", - }, - { - text: "How to use a Kernel account", - link: "/permissionless/how-to/accounts/use-kernel-account", - }, - { - text: "How to use a SimpleAccount", - link: "/permissionless/how-to/accounts/use-simple-account", - }, - { - text: "How to use a Biconomy account", - link: "/permissionless/how-to/accounts/use-biconomy-account", - }, - { - text: "How to use a LightAccount", - link: "/permissionless/how-to/accounts/use-light-account", - }, - { - text: "How to use a Trust Wallet account", - link: "/permissionless/how-to/accounts/use-trustwallet-account", - }, - { - text: "How to use a Erc 7579 compatible smart account", - link: "/permissionless/how-to/accounts/user-erc7579-actions", - }, - ], - }, - { - text: "Paymasters", - items: [ - { - text: "How to use a custom Paymaster", - link: "/permissionless/how-to/paymasters/use-custom-paymaster", - }, - ], - }, - { - text: "Signers", - link: "/permissionless/how-to/signers", - items: [ - { - text: "How to use a Dynamic signer", - link: "/permissionless/how-to/signers/dynamic", - }, - { - text: "How to use a Privy signer", - link: "/permissionless/how-to/signers/privy", - }, - { - text: "How to use a Passport signer", - link: "/permissionless/how-to/signers/passport", - }, - { - text: "How to use a Lit Protocol signer", - link: "/permissionless/how-to/signers/lit-protocol", - }, - { - text: "How to use a Magic signer", - link: "/permissionless/how-to/signers/magic", - }, - { - text: "How to use a Web3Auth signer", - link: "/permissionless/how-to/signers/web3auth", - }, - { - text: "How to use a Turnkey signer", - link: "/permissionless/how-to/signers/turnkey", - }, - { - text: "How to use a Fireblocks signer", - link: "/permissionless/how-to/signers/fireblocks", - }, - { - text: "How to use a Capsule signer", - link: "/permissionless/how-to/signers/capsule", - }, - { - text: "How to use a DFNS signer", - link: "/permissionless/how-to/signers/dfns", - }, - { - text: "How to use an Arcana Auth signer", - link: "/permissionless/how-to/signers/arcana", - }, - { - text: "How to use a Particle Network signer", - link: "/permissionless/how-to/signers/particle-network", - }, - ], - }, - ], - }, - { - text: "Reference", - link: "/permissionless/reference", - items: [ - { - text: "Clients", - collapsed: false, - items: [ - { - text: "Bundler Client", - link: "/permissionless/reference/clients/bundlerClient", - }, - { - text: "Pimlico Bundler Client", - link: "/permissionless/reference/clients/pimlicoBundlerClient", - }, - { - text: "Pimlico Paymaster Client", - link: "/permissionless/reference/clients/pimlicoPaymasterClient", - }, - { - text: "Smart Account Client", - link: "/permissionless/reference/clients/smartAccountClient", - }, - ], - }, - { - text: "Accounts", - collapsed: false, - items: [ - { - text: "signerToSimpleSmartAccount", - link: "/permissionless/reference/accounts/signerToSimpleSmartAccount", - }, - { - text: "signerToSafeSmartAccount", - link: "/permissionless/reference/accounts/signerToSafeSmartAccount", - }, - { - text: "signerToKernelSmartAccount", - link: "/permissionless/reference/accounts/signerToKernelSmartAccount", - }, - { - text: "signerToLightSmartAccount", - link: "/permissionless/reference/accounts/signerToLightSmartAccount", - }, - { - text: "signerToTrustSmartAccount", - link: "/permissionless/reference/accounts/signerToTrustSmartAccount", - }, - ], - }, - { - text: "Bundler Actions", - collapsed: false, - items: [ - { - text: "sendUserOperation", - link: "/permissionless/reference/bundler-actions/sendUserOperation", - }, - { - text: "estimateUserOperationGas", - link: "/permissionless/reference/bundler-actions/estimateUserOperationGas", - }, - { - text: "getUserOperationReceipt", - link: "/permissionless/reference/bundler-actions/getUserOperationReceipt", - }, - { - text: "waitForUserOperationReceipt", - link: "/permissionless/reference/bundler-actions/waitForUserOperationReceipt", - }, - { - text: "getUserOperationByHash", - link: "/permissionless/reference/bundler-actions/getUserOperationByHash", - }, - { - text: "supportedEntryPoints", - link: "/permissionless/reference/bundler-actions/supportedEntryPoints", - }, - ], - }, - { - text: "Smart Account Actions", - collapsed: false, - items: [ - { - text: "prepareUserOperationRequest", - link: "/permissionless/reference/smart-account-actions/prepareUserOperationRequest", - }, - { - text: "sendTransaction", - link: "/permissionless/reference/smart-account-actions/sendTransaction", - }, - { - text: "sendTransactions", - link: "/permissionless/reference/smart-account-actions/sendTransactions", - }, - { - text: "sendUserOperation", - link: "/permissionless/reference/smart-account-actions/sendUserOperation", - }, - { - text: "deployContract", - link: "/permissionless/reference/smart-account-actions/deployContract", - }, - { - text: "writeContract", - link: "/permissionless/reference/smart-account-actions/writeContract", - }, - { - text: "signMessage", - link: "/permissionless/reference/smart-account-actions/signMessage", - }, - { - text: "signTypedData", - link: "/permissionless/reference/smart-account-actions/signTypedData", - }, - ], - }, - { - text: "Erc7579 Actions", - collapsed: false, - items: [ - { - text: "accountId", - link: "/permissionless/reference/erc7579-actions/accountId", - }, - { - text: "installModule", - link: "/permissionless/reference/erc7579-actions/installModule", - }, - { - text: "uninstallModule", - link: "/permissionless/reference/erc7579-actions/uninstallModule", - }, - { - text: "isModuleInstalled", - link: "/permissionless/reference/erc7579-actions/isModuleInstalled", - }, - { - text: "supportsExecutionMode", - link: "/permissionless/reference/erc7579-actions/supportsExecutionMode", - }, - { - text: "supportsModule", - link: "/permissionless/reference/erc7579-actions/supportsModule", - }, - ], - }, - { - text: "Pimlico Bundler Actions", - collapsed: false, - items: [ - { - text: "sendCompressedUserOperation", - link: "/permissionless/reference/pimlico-bundler-actions/sendCompressedUserOperation", - }, - { - text: "getUserOperationGasPrice", - link: "/permissionless/reference/pimlico-bundler-actions/getUserOperationGasPrice", - }, - { - text: "getUserOperationStatus", - link: "/permissionless/reference/pimlico-bundler-actions/getUserOperationStatus", - }, - ], - }, - { - text: "Pimlico Paymaster Actions", - collapsed: false, - items: [ - { - text: "sponsorUserOperation", - link: "/permissionless/reference/pimlico-paymaster-actions/sponsorUserOperation", - }, - { - text: "validateSponsorshipPolicies", - link: "/permissionless/reference/pimlico-paymaster-actions/validateSponsorshipPolicies", - }, - ], - }, - { - text: "Public Actions", - collapsed: false, - items: [ - { - text: "getSenderAddress", - link: "/permissionless/reference/public-actions/getSenderAddress", - }, - { - text: "getAccountNonce", - link: "/permissionless/reference/public-actions/getAccountNonce", - }, - ], - }, - { - text: "Utilities", - collapsed: false, - items: [ - { - text: "getUserOperationHash", - link: "/permissionless/reference/utils/getUserOperationHash", - }, - { - text: "signUserOperationHashWithECDSA", - link: "/permissionless/reference/utils/signUserOperationHashWithECDSA", - }, - { - text: "getRequiredPrefund", - link: "/permissionless/reference/utils/getRequiredPrefund", - }, - { - text: "walletClientToSmartAccountSigner", - link: "/permissionless/reference/utils/walletClientToSmartAccountSigner", - }, - { - text: "providerToSmartAccountSigner", - link: "/permissionless/reference/utils/providerToSmartAccountSigner", - }, - ], - }, - { - text: "Glossary", - collapsed: false, - items: [ - { text: "Errors", link: "/permissionless/reference/glossary/errors" }, - ], - }, - ], - }, - { - text: "Experimental", - collapsed: false, - items: [ - { - text: "EIP-7677", - collapsed: false, - items: [ - { - text: "getPaymasterData", - link: "/permissionless/experimental/eip7677/getPaymasterData", - }, - { - text: "getPaymasterStubData", - link: "/permissionless/experimental/eip7677/getPaymasterStubData", - }, - ], - }, - ], - }, -]; + { + text: "Overview", + link: "/permissionless", + }, + { + text: "Why permissionless.js", + link: "/permissionless/why", + }, + { + text: "Tutorials", + link: "/permissionless/tutorial", + items: [ + { + text: "1. Send your first gasless transaction", + link: "/permissionless/tutorial/tutorial-1", + }, + { + text: "2. Submit a user operation with a Verifying Paymaster", + link: "/permissionless/tutorial/tutorial-2", + }, + { + text: "3. Submit a user operation with an ERC-20 Paymaster", + link: "/permissionless/tutorial/tutorial-3", + }, + ], + }, + { + text: "How-to Guides", + items: [ + { + text: "Update your existing app to sponsor gas fees for smart account users", + link: "/permissionless/how-to/dapp-gas-sponsorship", + }, + { + text: "Error Handling", + link: "/permissionless/how-to/error-handling", + }, + { + text: "Migration Guide", + link: "/permissionless/how-to/migration-guide", + }, + { + text: "Local Testing", + link: "/permissionless/how-to/local-testing", + }, + { + text: "Accounts", + items: [ + { + text: "EntryPoint support", + link: "/permissionless/how-to/accounts/support", + }, + { + text: "How to use a Safe account", + link: "/permissionless/how-to/accounts/use-safe-account", + }, + { + text: "How to use a Kernel account", + link: "/permissionless/how-to/accounts/use-kernel-account", + }, + { + text: "How to use a SimpleAccount", + link: "/permissionless/how-to/accounts/use-simple-account", + }, + { + text: "How to use a Biconomy account", + link: "/permissionless/how-to/accounts/use-biconomy-account", + }, + { + text: "How to use a LightAccount", + link: "/permissionless/how-to/accounts/use-light-account", + }, + { + text: "How to use a Trust Wallet account", + link: "/permissionless/how-to/accounts/use-trustwallet-account", + }, + { + text: "How to use an ERC-7579 compatible smart account", + link: "/permissionless/how-to/accounts/use-erc7579-account", + }, + ], + }, + { + text: "Paymasters", + items: [ + { + text: "How to use a custom Paymaster", + link: "/permissionless/how-to/paymasters/use-custom-paymaster", + }, + ], + }, + { + text: "Signers", + link: "/permissionless/how-to/signers", + items: [ + { + text: "How to use a Dynamic signer", + link: "/permissionless/how-to/signers/dynamic", + }, + { + text: "How to use a Privy signer", + link: "/permissionless/how-to/signers/privy", + }, + { + text: "How to use a Magic signer", + link: "/permissionless/how-to/signers/magic", + }, + { + text: "How to use a Passport signer", + link: "/permissionless/how-to/signers/passport", + }, + { + text: "How to use a Lit Protocol signer", + link: "/permissionless/how-to/signers/lit-protocol", + }, + { + text: "How to use a Web3Auth signer", + link: "/permissionless/how-to/signers/web3auth", + }, + { + text: "How to use a Turnkey signer", + link: "/permissionless/how-to/signers/turnkey", + }, + { + text: "How to use a Fireblocks signer", + link: "/permissionless/how-to/signers/fireblocks", + }, + { + text: "How to use a Capsule signer", + link: "/permissionless/how-to/signers/capsule", + }, + { + text: "How to use a DFNS signer", + link: "/permissionless/how-to/signers/dfns", + }, + { + text: "How to use an Arcana Auth signer", + link: "/permissionless/how-to/signers/arcana", + }, + { + text: "How to use a Particle Network signer", + link: "/permissionless/how-to/signers/particle-network", + }, + ], + }, + ], + }, + { + text: "Reference", + link: "/permissionless/reference", + items: [ + { + text: "Clients", + collapsed: false, + items: [ + { + text: "Bundler Client", + link: "/permissionless/reference/clients/bundlerClient", + }, + { + text: "Pimlico Bundler Client", + link: "/permissionless/reference/clients/pimlicoBundlerClient", + }, + { + text: "Pimlico Paymaster Client", + link: "/permissionless/reference/clients/pimlicoPaymasterClient", + }, + { + text: "Smart Account Client", + link: "/permissionless/reference/clients/smartAccountClient", + }, + ], + }, + { + text: "Accounts", + collapsed: false, + items: [ + { + text: "signerToSimpleSmartAccount", + link: "/permissionless/reference/accounts/signerToSimpleSmartAccount", + }, + { + text: "signerToSafeSmartAccount", + link: "/permissionless/reference/accounts/signerToSafeSmartAccount", + }, + { + text: "signerToKernelSmartAccount", + link: "/permissionless/reference/accounts/signerToKernelSmartAccount", + }, + { + text: "signerToLightSmartAccount", + link: "/permissionless/reference/accounts/signerToLightSmartAccount", + }, + { + text: "signerToTrustSmartAccount", + link: "/permissionless/reference/accounts/signerToTrustSmartAccount", + }, + ], + }, + { + text: "Bundler Actions", + collapsed: false, + items: [ + { + text: "sendUserOperation", + link: "/permissionless/reference/bundler-actions/sendUserOperation", + }, + { + text: "estimateUserOperationGas", + link: "/permissionless/reference/bundler-actions/estimateUserOperationGas", + }, + { + text: "getUserOperationReceipt", + link: "/permissionless/reference/bundler-actions/getUserOperationReceipt", + }, + { + text: "waitForUserOperationReceipt", + link: "/permissionless/reference/bundler-actions/waitForUserOperationReceipt", + }, + { + text: "getUserOperationByHash", + link: "/permissionless/reference/bundler-actions/getUserOperationByHash", + }, + { + text: "supportedEntryPoints", + link: "/permissionless/reference/bundler-actions/supportedEntryPoints", + }, + ], + }, + { + text: "Smart Account Actions", + collapsed: false, + items: [ + { + text: "prepareUserOperationRequest", + link: "/permissionless/reference/smart-account-actions/prepareUserOperationRequest", + }, + { + text: "sendTransaction", + link: "/permissionless/reference/smart-account-actions/sendTransaction", + }, + { + text: "sendTransactions", + link: "/permissionless/reference/smart-account-actions/sendTransactions", + }, + { + text: "sendUserOperation", + link: "/permissionless/reference/smart-account-actions/sendUserOperation", + }, + { + text: "deployContract", + link: "/permissionless/reference/smart-account-actions/deployContract", + }, + { + text: "writeContract", + link: "/permissionless/reference/smart-account-actions/writeContract", + }, + { + text: "signMessage", + link: "/permissionless/reference/smart-account-actions/signMessage", + }, + { + text: "signTypedData", + link: "/permissionless/reference/smart-account-actions/signTypedData", + }, + ], + }, + { + text: "Pimlico Bundler Actions", + collapsed: false, + items: [ + { + text: "sendCompressedUserOperation", + link: "/permissionless/reference/pimlico-bundler-actions/sendCompressedUserOperation", + }, + { + text: "getUserOperationGasPrice", + link: "/permissionless/reference/pimlico-bundler-actions/getUserOperationGasPrice", + }, + { + text: "getUserOperationStatus", + link: "/permissionless/reference/pimlico-bundler-actions/getUserOperationStatus", + }, + ], + }, + { + text: "Pimlico Paymaster Actions", + collapsed: false, + items: [ + { + text: "sponsorUserOperation", + link: "/permissionless/reference/pimlico-paymaster-actions/sponsorUserOperation", + }, + { + text: "validateSponsorshipPolicies", + link: "/permissionless/reference/pimlico-paymaster-actions/validateSponsorshipPolicies", + }, + ], + }, + { + text: "Public Actions", + collapsed: false, + items: [ + { + text: "getSenderAddress", + link: "/permissionless/reference/public-actions/getSenderAddress", + }, + { + text: "getAccountNonce", + link: "/permissionless/reference/public-actions/getAccountNonce", + }, + ], + }, + { + text: "ERC-7579 Actions", + collapsed: false, + items: [ + { + text: "accountId", + link: "/permissionless/reference/erc7579-actions/accountId", + }, + { + text: "installModule", + link: "/permissionless/reference/erc7579-actions/installModule", + }, + { + text: "uninstallModule", + link: "/permissionless/reference/erc7579-actions/uninstallModule", + }, + { + text: "isModuleInstalled", + link: "/permissionless/reference/erc7579-actions/isModuleInstalled", + }, + { + text: "supportsExecutionMode", + link: "/permissionless/reference/erc7579-actions/supportsExecutionMode", + }, + { + text: "supportsModule", + link: "/permissionless/reference/erc7579-actions/supportsModule", + }, + ], + }, + { + text: "Utilities", + collapsed: false, + items: [ + { + text: "getUserOperationHash", + link: "/permissionless/reference/utils/getUserOperationHash", + }, + { + text: "signUserOperationHashWithECDSA", + link: "/permissionless/reference/utils/signUserOperationHashWithECDSA", + }, + { + text: "getRequiredPrefund", + link: "/permissionless/reference/utils/getRequiredPrefund", + }, + { + text: "walletClientToSmartAccountSigner", + link: "/permissionless/reference/utils/walletClientToSmartAccountSigner", + }, + { + text: "providerToSmartAccountSigner", + link: "/permissionless/reference/utils/providerToSmartAccountSigner", + }, + ], + }, + { + text: "Glossary", + collapsed: false, + items: [{ text: "Errors", link: "/permissionless/reference/glossary/errors" }], + }, + ], + }, + { + text: "Experimental", + collapsed: false, + items: [ + { + text: "EIP-7677", + collapsed: false, + items: [ + { + text: "getPaymasterData", + link: "/permissionless/experimental/eip7677/getPaymasterData", + }, + { + text: "getPaymasterStubData", + link: "/permissionless/experimental/eip7677/getPaymasterStubData", + }, + ], + }, + ], + }, +] export default defineConfig({ - title: "Pimlico", - logoUrl: { light: "/pimlico-purple.svg", dark: "/pimlico-white.svg" }, - iconUrl: "/favicons/favicon.svg", - titleTemplate: "%s | Pimlico Docs", - editLink: { - pattern: "https://github.com/pimlicolabs/docs/edit/main/docs/pages/:path", - text: "Edit on GitHub", - }, - description: - "Pimlico is the world's most popular account abstraction infrastructure platform", - head: () => ( - <> -