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 .
Smart Account Architecture
1. EntryPoint Contract
The contract is the central hub through which all user operations are processed:
// 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
Bundlers are a critical component of the ERC-4337 infrastructure that collect "UserOperation" objects from users and submit them to the EntryPoint contract:
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:
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
// 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...
}
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:
// 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:
Free transactions: Subsidizing user operations as a business expense
Token payments: Users pay in ERC-20 tokens instead of ETH
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.
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.
The contract deploys new smart accounts when needed:
The optional contract can sponsor gas fees for users:
The structure is the fundamental data type in ERC-4337: