# SAManager Documentation - This is the Documentation for v0.8.x - App: https://samanager.xyz - Github: https://github.com/ethaccount/SAManager - For ideas about new features, you can check out the [discussion on GitHub](https://github.com/ethaccount/SAManager/discussions) - For bugs, check the [GitHub issues](https://github.com/ethaccount/SAManager/issues) or open a new one to report problems. - [Dapp Integration: SAManager SDK](https://github.com/ethaccount/SAManager/tree/main/packages/sdk#samanager-sdk) - Supported ERC-4337 EntryPoints: [v0.7](https://github.com/eth-infinitism/account-abstraction/tree/v0.7.0) and [v0.8](https://github.com/eth-infinitism/account-abstraction/tree/v0.8.0) - Supported standards: [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337), [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579), [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), [EIP-5792](https://eips.ethereum.org/EIPS/eip-5792) ## Table of Contents :::success [toc] ::: ## Features ### Import Account and Account Management All account information and validation methods are stored in the browser’s local storage, which can be easily cleared. Because of this, it’s important to provide users with a simple way to re-import their smart accounts. SAManager also aims to ensure users aren’t tied to any single wallet provider’s interface. Instead, they should be able to use their smart accounts in a decentralized way. This follows the idea of the walk-away test — whether users still have control over their assets if the project’s operators disappear. The logic for importing accounts can be found in [useImportAccountModal](https://github.com/ethaccount/SAManager/tree/v0.8.0/src/stores/useImportAccountModal.ts) and the [ImportAccountModal](https://github.com/ethaccount/SAManager/tree/v0.8.0/src/components/ImportAccountModal) component. ### Account Providers, Validation Methods, and Signers This section explains how SAManager abstracts the logic and validation of different contract accounts and validation modules. The [sendop](https://github.com/ethaccount/sendop) TypeScript library is part of this system and has been extracted as a standalone library, making it reusable for other projects. In the sendop library, [UserOpBuilder](https://github.com/ethaccount/sendop/tree/v0.8.0/src/core/UserOpBuilder.ts) is provided to assemble a user operation using the [builder pattern](https://medium.com/@robinviktorsson/a-guide-to-the-builder-design-pattern-in-typescript-and-node-js-with-practical-examples-9e113413ad63). In SAManager, there’s a [UserOpDirector](https://github.com/ethaccount/SAManager/tree/v0.8.0/src/lib/UserOpDirector.ts) which contains buildAccountExecutions -- a method that constructs user operations for different contract accounts. The [useTxModal](https://github.com/ethaccount/SAManager/tree/v0.8.0/src/stores/useTxModal.ts) hook continues the process by completing and sending the user operation. sendop also provides [AccountAPI (which includes ValidationAPI) and PaymasterAPI](https://github.com/ethaccount/sendop/tree/v0.8.0/src/types.ts). In SAManager, these are abstracted as [AccountProvider](https://github.com/ethaccount/SAManager/tree/v0.8.0/src/lib/accounts/types.ts) and [ValidationMethod](https://github.com/ethaccount/SAManager/blob/v0.8.0/src/lib/validations/methods.ts), to generalize the logic for different contract accounts and validation strategies. A contract’s validation logic might come from an ERC-7579 validation module, or it could be custom logic built into the account contract, like in [Simple7702Account](https://github.com/ethaccount/SAManager/blob/c05925e55826a977bb93a2ca87263cba8e9245dc/src/lib/validations/vMethods.ts#L77-L93). [Signers](https://github.com/ethaccount/SAManager/blob/v0.8.0/src/lib/validations/signers.ts) refer to the two signature generation methods provided by SAManager: an EOA wallet and the site’s built-in passkey integration. A ValidationMethod has `isValidSigner` function to check if the signer has the right to operate the account. For EOAs, the signer's identifier is the public key; for passkeys, it’s the hash of the passkey’s credential ID named authenticatorIdHash. ```mermaid graph TB %% Core Components UserOpDirector[UserOpDirector] AccountRegistry[AccountRegistry] %% Account Provider Block subgraph AccountProviderBlock ["AccountProvider"] AccountProvider[AccountProvider Interface] KernelProvider[Kernel Provider] NexusProvider[Nexus Provider] Safe7579Provider[Safe7579 Provider] Simple7702Provider[Simple7702 Provider] KernelProvider -.-> AccountProvider NexusProvider -.-> AccountProvider Safe7579Provider -.-> AccountProvider Simple7702Provider -.-> AccountProvider end %% ValidationMethod Block subgraph ValidationMethodBlock ["ValidationMethod"] ValidationMethod[ValidationMethod Abstract] ECDSAValidator[ECDSA Validator] WebAuthnValidator[WebAuthn Validator] OwnableValidator[Ownable Validator] Simple7702Validator[Simple7702 Validator] ECDSAValidator -.-> ValidationMethod WebAuthnValidator -.-> ValidationMethod OwnableValidator -.-> ValidationMethod Simple7702Validator -.-> ValidationMethod end %% Signer Block subgraph SignerBlock ["Signer"] Signer[Signer Interface] EOASigner[EOA Signer] PasskeySigner[Passkey Signer] EOASigner -.-> Signer PasskeySigner -.-> Signer end %% External Dependencies ValidationAPI[ValidationAPI] AccountAPI[AccountAPI] UserOpBuilder[UserOpBuilder] %% Main Flow UserOpDirector --> AccountRegistry AccountRegistry --> AccountProvider AccountProvider --> AccountAPI UserOpDirector --> ValidationMethod ValidationMethod --> ValidationAPI ValidationMethod --> Signer Signer --> UserOpBuilder %% Key connections ECDSAValidator --> EOASigner WebAuthnValidator --> PasskeySigner OwnableValidator --> EOASigner Simple7702Validator --> EOASigner AccountProvider --> ValidationAPI AccountAPI --> UserOpBuilder %% Styling classDef core fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px classDef external fill:#fff3e0,stroke:#e65100,stroke-width:2px classDef interface fill:#e1f5fe,stroke:#01579b,stroke-width:2px classDef impl fill:#f3e5f5,stroke:#4a148c,stroke-width:1px class UserOpDirector,AccountRegistry core class ValidationAPI,AccountAPI,UserOpBuilder external class AccountProvider,ValidationMethod,Signer interface class KernelProvider,NexusProvider,Safe7579Provider,Simple7702Provider,ECDSAValidator,WebAuthnValidator,OwnableValidator,Simple7702Validator,EOASigner,PasskeySigner impl ``` ### Passkey This app uses the native navigator.credentials API to interact with passkeys: - [credentials.create()](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create) is used to generate a public key. - [credentials.get()](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get) is used to obtain a signature. The app enables passkey interaction with the [WebAuthnValidator](https://sepolia.etherscan.io/address/0x2f167E55D42584f65e2E30A748F41ee75A311414#code) smart contract. When a passkey is registered on-chain, the following event is emitted: ```solidity event WebAuthnPublicKeyRegistered(address indexed kernel, bytes32 indexed authenticatorIdHash, uint256 pubKeyX, uint256 pubKeyY) ``` Each passkey comes with a credential ID. The `authenticatorIdHash` is calculated as follows: ```ts authenticatorIdHash = keccak256(decodeBase64URL(credentialId)) ``` In a standard [WebAuthn](https://webauthn.io/) flow, a relying party (typically a backend server) stores user account data and public keys. However, this app currently stores the public key in local storage and blockchain. It relies solely on passkeys without any backend service to prevent scenarios where backend service outages could block users from signing user operations. In the future, a backend may be introduced to store public keys to prevent data loss, but the app will continue to be built on the principle that passkey-based transactions should remain functional without a server. ### Scheduling This app uses [SmartSession](https://sepolia.etherscan.io/address/0x00000000002B0eCfbD0496EE71e01257dA0E37DE#code) to authorize a specific private key to act on behalf of a smart account for certain transactions. The scheduling feature includes [ScheduleTransfers](https://contractscan.xyz/contract/0xA8E374779aeE60413c974b484d6509c7E4DDb6bA) and [ScheduleOrders](https://contractscan.xyz/contract/0x40dc90D670C89F322fa8b9f685770296428DCb6b). To enable scheduling, users must install the SmartSession and ScheduleTransfers or ScheduleOrders modules, and authorize a key to execute the `executeOrder` function on those contracts on behalf of the account. [SAManager-backend](https://github.com/ethaccount/SAManager-backend) is a backend service that holds a private key. All scheduling operations on SAManager are authorized to this key to perform the scheduled jobs. On the frontend, a portion of the UserOperation is constructed and sent via [a POST request to register a job](https://samanager-backend.onrender.com/swagger/index.html#/jobs/post_jobs). The backend then polls on-chain data and, when appropriate, signs the UserOperation and submits it to the Alchemy bundler. ## Reference - This project relies on several contracts developed and deployed by the [Rhinestone team](https://github.com/rhinestonewtf), including [SmartSession](https://github.com/erc7579/smartsessions), [core-modules](https://github.com/rhinestonewtf/core-modules), [Safe7579](https://github.com/rhinestonewtf/safe7579), as well as libraries such as [module-sdk](https://github.com/rhinestonewtf/module-sdk) and [module-bases](https://github.com/rhinestonewtf/module-bases) - The smart account implementations also include contracts from [Biconomy's Nexus](https://github.com/bcnmy/nexus) and [Zerodev's Kernel](https://github.com/zerodevapp/kernel). - The ethereum node and bundler providers include [Alchemy's rundler](https://github.com/alchemyplatform/rundler), [Pimlico's alto](https://github.com/pimlicolabs/alto), Tenderly, Public Node, and more to be added in the future.