# ERC4337 Smart Account Wallets

Polystream integrates ERC-4337 Account Abstraction to provide a seamless user experience by abstracting away complex blockchain interactions. This architecture allows users to interact with DeFi protocols without managing gas fees directly or dealing with the traditional complications of cryptocurrency wallets.

Polystream's ERC-4337 integration is enabled by leveraging [Biconomy’s Nexus Smart Accounts](https://bcnmy.github.io/abstractjs/index.html).

***

### Smart Account Architecture

#### 1. EntryPoint Contract

The [`EntryPoint.sol`](https://github.com/eth-infinitism/account-abstraction/blob/abff2aca61a8f0934e533d0d352978055fddbd96/contracts/core/EntryPoint.sol) contract is the central hub through which all user operations are processed:

```solidity
// Core contract that validates and executes UserOperations
contract EntryPoint {
    function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;
    function handleAggregatedOps(...) external;
    function simulateValidation(UserOperation calldata userOp) external;
    // Additional functionality...
}
```

* Validates signatures and transaction parameters
* Executes batched user operations
* Manages gas refunds and paymaster interactions
* Provides simulation capabilities for off-chain validation

#### 2. Bundler&#x20;

Bundlers are a critical component of the ERC-4337 infrastructure that collect "UserOperation" objects from users and submit them to the EntryPoint contract:

<figure><img src="https://511560137-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBRX14z25wLMxFcY12pGf%2Fuploads%2Fpk74nXiKenHO5FZqFDaY%2FUntitled%20Diagram.drawio%20(1).png?alt=media&#x26;token=6f45ce62-26c6-444e-b360-99d1338f6cf1" alt=""><figcaption></figcaption></figure>

While the bundler itself is typically an off-chain service, your codebase integrates with bundlers through:

* UserOperation creation and signing in client-side code
* Verification and validation mechanisms in the smart contracts
* Tests for bundler compatibility

The core bundler interaction happens through the `SendUserOp` interface which is referenced in the `AASigner` class:

```typescript
export class AASigner extends Signer {
  // ...
  constructor(
    readonly signer: Signer,
    readonly entryPointAddress: string,
    readonly sendUserOp: SendUserOp, // Function to send UserOperations to a bundler
    readonly accountFactoryAddress: string,
    readonly index = 0,
    readonly provider = signer.provider
  ) {
    // ...
  }
  // ...
}
```

#### 3. Factory Contract

The [`SimpleAccountFactory.sol`](https://github.com/eth-infinitism/account-abstraction/blob/abff2aca61a8f0934e533d0d352978055fddbd96/contracts/samples/SimpleAccountFactory.sol) contract deploys new smart accounts when needed:

```solidity
// Creates new SimpleAccount instances
contract SimpleAccountFactory {
    function createAccount(address owner, uint256 salt) public returns (SimpleAccount);
    function getAddress(address owner, uint256 salt) public view returns (address);
    // Additional functionality...
}
```

* Deterministic account creation with CREATE2
* Address calculation for counterfactual accounts
* Batched account creation

#### 4. Paymaster

The optional [`VerifyingPaymaster.sol`](https://github.com/eth-infinitism/account-abstraction/blob/abff2aca61a8f0934e533d0d352978055fddbd96/contracts/samples/VerifyingPaymaster.sol) contract can sponsor gas fees for users:

```solidity
// Sponsors gas fees for users
contract VerifyingPaymaster {
    function validatePaymasterUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) external returns (bytes memory context, uint256 validationData);
    
    function postOp(
        PostOpMode mode,
        bytes calldata context,
        uint256 actualGasCost
    ) external;
    // Additional functionality...
}
```

* Validates operations it's willing to sponsor
* Implements post-operation logic for accounting
* Defines payment criteria and limitations

***

### User Operation Structure

The [`UserOperation.ts`](https://github.com/eth-infinitism/account-abstraction/blob/abff2aca61a8f0934e533d0d352978055fddbd96/test/UserOperation.ts) structure is the fundamental data type in ERC-4337:

```javascript
class UserOperation {
  constructor(params) {
    this.sender = getAddress(params.sender);          // Smart Account address
    this.nonce = params.nonce;                        // Unique nonce for operation
    this.factory = params.factory ?? undefined;       // Factory for counterfactual accounts
    this.factoryData = params.factoryData ?? '0x';    // Init data for account creation
    this.callData = params.callData ?? '0x';          // The operation data
    this.verificationGas = params.verificationGas;    // Gas for signature verification
    this.callGas = params.callGas;                    // Gas for the main call
    this.preVerificationGas = params.preVerificationGas; // Gas for pre-verification
    this.maxPriorityFee = params.maxPriorityFee;      // Max priority fee (EIP-1559)
    this.maxFeePerGas = params.maxFeePerGas;          // Max fee per gas (EIP-1559)
    this.paymaster = params.paymaster ?? undefined;   // Paymaster contract (optional)
    this.paymasterData = params.paymasterData ?? '0x'; // Paymaster verification data
    this.signature = params.signature ?? '0x';        // Account signature
    // Additional fields...
  }
}
```

***

### Sponsored Transactions

Polystream implements sponsored transactions through paymasters, allowing users to execute transactions without holding ETH. This creates a "Web2-like" experience where users don't need to understand gas or acquire ETH to use the platform.

The PaymasterFlow implementation is referenced in several test files, showing how transactions can be sponsored:

```typescript
// From account-abstraction/test/entrypoint.test.ts
describe('with paymaster (account with no eth)', () => {
  let testPaymasterAcceptAll: TestPaymasterAcceptAll
  let testPaymasterWithPostOp: TestPaymasterWithPostOp
  // ...
  
  beforeEach(async () => {
    testPaymasterAcceptAll = await new TestPaymasterAcceptAll__factory(ethersSigner).deploy(entryPoint.address)
    testPaymasterWithPostOp = await new TestPaymasterWithPostOp__factory(ethersSigner).deploy(entryPoint.address)
    await testPaymasterAcceptAll.addStake(globalUnstakeDelaySec, { value: paymasterStake })
    // ...
  })
  // ...
})
```

Paymasters can sponsor gas fees and can implement different payment models:

1. **Free transactions**: Subsidizing user operations as a business expense
2. **Token payments**: Users pay in ERC-20 tokens instead of ETH
3. **Subscription models**: Users with active subscriptions get free transactions

***

### Dealing with popups and signing for every transaction is one of the worst parts of crypto UX.

<figure><img src="https://511560137-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBRX14z25wLMxFcY12pGf%2Fuploads%2Fy7yChNk3c8u1XhAA7Rv8%2FScreenshot%202025-02-25%20at%203.48.13%E2%80%AFPM.png?alt=media&#x26;token=9d73e45e-46de-41f4-ab4d-9a847aa5d629" alt=""><figcaption></figcaption></figure>

Thanks to ERC4337, you won't need to sign endless transaction prompts:

* Set up once with a single approval
* No more constant wallet connection requests
* No more confusing technical permissions
* No more gas fee surprises

If interaction is needed, you'll only see one final confirmation - not dozens of confusing approval requests.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.polystream.xyz/polystream/erc4337-smart-account-wallets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
