Simulation Controls
Relevant source files
The following files were used as context for generating this wiki page:
Simulation Controls refer to the set of APIs and internal logic within the Walletless provider that allow developers to programmatically manipulate the behavior of a virtual EIP-1193 provider during end-to-end (E2E) testing. These controls enable the simulation of specific user actions, network conditions, and edge cases—such as rejecting a transaction or switching signing accounts—without requiring a physical browser extension or manual interaction.
By providing direct hooks to the provider's internal state, Simulation Controls facilitate deterministic testing environments. They allow a test runner to "impersonate" different accounts, switch between multiple blockchain networks (e.g., Mainnet to Arbitrum), and force error states like UserRejectedRequest (error code 4001) to verify application resilience.
Sources: src/provider.ts:130-150, README.md:14-25, src/types.ts:182-192
Core Control Mechanisms
The simulation system is primarily built into the E2EProviderWithInternal interface, which extends the standard EIP-1193 provider with additional control methods. These methods can be called directly on the provider instance or via standalone helper functions.
Account Simulation and Impersonation
The provider allows for dynamic switching of the signing account at runtime. This is handled by the setSigningAccount method, which resolves various input types into a valid viem Account or PrivateKeyAccount.
The diagram shows the resolution logic for switching signing accounts.
Sources: src/provider.ts:44-77, src/provider.ts:462-466
| Input Type | Description | Example |
|---|---|---|
number | Index (0-9) for default Anvil accounts | 0 |
Address | 42-char Ethereum address | 0xf39F...2266 |
Hex | 66-char raw private key | 0xac09...ff80 |
Account | A pre-configured viem Account object | privateKeyToAccount(key) |
| Sources: src/provider.ts:37-42, src/constants.ts:18-68 |
Transaction and Signature Rejection
To test error handling in DApps, the provider includes toggleable flags that intercept write operations and immediately throw a ProviderRpcError with code 4001.
setRejectSignature(boolean): Affects methods likepersonal_sign,eth_sign, andeth_signTypedData_v4.setRejectTransaction(boolean): Affectseth_sendTransaction.
When these flags are active, the provider bypasses the local walletClient signing logic and simulates a user clicking "Cancel" in a wallet interface.
Sources: src/provider.ts:258-278, src/provider.ts:468-474
Network and Chain Simulation
Simulation Controls allow for seamless network switching. The provider manages multiple RPC URLs and updates its internal walletClient and rpcUrl state when a chain change is triggered.
Chain Switching Logic
Chain switching can be initiated through the EIP-1193 standard wallet_switchEthereumChain method or the simulation-specific setChain(chainId) method.
The sequence of internal state updates when a simulation control changes the active chain.
Sources: src/provider.ts:476-495, src/provider.ts:375-400
Multi-Chain Configuration
The simulation environment is defined by the E2EProviderConfig. If no configuration is provided, it defaults to a single-chain setup using Anvil's default parameters.
| Parameter | Type | Default | Description |
|---|---|---|---|
chains | CompatibleChain[] | [mainnet] | Array of supported networks. |
rpcUrls | Record<number, string> | {} | Map of chain IDs to local node URLs. |
account | Hex | Account | Anvil PK 0 | Initial signing account. |
debug | boolean | false | Enables verbose request/response logging. |
| Sources: src/types.ts:28-44, src/provider.ts:153-158 |
Implementation Detail: Method Routing
The simulation controls rely on a specialized request handler that routes JSON-RPC methods into three distinct categories to maintain realism while allowing local control.
How simulation controls interact with the underlying RPC routing logic.
Sources: src/provider.ts:413-435, src/constants.ts:140-192
Read, Write, and Wallet Methods
- Read Methods: (
eth_call,eth_getBalance) are forwarded viafetchto the currentinternal.rpcUrl. - Write Methods: (
eth_sendTransaction,personal_sign) use theinternal.walletClientfor local signing. - Wallet Methods: (
eth_accounts,eth_chainId) return values directly from the provider'sstateobject, which is updated by simulation controls.
Sources: src/provider.ts:228-240, src/provider.ts:252-256, src/provider.ts:351-356
Integration with Testing Tools
For browser-based testing (e.g., Playwright), simulation controls are typically exposed on the window object. This allows the test runner to manipulate the wallet state from outside the DApp's execution context.
// App setup
const provider = createE2EProvider();
window.__provider = provider;
// Playwright test execution
await page.evaluate(() => {
window.__provider.setRejectTransaction(true);
window.__provider.setSigningAccount(5); // Switch to 6th Anvil account
});
Sources: README.md:126-140, test/provider.spec.ts:805-820
Conclusion
Simulation Controls provide the necessary infrastructure for high-performance, deterministic E2E testing of Web3 applications. By virtualizing the wallet interaction layer and providing synchronous control over signing accounts, network states, and error conditions, they eliminate the need for slow and flaky browser extension automation.
Sources: README.md:27-33, src/provider.ts:130-145