> ## Documentation Index
> Fetch the complete documentation index at: https://docs.learnway.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# ERC-4337 Account Abstraction & Paymaster

> Client-side smart accounts, VerifyingPaymaster policy engine, allowed transaction selectors, sponsored token contracts, and Alto Bundler.

# ERC-4337 Account Abstraction & Paymaster

LearnWay provides a 100% gasless on-chain experience on the client side using **ERC-4337 Account Abstraction**. Learners interact through smart accounts without holding native ETH for gas.

***

## Client-to-Paymaster Data Flow

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant Mobile as Mobile App
    participant PaymasterSvc as VerifyingPaymaster (learnway-backend)
    participant Alto as Alto Bundler (/alto)
    participant EntryPoint as EntryPoint 0.7 (Lisk L2)
    participant PaymasterContract as VerifyingPaymaster.sol
    participant TokenContract as USDT / fUSD Contract

    Mobile->>Mobile: Build UserOperation (sender=SmartAccount, callData=execute)
    Mobile->>PaymasterSvc: POST /paymaster/rpc/:chainId (pm_sponsorUserOperation)

    Note over PaymasterSvc: Policy Verification:<br/>1. Is sender registered user?<br/>2. Is target USDT or fUSD?<br/>3. Is selector transfer or approve?<br/>4. Is rate limit < 10 req/60s?

    PaymasterSvc-->>Mobile: Signed paymasterAndData (valid for 5 mins)
    Mobile->>Mobile: Attach paymasterAndData & sign UserOp
    Mobile->>Alto: eth_sendUserOperation(UserOp, EntryPoint)

    Note over Alto: Simulates UserOp & adds to batch

    Alto->>EntryPoint: handleOps([UserOp], bundlerSigner)
    EntryPoint->>PaymasterContract: validatePaymasterUserOp(UserOp, hash, maxCost)
    PaymasterContract-->>EntryPoint: Signature valid (Context)
    EntryPoint->>TokenContract: execute(target, value, data)
    TokenContract-->>EntryPoint: Transfer / Approve success
    EntryPoint->>PaymasterContract: postOp(mode, context, actualGasCost)
```

***

## The VerifyingPaymaster Policy Engine (`PaymasterPolicyService`)

The backend enforces strict cryptographic and security policies before signing any `UserOperation`:

### 1. Supported EntryPoints

* **`0x0000000071727De22E5E9d8BAf0edAc6f37da032`** (ERC-4337 EntryPoint v0.7 — Recommended)
* **`0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789`** (ERC-4337 EntryPoint v0.6)

### 2. User Registration Verification

The `sender` address must be a registered smart account belonging to an active user in PostgreSQL:

```sql theme={null}
SELECT count(*) FROM users u WHERE LOWER(u.walletAddress) = LOWER(:senderAddress);
```

### 3. Allowed Target Token Contracts

Only specific whitelisted tokens configured in environment variables are sponsored:

* **`USDT_CONTRACT_ADDRESS`** (Tether USD on Lisk L2)
* **`FUSD_CONTRACT_ADDRESS`** (Fonbnk USD stablecoin)

### 4. Allowed Method Selectors

The policy service unpacks standard smart account execution envelopes:

* Single call wrapper: `0xb61d27f6` (`execute(address dest, uint256 value, bytes func)`)
* Batch call wrapper: `0x47e1da2a` (`executeBatch(address[] dests, uint256[] values, bytes[] funcs)`)

Inside the execution envelope, the inner call must strictly match one of the following ERC-20 selectors:

| Selector     | Function Signature                         | Purpose                                |
| :----------- | :----------------------------------------- | :------------------------------------- |
| `0xa9059cbb` | `transfer(address to, uint256 amount)`     | Token payments, reward withdrawals     |
| `0x095ea7b3` | `approve(address spender, uint256 amount)` | Token approvals for platform contracts |

### 5. Rate Limiting & Sliding Windows

* **Rate Limit**: Maximum of **10 sponsored requests per 60-second window** per user address.
* **Window Resets**: Sliding in-memory window (`RATE_WINDOW_MS = 60000`) protecting against flood attacks.

***

## Cryptographic Signing Specification (`PaymasterSignerService`)

* **Supported Networks**:
  * **Chain ID 1135**: Lisk Mainnet
  * **Chain ID 4202**: Lisk Sepolia Testnet
* **Validity Horizon**:
  * `validAfter`: `0` (Immediately valid)
  * `validUntil`: Current timestamp + **300 seconds (5 minutes)**
* **Packed `paymasterData` Structure**:
  ```
  [0x01 (1 byte)] + [pad(validUntil, 6 bytes)] + [pad(validAfter, 6 bytes)] + [ECDSA signature (65 bytes)]
  ```
* **Signing Key**: Signed via ECDSA by the server's private key (`PAYMASTER_SIGNER_PRIVATE_KEY`), which matches the authorized signer configured on `VerifyingPaymaster.sol`.

***

## The Hosted Alto Bundler (`/alto`)

* **Role**: Self-hosted Pimlico **Alto** ERC-4337 bundler.
* **Function**: Receives completed UserOps from the mobile app via standard JSON-RPC (`eth_sendUserOperation`), simulates execution against Lisk L2 RPC nodes, batches valid operations, and submits `handleOps` transactions to the `EntryPoint` contract.

***

## Client-Side Key Management & SLIP-39 MPC Security

To sign ERC-4337 `UserOperation`s without requiring manual 12-word seed phrases, the mobile client implements a **SLIP-39 2-of-3 threshold secret sharing scheme** (`SecretSharingService`):

1. **Share Splitting**: The master private key is generated client-side and split into 3 cryptographic shares:
   * **Share 1 (`localShare`)**: Stored on the mobile device inside hardware-backed secure storage (`iOS Keychain` / `Android Keystore`), encrypted with the user's passphrase.
   * **Share 2 (`backendShare1`)**: Encrypted client-side with **Argon2id + AES-GCM** and stored in the backend database.
   * **Share 3 (`backendShare2`)**: Encrypted client-side with **Argon2id + AES-GCM** as an independent backup share and stored in the backend database.
2. **2-of-3 Threshold Reconstruction**:
   * Any 2 shares can reconstruct the master signing key in memory. A single share reveals zero information.
   * Even though the server stores two remote shares, both are encrypted with the user's secret passphrase before leaving the device, guaranteeing a **zero-knowledge non-custodial model**.
3. **Seedless Account Recovery**:
   * When switching devices, the user logs in, retrieves the two encrypted remote shares, and decrypts them with their passphrase to restore wallet signing capabilities instantly.
