### Get Simple Account Client Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/05-clients-accounts.md Example of how to initialize a simple account client using configuration and RPC details from a fixture. ```typescript const account = await getSimpleAccountClient({ entryPoint: { version: "0.7" }, ...rpc // anvilRpc + altoRpc + paymasterRpc come from testWithRpc }) ``` -------------------------------- ### Create Etherspot Smart Account Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/etherspot-smart-account.md Example demonstrating how to create an Etherspot smart account using a viem client and a private key. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toEtherspotSmartAccount } from "permissionless/accounts" const account = await toEtherspotSmartAccount({ client: createPublicClient({ chain: sepolia, transport: http() }), owners: [privateKeyToAccount("0x...")], }) ``` -------------------------------- ### Quick Start: Create Smart Account Client and Send Transaction Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/README.md This example demonstrates the complete flow of setting up a smart account client and sending a transaction using permissionless.js. It covers creating an owner, a public client, the smart account itself, and finally, the smart account client for transaction submission. Ensure you replace placeholder values like private keys and RPC URLs with your actual details. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toSimpleSmartAccount } from "permissionless/accounts" import { createSmartAccountClient } from "permissionless" // 1. Create an owner (the EOA that controls the smart account) const owner = privateKeyToAccount("0x...") // 2. Create a public client for on-chain reads const publicClient = createPublicClient({ chain: sepolia, transport: http("https://rpc.sepolia.org"), }) // 3. Create the smart account (computes counterfactual address) const account = await toSimpleSmartAccount({ client: publicClient, owner, }) // 4. Create a smart account client (wraps a bundler) const smartAccountClient = createSmartAccountClient({ account, chain: sepolia, bundlerTransport: http("https://bundler.example.com"), }) // 5. Send a transaction (creates, signs, and submits a UserOperation) const txHash = await smartAccountClient.sendTransaction({ to: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", value: 0n, data: "0x", }) ``` -------------------------------- ### Create Biconomy Smart Account Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/biconomy-smart-account.md Example demonstrating how to create a Biconomy smart account using `toBiconomySmartAccount`. This requires setting up a viem client, providing owner accounts, and specifying the EntryPoint details. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toBiconomySmartAccount } from "permissionless/accounts" const account = await toBiconomySmartAccount({ client: createPublicClient({ chain: sepolia, transport: http() }), owners: [privateKeyToAccount("0x...")], entryPoint: { address: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", version: "0.6", }, }) ``` -------------------------------- ### Usage Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/experimental/erc20-paymaster.md An example demonstrating how to set up and use the ERC-20 paymaster with `createSmartAccountClient`. ```APIDOC ## Usage ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toSimpleSmartAccount } from "permissionless/accounts" import { createSmartAccountClient } from "permissionless" import { createPimlicoClient } from "permissionless/clients/pimlico" import { prepareUserOperationForErc20Paymaster } from "permissionless/experimental/pimlico" // 1. Create clients const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const pimlicoClient = createPimlicoClient({ transport: http("https://api.pimlico.io/v2/sepolia/rpc?apikey=YOUR_KEY"), }) // 2. Create account const account = await toSimpleSmartAccount({ client: publicClient, owner: privateKeyToAccount("0x..."), }) // 3. Create smart account client with ERC-20 paymaster const smartAccountClient = createSmartAccountClient({ account, chain: sepolia, bundlerTransport: http("https://api.pimlico.io/v2/sepolia/rpc?apikey=YOUR_KEY"), paymaster: pimlicoClient, userOperation: { prepareUserOperation: prepareUserOperationForErc20Paymaster(pimlicoClient), }, }) // 4. Send transaction -- gas is paid in the ERC-20 token const hash = await smartAccountClient.sendTransaction({ to: "0x...", value: 0n, data: "0x", }) ``` ``` -------------------------------- ### Install permissionless.js and viem Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/README.md Install the necessary packages for using permissionless.js and viem. ```bash npm install permissionless viem ``` -------------------------------- ### Install Optional WebAuthn Dependency Source: https://github.com/pimlicolabs/permissionless.js/blob/main/README.md For WebAuthn functionality (passkeys), install the 'ox' package. ```bash npm install ox ``` ```bash bun install ox ``` ```bash yarn add ox ``` -------------------------------- ### Install permissionless.js Source: https://github.com/pimlicolabs/permissionless.js/blob/main/README.md Install permissionless.js and its peer dependency viem using npm, bun, or yarn. ```bash npm install viem permissionless ``` ```bash bun install viem permissionless ``` ```bash yarn add viem permissionless ``` -------------------------------- ### Create Simple Smart Account with EntryPoint 0.8 Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/simple-smart-account.md Example demonstrating how to create a Simple smart account specifically using EntryPoint version 0.8. ```typescript import { entryPoint08Address } from "viem/account-abstraction" const account = await toSimpleSmartAccount({ client: publicClient, owner, entryPoint: { address: entryPoint08Address, version: "0.8", }, }) ``` -------------------------------- ### Create Single Owner Safe Smart Account Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/safe-smart-account.md Example of creating a Safe smart account with a single owner. Ensure you have the necessary viem client and account setup. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toSafeSmartAccount } from "permissionless/accounts" const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const owner = privateKeyToAccount("0x...") const account = await toSafeSmartAccount({ client: publicClient, owners: [owner], version: "1.5.0", }) ``` -------------------------------- ### Example Passkey Server Flow Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/passkey-server-actions.md Demonstrates a complete flow for passkey registration, verification, and account creation using the passkey server client. ```typescript import { createPasskeyServerClient } from "permissionless/clients/passkeyServer" import { http } from "viem" const passkeyClient = createPasskeyServerClient({ transport: http("https://passkey-server.example.com"), }) // 1. Start registration const options = await passkeyClient.startRegistration({ userName: "alice@example.com", }) // 2. Browser creates credential (user interaction required) const credential = await navigator.credentials.create({ publicKey: options, }) // 3. Verify with server const result = await passkeyClient.verifyRegistration({ credential, }) console.log("Registered:", result.success) console.log("Public key:", result.publicKey) // 4. Use the public key to create a Safe account with WebAuthn // (see Safe account documentation for WebAuthn owner setup) ``` -------------------------------- ### Create EIP-7702 Kernel Smart Account Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/kernel-smart-account-7702.md Example demonstrating how to create an EIP-7702 Kernel smart account using a viem public client and a private key to define the owner. The account address will be the same as the owner's EOA address. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { to7702KernelSmartAccount } from "permissionless/accounts" const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const account = await to7702KernelSmartAccount({ client: publicClient, owner: privateKeyToAccount("0x..."), }) // Account address is the owner's EOA address console.log(account.address) ``` -------------------------------- ### Create EIP-7702 Simple Smart Account Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/simple-smart-account-7702.md Demonstrates how to create an EIP-7702 simple smart account using the `to7702SimpleSmartAccount` function. This example shows account creation and subsequent use with a smart account client. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { entryPoint08Address } from "viem/account-abstraction" import { to7702SimpleSmartAccount } from "permissionless/accounts" import { createSmartAccountClient } from "permissionless" const owner = privateKeyToAccount("0x...") const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const account = await to7702SimpleSmartAccount({ client: publicClient, owner, entryPoint: { address: entryPoint08Address, version: "0.8", }, }) // Account address is the same as the owner's EOA address console.log(account.address === owner.address) // true const client = createSmartAccountClient({ account, chain: sepolia, bundlerTransport: http("https://bundler.example.com"), }) ``` -------------------------------- ### PasskeyServerClient Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/clients/passkey-server-client.md Demonstrates how to create a PasskeyServerClient and initiate passkey registration. Ensure the authenticatorResponse is provided after the user completes the WebAuthn ceremony to verify registration. ```typescript import { http } from "viem" import { createPasskeyServerClient } from "permissionless/clients/passkeyServer" const passkeyClient = createPasskeyServerClient({ transport: http("https://passkey-server.example.com"), }) // Register a new passkey const registrationOptions = await passkeyClient.startRegistration({ userName: "alice", }) // After user completes WebAuthn ceremony: const result = await passkeyClient.verifyRegistration({ credential: authenticatorResponse, }) ``` -------------------------------- ### installModule Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/erc7579-actions.md Installs a single module on the account. ```APIDOC ## `installModule` Installs a single module on the account. ```typescript async function installModule( client: Client, args: InstallModuleParameters ): Promise ``` ### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `type` | `ModuleType` | Yes | Module type to install | | `address` | `Address` | Yes | Module contract address | | `context` | `Hex` | Yes | Module initialization data | | `account` | `SmartAccount` | No | Override client's account | ### Example ```typescript const hash = await client.installModule({ type: "executor", address: "0xModuleAddress...", context: "0x", // Module-specific init data }) ``` ``` -------------------------------- ### Create EcdsaKernelSmartAccount Example Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/ecdsa-kernel-smart-account.md An example demonstrating how to create an EcdsaKernelSmartAccount using the toEcdsaKernelSmartAccount function. This requires a public client, owner accounts, and specifies the kernel version and entry point details. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toEcdsaKernelSmartAccount } from "permissionless/accounts" const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const account = await toEcdsaKernelSmartAccount({ client: publicClient, owners: [privateKeyToAccount("0x...")], version: "0.3.1", entryPoint: { address: entryPoint07Address, version: "0.7", }, }) ``` -------------------------------- ### Install a Single ERC-7579 Module Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/erc7579-actions.md Install a single module onto the smart account. Provide the module's type, contract address, and initialization context. The `context` is module-specific initialization data. ```typescript const hash = await client.installModule({ type: "executor", address: "0xModuleAddress...", context: "0x", // Module-specific init data }) ``` -------------------------------- ### Create Simple Smart Account with Default EntryPoint Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/simple-smart-account.md Example of creating a Simple smart account using the default EntryPoint version (0.7). Requires viem and permissionless libraries. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toSimpleSmartAccount } from "permissionless/accounts" const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const owner = privateKeyToAccount("0x...") const account = await toSimpleSmartAccount({ client: publicClient, owner, }) console.log("Address:", account.address) ``` -------------------------------- ### installModules Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/erc7579-actions.md Installs multiple modules in a single UserOperation. ```APIDOC ## `installModules` Installs multiple modules in a single UserOperation. ```typescript async function installModules( client: Client, args: InstallModulesParameters ): Promise ``` ### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `modules` | `{ type: ModuleType, address: Address, context: Hex }[]` | Yes | Modules to install | | `account` | `SmartAccount` | No | Override client's account | ``` -------------------------------- ### Create Thirdweb Smart Account Instance Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/thirdweb-smart-account.md Example of creating a Thirdweb smart account instance using a viem client and an owner account. Ensure the necessary imports are included. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toThirdwebSmartAccount } from "permissionless/accounts" const account = await toThirdwebSmartAccount({ client: createPublicClient({ chain: sepolia, transport: http() }), owner: privateKeyToAccount("0x..."), }) ``` -------------------------------- ### Smart Account Client Setup with Unique Private Key Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/02-lifecycle.md Demonstrates the standard pattern for setting up a smart account client within a test, ensuring state isolation by generating a fresh private key for each test or describe block. ```typescript describe.each(getCoreSmartAccounts())( "myTest $name", ({ getSmartAccountClient, ... }) => { const privateKey = generatePrivateKey() // Fresh key per account type testWithRpc("test_v07", async ({ rpc }) => { const smartClient = await getSmartAccountClient({ entryPoint: { version: "0.7" }, privateKey, ...rpc }) // ... }) } ) ``` -------------------------------- ### Quick Start: Create Smart Account Client Source: https://github.com/pimlicolabs/permissionless.js/blob/main/README.md Initialize and configure a smart account client using permissionless.js, including paymaster and bundler configurations. Requires viem chains and http transport. ```typescript // Import the required modules. import { createSmartAccountClient } from "permissionless"; import { createPaymasterClient } from "viem/account-abstraction"; import { sepolia } from "viem/chains"; import { http } from "viem"; const paymaster = createPaymasterClient({ transport: http(`https://api.pimlico.io/v2/sepolia/rpc?apikey=${pimlicoApiKey}`) }) const account = toSimpleSmartAccount({ client: getPublicClient(anvilRpc), owner: privateKeyToAccount(generatePrivateKey()) }) // Create the required clients. const bundlerClient = createSmartAccountClient({ account, paymaster, chain: sepolia, bundlerTransport: http( `https://api.pimlico.io/v2/sepolia/rpc?apikey=${pimlicoApiKey}`, ), // Use any bundler url }); // Consume bundler, paymaster, and smart account actions! const userOperationReceipt = await bundlerClient.getUserOperationReceipt({ hash: "0x5faea6a3af76292c2b23468bbea96ef63fb31360848be195748437f0a79106c8", }); ``` -------------------------------- ### Extend Client with SmartAccountActions Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/clients/smart-account-client.md Example of extending a viem client with `smartAccountActions` to add smart account functionalities. ```typescript import { smartAccountActions } from "permissionless/clients" const client = createClient({ transport: http(bundlerUrl) }) .extend(bundlerActions) .extend(smartAccountActions) ``` -------------------------------- ### Create Kernel Smart Account Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/kernel-smart-account.md Example of creating a Kernel smart account using the `toKernelSmartAccount` function with a public client and an owner account. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toKernelSmartAccount } from "permissionless/accounts" const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const owner = privateKeyToAccount("0x...") const account = await toKernelSmartAccount({ client: publicClient, owners: [owner], version: "0.3.1", }) ``` -------------------------------- ### Create TrustSmartAccount Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/trust-smart-account.md Example of creating a TrustSmartAccount instance. Ensure the viem client, owner, and entryPoint are correctly configured. The entryPoint must be version 0.6. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toTrustSmartAccount } from "permissionless/accounts" const account = await toTrustSmartAccount({ client: createPublicClient({ chain: sepolia, transport: http() }), owner: privateKeyToAccount("0x..."), entryPoint: { address: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", version: "0.6", }, }) ``` -------------------------------- ### Create LightSmartAccount Instance Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/light-smart-account.md Example of creating a LightSmartAccount instance using the `toLightSmartAccount` factory function. This requires a viem client, an owner account, and the desired account version. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toLightSmartAccount } from "permissionless/accounts" const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const account = await toLightSmartAccount({ client: publicClient, owner: privateKeyToAccount("0x..."), version: "2.0.0", }) ``` -------------------------------- ### Import Biconomy Smart Account Utilities Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/biconomy-smart-account.md Import the necessary types and functions for creating a Biconomy smart account. Ensure you have permissionless.js installed. ```typescript import { toBiconomySmartAccount } from "permissionless/accounts" import type { ToBiconomySmartAccountParameters, ToBiconomySmartAccountReturnType, BiconomySmartAccountImplementation, } from "permissionless/accounts" ``` -------------------------------- ### Create Multi-Owner Safe Smart Account (2-of-3) Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/safe-smart-account.md Example of creating a Safe smart account with multiple owners and a specified signature threshold. ```typescript const account = await toSafeSmartAccount({ client: publicClient, owners: [owner1, owner2, owner3], threshold: 2n, version: "1.5.0", }) ``` -------------------------------- ### Usage Example: Create Smart Account Client with ERC-20 Paymaster Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/experimental/erc20-paymaster.md Demonstrates how to set up a smart account client that uses the ERC-20 paymaster for gas fees. This involves creating clients, an account, and configuring the smart account client with the paymaster and the ERC-20 preparation hook. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toSimpleSmartAccount } from "permissionless/accounts" import { createSmartAccountClient } from "permissionless" import { createPimlicoClient } from "permissionless/clients/pimlico" import { prepareUserOperationForErc20Paymaster } from "permissionless/experimental/pimlico" // 1. Create clients const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const pimlicoClient = createPimlicoClient({ transport: http("https://api.pimlico.io/v2/sepolia/rpc?apikey=YOUR_KEY"), }) // 2. Create account const account = await toSimpleSmartAccount({ client: publicClient, owner: privateKeyToAccount("0x..."), }) // 3. Create smart account client with ERC-20 paymaster const smartAccountClient = createSmartAccountClient({ account, chain: sepolia, bundlerTransport: http("https://api.pimlico.io/v2/sepolia/rpc?apikey=YOUR_KEY"), paymaster: pimlicoClient, userOperation: { prepareUserOperation: prepareUserOperationForErc20Paymaster(pimlicoClient), }, }) // 4. Send transaction -- gas is paid in the ERC-20 token const hash = await smartAccountClient.sendTransaction({ to: "0x...", value: 0n, data: "0x", }) ``` -------------------------------- ### New Account Helper Function Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/05-clients-accounts.md Example of how to wire a new smart-account type by creating a client helper function. This function should match the pattern of existing helpers and be added to `utils.ts`. ```typescript export const getFooClient = async ({ anvilRpc, privateKey }: AAParamType) => { return toFooSmartAccount({ client: getPublicClient(anvilRpc), entryPoint: { address: entryPoint07Address, version: "0.7" }, owner: privateKeyToAccount(privateKey ?? generatePrivateKey()) }) } ``` -------------------------------- ### Import Passkey Server Actions Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/architecture/02-export-map.md Import functions for starting and verifying WebAuthn registration from the Passkey server actions module. These are essential for integrating passkey authentication. ```typescript import { startRegistration, verifyRegistration } from "permissionless/actions/passkeyServer" ``` -------------------------------- ### CI Workflow for E2E Coverage Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/06-ci-and-running.md The CI workflow defines steps for checking out code, installing dependencies, setting up Node, building the project, configuring environment variables for testing, running the CI test script, and uploading coverage. ```yaml jobs: verify: uses: ./.github/workflows/verify.yml # lint + build docker-e2e: name: E2E-Coverage runs-on: ubuntu-latest timeout-minutes: 60 steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install-dependencies - uses: actions/setup-node@v4 with: { node-version: "v22.2.0" } - run: bun run build - run: echo "VITE_FORK_RPC_URL=${{ secrets.VITE_FORK_RPC_URL }}" > .env.test - run: bun run test:ci - uses: codecov/codecov-action@v3 ``` -------------------------------- ### Create and Use a Basic Smart Account Client Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/clients/smart-account-client.md Demonstrates the setup and usage of a basic smart account client. Requires viem and permissionless libraries. Initializes a public client, converts an owner account to a simple smart account, and then creates the smart account client to send transactions. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { privateKeyToAccount } from "viem/accounts" import { toSimpleSmartAccount } from "permissionless/accounts" import { createSmartAccountClient } from "permissionless" const publicClient = createPublicClient({ chain: sepolia, transport: http("https://rpc.sepolia.org"), }) const account = await toSimpleSmartAccount({ client: publicClient, owner: privateKeyToAccount("0x..."), }) const smartAccountClient = createSmartAccountClient({ account, chain: sepolia, bundlerTransport: http("https://bundler.example.com"), client: publicClient, }) const hash = await smartAccountClient.sendTransaction({ to: "0x...", value: 0n, data: "0x", }) ``` -------------------------------- ### Check if an ERC-7579 Module is Installed Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/erc7579-actions.md Verify if a specific module is currently installed on the smart account. This function requires the module type, its contract address, and any relevant context. ```typescript const installed = await client.isModuleInstalled({ type: "validator", address: "0xModuleAddress...", context: "0x", }) console.log("Module installed:", installed) // true or false ``` -------------------------------- ### Get Account Nonce Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/public-actions.md Reads the current nonce for a smart account from the EntryPoint contract. Use this to get the nonce for a specific smart account address and optional nonce key. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" import { getAccountNonce } from "permissionless/actions" import { entryPoint07Address } from "viem/account-abstraction" const publicClient = createPublicClient({ chain: sepolia, transport: http(), }) const nonce = await getAccountNonce(publicClient, { address: "0x1234...", entryPointAddress: entryPoint07Address, }) console.log("Current nonce:", nonce) ``` ```typescript const nonce = await getAccountNonce(publicClient, { address: "0x1234...", entryPointAddress: entryPoint07Address, key: 1n, // Use nonce lane 1 }) ``` -------------------------------- ### Create Kernel Smart Account with Specific EntryPoint Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/kernel-smart-account.md Demonstrates creating a Kernel smart account while explicitly specifying the EntryPoint address and version. ```typescript import { entryPoint07Address } from "viem/account-abstraction" const account = await toKernelSmartAccount({ client: publicClient, owners: [owner], version: "0.3.1", entryPoint: { address: entryPoint07Address, version: "0.7", }, }) ``` -------------------------------- ### startRegistration Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/passkey-server-actions.md Initiates a WebAuthn credential registration with the passkey server. This function prepares the necessary options for the browser's `navigator.credentials.create()` API. ```APIDOC ## startRegistration ### Description Initiates a WebAuthn credential registration with the passkey server. ### RPC Method pks_startRegistration ### Parameters #### Path Parameters - **userName** (string) - Required - User identifier for the credential ### Returns WebAuthn creation options to pass to the browser's `navigator.credentials.create()` API. ``` -------------------------------- ### Infrastructure Startup Order Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/03-infrastructure.md Illustrates the startup dependencies between Anvil, Alto, and the mock paymaster. Ensure this order is maintained when rearranging the testing rig. ```text ┌──────────────┐ ┌──────────────┐ ┌─────────────────┐ │ Anvil │ ◄── │ Alto │ ◄── │ Mock paymaster │ │ anvilPort │ │ altoPort │ │ paymasterPort │ └──────────────┘ └──────────────┘ └─────────────────┘ ▲ ▲ ▲ ▲ │ │ └─────────────────┤ │ │ │ │ │ └── paymaster.start() calls │ │ setup(anvilRpc, signerAddr) │ │ and later serves requests │ │ that hit altoRpc for RPC fanout │ │ │ └── alto boots and queries anvil for chainId, │ registered entrypoints, etc. │ └── setupContracts(anvilRpc): deploys EntryPoints v0.6/0.7/0.8 and every smart-account factory before Alto boots. ``` -------------------------------- ### isModuleInstalled Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/erc7579-actions.md Checks if a module is currently installed on the account. ```APIDOC ## `isModuleInstalled` Checks if a module is currently installed on the account. ```typescript async function isModuleInstalled( client: Client, args: IsModuleInstalledParameters ): Promise ``` ### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `type` | `ModuleType` | Yes | Module type to check | | `address` | `Address` | Yes | Module contract address | | `context` | `Hex` | Yes | Additional context | | `account` | `SmartAccount` | No | Override client's account | ### Example ```typescript const installed = await client.isModuleInstalled({ type: "validator", address: "0xModuleAddress...", context: "0x", }) console.log("Module installed:", installed) // true or false ``` ``` -------------------------------- ### Create Simple Smart Account Client Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/05-clients-accounts.md Use this helper to create a simple smart account client. It supports EntryPoint versions v0.6, v0.7, and v0.8. EIP-1271 is not supported. ```typescript return toSimpleSmartAccount({ client: getPublicClient(anvilRpc), entryPoint: { address: entryPointMapping[entryPoint.version], version: entryPoint.version }, owner: privateKeyToAccount(privateKey ?? generatePrivateKey()) }) ``` -------------------------------- ### Select EntryPoint Version for Smart Account Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/concepts/02-entrypoint-versions.md Specify the EntryPoint version when creating a smart account. Defaults to 0.7 if not provided. ```typescript import { entryPoint07Address } from "viem/account-abstraction" // Smart account with EntryPoint 0.7 (default) const account = await toSimpleSmartAccount({ client: publicClient, owner, entryPoint: { address: entryPoint07Address, version: "0.7", }, }) ``` -------------------------------- ### accountId Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/erc7579-actions.md Gets the ERC-7579 account identifier string. ```APIDOC ## `accountId` Gets the ERC-7579 account identifier string. ```typescript async function accountId( client: Client, args?: { account?: SmartAccount } ): Promise ``` ### Example ```typescript const id = await client.accountId() // e.g., "kernel.advanced.v0.3.1" ``` ``` -------------------------------- ### getUserOperationGasPrice Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/etherspot-actions.md Gets gas price recommendations from the Etherspot (Skandha) bundler. ```APIDOC ## getUserOperationGasPrice ### Description Gets gas price recommendations from the Etherspot (Skandha) bundler. ### RPC Method skandha_getGasPrice ### Signature ```typescript async function getUserOperationGasPrice( client: Client ): Promise ``` ### Returns ```typescript { maxFeePerGas: bigint, maxPriorityFeePerGas: bigint, } ``` ### Example ```typescript import { createClient, http } from "viem" import { getUserOperationGasPrice } from "permissionless/actions/etherspot" const client = createClient({ transport: http("https://skandha.etherspot.io/...") }) const gasPrice = await getUserOperationGasPrice(client) console.log("Max fee:", gasPrice.maxFeePerGas) ``` ``` -------------------------------- ### getUserOperationGasPrice Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/pimlico-actions.md Gets gas price recommendations from Pimlico at three speed tiers. ```APIDOC ## `getUserOperationGasPrice` Gets gas price recommendations from Pimlico at three speed tiers. **RPC method:** `pimlico_getUserOperationGasPrice` ### Signature ```typescript async function getUserOperationGasPrice( client: Client ): Promise ``` ### Returns ```typescript { slow: { maxFeePerGas: bigint, maxPriorityFeePerGas: bigint }, standard: { maxFeePerGas: bigint, maxPriorityFeePerGas: bigint }, fast: { maxFeePerGas: bigint, maxPriorityFeePerGas: bigint }, } ``` ### Example ```typescript const gasPrice = await pimlicoClient.getUserOperationGasPrice() console.log("Standard gas price:", gasPrice.standard.maxFeePerGas) ``` ``` -------------------------------- ### Send Transaction to Deterministic Deployer Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/04-contracts.md Example of sending a transaction to the deterministic deployer with initialization code. ```typescript walletClient.sendTransaction({ to: DETERMINISTIC_DEPLOYER, data: ENTRY_POINT_V08_CREATECALL, gas: 15_000_000n, nonce: nonce++ }), ``` -------------------------------- ### Set up Persistent Fork Environment Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/06-ci-and-running.md Configure the testing environment to use a persistent fork by setting the RPC URL in the .env.test file and running tests with bun. ```bash echo 'VITE_FORK_RPC_URL=https://eth.llamarpc.com' > .env.test bun run test ``` -------------------------------- ### Get Credentials Function Signature Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/passkey-server-actions.md Defines the function signature for retrieving all registered credentials for a user. ```typescript async function getCredentials( client: Client, args: GetCredentialsParameters ): Promise ``` -------------------------------- ### Create an Owner for Smart Account Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/concepts/03-smart-account-lifecycle.md Demonstrates three options for creating an owner: using a private key for backend scripts, a viem wallet client for browser wallets, or an EIP-1193 provider like window.ethereum. ```typescript import { privateKeyToAccount } from "viem/accounts" import { createWalletClient, http } from "viem" import { sepolia } from "viem/chains" // Option A: Private key (for scripts/backends) const owner = privateKeyToAccount("0x...") // Option B: Wallet client (for browser wallets) const owner = createWalletClient({ account: privateKeyToAccount("0x..."), chain: sepolia, transport: http(), }) // Option C: EIP-1193 provider (e.g., window.ethereum) const owner = window.ethereum ``` -------------------------------- ### ERC-7579 Actions Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/architecture/02-export-map.md Actions for managing ERC-7579 compatible smart accounts, including module installation and uninstallation. ```APIDOC ## erc7579Actions ### Description A decorator factory that adds all ERC-7579 methods to an object. ### Type `decorator factory` ## accountId ### Description Retrieves the ERC-7579 ID for a given account. ### Method `function` ## installModule ### Description Installs a single module onto the smart account. ### Method `function` ### Parameters - `InstallModuleParameters`: Parameters for installing a module. ## installModules ### Description Installs multiple modules onto the smart account. ### Method `function` ### Parameters - `InstallModulesParameters`: Parameters for batch module installation. ## isModuleInstalled ### Description Checks if a specific module is installed on the smart account. ### Method `function` ### Parameters - `IsModuleInstalledParameters`: Parameters for checking module installation. ## supportsExecutionMode ### Description Checks if the smart account supports a given execution mode. ### Method `function` ### Parameters - `SupportsExecutionModeParameters`: Parameters for checking execution mode support. ## supportsModule ### Description Checks if the smart account supports a given module type. ### Method `function` ### Parameters - `SupportsModuleParameters`: Parameters for checking module type support. ## uninstallModule ### Description Uninstalls a single module from the smart account. ### Method `function` ### Parameters - `UninstallModuleParameters`: Parameters for uninstalling a module. ## uninstallModules ### Description Uninstalls multiple modules from the smart account. ### Method `function` ### Parameters - `UninstallModulesParameters`: Parameters for batch module uninstallation. ## Erc7579Actions ### Description Type definition for the object containing ERC-7579 actions. ### Type `type` ## InstallModuleParameters ### Description Type definition for the parameters of the `installModule` function. ### Type `type` ## InstallModulesParameters ### Description Type definition for the parameters of the `installModules` function. ### Type `type` ## IsModuleInstalledParameters ### Description Type definition for the parameters of the `isModuleInstalled` function. ### Type `type` ## SupportsExecutionModeParameters ### Description Type definition for the parameters of the `supportsExecutionMode` function. ### Type `type` ## SupportsModuleParameters ### Description Type definition for the parameters of the `supportsModule` function. ### Type `type` ## UninstallModuleParameters ### Description Type definition for the parameters of the `uninstallModule` function. ### Type `type` ## UninstallModulesParameters ### Description Type definition for the parameters of the `uninstallModules` function. ### Type `type` ## CallType ### Description Defines the possible call types for ERC-7579 operations. ### Type `type` ### Values - `"call"` - `"batchcall"` - `"delegatecall"` ## ExecutionMode ### Description Descriptor for an execution mode. ### Type `type` ## ModuleType ### Description Defines the possible types of modules. ### Type `type` ### Values - `"validator"` - `"executor"` - `"fallback"` - `"hook"` ``` -------------------------------- ### getTokenQuotes Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/pimlico-actions.md Gets ERC-20 paymaster token quotes -- exchange rates for paying gas in tokens. ```APIDOC ## `getTokenQuotes` Gets ERC-20 paymaster token quotes -- exchange rates for paying gas in tokens. **RPC method:** `pimlico_getTokenQuotes` ### Signature ```typescript async function getTokenQuotes( client: Client, args: GetTokenQuotesParameters ): Promise ``` ### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `tokens` | `Address[]` | Yes | ERC-20 token addresses to quote | | `chain` | `Chain` | No | Target chain | | `entryPointAddress` | `Address` | No | EntryPoint address | ### Returns Array of token quote objects with exchange rates, paymaster addresses, and required amounts. ``` -------------------------------- ### Create a Viem Public Client Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/concepts/03-smart-account-lifecycle.md Sets up a viem public client required for on-chain read operations such as checking deployment status, reading nonces, and computing counterfactual addresses. ```typescript import { createPublicClient, http } from "viem" import { sepolia } from "viem/chains" const publicClient = createPublicClient({ chain: sepolia, transport: http("https://rpc.sepolia.org"), }) ``` -------------------------------- ### Get Credentials Return Type Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/passkey-server-actions.md Specifies the structure of the return value from the `getCredentials` function, an array of credential objects. ```typescript { id: string, publicKey: Hex }[] ``` -------------------------------- ### Start Registration Function Signature Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/passkey-server-actions.md Defines the function signature for initiating WebAuthn credential registration with the passkey server. ```typescript async function startRegistration( client: Client, args: StartRegistrationParameters ): Promise ``` -------------------------------- ### createPasskeyServerClient Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/clients/passkey-server-client.md Creates a PasskeyServerClient instance, which extends viem's Client with Passkey Server Actions. This client is used to interact with a passkey server for managing user credentials. ```APIDOC ## createPasskeyServerClient ### Description Creates a PasskeyServerClient instance, which extends viem's Client with Passkey Server Actions. This client is used to interact with a passkey server for managing user credentials. ### Parameters #### Config Parameters - **transport** (Transport) - Required - Transport to the passkey server - **chain** (Chain) - Optional - Chain - **account** (Account) - Optional - Account - **key** (string) - Optional - Client key (default: "public") - **name** (string) - Optional - Client name (default: "Passkey Server Client") - **cacheTime** (number) - Optional - Cache duration (default: viem default) - **pollingInterval** (number) - Optional - Polling interval (default: viem default) - **rpcSchema** (RpcSchema) - Optional - Additional RPC methods ### Return Type `PasskeyServerClient` is a viem `Client` with `PasskeyServerActions`: - `startRegistration` -- Begin WebAuthn credential registration - `verifyRegistration` -- Complete registration with authenticator response - `getCredentials` -- List registered credentials - `startAuthentication` -- Begin authentication challenge - `verifyAuthentication` -- Complete authentication ### Example ```typescript import { http } from "viem" import { createPasskeyServerClient } from "permissionless/clients/passkeyServer" const passkeyClient = createPasskeyServerClient({ transport: http("https://passkey-server.example.com"), }) // Register a new passkey const registrationOptions = await passkeyClient.startRegistration({ userName: "alice", }) // After user completes WebAuthn ceremony: const result = await passkeyClient.verifyRegistration({ credential: authenticatorResponse, }) ``` ``` -------------------------------- ### InvalidEntryPointError Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/types-and-errors/errors.md Thrown by `getSenderAddress` when the counterfactual address cannot be computed, for example, due to invalid init code or an incorrect EntryPoint address. ```APIDOC ## InvalidEntryPointError ### Description Thrown by `getSenderAddress` when the counterfactual address cannot be computed (e.g., invalid init code, wrong EntryPoint address). ### When It's Thrown - `getSenderAddress()` simulation fails - Invalid or incompatible init code / factory data - Wrong EntryPoint address ### Example ```typescript import { InvalidEntryPointError, getSenderAddress } from "permissionless/actions" try { const address = await getSenderAddress(client, { factory: "0x...", factoryData: "0x...", entryPointAddress: "0xWrongEntryPoint...", }) } catch (error) { if (error instanceof InvalidEntryPointError) { console.error("Failed to compute sender address:", error.message) } } ``` ``` -------------------------------- ### getLightAccountClient({ entryPoint, anvilRpc, version, privateKey }) Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/testing/05-clients-accounts.md Creates a light smart account client. Supports different versions and entry points based on the version. ```APIDOC ## getLightAccountClient({ entryPoint, anvilRpc, version, privateKey }) ### Description Creates a light smart account client. - Versions: `"1.1.0"` (default, v0.6), `"2.0.0"` (v0.7). - EntryPoint: depends on version. - EIP-1271: yes. ### Parameters - `entryPoint` (object) - Entry point configuration. - `anvilRpc` (string) - RPC URL for the anvil client. - `version` (string) - The version of the light account. - `privateKey` (string) - The private key for the account owner. ``` -------------------------------- ### Import Etherspot Actions Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/architecture/02-export-map.md Import the `getUserOperationGasPrice` function from the Etherspot actions module. This is used to get gas prices from the Etherspot bundler. ```typescript import { getUserOperationGasPrice } from "permissionless/actions/etherspot" ``` -------------------------------- ### Create a Simple Smart Account Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/README.md Use the `toSimpleSmartAccount` factory function to create a smart account. Requires a viem client and an owner key. Optional parameters like entryPoint, factoryAddress, and index can be provided. ```typescript import { toSimpleSmartAccount } from "permissionless/accounts" const account = await toSimpleSmartAccount({ client: publicClient, // viem Client for on-chain reads owner, // Optional parameters: entryPoint: { address, version: "0.7" }, factoryAddress: "0x...", index: 0n, address: "0x...", nonceKey: 0n, }) ``` -------------------------------- ### Encode Install Module Call Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/utils/erc7579-utils.md Encodes a call to the `installModule` function for ERC-7579 accounts. Requires module type, address, and initialization data. ```typescript import { encodeInstallModule } from "permissionless/utils" // Example usage (assuming parameters are defined elsewhere) // const calldata = encodeInstallModule({ type: "validator", address: "0x...", context: "0x..." }) ``` -------------------------------- ### Get User Operation Status Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/pimlico-actions.md Checks the current status of a submitted UserOperation using its hash. Returns the status and the transaction hash if included. ```typescript const status = await pimlicoClient.getUserOperationStatus({ hash: "0x...", }) if (status.status === "included") { console.log("Included in tx:", status.transactionHash) } ``` -------------------------------- ### Import Simple Smart Account Utilities Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/accounts/simple-smart-account.md Import necessary functions and types for creating a Simple smart account. ```typescript import { toSimpleSmartAccount } from "permissionless/accounts" import type { ToSimpleSmartAccountParameters, ToSimpleSmartAccountReturnType, SimpleSmartAccountImplementation, } from "permissionless/accounts" ``` -------------------------------- ### Get User Operation Gas Price Source: https://github.com/pimlicolabs/permissionless.js/blob/main/docs/actions/pimlico-actions.md Retrieves gas price recommendations from Pimlico for different speed tiers (slow, standard, fast). ```typescript const gasPrice = await pimlicoClient.getUserOperationGasPrice() console.log("Standard gas price:", gasPrice.standard.maxFeePerGas) ```