# 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.