A crypto wallet for developers and power users: simulate anything, locally, instantly
Prank Wallet is a new developer tool, a crypto wallet
With it you're able to do two interesting new things:
PS: obviously you can't sign transactions, but you can still see the UI as stani himself would
The ability to go to any website (either a own protocol you're developing locally, or an existing one), and quickly test an interaction, potentially under someone else's account, is a powerful developer tool. Being able to do that directly on your day-to-day wallet makes it even easier, especially for those who are not EVM experts (e.g.: designers, project managers, QA, or even junior developers who haven't learned the ropes yet)
It is also a powerful tool for end-users, as in introduces much needed security by being able to inform the user of side effects (e.g.: ERC20 transfers) that would happen, potentially highlighting phishing attacks or incorrect parameters. Again, these tools exist, but not in a self-hosted trustless approach that the more savvy users prefer.
This is in some ways similar to what some tooling out there already does, in some form (e.g.: Tenderly, Foundry, etc) However, there are differentiations:
With the state of open source projects such as Foundry and the REVM, these capabilities are already available, in a very efficient way, for local simulations. With the proper UX this can become accessible to everyone in the ecossystem, even the less tech-savy
The bulk of the project is a desktop app using Tauri: Rust on the worker, and Typescript/React for the UI this desktop app is compatible with Linux/Windows/MacOS (that's free with Tauri). It can also be built for mobile, although we haven't focused on that at the moment.
it communicates with dapps through a browser extension that needs to be installed. This extension does a lot of the same behind-the-scenes work as MetaMask, but instead of processing everything in the extension, it acts as a relay for the desktop app, forwarding all RPC calls from each browser tab to it (via websockets). This part was done largely by re-using the open-source work done by MetaMask itself (from the extension codebase, as well as several npm packages they built along the way for handling streams and browser-specific restrictions)
The Rust backend handles all the RPC calls, and holds the private key. Similar to any other wallet: it either forwards calls to an external RPC (we're using Alchemy for simplicity), or it handles some of them internally, such as transaction signing, and all EIP-1193 requests for network switching, account switching, etc.
The wallet is EIP-1993 compliant, and works with any dapp through the "Connect with Metamask" button. Most dapps assume that if window.ethereum
is there, it's metamask. This is a limitation of current standards, so we have to work with this for the time being.
All the impersonation / simulation work is done through Foundry libraries. We leverage the same REVM executor that Foundry already uses, and whenever a transaction is sent to the wallet, we immediately bootstrap a mainnet fork (at whatever the latest known block is) and run a simulation on it. This is near instant, since REVM fork mode only fetches whatever state is needed for the particular transaction to execute. In a regular home network, this takes no more than a couple of seconds even using a 3rd party RPC
From the result of the simulation, we're able to extract all Parity-style traces and infer information from the transaction receipt (gas used, ETH transferred) as well as emitted events (which indicate ERC20 transfers, and other known useful events). We also get the raw execution traces that may be useful for developers to work more closely with.
For clarity, here's an example user flow we're able to fully demo:
Besides this, the wallet shows the current ERC20 balances of whatever the current address is (either the real wallet, or an impersonation), by using a combination of AirStack (for on-chain balances) and Chainlink (for USD exchange rates)