A Simple, Open Source Embedded Wallet Pattern for Ethereum

The 1Shot team has been interested in embedded wallets for a while now as they really make a difference in successful user onboarding, especially for non-crypto native users. There are plenty of proprietary embedded wallet vendors in the space like Privy and Thirdweb, but these solutions aren’t very “web3” since you are essentially renting your user layer, and it can be quite expensive especially if you’re bootstrapping a new onchain product. Additionally, they are closed ecosystems, you have no control over their source code and they are inherently non-extensible which is not ideal given that the embedded wallet is a component of your product. I also find it egregious that many of these vendors charge a fee per signature.

We’ve been tracking the W3C proposal for WebAuthn’s pseudo random function (PRF) extension since its proposal in 2023. It now has widespread support by all major browser vendors and mobile operating systems. Using the PRF extension, you can now generate a portable native Ethereum key in the browser that can be accessed across devices. So we’ve put together an end-to-end template repo that enables a fully open source embedded wallet based on WebAuthn PRF that uses a nested iframe pattern. This makes the wallet consumable in third party sites as a provider just like a browser extension wallet.

There are two primary layers:

  1. The signing kernel - This is an immutable implementation of low-level signing utilities. It handles the credential creation ceremony as well as signature on payloads initiated by the user agent. The signing kernel is meant to be served from your application’s domain on a subdomain (or route) like ‘signer.myapp.com’ and must only be mountable by other subdomains on your TLD. The signing kernel is implemented using only browser-native APIs in pure javascript and has no external dependencies. The user’s private key never leaves this context. This layer is actually small enough that you could even serve it from a smart contract as proposed in EIP-8244.
  2. The branding layer - This is the wallet’s policy layer, it dictates the business logic of your embedded wallet and handles presenting interactive components to the user. The component is responsible for mounting the signing kernel iframe and implements the JSON-RPC methods your product or dapp wants to leverage. It is fully customizable by the product owner and is fully extensible via modules. It should serve from a subdomain (like wallet.myapp.com) or an appropriate route. Our template implementation implements the full EIP-1193 interface so the branding layer iframe can be consumed from and interacted with standard Web3 libraries like Viem or Ethers as a provider. You can even have one branding layer implementation for consuming on your own TLD that prevents mounting on third-party TLDs, and a second branding layer implementation with specialized business logic for consumption on external sites.

ows-demo

Benefits of this model:

  1. Free as in free speech: You get privy-like user experience (with much more flexibility) in a fully open source implementation that conforms to web3 standards like EIP-1193, so all your tooling that works for browser extensions will work with this. You can fork the repo and customize the JSON-RPC methods or UI components to be as sophisticated as you want.
  2. Free as in free beer: You basically have Ethereum native keys in your browser now thanks to WebAuthn PRF, so you shouldn’t be paying for user ops or MAUs anymore.
  3. Portable: works out-of-the-box with your standard web3 libraries like viem and ethers. An open standard wallet implementation can easily be called from third party apps just like a browser extension wallet. Works on mobile browsers and can follow the user across their devices.
  4. Extensible: Modules let you add customizable functionality like verifiable credential presentation linked to the portable user key or new agent-oriented standards like EIP-7715 for account delegations.
  5. Standards-Based: The cryptography in this approach relies entirely on standard W3C browser apis and pure javascript. Signing algorithms for secp256k1 (Ethereum and Bitcoin) and ed25519 (Solana), which are not implemented by the subtle crypto library, are lifted from mature implementations. The signing kernel imports no external dependencies, helping to protect it from supply chain attacks.

We actually want to get this to production quality to be used in real products so we’re looking for feedback from the Ethereum community on our approach, both in regards to our utilization of WebAuthn PRF for Ethereum key derivation and iframe isolation as well as the architectural design of the portable branding layer.