permissionless.js

repository·main·Indexed 42 days ago

https://github.com/pimlicolabs/permissionless.js

A TypeScript SDK for ERC-4337 Account Abstraction built on viem. It provides tools for managing smart accounts, interacting with bundlers and paymasters, and supports advanced standards like ERC-7579 and EIP-7702. The library includes 12 smart account implementations (such as Safe, Kernel, and Biconomy) and an extensible 'Actions' system for tasks like managing modules, retrieving gas prices, and handling sponsorship.

Tokens
87.3K
Snippets
240
Records
337
Agent score
53%

What's inside permissionless.js

  1. Overview of permissionless utility categories

    main

    The permissionless library provides utility functions organized into five main functional categories:

    1. Nonce Utils: Handles 2D nonce encoding and decoding (encodeNonce, decodeNonce).
    2. UserOperation Utils: Functions for UserOp packing and gas computation (getPackedUserOperation, getRequiredPrefund, deepHexlify, transactionReceiptStatus).
    3. ERC-7579 Utils: Module encoding and decoding for ERC-7579 (encode7579Calls, decode7579Calls, encodeInstallModule, encodeUninstallModule).
    4. ERC-20 Utils: State overrides for gas estimation (erc20AllowanceOverride, erc20BalanceOverride).
    5. Account Utils: Helpers for smart account management (isSmartAccountDeployed, toOwner, getAddressFromInitCodeOrPaymasterAndData).
  2. Overview of permissionless.js features

    main

    permissionless.js is a TypeScript library built on top of viem for managing ERC-4337 smart accounts. Key capabilities include:

    • Smart Account Support: High-level API for popular implementations like Safe, Kernel, and Biconomy.
    • Bundler Support: Full support for all ERC-4337 bundler RPC methods.
    • Gas Sponsorship: Support for paymaster actions to sponsor gas fees.
    • User Operation Utilities: Low-level utility functions for handling User Operations.
    • Extensibility: Modular design allowing custom smart accounts, bundlers, paymasters, and signers.
  3. Overview of permissionless library capabilities

    main

    permissionless is a TypeScript SDK built on viem designed for working with ERC-4337 Account Abstraction.

    Key capabilities include:

    • Smart Account Support: Support for 12 different smart account implementations (including Safe, Kernel, Biconomy, and more).
    • Bundler & Paymaster Integration: Support for multiple bundler providers and paymaster interactions.
    • Advanced Standards: Support for ERC-7579 modular accounts and EIP-7702 delegation.
    • Extensible Actions: A system of 'Actions' that allow for both standalone utility usage and decorated client usage (e.g., sendTransaction, signMessage).
  4. Overview of @permissionless/wagmi features

    main

    The @permissionless/wagmi library is a TypeScript wrapper built on top of permissionless.js and wagmi. It is designed to allow developers to support EIP-5792 features (such as those used by Coinbase Smart Wallet) with minimal complexity.

    Key features include:

    • ERC-7677 Paymaster service: Simplifies interaction with external smart accounts that offer paymaster support.
    • Transaction Batching: Enables sending multiple transactions from an external smart account easily.
    • Wagmi Integration: Maintains the same developer experience and style as the standard wagmi library.
  5. What is a Smart Account and how to create one

    main

    A smart account is a contract that validates UserOperations. Unlike EOAs, they can implement logic like multi-sig, session keys, or social recovery.

    In permissionless, you create a SmartAccount using factory functions like toSimpleSmartAccount(), toSafeSmartAccount(), toKernelSmartAccount(), etc. Each returned SmartAccount provides the following methods:

    • getAddress(): Returns the counterfactual address (works before deployment).
    • encodeCalls(calls): Encodes calls into account-specific calldata.
    • decodeCalls(data): Decodes calldata back to calls.
    • getNonce(): Gets current nonce from EntryPoint.
    • getStubSignature(): Gets a dummy signature for gas estimation.
    • sign(hash): Signs a hash.
    • signMessage(message): Signs an EIP-191 message.
    • signTypedData(typedData): Signs EIP-712 typed data.
    • signUserOperation(userOperation): Signs a UserOperation.
  6. Understand ERC-4337 2D Nonce Systems

    main

    ERC-4337 utilizes a 2D nonce system composed of a key (192 bits) and a sequence (64 bits).

    • Key: Identifies the 'nonce lane'. Using different keys allows for parallel nonce lanes, meaning multiple UserOperations can be in-flight simultaneously without blocking one another.
    • Sequence: A value that increments per operation within a specific lane.
  7. Understand ERC-4337 EntryPoint versions in permissionless.js

    main

    The ERC-4337 EntryPoint contract has three major versions supported by permissionless.js: 0.6, 0.7, and 0.8.

    Key Differences

    • Version 0.6: Uses combined initCode (factory + data) and paymasterAndData (paymaster + data) fields. Gas limits are uint256.
    • Version 0.7: Splits initCode into factory and factoryData, and paymasterAndData into paymaster, paymasterVerificationGasLimit, paymasterPostOpGasLimit, and paymasterData. Gas limits for most fields are uint128.
    • Version 0.8: Introduces the authorization field for EIP-7702 EOA delegation and uses EIP-712 typed data signing via getUserOperationTypedData from viem.

    Gas Model and Prefund Calculation

    The getRequiredPrefund() utility uses different formulas depending on the version:

    • 0.6: (callGasLimit + verificationGasLimit * 3 + preVerificationGas) * maxFeePerGas
    • 0.7/0.8: (callGasLimit + verificationGasLimit + paymasterVerificationGasLimit + paymasterPostOpGasLimit + preVerificationGas) * maxFeePerGas
  8. How package exports are structured

    main

    The project uses conditional exports in package.json to ensure compatibility across different module systems. When consuming a package, the environment will resolve to the appropriate format:

    • types: Used by TypeScript to resolve .d.ts files from the _types/ directory.
    • import: Used by ESM bundlers and Node.js (with "type": "module") to resolve files from the _esm/ directory.
    • default: Used by CommonJS require() calls to resolve files from the _cjs/ directory.

    Example Export Map

    {
      "exports": {
        ".": {
          "types": "./_types/index.d.ts",
          "import": "./_esm/index.js",
          "default": "./_cjs/index.js"
        }
      }
    }
  9. How Smart Account Factories work

    main

    A factory deploys smart account contracts on first use. The first UserOperation from a new account includes factory data that triggers deployment.

    In permissionless:

    • Each to*SmartAccount() factory configures the factory internally.
    • The getFactoryArgs() method returns { factory: Address, factoryData: Hex } for the first UserOp. After deployment, it returns undefined.
    • You can pass a custom factoryAddress to the factory configuration.